]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_apple_x509_cl/lib/DecodedExtensions.cpp
Security-55471.14.8.tar.gz
[apple/security.git] / libsecurity_apple_x509_cl / lib / DecodedExtensions.cpp
index 92b6cf262ff4f441d1c462d636ebb2da31065b30..2f5bedc6f3158c79f5972802f760b3c9f1f8f3e2 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * 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>
 
@@ -37,7 +38,7 @@
 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
@@ -66,11 +67,11 @@ DecodedExten::~DecodedExten()
         * 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,
@@ -81,10 +82,24 @@ CSSM_X509EXT_TAGandVALUE *DecodedExten::createTagAndValue(
        }
        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;
@@ -95,14 +110,14 @@ CSSM_X509EXT_TAGandVALUE *DecodedExten::createTagAndValue(
                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++) {
@@ -113,6 +128,7 @@ CSSM_X509EXT_TAGandVALUE *DecodedExten::createTagAndValue(
        tv->value.Length = len;
        tv->value.Data = const_cast<uint8 *>(lp);
        return tv;
+#endif
 }
 
 /*
@@ -128,10 +144,10 @@ void DecodedExten::convertToCdsa(
 {
        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);
@@ -157,12 +173,12 @@ void DecodedExten::convertToCdsa(
 
 /*
  * 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.
  */
@@ -173,7 +189,7 @@ void nssToCssm(
        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));
@@ -257,14 +273,14 @@ void DecodedExten::parse(
                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 */
@@ -291,7 +307,7 @@ void DecodedExten::parse(
                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);
@@ -304,10 +320,10 @@ void DecodedExten::parse(
 
 /*
  * 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),
@@ -318,7 +334,7 @@ DecodedExtensions::DecodedExtensions(
 {
 
 }
-       
+
 DecodedExtensions::~DecodedExtensions()
 {
        for(unsigned i=0; i<mNumExtensions; i++) {
@@ -334,16 +350,16 @@ DecodedExtensions::~DecodedExtensions()
 
 /*
  * 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 */
@@ -354,9 +370,9 @@ void DecodedExtensions::decodeFromNss(
        /* 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;
@@ -367,38 +383,38 @@ void DecodedExtensions::decodeFromNss(
                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);
@@ -413,7 +429,7 @@ void DecodedExtensions::decodeFromNss(
  * 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)
@@ -424,22 +440,22 @@ void DecodedExtensions::encodeToNss(
                /* 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 */
@@ -469,19 +485,19 @@ void DecodedExtensions::encodeToNss(
 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));
@@ -489,7 +505,7 @@ void DecodedExtensions::addExtension(
        mExtensions[mNumExtensions++] = new DecodedExten(extnId,
                critical, nssObj, berEncoded, templ, mCoder, rawExtn);
 }
-       
+
 const DecodedExten *DecodedExtensions::getExtension(
        unsigned extenDex) const
 {
@@ -510,7 +526,7 @@ void DecodedExtensions::convertToCdsa(
        }
        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++) {