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

Side by Side Diff: nss/lib/pk11wrap/pk11nobj.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/pk11wrap/pk11merge.c ('k') | nss/lib/pk11wrap/pk11obj.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 * This file manages Netscape specific PKCS #11 objects (CRLs, Trust objects,
6 * etc).
7 */
8
9 #include "secport.h"
10 #include "seccomon.h"
11 #include "secmod.h"
12 #include "secmodi.h"
13 #include "secmodti.h"
14 #include "pkcs11.h"
15 #include "pk11func.h"
16 #include "cert.h"
17 #include "certi.h"
18 #include "secitem.h"
19 #include "sechash.h"
20 #include "secoid.h"
21
22 #include "certdb.h"
23 #include "secerr.h"
24
25 #include "pki3hack.h"
26 #include "dev3hack.h"
27
28 #include "devm.h"
29 #include "pki.h"
30 #include "pkim.h"
31
32 extern const NSSError NSS_ERROR_NOT_FOUND;
33
34 CK_TRUST
35 pk11_GetTrustField(PK11SlotInfo *slot, PLArenaPool *arena,
36 CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type)
37 {
38 CK_TRUST rv = 0;
39 SECItem item;
40
41 item.data = NULL;
42 item.len = 0;
43
44 if( SECSuccess == PK11_ReadAttribute(slot, id, type, arena, &item) ) {
45 PORT_Assert(item.len == sizeof(CK_TRUST));
46 PORT_Memcpy(&rv, item.data, sizeof(CK_TRUST));
47 /* Damn, is there an endian problem here? */
48 return rv;
49 }
50
51 return 0;
52 }
53
54 PRBool
55 pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust *trust)
56 {
57 PLArenaPool *arena;
58
59 CK_ATTRIBUTE tobjTemplate[] = {
60 { CKA_CLASS, NULL, 0 },
61 { CKA_CERT_SHA1_HASH, NULL, 0 },
62 };
63
64 CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
65 CK_OBJECT_HANDLE tobjID;
66 unsigned char sha1_hash[SHA1_LENGTH];
67
68 CK_TRUST serverAuth, codeSigning, emailProtection, clientAuth;
69
70 PK11_HashBuf(SEC_OID_SHA1, sha1_hash, cert->derCert.data, cert->derCert.len);
71
72 PK11_SETATTRS(&tobjTemplate[0], CKA_CLASS, &tobjc, sizeof(tobjc));
73 PK11_SETATTRS(&tobjTemplate[1], CKA_CERT_SHA1_HASH, sha1_hash,
74 SHA1_LENGTH);
75
76 tobjID = pk11_FindObjectByTemplate(slot, tobjTemplate,
77 sizeof(tobjTemplate)/sizeof(tobjTemplate[0] ));
78 if( CK_INVALID_HANDLE == tobjID ) {
79 return PR_FALSE;
80 }
81
82 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
83 if( NULL == arena ) return PR_FALSE;
84
85 /* Unfortunately, it seems that PK11_GetAttributes doesn't deal
86 * well with nonexistent attributes. I guess we have to check
87 * the trust info fields one at a time.
88 */
89
90 /* We could verify CKA_CERT_HASH here */
91
92 /* We could verify CKA_EXPIRES here */
93
94
95 /* "Purpose" trust information */
96 serverAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_SERVER_AUTH);
97 clientAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CLIENT_AUTH);
98 codeSigning = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CODE_SIGNING);
99 emailProtection = pk11_GetTrustField(slot, arena, tobjID,
100 CKA_TRUST_EMAIL_PROTECTION);
101 /* Here's where the fun logic happens. We have to map back from the
102 * key usage, extended key usage, purpose, and possibly other trust values
103 * into the old trust-flags bits. */
104
105 /* First implementation: keep it simple for testing. We can study what other
106 * mappings would be appropriate and add them later.. fgmr 20000724 */
107
108 if ( serverAuth == CKT_NSS_TRUSTED ) {
109 trust->sslFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
110 }
111
112 if ( serverAuth == CKT_NSS_TRUSTED_DELEGATOR ) {
113 trust->sslFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA |
114 CERTDB_NS_TRUSTED_CA;
115 }
116 if ( clientAuth == CKT_NSS_TRUSTED_DELEGATOR ) {
117 trust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA ;
118 }
119
120 if ( emailProtection == CKT_NSS_TRUSTED ) {
121 trust->emailFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
122 }
123
124 if ( emailProtection == CKT_NSS_TRUSTED_DELEGATOR ) {
125 trust->emailFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED _CA;
126 }
127
128 if( codeSigning == CKT_NSS_TRUSTED ) {
129 trust->objectSigningFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
130 }
131
132 if( codeSigning == CKT_NSS_TRUSTED_DELEGATOR ) {
133 trust->objectSigningFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS _TRUSTED_CA;
134 }
135
136 /* There's certainly a lot more logic that can go here.. */
137
138 PORT_FreeArena(arena, PR_FALSE);
139
140 return PR_TRUE;
141 }
142
143 static SECStatus
144 pk11_CollectCrls(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
145 {
146 SECItem derCrl;
147 CERTCrlHeadNode *head = (CERTCrlHeadNode *) arg;
148 CERTCrlNode *new_node = NULL;
149 CK_ATTRIBUTE fetchCrl[3] = {
150 { CKA_VALUE, NULL, 0},
151 { CKA_NETSCAPE_KRL, NULL, 0},
152 { CKA_NETSCAPE_URL, NULL, 0},
153 };
154 const int fetchCrlSize = sizeof(fetchCrl)/sizeof(fetchCrl[2]);
155 CK_RV crv;
156 SECStatus rv = SECFailure;
157
158 crv = PK11_GetAttributes(head->arena,slot,crlID,fetchCrl,fetchCrlSize);
159 if (CKR_OK != crv) {
160 PORT_SetError(PK11_MapError(crv));
161 goto loser;
162 }
163
164 if (!fetchCrl[1].pValue) {
165 PORT_SetError(SEC_ERROR_CRL_INVALID);
166 goto loser;
167 }
168
169 new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena, sizeof(CERTCrlNode));
170 if (new_node == NULL) {
171 goto loser;
172 }
173
174 if (*((CK_BBOOL *)fetchCrl[1].pValue))
175 new_node->type = SEC_KRL_TYPE;
176 else
177 new_node->type = SEC_CRL_TYPE;
178
179 derCrl.type = siBuffer;
180 derCrl.data = (unsigned char *)fetchCrl[0].pValue;
181 derCrl.len = fetchCrl[0].ulValueLen;
182 new_node->crl=CERT_DecodeDERCrl(head->arena,&derCrl,new_node->type);
183 if (new_node->crl == NULL) {
184 goto loser;
185 }
186
187 if (fetchCrl[2].pValue) {
188 int nnlen = fetchCrl[2].ulValueLen;
189 new_node->crl->url = (char *)PORT_ArenaAlloc(head->arena, nnlen+1);
190 if ( !new_node->crl->url ) {
191 goto loser;
192 }
193 PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen);
194 new_node->crl->url[nnlen] = 0;
195 } else {
196 new_node->crl->url = NULL;
197 }
198
199
200 new_node->next = NULL;
201 if (head->last) {
202 head->last->next = new_node;
203 head->last = new_node;
204 } else {
205 head->first = head->last = new_node;
206 }
207 rv = SECSuccess;
208
209 loser:
210 return(rv);
211 }
212
213 /*
214 * Return a list of all the CRLs .
215 * CRLs are allocated in the list's arena.
216 */
217 SECStatus
218 PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx) {
219 pk11TraverseSlot creater;
220 CK_ATTRIBUTE theTemplate[2];
221 CK_ATTRIBUTE *attrs;
222 CK_OBJECT_CLASS certClass = CKO_NETSCAPE_CRL;
223 CK_BBOOL isKrl = CK_FALSE;
224
225 attrs = theTemplate;
226 PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); attrs++;
227 if (type != -1) {
228 isKrl = (CK_BBOOL) (type == SEC_KRL_TYPE);
229 PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, &isKrl, sizeof(isKrl)); attrs++;
230 }
231
232 creater.callback = pk11_CollectCrls;
233 creater.callbackArg = (void *) nodes;
234 creater.findTemplate = theTemplate;
235 creater.templateCount = (attrs - theTemplate);
236
237 return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx);
238 }
239
240 struct crlOptionsStr {
241 CERTCrlHeadNode* head;
242 PRInt32 decodeOptions;
243 };
244
245 typedef struct crlOptionsStr crlOptions;
246
247 static SECStatus
248 pk11_RetrieveCrlsCallback(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID,
249 void *arg)
250 {
251 SECItem* derCrl = NULL;
252 crlOptions* options = (crlOptions*) arg;
253 CERTCrlHeadNode *head = options->head;
254 CERTCrlNode *new_node = NULL;
255 CK_ATTRIBUTE fetchCrl[3] = {
256 { CKA_VALUE, NULL, 0},
257 { CKA_NETSCAPE_KRL, NULL, 0},
258 { CKA_NETSCAPE_URL, NULL, 0},
259 };
260 const int fetchCrlSize = sizeof(fetchCrl)/sizeof(fetchCrl[2]);
261 CK_RV crv;
262 SECStatus rv = SECFailure;
263 PRBool adopted = PR_FALSE; /* whether the CRL adopted the DER memory
264 successfully */
265 int i;
266
267 crv = PK11_GetAttributes(NULL,slot,crlID,fetchCrl,fetchCrlSize);
268 if (CKR_OK != crv) {
269 PORT_SetError(PK11_MapError(crv));
270 goto loser;
271 }
272
273 if (!fetchCrl[1].pValue) {
274 /* reject KRLs */
275 PORT_SetError(SEC_ERROR_CRL_INVALID);
276 goto loser;
277 }
278
279 new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena,
280 sizeof(CERTCrlNode));
281 if (new_node == NULL) {
282 goto loser;
283 }
284
285 new_node->type = SEC_CRL_TYPE;
286
287 derCrl = SECITEM_AllocItem(NULL, NULL, 0);
288 if (!derCrl) {
289 goto loser;
290 }
291 derCrl->type = siBuffer;
292 derCrl->data = (unsigned char *)fetchCrl[0].pValue;
293 derCrl->len = fetchCrl[0].ulValueLen;
294 new_node->crl = CERT_DecodeDERCrlWithFlags(NULL, derCrl,new_node->type,
295 options->decodeOptions);
296 if (new_node->crl == NULL) {
297 goto loser;
298 }
299 adopted = PR_TRUE; /* now that the CRL has adopted the DER memory,
300 we won't need to free it upon exit */
301
302 if (fetchCrl[2].pValue && fetchCrl[2].ulValueLen) {
303 /* copy the URL if there is one */
304 int nnlen = fetchCrl[2].ulValueLen;
305 new_node->crl->url = (char *)PORT_ArenaAlloc(new_node->crl->arena,
306 nnlen+1);
307 if ( !new_node->crl->url ) {
308 goto loser;
309 }
310 PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen);
311 new_node->crl->url[nnlen] = 0;
312 } else {
313 new_node->crl->url = NULL;
314 }
315
316 new_node->next = NULL;
317 if (head->last) {
318 head->last->next = new_node;
319 head->last = new_node;
320 } else {
321 head->first = head->last = new_node;
322 }
323 rv = SECSuccess;
324 new_node->crl->slot = PK11_ReferenceSlot(slot);
325 new_node->crl->pkcs11ID = crlID;
326
327 loser:
328 /* free attributes that weren't adopted by the CRL */
329 for (i=1;i<fetchCrlSize;i++) {
330 if (fetchCrl[i].pValue) {
331 PORT_Free(fetchCrl[i].pValue);
332 }
333 }
334 /* free the DER if the CRL object didn't adopt it */
335 if (fetchCrl[0].pValue && PR_FALSE == adopted) {
336 PORT_Free(fetchCrl[0].pValue);
337 }
338 if (derCrl && !adopted) {
339 /* clear the data fields, which we already took care of above */
340 derCrl->data = NULL;
341 derCrl->len = 0;
342 /* free the memory for the SECItem structure itself */
343 SECITEM_FreeItem(derCrl, PR_TRUE);
344 }
345 return(rv);
346 }
347
348 /*
349 * Return a list of CRLs matching specified issuer and type
350 * CRLs are not allocated in the list's arena, but rather in their own,
351 * arena, so that they can be used individually in the CRL cache .
352 * CRLs are always partially decoded for efficiency.
353 */
354 SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer,
355 void *wincx)
356 {
357 pk11TraverseSlot creater;
358 CK_ATTRIBUTE theTemplate[2];
359 CK_ATTRIBUTE *attrs;
360 CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
361 crlOptions options;
362
363 attrs = theTemplate;
364 PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++;
365
366 options.head = nodes;
367
368 /* - do a partial decoding - we don't need to decode the entries while
369 fetching
370 - don't copy the DER for optimal performance - CRL can be very large
371 - have the CRL objects adopt the DER, so SEC_DestroyCrl will free it
372 - keep bad CRL objects. The CRL cache is interested in them, for
373 security purposes. Bad CRL objects are a sign of something amiss.
374 */
375
376 options.decodeOptions = CRL_DECODE_SKIP_ENTRIES | CRL_DECODE_DONT_COPY_DER |
377 CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_KEEP_BAD_CRL;
378 if (issuer)
379 {
380 PK11_SETATTRS(attrs, CKA_SUBJECT, issuer->data, issuer->len); attrs++;
381 }
382
383 creater.callback = pk11_RetrieveCrlsCallback;
384 creater.callbackArg = (void *) &options;
385 creater.findTemplate = theTemplate;
386 creater.templateCount = (attrs - theTemplate);
387
388 return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx);
389 }
390
391 /*
392 * return the crl associated with a derSubjectName
393 */
394 SECItem *
395 PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
396 SECItem *name, int type, char **pUrl)
397 {
398 NSSCRL **crls, **crlp, *crl = NULL;
399 NSSDER subject;
400 SECItem *rvItem;
401 NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
402 char * url = NULL;
403
404 PORT_SetError(0);
405 NSSITEM_FROM_SECITEM(&subject, name);
406 if (*slot) {
407 nssCryptokiObject **instances;
408 nssPKIObjectCollection *collection;
409 nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
410 NSSToken *token = PK11Slot_GetNSSToken(*slot);
411 collection = nssCRLCollection_Create(td, NULL);
412 if (!collection) {
413 goto loser;
414 }
415 instances = nssToken_FindCRLsBySubject(token, NULL, &subject,
416 tokenOnly, 0, NULL);
417 nssPKIObjectCollection_AddInstances(collection, instances, 0);
418 nss_ZFreeIf(instances);
419 crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
420 nssPKIObjectCollection_Destroy(collection);
421 } else {
422 crls = nssTrustDomain_FindCRLsBySubject(td, &subject);
423 }
424 if ((!crls) || (*crls == NULL)) {
425 if (crls) {
426 nssCRLArray_Destroy(crls);
427 }
428 if (NSS_GetError() == NSS_ERROR_NOT_FOUND) {
429 PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
430 }
431 goto loser;
432 }
433 for (crlp = crls; *crlp; crlp++) {
434 if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) ||
435 ((*crlp)->isKRL && type != SEC_CRL_TYPE))
436 {
437 crl = nssCRL_AddRef(*crlp);
438 break;
439 }
440 }
441 nssCRLArray_Destroy(crls);
442 if (!crl) {
443 /* CRL collection was found, but no interesting CRL's were on it.
444 * Not an error */
445 PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
446 goto loser;
447 }
448 if (crl->url) {
449 url = PORT_Strdup(crl->url);
450 if (!url) {
451 goto loser;
452 }
453 }
454 rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size);
455 if (!rvItem) {
456 goto loser;
457 }
458 memcpy(rvItem->data, crl->encoding.data, crl->encoding.size);
459 *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot);
460 *crlHandle = crl->object.instances[0]->handle;
461 *pUrl = url;
462 nssCRL_Destroy(crl);
463 return rvItem;
464
465 loser:
466 if (url)
467 PORT_Free(url);
468 if (crl)
469 nssCRL_Destroy(crl);
470 if (PORT_GetError() == 0) {
471 PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
472 }
473 return NULL;
474 }
475
476 CK_OBJECT_HANDLE
477 PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
478 char *url, int type)
479 {
480 NSSItem derCRL, derSubject;
481 NSSToken *token = PK11Slot_GetNSSToken(slot);
482 nssCryptokiObject *object;
483 PRBool isKRL = (type == SEC_CRL_TYPE) ? PR_FALSE : PR_TRUE;
484 CK_OBJECT_HANDLE rvH;
485
486 NSSITEM_FROM_SECITEM(&derSubject, name);
487 NSSITEM_FROM_SECITEM(&derCRL, crl);
488
489 object = nssToken_ImportCRL(token, NULL,
490 &derSubject, &derCRL, isKRL, url, PR_TRUE);
491
492 if (object) {
493 rvH = object->handle;
494 nssCryptokiObject_Destroy(object);
495 } else {
496 rvH = CK_INVALID_HANDLE;
497 PORT_SetError(SEC_ERROR_CRL_IMPORT_FAILED);
498 }
499 return rvH;
500 }
501
502
503 /*
504 * delete a crl.
505 */
506 SECStatus
507 SEC_DeletePermCRL(CERTSignedCrl *crl)
508 {
509 PRStatus status;
510 NSSToken *token;
511 nssCryptokiObject *object;
512 PK11SlotInfo *slot = crl->slot;
513
514 if (slot == NULL) {
515 PORT_Assert(slot);
516 /* shouldn't happen */
517 PORT_SetError( SEC_ERROR_CRL_INVALID);
518 return SECFailure;
519 }
520 token = PK11Slot_GetNSSToken(slot);
521
522 object = nss_ZNEW(NULL, nssCryptokiObject);
523 if (!object) {
524 return SECFailure;
525 }
526 object->token = nssToken_AddRef(token);
527 object->handle = crl->pkcs11ID;
528 object->isTokenObject = PR_TRUE;
529
530 status = nssToken_DeleteStoredObject(object);
531
532 nssCryptokiObject_Destroy(object);
533 return (status == PR_SUCCESS) ? SECSuccess : SECFailure;
534 }
535
536 /*
537 * return the certificate associated with a derCert
538 */
539 SECItem *
540 PK11_FindSMimeProfile(PK11SlotInfo **slot, char *emailAddr,
541 SECItem *name, SECItem **profileTime)
542 {
543 CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
544 CK_ATTRIBUTE theTemplate[] = {
545 { CKA_SUBJECT, NULL, 0 },
546 { CKA_CLASS, NULL, 0 },
547 { CKA_NETSCAPE_EMAIL, NULL, 0 },
548 };
549 CK_ATTRIBUTE smimeData[] = {
550 { CKA_SUBJECT, NULL, 0 },
551 { CKA_VALUE, NULL, 0 },
552 };
553 /* if you change the array, change the variable below as well */
554 int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
555 CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
556 CK_ATTRIBUTE *attrs = theTemplate;
557 CK_RV crv;
558 SECItem *emailProfile = NULL;
559
560 if (!emailAddr || !emailAddr[0]) {
561 PORT_SetError(SEC_ERROR_INVALID_ARGS);
562 return NULL;
563 }
564
565 PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++;
566 PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++;
567 PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, emailAddr, strlen(emailAddr));
568 attrs++;
569
570 if (*slot) {
571 smimeh = pk11_FindObjectByTemplate(*slot,theTemplate,tsize);
572 } else {
573 PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
574 PR_FALSE,PR_TRUE,NULL);
575 PK11SlotListElement *le;
576
577 if (!list) {
578 return NULL;
579 }
580 /* loop through all the slots */
581 for (le = list->head; le; le = le->next) {
582 smimeh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize);
583 if (smimeh != CK_INVALID_HANDLE) {
584 *slot = PK11_ReferenceSlot(le->slot);
585 break;
586 }
587 }
588 PK11_FreeSlotList(list);
589 }
590
591 if (smimeh == CK_INVALID_HANDLE) {
592 PORT_SetError(SEC_ERROR_NO_KRL);
593 return NULL;
594 }
595
596 if (profileTime) {
597 PK11_SETATTRS(smimeData, CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0);
598 }
599
600 crv = PK11_GetAttributes(NULL,*slot,smimeh,smimeData,2);
601 if (crv != CKR_OK) {
602 PORT_SetError(PK11_MapError (crv));
603 goto loser;
604 }
605
606 if (!profileTime) {
607 SECItem profileSubject;
608
609 profileSubject.data = (unsigned char*) smimeData[0].pValue;
610 profileSubject.len = smimeData[0].ulValueLen;
611 if (!SECITEM_ItemsAreEqual(&profileSubject,name)) {
612 goto loser;
613 }
614 }
615
616 emailProfile = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
617 if (emailProfile == NULL) {
618 goto loser;
619 }
620
621 emailProfile->data = (unsigned char*) smimeData[1].pValue;
622 emailProfile->len = smimeData[1].ulValueLen;
623
624 if (profileTime) {
625 *profileTime = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
626 if (*profileTime) {
627 (*profileTime)->data = (unsigned char*) smimeData[0].pValue;
628 (*profileTime)->len = smimeData[0].ulValueLen;
629 }
630 }
631
632 loser:
633 if (emailProfile == NULL) {
634 if (smimeData[1].pValue) {
635 PORT_Free(smimeData[1].pValue);
636 }
637 }
638 if (profileTime == NULL || *profileTime == NULL) {
639 if (smimeData[0].pValue) {
640 PORT_Free(smimeData[0].pValue);
641 }
642 }
643 return emailProfile;
644 }
645
646
647 SECStatus
648 PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
649 SECItem *emailProfile, SECItem *profileTime)
650 {
651 CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
652 CK_BBOOL ck_true = CK_TRUE;
653 CK_ATTRIBUTE theTemplate[] = {
654 { CKA_CLASS, NULL, 0 },
655 { CKA_TOKEN, NULL, 0 },
656 { CKA_SUBJECT, NULL, 0 },
657 { CKA_NETSCAPE_EMAIL, NULL, 0 },
658 { CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0 },
659 { CKA_VALUE, NULL, 0 }
660 };
661 /* if you change the array, change the variable below as well */
662 int realSize = 0;
663 CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
664 CK_ATTRIBUTE *attrs = theTemplate;
665 CK_SESSION_HANDLE rwsession;
666 PK11SlotInfo *free_slot = NULL;
667 CK_RV crv;
668 #ifdef DEBUG
669 int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
670 #endif
671
672 PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++;
673 PK11_SETATTRS(attrs, CKA_TOKEN, &ck_true, sizeof(ck_true)); attrs++;
674 PK11_SETATTRS(attrs, CKA_SUBJECT, derSubj->data, derSubj->len); attrs++;
675 PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL,
676 emailAddr, PORT_Strlen(emailAddr)+1); attrs++;
677 if (profileTime) {
678 PK11_SETATTRS(attrs, CKA_NETSCAPE_SMIME_TIMESTAMP, profileTime->data,
679 profileTime->len); attrs++;
680 PK11_SETATTRS(attrs, CKA_VALUE,emailProfile->data,
681 emailProfile->len); attrs++;
682 }
683 realSize = attrs - theTemplate;
684 PORT_Assert (realSize <= tsize);
685
686 if (slot == NULL) {
687 free_slot = slot = PK11_GetInternalKeySlot();
688 /* we need to free the key slot in the end!!! */
689 }
690
691 rwsession = PK11_GetRWSession(slot);
692 if (rwsession == CK_INVALID_SESSION) {
693 PORT_SetError(SEC_ERROR_READ_ONLY);
694 if (free_slot) {
695 PK11_FreeSlot(free_slot);
696 }
697 return SECFailure;
698 }
699
700 crv = PK11_GETTAB(slot)->
701 C_CreateObject(rwsession,theTemplate,realSize,&smimeh);
702 if (crv != CKR_OK) {
703 PORT_SetError( PK11_MapError(crv) );
704 }
705
706 PK11_RestoreROSession(slot,rwsession);
707
708 if (free_slot) {
709 PK11_FreeSlot(free_slot);
710 }
711 return SECSuccess;
712 }
713
714
715 CERTSignedCrl * crl_storeCRL (PK11SlotInfo *slot,char *url,
716 CERTSignedCrl *newCrl, SECItem *derCrl, int type);
717
718 /* import the CRL into the token */
719
720 CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url,
721 int type, void *wincx, PRInt32 importOptions, PLArenaPool* arena,
722 PRInt32 decodeoptions)
723 {
724 CERTSignedCrl *newCrl, *crl;
725 SECStatus rv;
726 CERTCertificate *caCert = NULL;
727
728 newCrl = crl = NULL;
729
730 do {
731 newCrl = CERT_DecodeDERCrlWithFlags(arena, derCRL, type,
732 decodeoptions);
733 if (newCrl == NULL) {
734 if (type == SEC_CRL_TYPE) {
735 /* only promote error when the error code is too generic */
736 if (PORT_GetError () == SEC_ERROR_BAD_DER)
737 PORT_SetError(SEC_ERROR_CRL_INVALID);
738 } else {
739 PORT_SetError(SEC_ERROR_KRL_INVALID);
740 }
741 break;
742 }
743
744 if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)){
745 CERTCertDBHandle* handle = CERT_GetDefaultCertDB();
746 PR_ASSERT(handle != NULL);
747 caCert = CERT_FindCertByName (handle,
748 &newCrl->crl.derName);
749 if (caCert == NULL) {
750 PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
751 break;
752 }
753
754 /* If caCert is a v3 certificate, make sure that it can be used for
755 crl signing purpose */
756 rv = CERT_CheckCertUsage (caCert, KU_CRL_SIGN);
757 if (rv != SECSuccess) {
758 break;
759 }
760
761 rv = CERT_VerifySignedData(&newCrl->signatureWrap, caCert,
762 PR_Now(), wincx);
763 if (rv != SECSuccess) {
764 if (type == SEC_CRL_TYPE) {
765 PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE);
766 } else {
767 PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE);
768 }
769 break;
770 }
771 }
772
773 crl = crl_storeCRL(slot, url, newCrl, derCRL, type);
774
775 } while (0);
776
777 if (crl == NULL) {
778 SEC_DestroyCrl (newCrl);
779 }
780 if (caCert) {
781 CERT_DestroyCertificate(caCert);
782 }
783 return (crl);
784 }
OLDNEW
« no previous file with comments | « nss/lib/pk11wrap/pk11merge.c ('k') | nss/lib/pk11wrap/pk11obj.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698