/*
* Copyright (c) 2002 Apple Computer, 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
/*
- * DecodedItem.cpp - class representing the common portions of
- * NSS-format decoded certs and CRLs, with extensions parsed and
+ * DecodedItem.cpp - class representing the common portions of
+ * NSS-format decoded certs and CRLs, with extensions parsed and
* decoded (still in NSS format).
*/
#include "DecodedItem.h"
#include "cldebugging.h"
-#include "AppleX509CLSession.h"
+#include "AppleX509CLSession.h"
#include "CSPAttacher.h"
#include "CLFieldsCommon.h"
#include "clNssUtils.h"
#include "clNameUtils.h"
+#include <security_asn1/SecAsn1Types.h>
#include <Security/cssmapple.h>
#include <Security/oidscert.h>
DecodedExten::DecodedExten(
const CSSM_OID &extnId, // copied
bool critical,
- void *nssObj, // NSS_KeyUsage, NSS_BasicConstraints,
+ void *nssObj, // NSS_KeyUsage, NSS_BasicConstraints,
// etc. NOT COPIED, exists in same
// memory space as coder
bool berEncoded, // indicates unknown extension which we
* when coder is freed */
}
-/*
+/*
* Given a fully encoded BER object, create a CSSM_X509EXT_TAGandVALUE
- * representing it. We malloc the CSSM_X509EXT_TAGandVALUE itself using
+ * representing it. We malloc the CSSM_X509EXT_TAGandVALUE itself using
* specified allocator, but the referent (in CSSM_X509EXT_TAGandVALUE.value)
- * merely points to data inside the berValue.
+ * merely points to data inside the berValue.
*/
CSSM_X509EXT_TAGandVALUE *DecodedExten::createTagAndValue(
const CSSM_DATA &berValue,
}
CSSM_X509EXT_TAGandVALUE *tv = (CSSM_X509EXT_TAGandVALUE *)
alloc.malloc(sizeof(CSSM_X509EXT_TAGandVALUE));
+
+ // Important: by the time we get called, the extension data
+ // has already been deconstructed, and the raw value we are
+ // handed in berValue does not include ASN.1 type or length.
+ // Since createTagAndValue is only called in the case where
+ // the contents are unknown (and thus opaque), always treat
+ // as an octet string.
+
+ tv->type = SEC_ASN1_OCTET_STRING;
+ tv->value.Length = berValue.Length;
+ tv->value.Data = berValue.Data;
+ return tv;
+
+#if 0
tv->type = berValue.Data[0];
-
- /*
- * length of length is variable; ASN spec says it can actually be up to
+
+ /*
+ * length of length is variable; ASN spec says it can actually be up to
* 127 bytes, but we only have room for 32 bits!
*/
const uint8 *lp = berValue.Data + 1;
tv->value.Data = const_cast<uint8 *>(lp + 1);
return tv;
}
-
+
unsigned numLenBytes = len1 & 0x7f;
if(numLenBytes > 4) {
clErrorLog("createTagAndValue: impossible length of length (%u)\n", numLenBytes);
alloc.free(tv);
CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
}
-
+
uint32 len = 0;
lp++; // points to first length byte
for(uint32 dex=0; dex<numLenBytes; dex++) {
tv->value.Length = len;
tv->value.Data = const_cast<uint8 *>(lp);
return tv;
+#endif
}
/*
{
clAllocCopyData(alloc, mExtnId, cssmExt->extnId);
cssmExt->critical = mCritical ? CSSM_TRUE : CSSM_FALSE;
-
- /*
+
+ /*
* in either case copy the raw extension data if we have it (we may not
- * have it if this was created via setField).
+ * have it if this was created via setField).
*/
if(mRawExtn) {
clAllocCopyData(alloc, *mRawExtn, cssmExt->BERvalue);
/*
* Convert a DecodedExten to a CSSM_X509_EXTENSION. This includes
- * the mapping of the extnId to a known CDSA type and type and doing the
- * actual NSS-to-CDSA conversion. At the time this function is
- * called, the DecodedExten either has a valid mNssObj, or it's an
+ * the mapping of the extnId to a known CDSA type and type and doing the
+ * actual NSS-to-CDSA conversion. At the time this function is
+ * called, the DecodedExten either has a valid mNssObj, or it's an
* unknown extension type in which case mNssObj is an AsnOcts containing
- * the opaquely DER-encoded extension value.
- *
+ * the opaquely DER-encoded extension value.
+ *
* Currently only used when decoding a CRL and converting it en masse
* to CDSA.
*/
CdsaType *&cdsaObj, // mallocd and RETURNED
Allocator &alloc)
{
- nssObj = (NssType *)(decodedExt.nssObj());
+ nssObj = (NssType *)(decodedExt.nssObj());
assert(nssObj != NULL);
cdsaObj = (CdsaType *)alloc.malloc(sizeof(CdsaType));
memset(cdsaObj, 0, sizeof(CdsaType));
NSS_CRLDistributionPoints *nssObj;
nssToCssm<NSS_CRLDistributionPoints, CE_CRLDistPointsSyntax>(
*this,
- nssObj,
+ nssObj,
cdsaObj,
alloc);
CL_nssDistPointsToCssm((const NSS_CRLDistributionPoints&)*nssObj, *cdsaObj, mCoder, alloc);
vCdsaObj = cdsaObj;
}
/*
- * cert entry extensions
+ * cert entry extensions
*/
else if(clCompareCssmData(&mExtnId, &CSSMOID_HoldInstructionCode)) {
/* value is just an OID */
vCdsaObj = cdsaObj;
}
else {
- /* if we get here, this routine is not keeping up with
+ /* if we get here, this routine is not keeping up with
* clOidToNssInfo() */
// assert(0);
CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
/*
* A variable-size array of DecodedExtens.
- * Used for storing cert and CRL extensions as well as per-CRL-entry
+ * Used for storing cert and CRL extensions as well as per-CRL-entry
* extensions.
*/
-DecodedExtensions::DecodedExtensions(
+DecodedExtensions::DecodedExtensions(
SecNssCoder &coder,
Allocator &alloc)
: mCoder(coder),
{
}
-
+
DecodedExtensions::~DecodedExtensions()
{
for(unsigned i=0; i<mNumExtensions; i++) {
/*
* Initialize by decoding a NSS-style NSS_CertExtension array.
- * This involves figuring out what kind of object is represented in the
- * octet string in the extension, decoding it, and appending the resulting
+ * This involves figuring out what kind of object is represented in the
+ * octet string in the extension, decoding it, and appending the resulting
* NSS object to mExtensions in the form of a DecodedExten.
*
- * Called when decoding either a cert or a CRL (for caching it or
- * getting its fields) or a cert template (only via
+ * Called when decoding either a cert or a CRL (for caching it or
+ * getting its fields) or a cert template (only via
* CertGetAllTemplateFields()).
*/
void DecodedExtensions::decodeFromNss(
- NSS_CertExtension **extensions)
+ NSS_CertExtension **extensions)
{
if(extensions == NULL) {
/* OK, no extensions present */
/* traverse extension list */
for(unsigned dex=0; dex<numExtens; dex++) {
NSS_CertExtension *nssExten = extensions[dex];
-
+
/*
- * For this extension->extnId, cook up an appropriate
+ * For this extension->extnId, cook up an appropriate
* NSS-specific type (NSS_KeyUsage, etc.);
*/
CSSM_DATA &rawExtn = nssExten->value;
void *nssObj = NULL; // decode destination
found = clOidToNssInfo(nssExten->extnId, nssObjLen, templ);
if(!found) {
- /*
+ /*
* We don't know how to deal with this.
*/
berEncoded = true;
}
else {
- /*
+ /*
* Create NSS-style object specific to this extension, just
- * by knowing its length and ASN template.
+ * by knowing its length and ASN template.
* Decode the extensions's extnValue into that object. We don't
- * have to know what kind of object it is anymore.
+ * have to know what kind of object it is anymore.
*/
assert(templ != NULL);
nssObj = mCoder.malloc(nssObjLen);
memset(nssObj, 0, nssObjLen);
PRErrorCode prtn;
- prtn = mCoder.decodeItem(rawExtn, templ, nssObj);
+ prtn = mCoder.decodeItem(rawExtn, templ, nssObj);
if(prtn) {
- /*
- * FIXME - what do we do here? For now flag it
+ /*
+ * FIXME - what do we do here? For now flag it
* as an non-understood extension...
*/
clErrorLog("decodeExtensions: extension decode error\n");
nssObj = NULL;
berEncoded = true;
}
- }
+ }
if((nssObj != NULL) || berEncoded) {
/* append if the decode was successful */
addExtension(nssExten->extnId,
clNssBoolToCssm(nssExten->critical),
- nssObj,
+ nssObj,
berEncoded,
templ,
&rawExtn);
* is BER-encoded and the result is stored as an octet string
* (AsnOcts) in a new Extension object in the TBS.
*
- * Called from {Crl,Cert}CreateTemplate via encode{Tbs,Cts}().
+ * Called from {Crl,Cert}CreateTemplate via encode{Tbs,Cts}().
*/
void DecodedExtensions::encodeToNss(
NSS_CertExtension **&extensions)
/* no extensions, no error */
return;
}
-
+
/* malloc a NULL_terminated array of NSS_CertExtension pointers */
unsigned len = (mNumExtensions + 1) * sizeof(NSS_CertExtension *);
extensions = (NSS_CertExtension **)mCoder.malloc(len);
memset(extensions, 0, len);
-
- /* grind thru our DecodedExtens, creating an NSS_CertExtension for
+
+ /* grind thru our DecodedExtens, creating an NSS_CertExtension for
* each one */
for(unsigned extenDex=0; extenDex<mNumExtensions; extenDex++) {
- NSS_CertExtension *thisNssExten =
+ NSS_CertExtension *thisNssExten =
(NSS_CertExtension *)mCoder.malloc(sizeof(NSS_CertExtension));
memset(thisNssExten, 0, sizeof(NSS_CertExtension));
extensions[extenDex] = thisNssExten;
-
+
const DecodedExten *decodedExt = getExtension(extenDex);
-
+
/* BER-encode the extension object if appropriate */
if(decodedExt->berEncoded()) {
/* unknown extension type, it's already encoded */
void DecodedExtensions::addExtension(
const CSSM_OID &extnId, // copied
bool critical,
- void *nssObj, // NSS_KeyUsage, NSS_BasicConstraints,
+ void *nssObj, // NSS_KeyUsage, NSS_BasicConstraints,
// etc. NOT COPIED, exists in same
// memory space as coder
bool berEncoded, // indicates unknown extension which we
// do not BER-decode when parsing a cert
const SecAsn1Template *templ, // required if !berEncoded
const CSSM_DATA *rawExtn) // NSS_CertExtension.value, copied,
- // optional (not present during a
+ // optional (not present during a
// SetField op)
{
if(mNumExtensions == mSizeofExtensions) {
/* expand by doubling, or initial malloc */
- mSizeofExtensions = mNumExtensions ?
+ mSizeofExtensions = mNumExtensions ?
(2 * mNumExtensions) : MIN_EXTENSIONS;
mExtensions = (DecodedExten **)mAlloc.realloc(
mExtensions, mSizeofExtensions * sizeof(DecodedExten));
mExtensions[mNumExtensions++] = new DecodedExten(extnId,
critical, nssObj, berEncoded, templ, mCoder, rawExtn);
}
-
+
const DecodedExten *DecodedExtensions::getExtension(
unsigned extenDex) const
{
}
cssmExtens.extensions = (CSSM_X509_EXTENSION_PTR)alloc.malloc(
sizeof(CSSM_X509_EXTENSION) * mNumExtensions);
- memset(cssmExtens.extensions, 0,
+ memset(cssmExtens.extensions, 0,
sizeof(CSSM_X509_EXTENSION) * mNumExtensions);
cssmExtens.numberOfExtensions = mNumExtensions;
for(unsigned dex=0; dex<mNumExtensions; dex++) {