+++ /dev/null
-/*
- * Copyright (c) 2000-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.h - class representing the common portions of NSS-format
- * decoded certs and CRLs, with extensions parsed and decoded (still in
- * NSS format).
- *
- * When a DecodedItem (cert or CRL) is quiescent and cached in the CL
- * (either by an explicit cache call like CSSM_CL_CertCache or
- * CSSM_CL_CrlCache(), or during a succession of GetFirst/GetNext field
- * ops), the item is stored in the CL in what we call NSS form. NSS is
- * the module we use to perform DER encoding and decoding; NSS form
- * refers to structs defining Certs, CRLs, and extensions which are
- * directly encodable and decodable by the NSS library. NSS structs are
- * similar to their CDSA counterparts, sometimes identical, usually
- * subtly different (due to requirements of the NSS module).
- *
- * Decoding a cert or a CRL:
- * -------------------------
- *
- * When an app decodes a cert or CRL for any reason, the following phases
- * are executed:
- *
- * PHASE I
- * -------
- *
- * Basic BER-decode if the incoming CSSM_DATA blob. This happens in the
- * constructors for DecodedCert and DecodedCrl. A modified/restricted
- * version of this occurs in DecodedCert::decodeTbs(), which is used
- * during a CSSM_CL_CertGetAllTemplateFields() call.
- *
- * PHASE II
- * --------
- *
- * Extensions are converted from untyped blobs - which is how they look
- * after PHASE I - to NSS-style C structs. This is done by examining
- * the ExtnId of each cert's or CRL's extensions and doing a BER decode
- * specific to that extension type. This is performed in
- * DecodedExtensions.decodeFromNss() which is called immediately after
- * the top-level decode performed in PHASE I.
- *
- * It is at this point that a cert or CRL can be cached in the CL's
- * cacheMap or queryMap (see AppleX509CLSession.{h,cpp}. We call this
- * state "NSS Form".
- *
- * PHASE III (CRLs only)
- * --------------------
- *
- * This occurs when an app is actually fetching a full CRL in
- * CDSA form. Individual entries in a CRL's revocation list also
- * contain per-entry extension lists. These are converted from
- * untyped blobs to meaningful NSS-style extension structs as
- * in PHASE II prior to the conversion to CDSA form in PHASE IV.
- *
- * PHASE IV
- * ---------
- *
- * This occurs when an app is actually fetching fields in CDSA form.
- * This involves converting objects from NSS form to CDSA form
- * (if necessary) and copying to the session allocator's memory space.
- *
- * The rationale behind this phased approach - in particular, the
- * reason that in-memory items are stored in NSS form - is that this
- * minimizes the number of copies between the intiial parse of a cert
- * or CRL and the final GetField op. Since a GetField op inherently
- * requires a copy (from internal memory to the session allocator's
- * space), and conversion from NSS to CDSA form is basically a bunch of
- * copies as well, we might as well just stop with the item in CRL
- * format as soon as PHASE II is complete. Note that completion of
- * PHASE II is in fact required before caching a cert since that enables
- * us to have access to extension-specific info while a cert is
- * cached. The KeyUsage and ExtendedKeyUsage extensions are used in
- * this manner to get key info from a TBS cert.
- *
- *
- * Creating and encoding a cert:
- * -----------------------------
- *
- * Creating a cert (creating CRLs is not supported in this release)
- * follows more or less the reverse procedure, as follows:
- *
- * PHASE I
- * -------
- *
- * During a CSSM_CL_CertCreateTemplate() op, all fields which the
- * app wishes to specify are passed into the CL in CDSA form. These
- * fields are converted to NSS form in a temporary DecodedCert. This
- * includes extensions (in NSS form).
- *
- * PHASE II
- * --------
- *
- * Extensions in NSS form are encoded and bundled up into the final,
- * BER-encode ready NSS_CertExtension array form. This occurs
- * in DecodedCert::encodeExtensions(), called from the top of
- * DecodedCert::encodeTbs(). We're still processing an app's
- * CSSM_CL_CertCreateTemplate() call at this point.
- *
- * PHASE III
- * ---------
- *
- * Final DER-encoding of a TBS cert is performed in
- * DecodedCert::encodeTbs(). The resulting CSSM_DATA is
- * passed back to the app as what CDSA calls a template.
- * This completes the CSSM_CL_CertCreateTemplate() call.
- *
- * PHASE IV
- * --------
- *
- * The TBS cert blob is signed and the resulting DER-encoded
- * cert is passed back to the app.
- */
-
-#ifndef _DECODED_ITEM_H_
-#define _DECODED_ITEM_H_
-
-#include <Security/cssmtype.h>
-#include <security_cdsa_utilities/cssmdata.h>
-
-#include "cldebugging.h"
-#include "DecodedExtensions.h"
-#include <security_asn1/SecNssCoder.h>
-
-/* state of a DecodedItem */
-typedef enum {
- IS_Empty,
- IS_DecodedAll, // can't set fields in this state
- IS_DecodedTBS, // ditto
- IS_Building // in the process of setting fields
-} ItemState;
-
-
-class AppleX509CLSession;
-
-class DecodedItem
-{
-public:
- DecodedItem(
- AppleX509CLSession &session);
-
- virtual ~DecodedItem();
-
- SecNssCoder &coder() { return mCoder; }
-
- static void describeFormat(
- Allocator &alloc,
- uint32 &NumberOfFields,
- CSSM_OID_PTR &OidList);
-
-public:
- /***
- *** Extensions support
- ***/
-
- /* called from decodeExtensions and setField* */
- void addExtension(
- void *nssThing, // e.g. NSS_KeyUsage
- const CSSM_OID &extnId,
- bool critical,
- bool berEncoded,
- const SecAsn1Template *templ, // to decode/encode if !berEncoded
- const CSSM_DATA *rawExtn=NULL) // Extension.extnValue, copied, only for
- // setField*()
- { mDecodedExtensions.addExtension(extnId, critical, nssThing,
- berEncoded, templ, rawExtn);
- }
-
- const DecodedExten *findDecodedExt(
- const CSSM_OID &extnId, // for known extensions
- bool unknown, // otherwise
- uint32 index,
- uint32 &numFields) const;
-
- const DecodedExtensions &decodedExtens() const
- { return mDecodedExtensions; }
-
- /*
- * Common code for get extension field routines.
- * Given an OID identifying an extension and an index, see if
- * we have the specified extension in mDecodedExtensions and
- * return the NSS and CDSA style objects as well as the
- * DecodedExten.
- */
- template<class NssType, class CdsaType>
- bool GetExtenTop(
- unsigned index, // which occurrence (0 = first)
- uint32 &numFields, // RETURNED
- Allocator &alloc,
- const CSSM_OID &fieldId, // identifies extension we seek
- NssType *&nssObj, // RETURNED
- CdsaType *&cdsaObj, // mallocd and RETURNED
- const DecodedExten *&decodedExt) const // RETURNED
- {
- /* See if we have one of these in our list of DecodedExtens */
- decodedExt = findDecodedExt(fieldId, false, index, numFields);
- if(decodedExt == NULL) {
- return false;
- }
- nssObj = (NssType *)decodedExt->nssObj();
- cdsaObj = (CdsaType *)alloc.malloc(sizeof(CdsaType));
- memset(cdsaObj, 0, sizeof(CdsaType));
- return true;
- }
-
-protected:
- ItemState mState;
- Allocator &mAlloc;
- SecNssCoder mCoder; // from which all local allocs come
- AppleX509CLSession &mSession;
- DecodedExtensions mDecodedExtensions;
-
-};
-
-
-#endif /* _DECODED_ITEM_H_ */