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

Side by Side Diff: mozilla/security/nss/lib/pki/certificate.c

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

Powered by Google App Engine
This is Rietveld 408576698