diff options
Diffstat (limited to 'libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c')
-rw-r--r-- | libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c | 89 |
1 files changed, 44 insertions, 45 deletions
diff --git a/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c b/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c index 8e87f84..b837cdd 100644 --- a/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c +++ b/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c @@ -5,8 +5,6 @@ * * The library is free for all purposes without any express * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" @@ -22,15 +20,15 @@ struct edge { unsigned long size; }; -static int qsort_helper(const void *a, const void *b) +static int _qsort_helper(const void *a, const void *b) { struct edge *A = (struct edge *)a, *B = (struct edge *)b; int r; unsigned long x; - + /* compare min length */ r = XMEMCMP(A->start, B->start, MIN(A->size, B->size)); - + if (r == 0 && A->size != B->size) { if (A->size > B->size) { for (x = B->size; x < A->size; x++) { @@ -44,28 +42,29 @@ static int qsort_helper(const void *a, const void *b) return -1; } } - } + } } - - return r; + + return r; } /** Encode a SETOF stucture @param list The list of items to encode @param inlen The number of items in the list - @param out [out] The destination + @param out [out] The destination @param outlen [in/out] The size of the output @return CRYPT_OK on success -*/ +*/ int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen) { - unsigned long x, y, z, hdrlen; + unsigned long x, y, z; + ptrdiff_t hdrlen; int err; struct edge *edges; unsigned char *ptr, *buf; - + /* check that they're all the same type */ for (x = 1; x < inlen; x++) { if (list[x].type != list[x-1].type) { @@ -77,43 +76,43 @@ int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, buf = XCALLOC(1, *outlen); if (buf == NULL) { return CRYPT_MEM; - } - + } + /* encode list */ if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) { XFREE(buf); return err; } - + /* allocate edges */ edges = XCALLOC(inlen, sizeof(*edges)); if (edges == NULL) { XFREE(buf); return CRYPT_MEM; - } - + } + /* skip header */ - ptr = buf + 1; + ptr = buf + 1; + + /* now skip length data */ + x = *ptr++; + if (x >= 0x80) { + ptr += (x & 0x7F); + } + + /* get the size of the static header */ + hdrlen = ptr - buf; + - /* now skip length data */ - x = *ptr++; - if (x >= 0x80) { - ptr += (x & 0x7F); - } - - /* get the size of the static header */ - hdrlen = ((unsigned long)ptr) - ((unsigned long)buf); - - /* scan for edges */ x = 0; while (ptr < (buf + *outlen)) { /* store start */ edges[x].start = ptr; - + /* skip type */ z = 1; - + /* parse length */ y = ptr[z++]; if (y < 128) { @@ -125,38 +124,38 @@ int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]); } } - + /* skip content */ edges[x].size += z; ptr += edges[x].size; ++x; - } - + } + /* sort based on contents (using edges) */ - XQSORT(edges, inlen, sizeof(*edges), &qsort_helper); - + XQSORT(edges, inlen, sizeof(*edges), &_qsort_helper); + /* copy static header */ XMEMCPY(out, buf, hdrlen); - + /* copy+sort using edges+indecies to output from buffer */ - for (y = hdrlen, x = 0; x < inlen; x++) { + for (y = (unsigned long)hdrlen, x = 0; x < inlen; x++) { XMEMCPY(out+y, edges[x].start, edges[x].size); y += edges[x].size; - } - + } + #ifdef LTC_CLEAN_STACK zeromem(buf, *outlen); -#endif - +#endif + /* free buffers */ XFREE(edges); XFREE(buf); - + return CRYPT_OK; } #endif -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ |