diff options
Diffstat (limited to 'libtomcrypt/src/pk/asn1')
40 files changed, 1599 insertions, 238 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 da5b989..1d3569c 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -51,7 +51,7 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, /* get the length of the data */ if (in[x] & 0x80) { /* long format get number of length bytes */ - y = in[x++] & 127; + y = in[x++] & 0x7F; /* invalid if 0 or > 2 */ if (y == 0 || y > 2) { @@ -65,7 +65,7 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, } } else { /* short format */ - dlen = in[x++] & 127; + dlen = in[x++] & 0x7F; } /* is the data len too long or too short? */ @@ -78,6 +78,7 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, /* too many bits? */ if (blen > *outlen) { + *outlen = blen; return CRYPT_BUFFER_OVERFLOW; } @@ -97,5 +98,5 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/06/16 21:53:41 $ */ 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 569c15b..757963c 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -29,7 +29,8 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { - unsigned long len, x, y, buf; + unsigned long len, x, y; + unsigned char buf; int err; LTC_ARGCHK(in != NULL); @@ -42,6 +43,7 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen, } if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } @@ -51,18 +53,18 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen, out[x++] = 0x03; if (y < 128) { - out[x++] = y; + out[x++] = (unsigned char)y; } else if (y < 256) { out[x++] = 0x81; - out[x++] = y; + out[x++] = (unsigned char)y; } else if (y < 65536) { out[x++] = 0x82; - out[x++] = (y>>8)&255; - out[x++] = y&255; + out[x++] = (unsigned char)((y>>8)&255); + out[x++] = (unsigned char)(y&255); } /* store number of zero padding bits */ - out[x++] = (8 - inlen) & 7; + out[x++] = (unsigned char)((8 - inlen) & 7); /* store the bits in big endian format */ for (y = buf = 0; y < inlen; y++) { @@ -83,5 +85,5 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen, #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/04 21:34:03 $ */ 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 dd6ea6d..3dc2abf 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -50,5 +50,5 @@ int der_length_bit_string(unsigned long nbits, unsigned long *outlen) /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2006/03/31 14:15:35 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c b/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c new file mode 100644 index 0000000..7259e51 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c @@ -0,0 +1,47 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file der_decode_boolean.c + ASN.1 DER, decode a BOOLEAN, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a BOOLEAN + @param in The destination for the DER encoded BOOLEAN + @param inlen The size of the DER BOOLEAN + @param out [out] The boolean to decode + @return CRYPT_OK if successful +*/ +int der_decode_boolean(const unsigned char *in, unsigned long inlen, + int *out) +{ + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + + 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: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2006/04/22 17:01:59 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c b/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c new file mode 100644 index 0000000..9344a79 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c @@ -0,0 +1,51 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file der_encode_boolean.c + ASN.1 DER, encode a BOOLEAN, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BOOLEAN + @param in The boolean to encode + @param out [out] The destination for the DER encoded BOOLEAN + @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, + 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: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/06/16 21:53:41 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c b/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c new file mode 100644 index 0000000..cd5bf2d --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c @@ -0,0 +1,35 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file der_length_boolean.c + ASN.1 DER, get length of a BOOLEAN, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of a BOOLEAN + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_length_boolean(unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + *outlen = 3; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2006/04/22 17:28:38 $ */ 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 61cba11..4ff6f17 100644 --- a/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c +++ b/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -96,6 +96,7 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, case LTC_ASN1_NULL: if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { *inlen = 2; + list[x].used = 1; return CRYPT_OK; } break; @@ -134,6 +135,17 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, } break; + case LTC_ASN1_UTF8_STRING: + if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_utf8_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + case LTC_ASN1_UTCTIME: z = *inlen; if (der_decode_utctime(in, &z, data) == CRYPT_OK) { @@ -143,6 +155,8 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, } break; + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) { if (der_length_sequence(data, size, &z) == CRYPT_OK) { @@ -164,5 +178,5 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen, #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2005/06/19 11:25:01 $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/06 02:23:49 $ */ 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 ac0a4af..2514b77 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -67,6 +67,7 @@ int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, /* is it too long? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } @@ -91,5 +92,5 @@ int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/06/16 21:53:41 $ */ 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 a79b46e..aff3392 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -42,6 +42,7 @@ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, /* too big? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } @@ -49,19 +50,19 @@ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, x = 0; out[x++] = 0x16; if (inlen < 128) { - out[x++] = inlen; + out[x++] = (unsigned char)inlen; } else if (inlen < 256) { out[x++] = 0x81; - out[x++] = inlen; + out[x++] = (unsigned char)inlen; } else if (inlen < 65536UL) { out[x++] = 0x82; - out[x++] = (inlen>>8)&255; - out[x++] = inlen&255; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); } else if (inlen < 16777216UL) { out[x++] = 0x83; - out[x++] = (inlen>>16)&255; - out[x++] = (inlen>>8)&255; - out[x++] = inlen&255; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); } else { return CRYPT_INVALID_ARG; } @@ -80,5 +81,5 @@ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/04 21:34:03 $ */ 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 d07d630..6278dd2 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -190,5 +190,5 @@ int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, un /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2006/03/31 14:15:35 $ */ 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 e68b2c9..aef87a3 100644 --- a/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c +++ b/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -25,7 +25,7 @@ @param num The first mp_int to decode @return CRYPT_OK if successful */ -int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num) +int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) { unsigned long x, y, z; int err; @@ -56,7 +56,7 @@ int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num } /* no so read it */ - if ((err = mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in + x, z))) != CRYPT_OK) { + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) { return err; } } else { @@ -80,23 +80,23 @@ int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num } /* no so read it */ - if ((err = mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in + x, y))) != CRYPT_OK) { + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) { return err; } } /* see if it's negative */ if (in[x] & 0x80) { - mp_int tmp; - if (mp_init(&tmp) != MP_OKAY) { + void *tmp; + if (mp_init(&tmp) != CRYPT_OK) { return CRYPT_MEM; } - if (mp_2expt(&tmp, mp_count_bits(num)) != MP_OKAY || mp_sub(num, &tmp, num) != MP_OKAY) { - mp_clear(&tmp); + if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) { + mp_clear(tmp); return CRYPT_MEM; } - mp_clear(&tmp); + mp_clear(tmp); } return CRYPT_OK; @@ -106,5 +106,5 @@ int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c,v $ */ -/* $Revision: 1.2 $ */ -/* $Date: 2005/06/01 00:06:05 $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/03/31 14:15:35 $ */ 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 f0f41be..ff4fce6 100644 --- a/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c +++ b/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -26,7 +26,7 @@ @param outlen [in/out] The max size and resulting size of the DER encoded integers @return CRYPT_OK if successful */ -int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) +int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) { unsigned long tmplen, y; int err, leading_zero; @@ -41,12 +41,13 @@ int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) } if (*outlen < tmplen) { + *outlen = tmplen; return CRYPT_BUFFER_OVERFLOW; } - if (mp_cmp_d(num, 0) != MP_LT) { + if (mp_cmp_d(num, 0) != LTC_MP_LT) { /* we only need a leading zero if the msb of the first byte is one */ - if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == MP_YES) { + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { leading_zero = 1; } else { leading_zero = 0; @@ -59,7 +60,7 @@ int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) y = mp_count_bits(num); y = y + (8 - (y & 7)); y = y >> 3; - + if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --y; } /* now store initial data */ @@ -69,16 +70,16 @@ int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) *out++ = (unsigned char)y; } else if (y < 256) { *out++ = 0x81; - *out++ = y; + *out++ = (unsigned char)y; } else if (y < 65536UL) { *out++ = 0x82; - *out++ = (y>>8)&255; - *out++ = y; + *out++ = (unsigned char)((y>>8)&255); + *out++ = (unsigned char)y; } else if (y < 16777216UL) { *out++ = 0x83; - *out++ = (y>>16)&255; - *out++ = (y>>8)&255; - *out++ = y; + *out++ = (unsigned char)((y>>16)&255); + *out++ = (unsigned char)((y>>8)&255); + *out++ = (unsigned char)y; } else { return CRYPT_INVALID_ARG; } @@ -89,31 +90,32 @@ int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) } /* if it's not zero store it as big endian */ - if (mp_cmp_d(num, 0) == MP_GT) { + if (mp_cmp_d(num, 0) == LTC_MP_GT) { /* now store the mpint */ - if ((err = mp_to_unsigned_bin(num, out)) != MP_OKAY) { - return mpi_to_ltc_error(err); + if ((err = mp_to_unsigned_bin(num, out)) != CRYPT_OK) { + return err; } - } else if (mp_iszero(num) != MP_YES) { - mp_int tmp; + } else if (mp_iszero(num) != LTC_MP_YES) { + void *tmp; + /* negative */ - if (mp_init(&tmp) != MP_OKAY) { + if (mp_init(&tmp) != CRYPT_OK) { return CRYPT_MEM; } /* 2^roundup and subtract */ y = mp_count_bits(num); y = y + (8 - (y & 7)); - if (mp_2expt(&tmp, y) != MP_OKAY || mp_add(&tmp, num, &tmp) != MP_OKAY) { - mp_clear(&tmp); + if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) y -= 8; + if (mp_2expt(tmp, y) != CRYPT_OK || mp_add(tmp, num, tmp) != CRYPT_OK) { + mp_clear(tmp); return CRYPT_MEM; } - - if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY) { - mp_clear(&tmp); - return mpi_to_ltc_error(err); + if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) { + mp_clear(tmp); + return err; } - mp_clear(&tmp); + mp_clear(tmp); } /* we good */ @@ -124,5 +126,5 @@ int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/04 21:34:03 $ */ 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 1bfee45..bcc331d 100644 --- a/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c +++ b/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -19,11 +19,11 @@ #ifdef LTC_DER /** Gets length of DER encoding of num - @param num The mp_int to get the size of + @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 */ -int der_length_integer(mp_int *num, unsigned long *outlen) +int der_length_integer(void *num, unsigned long *outlen) { unsigned long z, len; int leading_zero; @@ -31,11 +31,11 @@ int der_length_integer(mp_int *num, unsigned long *outlen) LTC_ARGCHK(num != NULL); LTC_ARGCHK(outlen != NULL); - if (mp_cmp_d(num, 0) != MP_LT) { + if (mp_cmp_d(num, 0) != LTC_MP_LT) { /* positive */ /* we only need a leading zero if the msb of the first byte is one */ - if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == MP_YES) { + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { leading_zero = 1; } else { leading_zero = 0; @@ -49,6 +49,7 @@ int der_length_integer(mp_int *num, unsigned long *outlen) 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; len = z = z >> 3; } @@ -77,5 +78,5 @@ int der_length_integer(mp_int *num, unsigned long *outlen) #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/04/22 01:22:55 $ */ 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 c69c9a3..1fa87d8 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -67,14 +67,8 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle return CRYPT_INVALID_PACKET; } - /* decode word1 and word2 */ - --len; - t = in[x++]; - words[0] = t/40; - words[1] = t%40; - - /* decode rest */ - y = 2; + /* decode words */ + y = 0; t = 0; while (len--) { t = (t << 7) | (in[x] & 0x7F); @@ -83,7 +77,13 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle if (y >= *outlen) { return CRYPT_BUFFER_OVERFLOW; } - words[y++] = t; + if (y == 0) { + words[0] = t / 40; + words[1] = t % 40; + y = 2; + } else { + words[y++] = t; + } t = 0; } } @@ -95,5 +95,5 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/11/21 00:18:23 $ */ 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 16eb112..b343aaa 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -27,7 +27,7 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords, unsigned char *out, unsigned long *outlen) { - unsigned long i, x, y, z, t, mask; + unsigned long i, x, y, z, t, mask, wordbuf; int err; LTC_ARGCHK(words != NULL); @@ -39,50 +39,54 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords, return err; } if (x > *outlen) { + *outlen = x; return CRYPT_BUFFER_OVERFLOW; } /* compute length to store OID data */ - z = 1; - for (y = 2; y < nwords; y++) { - t = der_object_identifier_bits(words[y]); - z += t/7 + ((t%7) ? 1 : 0); + z = 0; + wordbuf = words[0] * 40 + words[1]; + for (y = 1; y < nwords; y++) { + t = der_object_identifier_bits(wordbuf); + z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); + if (y < nwords - 1) { + wordbuf = words[y + 1]; + } } /* store header + length */ x = 0; out[x++] = 0x06; if (z < 128) { - out[x++] = z; + out[x++] = (unsigned char)z; } else if (z < 256) { out[x++] = 0x81; - out[x++] = z; + out[x++] = (unsigned char)z; } else if (z < 65536UL) { out[x++] = 0x82; - out[x++] = (z>>8)&255; - out[x++] = z&255; + out[x++] = (unsigned char)((z>>8)&255); + out[x++] = (unsigned char)(z&255); } else { return CRYPT_INVALID_ARG; } /* store first byte */ - out[x++] = words[0] * 40 + words[1]; - - for (i = 2; i < nwords; i++) { + wordbuf = words[0] * 40 + words[1]; + for (i = 1; i < nwords; i++) { /* store 7 bit words in little endian */ - t = words[i] & 0xFFFFFFFF; + t = wordbuf & 0xFFFFFFFF; if (t) { y = x; mask = 0; while (t) { - out[x++] = (t & 0x7F) | mask; + 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] = t; + t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t; ++y; --z; } @@ -90,6 +94,10 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords, /* zero word */ out[x++] = 0x00; } + + if (i < nwords - 1) { + wordbuf = words[i + 1]; + } } *outlen = x; @@ -99,5 +107,5 @@ int der_encode_object_identifier(unsigned long *words, unsigned long nwords, #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/04 21:34:03 $ */ 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 d03d1a7..a4cf53f 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -39,7 +39,7 @@ unsigned long der_object_identifier_bits(unsigned long x) */ int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen) { - unsigned long y, z, t; + unsigned long y, z, t, wordbuf; LTC_ARGCHK(words != NULL); LTC_ARGCHK(outlen != NULL); @@ -50,16 +50,21 @@ int der_length_object_identifier(unsigned long *words, unsigned long nwords, uns return CRYPT_INVALID_ARG; } - /* word1 = 0,1,2 and word2 0..39 */ - if (words[0] > 2 || words[1] > 39) { + /* word1 = 0,1,2,3 and word2 0..39 */ + if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) { return CRYPT_INVALID_ARG; } - /* leading byte of first two words */ - z = 1; - for (y = 2; y < nwords; y++) { - t = der_object_identifier_bits(words[y]); - z += t/7 + ((t%7) ? 1 : 0); + /* leading word is the first two */ + z = 0; + wordbuf = words[0] * 40 + words[1]; + for (y = 1; y < nwords; y++) { + t = der_object_identifier_bits(wordbuf); + z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); + if (y < nwords - 1) { + /* grab next word */ + wordbuf = words[y+1]; + } } /* now depending on the length our length encoding changes */ @@ -80,5 +85,5 @@ int der_length_object_identifier(unsigned long *words, unsigned long nwords, uns #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/04/16 20:17:42 $ */ 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 2d3800f..b937e63 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -66,6 +66,7 @@ int der_decode_octet_string(const unsigned char *in, unsigned long inlen, /* is it too long? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } @@ -86,5 +87,5 @@ int der_decode_octet_string(const unsigned char *in, unsigned long inlen, #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/06/16 21:53:41 $ */ 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 f34b708..fe0f163 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -43,6 +43,7 @@ int der_encode_octet_string(const unsigned char *in, unsigned long inlen, /* too big? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } @@ -50,19 +51,19 @@ int der_encode_octet_string(const unsigned char *in, unsigned long inlen, x = 0; out[x++] = 0x04; if (inlen < 128) { - out[x++] = inlen; + out[x++] = (unsigned char)inlen; } else if (inlen < 256) { out[x++] = 0x81; - out[x++] = inlen; + out[x++] = (unsigned char)inlen; } else if (inlen < 65536UL) { out[x++] = 0x82; - out[x++] = (inlen>>8)&255; - out[x++] = inlen&255; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); } else if (inlen < 16777216UL) { out[x++] = 0x83; - out[x++] = (inlen>>16)&255; - out[x++] = (inlen>>8)&255; - out[x++] = inlen&255; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); } else { return CRYPT_INVALID_ARG; } @@ -81,5 +82,5 @@ int der_encode_octet_string(const unsigned char *in, unsigned long inlen, #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/04 21:34:03 $ */ 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 9a0bed3..3caf352 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -49,5 +49,5 @@ int der_length_octet_string(unsigned long noctets, unsigned long *outlen) /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/16 15:08:11 $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2006/03/31 14:15:35 $ */ 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 cbc9239..cae96d8 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -67,6 +67,7 @@ int der_decode_printable_string(const unsigned char *in, unsigned long inlen, /* is it too long? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } @@ -91,5 +92,5 @@ int der_decode_printable_string(const unsigned char *in, unsigned long inlen, #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/21 02:29:54 $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/06/16 21:53:41 $ */ 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 ab4e8bf..9061b1f 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -42,6 +42,7 @@ int der_encode_printable_string(const unsigned char *in, unsigned long inlen, /* too big? */ if (len > *outlen) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } @@ -49,19 +50,19 @@ int der_encode_printable_string(const unsigned char *in, unsigned long inlen, x = 0; out[x++] = 0x13; if (inlen < 128) { - out[x++] = inlen; + out[x++] = (unsigned char)inlen; } else if (inlen < 256) { out[x++] = 0x81; - out[x++] = inlen; + out[x++] = (unsigned char)inlen; } else if (inlen < 65536UL) { out[x++] = 0x82; - out[x++] = (inlen>>8)&255; - out[x++] = inlen&255; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); } else if (inlen < 16777216UL) { out[x++] = 0x83; - out[x++] = (inlen>>16)&255; - out[x++] = (inlen>>8)&255; - out[x++] = inlen&255; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); } else { return CRYPT_INVALID_ARG; } @@ -80,5 +81,5 @@ int der_encode_printable_string(const unsigned char *in, unsigned long inlen, #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/21 02:29:54 $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/04 21:34:03 $ */ 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 34065f2..799b6b6 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -162,5 +162,5 @@ int der_length_printable_string(const unsigned char *octets, unsigned long nocte /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c,v $ */ -/* $Revision: 1.1 $ */ -/* $Date: 2005/05/21 02:29:54 $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2006/03/31 14:15:35 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence.c b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c index 335a882..1f65602 100644 --- a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence.c +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c @@ -6,14 +6,14 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" #include <stdarg.h> /** - @file der_decode_sequence.c + @file der_decode_sequence_ex.c ASN.1 DER, decode a SEQUENCE, Tom St Denis */ @@ -25,10 +25,11 @@ @param inlen The size of the input @param list The list of items to decode @param outlen The number of items in the list + @param ordered Search an unordeded or ordered list @return CRYPT_OK on success */ -int der_decode_sequence(const unsigned char *in, unsigned long inlen, - ltc_asn1_list *list, unsigned long outlen) +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; @@ -36,17 +37,18 @@ int der_decode_sequence(const unsigned char *in, unsigned long inlen, LTC_ARGCHK(in != NULL); LTC_ARGCHK(list != NULL); - + /* get blk size */ if (inlen < 2) { return CRYPT_INVALID_PACKET; } - /* sequence type? */ + /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */ x = 0; - if (in[x++] != 0x30) { + if (in[x] != 0x30 && in[x] != 0x31) { return CRYPT_INVALID_PACKET; } + ++x; if (in[x] < 128) { blksize = in[x++]; @@ -73,154 +75,205 @@ int der_decode_sequence(const unsigned char *in, unsigned long inlen, return CRYPT_INVALID_PACKET; } + /* mark all as unused */ + for (i = 0; i < outlen; i++) { + list[i].used = 0; + } + /* ok read data */ inlen = blksize; for (i = 0; i < 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) { break; } switch (type) { + case LTC_ASN1_BOOLEAN: + z = inlen; + if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = der_length_boolean(&z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + case LTC_ASN1_INTEGER: z = inlen; if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { + if (!ordered) { continue; } goto LBL_ERR; } if ((err = der_length_integer(data, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - inlen -= z; break; - case LTC_ASN1_SHORT_INTEGER: z = inlen; if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { + if (!ordered) { continue; } goto LBL_ERR; } - if ((err = der_length_short_integer(size, &z)) != CRYPT_OK) { + if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - inlen -= z; + break; case LTC_ASN1_BIT_STRING: z = inlen; if ((err = der_decode_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; } - x += z; - inlen -= z; break; case LTC_ASN1_OCTET_STRING: z = inlen; if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } goto LBL_ERR; } list[i].size = size; if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - inlen -= z; break; case LTC_ASN1_NULL: if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { + if (!ordered) { continue; } err = CRYPT_INVALID_PACKET; goto LBL_ERR; } - x += 2; - inlen -= 2; + z = 2; break; case LTC_ASN1_OBJECT_IDENTIFIER: z = inlen; if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } goto LBL_ERR; } list[i].size = size; if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - inlen -= z; break; case LTC_ASN1_IA5_STRING: z = inlen; if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } goto LBL_ERR; } list[i].size = size; if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - inlen -= z; break; case LTC_ASN1_PRINTABLE_STRING: z = inlen; if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } goto LBL_ERR; } list[i].size = size; if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - inlen -= z; + break; + + case LTC_ASN1_UTF8_STRING: + z = inlen; + if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } break; case LTC_ASN1_UTCTIME: z = inlen; if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) { + if (!ordered) { continue; } goto LBL_ERR; } - x += z; - inlen -= z; break; + case LTC_ASN1_SET: + z = inlen; + if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: + /* detect if we have the right type */ + if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + z = inlen; if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) { + if (!ordered) { continue; } goto LBL_ERR; } if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { goto LBL_ERR; } - x += z; - inlen -= z; break; case LTC_ASN1_CHOICE: z = inlen; if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) { + if (!ordered) { continue; } goto LBL_ERR; } - x += z; - inlen -= z; break; default: err = CRYPT_INVALID_ARG; goto LBL_ERR; } + x += z; + inlen -= z; + list[i].used = 1; + if (!ordered) { + /* restart the decoder */ + i = -1; + } } + + for (i = 0; i < outlen; i++) { + if (list[i].used == 0) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + } err = CRYPT_OK; LBL_ERR: @@ -229,6 +282,6 @@ LBL_ERR: #endif -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence.c,v $ */ -/* $Revision: 1.8 $ */ -/* $Date: 2005/06/18 19:20:23 $ */ +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c,v $ */ +/* $Revision: 1.15 $ */ +/* $Date: 2006/11/26 02:25:18 $ */ 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 new file mode 100644 index 0000000..19d8c86 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c @@ -0,0 +1,386 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file der_decode_sequence_flexi.c + ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis +*/ + +#ifdef LTC_DER + +static unsigned long fetch_length(const unsigned char *in, unsigned long inlen) +{ + unsigned long x, y, z; + + y = 0; + + /* skip type and read len */ + if (inlen < 2) { + return 0xFFFFFFFF; + } + ++in; ++y; + + /* read len */ + x = *in++; ++y; + + /* <128 means literal */ + if (x < 128) { + return x+y; + } + 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; + z = 0; + while (x--) { + z = (z<<8) | ((unsigned long)*in); + ++in; + } + return z+y; +} + +/** + 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 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; + void *realloc_tmp; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(out != NULL); + + l = NULL; + totlen = 0; + + /* scan the input and and get lengths and what not */ + while (*inlen) { + /* read the type byte */ + type = *in; + + /* fetch length */ + len = fetch_length(in, *inlen); + 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; + } + + /* 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; + } + break; + + case 0x02: /* INTEGER */ + /* init field */ + l->type = LTC_ASN1_INTEGER; + l->size = 1; + 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; + } + break; + + case 0x03: /* BIT */ + /* init field */ + l->type = LTC_ASN1_BIT_STRING; + l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */ + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + 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; + } + break; + + case 0x04: /* OCTET */ + + /* init field */ + l->type = LTC_ASN1_OCTET_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + 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; + + if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) { + 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 */ + break; + } + l->data = realloc_tmp; + break; + + case 0x0C: /* UTF8 */ + + /* init field */ + l->type = LTC_ASN1_UTF8_STRING; + l->size = len; + + if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) { + 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; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + 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 0x16: /* IA5 */ + + /* init field */ + l->type = LTC_ASN1_IA5_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + 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; + + if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) { + 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 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; + } + + /* 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; + + break; + default: + /* invalid byte ... this is a soft error */ + /* remove link */ + 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; + } + } + + /* return */ + *out = l; + *inlen = totlen; + return CRYPT_OK; + +error: + /* free list */ + der_sequence_free(l); + + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c,v $ */ +/* $Revision: 1.25 $ */ +/* $Date: 2006/11/26 02:25:18 $ */ 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 a4a1038..a15c182 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" #include <stdarg.h> @@ -19,6 +19,13 @@ #ifdef LTC_DER +/** + Decode a SEQUENCE type using a VA list + @param in Input buffer + @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; @@ -42,6 +49,7 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) } switch (type) { + case LTC_ASN1_BOOLEAN: case LTC_ASN1_INTEGER: case LTC_ASN1_SHORT_INTEGER: case LTC_ASN1_BIT_STRING: @@ -50,7 +58,10 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) case LTC_ASN1_OBJECT_IDENTIFIER: case LTC_ASN1_IA5_STRING: case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: case LTC_ASN1_UTCTIME: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: case LTC_ASN1_CHOICE: ++x; @@ -86,6 +97,7 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) } switch (type) { + case LTC_ASN1_BOOLEAN: case LTC_ASN1_INTEGER: case LTC_ASN1_SHORT_INTEGER: case LTC_ASN1_BIT_STRING: @@ -94,8 +106,11 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) case LTC_ASN1_OBJECT_IDENTIFIER: case LTC_ASN1_IA5_STRING: case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: case LTC_ASN1_UTCTIME: case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: case LTC_ASN1_CHOICE: list[x].type = type; list[x].size = size; @@ -120,5 +135,5 @@ LBL_ERR: /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2005/06/18 19:20:23 $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2006/11/26 02:25:18 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence.c b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c index d53153c..cdb4f1e 100644 --- a/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence.c +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c @@ -6,14 +6,14 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" #include <stdarg.h> /** - @file der_encode_sequence.c + @file der_encode_sequence_ex.c ASN.1 DER, encode a SEQUENCE, Tom St Denis */ @@ -25,10 +25,11 @@ @param inlen The number of items in the list @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(ltc_asn1_list *list, unsigned long inlen, - unsigned char *out, unsigned long *outlen) +int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int type_of) { int err, type; unsigned long size, x, y, z, i; @@ -50,6 +51,13 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, } 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; @@ -103,6 +111,13 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, 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; @@ -110,13 +125,14 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, 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; @@ -144,27 +160,29 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, /* too big ? */ if (*outlen < y) { + *outlen = y; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } /* store header */ x = 0; - out[x++] = 0x30; + out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31; + if (z < 128) { - out[x++] = z; + out[x++] = (unsigned char)z; } else if (z < 256) { out[x++] = 0x81; - out[x++] = z; + out[x++] = (unsigned char)z; } else if (z < 65536UL) { out[x++] = 0x82; - out[x++] = (z>>8UL)&255; - out[x++] = z&255; + out[x++] = (unsigned char)((z>>8UL)&255); + out[x++] = (unsigned char)(z&255); } else if (z < 16777216UL) { out[x++] = 0x83; - out[x++] = (z>>16UL)&255; - out[x++] = (z>>8UL)&255; - out[x++] = z&255; + out[x++] = (unsigned char)((z>>16UL)&255); + out[x++] = (unsigned char)((z>>8UL)&255); + out[x++] = (unsigned char)(z&255); } /* store data */ @@ -179,6 +197,15 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, } switch (type) { + case LTC_ASN1_BOOLEAN: + z = *outlen; + 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) { @@ -248,6 +275,15 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, *outlen -= z; break; + case LTC_ASN1_UTF8_STRING: + z = *outlen; + 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: z = *outlen; if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) { @@ -257,15 +293,33 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, *outlen -= z; break; - case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + z = *outlen; + if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SETOF: z = *outlen; - if ((err = der_encode_sequence(data, size, out + x, &z)) != CRYPT_OK) { + if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; + case LTC_ASN1_SEQUENCE: + z = *outlen; + if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + default: err = CRYPT_INVALID_ARG; goto LBL_ERR; 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 9ff48b9..da34c64 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" #include <stdarg.h> @@ -19,6 +19,13 @@ #ifdef LTC_DER +/** + Encode a SEQUENCE type using a VA list + @param out [out] Destination for data + @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; @@ -43,6 +50,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) } switch (type) { + case LTC_ASN1_BOOLEAN: case LTC_ASN1_INTEGER: case LTC_ASN1_SHORT_INTEGER: case LTC_ASN1_BIT_STRING: @@ -51,8 +59,11 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) case LTC_ASN1_OBJECT_IDENTIFIER: case LTC_ASN1_IA5_STRING: case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: case LTC_ASN1_UTCTIME: case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: ++x; break; @@ -86,6 +97,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) } switch (type) { + case LTC_ASN1_BOOLEAN: case LTC_ASN1_INTEGER: case LTC_ASN1_SHORT_INTEGER: case LTC_ASN1_BIT_STRING: @@ -94,8 +106,11 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) case LTC_ASN1_OBJECT_IDENTIFIER: case LTC_ASN1_IA5_STRING: case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: case LTC_ASN1_UTCTIME: case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: list[x].type = type; list[x].size = size; list[x++].data = data; @@ -119,5 +134,5 @@ LBL_ERR: /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2005/06/18 19:20:23 $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2006/11/26 02:25:18 $ */ 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 9120451..36f4a2a 100644 --- a/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c @@ -6,11 +6,9 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" -#include <stdarg.h> - /** @file der_length_sequence.c @@ -48,6 +46,13 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, } 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; @@ -101,6 +106,22 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, 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_UTF8_STRING: + if ((err = der_length_utf8_string(data, size, &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; @@ -142,3 +163,7 @@ LBL_ERR: } #endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2006/11/26 02:25:18 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c b/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c new file mode 100644 index 0000000..dc826e3 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c @@ -0,0 +1,65 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file der_sequence_free.c + ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis +*/ + +#ifdef LTC_DER + +/** + 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; + + /* walk to the start of the chain */ + while (in->prev != NULL || in->parent != NULL) { + if (in->parent != NULL) { + in = in->parent; + } else { + in = in->prev; + } + } + + /* now walk the list and free stuff */ + while (in != NULL) { + /* is there a child? */ + if (in->child) { + /* disconnect */ + 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; + 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); + in = l; + } +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/03/31 14:15:35 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c b/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c new file mode 100644 index 0000000..a08d2b0 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c @@ -0,0 +1,103 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file der_encode_set.c + ASN.1 DER, Encode a SET, Tom St Denis +*/ + +#ifdef LTC_DER + +/* LTC define to ASN.1 TAG */ +static int ltc_to_asn1(int v) +{ + switch (v) { + case LTC_ASN1_BOOLEAN: return 0x01; + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: return 0x02; + 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_IA5_STRING: return 0x16; + case LTC_ASN1_UTCTIME: return 0x17; + case LTC_ASN1_SEQUENCE: return 0x30; + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: return 0x31; + default: return -1; + } +} + + +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); + + /* 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 */ + return A->used - B->used; + } 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 outlen [in/out] The size of the output + @return CRYPT_OK on success +*/ +int der_encode_set(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + 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); + + /* call der_encode_sequence_ex() */ + err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET); + + /* free list */ + XFREE(copy); + + return err; +} + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2006/11/26 02:27:37 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c b/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c new file mode 100644 index 0000000..6c12eb4 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c @@ -0,0 +1,162 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file der_encode_setof.c + ASN.1 DER, Encode SET OF, Tom St Denis +*/ + +#ifdef LTC_DER + +struct edge { + unsigned char *start; + unsigned long size; +}; + +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++) { + if (A->start[x]) { + return 1; + } + } + } else { + for (x = A->size; x < B->size; x++) { + if (B->start[x]) { + return -1; + } + } + } + } + + 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 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; + 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) { + return CRYPT_INVALID_ARG; + } + } + + /* alloc buffer to store copy of output */ + 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; + + /* 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) { + edges[x].size = y; + } else { + y &= 0x7F; + edges[x].size = 0; + while (y--) { + 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); + + /* copy static header */ + XMEMCPY(out, buf, hdrlen); + + /* copy+sort using edges+indecies to output from buffer */ + for (y = 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 + + /* free buffers */ + XFREE(edges); + XFREE(buf); + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2006/03/31 14:15:35 $ */ 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 7d3d3b7..1407e9a 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -19,7 +19,7 @@ #ifdef LTC_DER /** - Read a mp_int integer + Read a short integer @param in The DER encoded data @param inlen Size of data @param num [out] The integer to decode @@ -64,5 +64,5 @@ int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsig #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2005/05/23 01:04:13 $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/03/31 14:15:35 $ */ 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 eb94d38..95da2fa 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -18,9 +18,8 @@ #ifdef LTC_DER -/* Exports a positive integer as DER format (upto 32-bits in size) */ /** - Store a mp_int integer + Store a short integer in the range (0,2^32-1) @param num The integer to encode @param out [out] The destination for the DER encoded integers @param outlen [in/out] The max size and resulting size of the DER encoded integers @@ -43,6 +42,7 @@ int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned lon } if (*outlen < len) { + *outlen = len; return CRYPT_BUFFER_OVERFLOW; } @@ -70,7 +70,7 @@ int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned lon /* store header */ x = 0; out[x++] = 0x02; - out[x++] = z; + out[x++] = (unsigned char)z; /* if 31st bit is set output a leading zero and decrement count */ if (z == 5) { @@ -80,7 +80,7 @@ int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned lon /* store values */ for (y = 0; y < z; y++) { - out[x++] = (num >> 24) & 0xFF; + out[x++] = (unsigned char)((num >> 24) & 0xFF); num <<= 8; } @@ -93,5 +93,5 @@ int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned lon #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c,v $ */ -/* $Revision: 1.3 $ */ -/* $Date: 2005/05/23 01:27:03 $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/04 21:34:03 $ */ 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 7324b4a..073e294 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 @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -39,7 +39,7 @@ int der_length_short_integer(unsigned long num, unsigned long *outlen) ++z; y >>= 8; } - + /* handle zero */ if (z == 0) { z = 1; @@ -59,11 +59,12 @@ int der_length_short_integer(unsigned long num, unsigned long *outlen) /* return length */ *outlen = len; + return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c,v $ */ -/* $Revision: 1.3 $ */ -/* $Date: 2005/05/23 01:35:38 $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/03/31 14:15:35 $ */ 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 43ba033..8a1f5fb 100644 --- a/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c +++ b/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -39,6 +39,13 @@ static int char_to_int(unsigned char x) if (y >= max) return CRYPT_INVALID_PACKET; \ x += 2; +/** + Decodes a UTC 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 UTC time structure + @return CRYPT_OK if successful +*/ int der_decode_utctime(const unsigned char *in, unsigned long *inlen, ltc_utctime *out) { @@ -116,5 +123,5 @@ YYMMDDhhmmss-hh'mm' #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2005/06/19 12:07:00 $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/03/31 14:15:35 $ */ 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 dad8c84..ae2ccbe 100644 --- a/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c +++ b/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -24,8 +24,10 @@ static const char *baseten = "0123456789"; out[x++] = der_ia5_char_encode(baseten[y % 10]); /** - Gets length of DER encoding of UTCTIME - @param outlen [out] The length of the DER encoding + Encodes a UTC time structure in DER format + @param utctime The UTC time structure to encode + @param out The destination of the DER encoding of the UTC time structure + @param outlen [in/out] The length of the DER encoding @return CRYPT_OK if successful */ int der_encode_utctime(ltc_utctime *utctime, @@ -42,6 +44,7 @@ int der_encode_utctime(ltc_utctime *utctime, return err; } if (tmplen > *outlen) { + *outlen = tmplen; return CRYPT_BUFFER_OVERFLOW; } @@ -66,7 +69,7 @@ int der_encode_utctime(ltc_utctime *utctime, } /* store length */ - out[1] = x - 2; + out[1] = (unsigned char)(x - 2); /* all good let's return */ *outlen = x; @@ -76,5 +79,5 @@ int der_encode_utctime(ltc_utctime *utctime, #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2005/06/19 12:07:00 $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/04 21:34:03 $ */ 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 84e654a..60f09de 100644 --- a/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c +++ b/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c @@ -6,7 +6,7 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" @@ -19,6 +19,7 @@ /** Gets length of DER encoding of UTCTIME + @param utctime The UTC time structure to get the size of @param outlen [out] The length of the DER encoding @return CRYPT_OK if successful */ @@ -41,5 +42,5 @@ int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen) #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c,v $ */ -/* $Revision: 1.2 $ */ -/* $Date: 2005/06/19 11:23:04 $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/03/31 14:15:35 $ */ 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 new file mode 100644 index 0000000..28b5520 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c @@ -0,0 +1,111 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file der_decode_utf8_string.c + ASN.1 DER, encode a UTF8 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a UTF8 STRING + @param in The DER encoded UTF8 STRING + @param inlen The size of the DER UTF8 STRING + @param out [out] The array of utf8s stored (one per char) + @param outlen [in/out] The number of utf8s stored + @return CRYPT_OK if successful +*/ +int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, + wchar_t *out, unsigned long *outlen) +{ + wchar_t tmp; + unsigned long x, y, z, len; + + 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 0x0C */ + if ((in[0] & 0x1F) != 0x0C) { + 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; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* proceed to decode */ + 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; + } + + /* decode, grab upper bits */ + tmp >>= z; + + /* grab remaining bytes */ + if (z > 1) { --z; } + while (z-- != 0) { + if ((in[x] & 0xC0) != 0x80) { + return CRYPT_INVALID_PACKET; + } + tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F); + } + + if (y > *outlen) { + *outlen = y; + return CRYPT_BUFFER_OVERFLOW; + } + out[y++] = tmp; + } + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/11/26 02:27:37 $ */ 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 new file mode 100644 index 0000000..2dd6081 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c @@ -0,0 +1,105 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file der_encode_utf8_string.c + ASN.1 DER, encode a UTF8 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store an UTF8 STRING + @param in The array of UTF8 to store (one per wchar_t) + @param inlen The number of UTF8 to store + @param out [out] The destination for the DER encoded UTF8 STRING + @param outlen [in/out] The max size and resulting size of the DER UTF8 STRING + @return CRYPT_OK if successful +*/ +int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + for (x = len = 0; x < inlen; x++) { + if (in[x] < 0 || in[x] > 0x1FFFF) { + return CRYPT_INVALID_ARG; + } + len += der_utf8_charsize(in[x]); + } + + if (len < 128) { + y = 2 + len; + } else if (len < 256) { + y = 3 + len; + } else if (len < 65536UL) { + y = 4 + len; + } else if (len < 16777216UL) { + y = 5 + len; + } else { + return CRYPT_INVALID_ARG; + } + + /* too big? */ + if (y > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x0C; + if (len < 128) { + out[x++] = len; + } else if (len < 256) { + out[x++] = 0x81; + out[x++] = len; + } else if (len < 65536UL) { + out[x++] = 0x82; + out[x++] = (len>>8)&255; + out[x++] = len&255; + } else if (len < 16777216UL) { + out[x++] = 0x83; + out[x++] = (len>>16)&255; + out[x++] = (len>>8)&255; + out[x++] = len&255; + } else { + return CRYPT_INVALID_ARG; + } + + /* store UTF8 */ + for (y = 0; y < inlen; y++) { + switch (der_utf8_charsize(in[y])) { + case 1: out[x++] = 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; + 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; + } + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/16 17:41:21 $ */ 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 new file mode 100644 index 0000000..b5b2bc6 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c @@ -0,0 +1,83 @@ +/* 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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com + */ +#include "tomcrypt.h" + +/** + @file der_length_utf8_string.c + ASN.1 DER, get length of UTF8 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** Return the size in bytes of a UTF-8 character + @param c The UTF-8 character to measure + @return The size in bytes +*/ +unsigned long der_utf8_charsize(const wchar_t c) +{ + if (c <= 0x7F) { + return 1; + } else if (c <= 0x7FF) { + return 2; + } else if (c <= 0xFFFF) { + return 3; + } else { + return 4; + } +} + +/** + 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 + @return CRYPT_OK if successful +*/ +int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(outlen != NULL); + + len = 0; + for (x = 0; x < noctets; x++) { + if (in[x] < 0 || in[x] > 0x10FFFF) { + return CRYPT_INVALID_ARG; + } + len += der_utf8_charsize(in[x]); + } + + if (len < 128) { + /* 0C LL DD DD DD ... */ + *outlen = 2 + len; + } else if (len < 256) { + /* 0C 81 LL DD DD DD ... */ + *outlen = 3 + len; + } else if (len < 65536UL) { + /* 0C 82 LL LL DD DD DD ... */ + *outlen = 4 + len; + } else if (len < 16777216UL) { + /* 0C 83 LL LL LL DD DD DD ... */ + *outlen = 5 + len; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/16 17:41:21 $ */ |