diff options
Diffstat (limited to 'libtomcrypt/src/pk/asn1')
50 files changed, 2027 insertions, 917 deletions
diff --git a/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c b/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c index bace8c8..5203fcf 100644 --- a/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c +++ b/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -45,8 +43,8 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, return CRYPT_INVALID_PACKET; } - /* offset in the data */ - x = 1; + /* offset in the data */ + x = 1; /* get the length of the data */ if (in[x] & 0x80) { @@ -67,7 +65,7 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, /* short format */ dlen = in[x++] & 0x7F; } - + /* is the data len too long or too short? */ if ((dlen == 0) || (dlen + x > inlen)) { return CRYPT_INVALID_PACKET; @@ -97,6 +95,6 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/bit/der_decode_raw_bit_string.c b/libtomcrypt/src/pk/asn1/der/bit/der_decode_raw_bit_string.c new file mode 100644 index 0000000..223899b --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/bit/der_decode_raw_bit_string.c @@ -0,0 +1,107 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" + +/** + @file der_decode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +#define SETBIT(v, n) (v=((unsigned char)(v) | (1U << (unsigned char)(n)))) +#define CLRBIT(v, n) (v=((unsigned char)(v) & ~(1U << (unsigned char)(n)))) + +/** + Store a BIT STRING + @param in The DER encoded BIT STRING + @param inlen The size of the DER BIT STRING + @param out [out] The array of bits stored (8 per char) + @param outlen [in/out] The number of bits stored + @return CRYPT_OK if successful +*/ +int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long dlen, blen, x, y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* packet must be at least 4 bytes */ + if (inlen < 4) { + return CRYPT_INVALID_ARG; + } + + /* check for 0x03 */ + if ((in[0]&0x1F) != 0x03) { + return CRYPT_INVALID_PACKET; + } + + /* offset in the data */ + x = 1; + + /* get the length of the data */ + if (in[x] & 0x80) { + /* long format get number of length bytes */ + y = in[x++] & 0x7F; + + /* invalid if 0 or > 2 */ + if (y == 0 || y > 2) { + return CRYPT_INVALID_PACKET; + } + + /* read the data len */ + dlen = 0; + while (y--) { + dlen = (dlen << 8) | (unsigned long)in[x++]; + } + } else { + /* short format */ + dlen = in[x++] & 0x7F; + } + + /* is the data len too long or too short? */ + if ((dlen == 0) || (dlen + x > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* get padding count */ + blen = ((dlen - 1) << 3) - (in[x++] & 7); + + /* too many bits? */ + if (blen > *outlen) { + *outlen = blen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode/store the bits */ + for (y = 0; y < blen; y++) { + if (in[x] & (1 << (7 - (y & 7)))) { + SETBIT(out[y/8], 7-(y%8)); + } else { + CLRBIT(out[y/8], 7-(y%8)); + } + if ((y & 7) == 7) { + ++x; + } + } + + /* we done */ + *outlen = blen; + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c b/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c index e64bd1f..c552184 100644 --- a/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c +++ b/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -84,6 +82,6 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen, #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/bit/der_encode_raw_bit_string.c b/libtomcrypt/src/pk/asn1/der/bit/der_encode_raw_bit_string.c new file mode 100644 index 0000000..298c4e3 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/bit/der_encode_raw_bit_string.c @@ -0,0 +1,90 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" + +/** + @file der_encode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +#define getbit(n, k) (((n) & ( 1 << (k) )) >> (k)) + +/** + Store a BIT STRING + @param in The array of bits to store (8 per char) + @param inlen The number of bits to store + @param out [out] The destination for the DER encoded BIT STRING + @param outlen [in/out] The max size and resulting size of the DER BIT STRING + @return CRYPT_OK if successful +*/ +int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y; + unsigned char buf; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* avoid overflows */ + if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) { + return err; + } + + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header (include bit padding count in length) */ + x = 0; + y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1; + + out[x++] = 0x03; + if (y < 128) { + out[x++] = (unsigned char)y; + } else if (y < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)y; + } else if (y < 65536) { + out[x++] = 0x82; + out[x++] = (unsigned char)((y>>8)&255); + out[x++] = (unsigned char)(y&255); + } + + /* store number of zero padding bits */ + out[x++] = (unsigned char)((8 - inlen) & 7); + + /* store the bits in big endian format */ + for (y = buf = 0; y < inlen; y++) { + buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7)); + if ((y & 7) == 7) { + out[x++] = buf; + buf = 0; + } + } + /* store last byte */ + if (inlen & 7) { + out[x++] = buf; + } + + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c b/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c index 3ec5f58..b9c99fb 100644 --- a/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c +++ b/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -17,7 +15,7 @@ #ifdef LTC_DER /** - Gets length of DER encoding of BIT STRING + Gets length of DER encoding of BIT STRING @param nbits The number of bits in the string to encode @param outlen [out] The length of the DER encoding for the given string @return CRYPT_OK if successful @@ -29,7 +27,7 @@ int der_length_bit_string(unsigned long nbits, unsigned long *outlen) /* get the number of the bytes */ nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1; - + if (nbytes < 128) { /* 03 LL PP DD DD DD ... */ *outlen = 2 + nbytes; @@ -49,6 +47,6 @@ int der_length_bit_string(unsigned long nbits, unsigned long *outlen) #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c b/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c index e7c5699..da60ca9 100644 --- a/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c +++ b/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -30,18 +28,18 @@ int der_decode_boolean(const unsigned char *in, unsigned long inlen, { LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); - - if (inlen != 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) { + + if (inlen < 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) { return CRYPT_INVALID_ARG; } - + *out = (in[2]==0xFF) ? 1 : 0; - + return CRYPT_OK; } #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c b/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c index b40fae6..c5cacdd 100644 --- a/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c +++ b/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -25,27 +23,27 @@ @param outlen [in/out] The max size and resulting size of the DER BOOLEAN @return CRYPT_OK if successful */ -int der_encode_boolean(int in, +int der_encode_boolean(int in, unsigned char *out, unsigned long *outlen) { LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(out != NULL); - + if (*outlen < 3) { *outlen = 3; return CRYPT_BUFFER_OVERFLOW; } - + *outlen = 3; out[0] = 0x01; out[1] = 0x01; out[2] = in ? 0xFF : 0x00; - + return CRYPT_OK; } #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c b/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c index 5437031..a1a3a7b 100644 --- a/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c +++ b/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -17,7 +15,7 @@ #ifdef LTC_DER /** - Gets length of DER encoding of a BOOLEAN + Gets length of DER encoding of a BOOLEAN @param outlen [out] The length of the DER encoding @return CRYPT_OK if successful */ @@ -30,6 +28,6 @@ int der_length_boolean(unsigned long *outlen) #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c b/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c index 1220b37..0bfd3bb 100644 --- a/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c +++ b/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -51,6 +49,16 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, data = list[x].data; switch (list[x].type) { + case LTC_ASN1_BOOLEAN: + if (der_decode_boolean(in, *inlen, data) == CRYPT_OK) { + if (der_length_boolean(&z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + case LTC_ASN1_INTEGER: if (der_decode_integer(in, *inlen, data) == CRYPT_OK) { if (der_length_integer(data, &z) == CRYPT_OK) { @@ -82,6 +90,17 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, } break; + case LTC_ASN1_RAW_BIT_STRING: + if (der_decode_raw_bit_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_bit_string(size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + case LTC_ASN1_OCTET_STRING: if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_octet_string(size, &z) == CRYPT_OK) { @@ -100,7 +119,7 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, return CRYPT_OK; } break; - + case LTC_ASN1_OBJECT_IDENTIFIER: if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_object_identifier(data, size, &z) == CRYPT_OK) { @@ -112,6 +131,17 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, } break; + case LTC_ASN1_TELETEX_STRING: + if (der_decode_teletex_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_teletex_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + case LTC_ASN1_IA5_STRING: if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_ia5_string(data, size, &z) == CRYPT_OK) { @@ -123,7 +153,6 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, } break; - case LTC_ASN1_PRINTABLE_STRING: if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_printable_string(data, size, &z) == CRYPT_OK) { @@ -155,6 +184,15 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, } break; + case LTC_ASN1_GENERALIZEDTIME: + z = *inlen; + if (der_decode_generalizedtime(in, &z, data) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + break; + case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: @@ -167,7 +205,10 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, } break; - default: + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: return CRYPT_INVALID_ARG; } } @@ -177,6 +218,6 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c b/libtomcrypt/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c new file mode 100644 index 0000000..016a4c2 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c @@ -0,0 +1,144 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" + +/** + @file der_decode_generalizedtime.c + ASN.1 DER, decode a GeneralizedTime, Steffen Jaeckel + Based on der_decode_utctime.c +*/ + +#ifdef LTC_DER + +static int _char_to_int(unsigned char x) +{ + switch (x) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + default: return 100; + } +} + +#define DECODE_V(y, max) do {\ + y = _char_to_int(buf[x])*10 + _char_to_int(buf[x+1]); \ + if (y >= max) return CRYPT_INVALID_PACKET; \ + x += 2; \ +} while(0) + +#define DECODE_V4(y, max) do {\ + y = _char_to_int(buf[x])*1000 + _char_to_int(buf[x+1])*100 + _char_to_int(buf[x+2])*10 + _char_to_int(buf[x+3]); \ + if (y >= max) return CRYPT_INVALID_PACKET; \ + x += 4; \ +} while(0) + +/** + Decodes a Generalized time structure in DER format (reads all 6 valid encoding formats) + @param in Input buffer + @param inlen Length of input buffer in octets + @param out [out] Destination of Generalized time structure + @return CRYPT_OK if successful +*/ +int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, + ltc_generalizedtime *out) +{ + unsigned char buf[32]; + unsigned long x; + int y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(out != NULL); + + /* check header */ + if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* decode the string */ + for (x = 0; x < in[1]; x++) { + y = der_ia5_value_decode(in[x+2]); + if (y == -1) { + return CRYPT_INVALID_PACKET; + } + if (!((y >= '0' && y <= '9') + || y == 'Z' || y == '.' + || y == '+' || y == '-')) { + return CRYPT_INVALID_PACKET; + } + buf[x] = y; + } + *inlen = 2 + x; + + if (x < 15) { + return CRYPT_INVALID_PACKET; + } + + /* possible encodings are +YYYYMMDDhhmmssZ +YYYYMMDDhhmmss+hh'mm' +YYYYMMDDhhmmss-hh'mm' +YYYYMMDDhhmmss.fsZ +YYYYMMDDhhmmss.fs+hh'mm' +YYYYMMDDhhmmss.fs-hh'mm' + + So let's do a trivial decode upto [including] ss + */ + + x = 0; + DECODE_V4(out->YYYY, 10000); + DECODE_V(out->MM, 13); + DECODE_V(out->DD, 32); + DECODE_V(out->hh, 24); + DECODE_V(out->mm, 60); + DECODE_V(out->ss, 60); + + /* clear fractional seconds info */ + out->fs = 0; + + /* now is it Z or . */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '.') { + x++; + while (buf[x] >= '0' && buf[x] <= '9') { + unsigned fs = out->fs; + if (x >= sizeof(buf)) return CRYPT_INVALID_PACKET; + out->fs *= 10; + out->fs += _char_to_int(buf[x]); + if (fs > out->fs) return CRYPT_OVERFLOW; + x++; + } + } + + /* now is it Z, +, - */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '+' || buf[x] == '-') { + out->off_dir = (buf[x++] == '+') ? 0 : 1; + DECODE_V(out->off_hh, 24); + DECODE_V(out->off_mm, 60); + return CRYPT_OK; + } else { + return CRYPT_INVALID_PACKET; + } +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c b/libtomcrypt/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c new file mode 100644 index 0000000..ddc472a --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/generalizedtime/der_encode_generalizedtime.c @@ -0,0 +1,108 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" + +/** + @file der_encode_utctime.c + ASN.1 DER, encode a GeneralizedTime, Steffen Jaeckel + Based on der_encode_utctime.c +*/ + +#ifdef LTC_DER + +static const char * const baseten = "0123456789"; + +#define STORE_V(y) do {\ + out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[y % 10]); \ +} while(0) + +#define STORE_V4(y) do {\ + out[x++] = der_ia5_char_encode(baseten[(y/1000) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[(y/100) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[y % 10]); \ +} while(0) + +/** + Encodes a Generalized time structure in DER format + @param gtime The GeneralizedTime structure to encode + @param out The destination of the DER encoding of the GeneralizedTime structure + @param outlen [in/out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_encode_generalizedtime(ltc_generalizedtime *gtime, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, tmplen; + int err; + + LTC_ARGCHK(gtime != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = der_length_generalizedtime(gtime, &tmplen)) != CRYPT_OK) { + return err; + } + if (tmplen > *outlen) { + *outlen = tmplen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header */ + out[0] = 0x18; + + /* store values */ + x = 2; + STORE_V4(gtime->YYYY); + STORE_V(gtime->MM); + STORE_V(gtime->DD); + STORE_V(gtime->hh); + STORE_V(gtime->mm); + STORE_V(gtime->ss); + + if (gtime->fs) { + unsigned long divisor; + unsigned fs = gtime->fs; + unsigned len = 0; + out[x++] = der_ia5_char_encode('.'); + divisor = 1; + do { + fs /= 10; + divisor *= 10; + len++; + } while(fs != 0); + while (len-- > 1) { + divisor /= 10; + out[x++] = der_ia5_char_encode(baseten[(gtime->fs/divisor) % 10]); + } + out[x++] = der_ia5_char_encode(baseten[gtime->fs % 10]); + } + + if (gtime->off_mm || gtime->off_hh) { + out[x++] = der_ia5_char_encode(gtime->off_dir ? '-' : '+'); + STORE_V(gtime->off_hh); + STORE_V(gtime->off_mm); + } else { + out[x++] = der_ia5_char_encode('Z'); + } + + /* store length */ + out[1] = (unsigned char)(x - 2); + + /* all good let's return */ + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c b/libtomcrypt/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c new file mode 100644 index 0000000..def6270 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/generalizedtime/der_length_generalizedtime.c @@ -0,0 +1,58 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" + +/** + @file der_length_utctime.c + ASN.1 DER, get length of GeneralizedTime, Steffen Jaeckel + Based on der_length_utctime.c +*/ + +#ifdef LTC_DER + +/** + Gets length of DER encoding of GeneralizedTime + @param gtime The GeneralizedTime structure to get the size of + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(gtime != NULL); + + if (gtime->fs == 0) { + /* we encode as YYYYMMDDhhmmssZ */ + *outlen = 2 + 14 + 1; + } else { + unsigned long len = 2 + 14 + 1; + unsigned fs = gtime->fs; + do { + fs /= 10; + len++; + } while(fs != 0); + if (gtime->off_hh == 0 && gtime->off_mm == 0) { + /* we encode as YYYYMMDDhhmmss.fsZ */ + len += 1; + } + else { + /* we encode as YYYYMMDDhhmmss.fs{+|-}hh'mm' */ + len += 5; + } + *outlen = len; + } + + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c b/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c index 1880ada..c347251 100644 --- a/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c +++ b/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -88,9 +86,9 @@ int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, return CRYPT_OK; } - + #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c b/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c index 6009dbc..18b926e 100644 --- a/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c +++ b/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -37,7 +35,7 @@ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, /* get the size */ if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) { - return err; + return err; } /* too big? */ @@ -80,6 +78,6 @@ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c b/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c index f10c1b8..5f1a78d 100644 --- a/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c +++ b/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -21,106 +19,106 @@ static const struct { int code, value; } ia5_table[] = { { '\0', 0 }, -{ '\a', 7 }, -{ '\b', 8 }, -{ '\t', 9 }, -{ '\n', 10 }, -{ '\f', 12 }, -{ '\r', 13 }, -{ ' ', 32 }, -{ '!', 33 }, -{ '"', 34 }, -{ '#', 35 }, -{ '$', 36 }, -{ '%', 37 }, -{ '&', 38 }, -{ '\'', 39 }, -{ '(', 40 }, -{ ')', 41 }, -{ '*', 42 }, -{ '+', 43 }, -{ ',', 44 }, -{ '-', 45 }, -{ '.', 46 }, -{ '/', 47 }, -{ '0', 48 }, -{ '1', 49 }, -{ '2', 50 }, -{ '3', 51 }, -{ '4', 52 }, -{ '5', 53 }, -{ '6', 54 }, -{ '7', 55 }, -{ '8', 56 }, -{ '9', 57 }, -{ ':', 58 }, -{ ';', 59 }, -{ '<', 60 }, -{ '=', 61 }, -{ '>', 62 }, -{ '?', 63 }, -{ '@', 64 }, -{ 'A', 65 }, -{ 'B', 66 }, -{ 'C', 67 }, -{ 'D', 68 }, -{ 'E', 69 }, -{ 'F', 70 }, -{ 'G', 71 }, -{ 'H', 72 }, -{ 'I', 73 }, -{ 'J', 74 }, -{ 'K', 75 }, -{ 'L', 76 }, -{ 'M', 77 }, -{ 'N', 78 }, -{ 'O', 79 }, -{ 'P', 80 }, -{ 'Q', 81 }, -{ 'R', 82 }, -{ 'S', 83 }, -{ 'T', 84 }, -{ 'U', 85 }, -{ 'V', 86 }, -{ 'W', 87 }, -{ 'X', 88 }, -{ 'Y', 89 }, -{ 'Z', 90 }, -{ '[', 91 }, -{ '\\', 92 }, -{ ']', 93 }, -{ '^', 94 }, -{ '_', 95 }, -{ '`', 96 }, -{ 'a', 97 }, -{ 'b', 98 }, -{ 'c', 99 }, -{ 'd', 100 }, -{ 'e', 101 }, -{ 'f', 102 }, -{ 'g', 103 }, -{ 'h', 104 }, -{ 'i', 105 }, -{ 'j', 106 }, -{ 'k', 107 }, -{ 'l', 108 }, -{ 'm', 109 }, -{ 'n', 110 }, -{ 'o', 111 }, -{ 'p', 112 }, -{ 'q', 113 }, -{ 'r', 114 }, -{ 's', 115 }, -{ 't', 116 }, -{ 'u', 117 }, -{ 'v', 118 }, -{ 'w', 119 }, -{ 'x', 120 }, -{ 'y', 121 }, -{ 'z', 122 }, -{ '{', 123 }, -{ '|', 124 }, -{ '}', 125 }, +{ '\a', 7 }, +{ '\b', 8 }, +{ '\t', 9 }, +{ '\n', 10 }, +{ '\f', 12 }, +{ '\r', 13 }, +{ ' ', 32 }, +{ '!', 33 }, +{ '"', 34 }, +{ '#', 35 }, +{ '$', 36 }, +{ '%', 37 }, +{ '&', 38 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '*', 42 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ ';', 59 }, +{ '<', 60 }, +{ '=', 61 }, +{ '>', 62 }, +{ '?', 63 }, +{ '@', 64 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ '[', 91 }, +{ '\\', 92 }, +{ ']', 93 }, +{ '^', 94 }, +{ '_', 95 }, +{ '`', 96 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +{ '{', 123 }, +{ '|', 124 }, +{ '}', 125 }, { '~', 126 } }; @@ -145,10 +143,10 @@ int der_ia5_value_decode(int v) } return -1; } - + /** - Gets length of DER encoding of IA5 STRING - @param octets The values you want to encode + Gets length of DER encoding of IA5 STRING + @param octets The values you want to encode @param noctets The number of octets in the string to encode @param outlen [out] The length of the DER encoding for the given string @return CRYPT_OK if successful @@ -189,6 +187,6 @@ int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, un #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c b/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c index 0ed8ad7..88cf93f 100644 --- a/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c +++ b/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -54,7 +52,7 @@ int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) if (x + z > inlen) { return CRYPT_INVALID_PACKET; } - + /* no so read it */ if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) { return err; @@ -62,7 +60,7 @@ int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) } else { /* long form */ z &= 0x7F; - + /* will number of length bytes overflow? (or > 4) */ if (((x + z) > inlen) || (z > 4) || (z == 0)) { return CRYPT_INVALID_PACKET; @@ -97,7 +95,7 @@ int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) return CRYPT_MEM; } mp_clear(tmp); - } + } return CRYPT_OK; @@ -105,6 +103,6 @@ int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c b/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c index e80bb3c..a8bada5 100644 --- a/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c +++ b/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -27,7 +25,7 @@ @return CRYPT_OK if successful */ int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) -{ +{ unsigned long tmplen, y; int err, leading_zero; @@ -97,7 +95,7 @@ int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) } } else if (mp_iszero(num) != LTC_MP_YES) { void *tmp; - + /* negative */ if (mp_init(&tmp) != CRYPT_OK) { return CRYPT_MEM; @@ -119,12 +117,12 @@ int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) } /* we good */ - *outlen = tmplen; + *outlen = tmplen; return CRYPT_OK; } #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c b/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c index 9d49683..753ef0e 100644 --- a/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c +++ b/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -18,8 +16,8 @@ #ifdef LTC_DER /** - Gets length of DER encoding of num - @param num The int to get the size of + Gets length of DER encoding of num + @param num The int to get the size of @param outlen [out] The length of the DER encoding for the given integer @return CRYPT_OK if successful */ @@ -46,7 +44,6 @@ int der_length_integer(void *num, unsigned long *outlen) } else { /* it's negative */ /* find power of 2 that is a multiple of eight and greater than count bits */ - leading_zero = 0; z = mp_count_bits(num); z = z + (8 - (z & 7)); if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z; @@ -71,12 +68,12 @@ int der_length_integer(void *num, unsigned long *outlen) ++len; /* return length */ - *outlen = len; + *outlen = len; return CRYPT_OK; } #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c b/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c index 406acdc..75bc127 100644 --- a/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c +++ b/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -28,6 +26,7 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle unsigned long *words, unsigned long *outlen) { unsigned long x, y, t, len; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(words != NULL); @@ -40,6 +39,7 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle /* must be room for at least two words */ if (*outlen < 2) { + *outlen = 2; return CRYPT_BUFFER_OVERFLOW; } @@ -48,19 +48,19 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle if ((in[x++] & 0x1F) != 0x06) { return CRYPT_INVALID_PACKET; } - + /* get the length */ if (in[x] < 128) { - len = in[x++]; + len = in[x++]; } else { - if (in[x] < 0x81 || in[x] > 0x82) { - return CRYPT_INVALID_PACKET; - } - y = in[x++] & 0x7F; - len = 0; - while (y--) { - len = (len << 8) | (unsigned long)in[x++]; - } + if (in[x] < 0x81 || in[x] > 0x82) { + return CRYPT_INVALID_PACKET; + } + y = in[x++] & 0x7F; + len = 0; + while (y--) { + len = (len << 8) | (unsigned long)in[x++]; + } } if (len < 1 || (len + x) > inlen) { @@ -71,29 +71,36 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle y = 0; t = 0; while (len--) { - t = (t << 7) | (in[x] & 0x7F); - if (!(in[x++] & 0x80)) { - /* store t */ - if (y >= *outlen) { - return CRYPT_BUFFER_OVERFLOW; - } - if (y == 0) { - words[0] = t / 40; - words[1] = t % 40; - y = 2; - } else { - words[y++] = t; + t = (t << 7) | (in[x] & 0x7F); + if (!(in[x++] & 0x80)) { + /* store t */ + if (y >= *outlen) { + y++; + } else { + if (y == 0) { + words[0] = t / 40; + words[1] = t % 40; + y = 2; + } else { + words[y++] = t; + } + } + t = 0; } - t = 0; - } } - + + if (y > *outlen) { + err = CRYPT_BUFFER_OVERFLOW; + } else { + err = CRYPT_OK; + } + *outlen = y; - return CRYPT_OK; + return err; } #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c b/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c index f018ba9..b1ce62c 100644 --- a/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c +++ b/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -55,7 +53,7 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords, } /* store header + length */ - x = 0; + x = 0; out[x++] = 0x06; if (z < 128) { out[x++] = (unsigned char)z; @@ -71,33 +69,33 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords, } /* store first byte */ - wordbuf = words[0] * 40 + words[1]; - for (i = 1; i < nwords; i++) { - /* store 7 bit words in little endian */ - t = wordbuf & 0xFFFFFFFF; - if (t) { - y = x; - mask = 0; - while (t) { - out[x++] = (unsigned char)((t & 0x7F) | mask); - t >>= 7; - mask |= 0x80; /* upper bit is set on all but the last byte */ - } - /* now swap bytes y...x-1 */ - z = x - 1; - while (y < z) { - t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t; - ++y; - --z; - } - } else { - /* zero word */ - out[x++] = 0x00; - } - - if (i < nwords - 1) { - wordbuf = words[i + 1]; - } + wordbuf = words[0] * 40 + words[1]; + for (i = 1; i < nwords; i++) { + /* store 7 bit words in little endian */ + t = wordbuf & 0xFFFFFFFF; + if (t) { + y = x; + mask = 0; + while (t) { + out[x++] = (unsigned char)((t & 0x7F) | mask); + t >>= 7; + mask |= 0x80; /* upper bit is set on all but the last byte */ + } + /* now swap bytes y...x-1 */ + z = x - 1; + while (y < z) { + t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t; + ++y; + --z; + } + } else { + /* zero word */ + out[x++] = 0x00; + } + + if (i < nwords - 1) { + wordbuf = words[i + 1]; + } } *outlen = x; @@ -106,6 +104,6 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords, #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c b/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c index ccb1e6d..ac08915 100644 --- a/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c +++ b/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -32,14 +30,14 @@ unsigned long der_object_identifier_bits(unsigned long x) /** Gets length of DER encoding of Object Identifier - @param nwords The number of OID words + @param nwords The number of OID words @param words The actual OID words to get the size of @param outlen [out] The length of the DER encoding for the given string @return CRYPT_OK if successful */ int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen) { - unsigned long y, z, t, wordbuf; + unsigned long y, z, t, wordbuf; LTC_ARGCHK(words != NULL); LTC_ARGCHK(outlen != NULL); @@ -84,6 +82,6 @@ int der_length_object_identifier(unsigned long *words, unsigned long nwords, uns #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c b/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c index 952d739..02859dc 100644 --- a/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c +++ b/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -83,9 +81,9 @@ int der_decode_octet_string(const unsigned char *in, unsigned long inlen, return CRYPT_OK; } - + #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c b/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c index 9a16c3b..9c9d1a6 100644 --- a/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c +++ b/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -38,7 +36,7 @@ int der_encode_octet_string(const unsigned char *in, unsigned long inlen, /* get the size */ if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) { - return err; + return err; } /* too big? */ @@ -81,6 +79,6 @@ int der_encode_octet_string(const unsigned char *in, unsigned long inlen, #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c b/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c index 07da058..10c9e89 100644 --- a/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c +++ b/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -17,7 +15,7 @@ #ifdef LTC_DER /** - Gets length of DER encoding of OCTET STRING + Gets length of DER encoding of OCTET STRING @param noctets The number of octets in the string to encode @param outlen [out] The length of the DER encoding for the given string @return CRYPT_OK if successful @@ -48,6 +46,6 @@ int der_length_octet_string(unsigned long noctets, unsigned long *outlen) #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c b/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c index 56bf376..6947429 100644 --- a/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c +++ b/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -88,9 +86,9 @@ int der_decode_printable_string(const unsigned char *in, unsigned long inlen, return CRYPT_OK; } - + #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c b/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c index 7d7cfd2..ee54e48 100644 --- a/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c +++ b/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -37,7 +35,7 @@ int der_encode_printable_string(const unsigned char *in, unsigned long inlen, /* get the size */ if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) { - return err; + return err; } /* too big? */ @@ -80,6 +78,6 @@ int der_encode_printable_string(const unsigned char *in, unsigned long inlen, #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c b/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c index 9f78f20..40f0beb 100644 --- a/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c +++ b/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -20,80 +18,80 @@ static const struct { int code, value; } printable_table[] = { -{ ' ', 32 }, -{ '\'', 39 }, -{ '(', 40 }, -{ ')', 41 }, -{ '+', 43 }, -{ ',', 44 }, -{ '-', 45 }, -{ '.', 46 }, -{ '/', 47 }, -{ '0', 48 }, -{ '1', 49 }, -{ '2', 50 }, -{ '3', 51 }, -{ '4', 52 }, -{ '5', 53 }, -{ '6', 54 }, -{ '7', 55 }, -{ '8', 56 }, -{ '9', 57 }, -{ ':', 58 }, -{ '=', 61 }, -{ '?', 63 }, -{ 'A', 65 }, -{ 'B', 66 }, -{ 'C', 67 }, -{ 'D', 68 }, -{ 'E', 69 }, -{ 'F', 70 }, -{ 'G', 71 }, -{ 'H', 72 }, -{ 'I', 73 }, -{ 'J', 74 }, -{ 'K', 75 }, -{ 'L', 76 }, -{ 'M', 77 }, -{ 'N', 78 }, -{ 'O', 79 }, -{ 'P', 80 }, -{ 'Q', 81 }, -{ 'R', 82 }, -{ 'S', 83 }, -{ 'T', 84 }, -{ 'U', 85 }, -{ 'V', 86 }, -{ 'W', 87 }, -{ 'X', 88 }, -{ 'Y', 89 }, -{ 'Z', 90 }, -{ 'a', 97 }, -{ 'b', 98 }, -{ 'c', 99 }, -{ 'd', 100 }, -{ 'e', 101 }, -{ 'f', 102 }, -{ 'g', 103 }, -{ 'h', 104 }, -{ 'i', 105 }, -{ 'j', 106 }, -{ 'k', 107 }, -{ 'l', 108 }, -{ 'm', 109 }, -{ 'n', 110 }, -{ 'o', 111 }, -{ 'p', 112 }, -{ 'q', 113 }, -{ 'r', 114 }, -{ 's', 115 }, -{ 't', 116 }, -{ 'u', 117 }, -{ 'v', 118 }, -{ 'w', 119 }, -{ 'x', 120 }, -{ 'y', 121 }, -{ 'z', 122 }, +{ ' ', 32 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ '=', 61 }, +{ '?', 63 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, }; int der_printable_char_encode(int c) @@ -117,10 +115,10 @@ int der_printable_value_decode(int v) } return -1; } - + /** - Gets length of DER encoding of Printable STRING - @param octets The values you want to encode + Gets length of DER encoding of Printable STRING + @param octets The values you want to encode @param noctets The number of octets in the string to encode @param outlen [out] The length of the DER encoding for the given string @return CRYPT_OK if successful @@ -161,6 +159,6 @@ int der_length_printable_string(const unsigned char *octets, unsigned long nocte #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c index 5042b18..b820c68 100644 --- a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c @@ -5,11 +5,8 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include <stdarg.h> /** @@ -31,13 +28,14 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, ltc_asn1_list *list, unsigned long outlen, int ordered) { - int err, type; - unsigned long size, x, y, z, i, blksize; + int err, i; + ltc_asn1_type type; + unsigned long size, x, y, z, blksize; void *data; LTC_ARGCHK(in != NULL); LTC_ARGCHK(list != NULL); - + /* get blk size */ if (inlen < 2) { return CRYPT_INVALID_PACKET; @@ -50,9 +48,12 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, } ++x; + /* check if the msb is set, which signals that the + * 7 lsb bits represent the number of bytes of the length + */ if (in[x] < 128) { blksize = in[x++]; - } else if (in[x] & 0x80) { + } else { if (in[x] < 0x81 || in[x] > 0x83) { return CRYPT_INVALID_PACKET; } @@ -68,28 +69,28 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, while (y--) { blksize = (blksize << 8) | (unsigned long)in[x++]; } - } + } - /* would this blksize overflow? */ - if (x + blksize > inlen) { - return CRYPT_INVALID_PACKET; - } + /* would this blksize overflow? */ + if (x + blksize > inlen) { + return CRYPT_INVALID_PACKET; + } /* mark all as unused */ - for (i = 0; i < outlen; i++) { + for (i = 0; i < (int)outlen; i++) { list[i].used = 0; - } + } - /* ok read data */ + /* ok read data */ inlen = blksize; - for (i = 0; i < outlen; i++) { + for (i = 0; i < (int)outlen; i++) { z = 0; type = list[i].type; size = list[i].size; data = list[i].data; if (!ordered && list[i].used == 1) { continue; } - if (type == LTC_ASN1_EOL) { + if (type == LTC_ASN1_EOL) { break; } @@ -97,13 +98,14 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, case LTC_ASN1_BOOLEAN: z = inlen; if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { + if (!ordered) { continue; } goto LBL_ERR; } if ((err = der_length_boolean(&z)) != CRYPT_OK) { goto LBL_ERR; - } - break; - + } + break; + case LTC_ASN1_INTEGER: z = inlen; if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { @@ -124,7 +126,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { goto LBL_ERR; } - + break; case LTC_ASN1_BIT_STRING: @@ -139,6 +141,18 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, } break; + case LTC_ASN1_RAW_BIT_STRING: + z = inlen; + if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + case LTC_ASN1_OCTET_STRING: z = inlen; if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { @@ -159,7 +173,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, } z = 2; break; - + case LTC_ASN1_OBJECT_IDENTIFIER: z = inlen; if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { @@ -172,6 +186,18 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, } break; + case LTC_ASN1_TELETEX_STRING: + z = inlen; + if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_teletex_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + case LTC_ASN1_IA5_STRING: z = inlen; if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { @@ -217,6 +243,14 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, } break; + case LTC_ASN1_GENERALIZEDTIME: + z = inlen; + if ((err = der_decode_generalizedtime(in + x, &z, data)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + break; + case LTC_ASN1_SET: z = inlen; if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { @@ -227,7 +261,7 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, goto LBL_ERR; } break; - + case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: /* detect if we have the right type */ @@ -255,33 +289,40 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, } break; - default: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: err = CRYPT_INVALID_ARG; goto LBL_ERR; } x += z; inlen -= z; list[i].used = 1; - if (!ordered) { + if (!ordered) { /* restart the decoder */ i = -1; - } + } } - - for (i = 0; i < outlen; i++) { + + for (i = 0; i < (int)outlen; i++) { if (list[i].used == 0) { err = CRYPT_INVALID_PACKET; goto LBL_ERR; } - } - err = CRYPT_OK; + } + + if (inlen == 0) { + err = CRYPT_OK; + } else { + err = CRYPT_INPUT_TOO_LONG; + } LBL_ERR: return err; -} - +} + #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c index 4fd3aaa..142ef95 100644 --- a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -17,102 +15,129 @@ #ifdef LTC_DER -static unsigned long fetch_length(const unsigned char *in, unsigned long inlen) +static unsigned long _fetch_length(const unsigned char *in, unsigned long inlen, unsigned long *data_offset) { - unsigned long x, y, z; + unsigned long x, z; - y = 0; + *data_offset = 0; /* skip type and read len */ if (inlen < 2) { return 0xFFFFFFFF; } - ++in; ++y; - + ++in; ++(*data_offset); + /* read len */ - x = *in++; ++y; - + x = *in++; ++(*data_offset); + /* <128 means literal */ if (x < 128) { - return x+y; + return x+*data_offset; } x &= 0x7F; /* the lower 7 bits are the length of the length */ inlen -= 2; - + /* len means len of len! */ if (x == 0 || x > 4 || x > inlen) { return 0xFFFFFFFF; } - - y += x; + + *data_offset += x; z = 0; - while (x--) { + while (x--) { z = (z<<8) | ((unsigned long)*in); ++in; } - return z+y; + return z+*data_offset; } -/** +static int _new_element(ltc_asn1_list **l) +{ + /* alloc new link */ + if (*l == NULL) { + *l = XCALLOC(1, sizeof(ltc_asn1_list)); + if (*l == NULL) { + return CRYPT_MEM; + } + } else { + (*l)->next = XCALLOC(1, sizeof(ltc_asn1_list)); + if ((*l)->next == NULL) { + return CRYPT_MEM; + } + (*l)->next->prev = *l; + *l = (*l)->next; + } + return CRYPT_OK; +} + +/** ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements. @param in The input buffer - @param inlen [in/out] The length of the input buffer and on output the amount of decoded data + @param inlen [in/out] The length of the input buffer and on output the amount of decoded data @param out [out] A pointer to the linked list @return CRYPT_OK on success. -*/ +*/ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out) { ltc_asn1_list *l; - unsigned long err, type, len, totlen, x, y; + unsigned long err, type, len, totlen, data_offset; void *realloc_tmp; - + LTC_ARGCHK(in != NULL); LTC_ARGCHK(inlen != NULL); LTC_ARGCHK(out != NULL); l = NULL; totlen = 0; - + + if (*inlen == 0) { + /* alloc new link */ + if ((err = _new_element(&l)) != CRYPT_OK) { + goto error; + } + } + /* scan the input and and get lengths and what not */ - while (*inlen) { + while (*inlen) { /* read the type byte */ type = *in; /* fetch length */ - len = fetch_length(in, *inlen); + len = _fetch_length(in, *inlen, &data_offset); if (len > *inlen) { err = CRYPT_INVALID_PACKET; goto error; } /* alloc new link */ - if (l == NULL) { - l = XCALLOC(1, sizeof(*l)); - if (l == NULL) { - err = CRYPT_MEM; - goto error; - } - } else { - l->next = XCALLOC(1, sizeof(*l)); - if (l->next == NULL) { - err = CRYPT_MEM; - goto error; - } - l->next->prev = l; - l = l->next; + if ((err = _new_element(&l)) != CRYPT_OK) { + goto error; + } + + if ((type & 0x20) && (type != 0x30) && (type != 0x31)) { + /* constructed, use the 'used' field to store the original identifier */ + l->used = type; + /* treat constructed elements like SETs */ + type = 0x20; + } + else if ((type & 0xC0) == 0x80) { + /* context-specific, use the 'used' field to store the original identifier */ + l->used = type; + /* context-specific elements are treated as opaque data */ + type = 0x80; } - /* now switch on type */ + /* now switch on type */ switch (type) { case 0x01: /* BOOLEAN */ l->type = LTC_ASN1_BOOLEAN; l->size = 1; l->data = XCALLOC(1, sizeof(int)); - + if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) { goto error; } - + if ((err = der_length_boolean(&len)) != CRYPT_OK) { goto error; } @@ -125,12 +150,12 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc if ((err = mp_init(&l->data)) != CRYPT_OK) { goto error; } - + /* decode field */ if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) { goto error; } - + /* calc length of object */ if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) { goto error; @@ -146,11 +171,11 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc err = CRYPT_MEM; goto error; } - + if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } - + if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) { goto error; } @@ -166,34 +191,34 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc err = CRYPT_MEM; goto error; } - + if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } - + if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) { goto error; } break; case 0x05: /* NULL */ - + /* valid NULL is 0x05 0x00 */ if (in[0] != 0x05 || in[1] != 0x00) { err = CRYPT_INVALID_PACKET; goto error; } - + /* simple to store ;-) */ l->type = LTC_ASN1_NULL; l->data = NULL; l->size = 0; len = 2; - + break; - + case 0x06: /* OID */ - + /* init field */ l->type = LTC_ASN1_OBJECT_IDENTIFIER; l->size = len; @@ -202,15 +227,15 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc err = CRYPT_MEM; goto error; } - + if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } - + if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) { goto error; } - + /* resize it to save a bunch of mem */ if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) { /* out of heap but this is not an error */ @@ -218,9 +243,9 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc } l->data = realloc_tmp; break; - + case 0x0C: /* UTF8 */ - + /* init field */ l->type = LTC_ASN1_UTF8_STRING; l->size = len; @@ -229,18 +254,18 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc err = CRYPT_MEM; goto error; } - + if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } - + if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) { goto error; } break; case 0x13: /* PRINTABLE */ - + /* init field */ l->type = LTC_ASN1_PRINTABLE_STRING; l->size = len; @@ -249,18 +274,38 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc err = CRYPT_MEM; goto error; } - + if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } - + if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) { goto error; } break; - + + case 0x14: /* TELETEXT */ + + /* init field */ + l->type = LTC_ASN1_TELETEX_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_teletex_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_teletex_string(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + case 0x16: /* IA5 */ - + /* init field */ l->type = LTC_ASN1_IA5_STRING; l->size = len; @@ -269,18 +314,18 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc err = CRYPT_MEM; goto error; } - + if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } - + if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) { goto error; } break; - + case 0x17: /* UTC TIME */ - + /* init field */ l->type = LTC_ASN1_UTCTIME; l->size = 1; @@ -289,83 +334,125 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc err = CRYPT_MEM; goto error; } - + len = *inlen; if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) { goto error; } - + if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) { goto error; } break; - + + case 0x18: + l->type = LTC_ASN1_GENERALIZEDTIME; + l->size = len; + + if ((l->data = XCALLOC(1, sizeof(ltc_generalizedtime))) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_generalizedtime(in, &len, l->data)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_generalizedtime(l->data, &len)) != CRYPT_OK) { + goto error; + } + + break; + + case 0x20: /* Any CONSTRUCTED element that is neither SEQUENCE nor SET */ case 0x30: /* SEQUENCE */ case 0x31: /* SET */ - + /* init field */ - l->type = (type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET; - - /* we have to decode the SEQUENCE header and get it's length */ - - /* move past type */ - ++in; --(*inlen); - - /* read length byte */ - x = *in++; --(*inlen); - - /* smallest SEQUENCE/SET header */ - y = 2; - - /* now if it's > 127 the next bytes are the length of the length */ - if (x > 128) { - x &= 0x7F; - in += x; - *inlen -= x; - - /* update sequence header len */ - y += x; - } - + if (type == 0x20) { + l->type = LTC_ASN1_CONSTRUCTED; + } + else if (type == 0x30) { + l->type = LTC_ASN1_SEQUENCE; + } + else { + l->type = LTC_ASN1_SET; + } + + if ((l->data = XMALLOC(len)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + XMEMCPY(l->data, in, len); + l->size = len; + + + /* jump to the start of the data */ + in += data_offset; + *inlen -= data_offset; + len = len - data_offset; + /* Sequence elements go as child */ - len = len - y; if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) { goto error; } - + /* len update */ - totlen += y; - - /* link them up y0 */ - l->child->parent = l; - + totlen += data_offset; + + /* the flexi decoder can also do nothing, so make sure a child has been allocated */ + if (l->child) { + /* link them up y0 */ + l->child->parent = l; + } + + break; + + case 0x80: /* Context-specific */ + l->type = LTC_ASN1_CONTEXT_SPECIFIC; + + if ((l->data = XCALLOC(1, len - data_offset)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + XMEMCPY(l->data, in + data_offset, len - data_offset); + l->size = len - data_offset; + break; + default: /* invalid byte ... this is a soft error */ /* remove link */ - l = l->prev; - XFREE(l->next); - l->next = NULL; + if (l->prev) { + l = l->prev; + XFREE(l->next); + l->next = NULL; + } goto outside; } - + /* advance pointers */ totlen += len; in += len; *inlen -= len; } - -outside: - - /* rewind l please */ - while (l->prev != NULL || l->parent != NULL) { - if (l->parent != NULL) { - l = l->parent; - } else { - l = l->prev; + +outside: + + /* in case we processed anything */ + if (totlen) { + /* rewind l please */ + while (l->prev != NULL || l->parent != NULL) { + if (l->parent != NULL) { + l = l->parent; + } else { + l = l->prev; + } } } - + /* return */ *out = l; *inlen = totlen; @@ -381,6 +468,6 @@ error: #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c index 4202eb3..1361b76 100644 --- a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include <stdarg.h> @@ -25,10 +23,11 @@ @param inlen Length of input in octets @remark <...> is of the form <type, size, data> (int, unsigned long, void*) @return CRYPT_OK on success -*/ +*/ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) { - int err, type; + int err; + ltc_asn1_type type; unsigned long size, x; void *data; va_list args; @@ -40,11 +39,13 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) va_start(args, inlen); x = 0; for (;;) { - type = va_arg(args, int); + type = (ltc_asn1_type)va_arg(args, int); size = va_arg(args, unsigned long); data = va_arg(args, void*); + LTC_UNUSED_PARAM(size); + LTC_UNUSED_PARAM(data); - if (type == LTC_ASN1_EOL) { + if (type == LTC_ASN1_EOL) { break; } @@ -64,10 +65,15 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: case LTC_ASN1_CHOICE: - ++x; + case LTC_ASN1_RAW_BIT_STRING: + case LTC_ASN1_TELETEX_STRING: + case LTC_ASN1_GENERALIZEDTIME: + ++x; break; - - default: + + case LTC_ASN1_EOL: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: va_end(args); return CRYPT_INVALID_ARG; } @@ -88,11 +94,11 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) va_start(args, inlen); x = 0; for (;;) { - type = va_arg(args, int); + type = (ltc_asn1_type)va_arg(args, int); size = va_arg(args, unsigned long); data = va_arg(args, void*); - if (type == LTC_ASN1_EOL) { + if (type == LTC_ASN1_EOL) { break; } @@ -110,23 +116,23 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) case LTC_ASN1_UTCTIME: case LTC_ASN1_SEQUENCE: case LTC_ASN1_SET: - case LTC_ASN1_SETOF: + case LTC_ASN1_SETOF: case LTC_ASN1_CHOICE: - list[x].type = type; - list[x].size = size; - list[x++].data = data; + case LTC_ASN1_RAW_BIT_STRING: + case LTC_ASN1_TELETEX_STRING: + case LTC_ASN1_GENERALIZEDTIME: + LTC_SET_ASN1(list, x++, type, data, size); + break; + /* coverity[dead_error_line] */ + case LTC_ASN1_EOL: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: break; - - default: - va_end(args); - err = CRYPT_INVALID_ARG; - goto LBL_ERR; } } va_end(args); err = der_decode_sequence(in, inlen, list, x); -LBL_ERR: XFREE(list); return err; } @@ -134,6 +140,6 @@ LBL_ERR: #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_subject_public_key_info.c b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_subject_public_key_info.c new file mode 100644 index 0000000..6826181 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_subject_public_key_info.c @@ -0,0 +1,112 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" +/** + @file der_decode_subject_public_key_info.c + ASN.1 DER, encode a Subject Public Key structure --nmav +*/ + +#ifdef LTC_DER + +/* AlgorithmIdentifier := SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm + * } + * + * SubjectPublicKeyInfo := SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + */ +/** + Decode a subject public key info + @param in The input buffer + @param inlen The length of the input buffer + @param algorithm One out of the enum #public_key_algorithms + @param public_key The buffer for the public key + @param public_key_len [in/out] The length of the public key buffer and the written length + @param parameters_type The parameters' type out of the enum ltc_asn1_type + @param parameters The parameters to include + @param parameters_len The number of parameters to include + @return CRYPT_OK on success +*/ +int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, + unsigned int algorithm, void* public_key, unsigned long* public_key_len, + unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len) +{ + int err; + unsigned long len; + oid_st oid; + unsigned char *tmpbuf; + unsigned long tmpoid[16]; + ltc_asn1_list alg_id[2]; + ltc_asn1_list subject_pubkey[2]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != 0); + LTC_ARGCHK(public_key_len != NULL); + + err = pk_get_oid(algorithm, &oid); + if (err != CRYPT_OK) { + return err; + } + + /* see if the OpenSSL DER format RSA public key will work */ + tmpbuf = XCALLOC(1, inlen); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } + + /* this includes the internal hash ID and optional params (NULL in this case) */ + LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); + LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, parameters_len); + + /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey + * in a **BIT** string ... so we have to extract it then proceed to convert bit to octet + */ + LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2); + LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, inlen*8U); + + err=der_decode_sequence(in, inlen, subject_pubkey, 2UL); + if (err != CRYPT_OK) { + goto LBL_ERR; + } + + if ((alg_id[0].size != oid.OIDlen) || + XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0]))) { + /* OID mismatch */ + err = CRYPT_PK_INVALID_TYPE; + goto LBL_ERR; + } + + len = subject_pubkey[1].size/8; + if (*public_key_len > len) { + XMEMCPY(public_key, subject_pubkey[1].data, len); + *public_key_len = len; + } else { + *public_key_len = len; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + err = CRYPT_OK; + +LBL_ERR: + + XFREE(tmpbuf); + + return err; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c index e92f7c3..2b42ff4 100644 --- a/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c @@ -5,11 +5,8 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" -#include <stdarg.h> /** @@ -23,15 +20,16 @@ Encode a SEQUENCE @param list The list of items to encode @param inlen The number of items in the list - @param out [out] The destination + @param out [out] The destination @param outlen [in/out] The size of the output @param type_of LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF @return CRYPT_OK on success */ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, - unsigned char *out, unsigned long *outlen, int type_of) + unsigned char *out, unsigned long *outlen, int type_of) { - int err, type; + int err; + ltc_asn1_type type; unsigned long size, x, y, z, i; void *data; @@ -40,123 +38,8 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, LTC_ARGCHK(outlen != NULL); /* get size of output that will be required */ - y = 0; - for (i = 0; i < inlen; i++) { - type = list[i].type; - size = list[i].size; - data = list[i].data; - - if (type == LTC_ASN1_EOL) { - break; - } - - switch (type) { - case LTC_ASN1_BOOLEAN: - if ((err = der_length_boolean(&x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_INTEGER: - if ((err = der_length_integer(data, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_SHORT_INTEGER: - if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_BIT_STRING: - if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_OCTET_STRING: - if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_NULL: - y += 2; - break; - - case LTC_ASN1_OBJECT_IDENTIFIER: - if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_IA5_STRING: - if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_PRINTABLE_STRING: - if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_UTF8_STRING: - if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_UTCTIME: - if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_SET: - case LTC_ASN1_SETOF: - case LTC_ASN1_SEQUENCE: - if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - default: - err = CRYPT_INVALID_ARG; - goto LBL_ERR; - } - } - - /* calc header size */ - z = y; - if (y < 128) { - y += 2; - } else if (y < 256) { - /* 0x30 0x81 LL */ - y += 3; - } else if (y < 65536UL) { - /* 0x30 0x82 LL LL */ - y += 4; - } else if (y < 16777216UL) { - /* 0x30 0x83 LL LL LL */ - y += 5; - } else { - err = CRYPT_INVALID_ARG; - goto LBL_ERR; - } + y = 0; z = 0; + if ((err = der_length_sequence_ex(list, inlen, &y, &z)) != CRYPT_OK) return CRYPT_INVALID_ARG; /* too big ? */ if (*outlen < y) { @@ -168,7 +51,7 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, /* store header */ x = 0; out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31; - + if (z < 128) { out[x++] = (unsigned char)z; } else if (z < 256) { @@ -192,7 +75,7 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, size = list[i].size; data = list[i].data; - if (type == LTC_ASN1_EOL) { + if (type == LTC_ASN1_EOL) { break; } @@ -202,17 +85,13 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; break; - + case LTC_ASN1_INTEGER: z = *outlen; if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; break; case LTC_ASN1_SHORT_INTEGER: @@ -220,8 +99,6 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; break; case LTC_ASN1_BIT_STRING: @@ -229,8 +106,13 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; + break; + + case LTC_ASN1_RAW_BIT_STRING: + z = *outlen; + if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } break; case LTC_ASN1_OCTET_STRING: @@ -238,14 +120,12 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; break; case LTC_ASN1_NULL: - out[x++] = 0x05; - out[x++] = 0x00; - *outlen -= 2; + out[x] = 0x05; + out[x+1] = 0x00; + z = 2; break; case LTC_ASN1_OBJECT_IDENTIFIER: @@ -253,8 +133,6 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; break; case LTC_ASN1_IA5_STRING: @@ -262,17 +140,13 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; break; - + case LTC_ASN1_PRINTABLE_STRING: z = *outlen; if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; break; case LTC_ASN1_UTF8_STRING: @@ -280,8 +154,6 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; break; case LTC_ASN1_UTCTIME: @@ -289,8 +161,13 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; + break; + + case LTC_ASN1_GENERALIZEDTIME: + z = *outlen; + if ((err = der_encode_generalizedtime(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } break; case LTC_ASN1_SET: @@ -298,8 +175,6 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; break; case LTC_ASN1_SETOF: @@ -307,8 +182,6 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; break; case LTC_ASN1_SEQUENCE: @@ -316,20 +189,29 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - *outlen -= z; break; - - default: + + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: + case LTC_ASN1_TELETEX_STRING: err = CRYPT_INVALID_ARG; goto LBL_ERR; } + + x += z; + *outlen -= z; } *outlen = x; - err = CRYPT_OK; + err = CRYPT_OK; LBL_ERR: return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c index 659f029..c1b40c7 100644 --- a/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include <stdarg.h> @@ -25,10 +23,11 @@ @param outlen [in/out] Length of buffer and resulting length of output @remark <...> is of the form <type, size, data> (int, unsigned long, void*) @return CRYPT_OK on success -*/ +*/ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) { - int err, type; + int err; + ltc_asn1_type type; unsigned long size, x; void *data; va_list args; @@ -41,11 +40,13 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) va_start(args, outlen); x = 0; for (;;) { - type = va_arg(args, int); + type = (ltc_asn1_type)va_arg(args, int); size = va_arg(args, unsigned long); data = va_arg(args, void*); + LTC_UNUSED_PARAM(size); + LTC_UNUSED_PARAM(data); - if (type == LTC_ASN1_EOL) { + if (type == LTC_ASN1_EOL) { break; } @@ -64,10 +65,16 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) case LTC_ASN1_SEQUENCE: case LTC_ASN1_SET: case LTC_ASN1_SETOF: - ++x; + case LTC_ASN1_RAW_BIT_STRING: + case LTC_ASN1_GENERALIZEDTIME: + ++x; break; - - default: + + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: + case LTC_ASN1_TELETEX_STRING: va_end(args); return CRYPT_INVALID_ARG; } @@ -88,11 +95,11 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) va_start(args, outlen); x = 0; for (;;) { - type = va_arg(args, int); + type = (ltc_asn1_type)va_arg(args, int); size = va_arg(args, unsigned long); data = va_arg(args, void*); - if (type == LTC_ASN1_EOL) { + if (type == LTC_ASN1_EOL) { break; } @@ -111,12 +118,16 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) case LTC_ASN1_SEQUENCE: case LTC_ASN1_SET: case LTC_ASN1_SETOF: - list[x].type = type; - list[x].size = size; - list[x++].data = data; + case LTC_ASN1_RAW_BIT_STRING: + case LTC_ASN1_GENERALIZEDTIME: + LTC_SET_ASN1(list, x++, type, data, size); break; - - default: + + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: + case LTC_ASN1_TELETEX_STRING: va_end(args); err = CRYPT_INVALID_ARG; goto LBL_ERR; @@ -124,7 +135,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) } va_end(args); - err = der_encode_sequence(list, x, out, outlen); + err = der_encode_sequence(list, x, out, outlen); LBL_ERR: XFREE(list); return err; @@ -133,6 +144,6 @@ LBL_ERR: #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_encode_subject_public_key_info.c b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_subject_public_key_info.c new file mode 100644 index 0000000..dcb869a --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_subject_public_key_info.c @@ -0,0 +1,71 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" + +/** + @file der_encode_subject_public_key_info.c + ASN.1 DER, encode a Subject Public Key structure --nmav +*/ + +#ifdef LTC_DER + +/* AlgorithmIdentifier := SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm + * } + * + * SubjectPublicKeyInfo := SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + */ +/** + Encode a subject public key info + @param out The output buffer + @param outlen [in/out] Length of buffer and resulting length of output + @param algorithm One out of the enum #public_key_algorithms + @param public_key The buffer for the public key + @param public_key_len The length of the public key buffer + @param parameters_type The parameters' type out of the enum ltc_asn1_type + @param parameters The parameters to include + @param parameters_len The number of parameters to include + @return CRYPT_OK on success +*/ +int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, + unsigned int algorithm, void* public_key, unsigned long public_key_len, + unsigned long parameters_type, void* parameters, unsigned long parameters_len) +{ + int err; + ltc_asn1_list alg_id[2]; + oid_st oid; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + err = pk_get_oid(algorithm, &oid); + if (err != CRYPT_OK) { + return err; + } + + LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen); + LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, parameters_len); + + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id, + LTC_ASN1_RAW_BIT_STRING, public_key_len*8U, public_key, + LTC_ASN1_EOL, 0UL, NULL); + +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ + diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c b/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c index 7221f99..aed7cc2 100644 --- a/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -18,17 +16,24 @@ #ifdef LTC_DER /** - Get the length of a DER sequence + Get the length of a DER sequence @param list The sequences of items in the SEQUENCE @param inlen The number of items - @param outlen [out] The length required in octets to store it + @param outlen [out] The length required in octets to store it @return CRYPT_OK on success */ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, - unsigned long *outlen) + unsigned long *outlen) +{ + return der_length_sequence_ex(list, inlen, outlen, NULL); +} + +int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen, unsigned long *payloadlen) { - int err, type; - unsigned long size, x, y, z, i; + int err; + ltc_asn1_type type; + unsigned long size, x, y, i, z; void *data; LTC_ARGCHK(list != NULL); @@ -41,7 +46,7 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, size = list[i].size; data = list[i].data; - if (type == LTC_ASN1_EOL) { + if (type == LTC_ASN1_EOL) { break; } @@ -52,7 +57,7 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, } y += x; break; - + case LTC_ASN1_INTEGER: if ((err = der_length_integer(data, &x)) != CRYPT_OK) { goto LBL_ERR; @@ -68,6 +73,7 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, break; case LTC_ASN1_BIT_STRING: + case LTC_ASN1_RAW_BIT_STRING: if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { goto LBL_ERR; } @@ -99,6 +105,13 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, y += x; break; + case LTC_ASN1_TELETEX_STRING: + if ((err = der_length_teletex_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + case LTC_ASN1_PRINTABLE_STRING: if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; @@ -113,6 +126,13 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, y += x; break; + case LTC_ASN1_GENERALIZEDTIME: + if ((err = der_length_generalizedtime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + case LTC_ASN1_UTF8_STRING: if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; @@ -129,8 +149,11 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, y += x; break; - - default: + + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: err = CRYPT_INVALID_ARG; goto LBL_ERR; } @@ -155,6 +178,7 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, } /* store size */ + if (payloadlen) *payloadlen = z; *outlen = y; err = CRYPT_OK; @@ -164,6 +188,6 @@ LBL_ERR: #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c b/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c index c933f58..3c2a663 100644 --- a/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -20,11 +18,13 @@ /** Free memory allocated by der_decode_sequence_flexi() @param in The list to free -*/ +*/ void der_sequence_free(ltc_asn1_list *in) { ltc_asn1_list *l; - + + if (!in) return; + /* walk to the start of the chain */ while (in->prev != NULL || in->parent != NULL) { if (in->parent != NULL) { @@ -33,7 +33,7 @@ void der_sequence_free(ltc_asn1_list *in) in = in->prev; } } - + /* now walk the list and free stuff */ while (in != NULL) { /* is there a child? */ @@ -42,24 +42,22 @@ void der_sequence_free(ltc_asn1_list *in) in->child->parent = NULL; der_sequence_free(in->child); } - - switch (in->type) { - case LTC_ASN1_SET: - case LTC_ASN1_SETOF: - case LTC_ASN1_SEQUENCE: break; + + switch (in->type) { + case LTC_ASN1_SETOF: break; case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break; default : if (in->data != NULL) { XFREE(in->data); } } - + /* move to next and free current */ l = in->next; - free(in); + XFREE(in); in = l; - } + } } #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_shrink.c b/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_shrink.c new file mode 100644 index 0000000..9b9e036 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_shrink.c @@ -0,0 +1,50 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" + +/** + @file der_sequence_shrink.c + Free memory allocated for CONSTRUCTED, SET or SEQUENCE elements by der_decode_sequence_flexi(), Steffen Jaeckel +*/ + +#ifdef LTC_DER + +/** + Free memory allocated for CONSTRUCTED, + SET or SEQUENCE elements by der_decode_sequence_flexi() + @param in The list to shrink +*/ +void der_sequence_shrink(ltc_asn1_list *in) +{ + if (!in) return; + + /* now walk the list and free stuff */ + while (in != NULL) { + /* is there a child? */ + if (in->child) { + der_sequence_shrink(in->child); + } + + switch (in->type) { + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_SET: + case LTC_ASN1_SEQUENCE : if (in->data != NULL) { XFREE(in->data); in->data = NULL; } break; + default: break; + } + + /* move to next and free current */ + in = in->next; + } +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c b/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c index a2d0128..fef3092 100644 --- a/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c +++ b/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -18,35 +16,42 @@ #ifdef LTC_DER /* LTC define to ASN.1 TAG */ -static int ltc_to_asn1(int v) +static int _ltc_to_asn1(ltc_asn1_type v) { switch (v) { case LTC_ASN1_BOOLEAN: return 0x01; case LTC_ASN1_INTEGER: case LTC_ASN1_SHORT_INTEGER: return 0x02; + case LTC_ASN1_RAW_BIT_STRING: case LTC_ASN1_BIT_STRING: return 0x03; case LTC_ASN1_OCTET_STRING: return 0x04; case LTC_ASN1_NULL: return 0x05; case LTC_ASN1_OBJECT_IDENTIFIER: return 0x06; case LTC_ASN1_UTF8_STRING: return 0x0C; case LTC_ASN1_PRINTABLE_STRING: return 0x13; + case LTC_ASN1_TELETEX_STRING: return 0x14; case LTC_ASN1_IA5_STRING: return 0x16; case LTC_ASN1_UTCTIME: return 0x17; + case LTC_ASN1_GENERALIZEDTIME: return 0x18; case LTC_ASN1_SEQUENCE: return 0x30; case LTC_ASN1_SET: case LTC_ASN1_SETOF: return 0x31; - default: return -1; + case LTC_ASN1_CHOICE: + case LTC_ASN1_CONSTRUCTED: + case LTC_ASN1_CONTEXT_SPECIFIC: + case LTC_ASN1_EOL: return -1; } -} - + return -1; +} + -static int qsort_helper(const void *a, const void *b) +static int _qsort_helper(const void *a, const void *b) { ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b; int r; - - r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type); - + + r = _ltc_to_asn1(A->type) - _ltc_to_asn1(B->type); + /* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC. So we force it to be :-) */ if (r == 0) { /* their order in the original list now determines the position */ @@ -54,13 +59,13 @@ static int qsort_helper(const void *a, const void *b) } else { return r; } -} +} /* Encode a SET type @param list The list of items to encode @param inlen The number of items in the list - @param out [out] The destination + @param out [out] The destination @param outlen [in/out] The size of the output @return CRYPT_OK on success */ @@ -70,34 +75,34 @@ int der_encode_set(ltc_asn1_list *list, unsigned long inlen, ltc_asn1_list *copy; unsigned long x; int err; - + /* make copy of list */ copy = XCALLOC(inlen, sizeof(*copy)); if (copy == NULL) { return CRYPT_MEM; - } - + } + /* fill in used member with index so we can fully sort it */ for (x = 0; x < inlen; x++) { copy[x] = list[x]; copy[x].used = x; - } - + } + /* sort it by the "type" field */ - XQSORT(copy, inlen, sizeof(*copy), &qsort_helper); - + XQSORT(copy, inlen, sizeof(*copy), &_qsort_helper); + /* call der_encode_sequence_ex() */ - err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET); - + err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET); + /* free list */ XFREE(copy); - + return err; -} +} #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c b/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c index 8e87f84..b837cdd 100644 --- a/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c +++ b/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -22,15 +20,15 @@ struct edge { unsigned long size; }; -static int qsort_helper(const void *a, const void *b) +static int _qsort_helper(const void *a, const void *b) { struct edge *A = (struct edge *)a, *B = (struct edge *)b; int r; unsigned long x; - + /* compare min length */ r = XMEMCMP(A->start, B->start, MIN(A->size, B->size)); - + if (r == 0 && A->size != B->size) { if (A->size > B->size) { for (x = B->size; x < A->size; x++) { @@ -44,28 +42,29 @@ static int qsort_helper(const void *a, const void *b) return -1; } } - } + } } - - return r; + + return r; } /** Encode a SETOF stucture @param list The list of items to encode @param inlen The number of items in the list - @param out [out] The destination + @param out [out] The destination @param outlen [in/out] The size of the output @return CRYPT_OK on success -*/ +*/ int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen) { - unsigned long x, y, z, hdrlen; + unsigned long x, y, z; + ptrdiff_t hdrlen; int err; struct edge *edges; unsigned char *ptr, *buf; - + /* check that they're all the same type */ for (x = 1; x < inlen; x++) { if (list[x].type != list[x-1].type) { @@ -77,43 +76,43 @@ int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, buf = XCALLOC(1, *outlen); if (buf == NULL) { return CRYPT_MEM; - } - + } + /* encode list */ if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) { XFREE(buf); return err; } - + /* allocate edges */ edges = XCALLOC(inlen, sizeof(*edges)); if (edges == NULL) { XFREE(buf); return CRYPT_MEM; - } - + } + /* skip header */ - ptr = buf + 1; + ptr = buf + 1; + + /* now skip length data */ + x = *ptr++; + if (x >= 0x80) { + ptr += (x & 0x7F); + } + + /* get the size of the static header */ + hdrlen = ptr - buf; + - /* now skip length data */ - x = *ptr++; - if (x >= 0x80) { - ptr += (x & 0x7F); - } - - /* get the size of the static header */ - hdrlen = ((unsigned long)ptr) - ((unsigned long)buf); - - /* scan for edges */ x = 0; while (ptr < (buf + *outlen)) { /* store start */ edges[x].start = ptr; - + /* skip type */ z = 1; - + /* parse length */ y = ptr[z++]; if (y < 128) { @@ -125,38 +124,38 @@ int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]); } } - + /* skip content */ edges[x].size += z; ptr += edges[x].size; ++x; - } - + } + /* sort based on contents (using edges) */ - XQSORT(edges, inlen, sizeof(*edges), &qsort_helper); - + XQSORT(edges, inlen, sizeof(*edges), &_qsort_helper); + /* copy static header */ XMEMCPY(out, buf, hdrlen); - + /* copy+sort using edges+indecies to output from buffer */ - for (y = hdrlen, x = 0; x < inlen; x++) { + for (y = (unsigned long)hdrlen, x = 0; x < inlen; x++) { XMEMCPY(out+y, edges[x].start, edges[x].size); y += edges[x].size; - } - + } + #ifdef LTC_CLEAN_STACK zeromem(buf, *outlen); -#endif - +#endif + /* free buffers */ XFREE(edges); XFREE(buf); - + return CRYPT_OK; } #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c b/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c index a174740..71debf3 100644 --- a/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c +++ b/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -63,6 +61,6 @@ int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsig #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c b/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c index 903ceb4..ea413eb 100644 --- a/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c +++ b/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -26,10 +24,10 @@ @return CRYPT_OK if successful */ int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen) -{ +{ unsigned long len, x, y, z; int err; - + LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); @@ -86,12 +84,12 @@ int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned lon /* we good */ *outlen = x; - + return CRYPT_OK; } #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c b/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c index 0b8fdcf..52d0e1a 100644 --- a/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c +++ b/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -18,8 +16,8 @@ #ifdef LTC_DER /** - Gets length of DER encoding of num - @param num The integer to get the size of + Gets length of DER encoding of num + @param num The integer to get the size of @param outlen [out] The length of the DER encoding for the given integer @return CRYPT_OK if successful */ @@ -39,7 +37,7 @@ int der_length_short_integer(unsigned long num, unsigned long *outlen) ++z; y >>= 8; } - + /* handle zero */ if (z == 0) { z = 1; @@ -58,13 +56,13 @@ int der_length_short_integer(unsigned long num, unsigned long *outlen) len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; /* return length */ - *outlen = len; - + *outlen = len; + return CRYPT_OK; } #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/teletex_string/der_decode_teletex_string.c b/libtomcrypt/src/pk/asn1/der/teletex_string/der_decode_teletex_string.c new file mode 100644 index 0000000..0c7c3c8 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/teletex_string/der_decode_teletex_string.c @@ -0,0 +1,93 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" + +/** + @file der_decode_teletex_string.c + ASN.1 DER, encode a teletex STRING +*/ + +#ifdef LTC_DER + +/** + Store a teletex STRING + @param in The DER encoded teletex STRING + @param inlen The size of the DER teletex STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_teletex_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x14 */ + if ((in[0] & 0x1F) != 0x14) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_teletex_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/teletex_string/der_length_teletex_string.c b/libtomcrypt/src/pk/asn1/der/teletex_string/der_length_teletex_string.c new file mode 100644 index 0000000..29fe5b0 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/teletex_string/der_length_teletex_string.c @@ -0,0 +1,208 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" + +/** + @file der_length_teletex_string.c + ASN.1 DER, get length of teletex STRING +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} teletex_table[] = { +{ '\0', 0 }, +{ '\a', 7 }, +{ '\b', 8 }, +{ '\t', 9 }, +{ '\n', 10 }, +{ '\v', 11 }, +{ '\f', 12 }, +{ '\r', 13 }, +{ ' ', 32 }, +{ '!', 33 }, +{ '"', 34 }, +{ '%', 37 }, +{ '&', 38 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ ';', 59 }, +{ '<', 60 }, +{ '=', 61 }, +{ '>', 62 }, +{ '?', 63 }, +{ '@', 64 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ '[', 91 }, +{ ']', 93 }, +{ '_', 95 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +{ '|', 124 }, +{ ' ', 160 }, +{ 0xa1, 161 }, +{ 0xa2, 162 }, +{ 0xa3, 163 }, +{ '$', 164 }, +{ 0xa5, 165 }, +{ '#', 166 }, +{ 0xa7, 167 }, +{ 0xa4, 168 }, +{ 0xab, 171 }, +{ 0xb0, 176 }, +{ 0xb1, 177 }, +{ 0xb2, 178 }, +{ 0xb3, 179 }, +{ 0xd7, 180 }, +{ 0xb5, 181 }, +{ 0xb6, 182 }, +{ 0xb7, 183 }, +{ 0xf7, 184 }, +{ 0xbb, 187 }, +{ 0xbc, 188 }, +{ 0xbd, 189 }, +{ 0xbe, 190 }, +{ 0xbf, 191 }, +}; + +int der_teletex_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) { + if (teletex_table[x].code == c) { + return teletex_table[x].value; + } + } + return -1; +} + +int der_teletex_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) { + if (teletex_table[x].value == v) { + return teletex_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of teletex STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_teletex_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c b/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c index c86bc75..07fcb80 100644 --- a/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c +++ b/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -17,7 +15,7 @@ #ifdef LTC_DER -static int char_to_int(unsigned char x) +static int _char_to_int(unsigned char x) { switch (x) { case '0': return 0; @@ -30,12 +28,12 @@ static int char_to_int(unsigned char x) case '7': return 7; case '8': return 8; case '9': return 9; + default: return 100; } - return 100; } #define DECODE_V(y, max) \ - y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \ + y = _char_to_int(buf[x])*10 + _char_to_int(buf[x+1]); \ if (y >= max) return CRYPT_INVALID_PACKET; \ x += 2; @@ -49,7 +47,7 @@ static int char_to_int(unsigned char x) int der_decode_utctime(const unsigned char *in, unsigned long *inlen, ltc_utctime *out) { - unsigned char buf[32]; + unsigned char buf[32] = { 0 }; /* initialize as all zeroes */ unsigned long x; int y; @@ -73,7 +71,7 @@ int der_decode_utctime(const unsigned char *in, unsigned long *inlen, *inlen = 2 + x; - /* possible encodings are + /* possible encodings are YYMMDDhhmmZ YYMMDDhhmm+hh'mm' YYMMDDhhmm-hh'mm' @@ -81,7 +79,7 @@ YYMMDDhhmmssZ YYMMDDhhmmss+hh'mm' YYMMDDhhmmss-hh'mm' - So let's do a trivial decode upto [including] mm + So let's do a trivial decode upto [including] mm */ x = 0; @@ -122,6 +120,6 @@ YYMMDDhhmmss-hh'mm' #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c b/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c index f8d0c56..c6c8464 100644 --- a/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c +++ b/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -17,7 +15,7 @@ #ifdef LTC_DER -static const char *baseten = "0123456789"; +static const char * const baseten = "0123456789"; #define STORE_V(y) \ out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ @@ -30,12 +28,12 @@ static const char *baseten = "0123456789"; @param outlen [in/out] The length of the DER encoding @return CRYPT_OK if successful */ -int der_encode_utctime(ltc_utctime *utctime, +int der_encode_utctime(ltc_utctime *utctime, unsigned char *out, unsigned long *outlen) { unsigned long x, tmplen; int err; - + LTC_ARGCHK(utctime != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); @@ -47,7 +45,7 @@ int der_encode_utctime(ltc_utctime *utctime, *outlen = tmplen; return CRYPT_BUFFER_OVERFLOW; } - + /* store header */ out[0] = 0x17; @@ -70,7 +68,7 @@ int der_encode_utctime(ltc_utctime *utctime, /* store length */ out[1] = (unsigned char)(x - 2); - + /* all good let's return */ *outlen = x; return CRYPT_OK; @@ -78,6 +76,6 @@ int der_encode_utctime(ltc_utctime *utctime, #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c b/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c index e33c4f3..4202083 100644 --- a/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c +++ b/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -41,6 +39,6 @@ int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen) #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c b/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c index d9cbdaf..195a3f5 100644 --- a/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c +++ b/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -31,6 +29,7 @@ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, { wchar_t tmp; unsigned long x, y, z, len; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -73,10 +72,10 @@ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, for (y = 0; x < inlen; ) { /* get first byte */ tmp = in[x++]; - + /* count number of bytes */ for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF); - + if (z > 4 || (x + (z - 1) > inlen)) { return CRYPT_INVALID_PACKET; } @@ -93,19 +92,23 @@ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F); } - if (y > *outlen) { - *outlen = y; - return CRYPT_BUFFER_OVERFLOW; + if (y < *outlen) { + out[y] = tmp; } - out[y++] = tmp; + y++; + } + if (y > *outlen) { + err = CRYPT_BUFFER_OVERFLOW; + } else { + err = CRYPT_OK; } *outlen = y; - return CRYPT_OK; + return err; } - + #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c b/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c index 847a726..4c2030f 100644 --- a/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c +++ b/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -37,9 +35,7 @@ int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, /* get the size */ for (x = len = 0; x < inlen; x++) { - if (in[x] < 0 || in[x] > 0x1FFFF) { - return CRYPT_INVALID_ARG; - } + if (!der_utf8_valid_char(in[x])) return CRYPT_INVALID_ARG; len += der_utf8_charsize(in[x]); } @@ -57,7 +53,7 @@ int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, /* too big? */ if (y > *outlen) { - *outlen = len; + *outlen = y; return CRYPT_BUFFER_OVERFLOW; } @@ -79,6 +75,7 @@ int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, out[x++] = (unsigned char)((len>>8)&255); out[x++] = (unsigned char)(len&255); } else { + /* coverity[dead_error_line] */ return CRYPT_INVALID_ARG; } @@ -88,7 +85,9 @@ int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, case 1: out[x++] = (unsigned char)in[y]; break; case 2: out[x++] = 0xC0 | ((in[y] >> 6) & 0x1F); out[x++] = 0x80 | (in[y] & 0x3F); break; case 3: out[x++] = 0xE0 | ((in[y] >> 12) & 0x0F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; +#if !defined(LTC_WCHAR_MAX) || LTC_WCHAR_MAX > 0xFFFF case 4: out[x++] = 0xF0 | ((in[y] >> 18) & 0x07); out[x++] = 0x80 | ((in[y] >> 12) & 0x3F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; +#endif } } @@ -100,6 +99,6 @@ int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c b/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c index 3321f94..88f4355 100644 --- a/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c +++ b/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -27,15 +25,38 @@ unsigned long der_utf8_charsize(const wchar_t c) return 1; } else if (c <= 0x7FF) { return 2; +#if LTC_WCHAR_MAX == 0xFFFF + } else { + return 3; + } +#else } else if (c <= 0xFFFF) { return 3; } else { return 4; } +#endif +} + +/** + Test whether the given code point is valid character + @param c The UTF-8 character to test + @return 1 - valid, 0 - invalid +*/ +int der_utf8_valid_char(const wchar_t c) +{ + LTC_UNUSED_PARAM(c); +#if !defined(LTC_WCHAR_MAX) || LTC_WCHAR_MAX > 0xFFFF + if (c > 0x10FFFF) return 0; +#endif +#if LTC_WCHAR_MAX != 0xFFFF && LTC_WCHAR_MAX != 0xFFFFFFFF + if (c < 0) return 0; +#endif + return 1; } /** - Gets length of DER encoding of UTF8 STRING + Gets length of DER encoding of UTF8 STRING @param in The characters to measure the length of @param noctets The number of octets in the string to encode @param outlen [out] The length of the DER encoding for the given string @@ -50,9 +71,7 @@ int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned lo len = 0; for (x = 0; x < noctets; x++) { - if (in[x] < 0 || in[x] > 0x10FFFF) { - return CRYPT_INVALID_ARG; - } + if (!der_utf8_valid_char(in[x])) return CRYPT_INVALID_ARG; len += der_utf8_charsize(in[x]); } @@ -78,6 +97,6 @@ int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned lo #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ |