1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
6 * The library is free for all purposes without any express
12 @file der_encode_setof.c
13 ASN.1 DER, Encode SET OF, Tom St Denis
23 static int _qsort_helper(const void *a, const void *b)
25 struct edge *A = (struct edge *)a, *B = (struct edge *)b;
29 /* compare min length */
30 r = XMEMCMP(A->start, B->start, MIN(A->size, B->size));
32 if (r == 0 && A->size != B->size) {
33 if (A->size > B->size) {
34 for (x = B->size; x < A->size; x++) {
40 for (x = A->size; x < B->size; x++) {
52 Encode a SETOF stucture
53 @param list The list of items to encode
54 @param inlen The number of items in the list
55 @param out [out] The destination
56 @param outlen [in/out] The size of the output
57 @return CRYPT_OK on success
59 int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
60 unsigned char *out, unsigned long *outlen)
62 unsigned long x, y, z;
66 unsigned char *ptr, *buf;
68 /* check that they're all the same type */
69 for (x = 1; x < inlen; x++) {
70 if (list[x].type != list[x-1].type) {
71 return CRYPT_INVALID_ARG;
75 /* alloc buffer to store copy of output */
76 buf = XCALLOC(1, *outlen);
82 if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) {
88 edges = XCALLOC(inlen, sizeof(*edges));
97 /* now skip length data */
103 /* get the size of the static header */
109 while (ptr < (buf + *outlen)) {
111 edges[x].start = ptr;
124 edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]);
130 ptr += edges[x].size;
134 /* sort based on contents (using edges) */
135 XQSORT(edges, inlen, sizeof(*edges), &_qsort_helper);
137 /* copy static header */
138 XMEMCPY(out, buf, hdrlen);
140 /* copy+sort using edges+indecies to output from buffer */
141 for (y = (unsigned long)hdrlen, x = 0; x < inlen; x++) {
142 XMEMCPY(out+y, edges[x].start, edges[x].size);
146 #ifdef LTC_CLEAN_STACK
147 zeromem(buf, *outlen);
159 /* ref: $Format:%D$ */
160 /* git commit: $Format:%H$ */
161 /* commit time: $Format:%ai$ */