X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_x509_cl/lib/DecodedExtensions.cpp diff --git a/libsecurity_apple_x509_cl/lib/DecodedExtensions.cpp b/libsecurity_apple_x509_cl/lib/DecodedExtensions.cpp deleted file mode 100644 index 2f5bedc6..00000000 --- a/libsecurity_apple_x509_cl/lib/DecodedExtensions.cpp +++ /dev/null @@ -1,543 +0,0 @@ -/* - * 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 - * 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. - */ - - -/* - * 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 "CSPAttacher.h" -#include "CLFieldsCommon.h" -#include "clNssUtils.h" -#include "clNameUtils.h" -#include -#include -#include - -#define MIN_EXTENSIONS 4 // initial size of *mExtensions - -DecodedExten::DecodedExten( - const CSSM_OID &extnId, // copied - bool critical, - 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, // to decode/encode if !berEncoded - SecNssCoder &coder, // all local allocs from here - const CSSM_DATA *rawExtn) // NSS_CertExtension.value, copied to - // mRawExtn - : mCritical(critical), - mNssObj(nssObj), - mBerEncoded(berEncoded), - mTempl(templ), - mCoder(coder), - mRawExtn(NULL) -{ - coder.allocCopyItem(extnId, mExtnId); - if(rawExtn) { - mRawExtn = (CSSM_DATA *)coder.malloc(sizeof(CSSM_DATA)); - coder.allocCopyItem(*rawExtn, *mRawExtn); - } -} - -DecodedExten::~DecodedExten() -{ - /* the only stuff we allocated was in the coder pool and will be freed - * 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 - * specified allocator, but the referent (in CSSM_X509EXT_TAGandVALUE.value) - * merely points to data inside the berValue. - */ -CSSM_X509EXT_TAGandVALUE *DecodedExten::createTagAndValue( - const CSSM_DATA &berValue, - Allocator &alloc) const -{ - if((berValue.Data == NULL) || (berValue.Length == 0)) { - return NULL; - } - 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 - * 127 bytes, but we only have room for 32 bits! - */ - const uint8 *lp = berValue.Data + 1; - uint8 len1 = *lp; - if((len1 & 0x80) == 0) { - /* short form */ - tv->value.Length = len1; - tv->value.Data = const_cast(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; dexvalue.Length = len; - tv->value.Data = const_cast(lp); - return tv; -#endif -} - -/* - * Convert this extension to a CSSM_X509_EXTENSION, in the specified - * (app-level) alloc space, after its contents have - * been converted to a native CDSA object (CE_KeyUsage, etc.). - */ -void DecodedExten::convertToCdsa( - void *cdsaObj, // e.g. CE_KeyUsage - // CSSM_DATA_PTR for berEncoded - CSSM_X509_EXTENSION_PTR cssmExt, // contents RETURNED - Allocator &alloc) const -{ - 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). - */ - if(mRawExtn) { - clAllocCopyData(alloc, *mRawExtn, cssmExt->BERvalue); - } - else { - cssmExt->BERvalue.Data = NULL; - cssmExt->BERvalue.Length = 0; - } - if(mBerEncoded) { - /* an extension we never parsed or understood */ - assert(cdsaObj == NULL); - cssmExt->format = CSSM_X509_DATAFORMAT_ENCODED; - cssmExt->value.tagAndValue = createTagAndValue(cssmExt->BERvalue, alloc); - } - else { - /* caller sees parsed version plus raw BER-encoded bytes */ - assert(cdsaObj != NULL); - cssmExt->format = CSSM_X509_DATAFORMAT_PARSED; - /* in app alloc's space, mallocd by getField*() */ - cssmExt->value.parsedValue = cdsaObj; - } -} - -/* - * 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 - * unknown extension type in which case mNssObj is an AsnOcts containing - * the opaquely DER-encoded extension value. - * - * Currently only used when decoding a CRL and converting it en masse - * to CDSA. - */ -template -void nssToCssm( - const DecodedExten &decodedExt, - NssType *&nssObj, // RETURNED - CdsaType *&cdsaObj, // mallocd and RETURNED - Allocator &alloc) -{ - nssObj = (NssType *)(decodedExt.nssObj()); - assert(nssObj != NULL); - cdsaObj = (CdsaType *)alloc.malloc(sizeof(CdsaType)); - memset(cdsaObj, 0, sizeof(CdsaType)); -} - -void DecodedExten::parse( - CSSM_X509_EXTENSION_PTR cssmExt, // mallocd by caller, RETURNED - Allocator &alloc) const -{ - void *vCdsaObj = NULL; - if(mBerEncoded) { - /* non-understood extension */ - convertToCdsa(NULL, cssmExt, alloc); - return; - } - if(clCompareCssmData(&mExtnId, &CSSMOID_AuthorityKeyIdentifier)) { - CE_AuthorityKeyID *cdsaObj; - NSS_AuthorityKeyId *nssObj; - nssToCssm( - *this, - nssObj, - cdsaObj, - alloc); - CL_nssAuthorityKeyIdToCssm(*nssObj, *cdsaObj, mCoder, alloc); - vCdsaObj = cdsaObj; - } - /* same encoding (uint32) for all of these: */ - else if(clCompareCssmData(&mExtnId, &CSSMOID_CrlNumber) || - clCompareCssmData(&mExtnId, &CSSMOID_DeltaCrlIndicator) || - clCompareCssmData(&mExtnId, &CSSMOID_CrlReason)) { - CE_CrlNumber *cdsaObj; - CSSM_DATA *nssObj; - nssToCssm( - *this, - nssObj, - cdsaObj, - alloc); - CSSM_RETURN toThrow; - if(clCompareCssmData(&mExtnId, &CSSMOID_CrlReason)) { - toThrow = CSSMERR_CL_INVALID_CRL_POINTER; - } - else { - /* tolerate crlNumber > 4 bytes */ - toThrow = CSSM_OK; - } - *cdsaObj = clDataToInt(*nssObj, toThrow); - vCdsaObj = cdsaObj; - } - /* same encoding (GeneralNames) for all of these: */ - else if(clCompareCssmData(&mExtnId, &CSSMOID_IssuerAltName) || - clCompareCssmData(&mExtnId, &CSSMOID_SubjectAltName) || - clCompareCssmData(&mExtnId, &CSSMOID_CertIssuer)) { - CE_GeneralNames *cdsaObj; - NSS_GeneralNames *nssObj; - nssToCssm( - *this, - nssObj, - cdsaObj, - alloc); - CL_nssGeneralNamesToCssm(*nssObj, *cdsaObj, mCoder, alloc); - vCdsaObj = cdsaObj; - } - else if(clCompareCssmData(&mExtnId, &CSSMOID_IssuingDistributionPoint)) { - CE_IssuingDistributionPoint *cdsaObj; - NSS_IssuingDistributionPoint *nssObj; - nssToCssm( - *this, - nssObj, - cdsaObj, - alloc); - CL_nssIssuingDistPointToCssm(nssObj, cdsaObj, mCoder, alloc); - vCdsaObj = cdsaObj; - } - /* - CrashTracer: [USER] 48 crashes in WebProcess at ... - This code should not normally be executed, since it seems from RFC5280 that - CSSMOID_IssuingDistributionPoint is the correct extension to use. - */ - else if(clCompareCssmData(&mExtnId, &CSSMOID_CrlDistributionPoints)) { - CE_CRLDistPointsSyntax *cdsaObj; - NSS_CRLDistributionPoints *nssObj; - nssToCssm( - *this, - nssObj, - cdsaObj, - alloc); - CL_nssDistPointsToCssm((const NSS_CRLDistributionPoints&)*nssObj, *cdsaObj, mCoder, alloc); - vCdsaObj = cdsaObj; - } - /* - * cert entry extensions - */ - else if(clCompareCssmData(&mExtnId, &CSSMOID_HoldInstructionCode)) { - /* value is just an OID */ - CSSM_OID *cdsaObj; - CSSM_DATA *nssObj; - nssToCssm( - *this, - nssObj, - cdsaObj, - alloc); - clAllocCopyData(alloc, *nssObj, *cdsaObj); - vCdsaObj = cdsaObj; - } - else if(clCompareCssmData(&mExtnId, &CSSMOID_InvalidityDate)) { - /* GeneralizedTime */ - CSSM_DATA *cdsaObj; - CSSM_DATA *nssObj; - nssToCssm( - *this, - nssObj, - cdsaObj, - alloc); - clAllocCopyData(alloc, *nssObj, *cdsaObj); - vCdsaObj = cdsaObj; - } - else { - /* if we get here, this routine is not keeping up with - * clOidToNssInfo() */ - // assert(0); - CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR); - } - convertToCdsa(vCdsaObj, cssmExt, alloc); -} - - -#pragma mark ------ DecodedExtensions ------ - -/* - * A variable-size array of DecodedExtens. - * Used for storing cert and CRL extensions as well as per-CRL-entry - * extensions. - */ -DecodedExtensions::DecodedExtensions( - SecNssCoder &coder, - Allocator &alloc) - : mCoder(coder), - mAlloc(alloc), - mExtensions(NULL), - mNumExtensions(0), - mSizeofExtensions(0) -{ - -} - -DecodedExtensions::~DecodedExtensions() -{ - for(unsigned i=0; iextnId, cook up an appropriate - * NSS-specific type (NSS_KeyUsage, etc.); - */ - CSSM_DATA &rawExtn = nssExten->value; - bool berEncoded = false; - bool found; // we understand this OID - unsigned nssObjLen; // size of associated NSS object - const SecAsn1Template *templ = NULL; // template for decoding - 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. - * Decode the extensions's extnValue into that object. We don't - * 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); - if(prtn) { - /* - * 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, - berEncoded, - templ, - &rawExtn); - } - } -} - -/* - * Encode into a NSS-style Extensions. - * - * Each extension object, currently stored as some AsnType subclass, - * 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}(). - */ -void DecodedExtensions::encodeToNss( - NSS_CertExtension **&extensions) -{ - assert(extensions == NULL); - - if(mNumExtensions == 0) { - /* 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 - * each one */ - for(unsigned extenDex=0; extenDexberEncoded()) { - /* unknown extension type, it's already encoded */ - const CSSM_DATA *srcBer = (const CSSM_DATA *)decodedExt->rawExtn(); - assert(srcBer != NULL); - mCoder.allocCopyItem(*srcBer, thisNssExten->value); - } - else { - PRErrorCode prtn; - prtn = mCoder.encodeItem(decodedExt->nssObj(), - decodedExt->templ(), thisNssExten->value); - if(prtn) { - clErrorLog("encodeToNss: extension encode error"); - CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR); - } - } - ArenaAllocator arenaAlloc(mCoder); - if(decodedExt->critical()) { - /* optional, default false */ - clCssmBoolToNss(CSSM_TRUE, thisNssExten->critical, arenaAlloc); - } - mCoder.allocCopyItem(decodedExt->extnId(), thisNssExten->extnId); - } -} - -/* add/retrieve entries */ -void DecodedExtensions::addExtension( - const CSSM_OID &extnId, // copied - bool critical, - 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 - // SetField op) -{ - if(mNumExtensions == mSizeofExtensions) { - /* expand by doubling, or initial malloc */ - 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 -{ - assert(extenDex < mNumExtensions); - return mExtensions[extenDex]; -} - -/* Convert to CSSM_X509_EXTENSIONS */ -/* Currently only used when decoding a CRL and converting it en masse - * to CDSA */ -void DecodedExtensions::convertToCdsa( - CSSM_X509_EXTENSIONS &cssmExtens, - Allocator &alloc) const -{ - memset(&cssmExtens, 0, sizeof(cssmExtens)); - if(mNumExtensions == 0) { - return; - } - cssmExtens.extensions = (CSSM_X509_EXTENSION_PTR)alloc.malloc( - sizeof(CSSM_X509_EXTENSION) * mNumExtensions); - memset(cssmExtens.extensions, 0, - sizeof(CSSM_X509_EXTENSION) * mNumExtensions); - cssmExtens.numberOfExtensions = mNumExtensions; - for(unsigned dex=0; dexparse(&cssmExtens.extensions[dex], alloc); - } - catch(...) { - /* FIXME - what now? */ - clFieldLog("DecodedExtensions:convertToCdsa: extension " - "decode error"); - } - } -} -