--- /dev/null
+/*
+ * Copyright (c) 2000-2012 Apple Inc. All Rights Reserved.
+ *
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
+ * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
+ * specific language governing rights and limitations under the License.
+ */
+
+
+/*
+ * CLCertExtensions.cpp - extensions support. A major component of DecodedCert.
+ *
+ */
+
+#include "DecodedCert.h"
+#include "cldebugging.h"
+#include "CLCertExtensions.h"
+#include "CLFieldsCommon.h"
+#include "clNssUtils.h"
+#include "clNameUtils.h"
+#include <security_utilities/utilities.h>
+#include <Security/oidscert.h>
+#include <Security/oidsattr.h>
+#include <Security/cssmerr.h>
+#include <Security/x509defs.h>
+#include <Security/certextensions.h>
+#include <security_utilities/globalizer.h>
+#include <Security/certExtensionTemplates.h>
+#include <Security/SecAsn1Templates.h>
+
+/***
+ *** get/set/free functions called out from CertFields.cpp
+ ***/
+
+/***
+ *** KeyUsage
+ *** CDSA format CE_KeyUsage
+ *** NSS format CSSM_DATA, length 2
+ *** OID CSSMOID_KeyUsage
+ ***/
+
+void setFieldKeyUsage(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue,
+ false);
+ CE_KeyUsage *cdsaObj = (CE_KeyUsage *)cssmExt->value.parsedValue;
+
+ /* Alloc an NSS-style key usage in cert.coder's memory */
+ SecNssCoder &coder = cert.coder();
+ CSSM_DATA *nssObj = (CSSM_DATA *)coder.malloc(sizeof(CSSM_DATA));
+ coder.allocItem(*nssObj, 2);
+
+ /* cdsaObj --> nssObj */
+ nssObj->Data[0] = (*cdsaObj) >> 8;
+ nssObj->Data[1] = *cdsaObj;
+
+ /* Adjust length for BIT STRING encoding */
+ clCssmBitStringToNss(*nssObj);
+
+ /* add to mExtensions */
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1KeyUsageTemplate);
+}
+
+
+bool getFieldKeyUsage(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ CSSM_DATA *nssObj;
+ CE_KeyUsage *cdsaObj;
+ bool brtn;
+
+ brtn = cert.GetExtenTop<CSSM_DATA, CE_KeyUsage>(
+ index,
+ numFields,
+ fieldValue.allocator,
+ CSSMOID_KeyUsage,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+
+ /* make a copy - can't modify length in place */
+ CSSM_DATA bitString = *nssObj;
+ clNssBitStringToCssm(bitString);
+ size_t toCopy = bitString.Length;
+ if(toCopy > 2) {
+ /* I hope I never see this... */
+ clErrorLog("getFieldKeyUsage: KeyUsage larger than 2 bytes!");
+ toCopy = 2;
+ }
+ unsigned char bits[2] = {0, 0};
+ memmove(bits, bitString.Data, toCopy);
+ *cdsaObj = (((unsigned)bits[0]) << 8) | bits[1];
+
+ /* pass back to caller */
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+/***
+ *** Basic Constraints
+ *** CDSA format: CE_BasicConstraints
+ *** NSS format CE_BasicConstraints
+ *** OID CSSMOID_BasicConstraints
+ ***/
+
+void setFieldBasicConstraints(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt =
+ verifySetFreeExtension(fieldValue, false);
+ CE_BasicConstraints *cdsaObj =
+ (CE_BasicConstraints *)cssmExt->value.parsedValue;
+
+ /* Alloc an NSS-style BasicConstraints in cert.coder's memory */
+ SecNssCoder &coder = cert.coder();
+ NSS_BasicConstraints *nssObj =
+ (NSS_BasicConstraints *)coder.malloc(sizeof(NSS_BasicConstraints));
+ memset(nssObj, 0, sizeof(*nssObj));
+
+ /* cdsaObj --> nssObj */
+ ArenaAllocator arenaAlloc(coder);
+ clCssmBoolToNss(cdsaObj->cA, nssObj->cA, arenaAlloc);
+ if(cdsaObj->pathLenConstraintPresent) {
+ clIntToData(cdsaObj->pathLenConstraint,
+ nssObj->pathLenConstraint, arenaAlloc);
+ }
+
+ /* add to mExtensions */
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1BasicConstraintsTemplate);
+}
+
+
+bool getFieldBasicConstraints(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_BasicConstraints *nssObj;
+ CE_BasicConstraints *cdsaObj;
+ bool brtn;
+
+ brtn = cert.GetExtenTop<NSS_BasicConstraints, CE_BasicConstraints>(
+ index,
+ numFields,
+ fieldValue.allocator,
+ CSSMOID_BasicConstraints,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+
+ if(nssObj->cA.Data == NULL) {
+ /* default */
+ cdsaObj->cA = CSSM_FALSE;
+ }
+ else {
+ cdsaObj->cA = clNssBoolToCssm(nssObj->cA);
+ }
+ if(nssObj->pathLenConstraint.Data == NULL) {
+ /* optional */
+ cdsaObj->pathLenConstraintPresent = CSSM_FALSE;
+ cdsaObj->pathLenConstraint = 0;
+ }
+ else {
+ cdsaObj->pathLenConstraintPresent = CSSM_TRUE;
+ cdsaObj->pathLenConstraint = clDataToInt(nssObj->pathLenConstraint);
+ }
+
+ /* pass back to caller */
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+/***
+ *** Extended Key Usage
+ *** CDSA format: CE_ExtendedKeyUsage
+ *** NSS format: NSS_ExtKeyUsage
+ *** OID CSSMOID_ExtendedKeyUsage
+ ***/
+void setFieldExtKeyUsage(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue,
+ false);
+ CE_ExtendedKeyUsage *cdsaObj =
+ (CE_ExtendedKeyUsage *)cssmExt->value.parsedValue;
+
+ SecNssCoder &coder = cert.coder();
+ NSS_ExtKeyUsage *nssObj =
+ (NSS_ExtKeyUsage *)coder.malloc(sizeof(NSS_ExtKeyUsage));
+ memset(nssObj, 0, sizeof(*nssObj));
+ if(cdsaObj->numPurposes != 0) {
+ nssObj->purposes =
+ (CSSM_OID **)clNssNullArray(cdsaObj->numPurposes, coder);
+ }
+
+ /* cdsaObj --> nssObj, one 'purpose' (OID) at a time */
+ for(unsigned dex=0; dex<cdsaObj->numPurposes; dex++) {
+ nssObj->purposes[dex] = (CSSM_OID *)coder.malloc(sizeof(CSSM_OID));
+ coder.allocCopyItem(cdsaObj->purposes[dex],
+ *nssObj->purposes[dex]);
+ }
+
+ /* add to mExtensions */
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1ExtKeyUsageTemplate);
+}
+
+bool getFieldExtKeyUsage(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_ExtKeyUsage *nssObj;
+ CE_ExtendedKeyUsage *cdsaObj;
+ bool brtn;
+ Allocator &alloc = fieldValue.allocator;
+
+ brtn = cert.GetExtenTop<NSS_ExtKeyUsage, CE_ExtendedKeyUsage>(
+ index,
+ numFields,
+ alloc,
+ CSSMOID_ExtendedKeyUsage,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+
+ /* nssObj --> cdsaObj, one purpose at a time */
+ unsigned numPurposes = clNssArraySize((const void **)nssObj->purposes);
+ cdsaObj->numPurposes = numPurposes;
+ if(numPurposes) {
+ unsigned len = numPurposes * sizeof(CSSM_OID);
+ cdsaObj->purposes = (CSSM_OID_PTR)alloc.malloc(len);
+ memset(cdsaObj->purposes, 0, len);
+ }
+ for(unsigned dex=0; dex<numPurposes; dex++) {
+ clAllocCopyData(alloc, *nssObj->purposes[dex], cdsaObj->purposes[dex]);
+ }
+
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+void freeFieldExtKeyUsage(
+ CssmOwnedData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+ Allocator &alloc = fieldValue.allocator;
+ CE_ExtendedKeyUsage *cdsaObj =
+ (CE_ExtendedKeyUsage *)cssmExt->value.parsedValue;
+ unsigned oidDex;
+ for(oidDex=0; oidDex<cdsaObj->numPurposes; oidDex++) {
+ alloc.free(cdsaObj->purposes[oidDex].Data);
+ }
+ alloc.free(cdsaObj->purposes);
+ freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Subject Key Identifier
+ *** CDSA format: CE_SubjectKeyID, which is just a CSSM_DATA
+ *** OID CSSMOID_SubjectKeyIdentifier
+ ***/
+
+void setFieldSubjectKeyId(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue,
+ false);
+ CE_SubjectKeyID *cdsaObj = (CE_SubjectKeyID *)cssmExt->value.parsedValue;
+ SecNssCoder &coder = cert.coder();
+ CSSM_DATA *nssObj = (CSSM_DATA *)coder.malloc(sizeof(CSSM_DATA));
+ coder.allocCopyItem(*cdsaObj, *nssObj);
+
+ /* add to mExtensions */
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1SubjectKeyIdTemplate);
+}
+
+bool getFieldSubjectKeyId(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ CSSM_DATA *nssObj;
+ CE_SubjectKeyID *cdsaObj;
+ bool brtn;
+ Allocator &alloc = fieldValue.allocator;
+
+ brtn = cert.GetExtenTop<CSSM_DATA, CE_SubjectKeyID>(
+ index,
+ numFields,
+ alloc,
+ CSSMOID_SubjectKeyIdentifier,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+
+ /* if this fails, we're out of sync with nssExtenInfo[] in
+ * CLFieldsCommon.cpp */
+ assert(nssObj != NULL);
+ clAllocCopyData(alloc, *nssObj, *cdsaObj);
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+void freeFieldSubjectKeyId (
+ CssmOwnedData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+ Allocator &alloc = fieldValue.allocator;
+ CE_SubjectKeyID *cdsaObj = (CE_SubjectKeyID *)cssmExt->value.parsedValue;
+ alloc.free(cdsaObj->Data);
+ freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Authority Key Identifier
+ *** CDSA format: CE_AuthorityKeyID
+ *** NSS format: NSS_AuthorityKeyId
+ *** OID CSSMOID_AuthorityKeyIdentifier
+ ***/
+
+void setFieldAuthorityKeyId(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue,
+ false);
+ CE_AuthorityKeyID *cdsaObj =
+ (CE_AuthorityKeyID *)cssmExt->value.parsedValue;
+
+ /* Alloc an NSS-style AuthorityKeyId in cert.coder's memory */
+ SecNssCoder &coder = cert.coder();
+ NSS_AuthorityKeyId *nssObj =
+ (NSS_AuthorityKeyId *)coder.malloc(sizeof(NSS_AuthorityKeyId));
+ memset(nssObj, 0, sizeof(*nssObj));
+
+ /* convert caller's CDSA-style CE_AuthorityKeyID to NSS */
+ CL_cssmAuthorityKeyIdToNss(*cdsaObj, *nssObj, coder);
+
+ /* add to mExtensions */
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1AuthorityKeyIdTemplate);
+}
+
+bool getFieldAuthorityKeyId(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_AuthorityKeyId *nssObj;
+ CE_AuthorityKeyID *cdsaObj;
+ bool brtn;
+ Allocator &alloc = fieldValue.allocator;
+
+ brtn = cert.GetExtenTop<NSS_AuthorityKeyId, CE_AuthorityKeyID>(
+ index,
+ numFields,
+ alloc,
+ CSSMOID_AuthorityKeyIdentifier,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+ assert(nssObj != NULL);
+
+ /* nssObj --> cdsaObj */
+ CL_nssAuthorityKeyIdToCssm(*nssObj, *cdsaObj, cert.coder(), alloc);
+
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+void freeFieldAuthorityKeyId (
+ CssmOwnedData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+ Allocator &alloc = fieldValue.allocator;
+ CE_AuthorityKeyID *cdsaObj = (CE_AuthorityKeyID *)cssmExt->value.parsedValue;
+ CL_freeAuthorityKeyId(*cdsaObj, alloc);
+ freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Subject/Issuer alternate name
+ *** CDSA Format: CE_GeneralNames
+ *** NSS format: NSS_GeneralNames
+ *** OID: CSSMOID_SubjectAltName, CSSMOID_IssuerAltName
+ ***/
+void setFieldSubjIssuerAltName(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt =
+ verifySetFreeExtension(fieldValue, false);
+ CE_GeneralNames *cdsaObj = (CE_GeneralNames *)cssmExt->value.parsedValue;
+
+ /* Alloc an NSS-style GeneralNames in cert.coder's memory */
+ SecNssCoder &coder = cert.coder();
+ NSS_GeneralNames *nssObj =
+ (NSS_GeneralNames *)coder.malloc(sizeof(NSS_GeneralNames));
+ memset(nssObj, 0, sizeof(*nssObj));
+
+ /* cdsaObj --> nssObj */
+ CL_cssmGeneralNamesToNss(*cdsaObj, *nssObj, coder);
+
+ /* add to mExtensions */
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1GeneralNamesTemplate);
+}
+
+bool getFieldSubjAltName(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_GeneralNames *nssObj;
+ CE_GeneralNames *cdsaObj;
+ bool brtn;
+
+ brtn = cert.GetExtenTop<NSS_GeneralNames, CE_GeneralNames>(
+ index,
+ numFields,
+ fieldValue.allocator,
+ CSSMOID_SubjectAltName,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+ CL_nssGeneralNamesToCssm(*nssObj, *cdsaObj,
+ cert.coder(), fieldValue.allocator);
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+bool getFieldIssuerAltName(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_GeneralNames *nssObj;
+ CE_GeneralNames *cdsaObj;
+ bool brtn;
+
+ brtn = cert.GetExtenTop<NSS_GeneralNames, CE_GeneralNames>(
+ index,
+ numFields,
+ fieldValue.allocator,
+ CSSMOID_IssuerAltName,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+ CL_nssGeneralNamesToCssm(*nssObj, *cdsaObj,
+ cert.coder(), fieldValue.allocator);
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+void freeFieldSubjIssuerAltName (
+ CssmOwnedData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+ Allocator &alloc = fieldValue.allocator;
+ CE_GeneralNames *cdsaObj = (CE_GeneralNames *)cssmExt->value.parsedValue;
+ CL_freeCssmGeneralNames(cdsaObj, alloc);
+ freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Certificate Policies
+ *** CDSA Format: CE_CertPolicies
+ *** NSS format : NSS_CertPolicies
+ *** OID: CSSMOID_CertificatePolicies
+ ***/
+
+#define MAX_IA5_NAME_SIZE 1024
+
+void setFieldCertPolicies(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt =
+ verifySetFreeExtension(fieldValue, false);
+ SecNssCoder &coder = cert.coder();
+ NSS_CertPolicies *nssObj =
+ (NSS_CertPolicies *)coder.malloc(sizeof(NSS_CertPolicies));
+ memset(nssObj, 0, sizeof(NSS_CertPolicies));
+ CE_CertPolicies *cdsaObj =
+ (CE_CertPolicies *)cssmExt->value.parsedValue;
+
+ if(cdsaObj->numPolicies) {
+ nssObj->policies =
+ (NSS_PolicyInformation **)clNssNullArray(
+ cdsaObj->numPolicies, coder);
+ }
+ for(unsigned polDex=0; polDex<cdsaObj->numPolicies; polDex++) {
+ CE_PolicyInformation *cPolInfo = &cdsaObj->policies[polDex];
+ NSS_PolicyInformation *nPolInfo = (NSS_PolicyInformation *)
+ coder.malloc(sizeof(NSS_PolicyInformation));
+ memset(nPolInfo, 0, sizeof(*nPolInfo));
+ nssObj->policies[polDex] = nPolInfo;
+
+ coder.allocCopyItem(cPolInfo->certPolicyId, nPolInfo->certPolicyId);
+
+ unsigned numQual = cPolInfo->numPolicyQualifiers;
+ if(numQual != 0) {
+ nPolInfo->policyQualifiers =
+ (NSS_PolicyQualifierInfo **)clNssNullArray(numQual,
+ coder);
+ }
+ for(unsigned qualDex=0; qualDex<numQual; qualDex++) {
+ CE_PolicyQualifierInfo *cQualInfo =
+ &cPolInfo->policyQualifiers[qualDex];
+ NSS_PolicyQualifierInfo *nQualInfo =
+ (NSS_PolicyQualifierInfo *)coder.malloc(
+ sizeof(NSS_PolicyQualifierInfo));
+ memset(nQualInfo, 0, sizeof(NSS_PolicyQualifierInfo));
+ nPolInfo->policyQualifiers[qualDex] = nQualInfo;
+
+ /*
+ * OK we're at the lowest level.
+ * policyQualifierId == id_qt_cps: qualifier is
+ * an IA5 string, incoming data is its contents.
+ * Else incoming data is an encoded blob we pass on directly.
+ */
+ coder.allocCopyItem(cQualInfo->policyQualifierId,
+ nQualInfo->policyQualifierId);
+
+ if(clCompareCssmData(&cQualInfo->policyQualifierId,
+ &CSSMOID_QT_CPS)) {
+ if(coder.encodeItem(&cQualInfo->qualifier,
+ kSecAsn1IA5StringTemplate,
+ nQualInfo->qualifier)) {
+ clErrorLog("setFieldCertPOlicies: IA5 encode error\n");
+ CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
+ }
+ }
+ else {
+ /* uninterpreted, copy over directly */
+ coder.allocCopyItem(cQualInfo->qualifier,
+ nQualInfo->qualifier);
+ }
+ } /* for each qualifier */
+ } /* for each policy */
+
+ /* add to mExtensions */
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1CertPoliciesTemplate);
+}
+
+bool getFieldCertPolicies(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_CertPolicies *nssObj;
+ CE_CertPolicies *cdsaObj;
+ bool brtn;
+ Allocator &alloc = fieldValue.allocator;
+ brtn = cert.GetExtenTop<NSS_CertPolicies, CE_CertPolicies>(
+ index,
+ numFields,
+ fieldValue.allocator,
+ CSSMOID_CertificatePolicies,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+ assert(nssObj != NULL);
+
+ memset(cdsaObj, 0, sizeof(*cdsaObj));
+ cdsaObj->numPolicies =
+ clNssArraySize((const void **)nssObj->policies);
+ unsigned sz = cdsaObj->numPolicies * sizeof(CE_PolicyInformation);
+ if(sz) {
+ cdsaObj->policies = (CE_PolicyInformation *)alloc.malloc(sz);
+ memset(cdsaObj->policies, 0, sz);
+ }
+
+ for(unsigned polDex=0; polDex<cdsaObj->numPolicies; polDex++) {
+ CE_PolicyInformation *cPolInfo = &cdsaObj->policies[polDex];
+ NSS_PolicyInformation *nPolInfo = nssObj->policies[polDex];
+ clAllocCopyData(alloc, nPolInfo->certPolicyId,
+ cPolInfo->certPolicyId);
+ if(nPolInfo->policyQualifiers == NULL) {
+ continue;
+ }
+
+ cPolInfo->numPolicyQualifiers =
+ clNssArraySize((const void **)nPolInfo->policyQualifiers);
+ sz = cPolInfo->numPolicyQualifiers *
+ sizeof(CE_PolicyQualifierInfo);
+ cPolInfo->policyQualifiers = (CE_PolicyQualifierInfo *)
+ alloc.malloc(sz);
+ memset(cPolInfo->policyQualifiers, 0, sz);
+
+ for(unsigned qualDex=0; qualDex<cPolInfo->numPolicyQualifiers;
+ qualDex++) {
+ NSS_PolicyQualifierInfo *nQualInfo =
+ nPolInfo->policyQualifiers[qualDex];
+ CE_PolicyQualifierInfo *cQualInfo =
+ &cPolInfo->policyQualifiers[qualDex];
+
+ /*
+ * leaf.
+ * policyQualifierId == CSSMOID_QT_CPS :
+ * IA5String - decode and return contents.
+ * Else return whole thing.
+ */
+ clAllocCopyData(alloc, nQualInfo->policyQualifierId,
+ cQualInfo->policyQualifierId);
+ CSSM_DATA toCopy = nQualInfo->qualifier;
+ if(clCompareCssmData(&nQualInfo->policyQualifierId,
+ &CSSMOID_QT_CPS)) {
+ /* decode as IA5String to temp memory */
+ toCopy.Data = NULL;
+ toCopy.Length = 0;
+ if(cert.coder().decodeItem(nQualInfo->qualifier,
+ kSecAsn1IA5StringTemplate,
+ &toCopy)) {
+ clErrorLog("***getCertPolicies: bad IA5String!\n");
+ CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
+ }
+ }
+ /* else copy out nQualInfo->qualifier */
+ clAllocCopyData(alloc, toCopy, cQualInfo->qualifier);
+ } /* for each qualifier */
+ } /* for each policy info */
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+void freeFieldCertPolicies (
+ CssmOwnedData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+ Allocator &alloc = fieldValue.allocator;
+ CE_CertPolicies *cdsaObj = (CE_CertPolicies *)cssmExt->value.parsedValue;
+ for(unsigned polDex=0; polDex<cdsaObj->numPolicies; polDex++) {
+ CE_PolicyInformation *cPolInfo = &cdsaObj->policies[polDex];
+ alloc.free(cPolInfo->certPolicyId.Data);
+ for(unsigned qualDex=0;
+ qualDex<cPolInfo->numPolicyQualifiers;
+ qualDex++) {
+ CE_PolicyQualifierInfo *cQualInfo =
+ &cPolInfo->policyQualifiers[qualDex];
+ alloc.free(cQualInfo->policyQualifierId.Data);
+ alloc.free(cQualInfo->qualifier.Data);
+ }
+ alloc.free(cPolInfo->policyQualifiers);
+ }
+ alloc.free(cdsaObj->policies);
+ freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue,
+ // BERvalue
+}
+
+/***
+ *** Netscape cert type
+ *** CDSA Format: CE_NetscapeCertType (a uint16)
+ *** NSS format CSSM_DATA, length 2
+ *** OID: CSSMOID_NetscapeCertType
+ ***/
+void setFieldNetscapeCertType(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue,
+ false);
+ CE_NetscapeCertType *cdsaObj =
+ (CE_NetscapeCertType *)cssmExt->value.parsedValue;
+
+ /* Alloc an NSS-style key usage in cert.coder's memory */
+ SecNssCoder &coder = cert.coder();
+ CSSM_DATA *nssObj = (CSSM_DATA *)coder.malloc(sizeof(CSSM_DATA));
+ coder.allocItem(*nssObj, 2);
+
+ /* cdsaObj --> nssObj */
+ nssObj->Data[0] = (*cdsaObj) >> 8;
+ nssObj->Data[1] = *cdsaObj;
+
+ /* Adjust length for BIT STRING encoding */
+ clCssmBitStringToNss(*nssObj);
+
+ /* add to mExtensions */
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1NetscapeCertTypeTemplate);
+}
+
+bool getFieldNetscapeCertType(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ CSSM_DATA *nssObj;
+ CE_NetscapeCertType *cdsaObj;
+ bool brtn;
+
+ brtn = cert.GetExtenTop<CSSM_DATA, CE_NetscapeCertType>(
+ index,
+ numFields,
+ fieldValue.allocator,
+ CSSMOID_NetscapeCertType,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+
+ /* make a copy - can't modify length in place */
+ CSSM_DATA bitString = *nssObj;
+ clNssBitStringToCssm(bitString);
+ size_t toCopy = bitString.Length;
+ if(toCopy > 2) {
+ /* I hope I never see this... */
+ clErrorLog("getFieldKeyUsage: CertType larger than 2 bytes!");
+ toCopy = 2;
+ }
+ unsigned char bits[2] = {0, 0};
+ memmove(bits, bitString.Data, toCopy);
+ *cdsaObj = (((unsigned)bits[0]) << 8) | bits[1];
+
+ /* pass back to caller */
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+/***
+ *** CRL Distribution points
+ *** CDSA Format: CE_CRLDistPointsSyntax
+ *** NSS format: NSS_CRLDistributionPoints
+ *** OID: CSSMOID_CrlDistributionPoints
+ ***/
+void setFieldCrlDistPoints(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt =
+ verifySetFreeExtension(fieldValue, false);
+ CE_CRLDistPointsSyntax *cdsaObj =
+ (CE_CRLDistPointsSyntax *)cssmExt->value.parsedValue;
+ SecNssCoder &coder = cert.coder();
+ NSS_CRLDistributionPoints *nssObj =
+ (NSS_CRLDistributionPoints *)coder.malloc(
+ sizeof(NSS_CRLDistributionPoints));
+
+ CL_cssmDistPointsToNss(*cdsaObj, *nssObj, coder);
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1CRLDistributionPointsTemplate);
+}
+
+bool getFieldCrlDistPoints(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_CRLDistributionPoints *nssObj;
+ CE_CRLDistPointsSyntax *cdsaObj;
+ bool brtn;
+ Allocator &alloc = fieldValue.allocator;
+
+ brtn = cert.GetExtenTop<NSS_CRLDistributionPoints,
+ CE_CRLDistPointsSyntax>(
+ index,
+ numFields,
+ alloc,
+ CSSMOID_CrlDistributionPoints,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+ assert(nssObj != NULL);
+ CL_nssDistPointsToCssm(*nssObj, *cdsaObj, cert.coder(), alloc);
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+void freeFieldCrlDistPoints (
+ CssmOwnedData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+ Allocator &alloc = fieldValue.allocator;
+ CE_CRLDistPointsSyntax *cdsaObj =
+ (CE_CRLDistPointsSyntax *)cssmExt->value.parsedValue;
+ CL_freeCssmDistPoints(cdsaObj, alloc);
+ freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** {Subject,Authority}InfoAccess
+ ***
+ *** CDSA Format: CE_AuthorityInfoAccess
+ *** NSS format: NSS_AuthorityInfoAccess
+ *** OID: CSSMOID_AuthorityInfoAccess, CSSMOID_SubjectInfoAccess
+ ***/
+void setFieldAuthInfoAccess(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt =
+ verifySetFreeExtension(fieldValue, false);
+ CE_AuthorityInfoAccess *cdsaObj =
+ (CE_AuthorityInfoAccess *)cssmExt->value.parsedValue;
+ SecNssCoder &coder = cert.coder();
+ NSS_AuthorityInfoAccess *nssObj =
+ (NSS_AuthorityInfoAccess *)coder.malloc(
+ sizeof(NSS_AuthorityInfoAccess));
+
+ CL_cssmInfoAccessToNss(*cdsaObj, *nssObj, coder);
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1AuthorityInfoAccessTemplate);
+}
+
+bool getFieldAuthInfoAccess(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_AuthorityInfoAccess *nssObj;
+ CE_AuthorityInfoAccess *cdsaObj;
+ bool brtn;
+ Allocator &alloc = fieldValue.allocator;
+
+ brtn = cert.GetExtenTop<NSS_AuthorityInfoAccess,
+ CE_AuthorityInfoAccess>(
+ index,
+ numFields,
+ alloc,
+ CSSMOID_AuthorityInfoAccess,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+ assert(nssObj != NULL);
+ CL_infoAccessToCssm(*nssObj, *cdsaObj, cert.coder(), alloc);
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+bool getFieldSubjInfoAccess(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_AuthorityInfoAccess *nssObj;
+ CE_AuthorityInfoAccess *cdsaObj;
+ bool brtn;
+ Allocator &alloc = fieldValue.allocator;
+
+ brtn = cert.GetExtenTop<NSS_AuthorityInfoAccess,
+ CE_AuthorityInfoAccess>(
+ index,
+ numFields,
+ alloc,
+ CSSMOID_SubjectInfoAccess,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+ assert(nssObj != NULL);
+ CL_infoAccessToCssm(*nssObj, *cdsaObj, cert.coder(), alloc);
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+void freeFieldInfoAccess (
+ CssmOwnedData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+ Allocator &alloc = fieldValue.allocator;
+ CE_AuthorityInfoAccess *cdsaObj =
+ (CE_AuthorityInfoAccess *)cssmExt->value.parsedValue;
+ CL_freeInfoAccess(*cdsaObj, alloc);
+ freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue
+
+}
+
+/***
+ *** Qualfied Cert Statements
+ ***
+ *** CDSA Format: CE_QC_Statements
+ *** NSS format: NSS_QC_Statements
+ *** OID: CSSMOID_QC_Statements
+ ***/
+void setFieldQualCertStatements(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt =
+ verifySetFreeExtension(fieldValue, false);
+ CE_QC_Statements *cdsaObj =
+ (CE_QC_Statements *)cssmExt->value.parsedValue;
+ SecNssCoder &coder = cert.coder();
+ NSS_QC_Statements *nssObj =
+ (NSS_QC_Statements *)coder.malloc(
+ sizeof(NSS_QC_Statements));
+
+ CL_cssmQualCertStatementsToNss(*cdsaObj, *nssObj, coder);
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1QC_StatementsTemplate);
+}
+
+bool getFieldQualCertStatements(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_QC_Statements *nssObj;
+ CE_QC_Statements *cdsaObj;
+ bool brtn;
+ Allocator &alloc = fieldValue.allocator;
+
+ brtn = cert.GetExtenTop<NSS_QC_Statements,
+ CE_QC_Statements>(
+ index,
+ numFields,
+ alloc,
+ CSSMOID_QC_Statements,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+ assert(nssObj != NULL);
+ CL_qualCertStatementsToCssm(*nssObj, *cdsaObj, cert.coder(), alloc);
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+void freeFieldQualCertStatements(
+ CssmOwnedData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+ Allocator &alloc = fieldValue.allocator;
+ CE_QC_Statements *cdsaObj =
+ (CE_QC_Statements *)cssmExt->value.parsedValue;
+ CL_freeQualCertStatements(*cdsaObj, alloc);
+ freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Name Constraints
+ *** CDSA Format: CE_NameConstraints
+ *** NSS format: NSS_NameConstraints
+ *** OID: CSSMOID_NameConstraints
+ ***/
+void setFieldNameConstraints(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt =
+ verifySetFreeExtension(fieldValue, false);
+ CE_NameConstraints *cdsaObj =
+ (CE_NameConstraints *)cssmExt->value.parsedValue;
+ SecNssCoder &coder = cert.coder();
+ NSS_NameConstraints *nssObj =
+ (NSS_NameConstraints *)coder.malloc(
+ sizeof(NSS_NameConstraints));
+ CL_cssmNameConstraintsToNss(*cdsaObj, *nssObj, coder);
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1NameConstraintsTemplate);
+}
+
+bool getFieldNameConstraints(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_NameConstraints *nssObj;
+ CE_NameConstraints *cdsaObj;
+ bool brtn;
+ Allocator &alloc = fieldValue.allocator;
+
+ brtn = cert.GetExtenTop<NSS_NameConstraints,
+ CE_NameConstraints>(
+ index,
+ numFields,
+ alloc,
+ CSSMOID_NameConstraints,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+ assert(nssObj != NULL);
+ CL_nssNameConstraintsToCssm(*nssObj, *cdsaObj, cert.coder(), alloc);
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+void freeFieldNameConstraints (
+ CssmOwnedData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+ Allocator &alloc = fieldValue.allocator;
+ CE_NameConstraints *cdsaObj =
+ (CE_NameConstraints *)cssmExt->value.parsedValue;
+ CL_freeCssmNameConstraints(cdsaObj, alloc);
+ freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Policy Mappings
+ *** CDSA Format: CE_PolicyMappings
+ *** NSS format: NSS_PolicyMappings
+ *** OID: CSSMOID_PolicyMappings
+ ***/
+void setFieldPolicyMappings(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt =
+ verifySetFreeExtension(fieldValue, false);
+ CE_PolicyMappings *cdsaObj =
+ (CE_PolicyMappings *)cssmExt->value.parsedValue;
+ SecNssCoder &coder = cert.coder();
+ NSS_PolicyMappings *nssObj =
+ (NSS_PolicyMappings *)coder.malloc(
+ sizeof(NSS_PolicyMappings));
+ CL_cssmPolicyMappingsToNss(*cdsaObj, *nssObj, coder);
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1PolicyMappingsTemplate);
+}
+
+bool getFieldPolicyMappings(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_PolicyMappings *nssObj;
+ CE_PolicyMappings *cdsaObj;
+ bool brtn;
+ Allocator &alloc = fieldValue.allocator;
+
+ brtn = cert.GetExtenTop<NSS_PolicyMappings,
+ CE_PolicyMappings>(
+ index,
+ numFields,
+ alloc,
+ CSSMOID_PolicyMappings,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+ assert(nssObj != NULL);
+ CL_nssPolicyMappingsToCssm(*nssObj, *cdsaObj, cert.coder(), alloc);
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+void freeFieldPolicyMappings (
+ CssmOwnedData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+ Allocator &alloc = fieldValue.allocator;
+ CE_PolicyMappings *cdsaObj =
+ (CE_PolicyMappings *)cssmExt->value.parsedValue;
+ CL_freeCssmPolicyMappings(cdsaObj, alloc);
+ freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Policy Constraints
+ *** CDSA Format: CE_PolicyConstraints
+ *** NSS format: NSS_PolicyConstraints
+ *** OID: CSSMOID_PolicyConstraints
+ ***/
+void setFieldPolicyConstraints(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt =
+ verifySetFreeExtension(fieldValue, false);
+ CE_PolicyConstraints *cdsaObj =
+ (CE_PolicyConstraints *)cssmExt->value.parsedValue;
+ SecNssCoder &coder = cert.coder();
+ NSS_PolicyConstraints *nssObj =
+ (NSS_PolicyConstraints *)coder.malloc(
+ sizeof(NSS_PolicyConstraints));
+ CL_cssmPolicyConstraintsToNss(cdsaObj, nssObj, coder);
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1PolicyConstraintsTemplate);
+}
+
+bool getFieldPolicyConstraints(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ NSS_PolicyConstraints *nssObj;
+ CE_PolicyConstraints *cdsaObj;
+ bool brtn;
+ Allocator &alloc = fieldValue.allocator;
+
+ brtn = cert.GetExtenTop<NSS_PolicyConstraints,
+ CE_PolicyConstraints>(
+ index,
+ numFields,
+ alloc,
+ CSSMOID_PolicyConstraints,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+ assert(nssObj != NULL);
+ CL_nssPolicyConstraintsToCssm(nssObj, cdsaObj, cert.coder(), alloc);
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+
+void freeFieldPolicyConstraints (
+ CssmOwnedData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false);
+ Allocator &alloc = fieldValue.allocator;
+ CE_PolicyConstraints *cdsaObj =
+ (CE_PolicyConstraints *)cssmExt->value.parsedValue;
+ CL_freeCssmPolicyConstraints(cdsaObj, alloc);
+ freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue
+}
+
+/***
+ *** Inhibit Any Policy
+ *** CDSA Format: CE_InhibitAnyPolicy (an integer)
+ *** NSS format: CSSM_DATA, sizeof(uint32)
+ *** OID: CSSMOID_InhibitAnyPolicy
+ ***/
+void setFieldInhibitAnyPolicy(
+ DecodedItem &cert,
+ const CssmData &fieldValue)
+{
+ CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue,
+ false);
+ CE_InhibitAnyPolicy *cdsaObj =
+ (CE_InhibitAnyPolicy *)cssmExt->value.parsedValue;
+
+ /* Alloc in cert.coder's memory */
+ SecNssCoder &coder = cert.coder();
+ CSSM_DATA *nssObj = (CSSM_DATA *)coder.malloc(sizeof(CSSM_DATA));
+ coder.allocItem(*nssObj, sizeof(uint32));
+
+ /* cdsaObj --> nssObj */
+ nssObj->Data[0] = (*cdsaObj) >> 24;
+ nssObj->Data[1] = (*cdsaObj) >> 16;
+ nssObj->Data[2] = (*cdsaObj) >> 8;
+ nssObj->Data[3] = *cdsaObj;
+
+ /* add to mExtensions */
+ cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false,
+ kSecAsn1IntegerTemplate);
+}
+
+bool getFieldInhibitAnyPolicy(
+ DecodedItem &cert,
+ unsigned index, // which occurrence (0 = first)
+ uint32 &numFields, // RETURNED
+ CssmOwnedData &fieldValue)
+{
+ const DecodedExten *decodedExt;
+ CSSM_DATA *nssObj;
+ CE_InhibitAnyPolicy *cdsaObj;
+ bool brtn;
+
+ brtn = cert.GetExtenTop<CSSM_DATA, CE_InhibitAnyPolicy>(
+ index,
+ numFields,
+ fieldValue.allocator,
+ CSSMOID_InhibitAnyPolicy,
+ nssObj,
+ cdsaObj,
+ decodedExt);
+ if(!brtn) {
+ return false;
+ }
+
+ *cdsaObj = *(nssObj->Data); //%%%FIXME check this
+
+ /* pass back to caller */
+ getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue);
+ return true;
+}
+