X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_x509_cl/lib/CLFieldsCommon.cpp diff --git a/libsecurity_apple_x509_cl/lib/CLFieldsCommon.cpp b/libsecurity_apple_x509_cl/lib/CLFieldsCommon.cpp deleted file mode 100644 index f507a236..00000000 --- a/libsecurity_apple_x509_cl/lib/CLFieldsCommon.cpp +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (c) 2002-2010 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. - */ - - -/* - * CLFieldsCommon.h - get/set/free routines common to certs and CRLs - */ - -#include "CLFieldsCommon.h" -#include "clNameUtils.h" -#include "clNssUtils.h" -#include "AppleX509CLSession.h" -#include -#include -#include -#include -#include - -/* - * Table to map an OID to the info needed to decode the - * associated extension - */ -typedef struct { - const CSSM_OID &oid; - unsigned nssObjLen; - const SecAsn1Template *templ; -} NssExtenInfo; - -static const NssExtenInfo nssExtenInfo[] = { - { CSSMOID_KeyUsage, - sizeof(CSSM_DATA), - kSecAsn1KeyUsageTemplate }, - { CSSMOID_BasicConstraints, - sizeof(NSS_BasicConstraints), - kSecAsn1BasicConstraintsTemplate }, - { CSSMOID_ExtendedKeyUsage, - sizeof(NSS_ExtKeyUsage), - kSecAsn1ExtKeyUsageTemplate }, - { CSSMOID_SubjectKeyIdentifier, - sizeof(CSSM_DATA), - kSecAsn1SubjectKeyIdTemplate }, - { CSSMOID_AuthorityKeyIdentifier, - sizeof(NSS_AuthorityKeyId), - kSecAsn1AuthorityKeyIdTemplate }, - { CSSMOID_SubjectAltName, - sizeof(NSS_GeneralNames), - kSecAsn1GeneralNamesTemplate }, - { CSSMOID_IssuerAltName, - sizeof(NSS_GeneralNames), - kSecAsn1GeneralNamesTemplate }, - { CSSMOID_CertificatePolicies, - sizeof(NSS_CertPolicies), - kSecAsn1CertPoliciesTemplate }, - { CSSMOID_NetscapeCertType, - sizeof(CSSM_DATA), - kSecAsn1NetscapeCertTypeTemplate }, - { CSSMOID_CrlDistributionPoints, - sizeof(NSS_CRLDistributionPoints), - kSecAsn1CRLDistributionPointsTemplate }, - { CSSMOID_CertIssuer, - sizeof(NSS_GeneralNames), - kSecAsn1GeneralNamesTemplate }, - { CSSMOID_AuthorityInfoAccess, - sizeof(NSS_AuthorityInfoAccess), - kSecAsn1AuthorityInfoAccessTemplate }, - { CSSMOID_SubjectInfoAccess, - sizeof(NSS_AuthorityInfoAccess), - kSecAsn1AuthorityInfoAccessTemplate }, - /* CRL extensions */ - { CSSMOID_CrlNumber, - sizeof(CSSM_DATA), - kSecAsn1IntegerTemplate }, - { CSSMOID_IssuingDistributionPoint, - sizeof(NSS_IssuingDistributionPoint), - kSecAsn1IssuingDistributionPointTemplate }, - { CSSMOID_HoldInstructionCode, - sizeof(CSSM_OID), - kSecAsn1ObjectIDTemplate }, - { CSSMOID_CrlReason, - sizeof(CSSM_DATA), - kSecAsn1EnumeratedTemplate }, - { CSSMOID_DeltaCrlIndicator, - sizeof(CSSM_DATA), - kSecAsn1IntegerTemplate }, - { CSSMOID_InvalidityDate, - sizeof(CSSM_DATA), - kSecAsn1GeneralizedTimeTemplate }, - { CSSMOID_QC_Statements, - sizeof(NSS_QC_Statements), - kSecAsn1QC_StatementsTemplate }, - { CSSMOID_NameConstraints, - sizeof(NSS_NameConstraints), - kSecAsn1NameConstraintsTemplate }, - { CSSMOID_PolicyMappings, - sizeof(NSS_PolicyMappings), - kSecAsn1PolicyMappingsTemplate }, - { CSSMOID_PolicyConstraints, - sizeof(NSS_PolicyConstraints), - kSecAsn1PolicyConstraintsTemplate }, - { CSSMOID_InhibitAnyPolicy, - sizeof(CSSM_DATA), - kSecAsn1IntegerTemplate }, -}; - -#define NUM_NSS_EXTEN_INFOS (sizeof(nssExtenInfo) / sizeof(nssExtenInfo[0])) - -/* - * Returns true if we find the OID. - */ -bool clOidToNssInfo( - const CSSM_OID &oid, - unsigned &nssObjLen, // RETURNED - const SecAsn1Template *&templ) // RETURNED -{ - for(unsigned dex=0; dex(fieldValue.data()); - if(berEncoded) { - if(cssmExt->BERvalue.Data == NULL) { - CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER); - } - } - else { - if(cssmExt->value.parsedValue == NULL) { - CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER); - } - } - return cssmExt; -} - -/* - * Common free code for all extensions. Extension-specific code must - * free anything beyond cdsaExt->Value.parsedValue, then we free everything - * else (except the extension struct itself, which is freed by - * DecodedCert::freeCertFieldData()). - * The value union may contain a parsed value, or a CSSM_X509EXT_TAGandVALUE; - * wed ont' care, we just free it. - */ -void freeFieldExtenCommon( - CSSM_X509_EXTENSION_PTR exten, - Allocator &alloc) -{ - alloc.free(exten->extnId.Data); - alloc.free(exten->BERvalue.Data); // may be NULL - alloc.free(exten->value.parsedValue); // may be NULL -} - -/* - * One common free for extensions whose parsed value doesn't go any deeper - * than cssmExt->value.parsedValue. - */ -void freeFieldSimpleExtension ( - CssmOwnedData &fieldValue) -{ - CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, - false); - freeFieldExtenCommon(cssmExt, fieldValue.allocator); -} - - -/*** - *** Common code for get/set subject/issuer name (C struct version) - *** Format = CSSM_X509_NAME - *** class Name from sm_x501if - ***/ -bool getField_RDN_NSS ( - const NSS_Name &nssName, - CssmOwnedData &fieldValue) // RETURNED -{ - /* alloc top-level CSSM_X509_NAME */ - Allocator &alloc = fieldValue.allocator; - fieldValue.malloc(sizeof(CSSM_X509_NAME)); - CSSM_X509_NAME_PTR cssmName = (CSSM_X509_NAME_PTR)fieldValue.data(); - - CL_nssNameToCssm(nssName, *cssmName, alloc); - return true; -} - -void freeField_RDN ( - CssmOwnedData &fieldValue) -{ - if(fieldValue.data() == NULL) { - return; - } - if(fieldValue.length() != sizeof(CSSM_X509_NAME)) { - CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER); - } - Allocator &alloc = fieldValue.allocator; - CSSM_X509_NAME_PTR x509Name = (CSSM_X509_NAME_PTR)fieldValue.data(); - CL_freeX509Name(x509Name, alloc); - - /* top-level x509Name pointer freed by freeCertFieldData() */ -} - -/*** - *** Common code for Issuer Name, Subject Name (normalized and encoded - *** version) - *** Format = CSSM_DATA containing the DER encoding of the normalized name - ***/ -bool getField_normRDN_NSS ( - const CSSM_DATA &derName, - uint32 &numFields, // RETURNED (if successful, 0 or 1) - CssmOwnedData &fieldValue) // RETURNED -{ - if(derName.Data == NULL) { - /* This can happen during CertGetAllTemplateFields() because - * the normalized fields are only set up during cert/CRL decode */ - return false; - } - - /* - * First make a temp decoded copy which we'll be manipulating. - */ - SecNssCoder coder; - NSS_Name decodedName; - - memset(&decodedName, 0, sizeof(decodedName)); - PRErrorCode prtn = coder.decodeItem(derName, kSecAsn1NameTemplate, &decodedName); - if(prtn) { - /* - * Actually should never happen since this same bag of bits successfully - * decoded when the cert as a whole was decoded... - */ - clErrorLog("getField_normRDN decode error\n"); - CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT); - - } - - /* normalize */ - CL_normalizeX509NameNSS(decodedName, coder); - - /* encode result */ - prtn = SecNssEncodeItemOdata(&decodedName, kSecAsn1NameTemplate, fieldValue); - if(prtn) { - clErrorLog("getField_normRDN encode error\n"); - CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR); - } - numFields = 1; - return true; -} - -/*** - *** Common code for Time fields - Validity not before, Not After, - *** This Update, Next Update - *** Format: CSSM_X509_TIME - ***/ -bool getField_TimeNSS ( - const NSS_Time &nssTime, - unsigned index, // which occurrence (0 = first) - uint32 &numFields, // RETURNED - CssmOwnedData &fieldValue) // RETURNED -{ - if(!tbsGetCheck(nssTime.item.Data, index)) { - return false; - } - Allocator &alloc = fieldValue.allocator; - fieldValue.malloc(sizeof(CSSM_X509_TIME)); - CSSM_X509_TIME *cssmTime = - (CSSM_X509_TIME *)fieldValue.data(); - if(CL_nssTimeToCssm(nssTime, *cssmTime, alloc)) { - numFields = 1; - return true; - } - else { - return false; - } -} - -void setField_TimeNSS ( - const CssmData &fieldValue, - NSS_Time &nssTime, - SecNssCoder &coder) -{ - CSSM_X509_TIME *cssmTime = - (CSSM_X509_TIME *)fieldValue.data(); - CL_cssmTimeToNss(*cssmTime, nssTime, coder); -} - -void freeField_Time ( - CssmOwnedData &fieldValue) -{ - CSSM_X509_TIME *cssmTime = (CSSM_X509_TIME *)fieldValue.data(); - if(cssmTime == NULL) { - return; - } - if(fieldValue.length() != sizeof(CSSM_X509_TIME)) { - CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER); - } - CL_freeCssmTime(cssmTime, fieldValue.allocator); -} - -/*** - *** TBS AlgId, Signature AlgId - *** Format = CSSM_X509_ALGORITHM_IDENTIFIER - ***/ -void getField_AlgIdNSS ( - const CSSM_X509_ALGORITHM_IDENTIFIER &srcAlgId, - CssmOwnedData &fieldValue) // RETURNED -{ - Allocator &alloc = fieldValue.allocator; - fieldValue.malloc(sizeof(CSSM_X509_ALGORITHM_IDENTIFIER)); - CSSM_X509_ALGORITHM_IDENTIFIER *destAlgId = - (CSSM_X509_ALGORITHM_IDENTIFIER *)fieldValue.data(); - CL_copyAlgId(srcAlgId, *destAlgId, alloc); -} - -void setField_AlgIdNSS ( - const CssmData &fieldValue, - CSSM_X509_ALGORITHM_IDENTIFIER &dstAlgId, - SecNssCoder &coder) -{ - CSSM_X509_ALGORITHM_IDENTIFIER *srcAlgId = - (CSSM_X509_ALGORITHM_IDENTIFIER *)fieldValue.data(); - /* allocator for this coder */ - ArenaAllocator areanAlloc(coder); - CL_copyAlgId(*srcAlgId, dstAlgId, areanAlloc); -} - -void freeField_AlgId ( - CssmOwnedData &fieldValue) -{ - CSSM_X509_ALGORITHM_IDENTIFIER *cssmAlgId = - (CSSM_X509_ALGORITHM_IDENTIFIER *)fieldValue.data(); - if(cssmAlgId == NULL) { - return; - } - if(fieldValue.length() != sizeof(CSSM_X509_ALGORITHM_IDENTIFIER)) { - CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER); - } - Allocator &alloc = fieldValue.allocator; - alloc.free(cssmAlgId->algorithm.Data); - alloc.free(cssmAlgId->parameters.Data); - memset(cssmAlgId, 0, sizeof(CSSM_X509_ALGORITHM_IDENTIFIER)); -} - -/* - * Routines for common validity checking for certificateToSign fields. - * - * Call from setField*: verify field isn't already set, optionally validate - * input length - */ -void tbsSetCheck( - void *fieldToSet, - const CssmData &fieldValue, - uint32 expLength, - const char *op) -{ - if(fieldToSet != NULL) { - /* can't add another */ - clErrorLog("setField(%s): field already set", op); - CssmError::throwMe(CSSMERR_CL_INVALID_NUMBER_OF_FIELDS); - } - if((expLength != 0) && (fieldValue.length() != expLength)) { - clErrorLog("setField(%s): bad length : exp %d got %d", - op, (int)expLength, (int)fieldValue.length()); - CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER); - } -} - -/* - * Call from getField* for unique fields - detect missing field or - * index out of bounds. - */ -bool tbsGetCheck( - const void *requiredField, - uint32 reqIndex) -{ - if((requiredField == NULL) || (reqIndex != 0)) { - return false; - } - else { - return true; - } -} - -/*** - *** unknown extensions - *** CDSA format: raw bytes in a CSSM_DATA. This data is the BER-encoding of - *** some extension struct we don't know about. - *** NSS format CSSM_DATA - *** OID CSSMOID_X509V3CertificateExtensionCStruct - ***/ - -void setFieldUnknownExt( - DecodedItem &cert, - const CssmData &fieldValue) -{ - CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, true); - SecNssCoder &coder = cert.coder(); - CSSM_DATA *rawExtn = (CSSM_DATA *)coder.malloc(sizeof(CSSM_DATA)); - coder.allocCopyItem(cssmExt->BERvalue, *rawExtn); - cert.addExtension(NULL, cssmExt->extnId, cssmExt->critical, - true, NULL /* no template */, rawExtn); -} - -bool getFieldUnknownExt( - DecodedItem &cert, - unsigned index, // which occurrence (0 = first) - uint32 &numFields, // RETURNED - CssmOwnedData &fieldValue) -{ - uint8 noOidDataLikeThis[2] = {1, 2}; // a dummy argument - CSSM_OID noOidLikeThis = {2, noOidDataLikeThis}; - const DecodedExten *decodedExt = - cert.DecodedItem::findDecodedExt(noOidLikeThis, - true, index, numFields); - if(decodedExt == NULL) { - return false; - } - getFieldExtenCommon(NULL, *decodedExt, fieldValue); - return true; -} - -void freeFieldUnknownExt ( - CssmOwnedData &fieldValue) -{ - CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, true); - Allocator &alloc = fieldValue.allocator; - freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue -} - -/* setField for read-only OIDs (i.e., the ones in cert/CRL, not TBS) */ -void setField_ReadOnly ( - DecodedItem &item, - const CssmData &fieldValue) -{ - clErrorLog("Attempt to set a read-only field"); - CssmError::throwMe(CSSMERR_CL_UNKNOWN_TAG); -} - -bool getField_Unimplemented ( - DecodedItem &item, - unsigned index, // which occurrence (0 = first) - uint32 &numFields, // RETURNED - CssmOwnedData &fieldValue) // RETURNED -{ - clErrorLog("Attempt to get an unimplemented field"); - CssmError::throwMe(CSSMERR_CL_UNKNOWN_TAG); -} - - -