diff options
author | Matt Johnston <matt@ucc.asn.au> | 2007-01-11 02:41:05 +0000 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2007-01-11 02:41:05 +0000 |
commit | a938f4cfe140e8561d9dbf108b896492a662a893 (patch) | |
tree | f2a74322f959ff6a505ba5e87274ebe3d17d5e74 /libtomcrypt/src/pk/asn1/der/sequence | |
parent | 692d737a821c5e401c227d936b8f0d76b955650f (diff) | |
parent | 28ad393b008b34bc3cdbaa192440b8cc615329f0 (diff) |
propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 2af22fb4e878750b88f80f90d439b316d229796f)
to branch 'au.asn.ucc.matt.dropbear' (head 02c413252c90e9de8e03d91e9939dde3029f5c0a)
--HG--
extra : convert_revision : 52ccb0ad0587a62bc64aecb939adbb76546aac16
Diffstat (limited to 'libtomcrypt/src/pk/asn1/der/sequence')
-rw-r--r-- | libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c (renamed from libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence.c) | 121 | ||||
-rw-r--r-- | libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c | 386 | ||||
-rw-r--r-- | libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c | 21 | ||||
-rw-r--r-- | libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c (renamed from libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence.c) | 84 | ||||
-rw-r--r-- | libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c | 21 | ||||
-rw-r--r-- | libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c | 31 | ||||
-rw-r--r-- | libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c | 65 |
7 files changed, 671 insertions, 58 deletions
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 $ */ |