2 * Copyright (c) 2000-2010 Apple Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 * CLCertExtensions.cpp - extensions support. A major component of DecodedCert.
24 #include "DecodedCert.h"
25 #include "cldebugging.h"
26 #include "CLCertExtensions.h"
27 #include "CLFieldsCommon.h"
28 #include "clNssUtils.h"
29 #include "clNameUtils.h"
30 #include <security_utilities/utilities.h>
31 #include <Security/oidscert.h>
32 #include <Security/oidsattr.h>
33 #include <Security/cssmerr.h>
34 #include <Security/x509defs.h>
35 #include <Security/certextensions.h>
36 #include <security_utilities/globalizer.h>
37 #include <Security/certExtensionTemplates.h>
38 #include <Security/SecAsn1Templates.h>
41 *** get/set/free functions called out from CertFields.cpp
46 *** CDSA format CE_KeyUsage
47 *** NSS format CSSM_DATA, length 2
48 *** OID CSSMOID_KeyUsage
51 void setFieldKeyUsage(
53 const CssmData
&fieldValue
)
55 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
,
57 CE_KeyUsage
*cdsaObj
= (CE_KeyUsage
*)cssmExt
->value
.parsedValue
;
59 /* Alloc an NSS-style key usage in cert.coder's memory */
60 SecNssCoder
&coder
= cert
.coder();
61 CSSM_DATA
*nssObj
= (CSSM_DATA
*)coder
.malloc(sizeof(CSSM_DATA
));
62 coder
.allocItem(*nssObj
, 2);
64 /* cdsaObj --> nssObj */
65 nssObj
->Data
[0] = (*cdsaObj
) >> 8;
66 nssObj
->Data
[1] = *cdsaObj
;
68 /* Adjust length for BIT STRING encoding */
69 clCssmBitStringToNss(*nssObj
);
71 /* add to mExtensions */
72 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
73 kSecAsn1KeyUsageTemplate
);
77 bool getFieldKeyUsage(
79 unsigned index
, // which occurrence (0 = first)
80 uint32
&numFields
, // RETURNED
81 CssmOwnedData
&fieldValue
)
83 const DecodedExten
*decodedExt
;
88 brtn
= cert
.GetExtenTop
<CSSM_DATA
, CE_KeyUsage
>(
100 /* make a copy - can't modify length in place */
101 CSSM_DATA bitString
= *nssObj
;
102 clNssBitStringToCssm(bitString
);
103 size_t toCopy
= bitString
.Length
;
105 /* I hope I never see this... */
106 clErrorLog("getFieldKeyUsage: KeyUsage larger than 2 bytes!");
109 unsigned char bits
[2] = {0, 0};
110 memmove(bits
, bitString
.Data
, toCopy
);
111 *cdsaObj
= (((unsigned)bits
[0]) << 8) | bits
[1];
113 /* pass back to caller */
114 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
119 *** Basic Constraints
120 *** CDSA format: CE_BasicConstraints
121 *** NSS format CE_BasicConstraints
122 *** OID CSSMOID_BasicConstraints
125 void setFieldBasicConstraints(
127 const CssmData
&fieldValue
)
129 CSSM_X509_EXTENSION_PTR cssmExt
=
130 verifySetFreeExtension(fieldValue
, false);
131 CE_BasicConstraints
*cdsaObj
=
132 (CE_BasicConstraints
*)cssmExt
->value
.parsedValue
;
134 /* Alloc an NSS-style BasicConstraints in cert.coder's memory */
135 SecNssCoder
&coder
= cert
.coder();
136 NSS_BasicConstraints
*nssObj
=
137 (NSS_BasicConstraints
*)coder
.malloc(sizeof(NSS_BasicConstraints
));
138 memset(nssObj
, 0, sizeof(*nssObj
));
140 /* cdsaObj --> nssObj */
141 ArenaAllocator
arenaAlloc(coder
);
142 clCssmBoolToNss(cdsaObj
->cA
, nssObj
->cA
, arenaAlloc
);
143 if(cdsaObj
->pathLenConstraintPresent
) {
144 clIntToData(cdsaObj
->pathLenConstraint
,
145 nssObj
->pathLenConstraint
, arenaAlloc
);
148 /* add to mExtensions */
149 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
150 kSecAsn1BasicConstraintsTemplate
);
154 bool getFieldBasicConstraints(
156 unsigned index
, // which occurrence (0 = first)
157 uint32
&numFields
, // RETURNED
158 CssmOwnedData
&fieldValue
)
160 const DecodedExten
*decodedExt
;
161 NSS_BasicConstraints
*nssObj
;
162 CE_BasicConstraints
*cdsaObj
;
165 brtn
= cert
.GetExtenTop
<NSS_BasicConstraints
, CE_BasicConstraints
>(
168 fieldValue
.allocator
,
169 CSSMOID_BasicConstraints
,
177 if(nssObj
->cA
.Data
== NULL
) {
179 cdsaObj
->cA
= CSSM_FALSE
;
182 cdsaObj
->cA
= clNssBoolToCssm(nssObj
->cA
);
184 if(nssObj
->pathLenConstraint
.Data
== NULL
) {
186 cdsaObj
->pathLenConstraintPresent
= CSSM_FALSE
;
187 cdsaObj
->pathLenConstraint
= 0;
190 cdsaObj
->pathLenConstraintPresent
= CSSM_TRUE
;
191 cdsaObj
->pathLenConstraint
= clDataToInt(nssObj
->pathLenConstraint
);
194 /* pass back to caller */
195 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
200 *** Extended Key Usage
201 *** CDSA format: CE_ExtendedKeyUsage
202 *** NSS format: NSS_ExtKeyUsage
203 *** OID CSSMOID_ExtendedKeyUsage
205 void setFieldExtKeyUsage(
207 const CssmData
&fieldValue
)
209 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
,
211 CE_ExtendedKeyUsage
*cdsaObj
=
212 (CE_ExtendedKeyUsage
*)cssmExt
->value
.parsedValue
;
214 SecNssCoder
&coder
= cert
.coder();
215 NSS_ExtKeyUsage
*nssObj
=
216 (NSS_ExtKeyUsage
*)coder
.malloc(sizeof(NSS_ExtKeyUsage
));
217 memset(nssObj
, 0, sizeof(*nssObj
));
218 if(cdsaObj
->numPurposes
!= 0) {
220 (CSSM_OID
**)clNssNullArray(cdsaObj
->numPurposes
, coder
);
223 /* cdsaObj --> nssObj, one 'purpose' (OID) at a time */
224 for(unsigned dex
=0; dex
<cdsaObj
->numPurposes
; dex
++) {
225 nssObj
->purposes
[dex
] = (CSSM_OID
*)coder
.malloc(sizeof(CSSM_OID
));
226 coder
.allocCopyItem(cdsaObj
->purposes
[dex
],
227 *nssObj
->purposes
[dex
]);
230 /* add to mExtensions */
231 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
232 kSecAsn1ExtKeyUsageTemplate
);
235 bool getFieldExtKeyUsage(
237 unsigned index
, // which occurrence (0 = first)
238 uint32
&numFields
, // RETURNED
239 CssmOwnedData
&fieldValue
)
241 const DecodedExten
*decodedExt
;
242 NSS_ExtKeyUsage
*nssObj
;
243 CE_ExtendedKeyUsage
*cdsaObj
;
245 Allocator
&alloc
= fieldValue
.allocator
;
247 brtn
= cert
.GetExtenTop
<NSS_ExtKeyUsage
, CE_ExtendedKeyUsage
>(
251 CSSMOID_ExtendedKeyUsage
,
259 /* nssObj --> cdsaObj, one purpose at a time */
260 unsigned numPurposes
= clNssArraySize((const void **)nssObj
->purposes
);
261 cdsaObj
->numPurposes
= numPurposes
;
263 unsigned len
= numPurposes
* sizeof(CSSM_OID
);
264 cdsaObj
->purposes
= (CSSM_OID_PTR
)alloc
.malloc(len
);
265 memset(cdsaObj
->purposes
, 0, len
);
267 for(unsigned dex
=0; dex
<numPurposes
; dex
++) {
268 clAllocCopyData(alloc
, *nssObj
->purposes
[dex
], cdsaObj
->purposes
[dex
]);
271 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
275 void freeFieldExtKeyUsage(
276 CssmOwnedData
&fieldValue
)
278 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
, false);
279 Allocator
&alloc
= fieldValue
.allocator
;
280 CE_ExtendedKeyUsage
*cdsaObj
=
281 (CE_ExtendedKeyUsage
*)cssmExt
->value
.parsedValue
;
283 for(oidDex
=0; oidDex
<cdsaObj
->numPurposes
; oidDex
++) {
284 alloc
.free(cdsaObj
->purposes
[oidDex
].Data
);
286 alloc
.free(cdsaObj
->purposes
);
287 freeFieldExtenCommon(cssmExt
, alloc
); // frees extnId, parsedValue, BERvalue
291 *** Subject Key Identifier
292 *** CDSA format: CE_SubjectKeyID, which is just a CSSM_DATA
293 *** OID CSSMOID_SubjectKeyIdentifier
296 void setFieldSubjectKeyId(
298 const CssmData
&fieldValue
)
300 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
,
302 CE_SubjectKeyID
*cdsaObj
= (CE_SubjectKeyID
*)cssmExt
->value
.parsedValue
;
303 SecNssCoder
&coder
= cert
.coder();
304 CSSM_DATA
*nssObj
= (CSSM_DATA
*)coder
.malloc(sizeof(CSSM_DATA
));
305 coder
.allocCopyItem(*cdsaObj
, *nssObj
);
307 /* add to mExtensions */
308 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
309 kSecAsn1SubjectKeyIdTemplate
);
312 bool getFieldSubjectKeyId(
314 unsigned index
, // which occurrence (0 = first)
315 uint32
&numFields
, // RETURNED
316 CssmOwnedData
&fieldValue
)
318 const DecodedExten
*decodedExt
;
320 CE_SubjectKeyID
*cdsaObj
;
322 Allocator
&alloc
= fieldValue
.allocator
;
324 brtn
= cert
.GetExtenTop
<CSSM_DATA
, CE_SubjectKeyID
>(
328 CSSMOID_SubjectKeyIdentifier
,
336 /* if this fails, we're out of sync with nssExtenInfo[] in
337 * CLFieldsCommon.cpp */
338 assert(nssObj
!= NULL
);
339 clAllocCopyData(alloc
, *nssObj
, *cdsaObj
);
340 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
344 void freeFieldSubjectKeyId (
345 CssmOwnedData
&fieldValue
)
347 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
, false);
348 Allocator
&alloc
= fieldValue
.allocator
;
349 CE_SubjectKeyID
*cdsaObj
= (CE_SubjectKeyID
*)cssmExt
->value
.parsedValue
;
350 alloc
.free(cdsaObj
->Data
);
351 freeFieldExtenCommon(cssmExt
, alloc
); // frees extnId, parsedValue, BERvalue
355 *** Authority Key Identifier
356 *** CDSA format: CE_AuthorityKeyID
357 *** NSS format: NSS_AuthorityKeyId
358 *** OID CSSMOID_AuthorityKeyIdentifier
361 void setFieldAuthorityKeyId(
363 const CssmData
&fieldValue
)
365 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
,
367 CE_AuthorityKeyID
*cdsaObj
=
368 (CE_AuthorityKeyID
*)cssmExt
->value
.parsedValue
;
370 /* Alloc an NSS-style AuthorityKeyId in cert.coder's memory */
371 SecNssCoder
&coder
= cert
.coder();
372 NSS_AuthorityKeyId
*nssObj
=
373 (NSS_AuthorityKeyId
*)coder
.malloc(sizeof(NSS_AuthorityKeyId
));
374 memset(nssObj
, 0, sizeof(*nssObj
));
376 /* convert caller's CDSA-style CE_AuthorityKeyID to NSS */
377 CL_cssmAuthorityKeyIdToNss(*cdsaObj
, *nssObj
, coder
);
379 /* add to mExtensions */
380 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
381 kSecAsn1AuthorityKeyIdTemplate
);
384 bool getFieldAuthorityKeyId(
386 unsigned index
, // which occurrence (0 = first)
387 uint32
&numFields
, // RETURNED
388 CssmOwnedData
&fieldValue
)
390 const DecodedExten
*decodedExt
;
391 NSS_AuthorityKeyId
*nssObj
;
392 CE_AuthorityKeyID
*cdsaObj
;
394 Allocator
&alloc
= fieldValue
.allocator
;
396 brtn
= cert
.GetExtenTop
<NSS_AuthorityKeyId
, CE_AuthorityKeyID
>(
400 CSSMOID_AuthorityKeyIdentifier
,
407 assert(nssObj
!= NULL
);
409 /* nssObj --> cdsaObj */
410 CL_nssAuthorityKeyIdToCssm(*nssObj
, *cdsaObj
, cert
.coder(), alloc
);
412 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
416 void freeFieldAuthorityKeyId (
417 CssmOwnedData
&fieldValue
)
419 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
, false);
420 Allocator
&alloc
= fieldValue
.allocator
;
421 CE_AuthorityKeyID
*cdsaObj
= (CE_AuthorityKeyID
*)cssmExt
->value
.parsedValue
;
422 CL_freeAuthorityKeyId(*cdsaObj
, alloc
);
423 freeFieldExtenCommon(cssmExt
, alloc
); // frees extnId, parsedValue, BERvalue
427 *** Subject/Issuer alternate name
428 *** CDSA Format: CE_GeneralNames
429 *** NSS format: NSS_GeneralNames
430 *** OID: CSSMOID_SubjectAltName, CSSMOID_IssuerAltName
432 void setFieldSubjIssuerAltName(
434 const CssmData
&fieldValue
)
436 CSSM_X509_EXTENSION_PTR cssmExt
=
437 verifySetFreeExtension(fieldValue
, false);
438 CE_GeneralNames
*cdsaObj
= (CE_GeneralNames
*)cssmExt
->value
.parsedValue
;
440 /* Alloc an NSS-style GeneralNames in cert.coder's memory */
441 SecNssCoder
&coder
= cert
.coder();
442 NSS_GeneralNames
*nssObj
=
443 (NSS_GeneralNames
*)coder
.malloc(sizeof(NSS_GeneralNames
));
444 memset(nssObj
, 0, sizeof(*nssObj
));
446 /* cdsaObj --> nssObj */
447 CL_cssmGeneralNamesToNss(*cdsaObj
, *nssObj
, coder
);
449 /* add to mExtensions */
450 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
451 kSecAsn1GeneralNamesTemplate
);
454 bool getFieldSubjAltName(
456 unsigned index
, // which occurrence (0 = first)
457 uint32
&numFields
, // RETURNED
458 CssmOwnedData
&fieldValue
)
460 const DecodedExten
*decodedExt
;
461 NSS_GeneralNames
*nssObj
;
462 CE_GeneralNames
*cdsaObj
;
465 brtn
= cert
.GetExtenTop
<NSS_GeneralNames
, CE_GeneralNames
>(
468 fieldValue
.allocator
,
469 CSSMOID_SubjectAltName
,
476 CL_nssGeneralNamesToCssm(*nssObj
, *cdsaObj
,
477 cert
.coder(), fieldValue
.allocator
);
478 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
482 bool getFieldIssuerAltName(
484 unsigned index
, // which occurrence (0 = first)
485 uint32
&numFields
, // RETURNED
486 CssmOwnedData
&fieldValue
)
488 const DecodedExten
*decodedExt
;
489 NSS_GeneralNames
*nssObj
;
490 CE_GeneralNames
*cdsaObj
;
493 brtn
= cert
.GetExtenTop
<NSS_GeneralNames
, CE_GeneralNames
>(
496 fieldValue
.allocator
,
497 CSSMOID_IssuerAltName
,
504 CL_nssGeneralNamesToCssm(*nssObj
, *cdsaObj
,
505 cert
.coder(), fieldValue
.allocator
);
506 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
510 void freeFieldSubjIssuerAltName (
511 CssmOwnedData
&fieldValue
)
513 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
, false);
514 Allocator
&alloc
= fieldValue
.allocator
;
515 CE_GeneralNames
*cdsaObj
= (CE_GeneralNames
*)cssmExt
->value
.parsedValue
;
516 CL_freeCssmGeneralNames(cdsaObj
, alloc
);
517 freeFieldExtenCommon(cssmExt
, alloc
); // frees extnId, parsedValue, BERvalue
521 *** Certificate Policies
522 *** CDSA Format: CE_CertPolicies
523 *** NSS format : NSS_CertPolicies
524 *** OID: CSSMOID_CertificatePolicies
527 #define MAX_IA5_NAME_SIZE 1024
529 void setFieldCertPolicies(
531 const CssmData
&fieldValue
)
533 CSSM_X509_EXTENSION_PTR cssmExt
=
534 verifySetFreeExtension(fieldValue
, false);
535 SecNssCoder
&coder
= cert
.coder();
536 NSS_CertPolicies
*nssObj
=
537 (NSS_CertPolicies
*)coder
.malloc(sizeof(NSS_CertPolicies
));
538 memset(nssObj
, 0, sizeof(NSS_CertPolicies
));
539 CE_CertPolicies
*cdsaObj
=
540 (CE_CertPolicies
*)cssmExt
->value
.parsedValue
;
542 if(cdsaObj
->numPolicies
) {
544 (NSS_PolicyInformation
**)clNssNullArray(
545 cdsaObj
->numPolicies
, coder
);
547 for(unsigned polDex
=0; polDex
<cdsaObj
->numPolicies
; polDex
++) {
548 CE_PolicyInformation
*cPolInfo
= &cdsaObj
->policies
[polDex
];
549 NSS_PolicyInformation
*nPolInfo
= (NSS_PolicyInformation
*)
550 coder
.malloc(sizeof(NSS_PolicyInformation
));
551 memset(nPolInfo
, 0, sizeof(*nPolInfo
));
552 nssObj
->policies
[polDex
] = nPolInfo
;
554 coder
.allocCopyItem(cPolInfo
->certPolicyId
, nPolInfo
->certPolicyId
);
556 unsigned numQual
= cPolInfo
->numPolicyQualifiers
;
558 nPolInfo
->policyQualifiers
=
559 (NSS_PolicyQualifierInfo
**)clNssNullArray(numQual
,
562 for(unsigned qualDex
=0; qualDex
<numQual
; qualDex
++) {
563 CE_PolicyQualifierInfo
*cQualInfo
=
564 &cPolInfo
->policyQualifiers
[qualDex
];
565 NSS_PolicyQualifierInfo
*nQualInfo
=
566 (NSS_PolicyQualifierInfo
*)coder
.malloc(
567 sizeof(NSS_PolicyQualifierInfo
));
568 memset(nQualInfo
, 0, sizeof(NSS_PolicyQualifierInfo
));
569 nPolInfo
->policyQualifiers
[qualDex
] = nQualInfo
;
572 * OK we're at the lowest level.
573 * policyQualifierId == id_qt_cps: qualifier is
574 * an IA5 string, incoming data is its contents.
575 * Else incoming data is an encoded blob we pass on directly.
577 coder
.allocCopyItem(cQualInfo
->policyQualifierId
,
578 nQualInfo
->policyQualifierId
);
580 if(clCompareCssmData(&cQualInfo
->policyQualifierId
,
582 if(coder
.encodeItem(&cQualInfo
->qualifier
,
583 kSecAsn1IA5StringTemplate
,
584 nQualInfo
->qualifier
)) {
585 clErrorLog("setFieldCertPOlicies: IA5 encode error\n");
586 CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR
);
590 /* uninterpreted, copy over directly */
591 coder
.allocCopyItem(cQualInfo
->qualifier
,
592 nQualInfo
->qualifier
);
594 } /* for each qualifier */
595 } /* for each policy */
597 /* add to mExtensions */
598 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
599 kSecAsn1CertPoliciesTemplate
);
602 bool getFieldCertPolicies(
604 unsigned index
, // which occurrence (0 = first)
605 uint32
&numFields
, // RETURNED
606 CssmOwnedData
&fieldValue
)
608 const DecodedExten
*decodedExt
;
609 NSS_CertPolicies
*nssObj
;
610 CE_CertPolicies
*cdsaObj
;
612 Allocator
&alloc
= fieldValue
.allocator
;
613 brtn
= cert
.GetExtenTop
<NSS_CertPolicies
, CE_CertPolicies
>(
616 fieldValue
.allocator
,
617 CSSMOID_CertificatePolicies
,
624 assert(nssObj
!= NULL
);
626 memset(cdsaObj
, 0, sizeof(*cdsaObj
));
627 cdsaObj
->numPolicies
=
628 clNssArraySize((const void **)nssObj
->policies
);
629 unsigned sz
= cdsaObj
->numPolicies
* sizeof(CE_PolicyInformation
);
631 cdsaObj
->policies
= (CE_PolicyInformation
*)alloc
.malloc(sz
);
632 memset(cdsaObj
->policies
, 0, sz
);
635 for(unsigned polDex
=0; polDex
<cdsaObj
->numPolicies
; polDex
++) {
636 CE_PolicyInformation
*cPolInfo
= &cdsaObj
->policies
[polDex
];
637 NSS_PolicyInformation
*nPolInfo
= nssObj
->policies
[polDex
];
638 clAllocCopyData(alloc
, nPolInfo
->certPolicyId
,
639 cPolInfo
->certPolicyId
);
640 if(nPolInfo
->policyQualifiers
== NULL
) {
644 cPolInfo
->numPolicyQualifiers
=
645 clNssArraySize((const void **)nPolInfo
->policyQualifiers
);
646 sz
= cPolInfo
->numPolicyQualifiers
*
647 sizeof(CE_PolicyQualifierInfo
);
648 cPolInfo
->policyQualifiers
= (CE_PolicyQualifierInfo
*)
650 memset(cPolInfo
->policyQualifiers
, 0, sz
);
652 for(unsigned qualDex
=0; qualDex
<cPolInfo
->numPolicyQualifiers
;
654 NSS_PolicyQualifierInfo
*nQualInfo
=
655 nPolInfo
->policyQualifiers
[qualDex
];
656 CE_PolicyQualifierInfo
*cQualInfo
=
657 &cPolInfo
->policyQualifiers
[qualDex
];
661 * policyQualifierId == CSSMOID_QT_CPS :
662 * IA5String - decode and return contents.
663 * Else return whole thing.
665 clAllocCopyData(alloc
, nQualInfo
->policyQualifierId
,
666 cQualInfo
->policyQualifierId
);
667 CSSM_DATA toCopy
= nQualInfo
->qualifier
;
668 if(clCompareCssmData(&nQualInfo
->policyQualifierId
,
670 /* decode as IA5String to temp memory */
673 if(cert
.coder().decodeItem(nQualInfo
->qualifier
,
674 kSecAsn1IA5StringTemplate
,
676 clErrorLog("***getCertPolicies: bad IA5String!\n");
677 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT
);
680 /* else copy out nQualInfo->qualifier */
681 clAllocCopyData(alloc
, toCopy
, cQualInfo
->qualifier
);
682 } /* for each qualifier */
683 } /* for each policy info */
684 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
688 void freeFieldCertPolicies (
689 CssmOwnedData
&fieldValue
)
691 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
, false);
692 Allocator
&alloc
= fieldValue
.allocator
;
693 CE_CertPolicies
*cdsaObj
= (CE_CertPolicies
*)cssmExt
->value
.parsedValue
;
694 for(unsigned polDex
=0; polDex
<cdsaObj
->numPolicies
; polDex
++) {
695 CE_PolicyInformation
*cPolInfo
= &cdsaObj
->policies
[polDex
];
696 alloc
.free(cPolInfo
->certPolicyId
.Data
);
697 for(unsigned qualDex
=0;
698 qualDex
<cPolInfo
->numPolicyQualifiers
;
700 CE_PolicyQualifierInfo
*cQualInfo
=
701 &cPolInfo
->policyQualifiers
[qualDex
];
702 alloc
.free(cQualInfo
->policyQualifierId
.Data
);
703 alloc
.free(cQualInfo
->qualifier
.Data
);
705 alloc
.free(cPolInfo
->policyQualifiers
);
707 alloc
.free(cdsaObj
->policies
);
708 freeFieldExtenCommon(cssmExt
, alloc
); // frees extnId, parsedValue,
713 *** Netscape cert type
714 *** CDSA Format: CE_NetscapeCertType (a uint16)
715 *** NSS format CSSM_DATA, length 2
716 *** OID: CSSMOID_NetscapeCertType
718 void setFieldNetscapeCertType(
720 const CssmData
&fieldValue
)
722 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
,
724 CE_NetscapeCertType
*cdsaObj
=
725 (CE_NetscapeCertType
*)cssmExt
->value
.parsedValue
;
727 /* Alloc an NSS-style key usage in cert.coder's memory */
728 SecNssCoder
&coder
= cert
.coder();
729 CSSM_DATA
*nssObj
= (CSSM_DATA
*)coder
.malloc(sizeof(CSSM_DATA
));
730 coder
.allocItem(*nssObj
, 2);
732 /* cdsaObj --> nssObj */
733 nssObj
->Data
[0] = (*cdsaObj
) >> 8;
734 nssObj
->Data
[1] = *cdsaObj
;
736 /* Adjust length for BIT STRING encoding */
737 clCssmBitStringToNss(*nssObj
);
739 /* add to mExtensions */
740 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
741 kSecAsn1NetscapeCertTypeTemplate
);
744 bool getFieldNetscapeCertType(
746 unsigned index
, // which occurrence (0 = first)
747 uint32
&numFields
, // RETURNED
748 CssmOwnedData
&fieldValue
)
750 const DecodedExten
*decodedExt
;
752 CE_NetscapeCertType
*cdsaObj
;
755 brtn
= cert
.GetExtenTop
<CSSM_DATA
, CE_NetscapeCertType
>(
758 fieldValue
.allocator
,
759 CSSMOID_NetscapeCertType
,
767 /* make a copy - can't modify length in place */
768 CSSM_DATA bitString
= *nssObj
;
769 clNssBitStringToCssm(bitString
);
770 size_t toCopy
= bitString
.Length
;
772 /* I hope I never see this... */
773 clErrorLog("getFieldKeyUsage: CertType larger than 2 bytes!");
776 unsigned char bits
[2] = {0, 0};
777 memmove(bits
, bitString
.Data
, toCopy
);
778 *cdsaObj
= (((unsigned)bits
[0]) << 8) | bits
[1];
780 /* pass back to caller */
781 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
786 *** CRL Distribution points
787 *** CDSA Format: CE_CRLDistPointsSyntax
788 *** NSS format: NSS_CRLDistributionPoints
789 *** OID: CSSMOID_CrlDistributionPoints
791 void setFieldCrlDistPoints(
793 const CssmData
&fieldValue
)
795 CSSM_X509_EXTENSION_PTR cssmExt
=
796 verifySetFreeExtension(fieldValue
, false);
797 CE_CRLDistPointsSyntax
*cdsaObj
=
798 (CE_CRLDistPointsSyntax
*)cssmExt
->value
.parsedValue
;
799 SecNssCoder
&coder
= cert
.coder();
800 NSS_CRLDistributionPoints
*nssObj
=
801 (NSS_CRLDistributionPoints
*)coder
.malloc(
802 sizeof(NSS_CRLDistributionPoints
));
804 CL_cssmDistPointsToNss(*cdsaObj
, *nssObj
, coder
);
805 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
806 kSecAsn1CRLDistributionPointsTemplate
);
809 bool getFieldCrlDistPoints(
811 unsigned index
, // which occurrence (0 = first)
812 uint32
&numFields
, // RETURNED
813 CssmOwnedData
&fieldValue
)
815 const DecodedExten
*decodedExt
;
816 NSS_CRLDistributionPoints
*nssObj
;
817 CE_CRLDistPointsSyntax
*cdsaObj
;
819 Allocator
&alloc
= fieldValue
.allocator
;
821 brtn
= cert
.GetExtenTop
<NSS_CRLDistributionPoints
,
822 CE_CRLDistPointsSyntax
>(
826 CSSMOID_CrlDistributionPoints
,
833 assert(nssObj
!= NULL
);
834 CL_nssDistPointsToCssm(*nssObj
, *cdsaObj
, cert
.coder(), alloc
);
835 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
839 void freeFieldCrlDistPoints (
840 CssmOwnedData
&fieldValue
)
842 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
, false);
843 Allocator
&alloc
= fieldValue
.allocator
;
844 CE_CRLDistPointsSyntax
*cdsaObj
=
845 (CE_CRLDistPointsSyntax
*)cssmExt
->value
.parsedValue
;
846 CL_freeCssmDistPoints(cdsaObj
, alloc
);
847 freeFieldExtenCommon(cssmExt
, alloc
); // frees extnId, parsedValue, BERvalue
851 *** {Subject,Authority}InfoAccess
853 *** CDSA Format: CE_AuthorityInfoAccess
854 *** NSS format: NSS_AuthorityInfoAccess
855 *** OID: CSSMOID_AuthorityInfoAccess, CSSMOID_SubjectInfoAccess
857 void setFieldAuthInfoAccess(
859 const CssmData
&fieldValue
)
861 CSSM_X509_EXTENSION_PTR cssmExt
=
862 verifySetFreeExtension(fieldValue
, false);
863 CE_AuthorityInfoAccess
*cdsaObj
=
864 (CE_AuthorityInfoAccess
*)cssmExt
->value
.parsedValue
;
865 SecNssCoder
&coder
= cert
.coder();
866 NSS_AuthorityInfoAccess
*nssObj
=
867 (NSS_AuthorityInfoAccess
*)coder
.malloc(
868 sizeof(NSS_AuthorityInfoAccess
));
870 CL_cssmInfoAccessToNss(*cdsaObj
, *nssObj
, coder
);
871 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
872 kSecAsn1AuthorityInfoAccessTemplate
);
875 bool getFieldAuthInfoAccess(
877 unsigned index
, // which occurrence (0 = first)
878 uint32
&numFields
, // RETURNED
879 CssmOwnedData
&fieldValue
)
881 const DecodedExten
*decodedExt
;
882 NSS_AuthorityInfoAccess
*nssObj
;
883 CE_AuthorityInfoAccess
*cdsaObj
;
885 Allocator
&alloc
= fieldValue
.allocator
;
887 brtn
= cert
.GetExtenTop
<NSS_AuthorityInfoAccess
,
888 CE_AuthorityInfoAccess
>(
892 CSSMOID_AuthorityInfoAccess
,
899 assert(nssObj
!= NULL
);
900 CL_infoAccessToCssm(*nssObj
, *cdsaObj
, cert
.coder(), alloc
);
901 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
905 bool getFieldSubjInfoAccess(
907 unsigned index
, // which occurrence (0 = first)
908 uint32
&numFields
, // RETURNED
909 CssmOwnedData
&fieldValue
)
911 const DecodedExten
*decodedExt
;
912 NSS_AuthorityInfoAccess
*nssObj
;
913 CE_AuthorityInfoAccess
*cdsaObj
;
915 Allocator
&alloc
= fieldValue
.allocator
;
917 brtn
= cert
.GetExtenTop
<NSS_AuthorityInfoAccess
,
918 CE_AuthorityInfoAccess
>(
922 CSSMOID_SubjectInfoAccess
,
929 assert(nssObj
!= NULL
);
930 CL_infoAccessToCssm(*nssObj
, *cdsaObj
, cert
.coder(), alloc
);
931 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
935 void freeFieldInfoAccess (
936 CssmOwnedData
&fieldValue
)
938 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
, false);
939 Allocator
&alloc
= fieldValue
.allocator
;
940 CE_AuthorityInfoAccess
*cdsaObj
=
941 (CE_AuthorityInfoAccess
*)cssmExt
->value
.parsedValue
;
942 CL_freeInfoAccess(*cdsaObj
, alloc
);
943 freeFieldExtenCommon(cssmExt
, alloc
); // frees extnId, parsedValue, BERvalue
948 *** Qualfied Cert Statements
950 *** CDSA Format: CE_QC_Statements
951 *** NSS format: NSS_QC_Statements
952 *** OID: CSSMOID_QC_Statements
954 void setFieldQualCertStatements(
956 const CssmData
&fieldValue
)
958 CSSM_X509_EXTENSION_PTR cssmExt
=
959 verifySetFreeExtension(fieldValue
, false);
960 CE_QC_Statements
*cdsaObj
=
961 (CE_QC_Statements
*)cssmExt
->value
.parsedValue
;
962 SecNssCoder
&coder
= cert
.coder();
963 NSS_QC_Statements
*nssObj
=
964 (NSS_QC_Statements
*)coder
.malloc(
965 sizeof(NSS_QC_Statements
));
967 CL_cssmQualCertStatementsToNss(*cdsaObj
, *nssObj
, coder
);
968 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
969 kSecAsn1QC_StatementsTemplate
);
972 bool getFieldQualCertStatements(
974 unsigned index
, // which occurrence (0 = first)
975 uint32
&numFields
, // RETURNED
976 CssmOwnedData
&fieldValue
)
978 const DecodedExten
*decodedExt
;
979 NSS_QC_Statements
*nssObj
;
980 CE_QC_Statements
*cdsaObj
;
982 Allocator
&alloc
= fieldValue
.allocator
;
984 brtn
= cert
.GetExtenTop
<NSS_QC_Statements
,
989 CSSMOID_QC_Statements
,
996 assert(nssObj
!= NULL
);
997 CL_qualCertStatementsToCssm(*nssObj
, *cdsaObj
, cert
.coder(), alloc
);
998 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
1002 void freeFieldQualCertStatements(
1003 CssmOwnedData
&fieldValue
)
1005 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
, false);
1006 Allocator
&alloc
= fieldValue
.allocator
;
1007 CE_QC_Statements
*cdsaObj
=
1008 (CE_QC_Statements
*)cssmExt
->value
.parsedValue
;
1009 CL_freeQualCertStatements(*cdsaObj
, alloc
);
1010 freeFieldExtenCommon(cssmExt
, alloc
); // frees extnId, parsedValue, BERvalue
1014 *** Name Constraints
1015 *** CDSA Format: CE_NameConstraints
1016 *** NSS format: NSS_NameConstraints
1017 *** OID: CSSMOID_NameConstraints
1019 void setFieldNameConstraints(
1021 const CssmData
&fieldValue
)
1023 CSSM_X509_EXTENSION_PTR cssmExt
=
1024 verifySetFreeExtension(fieldValue
, false);
1025 CE_NameConstraints
*cdsaObj
=
1026 (CE_NameConstraints
*)cssmExt
->value
.parsedValue
;
1027 SecNssCoder
&coder
= cert
.coder();
1028 NSS_NameConstraints
*nssObj
=
1029 (NSS_NameConstraints
*)coder
.malloc(
1030 sizeof(NSS_NameConstraints
));
1031 CL_cssmNameConstraintsToNss(*cdsaObj
, *nssObj
, coder
);
1032 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
1033 kSecAsn1NameConstraintsTemplate
);
1036 bool getFieldNameConstraints(
1038 unsigned index
, // which occurrence (0 = first)
1039 uint32
&numFields
, // RETURNED
1040 CssmOwnedData
&fieldValue
)
1042 const DecodedExten
*decodedExt
;
1043 NSS_NameConstraints
*nssObj
;
1044 CE_NameConstraints
*cdsaObj
;
1046 Allocator
&alloc
= fieldValue
.allocator
;
1048 brtn
= cert
.GetExtenTop
<NSS_NameConstraints
,
1049 CE_NameConstraints
>(
1053 CSSMOID_NameConstraints
,
1060 assert(nssObj
!= NULL
);
1061 CL_nssNameConstraintsToCssm(*nssObj
, *cdsaObj
, cert
.coder(), alloc
);
1062 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
1066 void freeFieldNameConstraints (
1067 CssmOwnedData
&fieldValue
)
1069 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
, false);
1070 Allocator
&alloc
= fieldValue
.allocator
;
1071 CE_NameConstraints
*cdsaObj
=
1072 (CE_NameConstraints
*)cssmExt
->value
.parsedValue
;
1073 CL_freeCssmNameConstraints(cdsaObj
, alloc
);
1074 freeFieldExtenCommon(cssmExt
, alloc
); // frees extnId, parsedValue, BERvalue
1079 *** CDSA Format: CE_PolicyMappings
1080 *** NSS format: NSS_PolicyMappings
1081 *** OID: CSSMOID_PolicyMappings
1083 void setFieldPolicyMappings(
1085 const CssmData
&fieldValue
)
1087 CSSM_X509_EXTENSION_PTR cssmExt
=
1088 verifySetFreeExtension(fieldValue
, false);
1089 CE_PolicyMappings
*cdsaObj
=
1090 (CE_PolicyMappings
*)cssmExt
->value
.parsedValue
;
1091 SecNssCoder
&coder
= cert
.coder();
1092 NSS_PolicyMappings
*nssObj
=
1093 (NSS_PolicyMappings
*)coder
.malloc(
1094 sizeof(NSS_PolicyMappings
));
1095 CL_cssmPolicyMappingsToNss(*cdsaObj
, *nssObj
, coder
);
1096 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
1097 kSecAsn1PolicyMappingsTemplate
);
1100 bool getFieldPolicyMappings(
1102 unsigned index
, // which occurrence (0 = first)
1103 uint32
&numFields
, // RETURNED
1104 CssmOwnedData
&fieldValue
)
1106 const DecodedExten
*decodedExt
;
1107 NSS_PolicyMappings
*nssObj
;
1108 CE_PolicyMappings
*cdsaObj
;
1110 Allocator
&alloc
= fieldValue
.allocator
;
1112 brtn
= cert
.GetExtenTop
<NSS_PolicyMappings
,
1117 CSSMOID_PolicyMappings
,
1124 assert(nssObj
!= NULL
);
1125 CL_nssPolicyMappingsToCssm(*nssObj
, *cdsaObj
, cert
.coder(), alloc
);
1126 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
1130 void freeFieldPolicyMappings (
1131 CssmOwnedData
&fieldValue
)
1133 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
, false);
1134 Allocator
&alloc
= fieldValue
.allocator
;
1135 CE_PolicyMappings
*cdsaObj
=
1136 (CE_PolicyMappings
*)cssmExt
->value
.parsedValue
;
1137 CL_freeCssmPolicyMappings(cdsaObj
, alloc
);
1138 freeFieldExtenCommon(cssmExt
, alloc
); // frees extnId, parsedValue, BERvalue
1142 *** Policy Constraints
1143 *** CDSA Format: CE_PolicyConstraints
1144 *** NSS format: NSS_PolicyConstraints
1145 *** OID: CSSMOID_PolicyConstraints
1147 void setFieldPolicyConstraints(
1149 const CssmData
&fieldValue
)
1151 CSSM_X509_EXTENSION_PTR cssmExt
=
1152 verifySetFreeExtension(fieldValue
, false);
1153 CE_PolicyConstraints
*cdsaObj
=
1154 (CE_PolicyConstraints
*)cssmExt
->value
.parsedValue
;
1155 SecNssCoder
&coder
= cert
.coder();
1156 NSS_PolicyConstraints
*nssObj
=
1157 (NSS_PolicyConstraints
*)coder
.malloc(
1158 sizeof(NSS_PolicyConstraints
));
1159 CL_cssmPolicyConstraintsToNss(cdsaObj
, nssObj
, coder
);
1160 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
1161 kSecAsn1PolicyConstraintsTemplate
);
1164 bool getFieldPolicyConstraints(
1166 unsigned index
, // which occurrence (0 = first)
1167 uint32
&numFields
, // RETURNED
1168 CssmOwnedData
&fieldValue
)
1170 const DecodedExten
*decodedExt
;
1171 NSS_PolicyConstraints
*nssObj
;
1172 CE_PolicyConstraints
*cdsaObj
;
1174 Allocator
&alloc
= fieldValue
.allocator
;
1176 brtn
= cert
.GetExtenTop
<NSS_PolicyConstraints
,
1177 CE_PolicyConstraints
>(
1181 CSSMOID_PolicyConstraints
,
1188 assert(nssObj
!= NULL
);
1189 CL_nssPolicyConstraintsToCssm(nssObj
, cdsaObj
, cert
.coder(), alloc
);
1190 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);
1194 void freeFieldPolicyConstraints (
1195 CssmOwnedData
&fieldValue
)
1197 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
, false);
1198 Allocator
&alloc
= fieldValue
.allocator
;
1199 CE_PolicyConstraints
*cdsaObj
=
1200 (CE_PolicyConstraints
*)cssmExt
->value
.parsedValue
;
1201 CL_freeCssmPolicyConstraints(cdsaObj
, alloc
);
1202 freeFieldExtenCommon(cssmExt
, alloc
); // frees extnId, parsedValue, BERvalue
1206 *** Inhibit Any Policy
1207 *** CDSA Format: CE_InhibitAnyPolicy (an integer)
1208 *** NSS format: CSSM_DATA, sizeof(uint32)
1209 *** OID: CSSMOID_InhibitAnyPolicy
1211 void setFieldInhibitAnyPolicy(
1213 const CssmData
&fieldValue
)
1215 CSSM_X509_EXTENSION_PTR cssmExt
= verifySetFreeExtension(fieldValue
,
1217 CE_InhibitAnyPolicy
*cdsaObj
=
1218 (CE_InhibitAnyPolicy
*)cssmExt
->value
.parsedValue
;
1220 /* Alloc in cert.coder's memory */
1221 SecNssCoder
&coder
= cert
.coder();
1222 CSSM_DATA
*nssObj
= (CSSM_DATA
*)coder
.malloc(sizeof(CSSM_DATA
));
1223 coder
.allocItem(*nssObj
, sizeof(uint32
));
1225 /* cdsaObj --> nssObj */
1226 nssObj
->Data
[0] = (*cdsaObj
) >> 24;
1227 nssObj
->Data
[1] = (*cdsaObj
) >> 16;
1228 nssObj
->Data
[2] = (*cdsaObj
) >> 8;
1229 nssObj
->Data
[3] = *cdsaObj
;
1231 /* add to mExtensions */
1232 cert
.addExtension(nssObj
, cssmExt
->extnId
, cssmExt
->critical
, false,
1233 kSecAsn1IntegerTemplate
);
1236 bool getFieldInhibitAnyPolicy(
1238 unsigned index
, // which occurrence (0 = first)
1239 uint32
&numFields
, // RETURNED
1240 CssmOwnedData
&fieldValue
)
1242 const DecodedExten
*decodedExt
;
1244 CE_InhibitAnyPolicy
*cdsaObj
;
1247 brtn
= cert
.GetExtenTop
<CSSM_DATA
, CE_InhibitAnyPolicy
>(
1250 fieldValue
.allocator
,
1251 CSSMOID_InhibitAnyPolicy
,
1259 *cdsaObj
= *(nssObj
->Data
); //%%%FIXME check this
1261 /* pass back to caller */
1262 getFieldExtenCommon(cdsaObj
, *decodedExt
, fieldValue
);