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

Side by Side Diff: nss/lib/pki/certificate.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/pki/certdecode.c ('k') | nss/lib/pki/cryptocontext.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 #ifndef NSSPKI_H
6 #include "nsspki.h"
7 #endif /* NSSPKI_H */
8
9 #ifndef PKIT_H
10 #include "pkit.h"
11 #endif /* PKIT_H */
12
13 #ifndef PKIM_H
14 #include "pkim.h"
15 #endif /* PKIM_H */
16
17 #ifndef DEV_H
18 #include "dev.h"
19 #endif /* DEV_H */
20
21 #include "pkistore.h"
22
23 #include "pki3hack.h"
24 #include "pk11func.h"
25 #include "hasht.h"
26
27 #ifndef BASE_H
28 #include "base.h"
29 #endif /* BASE_H */
30
31 extern const NSSError NSS_ERROR_NOT_FOUND;
32
33 /* Creates a certificate from a base object */
34 NSS_IMPLEMENT NSSCertificate *
35 nssCertificate_Create (
36 nssPKIObject *object
37 )
38 {
39 PRStatus status;
40 NSSCertificate *rvCert;
41 nssArenaMark * mark;
42 NSSArena *arena = object->arena;
43 PR_ASSERT(object->instances != NULL && object->numInstances > 0);
44 PR_ASSERT(object->lockType == nssPKIMonitor);
45 mark = nssArena_Mark(arena);
46 rvCert = nss_ZNEW(arena, NSSCertificate);
47 if (!rvCert) {
48 return (NSSCertificate *)NULL;
49 }
50 rvCert->object = *object;
51 /* XXX should choose instance based on some criteria */
52 status = nssCryptokiCertificate_GetAttributes(object->instances[0],
53 NULL, /* XXX sessionOpt */
54 arena,
55 &rvCert->type,
56 &rvCert->id,
57 &rvCert->encoding,
58 &rvCert->issuer,
59 &rvCert->serial,
60 &rvCert->subject);
61 if (status != PR_SUCCESS ||
62 !rvCert->encoding.data ||
63 !rvCert->encoding.size ||
64 !rvCert->issuer.data ||
65 !rvCert->issuer.size ||
66 !rvCert->serial.data ||
67 !rvCert->serial.size) {
68 if (mark)
69 nssArena_Release(arena, mark);
70 return (NSSCertificate *)NULL;
71 }
72 if (mark)
73 nssArena_Unmark(arena, mark);
74 return rvCert;
75 }
76
77 NSS_IMPLEMENT NSSCertificate *
78 nssCertificate_AddRef (
79 NSSCertificate *c
80 )
81 {
82 if (c) {
83 nssPKIObject_AddRef(&c->object);
84 }
85 return c;
86 }
87
88 NSS_IMPLEMENT PRStatus
89 nssCertificate_Destroy (
90 NSSCertificate *c
91 )
92 {
93 nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
94 nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
95
96 if (c) {
97 PRUint32 i;
98 nssDecodedCert *dc = c->decoding;
99 NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
100 NSSCryptoContext *cc = c->object.cryptoContext;
101
102 PR_ASSERT(c->object.refCount > 0);
103
104 /* --- LOCK storage --- */
105 if (cc) {
106 nssCertificateStore_Lock(cc->certStore, &lockTrace);
107 } else {
108 nssTrustDomain_LockCertCache(td);
109 }
110 if (PR_ATOMIC_DECREMENT(&c->object.refCount) == 0) {
111 /* --- remove cert and UNLOCK storage --- */
112 if (cc) {
113 nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
114 nssCertificateStore_Unlock(cc->certStore, &lockTrace,
115 &unlockTrace);
116 } else {
117 nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
118 nssTrustDomain_UnlockCertCache(td);
119 }
120 /* free cert data */
121 for (i=0; i<c->object.numInstances; i++) {
122 nssCryptokiObject_Destroy(c->object.instances[i]);
123 }
124 nssPKIObject_DestroyLock(&c->object);
125 nssArena_Destroy(c->object.arena);
126 nssDecodedCert_Destroy(dc);
127 } else {
128 /* --- UNLOCK storage --- */
129 if (cc) {
130 nssCertificateStore_Unlock(cc->certStore,
131 &lockTrace,
132 &unlockTrace);
133 } else {
134 nssTrustDomain_UnlockCertCache(td);
135 }
136 }
137 }
138 return PR_SUCCESS;
139 }
140
141 NSS_IMPLEMENT PRStatus
142 NSSCertificate_Destroy (
143 NSSCertificate *c
144 )
145 {
146 return nssCertificate_Destroy(c);
147 }
148
149 NSS_IMPLEMENT NSSDER *
150 nssCertificate_GetEncoding (
151 NSSCertificate *c
152 )
153 {
154 if (c->encoding.size > 0 && c->encoding.data) {
155 return &c->encoding;
156 } else {
157 return (NSSDER *)NULL;
158 }
159 }
160
161 NSS_IMPLEMENT NSSDER *
162 nssCertificate_GetIssuer (
163 NSSCertificate *c
164 )
165 {
166 if (c->issuer.size > 0 && c->issuer.data) {
167 return &c->issuer;
168 } else {
169 return (NSSDER *)NULL;
170 }
171 }
172
173 NSS_IMPLEMENT NSSDER *
174 nssCertificate_GetSerialNumber (
175 NSSCertificate *c
176 )
177 {
178 if (c->serial.size > 0 && c->serial.data) {
179 return &c->serial;
180 } else {
181 return (NSSDER *)NULL;
182 }
183 }
184
185 NSS_IMPLEMENT NSSDER *
186 nssCertificate_GetSubject (
187 NSSCertificate *c
188 )
189 {
190 if (c->subject.size > 0 && c->subject.data) {
191 return &c->subject;
192 } else {
193 return (NSSDER *)NULL;
194 }
195 }
196
197 /* Returns a copy, Caller must free using nss_ZFreeIf */
198 NSS_IMPLEMENT NSSUTF8 *
199 nssCertificate_GetNickname (
200 NSSCertificate *c,
201 NSSToken *tokenOpt
202 )
203 {
204 return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt);
205 }
206
207 NSS_IMPLEMENT NSSASCII7 *
208 nssCertificate_GetEmailAddress (
209 NSSCertificate *c
210 )
211 {
212 return c->email;
213 }
214
215 NSS_IMPLEMENT PRStatus
216 NSSCertificate_DeleteStoredObject (
217 NSSCertificate *c,
218 NSSCallback *uhh
219 )
220 {
221 return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE);
222 }
223
224 NSS_IMPLEMENT PRStatus
225 NSSCertificate_Validate (
226 NSSCertificate *c,
227 NSSTime *timeOpt, /* NULL for "now" */
228 NSSUsage *usage,
229 NSSPolicies *policiesOpt /* NULL for none */
230 )
231 {
232 nss_SetError(NSS_ERROR_NOT_FOUND);
233 return PR_FAILURE;
234 }
235
236 NSS_IMPLEMENT void ** /* void *[] */
237 NSSCertificate_ValidateCompletely (
238 NSSCertificate *c,
239 NSSTime *timeOpt, /* NULL for "now" */
240 NSSUsage *usage,
241 NSSPolicies *policiesOpt, /* NULL for none */
242 void **rvOpt, /* NULL for allocate */
243 PRUint32 rvLimit, /* zero for no limit */
244 NSSArena *arenaOpt /* NULL for heap */
245 )
246 {
247 nss_SetError(NSS_ERROR_NOT_FOUND);
248 return NULL;
249 }
250
251 NSS_IMPLEMENT PRStatus
252 NSSCertificate_ValidateAndDiscoverUsagesAndPolicies (
253 NSSCertificate *c,
254 NSSTime **notBeforeOutOpt,
255 NSSTime **notAfterOutOpt,
256 void *allowedUsages,
257 void *disallowedUsages,
258 void *allowedPolicies,
259 void *disallowedPolicies,
260 /* more args.. work on this fgmr */
261 NSSArena *arenaOpt
262 )
263 {
264 nss_SetError(NSS_ERROR_NOT_FOUND);
265 return PR_FAILURE;
266 }
267
268 NSS_IMPLEMENT NSSDER *
269 NSSCertificate_Encode (
270 NSSCertificate *c,
271 NSSDER *rvOpt,
272 NSSArena *arenaOpt
273 )
274 {
275 /* Item, DER, BER are all typedefs now... */
276 return nssItem_Duplicate((NSSItem *)&c->encoding, arenaOpt, rvOpt);
277 }
278
279 NSS_IMPLEMENT nssDecodedCert *
280 nssCertificate_GetDecoding (
281 NSSCertificate *c
282 )
283 {
284 nssDecodedCert* deco = NULL;
285 if (c->type == NSSCertificateType_PKIX) {
286 (void)STAN_GetCERTCertificate(c);
287 }
288 nssPKIObject_Lock(&c->object);
289 if (!c->decoding) {
290 deco = nssDecodedCert_Create(NULL, &c->encoding, c->type);
291 PORT_Assert(!c->decoding);
292 c->decoding = deco;
293 } else {
294 deco = c->decoding;
295 }
296 nssPKIObject_Unlock(&c->object);
297 return deco;
298 }
299
300 static NSSCertificate **
301 filter_subject_certs_for_id (
302 NSSCertificate **subjectCerts,
303 void *id
304 )
305 {
306 NSSCertificate **si;
307 nssDecodedCert *dcp;
308 int nextOpenSlot = 0;
309 int i;
310 nssCertIDMatch matchLevel = nssCertIDMatch_Unknown;
311 nssCertIDMatch match;
312
313 /* walk the subject certs */
314 for (si = subjectCerts; *si; si++) {
315 dcp = nssCertificate_GetDecoding(*si);
316 if (!dcp) {
317 NSSCertificate_Destroy(*si);
318 continue;
319 }
320 match = dcp->matchIdentifier(dcp, id);
321 switch (match) {
322 case nssCertIDMatch_Yes:
323 if (matchLevel == nssCertIDMatch_Unknown) {
324 /* we have non-definitive matches, forget them */
325 for (i = 0; i < nextOpenSlot; i++) {
326 NSSCertificate_Destroy(subjectCerts[i]);
327 subjectCerts[i] = NULL;
328 }
329 nextOpenSlot = 0;
330 /* only keep definitive matches from now on */
331 matchLevel = nssCertIDMatch_Yes;
332 }
333 /* keep the cert */
334 subjectCerts[nextOpenSlot++] = *si;
335 break;
336 case nssCertIDMatch_Unknown:
337 if (matchLevel == nssCertIDMatch_Unknown) {
338 /* only have non-definitive matches so far, keep it */
339 subjectCerts[nextOpenSlot++] = *si;
340 break;
341 }
342 /* else fall through, we have a definitive match already */
343 case nssCertIDMatch_No:
344 default:
345 NSSCertificate_Destroy(*si);
346 *si = NULL;
347 }
348 }
349 subjectCerts[nextOpenSlot] = NULL;
350 return subjectCerts;
351 }
352
353 static NSSCertificate **
354 filter_certs_for_valid_issuers (
355 NSSCertificate **certs
356 )
357 {
358 NSSCertificate **cp;
359 nssDecodedCert *dcp;
360 int nextOpenSlot = 0;
361
362 for (cp = certs; *cp; cp++) {
363 dcp = nssCertificate_GetDecoding(*cp);
364 if (dcp && dcp->isValidIssuer(dcp)) {
365 certs[nextOpenSlot++] = *cp;
366 } else {
367 NSSCertificate_Destroy(*cp);
368 }
369 }
370 certs[nextOpenSlot] = NULL;
371 return certs;
372 }
373
374 static NSSCertificate *
375 find_cert_issuer (
376 NSSCertificate *c,
377 NSSTime *timeOpt,
378 NSSUsage *usage,
379 NSSPolicies *policiesOpt,
380 NSSTrustDomain *td,
381 NSSCryptoContext *cc
382 )
383 {
384 NSSArena *arena;
385 NSSCertificate **certs = NULL;
386 NSSCertificate **ccIssuers = NULL;
387 NSSCertificate **tdIssuers = NULL;
388 NSSCertificate *issuer = NULL;
389
390 if (!cc)
391 cc = c->object.cryptoContext;
392 if (!td)
393 td = NSSCertificate_GetTrustDomain(c);
394 arena = nssArena_Create();
395 if (!arena) {
396 return (NSSCertificate *)NULL;
397 }
398 if (cc) {
399 ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
400 &c->issuer,
401 NULL,
402 0,
403 arena);
404 }
405 if (td)
406 tdIssuers = nssTrustDomain_FindCertificatesBySubject(td,
407 &c->issuer,
408 NULL,
409 0,
410 arena);
411 certs = nssCertificateArray_Join(ccIssuers, tdIssuers);
412 if (certs) {
413 nssDecodedCert *dc = NULL;
414 void *issuerID = NULL;
415 dc = nssCertificate_GetDecoding(c);
416 if (dc) {
417 issuerID = dc->getIssuerIdentifier(dc);
418 }
419 /* XXX review based on CERT_FindCertIssuer
420 * this function is not using the authCertIssuer field as a fallback
421 * if authority key id does not exist
422 */
423 if (issuerID) {
424 certs = filter_subject_certs_for_id(certs, issuerID);
425 }
426 certs = filter_certs_for_valid_issuers(certs);
427 issuer = nssCertificateArray_FindBestCertificate(certs,
428 timeOpt,
429 usage,
430 policiesOpt);
431 nssCertificateArray_Destroy(certs);
432 }
433 nssArena_Destroy(arena);
434 return issuer;
435 }
436
437 /* This function returns the built chain, as far as it gets,
438 ** even if/when it fails to find an issuer, and returns PR_FAILURE
439 */
440 NSS_IMPLEMENT NSSCertificate **
441 nssCertificate_BuildChain (
442 NSSCertificate *c,
443 NSSTime *timeOpt,
444 NSSUsage *usage,
445 NSSPolicies *policiesOpt,
446 NSSCertificate **rvOpt,
447 PRUint32 rvLimit,
448 NSSArena *arenaOpt,
449 PRStatus *statusOpt,
450 NSSTrustDomain *td,
451 NSSCryptoContext *cc
452 )
453 {
454 NSSCertificate **rvChain = NULL;
455 NSSUsage issuerUsage = *usage;
456 nssPKIObjectCollection *collection = NULL;
457 PRUint32 rvCount = 0;
458 PRStatus st;
459 PRStatus ret = PR_SUCCESS;
460
461 if (!c || !cc ||
462 (!td && (td = NSSCertificate_GetTrustDomain(c)) == NULL)) {
463 goto loser;
464 }
465 /* bump the usage up to CA level */
466 issuerUsage.nss3lookingForCA = PR_TRUE;
467 collection = nssCertificateCollection_Create(td, NULL);
468 if (!collection)
469 goto loser;
470 st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
471 if (st != PR_SUCCESS)
472 goto loser;
473 for (rvCount = 1; (!rvLimit || rvCount < rvLimit); ++rvCount) {
474 CERTCertificate *cCert = STAN_GetCERTCertificate(c);
475 if (cCert->isRoot) {
476 /* not including the issuer of the self-signed cert, which is,
477 * of course, itself
478 */
479 break;
480 }
481 c = find_cert_issuer(c, timeOpt, &issuerUsage, policiesOpt, td, cc);
482 if (!c) {
483 ret = PR_FAILURE;
484 break;
485 }
486 st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
487 nssCertificate_Destroy(c); /* collection has it */
488 if (st != PR_SUCCESS)
489 goto loser;
490 }
491 rvChain = nssPKIObjectCollection_GetCertificates(collection,
492 rvOpt,
493 rvLimit,
494 arenaOpt);
495 if (rvChain) {
496 nssPKIObjectCollection_Destroy(collection);
497 if (statusOpt)
498 *statusOpt = ret;
499 if (ret != PR_SUCCESS)
500 nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
501 return rvChain;
502 }
503
504 loser:
505 if (collection)
506 nssPKIObjectCollection_Destroy(collection);
507 if (statusOpt)
508 *statusOpt = PR_FAILURE;
509 nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
510 return rvChain;
511 }
512
513 NSS_IMPLEMENT NSSCertificate **
514 NSSCertificate_BuildChain (
515 NSSCertificate *c,
516 NSSTime *timeOpt,
517 NSSUsage *usage,
518 NSSPolicies *policiesOpt,
519 NSSCertificate **rvOpt,
520 PRUint32 rvLimit, /* zero for no limit */
521 NSSArena *arenaOpt,
522 PRStatus *statusOpt,
523 NSSTrustDomain *td,
524 NSSCryptoContext *cc
525 )
526 {
527 return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt,
528 rvOpt, rvLimit, arenaOpt, statusOpt,
529 td, cc);
530 }
531
532 NSS_IMPLEMENT NSSCryptoContext *
533 nssCertificate_GetCryptoContext (
534 NSSCertificate *c
535 )
536 {
537 return c->object.cryptoContext;
538 }
539
540 NSS_IMPLEMENT NSSTrustDomain *
541 nssCertificate_GetTrustDomain (
542 NSSCertificate *c
543 )
544 {
545 return c->object.trustDomain;
546 }
547
548 NSS_IMPLEMENT NSSTrustDomain *
549 NSSCertificate_GetTrustDomain (
550 NSSCertificate *c
551 )
552 {
553 return nssCertificate_GetTrustDomain(c);
554 }
555
556 NSS_IMPLEMENT NSSToken *
557 NSSCertificate_GetToken (
558 NSSCertificate *c,
559 PRStatus *statusOpt
560 )
561 {
562 return (NSSToken *)NULL;
563 }
564
565 NSS_IMPLEMENT NSSSlot *
566 NSSCertificate_GetSlot (
567 NSSCertificate *c,
568 PRStatus *statusOpt
569 )
570 {
571 return (NSSSlot *)NULL;
572 }
573
574 NSS_IMPLEMENT NSSModule *
575 NSSCertificate_GetModule (
576 NSSCertificate *c,
577 PRStatus *statusOpt
578 )
579 {
580 return (NSSModule *)NULL;
581 }
582
583 NSS_IMPLEMENT NSSItem *
584 NSSCertificate_Encrypt (
585 NSSCertificate *c,
586 NSSAlgorithmAndParameters *apOpt,
587 NSSItem *data,
588 NSSTime *timeOpt,
589 NSSUsage *usage,
590 NSSPolicies *policiesOpt,
591 NSSCallback *uhh,
592 NSSItem *rvOpt,
593 NSSArena *arenaOpt
594 )
595 {
596 nss_SetError(NSS_ERROR_NOT_FOUND);
597 return NULL;
598 }
599
600 NSS_IMPLEMENT PRStatus
601 NSSCertificate_Verify (
602 NSSCertificate *c,
603 NSSAlgorithmAndParameters *apOpt,
604 NSSItem *data,
605 NSSItem *signature,
606 NSSTime *timeOpt,
607 NSSUsage *usage,
608 NSSPolicies *policiesOpt,
609 NSSCallback *uhh
610 )
611 {
612 nss_SetError(NSS_ERROR_NOT_FOUND);
613 return PR_FAILURE;
614 }
615
616 NSS_IMPLEMENT NSSItem *
617 NSSCertificate_VerifyRecover (
618 NSSCertificate *c,
619 NSSAlgorithmAndParameters *apOpt,
620 NSSItem *signature,
621 NSSTime *timeOpt,
622 NSSUsage *usage,
623 NSSPolicies *policiesOpt,
624 NSSCallback *uhh,
625 NSSItem *rvOpt,
626 NSSArena *arenaOpt
627 )
628 {
629 nss_SetError(NSS_ERROR_NOT_FOUND);
630 return NULL;
631 }
632
633 NSS_IMPLEMENT NSSItem *
634 NSSCertificate_WrapSymmetricKey (
635 NSSCertificate *c,
636 NSSAlgorithmAndParameters *apOpt,
637 NSSSymmetricKey *keyToWrap,
638 NSSTime *timeOpt,
639 NSSUsage *usage,
640 NSSPolicies *policiesOpt,
641 NSSCallback *uhh,
642 NSSItem *rvOpt,
643 NSSArena *arenaOpt
644 )
645 {
646 nss_SetError(NSS_ERROR_NOT_FOUND);
647 return NULL;
648 }
649
650 NSS_IMPLEMENT NSSCryptoContext *
651 NSSCertificate_CreateCryptoContext (
652 NSSCertificate *c,
653 NSSAlgorithmAndParameters *apOpt,
654 NSSTime *timeOpt,
655 NSSUsage *usage,
656 NSSPolicies *policiesOpt,
657 NSSCallback *uhh
658 )
659 {
660 nss_SetError(NSS_ERROR_NOT_FOUND);
661 return NULL;
662 }
663
664 NSS_IMPLEMENT NSSPublicKey *
665 NSSCertificate_GetPublicKey (
666 NSSCertificate *c
667 )
668 {
669 #if 0
670 CK_ATTRIBUTE pubktemplate[] = {
671 { CKA_CLASS, NULL, 0 },
672 { CKA_ID, NULL, 0 },
673 { CKA_SUBJECT, NULL, 0 }
674 };
675 PRStatus nssrv;
676 CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
677 NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
678 if (c->id.size > 0) {
679 /* CKA_ID */
680 NSS_CK_ITEM_TO_ATTRIBUTE(&c->id, &pubktemplate[1]);
681 } else {
682 /* failure, yes? */
683 return (NSSPublicKey *)NULL;
684 }
685 if (c->subject.size > 0) {
686 /* CKA_SUBJECT */
687 NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]);
688 } else {
689 /* failure, yes? */
690 return (NSSPublicKey *)NULL;
691 }
692 /* Try the cert's token first */
693 if (c->token) {
694 nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
695 }
696 #endif
697 /* Try all other key tokens */
698 return (NSSPublicKey *)NULL;
699 }
700
701 NSS_IMPLEMENT NSSPrivateKey *
702 NSSCertificate_FindPrivateKey (
703 NSSCertificate *c,
704 NSSCallback *uhh
705 )
706 {
707 nss_SetError(NSS_ERROR_NOT_FOUND);
708 return NULL;
709 }
710
711 NSS_IMPLEMENT PRBool
712 NSSCertificate_IsPrivateKeyAvailable (
713 NSSCertificate *c,
714 NSSCallback *uhh,
715 PRStatus *statusOpt
716 )
717 {
718 PRBool isUser = PR_FALSE;
719 nssCryptokiObject **ip;
720 nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
721 if (!instances) {
722 return PR_FALSE;
723 }
724 for (ip = instances; *ip; ip++) {
725 nssCryptokiObject *instance = *ip;
726 if (nssToken_IsPrivateKeyAvailable(instance->token, c, instance)) {
727 isUser = PR_TRUE;
728 }
729 }
730 nssCryptokiObjectArray_Destroy(instances);
731 return isUser;
732 }
733
734 /* sort the subject cert list from newest to oldest */
735 PRIntn
736 nssCertificate_SubjectListSort (
737 void *v1,
738 void *v2
739 )
740 {
741 NSSCertificate *c1 = (NSSCertificate *)v1;
742 NSSCertificate *c2 = (NSSCertificate *)v2;
743 nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
744 nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
745 if (!dc1) {
746 return dc2 ? 1 : 0;
747 } else if (!dc2) {
748 return -1;
749 } else {
750 return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
751 }
752 }
753
754 NSS_IMPLEMENT PRBool
755 NSSUserCertificate_IsStillPresent (
756 NSSUserCertificate *uc,
757 PRStatus *statusOpt
758 )
759 {
760 nss_SetError(NSS_ERROR_NOT_FOUND);
761 return PR_FALSE;
762 }
763
764 NSS_IMPLEMENT NSSItem *
765 NSSUserCertificate_Decrypt (
766 NSSUserCertificate *uc,
767 NSSAlgorithmAndParameters *apOpt,
768 NSSItem *data,
769 NSSTime *timeOpt,
770 NSSUsage *usage,
771 NSSPolicies *policiesOpt,
772 NSSCallback *uhh,
773 NSSItem *rvOpt,
774 NSSArena *arenaOpt
775 )
776 {
777 nss_SetError(NSS_ERROR_NOT_FOUND);
778 return NULL;
779 }
780
781 NSS_IMPLEMENT NSSItem *
782 NSSUserCertificate_Sign (
783 NSSUserCertificate *uc,
784 NSSAlgorithmAndParameters *apOpt,
785 NSSItem *data,
786 NSSTime *timeOpt,
787 NSSUsage *usage,
788 NSSPolicies *policiesOpt,
789 NSSCallback *uhh,
790 NSSItem *rvOpt,
791 NSSArena *arenaOpt
792 )
793 {
794 nss_SetError(NSS_ERROR_NOT_FOUND);
795 return NULL;
796 }
797
798 NSS_IMPLEMENT NSSItem *
799 NSSUserCertificate_SignRecover (
800 NSSUserCertificate *uc,
801 NSSAlgorithmAndParameters *apOpt,
802 NSSItem *data,
803 NSSTime *timeOpt,
804 NSSUsage *usage,
805 NSSPolicies *policiesOpt,
806 NSSCallback *uhh,
807 NSSItem *rvOpt,
808 NSSArena *arenaOpt
809 )
810 {
811 nss_SetError(NSS_ERROR_NOT_FOUND);
812 return NULL;
813 }
814
815 NSS_IMPLEMENT NSSSymmetricKey *
816 NSSUserCertificate_UnwrapSymmetricKey (
817 NSSUserCertificate *uc,
818 NSSAlgorithmAndParameters *apOpt,
819 NSSItem *wrappedKey,
820 NSSTime *timeOpt,
821 NSSUsage *usage,
822 NSSPolicies *policiesOpt,
823 NSSCallback *uhh,
824 NSSItem *rvOpt,
825 NSSArena *arenaOpt
826 )
827 {
828 nss_SetError(NSS_ERROR_NOT_FOUND);
829 return NULL;
830 }
831
832 NSS_IMPLEMENT NSSSymmetricKey *
833 NSSUserCertificate_DeriveSymmetricKey (
834 NSSUserCertificate *uc, /* provides private key */
835 NSSCertificate *c, /* provides public key */
836 NSSAlgorithmAndParameters *apOpt,
837 NSSOID *target,
838 PRUint32 keySizeOpt, /* zero for best allowed */
839 NSSOperations operations,
840 NSSCallback *uhh
841 )
842 {
843 nss_SetError(NSS_ERROR_NOT_FOUND);
844 return NULL;
845 }
846
847 NSS_IMPLEMENT nssSMIMEProfile *
848 nssSMIMEProfile_Create (
849 NSSCertificate *cert,
850 NSSItem *profileTime,
851 NSSItem *profileData
852 )
853 {
854 NSSArena *arena;
855 nssSMIMEProfile *rvProfile;
856 nssPKIObject *object;
857 NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert);
858 NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert);
859 arena = nssArena_Create();
860 if (!arena) {
861 return NULL;
862 }
863 object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock);
864 if (!object) {
865 goto loser;
866 }
867 rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
868 if (!rvProfile) {
869 goto loser;
870 }
871 rvProfile->object = *object;
872 rvProfile->certificate = cert;
873 rvProfile->email = nssUTF8_Duplicate(cert->email, arena);
874 rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL);
875 if (profileTime) {
876 rvProfile->profileTime = nssItem_Duplicate(profileTime, arena, NULL);
877 }
878 if (profileData) {
879 rvProfile->profileData = nssItem_Duplicate(profileData, arena, NULL);
880 }
881 return rvProfile;
882 loser:
883 if (object) nssPKIObject_Destroy(object);
884 else if (arena) nssArena_Destroy(arena);
885 return (nssSMIMEProfile *)NULL;
886 }
887
888 /* execute a callback function on all members of a cert list */
889 NSS_EXTERN PRStatus
890 nssCertificateList_DoCallback (
891 nssList *certList,
892 PRStatus (* callback)(NSSCertificate *c, void *arg),
893 void *arg
894 )
895 {
896 nssListIterator *certs;
897 NSSCertificate *cert;
898 certs = nssList_CreateIterator(certList);
899 if (!certs) {
900 return PR_FAILURE;
901 }
902 for (cert = (NSSCertificate *)nssListIterator_Start(certs);
903 cert != (NSSCertificate *)NULL;
904 cert = (NSSCertificate *)nssListIterator_Next(certs))
905 {
906 (void)(*callback)(cert, arg);
907 }
908 nssListIterator_Finish(certs);
909 nssListIterator_Destroy(certs);
910 return PR_SUCCESS;
911 }
912
913 static PRStatus add_ref_callback(NSSCertificate *c, void *a)
914 {
915 nssCertificate_AddRef(c);
916 return PR_SUCCESS;
917 }
918
919 NSS_IMPLEMENT void
920 nssCertificateList_AddReferences (
921 nssList *certList
922 )
923 {
924 (void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL);
925 }
926
927
928 /*
929 * Is this trust record safe to apply to all certs of the same issuer/SN
930 * independent of the cert matching the hash. This is only true is the trust
931 * is unknown or distrusted. In general this feature is only useful to
932 * explicitly distrusting certs. It is not safe to use to trust certs, so
933 * only allow unknown and untrusted trust types.
934 */
935 PRBool
936 nssTrust_IsSafeToIgnoreCertHash(nssTrustLevel serverAuth,
937 nssTrustLevel clientAuth, nssTrustLevel codeSigning,
938 nssTrustLevel email, PRBool stepup)
939 {
940 /* step up is a trust type, if it's on, we must have a hash for the cert */
941 if (stepup) {
942 return PR_FALSE;
943 }
944 if ((serverAuth != nssTrustLevel_Unknown) &&
945 (serverAuth != nssTrustLevel_NotTrusted)) {
946 return PR_FALSE;
947 }
948 if ((clientAuth != nssTrustLevel_Unknown) &&
949 (clientAuth != nssTrustLevel_NotTrusted)) {
950 return PR_FALSE;
951 }
952 if ((codeSigning != nssTrustLevel_Unknown) &&
953 (codeSigning != nssTrustLevel_NotTrusted)) {
954 return PR_FALSE;
955 }
956 if ((email != nssTrustLevel_Unknown) &&
957 (email != nssTrustLevel_NotTrusted)) {
958 return PR_FALSE;
959 }
960 /* record only has Unknown and Untrusted entries, ok to accept without a
961 * hash */
962 return PR_TRUE;
963 }
964
965 NSS_IMPLEMENT NSSTrust *
966 nssTrust_Create (
967 nssPKIObject *object,
968 NSSItem *certData
969 )
970 {
971 PRStatus status;
972 PRUint32 i;
973 PRUint32 lastTrustOrder, myTrustOrder;
974 unsigned char sha1_hashcmp[SHA1_LENGTH];
975 unsigned char sha1_hashin[SHA1_LENGTH];
976 NSSItem sha1_hash;
977 NSSTrust *rvt;
978 nssCryptokiObject *instance;
979 nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection;
980 SECStatus rv; /* Should be stan flavor */
981 PRBool stepUp;
982
983 lastTrustOrder = 1<<16; /* just make it big */
984 PR_ASSERT(object->instances != NULL && object->numInstances > 0);
985 rvt = nss_ZNEW(object->arena, NSSTrust);
986 if (!rvt) {
987 return (NSSTrust *)NULL;
988 }
989 rvt->object = *object;
990
991 /* should be stan flavor of Hashbuf */
992 rv = PK11_HashBuf(SEC_OID_SHA1,sha1_hashcmp,certData->data,certData->size);
993 if (rv != SECSuccess) {
994 return (NSSTrust *)NULL;
995 }
996 sha1_hash.data = sha1_hashin;
997 sha1_hash.size = sizeof (sha1_hashin);
998 /* trust has to peek into the base object members */
999 nssPKIObject_Lock(object);
1000 for (i=0; i<object->numInstances; i++) {
1001 instance = object->instances[i];
1002 myTrustOrder = nssToken_GetTrustOrder(instance->token);
1003 status = nssCryptokiTrust_GetAttributes(instance, NULL,
1004 &sha1_hash,
1005 &serverAuth,
1006 &clientAuth,
1007 &codeSigning,
1008 &emailProtection,
1009 &stepUp);
1010 if (status != PR_SUCCESS) {
1011 nssPKIObject_Unlock(object);
1012 return (NSSTrust *)NULL;
1013 }
1014 /* if no hash is specified, then trust applies to all certs with
1015 * this issuer/SN. NOTE: This is only true for entries that
1016 * have distrust and unknown record */
1017 if (!(
1018 /* we continue if there is no hash, and the trust type is
1019 * safe to accept without a hash ... or ... */
1020 ((sha1_hash.size == 0) &&
1021 nssTrust_IsSafeToIgnoreCertHash(serverAuth,clientAuth,
1022 codeSigning, emailProtection,stepUp))
1023 ||
1024 /* we have a hash of the correct size, and it matches */
1025 ((sha1_hash.size == SHA1_LENGTH) && (PORT_Memcmp(sha1_hashin,
1026 sha1_hashcmp,SHA1_LENGTH) == 0)) )) {
1027 nssPKIObject_Unlock(object);
1028 return (NSSTrust *)NULL;
1029 }
1030 if (rvt->serverAuth == nssTrustLevel_Unknown ||
1031 myTrustOrder < lastTrustOrder)
1032 {
1033 rvt->serverAuth = serverAuth;
1034 }
1035 if (rvt->clientAuth == nssTrustLevel_Unknown ||
1036 myTrustOrder < lastTrustOrder)
1037 {
1038 rvt->clientAuth = clientAuth;
1039 }
1040 if (rvt->emailProtection == nssTrustLevel_Unknown ||
1041 myTrustOrder < lastTrustOrder)
1042 {
1043 rvt->emailProtection = emailProtection;
1044 }
1045 if (rvt->codeSigning == nssTrustLevel_Unknown ||
1046 myTrustOrder < lastTrustOrder)
1047 {
1048 rvt->codeSigning = codeSigning;
1049 }
1050 rvt->stepUpApproved = stepUp;
1051 lastTrustOrder = myTrustOrder;
1052 }
1053 nssPKIObject_Unlock(object);
1054 return rvt;
1055 }
1056
1057 NSS_IMPLEMENT NSSTrust *
1058 nssTrust_AddRef (
1059 NSSTrust *trust
1060 )
1061 {
1062 if (trust) {
1063 nssPKIObject_AddRef(&trust->object);
1064 }
1065 return trust;
1066 }
1067
1068 NSS_IMPLEMENT PRStatus
1069 nssTrust_Destroy (
1070 NSSTrust *trust
1071 )
1072 {
1073 if (trust) {
1074 (void)nssPKIObject_Destroy(&trust->object);
1075 }
1076 return PR_SUCCESS;
1077 }
1078
1079 NSS_IMPLEMENT nssSMIMEProfile *
1080 nssSMIMEProfile_AddRef (
1081 nssSMIMEProfile *profile
1082 )
1083 {
1084 if (profile) {
1085 nssPKIObject_AddRef(&profile->object);
1086 }
1087 return profile;
1088 }
1089
1090 NSS_IMPLEMENT PRStatus
1091 nssSMIMEProfile_Destroy (
1092 nssSMIMEProfile *profile
1093 )
1094 {
1095 if (profile) {
1096 (void)nssPKIObject_Destroy(&profile->object);
1097 }
1098 return PR_SUCCESS;
1099 }
1100
1101 NSS_IMPLEMENT NSSCRL *
1102 nssCRL_Create (
1103 nssPKIObject *object
1104 )
1105 {
1106 PRStatus status;
1107 NSSCRL *rvCRL;
1108 NSSArena *arena = object->arena;
1109 PR_ASSERT(object->instances != NULL && object->numInstances > 0);
1110 rvCRL = nss_ZNEW(arena, NSSCRL);
1111 if (!rvCRL) {
1112 return (NSSCRL *)NULL;
1113 }
1114 rvCRL->object = *object;
1115 /* XXX should choose instance based on some criteria */
1116 status = nssCryptokiCRL_GetAttributes(object->instances[0],
1117 NULL, /* XXX sessionOpt */
1118 arena,
1119 &rvCRL->encoding,
1120 NULL, /* subject */
1121 NULL, /* class */
1122 &rvCRL->url,
1123 &rvCRL->isKRL);
1124 if (status != PR_SUCCESS) {
1125 if (!arena) {
1126 nssPKIObject_Destroy((nssPKIObject *)rvCRL);
1127 }
1128 return (NSSCRL *)NULL;
1129 }
1130 return rvCRL;
1131 }
1132
1133 NSS_IMPLEMENT NSSCRL *
1134 nssCRL_AddRef (
1135 NSSCRL *crl
1136 )
1137 {
1138 if (crl) {
1139 nssPKIObject_AddRef(&crl->object);
1140 }
1141 return crl;
1142 }
1143
1144 NSS_IMPLEMENT PRStatus
1145 nssCRL_Destroy (
1146 NSSCRL *crl
1147 )
1148 {
1149 if (crl) {
1150 (void)nssPKIObject_Destroy(&crl->object);
1151 }
1152 return PR_SUCCESS;
1153 }
1154
1155 NSS_IMPLEMENT PRStatus
1156 nssCRL_DeleteStoredObject (
1157 NSSCRL *crl,
1158 NSSCallback *uhh
1159 )
1160 {
1161 return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE);
1162 }
1163
1164 NSS_IMPLEMENT NSSDER *
1165 nssCRL_GetEncoding (
1166 NSSCRL *crl
1167 )
1168 {
1169 if (crl && crl->encoding.data != NULL && crl->encoding.size > 0) {
1170 return &crl->encoding;
1171 } else {
1172 return (NSSDER *)NULL;
1173 }
1174 }
OLDNEW
« no previous file with comments | « nss/lib/pki/certdecode.c ('k') | nss/lib/pki/cryptocontext.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698