Mercurial > dropbear
comparison libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c @ 382:0cbe8f6dbf9e
propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 2af22fb4e878750b88f80f90d439b316d229796f)
to branch 'au.asn.ucc.matt.dropbear' (head 02c413252c90e9de8e03d91e9939dde3029f5c0a)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 11 Jan 2007 02:41:05 +0000 |
parents | |
children | f849a5ca2efc |
comparison
equal
deleted
inserted
replaced
379:b66a00272a90 | 382:0cbe8f6dbf9e |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 * | |
9 * Tom St Denis, [email protected], http://libtomcrypt.com | |
10 */ | |
11 #include "tomcrypt.h" | |
12 | |
13 /** | |
14 @file der_encode_setof.c | |
15 ASN.1 DER, Encode SET OF, Tom St Denis | |
16 */ | |
17 | |
18 #ifdef LTC_DER | |
19 | |
20 struct edge { | |
21 unsigned char *start; | |
22 unsigned long size; | |
23 }; | |
24 | |
25 static int qsort_helper(const void *a, const void *b) | |
26 { | |
27 struct edge *A = (struct edge *)a, *B = (struct edge *)b; | |
28 int r; | |
29 unsigned long x; | |
30 | |
31 /* compare min length */ | |
32 r = XMEMCMP(A->start, B->start, MIN(A->size, B->size)); | |
33 | |
34 if (r == 0 && A->size != B->size) { | |
35 if (A->size > B->size) { | |
36 for (x = B->size; x < A->size; x++) { | |
37 if (A->start[x]) { | |
38 return 1; | |
39 } | |
40 } | |
41 } else { | |
42 for (x = A->size; x < B->size; x++) { | |
43 if (B->start[x]) { | |
44 return -1; | |
45 } | |
46 } | |
47 } | |
48 } | |
49 | |
50 return r; | |
51 } | |
52 | |
53 /** | |
54 Encode a SETOF stucture | |
55 @param list The list of items to encode | |
56 @param inlen The number of items in the list | |
57 @param out [out] The destination | |
58 @param outlen [in/out] The size of the output | |
59 @return CRYPT_OK on success | |
60 */ | |
61 int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, | |
62 unsigned char *out, unsigned long *outlen) | |
63 { | |
64 unsigned long x, y, z, hdrlen; | |
65 int err; | |
66 struct edge *edges; | |
67 unsigned char *ptr, *buf; | |
68 | |
69 /* check that they're all the same type */ | |
70 for (x = 1; x < inlen; x++) { | |
71 if (list[x].type != list[x-1].type) { | |
72 return CRYPT_INVALID_ARG; | |
73 } | |
74 } | |
75 | |
76 /* alloc buffer to store copy of output */ | |
77 buf = XCALLOC(1, *outlen); | |
78 if (buf == NULL) { | |
79 return CRYPT_MEM; | |
80 } | |
81 | |
82 /* encode list */ | |
83 if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) { | |
84 XFREE(buf); | |
85 return err; | |
86 } | |
87 | |
88 /* allocate edges */ | |
89 edges = XCALLOC(inlen, sizeof(*edges)); | |
90 if (edges == NULL) { | |
91 XFREE(buf); | |
92 return CRYPT_MEM; | |
93 } | |
94 | |
95 /* skip header */ | |
96 ptr = buf + 1; | |
97 | |
98 /* now skip length data */ | |
99 x = *ptr++; | |
100 if (x >= 0x80) { | |
101 ptr += (x & 0x7F); | |
102 } | |
103 | |
104 /* get the size of the static header */ | |
105 hdrlen = ((unsigned long)ptr) - ((unsigned long)buf); | |
106 | |
107 | |
108 /* scan for edges */ | |
109 x = 0; | |
110 while (ptr < (buf + *outlen)) { | |
111 /* store start */ | |
112 edges[x].start = ptr; | |
113 | |
114 /* skip type */ | |
115 z = 1; | |
116 | |
117 /* parse length */ | |
118 y = ptr[z++]; | |
119 if (y < 128) { | |
120 edges[x].size = y; | |
121 } else { | |
122 y &= 0x7F; | |
123 edges[x].size = 0; | |
124 while (y--) { | |
125 edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]); | |
126 } | |
127 } | |
128 | |
129 /* skip content */ | |
130 edges[x].size += z; | |
131 ptr += edges[x].size; | |
132 ++x; | |
133 } | |
134 | |
135 /* sort based on contents (using edges) */ | |
136 XQSORT(edges, inlen, sizeof(*edges), &qsort_helper); | |
137 | |
138 /* copy static header */ | |
139 XMEMCPY(out, buf, hdrlen); | |
140 | |
141 /* copy+sort using edges+indecies to output from buffer */ | |
142 for (y = hdrlen, x = 0; x < inlen; x++) { | |
143 XMEMCPY(out+y, edges[x].start, edges[x].size); | |
144 y += edges[x].size; | |
145 } | |
146 | |
147 #ifdef LTC_CLEAN_STACK | |
148 zeromem(buf, *outlen); | |
149 #endif | |
150 | |
151 /* free buffers */ | |
152 XFREE(edges); | |
153 XFREE(buf); | |
154 | |
155 return CRYPT_OK; | |
156 } | |
157 | |
158 #endif | |
159 | |
160 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c,v $ */ | |
161 /* $Revision: 1.11 $ */ | |
162 /* $Date: 2006/03/31 14:15:35 $ */ |