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

Side by Side Diff: nss/lib/certdb/certxutl.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/certdb/certxutl.h ('k') | nss/lib/certdb/crl.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 /*
6 * Certificate Extensions handling code
7 *
8 */
9
10 #include "cert.h"
11 #include "secitem.h"
12 #include "secoid.h"
13 #include "secder.h"
14 #include "secasn1.h"
15 #include "certxutl.h"
16 #include "secerr.h"
17
18 #ifdef OLD
19 #include "ocspti.h" /* XXX a better extensions interface would not
20 * require knowledge of data structures of callers */
21 #endif
22
23 static CERTCertExtension *
24 GetExtension(CERTCertExtension **extensions, SECItem *oid)
25 {
26 CERTCertExtension **exts;
27 CERTCertExtension *ext = NULL;
28 SECComparison comp;
29
30 exts = extensions;
31
32 if (exts) {
33 while (*exts) {
34 ext = *exts;
35 comp = SECITEM_CompareItem(oid, &ext->id);
36 if (comp == SECEqual)
37 break;
38
39 exts++;
40 }
41 return (*exts ? ext : NULL);
42 }
43 return (NULL);
44 }
45
46 SECStatus
47 cert_FindExtensionByOID(CERTCertExtension **extensions, SECItem *oid,
48 SECItem *value)
49 {
50 CERTCertExtension *ext;
51 SECStatus rv = SECSuccess;
52
53 ext = GetExtension(extensions, oid);
54 if (ext == NULL) {
55 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
56 return (SECFailure);
57 }
58 if (value)
59 rv = SECITEM_CopyItem(NULL, value, &ext->value);
60 return (rv);
61 }
62
63 SECStatus
64 CERT_GetExtenCriticality(CERTCertExtension **extensions, int tag,
65 PRBool *isCritical)
66 {
67 CERTCertExtension *ext;
68 SECOidData *oid;
69
70 if (!isCritical)
71 return (SECSuccess);
72
73 /* find the extension in the extensions list */
74 oid = SECOID_FindOIDByTag((SECOidTag)tag);
75 if (!oid) {
76 return (SECFailure);
77 }
78 ext = GetExtension(extensions, &oid->oid);
79 if (ext == NULL) {
80 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
81 return (SECFailure);
82 }
83
84 /* If the criticality is omitted, then it is false by default.
85 ex->critical.data is NULL */
86 if (ext->critical.data == NULL)
87 *isCritical = PR_FALSE;
88 else
89 *isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE;
90 return (SECSuccess);
91 }
92
93 SECStatus
94 cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value)
95 {
96 SECOidData *oid;
97
98 oid = SECOID_FindOIDByTag((SECOidTag)tag);
99 if (!oid) {
100 return (SECFailure);
101 }
102
103 return (cert_FindExtensionByOID(extensions, &oid->oid, value));
104 }
105
106 typedef struct _extNode {
107 struct _extNode *next;
108 CERTCertExtension *ext;
109 } extNode;
110
111 typedef struct {
112 void (*setExts)(void *object, CERTCertExtension **exts);
113 void *object;
114 PLArenaPool *ownerArena;
115 PLArenaPool *arena;
116 extNode *head;
117 int count;
118 } extRec;
119
120 /*
121 * cert_StartExtensions
122 *
123 * NOTE: This interface changed significantly to remove knowledge
124 * about callers data structures (owner objects)
125 */
126 void *
127 cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
128 void (*setExts)(void *object, CERTCertExtension **exts))
129 {
130 PLArenaPool *arena;
131 extRec *handle;
132
133 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
134 if (!arena) {
135 return (0);
136 }
137
138 handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec));
139 if (!handle) {
140 PORT_FreeArena(arena, PR_FALSE);
141 return (0);
142 }
143
144 handle->object = owner;
145 handle->ownerArena = ownerArena;
146 handle->setExts = setExts;
147
148 handle->arena = arena;
149 handle->head = 0;
150 handle->count = 0;
151
152 return (handle);
153 }
154
155 static unsigned char hextrue = 0xff;
156
157 /*
158 * Note - assumes that data pointed to by oid->data will not move
159 */
160 SECStatus
161 CERT_AddExtensionByOID(void *exthandle, SECItem *oid, SECItem *value,
162 PRBool critical, PRBool copyData)
163 {
164 CERTCertExtension *ext;
165 SECStatus rv;
166 extNode *node;
167 extRec *handle;
168
169 handle = (extRec *)exthandle;
170
171 /* allocate space for extension and list node */
172 ext = (CERTCertExtension *)PORT_ArenaZAlloc(handle->ownerArena,
173 sizeof(CERTCertExtension));
174 if (!ext) {
175 return (SECFailure);
176 }
177
178 node = (extNode *)PORT_ArenaAlloc(handle->arena, sizeof(extNode));
179 if (!node) {
180 return (SECFailure);
181 }
182
183 /* add to list */
184 node->next = handle->head;
185 handle->head = node;
186
187 /* point to ext struct */
188 node->ext = ext;
189
190 /* the object ID of the extension */
191 ext->id = *oid;
192
193 /* set critical field */
194 if (critical) {
195 ext->critical.data = (unsigned char *)&hextrue;
196 ext->critical.len = 1;
197 }
198
199 /* set the value */
200 if (copyData) {
201 rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value);
202 if (rv) {
203 return (SECFailure);
204 }
205 } else {
206 ext->value = *value;
207 }
208
209 handle->count++;
210
211 return (SECSuccess);
212 }
213
214 SECStatus
215 CERT_AddExtension(void *exthandle, int idtag, SECItem *value, PRBool critical,
216 PRBool copyData)
217 {
218 SECOidData *oid;
219
220 oid = SECOID_FindOIDByTag((SECOidTag)idtag);
221 if (!oid) {
222 return (SECFailure);
223 }
224
225 return (CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical,
226 copyData));
227 }
228
229 SECStatus
230 CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
231 PRBool critical, const SEC_ASN1Template *atemplate)
232 {
233 extRec *handle;
234 SECItem *encitem;
235
236 handle = (extRec *)exthandle;
237
238 encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate);
239 if (encitem == NULL) {
240 return (SECFailure);
241 }
242
243 return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE);
244 }
245
246 void
247 PrepareBitStringForEncoding(SECItem *bitsmap, SECItem *value)
248 {
249 unsigned char onebyte;
250 unsigned int i, len = 0;
251
252 /* to prevent warning on some platform at compile time */
253 onebyte = '\0';
254 /* Get the position of the right-most turn-on bit */
255 for (i = 0; i < (value->len) * 8; ++i) {
256 if (i % 8 == 0)
257 onebyte = value->data[i / 8];
258 if (onebyte & 0x80)
259 len = i;
260 onebyte <<= 1;
261 }
262 bitsmap->data = value->data;
263 /* Add one here since we work with base 1 */
264 bitsmap->len = len + 1;
265 }
266
267 SECStatus
268 CERT_EncodeAndAddBitStrExtension(void *exthandle, int idtag, SECItem *value,
269 PRBool critical)
270 {
271 SECItem bitsmap;
272
273 PrepareBitStringForEncoding(&bitsmap, value);
274 return (CERT_EncodeAndAddExtension(exthandle, idtag, &bitsmap, critical,
275 SEC_ASN1_GET(SEC_BitStringTemplate)));
276 }
277
278 SECStatus
279 CERT_FinishExtensions(void *exthandle)
280 {
281 extRec *handle;
282 extNode *node;
283 CERTCertExtension **exts;
284 SECStatus rv = SECFailure;
285
286 handle = (extRec *)exthandle;
287
288 /* allocate space for extensions array */
289 exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *,
290 handle->count + 1);
291 if (exts == NULL) {
292 goto loser;
293 }
294
295 /* put extensions in owner object and update its version number */
296
297 #ifdef OLD
298 switch (handle->type) {
299 case CertificateExtensions:
300 handle->owner.cert->extensions = exts;
301 DER_SetUInteger(ownerArena, &(handle->owner.cert->version),
302 SEC_CERTIFICATE_VERSION_3);
303 break;
304 case CrlExtensions:
305 handle->owner.crl->extensions = exts;
306 DER_SetUInteger(ownerArena, &(handle->owner.crl->version),
307 SEC_CRL_VERSION_2);
308 break;
309 case OCSPRequestExtensions:
310 handle->owner.request->tbsRequest->requestExtensions = exts;
311 break;
312 case OCSPSingleRequestExtensions:
313 handle->owner.singleRequest->singleRequestExtensions = exts;
314 break;
315 case OCSPResponseSingleExtensions:
316 handle->owner.singleResponse->singleExtensions = exts;
317 break;
318 }
319 #endif
320
321 handle->setExts(handle->object, exts);
322
323 /* update the version number */
324
325 /* copy each extension pointer */
326 node = handle->head;
327 while (node) {
328 *exts = node->ext;
329
330 node = node->next;
331 exts++;
332 }
333
334 /* terminate the array of extensions */
335 *exts = 0;
336
337 rv = SECSuccess;
338
339 loser:
340 /* free working arena */
341 PORT_FreeArena(handle->arena, PR_FALSE);
342 return rv;
343 }
344
345 SECStatus
346 CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
347 {
348 CERTCertExtension *ext;
349 SECStatus rv = SECSuccess;
350 SECOidTag tag;
351 extNode *node;
352 extRec *handle = exthandle;
353
354 if (!exthandle || !extensions) {
355 PORT_SetError(SEC_ERROR_INVALID_ARGS);
356 return SECFailure;
357 }
358 while ((ext = *extensions++) != NULL) {
359 tag = SECOID_FindOIDTag(&ext->id);
360 for (node = handle->head; node != NULL; node = node->next) {
361 if (tag == 0) {
362 if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id))
363 break;
364 } else {
365 if (SECOID_FindOIDTag(&node->ext->id) == tag) {
366 break;
367 }
368 }
369 }
370 if (node == NULL) {
371 PRBool critical = (ext->critical.len != 0 &&
372 ext->critical.data[ext->critical.len - 1] != 0);
373 if (critical && tag == SEC_OID_UNKNOWN) {
374 PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
375 rv = SECFailure;
376 break;
377 }
378 /* add to list */
379 rv = CERT_AddExtensionByOID(exthandle, &ext->id, &ext->value,
380 critical, PR_TRUE);
381 if (rv != SECSuccess)
382 break;
383 }
384 }
385 return rv;
386 }
387
388 /*
389 * get the value of the Netscape Certificate Type Extension
390 */
391 SECStatus
392 CERT_FindBitStringExtension(CERTCertExtension **extensions, int tag,
393 SECItem *retItem)
394 {
395 SECItem wrapperItem, tmpItem = { siBuffer, 0 };
396 SECStatus rv;
397 PLArenaPool *arena = NULL;
398
399 wrapperItem.data = NULL;
400 tmpItem.data = NULL;
401
402 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
403
404 if (!arena) {
405 return (SECFailure);
406 }
407
408 rv = cert_FindExtension(extensions, tag, &wrapperItem);
409 if (rv != SECSuccess) {
410 goto loser;
411 }
412
413 rv = SEC_QuickDERDecodeItem(
414 arena, &tmpItem, SEC_ASN1_GET(SEC_BitStringTemplate), &wrapperItem);
415
416 if (rv != SECSuccess) {
417 goto loser;
418 }
419
420 retItem->data = (unsigned char *)PORT_Alloc((tmpItem.len + 7) >> 3);
421 if (retItem->data == NULL) {
422 goto loser;
423 }
424
425 PORT_Memcpy(retItem->data, tmpItem.data, (tmpItem.len + 7) >> 3);
426 retItem->len = tmpItem.len;
427
428 rv = SECSuccess;
429 goto done;
430
431 loser:
432 rv = SECFailure;
433
434 done:
435 if (arena) {
436 PORT_FreeArena(arena, PR_FALSE);
437 }
438
439 if (wrapperItem.data) {
440 PORT_Free(wrapperItem.data);
441 }
442
443 return (rv);
444 }
445
446 PRBool
447 cert_HasCriticalExtension(CERTCertExtension **extensions)
448 {
449 CERTCertExtension **exts;
450 CERTCertExtension *ext = NULL;
451 PRBool hasCriticalExten = PR_FALSE;
452
453 exts = extensions;
454
455 if (exts) {
456 while (*exts) {
457 ext = *exts;
458 /* If the criticality is omitted, it's non-critical */
459 if (ext->critical.data && ext->critical.data[0] == 0xff) {
460 hasCriticalExten = PR_TRUE;
461 break;
462 }
463 exts++;
464 }
465 }
466 return (hasCriticalExten);
467 }
468
469 PRBool
470 cert_HasUnknownCriticalExten(CERTCertExtension **extensions)
471 {
472 CERTCertExtension **exts;
473 CERTCertExtension *ext = NULL;
474 PRBool hasUnknownCriticalExten = PR_FALSE;
475
476 exts = extensions;
477
478 if (exts) {
479 while (*exts) {
480 ext = *exts;
481 /* If the criticality is omitted, it's non-critical.
482 If an extension is critical, make sure that we know
483 how to process the extension.
484 */
485 if (ext->critical.data && ext->critical.data[0] == 0xff) {
486 if (SECOID_KnownCertExtenOID(&ext->id) == PR_FALSE) {
487 hasUnknownCriticalExten = PR_TRUE;
488 break;
489 }
490 }
491 exts++;
492 }
493 }
494 return (hasUnknownCriticalExten);
495 }
OLDNEW
« no previous file with comments | « nss/lib/certdb/certxutl.h ('k') | nss/lib/certdb/crl.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698