comparison nss/lib/pki/certificate.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
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 PRStatus nssrv;
899 certs = nssList_CreateIterator(certList);
900 if (!certs) {
901 return PR_FAILURE;
902 }
903 for (cert = (NSSCertificate *)nssListIterator_Start(certs);
904 cert != (NSSCertificate *)NULL;
905 cert = (NSSCertificate *)nssListIterator_Next(certs))
906 {
907 nssrv = (*callback)(cert, arg);
908 }
909 nssListIterator_Finish(certs);
910 nssListIterator_Destroy(certs);
911 return PR_SUCCESS;
912 }
913
914 static PRStatus add_ref_callback(NSSCertificate *c, void *a)
915 {
916 nssCertificate_AddRef(c);
917 return PR_SUCCESS;
918 }
919
920 NSS_IMPLEMENT void
921 nssCertificateList_AddReferences (
922 nssList *certList
923 )
924 {
925 (void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL);
926 }
927
928
929 /*
930 * Is this trust record safe to apply to all certs of the same issuer/SN
931 * independent of the cert matching the hash. This is only true is the trust
932 * is unknown or distrusted. In general this feature is only useful to
933 * explicitly distrusting certs. It is not safe to use to trust certs, so
934 * only allow unknown and untrusted trust types.
935 */
936 PRBool
937 nssTrust_IsSafeToIgnoreCertHash(nssTrustLevel serverAuth,
938 nssTrustLevel clientAuth, nssTrustLevel codeSigning,
939 nssTrustLevel email, PRBool stepup)
940 {
941 /* step up is a trust type, if it's on, we must have a hash for the cert */
942 if (stepup) {
943 return PR_FALSE;
944 }
945 if ((serverAuth != nssTrustLevel_Unknown) &&
946 (serverAuth != nssTrustLevel_NotTrusted)) {
947 return PR_FALSE;
948 }
949 if ((clientAuth != nssTrustLevel_Unknown) &&
950 (clientAuth != nssTrustLevel_NotTrusted)) {
951 return PR_FALSE;
952 }
953 if ((codeSigning != nssTrustLevel_Unknown) &&
954 (codeSigning != nssTrustLevel_NotTrusted)) {
955 return PR_FALSE;
956 }
957 if ((email != nssTrustLevel_Unknown) &&
958 (email != nssTrustLevel_NotTrusted)) {
959 return PR_FALSE;
960 }
961 /* record only has Unknown and Untrusted entries, ok to accept without a
962 * hash */
963 return PR_TRUE;
964 }
965
966 NSS_IMPLEMENT NSSTrust *
967 nssTrust_Create (
968 nssPKIObject *object,
969 NSSItem *certData
970 )
971 {
972 PRStatus status;
973 PRUint32 i;
974 PRUint32 lastTrustOrder, myTrustOrder;
975 unsigned char sha1_hashcmp[SHA1_LENGTH];
976 unsigned char sha1_hashin[SHA1_LENGTH];
977 NSSItem sha1_hash;
978 NSSTrust *rvt;
979 nssCryptokiObject *instance;
980 nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection;
981 SECStatus rv; /* Should be stan flavor */
982 PRBool stepUp;
983
984 lastTrustOrder = 1<<16; /* just make it big */
985 PR_ASSERT(object->instances != NULL && object->numInstances > 0);
986 rvt = nss_ZNEW(object->arena, NSSTrust);
987 if (!rvt) {
988 return (NSSTrust *)NULL;
989 }
990 rvt->object = *object;
991
992 /* should be stan flavor of Hashbuf */
993 rv = PK11_HashBuf(SEC_OID_SHA1,sha1_hashcmp,certData->data,certData->size);
994 if (rv != SECSuccess) {
995 return (NSSTrust *)NULL;
996 }
997 sha1_hash.data = sha1_hashin;
998 sha1_hash.size = sizeof (sha1_hashin);
999 /* trust has to peek into the base object members */
1000 nssPKIObject_Lock(object);
1001 for (i=0; i<object->numInstances; i++) {
1002 instance = object->instances[i];
1003 myTrustOrder = nssToken_GetTrustOrder(instance->token);
1004 status = nssCryptokiTrust_GetAttributes(instance, NULL,
1005 &sha1_hash,
1006 &serverAuth,
1007 &clientAuth,
1008 &codeSigning,
1009 &emailProtection,
1010 &stepUp);
1011 if (status != PR_SUCCESS) {
1012 nssPKIObject_Unlock(object);
1013 return (NSSTrust *)NULL;
1014 }
1015 /* if no hash is specified, then trust applies to all certs with
1016 * this issuer/SN. NOTE: This is only true for entries that
1017 * have distrust and unknown record */
1018 if (!(
1019 /* we continue if there is no hash, and the trust type is
1020 * safe to accept without a hash ... or ... */
1021 ((sha1_hash.size == 0) &&
1022 nssTrust_IsSafeToIgnoreCertHash(serverAuth,clientAuth,
1023 codeSigning, emailProtection,stepUp))
1024 ||
1025 /* we have a hash of the correct size, and it matches */
1026 ((sha1_hash.size == SHA1_LENGTH) && (PORT_Memcmp(sha1_hashin,
1027 sha1_hashcmp,SHA1_LENGTH) == 0)) )) {
1028 nssPKIObject_Unlock(object);
1029 return (NSSTrust *)NULL;
1030 }
1031 if (rvt->serverAuth == nssTrustLevel_Unknown ||
1032 myTrustOrder < lastTrustOrder)
1033 {
1034 rvt->serverAuth = serverAuth;
1035 }
1036 if (rvt->clientAuth == nssTrustLevel_Unknown ||
1037 myTrustOrder < lastTrustOrder)
1038 {
1039 rvt->clientAuth = clientAuth;
1040 }
1041 if (rvt->emailProtection == nssTrustLevel_Unknown ||
1042 myTrustOrder < lastTrustOrder)
1043 {
1044 rvt->emailProtection = emailProtection;
1045 }
1046 if (rvt->codeSigning == nssTrustLevel_Unknown ||
1047 myTrustOrder < lastTrustOrder)
1048 {
1049 rvt->codeSigning = codeSigning;
1050 }
1051 rvt->stepUpApproved = stepUp;
1052 lastTrustOrder = myTrustOrder;
1053 }
1054 nssPKIObject_Unlock(object);
1055 return rvt;
1056 }
1057
1058 NSS_IMPLEMENT NSSTrust *
1059 nssTrust_AddRef (
1060 NSSTrust *trust
1061 )
1062 {
1063 if (trust) {
1064 nssPKIObject_AddRef(&trust->object);
1065 }
1066 return trust;
1067 }
1068
1069 NSS_IMPLEMENT PRStatus
1070 nssTrust_Destroy (
1071 NSSTrust *trust
1072 )
1073 {
1074 if (trust) {
1075 (void)nssPKIObject_Destroy(&trust->object);
1076 }
1077 return PR_SUCCESS;
1078 }
1079
1080 NSS_IMPLEMENT nssSMIMEProfile *
1081 nssSMIMEProfile_AddRef (
1082 nssSMIMEProfile *profile
1083 )
1084 {
1085 if (profile) {
1086 nssPKIObject_AddRef(&profile->object);
1087 }
1088 return profile;
1089 }
1090
1091 NSS_IMPLEMENT PRStatus
1092 nssSMIMEProfile_Destroy (
1093 nssSMIMEProfile *profile
1094 )
1095 {
1096 if (profile) {
1097 (void)nssPKIObject_Destroy(&profile->object);
1098 }
1099 return PR_SUCCESS;
1100 }
1101
1102 NSS_IMPLEMENT NSSCRL *
1103 nssCRL_Create (
1104 nssPKIObject *object
1105 )
1106 {
1107 PRStatus status;
1108 NSSCRL *rvCRL;
1109 NSSArena *arena = object->arena;
1110 PR_ASSERT(object->instances != NULL && object->numInstances > 0);
1111 rvCRL = nss_ZNEW(arena, NSSCRL);
1112 if (!rvCRL) {
1113 return (NSSCRL *)NULL;
1114 }
1115 rvCRL->object = *object;
1116 /* XXX should choose instance based on some criteria */
1117 status = nssCryptokiCRL_GetAttributes(object->instances[0],
1118 NULL, /* XXX sessionOpt */
1119 arena,
1120 &rvCRL->encoding,
1121 NULL, /* subject */
1122 NULL, /* class */
1123 &rvCRL->url,
1124 &rvCRL->isKRL);
1125 if (status != PR_SUCCESS) {
1126 return (NSSCRL *)NULL;
1127 }
1128 return rvCRL;
1129 }
1130
1131 NSS_IMPLEMENT NSSCRL *
1132 nssCRL_AddRef (
1133 NSSCRL *crl
1134 )
1135 {
1136 if (crl) {
1137 nssPKIObject_AddRef(&crl->object);
1138 }
1139 return crl;
1140 }
1141
1142 NSS_IMPLEMENT PRStatus
1143 nssCRL_Destroy (
1144 NSSCRL *crl
1145 )
1146 {
1147 if (crl) {
1148 (void)nssPKIObject_Destroy(&crl->object);
1149 }
1150 return PR_SUCCESS;
1151 }
1152
1153 NSS_IMPLEMENT PRStatus
1154 nssCRL_DeleteStoredObject (
1155 NSSCRL *crl,
1156 NSSCallback *uhh
1157 )
1158 {
1159 return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE);
1160 }
1161
1162 NSS_IMPLEMENT NSSDER *
1163 nssCRL_GetEncoding (
1164 NSSCRL *crl
1165 )
1166 {
1167 if (crl && crl->encoding.data != NULL && crl->encoding.size > 0) {
1168 return &crl->encoding;
1169 } else {
1170 return (NSSDER *)NULL;
1171 }
1172 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)