1
/* ***** BEGIN LICENSE BLOCK *****
2
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
* The contents of this file are subject to the Mozilla Public License Version
5
* 1.1 (the "License"); you may not use this file except in compliance with
6
* the License. You may obtain a copy of the License at
7
* http://www.mozilla.org/MPL/
9
* Software distributed under the License is distributed on an "AS IS" basis,
10
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
* for the specific language governing rights and limitations under the
14
* The Original Code is the PKIX-C library.
16
* The Initial Developer of the Original Code is
17
* Sun Microsystems, Inc.
18
* Portions created by the Initial Developer are
19
* Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
22
* Sun Microsystems, Inc.
24
* Alternatively, the contents of this file may be used under the terms of
25
* either the GNU General Public License Version 2 or later (the "GPL"), or
26
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
* in which case the provisions of the GPL or the LGPL are applicable instead
28
* of those above. If you wish to allow use of your version of this file only
29
* under the terms of either the GPL or the LGPL, and not to allow others to
30
* use your version of this file under the terms of the MPL, indicate your
31
* decision by deleting the provisions above and replace them with the notice
32
* and other provisions required by the GPL or the LGPL. If you do not delete
33
* the provisions above, a recipient may use your version of this file under
34
* the terms of any one of the MPL, the GPL or the LGPL.
36
* ***** END LICENSE BLOCK ***** */
40
* Certificate Object Functions
44
#include "pkix_pl_cert.h"
46
extern PKIX_PL_HashTable *cachedCertSigTable;
48
/* --Private-Cert-Functions------------------------------------- */
51
* FUNCTION: pkix_pl_Cert_IsExtensionCritical
54
* Checks the Cert specified by "cert" to determine whether the extension
55
* whose tag is the UInt32 value given by "tag" is marked as a critical
56
* extension, and stores the result in "pCritical".
58
* Tags are the index into the table "oids" of SECOidData defined in the
59
* file secoid.c. Constants, such as SEC_OID_X509_CERTIFICATE_POLICIES, are
60
* are defined in secoidt.h for most of the table entries.
62
* If the specified tag is invalid (not in the list of tags) or if the
63
* extension is not found in the certificate, PKIX_FALSE is stored.
67
* Address of Cert whose extensions are to be examined. Must be non-NULL.
69
* The UInt32 value of the tag for the extension whose criticality is
72
* Address where the Boolean value will be stored. Must be non-NULL.
74
* Platform-specific context pointer.
76
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
78
* Returns NULL if the function succeeds.
79
* Returns a Fatal Error if the function fails in an unrecoverable way.
82
pkix_pl_Cert_IsExtensionCritical(
85
PKIX_Boolean *pCritical,
88
PKIX_Boolean criticality = PKIX_FALSE;
89
CERTCertExtension **extensions = NULL;
92
PKIX_ENTER(CERT, "pkix_pl_Cert_IsExtensionCritical");
93
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCritical);
95
extensions = cert->nssCert->extensions;
96
PKIX_NULLCHECK_ONE(extensions);
98
PKIX_CERT_DEBUG("\t\tCalling CERT_GetExtenCriticality).\n");
99
rv = CERT_GetExtenCriticality(extensions, tag, &criticality);
100
if (SECSuccess == rv) {
101
*pCritical = criticality;
103
*pCritical = PKIX_FALSE;
110
* FUNCTION: pkix_pl_Cert_DecodePolicyInfo
113
* Decodes the contents of the CertificatePolicy extension in the
114
* CERTCertificate pointed to by "nssCert", to create a List of
115
* CertPolicyInfos, which is stored at the address "pCertPolicyInfos".
116
* A CERTCertificate contains the DER representation of the Cert.
117
* If this certificate does not have a CertificatePolicy extension,
118
* NULL will be stored. If a List is returned, it will be immutable.
122
* Address of the Cert data whose extension is to be examined. Must be
125
* Address where the List of CertPolicyInfos will be stored. Must be
128
* Platform-specific context pointer.
130
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
132
* Returns NULL if the function succeeds.
133
* Returns a Cert Error if the function fails in a non-fatal way.
134
* Returns a Fatal Error if the function fails in an unrecoverable way.
137
pkix_pl_Cert_DecodePolicyInfo(
138
CERTCertificate *nssCert,
139
PKIX_List **pCertPolicyInfos,
144
SECItem encodedCertPolicyInfo;
146
/* Allocated in the arena; freed in CERT_Destroy... */
147
CERTCertificatePolicies *certPol = NULL;
148
CERTPolicyInfo **policyInfos = NULL;
149
CERTPolicyInfo *policyInfo = NULL;
150
CERTPolicyQualifier **policyQualifiers = NULL;
151
CERTPolicyQualifier *policyQualifier = NULL;
153
/* Holder for the return value */
154
PKIX_List *infos = NULL;
156
char *oidAscii = NULL;
157
PKIX_PL_OID *pkixOID = NULL;
158
PKIX_List *qualifiers = NULL;
159
PKIX_PL_CertPolicyInfo *certPolicyInfo = NULL;
160
PKIX_PL_CertPolicyQualifier *certPolicyQualifier = NULL;
161
PKIX_PL_ByteArray *qualifierArray = NULL;
163
PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyInfo");
164
PKIX_NULLCHECK_TWO(nssCert, pCertPolicyInfos);
166
/* get PolicyInfo as a SECItem */
167
PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n");
168
rv = CERT_FindCertExtension
170
SEC_OID_X509_CERTIFICATE_POLICIES,
171
&encodedCertPolicyInfo);
172
if (SECSuccess != rv) {
173
*pCertPolicyInfos = NULL;
177
/* translate PolicyInfo to CERTCertificatePolicies */
178
PKIX_CERT_DEBUG("\t\tCERT_DecodeCertificatePoliciesExtension).\n");
179
certPol = CERT_DecodeCertificatePoliciesExtension
180
(&encodedCertPolicyInfo);
182
PORT_Free(encodedCertPolicyInfo.data);
184
if (NULL == certPol) {
185
PKIX_ERROR(PKIX_CERTDECODECERTIFICATEPOLICIESEXTENSIONFAILED);
189
* Check whether there are any policyInfos, so we can
190
* avoid creating an unnecessary List
192
policyInfos = certPol->policyInfos;
194
*pCertPolicyInfos = NULL;
198
/* create a List of CertPolicyInfo Objects */
199
PKIX_CHECK(PKIX_List_Create(&infos, plContext),
200
PKIX_LISTCREATEFAILED);
203
* Traverse the CERTCertificatePolicies structure,
204
* building each PKIX_PL_CertPolicyInfo object in turn
206
while (*policyInfos != NULL) {
207
policyInfo = *policyInfos;
208
policyQualifiers = policyInfo->policyQualifiers;
209
if (policyQualifiers) {
210
/* create a PKIX_List of PKIX_PL_CertPolicyQualifiers */
211
PKIX_CHECK(PKIX_List_Create(&qualifiers, plContext),
212
PKIX_LISTCREATEFAILED);
214
while (*policyQualifiers != NULL) {
215
policyQualifier = *policyQualifiers;
217
/* create the qualifier's OID object */
219
PKIX_CHECK(pkix_pl_oidBytes2Ascii
220
(&(policyQualifier->qualifierID),
223
PKIX_OIDBYTES2ASCIIFAILED);
225
PKIX_CHECK(PKIX_PL_OID_Create
226
(oidAscii, &pkixOID, plContext),
227
PKIX_OIDCREATEFAILED);
229
/* create qualifier's ByteArray object */
231
PKIX_CHECK(PKIX_PL_ByteArray_Create
232
(policyQualifier->qualifierValue.data,
233
policyQualifier->qualifierValue.len,
236
PKIX_BYTEARRAYCREATEFAILED);
238
/* create a CertPolicyQualifier object */
240
PKIX_CHECK(pkix_pl_CertPolicyQualifier_Create
243
&certPolicyQualifier,
245
PKIX_CERTPOLICYQUALIFIERCREATEFAILED);
247
PKIX_CHECK(PKIX_List_AppendItem
249
(PKIX_PL_Object *)certPolicyQualifier,
251
PKIX_LISTAPPENDITEMFAILED);
254
PKIX_DECREF(pkixOID);
255
PKIX_DECREF(qualifierArray);
256
PKIX_DECREF(certPolicyQualifier);
261
PKIX_CHECK(PKIX_List_SetImmutable
262
(qualifiers, plContext),
263
PKIX_LISTSETIMMUTABLEFAILED);
268
* Create an OID object pkixOID from policyInfo->policyID.
269
* (The CERTPolicyInfo structure has an oid field, but it
270
* is of type SECOidTag. This function wants a SECItem.)
273
PKIX_CHECK(pkix_pl_oidBytes2Ascii
274
(&(policyInfo->policyID), &oidAscii, plContext),
275
PKIX_OIDBYTES2ASCIIFAILED);
277
PKIX_CHECK(PKIX_PL_OID_Create
278
(oidAscii, &pkixOID, plContext),
279
PKIX_OIDCREATEFAILED);
281
/* Create a CertPolicyInfo object */
282
PKIX_CHECK(pkix_pl_CertPolicyInfo_Create
283
(pkixOID, qualifiers, &certPolicyInfo, plContext),
284
PKIX_CERTPOLICYINFOCREATEFAILED);
286
/* Append the new CertPolicyInfo object to the list */
287
PKIX_CHECK(PKIX_List_AppendItem
288
(infos, (PKIX_PL_Object *)certPolicyInfo, plContext),
289
PKIX_LISTAPPENDITEMFAILED);
292
PKIX_DECREF(pkixOID);
293
PKIX_DECREF(qualifiers);
294
PKIX_DECREF(certPolicyInfo);
300
* If there were no policies, we went straight to
301
* cleanup, so we don't have to NULLCHECK infos.
303
PKIX_CHECK(PKIX_List_SetImmutable(infos, plContext),
304
PKIX_LISTSETIMMUTABLEFAILED);
306
*pCertPolicyInfos = infos;
311
("\t\tCalling CERT_DestroyCertificatePoliciesExtension).\n");
312
CERT_DestroyCertificatePoliciesExtension(certPol);
315
if (PKIX_ERROR_RECEIVED){
320
PKIX_DECREF(pkixOID);
321
PKIX_DECREF(qualifiers);
322
PKIX_DECREF(certPolicyInfo);
323
PKIX_DECREF(certPolicyQualifier);
324
PKIX_DECREF(qualifierArray);
329
* FUNCTION: pkix_pl_Cert_DecodePolicyMapping
332
* Decodes the contents of the PolicyMapping extension of the CERTCertificate
333
* pointed to by "nssCert", storing the resulting List of CertPolicyMaps at
334
* the address pointed to by "pCertPolicyMaps". If this certificate does not
335
* have a PolicyMapping extension, NULL will be stored. If a List is returned,
336
* it will be immutable.
340
* Address of the Cert data whose extension is to be examined. Must be
343
* Address where the List of CertPolicyMaps will be stored. Must be
346
* Platform-specific context pointer.
348
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
350
* Returns NULL if the function succeeds.
351
* Returns a Cert Error if the function fails in a non-fatal way.
352
* Returns a Fatal Error if the function fails in an unrecoverable way.
355
pkix_pl_Cert_DecodePolicyMapping(
356
CERTCertificate *nssCert,
357
PKIX_List **pCertPolicyMaps,
361
SECItem encodedCertPolicyMaps;
363
/* Allocated in the arena; freed in CERT_Destroy... */
364
CERTCertificatePolicyMappings *certPolMaps = NULL;
365
CERTPolicyMap **policyMaps = NULL;
366
CERTPolicyMap *policyMap = NULL;
368
/* Holder for the return value */
369
PKIX_List *maps = NULL;
371
char *issuerPolicyOIDAscii = NULL;
372
char *subjectPolicyOIDAscii = NULL;
373
PKIX_PL_OID *issuerDomainOID = NULL;
374
PKIX_PL_OID *subjectDomainOID = NULL;
375
PKIX_PL_CertPolicyMap *certPolicyMap = NULL;
377
PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyMapping");
378
PKIX_NULLCHECK_TWO(nssCert, pCertPolicyMaps);
380
/* get PolicyMappings as a SECItem */
381
PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n");
382
rv = CERT_FindCertExtension
383
(nssCert, SEC_OID_X509_POLICY_MAPPINGS, &encodedCertPolicyMaps);
384
if (SECSuccess != rv) {
385
*pCertPolicyMaps = NULL;
389
/* translate PolicyMaps to CERTCertificatePolicyMappings */
390
certPolMaps = CERT_DecodePolicyMappingsExtension
391
(&encodedCertPolicyMaps);
393
PORT_Free(encodedCertPolicyMaps.data);
396
PKIX_ERROR(PKIX_CERTDECODEPOLICYMAPPINGSEXTENSIONFAILED);
399
PKIX_NULLCHECK_ONE(certPolMaps->policyMaps);
401
policyMaps = certPolMaps->policyMaps;
403
/* create a List of CertPolicyMap Objects */
404
PKIX_CHECK(PKIX_List_Create(&maps, plContext),
405
PKIX_LISTCREATEFAILED);
408
* Traverse the CERTCertificatePolicyMappings structure,
409
* building each CertPolicyMap object in turn
412
policyMap = *policyMaps;
414
/* create the OID for the issuer Domain Policy */
416
PKIX_CHECK(pkix_pl_oidBytes2Ascii
417
(&(policyMap->issuerDomainPolicy),
418
&issuerPolicyOIDAscii,
420
PKIX_OIDBYTES2ASCIIFAILED);
422
PKIX_CHECK(PKIX_PL_OID_Create
423
(issuerPolicyOIDAscii, &issuerDomainOID, plContext),
424
PKIX_OIDCREATEFAILED);
426
/* create the OID for the subject Domain Policy */
428
PKIX_CHECK(pkix_pl_oidBytes2Ascii
429
(&(policyMap->subjectDomainPolicy),
430
&subjectPolicyOIDAscii,
432
PKIX_OIDBYTES2ASCIIFAILED);
434
PKIX_CHECK(PKIX_PL_OID_Create
435
(subjectPolicyOIDAscii, &subjectDomainOID, plContext),
436
PKIX_OIDCREATEFAILED);
438
/* create the CertPolicyMap */
440
PKIX_CHECK(pkix_pl_CertPolicyMap_Create
445
PKIX_CERTPOLICYMAPCREATEFAILED);
447
PKIX_CHECK(PKIX_List_AppendItem
448
(maps, (PKIX_PL_Object *)certPolicyMap, plContext),
449
PKIX_LISTAPPENDITEMFAILED);
451
PKIX_FREE(issuerPolicyOIDAscii);
452
PKIX_FREE(subjectPolicyOIDAscii);
453
PKIX_DECREF(issuerDomainOID);
454
PKIX_DECREF(subjectDomainOID);
455
PKIX_DECREF(certPolicyMap);
458
} while (*policyMaps != NULL);
460
PKIX_CHECK(PKIX_List_SetImmutable(maps, plContext),
461
PKIX_LISTSETIMMUTABLEFAILED);
463
*pCertPolicyMaps = maps;
468
("\t\tCalling CERT_DestroyPolicyMappingsExtension).\n");
469
CERT_DestroyPolicyMappingsExtension(certPolMaps);
472
PKIX_FREE(issuerPolicyOIDAscii);
473
PKIX_FREE(subjectPolicyOIDAscii);
474
PKIX_DECREF(issuerDomainOID);
475
PKIX_DECREF(subjectDomainOID);
476
PKIX_DECREF(certPolicyMap);
482
* FUNCTION: pkix_pl_Cert_DecodePolicyConstraints
485
* Decodes the contents of the PolicyConstraints extension in the
486
* CERTCertificate pointed to by "nssCert", to obtain SkipCerts values
487
* which are stored at the addresses "pExplicitPolicySkipCerts" and
488
* "pInhibitMappingSkipCerts", respectively. If this certificate does
489
* not have an PolicyConstraints extension, or if either of the optional
490
* components is not supplied, this function stores a value of -1 for any
495
* Address of the Cert data whose extension is to be examined. Must be
497
* "pExplicitPolicySkipCerts"
498
* Address where the SkipCert value for the requireExplicitPolicy
499
* component will be stored. Must be non-NULL.
500
* "pInhibitMappingSkipCerts"
501
* Address where the SkipCert value for the inhibitPolicyMapping
502
* component will be stored. Must be non-NULL.
504
* Platform-specific context pointer.
506
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
508
* Returns NULL if the function succeeds.
509
* Returns a Cert Error if the function fails in a non-fatal way.
510
* Returns a Fatal Error if the function fails in an unrecoverable way.
513
pkix_pl_Cert_DecodePolicyConstraints(
514
CERTCertificate *nssCert,
515
PKIX_Int32 *pExplicitPolicySkipCerts,
516
PKIX_Int32 *pInhibitMappingSkipCerts,
519
CERTCertificatePolicyConstraints policyConstraints;
521
SECItem encodedCertPolicyConstraints;
522
PKIX_Int32 explicitPolicySkipCerts = -1;
523
PKIX_Int32 inhibitMappingSkipCerts = -1;
525
PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyConstraints");
527
(nssCert, pExplicitPolicySkipCerts, pInhibitMappingSkipCerts);
529
/* get the two skipCert values as SECItems */
530
PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n");
531
rv = CERT_FindCertExtension
533
SEC_OID_X509_POLICY_CONSTRAINTS,
534
&encodedCertPolicyConstraints);
536
if (rv == SECSuccess) {
538
policyConstraints.explicitPolicySkipCerts.data =
539
(unsigned char *)&explicitPolicySkipCerts;
540
policyConstraints.inhibitMappingSkipCerts.data =
541
(unsigned char *)&inhibitMappingSkipCerts;
543
/* translate DER to CERTCertificatePolicyConstraints */
544
rv = CERT_DecodePolicyConstraintsExtension
545
(&policyConstraints, &encodedCertPolicyConstraints);
547
PORT_Free(encodedCertPolicyConstraints.data);
549
if (rv != SECSuccess) {
551
(PKIX_CERTDECODEPOLICYCONSTRAINTSEXTENSIONFAILED);
555
*pExplicitPolicySkipCerts = explicitPolicySkipCerts;
556
*pInhibitMappingSkipCerts = inhibitMappingSkipCerts;
563
* FUNCTION: pkix_pl_Cert_DecodeInhibitAnyPolicy
566
* Decodes the contents of the InhibitAnyPolicy extension in the
567
* CERTCertificate pointed to by "nssCert", to obtain a SkipCerts value,
568
* which is stored at the address "pSkipCerts". If this certificate does
569
* not have an InhibitAnyPolicy extension, -1 will be stored.
573
* Address of the Cert data whose InhibitAnyPolicy extension is to be
574
* processed. Must be non-NULL.
576
* Address where the SkipCert value from the InhibitAnyPolicy extension
577
* will be stored. Must be non-NULL.
579
* Platform-specific context pointer.
581
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
583
* Returns NULL if the function succeeds.
584
* Returns a Cert Error if the function fails in a non-fatal way.
585
* Returns a Fatal Error if the function fails in an unrecoverable way.
588
pkix_pl_Cert_DecodeInhibitAnyPolicy(
589
CERTCertificate *nssCert,
590
PKIX_Int32 *pSkipCerts,
593
CERTCertificateInhibitAny inhibitAny;
595
SECItem encodedCertInhibitAny;
596
PKIX_Int32 skipCerts = -1;
598
PKIX_ENTER(CERT, "pkix_pl_Cert_DecodeInhibitAnyPolicy");
599
PKIX_NULLCHECK_TWO(nssCert, pSkipCerts);
601
/* get InhibitAny as a SECItem */
602
PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n");
603
rv = CERT_FindCertExtension
604
(nssCert, SEC_OID_X509_INHIBIT_ANY_POLICY, &encodedCertInhibitAny);
606
if (rv == SECSuccess) {
607
inhibitAny.inhibitAnySkipCerts.data =
608
(unsigned char *)&skipCerts;
610
/* translate DER to CERTCertificateInhibitAny */
611
rv = CERT_DecodeInhibitAnyExtension
612
(&inhibitAny, &encodedCertInhibitAny);
614
PORT_Free(encodedCertInhibitAny.data);
616
if (rv != SECSuccess) {
617
PKIX_ERROR(PKIX_CERTDECODEINHIBITANYEXTENSIONFAILED);
621
*pSkipCerts = skipCerts;
628
* FUNCTION: pkix_pl_Cert_GetNssSubjectAltNames
631
* Retrieves the Subject Alternative Names of the certificate specified by
632
* "cert" and stores it at "pNssSubjAltNames". If the Subject Alternative
633
* Name extension is not present, NULL is returned at "pNssSubjAltNames".
634
* If the Subject Alternative Names has not been previously decoded, it is
635
* decoded here with lock on the "cert" unless the flag "hasLock" indicates
636
* the lock had been obtained at a higher call level.
640
* Address of the certificate whose Subject Alternative Names extensions
641
* is retrieved. Must be non-NULL.
643
* Boolean indicates caller has acquired a lock.
646
* Address where the returned Subject Alternative Names will be stored.
649
* Platform-specific context pointer.
651
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
653
* Returns NULL if the function succeeds.
654
* Returns a Cert Error if the function fails in a non-fatal way.
655
* Returns a Fatal Error if the function fails in an unrecoverable way.
658
pkix_pl_Cert_GetNssSubjectAltNames(
660
PKIX_Boolean hasLock,
661
CERTGeneralName **pNssSubjAltNames,
664
CERTCertificate *nssCert = NULL;
665
CERTGeneralName *nssOriginalAltName = NULL;
666
PLArenaPool *arena = NULL;
667
SECItem altNameExtension = {siBuffer, NULL, 0};
668
SECStatus rv = SECFailure;
670
PKIX_ENTER(CERT, "pkix_pl_Cert_GetNssSubjectAltNames");
671
PKIX_NULLCHECK_THREE(cert, pNssSubjAltNames, cert->nssCert);
673
nssCert = cert->nssCert;
675
if ((cert->nssSubjAltNames == NULL) && (!cert->subjAltNamesAbsent)){
678
PKIX_OBJECT_LOCK(cert);
681
if ((cert->nssSubjAltNames == NULL) &&
682
(!cert->subjAltNamesAbsent)){
684
PKIX_PL_NSSCALLRV(CERT, rv, CERT_FindCertExtension,
686
SEC_OID_X509_SUBJECT_ALT_NAME,
689
if (rv != SECSuccess) {
690
*pNssSubjAltNames = NULL;
691
cert->subjAltNamesAbsent = PKIX_TRUE;
695
if (cert->arenaNameConstraints == NULL) {
696
PKIX_PL_NSSCALLRV(CERT, arena, PORT_NewArena,
697
(DER_DEFAULT_CHUNKSIZE));
700
PKIX_ERROR(PKIX_PORTNEWARENAFAILED);
702
cert->arenaNameConstraints = arena;
708
(CERTGeneralName *) CERT_DecodeAltNameExtension,
709
(cert->arenaNameConstraints, &altNameExtension));
711
PKIX_PL_NSSCALL(CERT, PORT_Free, (altNameExtension.data));
713
if (nssOriginalAltName == NULL) {
714
PKIX_ERROR(PKIX_CERTDECODEALTNAMEEXTENSIONFAILED);
716
cert->nssSubjAltNames = nssOriginalAltName;
721
PKIX_OBJECT_UNLOCK(cert);
725
*pNssSubjAltNames = cert->nssSubjAltNames;
728
PKIX_OBJECT_UNLOCK(lockedObject);
733
* FUNCTION: pkix_pl_Cert_CheckExtendKeyUsage
736
* For each of the ON bit in "requiredExtendedKeyUsages" that represents its
737
* SECCertUsageEnum type, this function checks "cert"'s certType (extended
738
* key usage) and key usage with what is required for SECCertUsageEnum type.
742
* Address of the certificate whose Extended Key Usage extensions
743
* is retrieved. Must be non-NULL.
744
* "requiredExtendedKeyUsages"
745
* An unsigned integer, its bit location is ON based on the required key
746
* usage value representing in SECCertUsageEnum.
748
* Address where the return value, indicating key usage check passed, is
749
* stored. Must be non-NULL.
751
* Platform-specific context pointer.
753
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
755
* Returns NULL if the function succeeds.
756
* Returns a Cert Error if the function fails in a non-fatal way.
757
* Returns a Fatal Error if the function fails in an unrecoverable way.
760
pkix_pl_Cert_CheckExtendedKeyUsage(
762
PKIX_UInt32 requiredExtendedKeyUsages,
766
PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
767
PKIX_UInt32 certType = 0;
768
PKIX_UInt32 requiredKeyUsage = 0;
769
PKIX_UInt32 requiredCertType = 0;
770
PKIX_UInt32 requiredExtendedKeyUsage = 0;
772
PKIX_Boolean isCA = PKIX_FALSE;
773
SECStatus rv = SECFailure;
775
PKIX_ENTER(CERT, "pkix_pl_Cert_CheckExtendKeyUsage");
776
PKIX_NULLCHECK_THREE(cert, pPass, cert->nssCert);
780
PKIX_CERT_DEBUG("\t\tCalling cert_GetCertType).\n");
781
cert_GetCertType(cert->nssCert);
782
certType = cert->nssCert->nsCertType;
784
PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
788
PKIX_CERTGETBASICCONSTRAINTFAILED);
790
if (basicConstraints != NULL) {
791
PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
792
(basicConstraints, &isCA, plContext),
793
PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
797
while (requiredExtendedKeyUsages != 0) {
799
/* Find the bit location of the right-most non-zero bit */
800
while (requiredExtendedKeyUsages != 0) {
801
if (((1 << i) & requiredExtendedKeyUsages) != 0) {
802
requiredExtendedKeyUsage = 1 << i;
807
requiredExtendedKeyUsages ^= requiredExtendedKeyUsage;
809
requiredExtendedKeyUsage = i;
811
PKIX_PL_NSSCALLRV(CERT, rv, CERT_KeyUsageAndTypeForCertUsage,
812
(requiredExtendedKeyUsage,
817
if (!(certType & requiredCertType)) {
821
PKIX_PL_NSSCALLRV(CERT, rv, CERT_CheckKeyUsage,
822
(cert->nssCert, requiredKeyUsage));
823
if (rv != SECSuccess) {
833
PKIX_DECREF(basicConstraints);
838
* FUNCTION: pkix_pl_Cert_ToString_Helper
841
* Helper function that creates a string representation of the Cert pointed
842
* to by "cert" and stores it at "pString", where the value of
843
* "partialString" determines whether a full or partial representation of
844
* the Cert is stored.
848
* Address of Cert whose string representation is desired.
851
* Boolean indicating whether a partial Cert representation is desired.
853
* Address where object pointer will be stored. Must be non-NULL.
855
* Platform-specific context pointer.
857
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
859
* Returns NULL if the function succeeds.
860
* Returns a Cert Error if the function fails in a non-fatal way.
861
* Returns a Fatal Error if the function fails in an unrecoverable way.
864
pkix_pl_Cert_ToString_Helper(
866
PKIX_Boolean partialString,
867
PKIX_PL_String **pString,
870
PKIX_PL_String *certString = NULL;
871
char *asciiFormat = NULL;
872
PKIX_PL_String *formatString = NULL;
873
PKIX_UInt32 certVersion;
874
PKIX_PL_BigInt *certSN = NULL;
875
PKIX_PL_String *certSNString = NULL;
876
PKIX_PL_X500Name *certIssuer = NULL;
877
PKIX_PL_String *certIssuerString = NULL;
878
PKIX_PL_X500Name *certSubject = NULL;
879
PKIX_PL_String *certSubjectString = NULL;
880
PKIX_PL_String *notBeforeString = NULL;
881
PKIX_PL_String *notAfterString = NULL;
882
PKIX_List *subjAltNames = NULL;
883
PKIX_PL_String *subjAltNamesString = NULL;
884
PKIX_PL_ByteArray *authKeyId = NULL;
885
PKIX_PL_String *authKeyIdString = NULL;
886
PKIX_PL_ByteArray *subjKeyId = NULL;
887
PKIX_PL_String *subjKeyIdString = NULL;
888
PKIX_PL_PublicKey *nssPubKey = NULL;
889
PKIX_PL_String *nssPubKeyString = NULL;
890
PKIX_List *critExtOIDs = NULL;
891
PKIX_PL_String *critExtOIDsString = NULL;
892
PKIX_List *extKeyUsages = NULL;
893
PKIX_PL_String *extKeyUsagesString = NULL;
894
PKIX_PL_CertBasicConstraints *basicConstraint = NULL;
895
PKIX_PL_String *certBasicConstraintsString = NULL;
896
PKIX_List *policyInfo = NULL;
897
PKIX_PL_String *certPolicyInfoString = NULL;
898
PKIX_List *certPolicyMappings = NULL;
899
PKIX_PL_String *certPolicyMappingsString = NULL;
900
PKIX_Int32 certExplicitPolicy = 0;
901
PKIX_Int32 certInhibitMapping = 0;
902
PKIX_Int32 certInhibitAnyPolicy = 0;
903
PKIX_PL_CertNameConstraints *nameConstraints = NULL;
904
PKIX_PL_String *nameConstraintsString = NULL;
905
PKIX_List *authorityInfoAccess = NULL;
906
PKIX_PL_String *authorityInfoAccessString = NULL;
907
PKIX_List *subjectInfoAccess = NULL;
908
PKIX_PL_String *subjectInfoAccessString = NULL;
910
PKIX_ENTER(CERT, "pkix_pl_Cert_ToString_Helper");
911
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pString);
914
* XXX Add to this format as certificate components are developed.
925
"\tSerialNumber: %s\n"
928
"\tValidity: [From: %s\n"
930
"\tSubjectAltNames: %s\n"
931
"\tAuthorityKeyId: %s\n"
932
"\tSubjectKeyId: %s\n"
933
"\tSubjPubKeyAlgId: %s\n"
934
"\tCritExtOIDs: %s\n"
935
"\tExtKeyUsages: %s\n"
936
"\tBasicConstraint: %s\n"
937
"\tCertPolicyInfo: %s\n"
938
"\tPolicyMappings: %s\n"
939
"\tExplicitPolicy: %d\n"
940
"\tInhibitMapping: %d\n"
941
"\tInhibitAnyPolicy:%d\n"
942
"\tNameConstraints: %s\n"
943
"\tAuthorityInfoAccess: %s\n"
944
"\tSubjectInfoAccess: %s\n"
951
PKIX_CHECK(PKIX_PL_String_Create
952
(PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
953
PKIX_STRINGCREATEFAILED);
956
PKIX_CHECK(PKIX_PL_Cert_GetIssuer
957
(cert, &certIssuer, plContext),
958
PKIX_CERTGETISSUERFAILED);
960
PKIX_CHECK(PKIX_PL_Object_ToString
961
((PKIX_PL_Object *)certIssuer, &certIssuerString, plContext),
962
PKIX_X500NAMETOSTRINGFAILED);
965
PKIX_CHECK(PKIX_PL_Cert_GetSubject(cert, &certSubject, plContext),
966
PKIX_CERTGETSUBJECTFAILED);
968
PKIX_TOSTRING(certSubject, &certSubjectString, plContext,
969
PKIX_X500NAMETOSTRINGFAILED);
972
PKIX_CHECK(PKIX_PL_Sprintf
980
*pString = certString;
985
PKIX_CHECK(PKIX_PL_Cert_GetVersion(cert, &certVersion, plContext),
986
PKIX_CERTGETVERSIONFAILED);
989
PKIX_CHECK(PKIX_PL_Cert_GetSerialNumber(cert, &certSN, plContext),
990
PKIX_CERTGETSERIALNUMBERFAILED);
992
PKIX_CHECK(PKIX_PL_Object_ToString
993
((PKIX_PL_Object *)certSN, &certSNString, plContext),
994
PKIX_BIGINTTOSTRINGFAILED);
996
/* Validity: NotBefore */
997
PKIX_CHECK(pkix_pl_Date_ToString_Helper
998
(&(cert->nssCert->validity.notBefore),
1001
PKIX_DATETOSTRINGHELPERFAILED);
1003
/* Validity: NotAfter */
1004
PKIX_CHECK(pkix_pl_Date_ToString_Helper
1005
(&(cert->nssCert->validity.notAfter),
1008
PKIX_DATETOSTRINGHELPERFAILED);
1010
/* SubjectAltNames */
1011
PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
1012
(cert, &subjAltNames, plContext),
1013
PKIX_CERTGETSUBJECTALTNAMESFAILED);
1015
PKIX_TOSTRING(subjAltNames, &subjAltNamesString, plContext,
1016
PKIX_LISTTOSTRINGFAILED);
1018
/* AuthorityKeyIdentifier */
1019
PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier
1020
(cert, &authKeyId, plContext),
1021
PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED);
1023
PKIX_TOSTRING(authKeyId, &authKeyIdString, plContext,
1024
PKIX_BYTEARRAYTOSTRINGFAILED);
1026
/* SubjectKeyIdentifier */
1027
PKIX_CHECK(PKIX_PL_Cert_GetSubjectKeyIdentifier
1028
(cert, &subjKeyId, plContext),
1029
PKIX_CERTGETSUBJECTKEYIDENTIFIERFAILED);
1031
PKIX_TOSTRING(subjKeyId, &subjKeyIdString, plContext,
1032
PKIX_BYTEARRAYTOSTRINGFAILED);
1034
/* SubjectPublicKey */
1035
PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
1036
(cert, &nssPubKey, plContext),
1037
PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
1039
PKIX_CHECK(PKIX_PL_Object_ToString
1040
((PKIX_PL_Object *)nssPubKey, &nssPubKeyString, plContext),
1041
PKIX_PUBLICKEYTOSTRINGFAILED);
1043
/* CriticalExtensionOIDs */
1044
PKIX_CHECK(PKIX_PL_Cert_GetCriticalExtensionOIDs
1045
(cert, &critExtOIDs, plContext),
1046
PKIX_CERTGETCRITICALEXTENSIONOIDSFAILED);
1048
PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext,
1049
PKIX_LISTTOSTRINGFAILED);
1051
/* ExtendedKeyUsages */
1052
PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
1053
(cert, &extKeyUsages, plContext),
1054
PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
1056
PKIX_TOSTRING(extKeyUsages, &extKeyUsagesString, plContext,
1057
PKIX_LISTTOSTRINGFAILED);
1059
/* CertBasicConstraints */
1060
PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
1061
(cert, &basicConstraint, plContext),
1062
PKIX_CERTGETBASICCONSTRAINTSFAILED);
1064
PKIX_TOSTRING(basicConstraint, &certBasicConstraintsString, plContext,
1065
PKIX_CERTBASICCONSTRAINTSTOSTRINGFAILED);
1067
/* CertPolicyInfo */
1068
PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
1069
(cert, &policyInfo, plContext),
1070
PKIX_CERTGETPOLICYINFORMATIONFAILED);
1072
PKIX_TOSTRING(policyInfo, &certPolicyInfoString, plContext,
1073
PKIX_LISTTOSTRINGFAILED);
1075
/* Advanced Policies */
1076
PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappings
1077
(cert, &certPolicyMappings, plContext),
1078
PKIX_CERTGETPOLICYMAPPINGSFAILED);
1080
PKIX_TOSTRING(certPolicyMappings, &certPolicyMappingsString, plContext,
1081
PKIX_LISTTOSTRINGFAILED);
1083
PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy
1084
(cert, &certExplicitPolicy, plContext),
1085
PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED);
1087
PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappingInhibited
1088
(cert, &certInhibitMapping, plContext),
1089
PKIX_CERTGETPOLICYMAPPINGINHIBITEDFAILED);
1091
PKIX_CHECK(PKIX_PL_Cert_GetInhibitAnyPolicy
1092
(cert, &certInhibitAnyPolicy, plContext),
1093
PKIX_CERTGETINHIBITANYPOLICYFAILED);
1095
/* Name Constraints */
1096
PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
1097
(cert, &nameConstraints, plContext),
1098
PKIX_CERTGETNAMECONSTRAINTSFAILED);
1100
PKIX_TOSTRING(nameConstraints, &nameConstraintsString, plContext,
1101
PKIX_LISTTOSTRINGFAILED);
1103
/* Authority Information Access */
1104
PKIX_CHECK(PKIX_PL_Cert_GetAuthorityInfoAccess
1105
(cert, &authorityInfoAccess, plContext),
1106
PKIX_CERTGETAUTHORITYINFOACCESSFAILED);
1108
PKIX_TOSTRING(authorityInfoAccess, &authorityInfoAccessString, plContext,
1109
PKIX_LISTTOSTRINGFAILED);
1111
/* Subject Information Access */
1112
PKIX_CHECK(PKIX_PL_Cert_GetSubjectInfoAccess
1113
(cert, &subjectInfoAccess, plContext),
1114
PKIX_CERTGETSUBJECTINFOACCESSFAILED);
1116
PKIX_TOSTRING(subjectInfoAccess, &subjectInfoAccessString, plContext,
1117
PKIX_LISTTOSTRINGFAILED);
1119
PKIX_CHECK(PKIX_PL_Sprintf
1135
certBasicConstraintsString,
1136
certPolicyInfoString,
1137
certPolicyMappingsString,
1138
certExplicitPolicy, /* an Int32, not a String */
1139
certInhibitMapping, /* an Int32, not a String */
1140
certInhibitAnyPolicy, /* an Int32, not a String */
1141
nameConstraintsString,
1142
authorityInfoAccessString,
1143
subjectInfoAccessString,
1144
cert->cacheFlag), /* a boolean */
1145
PKIX_SPRINTFFAILED);
1147
*pString = certString;
1150
PKIX_DECREF(certSN);
1151
PKIX_DECREF(certSNString);
1152
PKIX_DECREF(certIssuer);
1153
PKIX_DECREF(certIssuerString);
1154
PKIX_DECREF(certSubject);
1155
PKIX_DECREF(certSubjectString);
1156
PKIX_DECREF(notBeforeString);
1157
PKIX_DECREF(notAfterString);
1158
PKIX_DECREF(subjAltNames);
1159
PKIX_DECREF(subjAltNamesString);
1160
PKIX_DECREF(authKeyId);
1161
PKIX_DECREF(authKeyIdString);
1162
PKIX_DECREF(subjKeyId);
1163
PKIX_DECREF(subjKeyIdString);
1164
PKIX_DECREF(nssPubKey);
1165
PKIX_DECREF(nssPubKeyString);
1166
PKIX_DECREF(critExtOIDs);
1167
PKIX_DECREF(critExtOIDsString);
1168
PKIX_DECREF(extKeyUsages);
1169
PKIX_DECREF(extKeyUsagesString);
1170
PKIX_DECREF(basicConstraint);
1171
PKIX_DECREF(certBasicConstraintsString);
1172
PKIX_DECREF(policyInfo);
1173
PKIX_DECREF(certPolicyInfoString);
1174
PKIX_DECREF(certPolicyMappings);
1175
PKIX_DECREF(certPolicyMappingsString);
1176
PKIX_DECREF(nameConstraints);
1177
PKIX_DECREF(nameConstraintsString);
1178
PKIX_DECREF(authorityInfoAccess);
1179
PKIX_DECREF(authorityInfoAccessString);
1180
PKIX_DECREF(subjectInfoAccess);
1181
PKIX_DECREF(subjectInfoAccessString);
1182
PKIX_DECREF(formatString);
1188
* FUNCTION: pkix_pl_Cert_Destroy
1189
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
1192
pkix_pl_Cert_Destroy(
1193
PKIX_PL_Object *object,
1196
PKIX_PL_Cert *cert = NULL;
1198
PKIX_ENTER(CERT, "pkix_pl_Cert_Destroy");
1199
PKIX_NULLCHECK_ONE(object);
1201
PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
1202
PKIX_OBJECTNOTCERT);
1204
cert = (PKIX_PL_Cert*)object;
1206
PKIX_DECREF(cert->subject);
1207
PKIX_DECREF(cert->issuer);
1208
PKIX_DECREF(cert->subjAltNames);
1209
PKIX_DECREF(cert->publicKeyAlgId);
1210
PKIX_DECREF(cert->publicKey);
1211
PKIX_DECREF(cert->serialNumber);
1212
PKIX_DECREF(cert->critExtOids);
1213
PKIX_DECREF(cert->authKeyId);
1214
PKIX_DECREF(cert->subjKeyId);
1215
PKIX_DECREF(cert->extKeyUsages);
1216
PKIX_DECREF(cert->certBasicConstraints);
1217
PKIX_DECREF(cert->certPolicyInfos);
1218
PKIX_DECREF(cert->certPolicyMappings);
1219
PKIX_DECREF(cert->nameConstraints);
1220
PKIX_DECREF(cert->store);
1221
PKIX_DECREF(cert->authorityInfoAccess);
1222
PKIX_DECREF(cert->subjectInfoAccess);
1224
if (cert->arenaNameConstraints){
1225
/* This arena was allocated for SubjectAltNames */
1226
PKIX_PL_NSSCALL(CERT, PORT_FreeArena,
1227
(cert->arenaNameConstraints, PR_FALSE));
1229
cert->arenaNameConstraints = NULL;
1230
cert->nssSubjAltNames = NULL;
1233
PKIX_PL_NSSCALL(CERT, CERT_DestroyCertificate, (cert->nssCert));
1235
cert->nssCert = NULL;
1242
* FUNCTION: pkix_pl_Cert_ToString
1243
* (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
1246
pkix_pl_Cert_ToString(
1247
PKIX_PL_Object *object,
1248
PKIX_PL_String **pString,
1251
PKIX_PL_String *certString = NULL;
1252
PKIX_PL_Cert *pkixCert = NULL;
1254
PKIX_ENTER(CERT, "pkix_pl_Cert_toString");
1255
PKIX_NULLCHECK_TWO(object, pString);
1257
PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
1258
PKIX_OBJECTNOTCERT);
1260
pkixCert = (PKIX_PL_Cert *)object;
1262
PKIX_CHECK(pkix_pl_Cert_ToString_Helper
1263
(pkixCert, PKIX_FALSE, &certString, plContext),
1264
PKIX_CERTTOSTRINGHELPERFAILED);
1266
*pString = certString;
1273
* FUNCTION: pkix_pl_Cert_Hashcode
1274
* (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
1277
pkix_pl_Cert_Hashcode(
1278
PKIX_PL_Object *object,
1279
PKIX_UInt32 *pHashcode,
1282
PKIX_PL_Cert *pkixCert = NULL;
1283
CERTCertificate *nssCert = NULL;
1284
unsigned char *derBytes = NULL;
1285
PKIX_UInt32 derLength;
1286
PKIX_UInt32 certHash;
1288
PKIX_ENTER(CERT, "pkix_pl_Cert_Hashcode");
1289
PKIX_NULLCHECK_TWO(object, pHashcode);
1291
PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
1292
PKIX_OBJECTNOTCERT);
1294
pkixCert = (PKIX_PL_Cert *)object;
1296
nssCert = pkixCert->nssCert;
1297
derBytes = (nssCert->derCert).data;
1298
derLength = (nssCert->derCert).len;
1300
PKIX_CHECK(pkix_hash(derBytes, derLength, &certHash, plContext),
1303
*pHashcode = certHash;
1311
* FUNCTION: pkix_pl_Cert_Equals
1312
* (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
1315
pkix_pl_Cert_Equals(
1316
PKIX_PL_Object *firstObject,
1317
PKIX_PL_Object *secondObject,
1318
PKIX_Boolean *pResult,
1321
CERTCertificate *firstCert = NULL;
1322
CERTCertificate *secondCert = NULL;
1323
PKIX_UInt32 secondType;
1324
PKIX_Boolean cmpResult;
1326
PKIX_ENTER(CERT, "pkix_pl_Cert_Equals");
1327
PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
1329
/* test that firstObject is a Cert */
1330
PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CERT_TYPE, plContext),
1331
PKIX_FIRSTOBJECTNOTCERT);
1334
* Since we know firstObject is a Cert, if both references are
1335
* identical, they must be equal
1337
if (firstObject == secondObject){
1338
*pResult = PKIX_TRUE;
1343
* If secondObject isn't a Cert, we don't throw an error.
1344
* We simply return a Boolean result of FALSE
1346
*pResult = PKIX_FALSE;
1347
PKIX_CHECK(PKIX_PL_Object_GetType
1348
(secondObject, &secondType, plContext),
1349
PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
1350
if (secondType != PKIX_CERT_TYPE) goto cleanup;
1352
firstCert = ((PKIX_PL_Cert *)firstObject)->nssCert;
1353
secondCert = ((PKIX_PL_Cert *)secondObject)->nssCert;
1355
PKIX_NULLCHECK_TWO(firstCert, secondCert);
1357
/* CERT_CompareCerts does byte comparison on DER encodings of certs */
1358
PKIX_CERT_DEBUG("\t\tCalling CERT_CompareCerts).\n");
1359
cmpResult = CERT_CompareCerts(firstCert, secondCert);
1361
*pResult = cmpResult;
1368
* FUNCTION: pkix_pl_Cert_RegisterSelf
1370
* Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
1372
* Not Thread Safe - for performance and complexity reasons
1374
* Since this function is only called by PKIX_PL_Initialize, which should
1375
* only be called once, it is acceptable that this function is not
1379
pkix_pl_Cert_RegisterSelf(void *plContext)
1382
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
1383
pkix_ClassTable_Entry entry;
1385
PKIX_ENTER(CERT, "pkix_pl_Cert_RegisterSelf");
1387
entry.description = "Cert";
1388
entry.destructor = pkix_pl_Cert_Destroy;
1389
entry.equalsFunction = pkix_pl_Cert_Equals;
1390
entry.hashcodeFunction = pkix_pl_Cert_Hashcode;
1391
entry.toStringFunction = pkix_pl_Cert_ToString;
1392
entry.comparator = NULL;
1393
entry.duplicateFunction = pkix_duplicateImmutable;
1395
systemClasses[PKIX_CERT_TYPE] = entry;
1401
* FUNCTION: pkix_pl_Cert_CreateWithNSSCert
1404
* Creates a new certificate using the CERTCertificate pointed to by "nssCert"
1405
* and stores it at "pCert". Once created, a Cert is immutable.
1407
* This function is primarily used as a convenience function for the
1408
* performance tests that have easy access to a CERTCertificate.
1412
* Address of CERTCertificate representing the NSS certificate.
1415
* Address where object pointer will be stored. Must be non-NULL.
1417
* Platform-specific context pointer.
1419
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1421
* Returns NULL if the function succeeds.
1422
* Returns a Cert Error if the function fails in a non-fatal way.
1423
* Returns a Fatal Error if the function fails in an unrecoverable way.
1426
pkix_pl_Cert_CreateWithNSSCert(
1427
CERTCertificate *nssCert,
1428
PKIX_PL_Cert **pCert,
1431
PKIX_PL_Cert *cert = NULL;
1433
PKIX_ENTER(CERT, "PKIX_PL_Cert_CreateWithNSSCert");
1434
PKIX_NULLCHECK_TWO(pCert, nssCert);
1436
/* create a PKIX_PL_Cert object */
1437
PKIX_CHECK(PKIX_PL_Object_Alloc
1439
sizeof (PKIX_PL_Cert),
1440
(PKIX_PL_Object **)&cert,
1442
PKIX_COULDNOTCREATEOBJECT);
1444
/* populate the nssCert field */
1445
cert->nssCert = nssCert;
1447
/* initialize remaining fields */
1449
* Fields ending with Absent are initialized to PKIX_FALSE so that the
1450
* first time we need the value we will look for it. If we find it is
1451
* actually absent, the flag will at that time be set to PKIX_TRUE to
1452
* prevent searching for it later.
1453
* Fields ending with Processed are those where a value is defined
1454
* for the Absent case, and a value of zero is possible. When the
1455
* flag is still true we have to look for the field, set the default
1456
* value if necessary, and set the Processed flag to PKIX_TRUE.
1458
cert->subject = NULL;
1459
cert->issuer = NULL;
1460
cert->subjAltNames = NULL;
1461
cert->subjAltNamesAbsent = PKIX_FALSE;
1462
cert->publicKeyAlgId = NULL;
1463
cert->publicKey = NULL;
1464
cert->serialNumber = NULL;
1465
cert->critExtOids = NULL;
1466
cert->subjKeyId = NULL;
1467
cert->subjKeyIdAbsent = PKIX_FALSE;
1468
cert->authKeyId = NULL;
1469
cert->authKeyIdAbsent = PKIX_FALSE;
1470
cert->extKeyUsages = NULL;
1471
cert->extKeyUsagesAbsent = PKIX_FALSE;
1472
cert->certBasicConstraints = NULL;
1473
cert->basicConstraintsAbsent = PKIX_FALSE;
1474
cert->certPolicyInfos = NULL;
1475
cert->policyInfoAbsent = PKIX_FALSE;
1476
cert->policyMappingsAbsent = PKIX_FALSE;
1477
cert->certPolicyMappings = NULL;
1478
cert->policyConstraintsProcessed = PKIX_FALSE;
1479
cert->policyConstraintsExplicitPolicySkipCerts = 0;
1480
cert->policyConstraintsInhibitMappingSkipCerts = 0;
1481
cert->inhibitAnyPolicyProcessed = PKIX_FALSE;
1482
cert->inhibitAnySkipCerts = 0;
1483
cert->nameConstraints = NULL;
1484
cert->nameConstraintsAbsent = PKIX_FALSE;
1485
cert->arenaNameConstraints = NULL;
1486
cert->nssSubjAltNames = NULL;
1487
cert->cacheFlag = PKIX_FALSE;
1489
cert->authorityInfoAccess = NULL;
1490
cert->subjectInfoAccess = NULL;
1499
* FUNCTION: pkix_pl_Cert_CreateToList
1502
* Creates a new certificate using the DER-encoding pointed to by "derCertItem"
1503
* and appends it to the list pointed to by "certList". If Cert creation fails,
1504
* the function returns with certList unchanged, but any decoding Error is
1509
* Address of SECItem containing the DER representation of a certificate.
1512
* Address of List to which the Cert will be appended, if successfully
1513
* created. May be empty, but must be non-NULL.
1515
* Platform-specific context pointer.
1517
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1519
* Returns NULL if the function succeeds.
1520
* Returns a Cert Error if the function fails in a non-fatal way.
1521
* Returns a Fatal Error if the function fails in an unrecoverable way.
1524
pkix_pl_Cert_CreateToList(
1525
SECItem *derCertItem,
1526
PKIX_List *certList,
1529
CERTCertificate *nssCert = NULL;
1530
PKIX_PL_Cert *cert = NULL;
1532
PKIX_ENTER(CERT, "pkix_pl_Cert_CreateToList");
1533
PKIX_NULLCHECK_TWO(derCertItem, certList);
1535
PKIX_PL_NSSCALLRV(CERT, nssCert, CERT_DecodeDERCertificate,
1536
(derCertItem, PR_TRUE, NULL));
1539
PKIX_CHECK_ONLY_FATAL(pkix_pl_Cert_CreateWithNSSCert
1540
(nssCert, &cert, plContext),
1541
PKIX_CERTCREATEWITHNSSCERTFAILED);
1543
/* skip bad certs and append good ones */
1544
if (!PKIX_ERROR_RECEIVED) {
1545
PKIX_CHECK(PKIX_List_AppendItem
1546
(certList, (PKIX_PL_Object *) cert, plContext),
1547
PKIX_LISTAPPENDITEMFAILED);
1558
/* --Public-Functions------------------------------------------------------- */
1561
* FUNCTION: PKIX_PL_Cert_Create (see comments in pkix_pl_pki.h)
1562
* XXX We may want to cache the cert after parsing it, so it can be reused
1563
* XXX Are the NSS/NSPR functions thread safe
1566
PKIX_PL_Cert_Create(
1567
PKIX_PL_ByteArray *byteArray,
1568
PKIX_PL_Cert **pCert,
1571
CERTCertificate *nssCert = NULL;
1572
SECItem *derCertItem = NULL;
1573
void *derBytes = NULL;
1574
PKIX_UInt32 derLength;
1575
PKIX_Boolean copyDER;
1576
PKIX_PL_Cert *cert = NULL;
1578
PKIX_ENTER(CERT, "PKIX_PL_Cert_Create");
1579
PKIX_NULLCHECK_TWO(pCert, byteArray);
1581
PKIX_CHECK(PKIX_PL_ByteArray_GetPointer
1582
(byteArray, &derBytes, plContext),
1583
PKIX_BYTEARRAYGETPOINTERFAILED);
1585
PKIX_CHECK(PKIX_PL_ByteArray_GetLength
1586
(byteArray, &derLength, plContext),
1587
PKIX_BYTEARRAYGETLENGTHFAILED);
1589
derCertItem = SECITEM_AllocItem(NULL, NULL, derLength);
1590
if (derCertItem == NULL){
1591
PKIX_ERROR(PKIX_UNABLETOALLOCATESECITEM);
1594
(void) PORT_Memcpy(derCertItem->data, derBytes, derLength);
1597
* setting copyDER to true forces NSS to make its own copy of the DER,
1598
* allowing us to free our copy without worrying about whether NSS
1601
copyDER = PKIX_TRUE;
1602
PKIX_CERT_DEBUG("\t\tCalling CERT_DecodeDERCertificate).\n");
1603
nssCert = CERT_DecodeDERCertificate(derCertItem, copyDER, NULL);
1605
PKIX_ERROR(PKIX_CERTDECODEDERCERTIFICATEFAILED);
1608
PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
1609
(nssCert, &cert, plContext),
1610
PKIX_CERTCREATEWITHNSSCERTFAILED);
1616
SECITEM_FreeItem(derCertItem, PKIX_TRUE);
1619
if (nssCert && PKIX_ERROR_RECEIVED){
1620
PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyCertificate).\n");
1621
CERT_DestroyCertificate(nssCert);
1625
PKIX_FREE(derBytes);
1631
* FUNCTION: PKIX_PL_Cert_CreateFromCERTCertificate
1632
* (see comments in pkix_pl_pki.h)
1635
PKIX_PL_Cert_CreateFromCERTCertificate(
1636
const CERTCertificate *nssCert,
1637
PKIX_PL_Cert **pCert,
1642
PKIX_PL_ByteArray *byteArray = NULL;
1644
PKIX_ENTER(CERT, "PKIX_PL_Cert_CreateWithNssCert");
1645
PKIX_NULLCHECK_TWO(pCert, nssCert);
1647
buf = (void*)nssCert->derCert.data;
1648
len = nssCert->derCert.len;
1651
PKIX_PL_ByteArray_Create(buf, len, &byteArray, plContext),
1652
PKIX_BYTEARRAYCREATEFAILED);
1655
PKIX_PL_Cert_Create(byteArray, pCert, plContext),
1656
PKIX_CERTCREATEWITHNSSCERTFAILED);
1659
/* will be tested and used as a patch for bug 391612 */
1660
nssCert = CERT_DupCertificate(nssInCert);
1662
PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
1663
(nssCert, &cert, plContext),
1664
PKIX_CERTCREATEWITHNSSCERTFAILED);
1665
#endif /* PKIX_UNDEF */
1670
if (nssCert && PKIX_ERROR_RECEIVED){
1671
PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyCertificate).\n");
1672
CERT_DestroyCertificate(nssCert);
1675
#endif /* PKIX_UNDEF */
1677
PKIX_DECREF(byteArray);
1683
* FUNCTION: PKIX_PL_Cert_GetVersion (see comments in pkix_pl_pki.h)
1686
PKIX_PL_Cert_GetVersion(
1688
PKIX_UInt32 *pVersion,
1691
CERTCertificate *nssCert = NULL;
1692
PKIX_UInt32 myVersion;
1694
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetVersion");
1695
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pVersion);
1697
nssCert = cert->nssCert;
1698
myVersion = *(nssCert->version.data);
1701
PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1V2ORV3);
1704
*pVersion = myVersion;
1711
* FUNCTION: PKIX_PL_Cert_GetSerialNumber (see comments in pkix_pl_pki.h)
1714
PKIX_PL_Cert_GetSerialNumber(
1716
PKIX_PL_BigInt **pSerialNumber,
1719
CERTCertificate *nssCert = NULL;
1720
SECItem serialNumItem;
1721
PKIX_PL_BigInt *serialNumber = NULL;
1725
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSerialNumber");
1726
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSerialNumber);
1728
if (cert->serialNumber == NULL){
1730
PKIX_OBJECT_LOCK(cert);
1732
if (cert->serialNumber == NULL){
1734
nssCert = cert->nssCert;
1735
serialNumItem = nssCert->serialNumber;
1737
length = serialNumItem.len;
1738
bytes = (char *)serialNumItem.data;
1740
PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
1741
(bytes, length, &serialNumber, plContext),
1742
PKIX_BIGINTCREATEWITHBYTESFAILED);
1744
/* save a cached copy in case it is asked for again */
1745
cert->serialNumber = serialNumber;
1748
PKIX_OBJECT_UNLOCK(cert);
1751
PKIX_INCREF(cert->serialNumber);
1752
*pSerialNumber = cert->serialNumber;
1755
PKIX_OBJECT_UNLOCK(lockedObject);
1760
* FUNCTION: PKIX_PL_Cert_GetSubject (see comments in pkix_pl_pki.h)
1763
PKIX_PL_Cert_GetSubject(
1765
PKIX_PL_X500Name **pCertSubject,
1768
PKIX_PL_X500Name *pkixSubject = NULL;
1769
CERTName *subjName = NULL;
1770
SECItem *derSubjName = NULL;
1772
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubject");
1773
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCertSubject);
1775
/* if we don't have a cached copy from before, we create one */
1776
if (cert->subject == NULL){
1778
PKIX_OBJECT_LOCK(cert);
1780
if (cert->subject == NULL){
1782
subjName = &cert->nssCert->subject;
1783
derSubjName = &cert->nssCert->derSubject;
1785
/* if there is no subject name */
1786
if (derSubjName->data == NULL) {
1791
PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName
1792
(derSubjName, subjName, &pkixSubject,
1794
PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
1797
/* save a cached copy in case it is asked for again */
1798
cert->subject = pkixSubject;
1801
PKIX_OBJECT_UNLOCK(cert);
1804
PKIX_INCREF(cert->subject);
1805
*pCertSubject = cert->subject;
1808
PKIX_OBJECT_UNLOCK(lockedObject);
1813
* FUNCTION: PKIX_PL_Cert_GetIssuer (see comments in pkix_pl_pki.h)
1816
PKIX_PL_Cert_GetIssuer(
1818
PKIX_PL_X500Name **pCertIssuer,
1821
PKIX_PL_X500Name *pkixIssuer = NULL;
1822
SECItem *derIssuerName = NULL;
1823
CERTName *issuerName = NULL;
1825
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetIssuer");
1826
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCertIssuer);
1828
/* if we don't have a cached copy from before, we create one */
1829
if (cert->issuer == NULL){
1831
PKIX_OBJECT_LOCK(cert);
1833
if (cert->issuer == NULL){
1835
issuerName = &cert->nssCert->issuer;
1836
derIssuerName = &cert->nssCert->derIssuer;
1838
/* if there is no subject name */
1839
PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName
1840
(derIssuerName, issuerName,
1841
&pkixIssuer, plContext),
1842
PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
1844
/* save a cached copy in case it is asked for again */
1845
cert->issuer = pkixIssuer;
1848
PKIX_OBJECT_UNLOCK(cert);
1851
PKIX_INCREF(cert->issuer);
1852
*pCertIssuer = cert->issuer;
1859
* FUNCTION: PKIX_PL_Cert_GetSubjectAltNames (see comments in pkix_pl_pki.h)
1862
PKIX_PL_Cert_GetSubjectAltNames(
1864
PKIX_List **pSubjectAltNames, /* list of PKIX_PL_GeneralName */
1867
PKIX_PL_GeneralName *pkixAltName = NULL;
1868
PKIX_List *altNamesList = NULL;
1870
CERTGeneralName *nssOriginalAltName = NULL;
1871
CERTGeneralName *nssTempAltName = NULL;
1873
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectAltNames");
1874
PKIX_NULLCHECK_TWO(cert, pSubjectAltNames);
1876
/* if we don't have a cached copy from before, we create one */
1877
if ((cert->subjAltNames == NULL) && (!cert->subjAltNamesAbsent)){
1879
PKIX_OBJECT_LOCK(cert);
1881
if ((cert->subjAltNames == NULL) &&
1882
(!cert->subjAltNamesAbsent)){
1884
PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames
1887
&nssOriginalAltName,
1889
PKIX_CERTGETNSSSUBJECTALTNAMESFAILED);
1891
if (nssOriginalAltName == NULL) {
1892
cert->subjAltNamesAbsent = PKIX_TRUE;
1893
pSubjectAltNames = NULL;
1897
nssTempAltName = nssOriginalAltName;
1899
PKIX_CHECK(PKIX_List_Create(&altNamesList, plContext),
1900
PKIX_LISTCREATEFAILED);
1903
PKIX_CHECK(pkix_pl_GeneralName_Create
1904
(nssTempAltName, &pkixAltName, plContext),
1905
PKIX_GENERALNAMECREATEFAILED);
1907
PKIX_CHECK(PKIX_List_AppendItem
1909
(PKIX_PL_Object *)pkixAltName,
1911
PKIX_LISTAPPENDITEMFAILED);
1913
PKIX_DECREF(pkixAltName);
1916
("\t\tCalling CERT_GetNextGeneralName).\n");
1917
nssTempAltName = CERT_GetNextGeneralName
1920
} while (nssTempAltName != nssOriginalAltName);
1922
/* save a cached copy in case it is asked for again */
1923
cert->subjAltNames = altNamesList;
1924
PKIX_CHECK(PKIX_List_SetImmutable
1925
(cert->subjAltNames, plContext),
1926
PKIX_LISTSETIMMUTABLEFAILED);
1930
PKIX_OBJECT_UNLOCK(cert);
1933
PKIX_INCREF(cert->subjAltNames);
1935
*pSubjectAltNames = cert->subjAltNames;
1938
PKIX_DECREF(pkixAltName);
1939
if (PKIX_ERROR_RECEIVED){
1940
PKIX_DECREF(altNamesList);
1946
* FUNCTION: PKIX_PL_Cert_GetAllSubjectNames (see comments in pkix_pl_pki.h)
1949
PKIX_PL_Cert_GetAllSubjectNames(
1951
PKIX_List **pAllSubjectNames, /* list of PKIX_PL_GeneralName */
1954
CERTGeneralName *nssOriginalSubjectName = NULL;
1955
CERTGeneralName *nssTempSubjectName = NULL;
1956
PKIX_List *allSubjectNames = NULL;
1957
PKIX_PL_GeneralName *pkixSubjectName = NULL;
1958
PRArenaPool *arena = NULL;
1960
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAllSubjectNames");
1961
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAllSubjectNames);
1964
if (cert->nssCert->subjectName == NULL){
1965
/* if there is no subject DN, just get altnames */
1967
PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames
1969
PKIX_FALSE, /* hasLock */
1970
&nssOriginalSubjectName,
1972
PKIX_CERTGETNSSSUBJECTALTNAMESFAILED);
1974
} else { /* get subject DN and altnames */
1976
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1977
if (arena == NULL) {
1978
PKIX_ERROR(PKIX_PORTNEWARENAFAILED);
1981
/* This NSS call returns both Subject and Subject Alt Names */
1982
PKIX_CERT_DEBUG("\t\tCalling CERT_GetCertificateNames\n");
1983
nssOriginalSubjectName =
1984
CERT_GetCertificateNames(cert->nssCert, arena);
1987
if (nssOriginalSubjectName == NULL) {
1988
pAllSubjectNames = NULL;
1992
nssTempSubjectName = nssOriginalSubjectName;
1994
PKIX_CHECK(PKIX_List_Create(&allSubjectNames, plContext),
1995
PKIX_LISTCREATEFAILED);
1998
PKIX_CHECK(pkix_pl_GeneralName_Create
1999
(nssTempSubjectName, &pkixSubjectName, plContext),
2000
PKIX_GENERALNAMECREATEFAILED);
2002
PKIX_CHECK(PKIX_List_AppendItem
2004
(PKIX_PL_Object *)pkixSubjectName,
2006
PKIX_LISTAPPENDITEMFAILED);
2008
PKIX_DECREF(pkixSubjectName);
2011
("\t\tCalling CERT_GetNextGeneralName).\n");
2012
nssTempSubjectName = CERT_GetNextGeneralName
2013
(nssTempSubjectName);
2014
} while (nssTempSubjectName != nssOriginalSubjectName);
2016
*pAllSubjectNames = allSubjectNames;
2019
if (PKIX_ERROR_RECEIVED){
2020
PKIX_DECREF(allSubjectNames);
2024
PORT_FreeArena(arena, PR_FALSE);
2026
PKIX_DECREF(pkixSubjectName);
2031
* FUNCTION: PKIX_PL_Cert_GetSubjectPublicKeyAlgId
2032
* (see comments in pkix_pl_pki.h)
2035
PKIX_PL_Cert_GetSubjectPublicKeyAlgId(
2037
PKIX_PL_OID **pSubjKeyAlgId,
2040
CERTCertificate *nssCert = NULL;
2041
PKIX_PL_OID *pubKeyAlgId = NULL;
2042
SECAlgorithmID algorithm;
2044
char *asciiOID = NULL;
2046
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectPublicKeyAlgId");
2047
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSubjKeyAlgId);
2049
/* if we don't have a cached copy from before, we create one */
2050
if (cert->publicKeyAlgId == NULL){
2052
PKIX_OBJECT_LOCK(cert);
2054
if (cert->publicKeyAlgId == NULL){
2056
nssCert = cert->nssCert;
2057
algorithm = nssCert->subjectPublicKeyInfo.algorithm;
2058
algBytes = algorithm.algorithm;
2060
PKIX_NULLCHECK_ONE(algBytes.data);
2061
if (algBytes.len == 0) {
2062
PKIX_ERROR_FATAL(PKIX_ALGORITHMBYTESLENGTH0);
2065
PKIX_CHECK(pkix_pl_oidBytes2Ascii
2066
(&algBytes, &asciiOID, plContext),
2067
PKIX_OIDBYTES2ASCIIFAILED);
2069
PKIX_CHECK(PKIX_PL_OID_Create
2070
(asciiOID, &pubKeyAlgId, plContext),
2071
PKIX_OIDCREATEFAILED);
2073
/* save a cached copy in case it is asked for again */
2074
cert->publicKeyAlgId = pubKeyAlgId;
2077
PKIX_OBJECT_UNLOCK(cert);
2080
PKIX_INCREF(cert->publicKeyAlgId);
2081
*pSubjKeyAlgId = cert->publicKeyAlgId;
2084
PKIX_FREE(asciiOID);
2089
* FUNCTION: PKIX_PL_Cert_GetSubjectPublicKey (see comments in pkix_pl_pki.h)
2092
PKIX_PL_Cert_GetSubjectPublicKey(
2094
PKIX_PL_PublicKey **pPublicKey,
2097
PKIX_PL_PublicKey *pkixPubKey = NULL;
2100
CERTSubjectPublicKeyInfo *from = NULL;
2101
CERTSubjectPublicKeyInfo *to = NULL;
2102
SECItem *fromItem = NULL;
2103
SECItem *toItem = NULL;
2105
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectPublicKey");
2106
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPublicKey);
2108
/* if we don't have a cached copy from before, we create one */
2109
if (cert->publicKey == NULL){
2111
PKIX_OBJECT_LOCK(cert);
2113
if (cert->publicKey == NULL){
2115
/* create a PKIX_PL_PublicKey object */
2116
PKIX_CHECK(PKIX_PL_Object_Alloc
2117
(PKIX_PUBLICKEY_TYPE,
2118
sizeof (PKIX_PL_PublicKey),
2119
(PKIX_PL_Object **)&pkixPubKey,
2121
PKIX_COULDNOTCREATEOBJECT);
2123
/* initialize fields */
2124
pkixPubKey->nssSPKI = NULL;
2126
/* populate the SPKI field */
2127
PKIX_CHECK(PKIX_PL_Malloc
2128
(sizeof (CERTSubjectPublicKeyInfo),
2129
(void **)&pkixPubKey->nssSPKI,
2133
to = pkixPubKey->nssSPKI;
2134
from = &cert->nssCert->subjectPublicKeyInfo;
2136
PKIX_NULLCHECK_TWO(to, from);
2139
("\t\tCalling SECOID_CopyAlgorithmID).\n");
2140
rv = SECOID_CopyAlgorithmID
2141
(NULL, &to->algorithm, &from->algorithm);
2142
if (rv != SECSuccess) {
2143
PKIX_ERROR(PKIX_SECOIDCOPYALGORITHMIDFAILED);
2147
* NSS stores the length of subjectPublicKey in bits.
2148
* Therefore, we use that length converted to bytes
2149
* using ((length+7)>>3) before calling PORT_Memcpy
2150
* in order to avoid "read from uninitialized memory"
2154
toItem = &to->subjectPublicKey;
2155
fromItem = &from->subjectPublicKey;
2157
PKIX_NULLCHECK_TWO(toItem, fromItem);
2159
toItem->type = fromItem->type;
2162
(unsigned char*) PORT_ZAlloc(fromItem->len);
2164
PKIX_ERROR(PKIX_PORTZALLOCFAILED);
2167
(void) PORT_Memcpy(toItem->data,
2169
(fromItem->len + 7)>>3);
2170
toItem->len = fromItem->len;
2172
/* save a cached copy in case it is asked for again */
2173
cert->publicKey = pkixPubKey;
2176
PKIX_OBJECT_UNLOCK(cert);
2179
PKIX_INCREF(cert->publicKey);
2180
*pPublicKey = cert->publicKey;
2183
PKIX_OBJECT_UNLOCK(lockedObject);
2184
if (PKIX_ERROR_RECEIVED){
2185
PKIX_DECREF(pkixPubKey);
2191
* FUNCTION: PKIX_PL_Cert_GetCriticalExtensionOIDs
2192
* (see comments in pkix_pl_pki.h)
2195
PKIX_PL_Cert_GetCriticalExtensionOIDs(
2197
PKIX_List **pList, /* list of PKIX_PL_OID */
2200
PKIX_List *oidsList = NULL;
2201
CERTCertExtension **extensions = NULL;
2202
CERTCertificate *nssCert = NULL;
2204
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCriticalExtensionOIDs");
2205
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pList);
2207
/* if we don't have a cached copy from before, we create one */
2208
if (cert->critExtOids == NULL) {
2210
PKIX_OBJECT_LOCK(cert);
2212
if (cert->critExtOids == NULL) {
2214
nssCert = cert->nssCert;
2217
* ASN.1 for Extension
2219
* Extension ::= SEQUENCE {
2220
* extnID OBJECT IDENTIFIER,
2221
* critical BOOLEAN DEFAULT FALSE,
2222
* extnValue OCTET STRING }
2226
extensions = nssCert->extensions;
2228
PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
2229
(extensions, &oidsList, plContext),
2230
PKIX_GETCRITICALEXTENSIONOIDSFAILED);
2232
/* save a cached copy in case it is asked for again */
2233
cert->critExtOids = oidsList;
2236
PKIX_OBJECT_UNLOCK(cert);
2239
/* We should return a copy of the List since this list changes */
2240
PKIX_DUPLICATE(cert->critExtOids, pList, plContext,
2241
PKIX_OBJECTDUPLICATELISTFAILED);
2244
PKIX_OBJECT_UNLOCK(lockedObject);
2249
* FUNCTION: PKIX_PL_Cert_GetAuthorityKeyIdentifier
2250
* (see comments in pkix_pl_pki.h)
2253
PKIX_PL_Cert_GetAuthorityKeyIdentifier(
2255
PKIX_PL_ByteArray **pAuthKeyId,
2258
PKIX_PL_ByteArray *authKeyId = NULL;
2259
CERTCertificate *nssCert = NULL;
2260
CERTAuthKeyID *authKeyIdExtension = NULL;
2261
PRArenaPool *arena = NULL;
2264
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAuthorityKeyIdentifier");
2265
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAuthKeyId);
2267
/* if we don't have a cached copy from before, we create one */
2268
if ((cert->authKeyId == NULL) && (!cert->authKeyIdAbsent)){
2270
PKIX_OBJECT_LOCK(cert);
2272
if ((cert->authKeyId == NULL) && (!cert->authKeyIdAbsent)){
2274
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
2275
if (arena == NULL) {
2276
PKIX_ERROR(PKIX_PORTNEWARENAFAILED);
2279
nssCert = cert->nssCert;
2281
authKeyIdExtension =
2282
CERT_FindAuthKeyIDExten(arena, nssCert);
2283
if (authKeyIdExtension == NULL){
2284
cert->authKeyIdAbsent = PKIX_TRUE;
2289
retItem = authKeyIdExtension->keyID;
2291
if (retItem.len == 0){
2292
cert->authKeyIdAbsent = PKIX_TRUE;
2297
PKIX_CHECK(PKIX_PL_ByteArray_Create
2302
PKIX_BYTEARRAYCREATEFAILED);
2304
/* save a cached copy in case it is asked for again */
2305
cert->authKeyId = authKeyId;
2308
PKIX_OBJECT_UNLOCK(cert);
2311
PKIX_INCREF(cert->authKeyId);
2312
*pAuthKeyId = cert->authKeyId;
2315
PKIX_OBJECT_UNLOCK(lockedObject);
2317
PORT_FreeArena(arena, PR_FALSE);
2323
* FUNCTION: PKIX_PL_Cert_GetSubjectKeyIdentifier
2324
* (see comments in pkix_pl_pki.h)
2327
PKIX_PL_Cert_GetSubjectKeyIdentifier(
2329
PKIX_PL_ByteArray **pSubjKeyId,
2332
PKIX_PL_ByteArray *subjKeyId = NULL;
2333
CERTCertificate *nssCert = NULL;
2334
SECItem *retItem = NULL;
2337
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectKeyIdentifier");
2338
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSubjKeyId);
2340
/* if we don't have a cached copy from before, we create one */
2341
if ((cert->subjKeyId == NULL) && (!cert->subjKeyIdAbsent)){
2343
PKIX_OBJECT_LOCK(cert);
2345
if ((cert->subjKeyId == NULL) && (!cert->subjKeyIdAbsent)){
2347
retItem = SECITEM_AllocItem(NULL, NULL, 0);
2348
if (retItem == NULL){
2349
PKIX_ERROR(PKIX_UNABLETOALLOCATESECITEM);
2352
nssCert = cert->nssCert;
2354
status = CERT_FindSubjectKeyIDExtension
2356
if (status != SECSuccess) {
2357
cert->subjKeyIdAbsent = PKIX_TRUE;
2362
PKIX_CHECK(PKIX_PL_ByteArray_Create
2367
PKIX_BYTEARRAYCREATEFAILED);
2369
/* save a cached copy in case it is asked for again */
2370
cert->subjKeyId = subjKeyId;
2373
PKIX_OBJECT_UNLOCK(cert);
2376
PKIX_INCREF(cert->subjKeyId);
2377
*pSubjKeyId = cert->subjKeyId;
2380
PKIX_OBJECT_UNLOCK(lockedObject);
2382
SECITEM_FreeItem(retItem, PKIX_TRUE);
2388
* FUNCTION: PKIX_PL_Cert_GetExtendedKeyUsage (see comments in pkix_pl_pki.h)
2391
PKIX_PL_Cert_GetExtendedKeyUsage(
2393
PKIX_List **pKeyUsage, /* list of PKIX_PL_OID */
2396
CERTOidSequence *extKeyUsage = NULL;
2397
CERTCertificate *nssCert = NULL;
2398
PKIX_PL_OID *pkixOID = NULL;
2399
PKIX_List *oidsList = NULL;
2400
char *oidAscii = NULL;
2401
SECItem **oids = NULL;
2402
SECItem *oid = NULL;
2403
SECItem encodedExtKeyUsage;
2406
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetExtendedKeyUsage");
2407
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pKeyUsage);
2409
/* if we don't have a cached copy from before, we create one */
2410
if ((cert->extKeyUsages == NULL) && (!cert->extKeyUsagesAbsent)){
2412
PKIX_OBJECT_LOCK(cert);
2414
if ((cert->extKeyUsages == NULL) &&
2415
(!cert->extKeyUsagesAbsent)){
2417
nssCert = cert->nssCert;
2419
rv = CERT_FindCertExtension
2420
(nssCert, SEC_OID_X509_EXT_KEY_USAGE,
2421
&encodedExtKeyUsage);
2422
if (rv != SECSuccess){
2423
cert->extKeyUsagesAbsent = PKIX_TRUE;
2429
CERT_DecodeOidSequence(&encodedExtKeyUsage);
2430
if (extKeyUsage == NULL){
2431
PKIX_ERROR(PKIX_CERTDECODEOIDSEQUENCEFAILED);
2434
PORT_Free(encodedExtKeyUsage.data);
2436
oids = extKeyUsage->oids;
2439
/* no extended key usage extensions found */
2440
cert->extKeyUsagesAbsent = PKIX_TRUE;
2445
PKIX_CHECK(PKIX_List_Create(&oidsList, plContext),
2446
PKIX_LISTCREATEFAILED);
2451
PKIX_CHECK(pkix_pl_oidBytes2Ascii
2452
(oid, &oidAscii, plContext),
2453
PKIX_OIDBYTES2ASCIIFAILED);
2455
PKIX_CHECK(PKIX_PL_OID_Create
2456
(oidAscii, &pkixOID, plContext),
2457
PKIX_OIDCREATEFAILED);
2459
PKIX_CHECK(PKIX_List_AppendItem
2461
(PKIX_PL_Object *)pkixOID,
2463
PKIX_LISTAPPENDITEMFAILED);
2465
PKIX_FREE(oidAscii);
2467
PKIX_DECREF(pkixOID);
2470
/* save a cached copy in case it is asked for again */
2471
cert->extKeyUsages = oidsList;
2474
PKIX_OBJECT_UNLOCK(cert);
2477
if (cert->extKeyUsages){
2479
PKIX_INCREF(cert->extKeyUsages);
2481
PKIX_CHECK(PKIX_List_SetImmutable
2482
(cert->extKeyUsages, plContext),
2483
PKIX_LISTSETIMMUTABLEFAILED);
2486
*pKeyUsage = cert->extKeyUsages;
2489
PKIX_OBJECT_UNLOCK(lockedObject);
2491
PKIX_FREE(oidAscii);
2492
PKIX_DECREF(pkixOID);
2494
CERT_DestroyOidSequence(extKeyUsage);
2496
if (PKIX_ERROR_RECEIVED){
2497
PKIX_DECREF(oidsList);
2504
* FUNCTION: PKIX_PL_Cert_GetBasicConstraints
2505
* (see comments in pkix_pl_pki.h)
2508
PKIX_PL_Cert_GetBasicConstraints(
2510
PKIX_PL_CertBasicConstraints **pBasicConstraints,
2513
CERTCertificate *nssCert = NULL;
2514
CERTBasicConstraints nssBasicConstraint;
2516
PKIX_PL_CertBasicConstraints *basic;
2517
PKIX_Int32 pathLen = 0;
2518
PKIX_Boolean isCA = PKIX_FALSE;
2520
realBC, synthBC, absentBC
2521
} constraintSource = absentBC;
2523
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetBasicConstraints");
2524
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pBasicConstraints);
2526
/* if we don't have a cached copy from before, we create one */
2527
if ((cert->certBasicConstraints == NULL) &&
2528
(!cert->basicConstraintsAbsent)) {
2530
PKIX_OBJECT_LOCK(cert);
2532
if ((cert->certBasicConstraints == NULL) &&
2533
(!cert->basicConstraintsAbsent)) {
2535
nssCert = cert->nssCert;
2538
"\t\tCalling Cert_FindBasicConstraintExten\n");
2539
rv = CERT_FindBasicConstraintExten
2540
(nssCert, &nssBasicConstraint);
2541
if (rv == SECSuccess) {
2542
constraintSource = realBC;
2545
if (constraintSource == absentBC) {
2546
/* can we deduce it's a CA and create a
2547
synthetic constraint?
2549
CERTCertTrust trust;
2550
rv = CERT_GetCertTrust(nssCert, &trust);
2551
if (rv == SECSuccess) {
2552
int anyWantedFlag = CERTDB_TRUSTED_CA | CERTDB_VALID_CA;
2553
if ((trust.sslFlags & anyWantedFlag)
2554
|| (trust.emailFlags & anyWantedFlag)
2555
|| (trust.objectSigningFlags & anyWantedFlag)) {
2557
constraintSource = synthBC;
2562
if (constraintSource == absentBC) {
2563
cert->basicConstraintsAbsent = PKIX_TRUE;
2564
*pBasicConstraints = NULL;
2569
if (constraintSource == synthBC) {
2571
pathLen = PKIX_UNLIMITED_PATH_CONSTRAINT;
2573
isCA = (nssBasicConstraint.isCA)?PKIX_TRUE:PKIX_FALSE;
2575
/* The pathLen has meaning only for CAs */
2577
if (CERT_UNLIMITED_PATH_CONSTRAINT ==
2578
nssBasicConstraint.pathLenConstraint) {
2579
pathLen = PKIX_UNLIMITED_PATH_CONSTRAINT;
2581
pathLen = nssBasicConstraint.pathLenConstraint;
2586
PKIX_CHECK(pkix_pl_CertBasicConstraints_Create
2587
(isCA, pathLen, &basic, plContext),
2588
PKIX_CERTBASICCONSTRAINTSCREATEFAILED);
2590
/* save a cached copy in case it is asked for again */
2591
cert->certBasicConstraints = basic;
2594
PKIX_INCREF(cert->certBasicConstraints);
2595
*pBasicConstraints = cert->certBasicConstraints;
2598
PKIX_OBJECT_UNLOCK(lockedObject);
2603
* FUNCTION: PKIX_PL_Cert_GetPolicyInformation
2604
* (see comments in pkix_pl_pki.h)
2607
PKIX_PL_Cert_GetPolicyInformation(
2609
PKIX_List **pPolicyInfo,
2612
PKIX_List *policyList = NULL;
2614
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyInformation");
2615
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPolicyInfo);
2617
/* if we don't have a cached copy from before, we create one */
2618
if ((cert->certPolicyInfos == NULL) &&
2619
(!cert->policyInfoAbsent)) {
2621
PKIX_OBJECT_LOCK(cert);
2623
if ((cert->certPolicyInfos == NULL) &&
2624
(!cert->policyInfoAbsent)) {
2626
PKIX_CHECK(pkix_pl_Cert_DecodePolicyInfo
2627
(cert->nssCert, &policyList, plContext),
2628
PKIX_CERTDECODEPOLICYINFOFAILED);
2631
cert->policyInfoAbsent = PKIX_TRUE;
2632
*pPolicyInfo = NULL;
2637
PKIX_OBJECT_UNLOCK(cert);
2639
/* save a cached copy in case it is asked for again */
2640
cert->certPolicyInfos = policyList;
2643
PKIX_INCREF(cert->certPolicyInfos);
2645
*pPolicyInfo = cert->certPolicyInfos;
2648
PKIX_OBJECT_UNLOCK(lockedObject);
2653
* FUNCTION: PKIX_PL_Cert_GetPolicyMappings (see comments in pkix_pl_pki.h)
2656
PKIX_PL_Cert_GetPolicyMappings(
2658
PKIX_List **pPolicyMappings, /* list of PKIX_PL_CertPolicyMap */
2661
PKIX_List *policyMappings = NULL; /* list of PKIX_PL_CertPolicyMap */
2663
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyMappings");
2664
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPolicyMappings);
2666
/* if we don't have a cached copy from before, we create one */
2667
if (!(cert->certPolicyMappings) && !(cert->policyMappingsAbsent)) {
2669
PKIX_OBJECT_LOCK(cert);
2671
if (!(cert->certPolicyMappings) &&
2672
!(cert->policyMappingsAbsent)) {
2674
PKIX_CHECK(pkix_pl_Cert_DecodePolicyMapping
2675
(cert->nssCert, &policyMappings, plContext),
2676
PKIX_CERTDECODEPOLICYMAPPINGFAILED);
2678
if (!policyMappings) {
2679
cert->policyMappingsAbsent = PKIX_TRUE;
2680
*pPolicyMappings = NULL;
2685
PKIX_OBJECT_UNLOCK(cert);
2687
/* save a cached copy in case it is asked for again */
2688
cert->certPolicyMappings = policyMappings;
2691
PKIX_INCREF(cert->certPolicyMappings);
2692
*pPolicyMappings = cert->certPolicyMappings;
2695
PKIX_OBJECT_UNLOCK(lockedObject);
2700
* FUNCTION: PKIX_PL_Cert_GetRequireExplicitPolicy
2701
* (see comments in pkix_pl_pki.h)
2704
PKIX_PL_Cert_GetRequireExplicitPolicy(
2706
PKIX_Int32 *pSkipCerts,
2709
PKIX_Int32 explicitPolicySkipCerts = 0;
2710
PKIX_Int32 inhibitMappingSkipCerts = 0;
2712
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetRequireExplicitPolicy");
2713
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
2715
if (!(cert->policyConstraintsProcessed)) {
2716
PKIX_OBJECT_LOCK(cert);
2718
if (!(cert->policyConstraintsProcessed)) {
2721
* If we can't process it now, we probably will be
2722
* unable to process it later. Set the default value.
2724
cert->policyConstraintsProcessed = PKIX_TRUE;
2725
cert->policyConstraintsExplicitPolicySkipCerts = -1;
2726
cert->policyConstraintsInhibitMappingSkipCerts = -1;
2728
PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints
2730
&explicitPolicySkipCerts,
2731
&inhibitMappingSkipCerts,
2733
PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED);
2735
cert->policyConstraintsExplicitPolicySkipCerts =
2736
explicitPolicySkipCerts;
2737
cert->policyConstraintsInhibitMappingSkipCerts =
2738
inhibitMappingSkipCerts;
2741
PKIX_OBJECT_UNLOCK(cert);
2744
*pSkipCerts = cert->policyConstraintsExplicitPolicySkipCerts;
2747
PKIX_OBJECT_UNLOCK(lockedObject);
2752
* FUNCTION: PKIX_PL_Cert_GetPolicyMappingInhibited
2753
* (see comments in pkix_pl_pki.h)
2756
PKIX_PL_Cert_GetPolicyMappingInhibited(
2758
PKIX_Int32 *pSkipCerts,
2761
PKIX_Int32 explicitPolicySkipCerts = 0;
2762
PKIX_Int32 inhibitMappingSkipCerts = 0;
2764
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyMappingInhibited");
2765
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
2767
if (!(cert->policyConstraintsProcessed)) {
2768
PKIX_OBJECT_LOCK(cert);
2770
if (!(cert->policyConstraintsProcessed)) {
2773
* If we can't process it now, we probably will be
2774
* unable to process it later. Set the default value.
2776
cert->policyConstraintsProcessed = PKIX_TRUE;
2777
cert->policyConstraintsExplicitPolicySkipCerts = -1;
2778
cert->policyConstraintsInhibitMappingSkipCerts = -1;
2780
PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints
2782
&explicitPolicySkipCerts,
2783
&inhibitMappingSkipCerts,
2785
PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED);
2787
cert->policyConstraintsExplicitPolicySkipCerts =
2788
explicitPolicySkipCerts;
2789
cert->policyConstraintsInhibitMappingSkipCerts =
2790
inhibitMappingSkipCerts;
2793
PKIX_OBJECT_UNLOCK(cert);
2796
*pSkipCerts = cert->policyConstraintsInhibitMappingSkipCerts;
2799
PKIX_OBJECT_UNLOCK(lockedObject);
2804
* FUNCTION: PKIX_PL_Cert_GetInhibitAnyPolicy (see comments in pkix_pl_pki.h)
2807
PKIX_PL_Cert_GetInhibitAnyPolicy(
2809
PKIX_Int32 *pSkipCerts,
2812
PKIX_Int32 skipCerts = 0;
2814
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetInhibitAnyPolicy");
2815
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
2817
if (!(cert->inhibitAnyPolicyProcessed)) {
2819
PKIX_OBJECT_LOCK(cert);
2821
if (!(cert->inhibitAnyPolicyProcessed)) {
2824
* If we can't process it now, we probably will be
2825
* unable to process it later. Set the default value.
2827
cert->inhibitAnyPolicyProcessed = PKIX_TRUE;
2828
cert->inhibitAnySkipCerts = -1;
2830
PKIX_CHECK(pkix_pl_Cert_DecodeInhibitAnyPolicy
2831
(cert->nssCert, &skipCerts, plContext),
2832
PKIX_CERTDECODEINHIBITANYPOLICYFAILED);
2834
cert->inhibitAnySkipCerts = skipCerts;
2837
PKIX_OBJECT_UNLOCK(cert);
2841
PKIX_OBJECT_UNLOCK(lockedObject);
2842
*pSkipCerts = cert->inhibitAnySkipCerts;
2847
* FUNCTION: PKIX_PL_Cert_AreCertPoliciesCritical
2848
* (see comments in pkix_pl_pki.h)
2851
PKIX_PL_Cert_AreCertPoliciesCritical(
2853
PKIX_Boolean *pCritical,
2856
PKIX_Boolean criticality = PKIX_FALSE;
2858
PKIX_ENTER(CERT, "PKIX_PL_Cert_AreCertPoliciesCritical");
2859
PKIX_NULLCHECK_TWO(cert, pCritical);
2861
PKIX_CHECK(pkix_pl_Cert_IsExtensionCritical(
2863
SEC_OID_X509_CERTIFICATE_POLICIES,
2866
PKIX_CERTISEXTENSIONCRITICALFAILED);
2868
*pCritical = criticality;
2875
* FUNCTION: PKIX_PL_Cert_VerifySignature (see comments in pkix_pl_pki.h)
2878
PKIX_PL_Cert_VerifySignature(
2880
PKIX_PL_PublicKey *pubKey,
2883
CERTCertificate *nssCert = NULL;
2884
SECKEYPublicKey *nssPubKey = NULL;
2885
CERTSignedData *tbsCert = NULL;
2886
PKIX_PL_Cert *cachedCert = NULL;
2887
PKIX_Error *verifySig = NULL;
2888
PKIX_Error *cachedSig = NULL;
2890
PKIX_Boolean certEqual = PKIX_FALSE;
2891
PKIX_Boolean certInHash = PKIX_FALSE;
2893
PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifySignature");
2894
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pubKey);
2896
verifySig = PKIX_PL_HashTable_Lookup
2897
(cachedCertSigTable,
2898
(PKIX_PL_Object *) pubKey,
2899
(PKIX_PL_Object **) &cachedCert,
2902
if (cachedCert != NULL && verifySig == NULL) {
2903
/* Cached Signature Table lookup succeed */
2904
PKIX_EQUALS(cert, cachedCert, &certEqual, plContext,
2905
PKIX_OBJECTEQUALSFAILED);
2906
if (certEqual == PKIX_TRUE) {
2909
/* Different PubKey may hash to same value, skip add */
2910
certInHash = PKIX_TRUE;
2913
nssCert = cert->nssCert;
2914
tbsCert = &nssCert->signatureWrap;
2916
PKIX_CERT_DEBUG("\t\tCalling SECKEY_ExtractPublicKey).\n");
2917
nssPubKey = SECKEY_ExtractPublicKey(pubKey->nssSPKI);
2919
PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED);
2922
PKIX_CERT_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey).\n");
2923
status = CERT_VerifySignedDataWithPublicKey(tbsCert, nssPubKey, NULL);
2925
if (status != SECSuccess) {
2926
PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHISPUBLICKEY);
2929
if (certInHash == PKIX_FALSE) {
2930
cachedSig = PKIX_PL_HashTable_Add
2931
(cachedCertSigTable,
2932
(PKIX_PL_Object *) pubKey,
2933
(PKIX_PL_Object *) cert,
2936
if (cachedSig != NULL) {
2937
PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed\n");
2943
PKIX_CERT_DEBUG("\t\tCalling SECKEY_DestroyPublicKey).\n");
2944
SECKEY_DestroyPublicKey(nssPubKey);
2947
PKIX_DECREF(cachedCert);
2948
PKIX_DECREF(verifySig);
2949
PKIX_DECREF(cachedSig);
2955
* FUNCTION: PKIX_PL_Cert_CheckValidity (see comments in pkix_pl_pki.h)
2958
PKIX_PL_Cert_CheckValidity(
2963
SECCertTimeValidity val;
2966
PKIX_ENTER(CERT, "PKIX_PL_Cert_CheckValidity");
2967
PKIX_NULLCHECK_ONE(cert);
2969
/* if the caller supplies a date, we use it; else, use current time */
2971
PKIX_CHECK(pkix_pl_Date_GetPRTime
2972
(date, &timeToCheck, plContext),
2973
PKIX_DATEGETPRTIMEFAILED);
2975
timeToCheck = PR_Now();
2978
PKIX_CERT_DEBUG("\t\tCalling CERT_CheckCertValidTimes).\n");
2979
val = CERT_CheckCertValidTimes(cert->nssCert, timeToCheck, PKIX_FALSE);
2980
if (val != secCertTimeValid){
2981
PKIX_ERROR(PKIX_CERTCHECKCERTVALIDTIMESFAILED);
2989
* FUNCTION: PKIX_PL_Cert_GetValidityNotAfter (see comments in pkix_pl_pki.h)
2992
PKIX_PL_Cert_GetValidityNotAfter(
2994
PKIX_PL_Date **pDate,
2998
SECStatus rv = SECFailure;
3000
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetValidityNotAfter");
3001
PKIX_NULLCHECK_TWO(cert, pDate);
3003
PKIX_DATE_DEBUG("\t\tCalling DER_DecodeTimeChoice).\n");
3004
rv = DER_DecodeTimeChoice(&prtime, &(cert->nssCert->validity.notAfter));
3005
if (rv != SECSuccess){
3006
PKIX_ERROR(PKIX_DERDECODETIMECHOICEFAILED);
3009
PKIX_CHECK(pkix_pl_Date_CreateFromPRTime
3010
(prtime, pDate, plContext),
3011
PKIX_DATECREATEFROMPRTIMEFAILED);
3018
* FUNCTION: PKIX_PL_Cert_VerifyKeyUsage (see comments in pkix_pl_pki.h)
3021
PKIX_PL_Cert_VerifyKeyUsage(
3023
PKIX_UInt32 keyUsage,
3026
CERTCertificate *nssCert = NULL;
3027
PKIX_UInt32 nssKeyUsage = 0;
3030
PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifyKeyUsage");
3031
PKIX_NULLCHECK_TWO(cert, cert->nssCert);
3033
nssCert = cert->nssCert;
3035
/* if cert doesn't have keyUsage extension, all keyUsages are valid */
3036
if (!nssCert->keyUsagePresent){
3040
if (keyUsage & PKIX_DIGITAL_SIGNATURE){
3041
nssKeyUsage = nssKeyUsage | KU_DIGITAL_SIGNATURE;
3044
if (keyUsage & PKIX_NON_REPUDIATION){
3045
nssKeyUsage = nssKeyUsage | KU_NON_REPUDIATION;
3048
if (keyUsage & PKIX_KEY_ENCIPHERMENT){
3049
nssKeyUsage = nssKeyUsage | KU_KEY_ENCIPHERMENT;
3052
if (keyUsage & PKIX_DATA_ENCIPHERMENT){
3053
nssKeyUsage = nssKeyUsage | KU_DATA_ENCIPHERMENT;
3056
if (keyUsage & PKIX_KEY_AGREEMENT){
3057
nssKeyUsage = nssKeyUsage | KU_KEY_AGREEMENT;
3060
if (keyUsage & PKIX_KEY_CERT_SIGN){
3061
nssKeyUsage = nssKeyUsage | KU_KEY_CERT_SIGN;
3064
if (keyUsage & PKIX_CRL_SIGN){
3065
nssKeyUsage = nssKeyUsage | KU_CRL_SIGN;
3068
if (keyUsage & PKIX_ENCIPHER_ONLY){
3069
nssKeyUsage = nssKeyUsage | 0x01;
3072
if (keyUsage & PKIX_DECIPHER_ONLY){
3073
/* XXX we should support this once it is fixed in NSS */
3074
PKIX_ERROR(PKIX_DECIPHERONLYKEYUSAGENOTSUPPORTED);
3077
status = CERT_CheckKeyUsage(nssCert, nssKeyUsage);
3078
if (status != SECSuccess) {
3079
PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED);
3087
* FUNCTION: PKIX_PL_Cert_GetNameConstraints
3088
* (see comments in pkix_pl_pki.h)
3091
PKIX_PL_Cert_GetNameConstraints(
3093
PKIX_PL_CertNameConstraints **pNameConstraints,
3096
PKIX_PL_CertNameConstraints *nameConstraints = NULL;
3098
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetNameConstraints");
3099
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pNameConstraints);
3101
/* if we don't have a cached copy from before, we create one */
3102
if (cert->nameConstraints == NULL && !cert->nameConstraintsAbsent) {
3104
PKIX_OBJECT_LOCK(cert);
3106
if (cert->nameConstraints == NULL &&
3107
!cert->nameConstraintsAbsent) {
3109
PKIX_CHECK(pkix_pl_CertNameConstraints_Create
3110
(cert->nssCert, &nameConstraints, plContext),
3111
PKIX_CERTNAMECONSTRAINTSCREATEFAILED);
3113
if (nameConstraints == NULL) {
3114
cert->nameConstraintsAbsent = PKIX_TRUE;
3117
cert->nameConstraints = nameConstraints;
3120
PKIX_OBJECT_UNLOCK(cert);
3124
PKIX_INCREF(cert->nameConstraints);
3126
*pNameConstraints = cert->nameConstraints;
3129
PKIX_OBJECT_UNLOCK(lockedObject);
3134
* FUNCTION: PKIX_PL_Cert_CheckNameConstraints
3135
* (see comments in pkix_pl_pki.h)
3138
PKIX_PL_Cert_CheckNameConstraints(
3140
PKIX_PL_CertNameConstraints *nameConstraints,
3143
PKIX_Boolean checkPass = PKIX_TRUE;
3144
CERTGeneralName *nssSubjectNames = NULL;
3145
PRArenaPool *arena = NULL;
3147
PKIX_ENTER(CERT, "PKIX_PL_Cert_CheckNameConstraints");
3148
PKIX_NULLCHECK_ONE(cert);
3150
if (nameConstraints != NULL) {
3152
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
3153
if (arena == NULL) {
3154
PKIX_ERROR(PKIX_PORTNEWARENAFAILED);
3157
/* This NSS call returns both Subject and Subject Alt Names */
3158
PKIX_CERT_DEBUG("\t\tCalling CERT_GetCertificateNames\n");
3159
nssSubjectNames = CERT_GetCertificateNames
3160
(cert->nssCert, arena);
3162
PKIX_CHECK(pkix_pl_CertNameConstraints_CheckNameSpaceNssNames
3167
PKIX_CERTNAMECONSTRAINTSCHECKNAMESPACENSSNAMESFAILED);
3169
if (checkPass != PKIX_TRUE) {
3170
PKIX_ERROR(PKIX_CERTFAILEDNAMECONSTRAINTSCHECKING);
3176
PORT_FreeArena(arena, PR_FALSE);
3183
* FUNCTION: PKIX_PL_Cert_MergeNameConstraints
3184
* (see comments in pkix_pl_pki.h)
3187
PKIX_PL_Cert_MergeNameConstraints(
3188
PKIX_PL_CertNameConstraints *firstNC,
3189
PKIX_PL_CertNameConstraints *secondNC,
3190
PKIX_PL_CertNameConstraints **pResultNC,
3193
PKIX_PL_CertNameConstraints *mergedNC = NULL;
3195
PKIX_ENTER(CERT, "PKIX_PL_Cert_MergeNameConstraints");
3196
PKIX_NULLCHECK_TWO(firstNC, pResultNC);
3198
if (secondNC == NULL) {
3200
PKIX_INCREF(firstNC);
3201
*pResultNC = firstNC;
3206
PKIX_CHECK(pkix_pl_CertNameConstraints_Merge
3207
(firstNC, secondNC, &mergedNC, plContext),
3208
PKIX_CERTNAMECONSTRAINTSMERGEFAILED);
3210
*pResultNC = mergedNC;
3217
* FUNCTION: PKIX_PL_Cert_IsCertTrusted
3218
* (see comments in pkix_pl_pki.h)
3221
PKIX_PL_Cert_IsCertTrusted(
3223
PKIX_Boolean *pTrusted,
3226
PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
3227
SECCertUsage certUsage = 0;
3228
PKIX_Boolean trusted = PKIX_FALSE;
3229
SECStatus rv = SECFailure;
3230
unsigned int requiredFlags;
3231
SECTrustType trustType;
3232
CERTCertTrust trust;
3233
CERTCertificate *nssCert = NULL;
3234
SECCertificateUsage certificateUsage;
3236
PKIX_ENTER(CERT, "pkix_pl_Cert_IsCertTrusted");
3237
PKIX_NULLCHECK_TWO(cert, pTrusted);
3239
/* no key usage information and store is not trusted */
3240
if (plContext == NULL || cert->store == NULL) {
3241
*pTrusted = PKIX_FALSE;
3246
PKIX_CHECK(PKIX_CertStore_GetTrustCallback
3247
(cert->store, &trustCallback, plContext),
3248
PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
3250
PKIX_CHECK_ONLY_FATAL(trustCallback
3251
(cert->store, cert, &trusted, plContext),
3252
PKIX_CHECKTRUSTCALLBACKFAILED);
3254
if (PKIX_ERROR_RECEIVED || (trusted == PKIX_FALSE)) {
3256
*pTrusted = PKIX_FALSE;
3262
certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
3264
/* ensure we obtained a single usage bit only */
3265
PORT_Assert(!(certificateUsage & (certificateUsage - 1)));
3267
/* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
3268
while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; }
3270
rv = CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, &trustType);
3271
if (rv != SECSuccess) {
3273
trustType = trustSSL;
3276
nssCert = cert->nssCert;
3278
rv = CERT_GetCertTrust(nssCert, &trust);
3279
if (rv == SECSuccess) {
3280
unsigned int certFlags;
3281
certFlags = SEC_GET_TRUST_FLAGS((&trust), trustType);
3282
if ((certFlags & requiredFlags) == requiredFlags) {
3283
trusted = PKIX_TRUE;
3287
*pTrusted = trusted;
3294
* FUNCTION: PKIX_PL_Cert_GetCacheFlag (see comments in pkix_pl_pki.h)
3297
PKIX_PL_Cert_GetCacheFlag(
3299
PKIX_Boolean *pCacheFlag,
3302
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCacheFlag");
3303
PKIX_NULLCHECK_TWO(cert, pCacheFlag);
3305
*pCacheFlag = cert->cacheFlag;
3311
* FUNCTION: PKIX_PL_Cert_SetCacheFlag (see comments in pkix_pl_pki.h)
3314
PKIX_PL_Cert_SetCacheFlag(
3316
PKIX_Boolean cacheFlag,
3319
PKIX_ENTER(CERT, "PKIX_PL_Cert_SetCacheFlag");
3320
PKIX_NULLCHECK_ONE(cert);
3322
cert->cacheFlag = cacheFlag;
3328
* FUNCTION: PKIX_PL_Cert_GetTrustCertStore (see comments in pkix_pl_pki.h)
3331
PKIX_PL_Cert_GetTrustCertStore(
3333
PKIX_CertStore **pTrustCertStore,
3336
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetTrustCertStore");
3337
PKIX_NULLCHECK_TWO(cert, pTrustCertStore);
3339
PKIX_INCREF(cert->store);
3340
*pTrustCertStore = cert->store;
3346
* FUNCTION: PKIX_PL_Cert_SetTrustCertStore (see comments in pkix_pl_pki.h)
3349
PKIX_PL_Cert_SetTrustCertStore(
3351
PKIX_CertStore *trustCertStore,
3354
PKIX_ENTER(CERT, "PKIX_PL_Cert_SetTrustCertStore");
3355
PKIX_NULLCHECK_TWO(cert, trustCertStore);
3357
PKIX_INCREF(trustCertStore);
3358
cert->store = trustCertStore;
3364
* FUNCTION: PKIX_PL_Cert_GetAuthorityInfoAccess
3365
* (see comments in pkix_pl_pki.h)
3368
PKIX_PL_Cert_GetAuthorityInfoAccess(
3370
PKIX_List **pAiaList, /* of PKIX_PL_InfoAccess */
3373
PKIX_List *aiaList = NULL; /* of PKIX_PL_InfoAccess */
3374
SECItem *encodedAIA = NULL;
3375
CERTAuthInfoAccess **aia = NULL;
3376
PRArenaPool *arena = NULL;
3379
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAuthorityInfoAccess");
3380
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAiaList);
3382
/* if we don't have a cached copy from before, we create one */
3383
if (cert->authorityInfoAccess == NULL) {
3385
PKIX_OBJECT_LOCK(cert);
3387
if (cert->authorityInfoAccess == NULL) {
3389
PKIX_PL_NSSCALLRV(CERT, encodedAIA, SECITEM_AllocItem,
3392
if (encodedAIA == NULL) {
3396
PKIX_PL_NSSCALLRV(CERT, rv, CERT_FindCertExtension,
3398
SEC_OID_X509_AUTH_INFO_ACCESS,
3401
if (rv == SECFailure) {
3405
PKIX_PL_NSSCALLRV(CERT, arena, PORT_NewArena,
3406
(DER_DEFAULT_CHUNKSIZE));
3408
if (arena == NULL) {
3413
(CERT, aia, CERT_DecodeAuthInfoAccessExtension,
3414
(arena, encodedAIA));
3416
PKIX_CHECK(pkix_pl_InfoAccess_CreateList
3417
(aia, &aiaList, plContext),
3418
PKIX_INFOACCESSCREATELISTFAILED);
3420
cert->authorityInfoAccess = aiaList;
3423
PKIX_OBJECT_UNLOCK(cert);
3426
PKIX_INCREF(cert->authorityInfoAccess);
3428
*pAiaList = cert->authorityInfoAccess;
3431
PKIX_OBJECT_UNLOCK(lockedObject);
3432
if (arena != NULL) {
3433
PORT_FreeArena(arena, PR_FALSE);
3436
if (encodedAIA != NULL) {
3437
SECITEM_FreeItem(encodedAIA, PR_TRUE);
3443
/* XXX Following defines belongs to NSS */
3444
static const unsigned char siaOIDString[] = {0x2b, 0x06, 0x01, 0x05, 0x05,
3446
#define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
3449
* FUNCTION: PKIX_PL_Cert_GetSubjectInfoAccess
3450
* (see comments in pkix_pl_pki.h)
3453
PKIX_PL_Cert_GetSubjectInfoAccess(
3455
PKIX_List **pSiaList, /* of PKIX_PL_InfoAccess */
3458
PKIX_List *siaList; /* of PKIX_PL_InfoAccess */
3459
SECItem siaOID = OI(siaOIDString);
3460
SECItem *encodedSubjInfoAccess = NULL;
3461
CERTAuthInfoAccess **subjInfoAccess = NULL;
3462
PRArenaPool *arena = NULL;
3465
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectInfoAccess");
3466
PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSiaList);
3469
* Codes to deal with SubjectInfoAccess OID should be moved to
3470
* NSS soon. I implemented them here so we don't touch NSS
3471
* source tree, from JP's suggestion.
3474
/* if we don't have a cached copy from before, we create one */
3475
if (cert->subjectInfoAccess == NULL) {
3477
PKIX_OBJECT_LOCK(cert);
3479
if (cert->subjectInfoAccess == NULL) {
3481
encodedSubjInfoAccess = SECITEM_AllocItem(NULL, NULL, 0);
3482
if (encodedSubjInfoAccess == NULL) {
3487
("\t\tCalling CERT_FindCertExtensionByOID).\n");
3488
rv = CERT_FindCertExtensionByOID
3489
(cert->nssCert, &siaOID, encodedSubjInfoAccess);
3491
if (rv == SECFailure) {
3495
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
3496
if (arena == NULL) {
3501
* Decode Subject Information Access -
3502
* since its type is the same as Authority Information
3503
* Access, reuse the call. NSS- change name to avoid
3507
("\t\tCalling CERT_DecodeAuthInfoAccessExtension).\n");
3508
subjInfoAccess = CERT_DecodeAuthInfoAccessExtension
3509
(arena, encodedSubjInfoAccess);
3511
PKIX_CHECK(pkix_pl_InfoAccess_CreateList
3512
(subjInfoAccess, &siaList, plContext),
3513
PKIX_INFOACCESSCREATELISTFAILED);
3515
cert->subjectInfoAccess = siaList;
3519
PKIX_OBJECT_UNLOCK(cert);
3522
PKIX_INCREF(cert->subjectInfoAccess);
3523
*pSiaList = cert->subjectInfoAccess;
3526
PKIX_OBJECT_UNLOCK(lockedObject);
3527
if (arena != NULL) {
3528
PORT_FreeArena(arena, PR_FALSE);
3531
if (encodedSubjInfoAccess != NULL) {
3532
SECITEM_FreeItem(encodedSubjInfoAccess, PR_TRUE);
3538
* FUNCTION: PKIX_PL_Cert_GetCERTCertificate
3539
* (see comments in pkix_pl_pki.h)
3542
PKIX_PL_Cert_GetCERTCertificate(
3544
CERTCertificate **pnssCert,
3547
PKIX_ENTER(CERT, "PKIX_PL_Cert_GetNssCert");
3548
PKIX_NULLCHECK_TWO(cert, pnssCert);
3550
*pnssCert = CERT_DupCertificate(cert->nssCert);