Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(175)

Side by Side Diff: nss/lib/util/derenc.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nss/lib/util/derdec.c ('k') | nss/lib/util/dersubr.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include "secder.h"
6 #include "secerr.h"
7
8 #if 0
9 /*
10 * Generic templates for individual/simple items.
11 */
12
13 DERTemplate SECAnyTemplate[] = {
14 { DER_ANY,
15 0, NULL, sizeof(SECItem) }
16 };
17
18 DERTemplate SECBitStringTemplate[] = {
19 { DER_BIT_STRING,
20 0, NULL, sizeof(SECItem) }
21 };
22
23 DERTemplate SECBooleanTemplate[] = {
24 { DER_BOOLEAN,
25 0, NULL, sizeof(SECItem) }
26 };
27
28 DERTemplate SECIA5StringTemplate[] = {
29 { DER_IA5_STRING,
30 0, NULL, sizeof(SECItem) }
31 };
32
33 DERTemplate SECIntegerTemplate[] = {
34 { DER_INTEGER,
35 0, NULL, sizeof(SECItem) }
36 };
37
38 DERTemplate SECNullTemplate[] = {
39 { DER_NULL,
40 0, NULL, sizeof(SECItem) }
41 };
42
43 DERTemplate SECObjectIDTemplate[] = {
44 { DER_OBJECT_ID,
45 0, NULL, sizeof(SECItem) }
46 };
47
48 DERTemplate SECOctetStringTemplate[] = {
49 { DER_OCTET_STRING,
50 0, NULL, sizeof(SECItem) }
51 };
52
53 DERTemplate SECPrintableStringTemplate[] = {
54 { DER_PRINTABLE_STRING,
55 0, NULL, sizeof(SECItem) }
56 };
57
58 DERTemplate SECT61StringTemplate[] = {
59 { DER_T61_STRING,
60 0, NULL, sizeof(SECItem) }
61 };
62
63 DERTemplate SECUTCTimeTemplate[] = {
64 { DER_UTC_TIME,
65 0, NULL, sizeof(SECItem) }
66 };
67
68 #endif
69
70 static int
71 header_length(DERTemplate *dtemplate, PRUint32 contents_len)
72 {
73 PRUint32 len;
74 unsigned long encode_kind, under_kind;
75 PRBool explicit, optional, universal;
76
77 encode_kind = dtemplate->kind;
78
79 explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE;
80 optional = (encode_kind & DER_OPTIONAL) ? PR_TRUE : PR_FALSE;
81 universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
82 ? PR_TRUE : PR_FALSE;
83
84 PORT_Assert (!(explicit && universal)); /* bad templates */
85
86 if (encode_kind & DER_POINTER) {
87 if (dtemplate->sub != NULL) {
88 under_kind = dtemplate->sub->kind;
89 if (universal) {
90 encode_kind = under_kind;
91 }
92 } else if (universal) {
93 under_kind = encode_kind & ~DER_POINTER;
94 } else {
95 under_kind = dtemplate->arg;
96 }
97 } else if (encode_kind & DER_INLINE) {
98 PORT_Assert (dtemplate->sub != NULL);
99 under_kind = dtemplate->sub->kind;
100 if (universal) {
101 encode_kind = under_kind;
102 }
103 } else if (universal) {
104 under_kind = encode_kind;
105 } else {
106 under_kind = dtemplate->arg;
107 }
108
109 /* This is only used in decoding; it plays no part in encoding. */
110 if (under_kind & DER_DERPTR)
111 return 0;
112
113 /* No header at all for an "empty" optional. */
114 if ((contents_len == 0) && optional)
115 return 0;
116
117 /* And no header for a full DER_ANY. */
118 if (encode_kind & DER_ANY)
119 return 0;
120
121 /*
122 * The common case: one octet for identifier and as many octets
123 * as necessary to hold the content length.
124 */
125 len = 1 + DER_LengthLength(contents_len);
126
127 /* Account for the explicit wrapper, if necessary. */
128 if (explicit) {
129 #if 0 /*
130 * Well, I was trying to do something useful, but these
131 * assertions are too restrictive on valid templates.
132 * I wanted to make sure that the top-level "kind" of
133 * a template does not also specify DER_EXPLICIT, which
134 * should only modify a component field. Maybe later
135 * I can figure out a better way to detect such a problem,
136 * but for now I must remove these checks altogether.
137 */
138 /*
139 * This modifier applies only to components of a set or sequence;
140 * it should never be used on a set/sequence itself -- confirm.
141 */
142 PORT_Assert (under_kind != DER_SEQUENCE);
143 PORT_Assert (under_kind != DER_SET);
144 #endif
145
146 len += 1 + DER_LengthLength(len + contents_len);
147 }
148
149 return len;
150 }
151
152
153 static PRUint32
154 contents_length(DERTemplate *dtemplate, void *src)
155 {
156 PRUint32 len;
157 unsigned long encode_kind, under_kind;
158 PRBool universal;
159
160
161 PORT_Assert (src != NULL);
162
163 encode_kind = dtemplate->kind;
164
165 universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
166 ? PR_TRUE : PR_FALSE;
167 encode_kind &= ~DER_OPTIONAL;
168
169 if (encode_kind & DER_POINTER) {
170 src = *(void **)src;
171 if (src == NULL) {
172 return 0;
173 }
174 if (dtemplate->sub != NULL) {
175 dtemplate = dtemplate->sub;
176 under_kind = dtemplate->kind;
177 src = (void *)((char *)src + dtemplate->offset);
178 } else if (universal) {
179 under_kind = encode_kind & ~DER_POINTER;
180 } else {
181 under_kind = dtemplate->arg;
182 }
183 } else if (encode_kind & DER_INLINE) {
184 PORT_Assert (dtemplate->sub != NULL);
185 dtemplate = dtemplate->sub;
186 under_kind = dtemplate->kind;
187 src = (void *)((char *)src + dtemplate->offset);
188 } else if (universal) {
189 under_kind = encode_kind;
190 } else {
191 under_kind = dtemplate->arg;
192 }
193
194 /* Having any of these bits is not expected here... */
195 PORT_Assert ((under_kind & (DER_EXPLICIT | DER_INLINE | DER_OPTIONAL
196 | DER_POINTER | DER_SKIP)) == 0);
197
198 /* This is only used in decoding; it plays no part in encoding. */
199 if (under_kind & DER_DERPTR)
200 return 0;
201
202 if (under_kind & DER_INDEFINITE) {
203 PRUint32 sub_len;
204 void **indp = *(void ***)src;
205
206 if (indp == NULL)
207 return 0;
208
209 len = 0;
210 under_kind &= ~DER_INDEFINITE;
211
212 if (under_kind == DER_SET || under_kind == DER_SEQUENCE) {
213 DERTemplate *tmpt = dtemplate->sub;
214 PORT_Assert (tmpt != NULL);
215
216 for (; *indp != NULL; indp++) {
217 void *sub_src = (void *)((char *)(*indp) + tmpt->offset);
218 sub_len = contents_length (tmpt, sub_src);
219 len += sub_len + header_length (tmpt, sub_len);
220 }
221 } else {
222 /*
223 * XXX Lisa is not sure this code (for handling, for example,
224 * DER_INDEFINITE | DER_OCTET_STRING) is right.
225 */
226 for (; *indp != NULL; indp++) {
227 SECItem *item = (SECItem *)(*indp);
228 sub_len = item->len;
229 if (under_kind == DER_BIT_STRING) {
230 sub_len = (sub_len + 7) >> 3;
231 /* bit string contents involve an extra octet */
232 if (sub_len)
233 sub_len++;
234 }
235 if (under_kind != DER_ANY)
236 len += 1 + DER_LengthLength (sub_len);
237 }
238 }
239
240 return len;
241 }
242
243 switch (under_kind) {
244 case DER_SEQUENCE:
245 case DER_SET:
246 {
247 DERTemplate *tmpt;
248 void *sub_src;
249 PRUint32 sub_len;
250
251 len = 0;
252 for (tmpt = dtemplate + 1; tmpt->kind; tmpt++) {
253 sub_src = (void *)((char *)src + tmpt->offset);
254 sub_len = contents_length (tmpt, sub_src);
255 len += sub_len + header_length (tmpt, sub_len);
256 }
257 }
258 break;
259
260 case DER_BIT_STRING:
261 len = (((SECItem *)src)->len + 7) >> 3;
262 /* bit string contents involve an extra octet */
263 if (len)
264 len++;
265 break;
266
267 default:
268 len = ((SECItem *)src)->len;
269 break;
270 }
271
272 return len;
273 }
274
275
276 static unsigned char *
277 der_encode(unsigned char *buf, DERTemplate *dtemplate, void *src)
278 {
279 int header_len;
280 PRUint32 contents_len;
281 unsigned long encode_kind, under_kind;
282 PRBool explicit, universal;
283
284
285 /*
286 * First figure out how long the encoding will be. Do this by
287 * traversing the template from top to bottom and accumulating
288 * the length of each leaf item.
289 */
290 contents_len = contents_length (dtemplate, src);
291 header_len = header_length (dtemplate, contents_len);
292
293 /*
294 * Enough smarts was involved already, so that if both the
295 * header and the contents have a length of zero, then we
296 * are not doing any encoding for this element.
297 */
298 if (header_len == 0 && contents_len == 0)
299 return buf;
300
301 encode_kind = dtemplate->kind;
302
303 explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE;
304 encode_kind &= ~DER_OPTIONAL;
305 universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
306 ? PR_TRUE : PR_FALSE;
307
308 if (encode_kind & DER_POINTER) {
309 if (contents_len) {
310 src = *(void **)src;
311 PORT_Assert (src != NULL);
312 }
313 if (dtemplate->sub != NULL) {
314 dtemplate = dtemplate->sub;
315 under_kind = dtemplate->kind;
316 if (universal) {
317 encode_kind = under_kind;
318 }
319 src = (void *)((char *)src + dtemplate->offset);
320 } else if (universal) {
321 under_kind = encode_kind & ~DER_POINTER;
322 } else {
323 under_kind = dtemplate->arg;
324 }
325 } else if (encode_kind & DER_INLINE) {
326 dtemplate = dtemplate->sub;
327 under_kind = dtemplate->kind;
328 if (universal) {
329 encode_kind = under_kind;
330 }
331 src = (void *)((char *)src + dtemplate->offset);
332 } else if (universal) {
333 under_kind = encode_kind;
334 } else {
335 under_kind = dtemplate->arg;
336 }
337
338 if (explicit) {
339 buf = DER_StoreHeader (buf, encode_kind,
340 (1 + DER_LengthLength(contents_len)
341 + contents_len));
342 encode_kind = under_kind;
343 }
344
345 if ((encode_kind & DER_ANY) == 0) { /* DER_ANY already contains header */
346 buf = DER_StoreHeader (buf, encode_kind, contents_len);
347 }
348
349 /* If no real contents to encode, then we are done. */
350 if (contents_len == 0)
351 return buf;
352
353 if (under_kind & DER_INDEFINITE) {
354 void **indp;
355
356 indp = *(void ***)src;
357 PORT_Assert (indp != NULL);
358
359 under_kind &= ~DER_INDEFINITE;
360 if (under_kind == DER_SET || under_kind == DER_SEQUENCE) {
361 DERTemplate *tmpt = dtemplate->sub;
362 PORT_Assert (tmpt != NULL);
363 for (; *indp != NULL; indp++) {
364 void *sub_src = (void *)((char *)(*indp) + tmpt->offset);
365 buf = der_encode (buf, tmpt, sub_src);
366 }
367 } else {
368 for (; *indp != NULL; indp++) {
369 SECItem *item;
370 int sub_len;
371
372 item = (SECItem *)(*indp);
373 sub_len = item->len;
374 if (under_kind == DER_BIT_STRING) {
375 if (sub_len) {
376 int rem;
377
378 sub_len = (sub_len + 7) >> 3;
379 buf = DER_StoreHeader (buf, under_kind, sub_len + 1);
380 rem = (sub_len << 3) - item->len;
381 *buf++ = rem; /* remaining bits */
382 } else {
383 buf = DER_StoreHeader (buf, under_kind, 0);
384 }
385 } else if (under_kind != DER_ANY) {
386 buf = DER_StoreHeader (buf, under_kind, sub_len);
387 }
388 PORT_Memcpy (buf, item->data, sub_len);
389 buf += sub_len;
390 }
391 }
392 return buf;
393 }
394
395 switch (under_kind) {
396 case DER_SEQUENCE:
397 case DER_SET:
398 {
399 DERTemplate *tmpt;
400 void *sub_src;
401
402 for (tmpt = dtemplate + 1; tmpt->kind; tmpt++) {
403 sub_src = (void *)((char *)src + tmpt->offset);
404 buf = der_encode (buf, tmpt, sub_src);
405 }
406 }
407 break;
408
409 case DER_BIT_STRING:
410 {
411 SECItem *item;
412 int rem;
413
414 /*
415 * The contents length includes our extra octet; subtract
416 * it off so we just have the real string length there.
417 */
418 contents_len--;
419 item = (SECItem *)src;
420 PORT_Assert (contents_len == ((item->len + 7) >> 3));
421 rem = (contents_len << 3) - item->len;
422 *buf++ = rem; /* remaining bits */
423 PORT_Memcpy (buf, item->data, contents_len);
424 buf += contents_len;
425 }
426 break;
427
428 default:
429 {
430 SECItem *item;
431
432 item = (SECItem *)src;
433 PORT_Assert (contents_len == item->len);
434 PORT_Memcpy (buf, item->data, contents_len);
435 buf += contents_len;
436 }
437 break;
438 }
439
440 return buf;
441 }
442
443
444 SECStatus
445 DER_Encode(PLArenaPool *arena, SECItem *dest, DERTemplate *dtemplate, void *src)
446 {
447 unsigned int contents_len, header_len;
448
449 src = (void **)((char *)src + dtemplate->offset);
450
451 /*
452 * First figure out how long the encoding will be. Do this by
453 * traversing the template from top to bottom and accumulating
454 * the length of each leaf item.
455 */
456 contents_len = contents_length (dtemplate, src);
457 header_len = header_length (dtemplate, contents_len);
458
459 dest->len = contents_len + header_len;
460
461 /* Allocate storage to hold the encoding */
462 dest->data = (unsigned char*) PORT_ArenaAlloc(arena, dest->len);
463 if (dest->data == NULL) {
464 PORT_SetError(SEC_ERROR_NO_MEMORY);
465 return SECFailure;
466 }
467
468 /* Now encode into the buffer */
469 (void) der_encode (dest->data, dtemplate, src);
470
471 return SECSuccess;
472 }
OLDNEW
« no previous file with comments | « nss/lib/util/derdec.c ('k') | nss/lib/util/dersubr.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698