X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/Security/libsecurity_cdsa_utils/lib/cuDbUtils.cpp diff --git a/Security/libsecurity_cdsa_utils/lib/cuDbUtils.cpp b/Security/libsecurity_cdsa_utils/lib/cuDbUtils.cpp deleted file mode 100644 index 9e8f65a0..00000000 --- a/Security/libsecurity_cdsa_utils/lib/cuDbUtils.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/* - * Copyright (c) 2002-2003,2011-2012,2014 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. - */ - -/* - File: cuDbUtils.cpp - - Description: CDSA DB access utilities - - Author: dmitch -*/ - -#include "cuCdsaUtils.h" -#include "cuTimeStr.h" -#include "cuDbUtils.h" -#include "cuPrintCert.h" -#include -#include -#include -#include /* private SecInferLabelFromX509Name() */ -#include /* for cssmPerror() */ -#include -#include -#include -#include -#include /* private API */ - -#ifndef NDEBUG -#define dprintf(args...) printf(args) -#else -#define dprintf(args...) -#endif - -/* - * Add a certificate to an open DLDB. - */ -CSSM_RETURN cuAddCertToDb( - CSSM_DL_DB_HANDLE dlDbHand, - const CSSM_DATA *cert, - CSSM_CERT_TYPE certType, - CSSM_CERT_ENCODING certEncoding, - const char *printName, // C string - const CSSM_DATA *publicKeyHash) -{ - CSSM_DB_ATTRIBUTE_DATA attrs[6]; - CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs; - CSSM_DB_ATTRIBUTE_DATA_PTR attr = &attrs[0]; - CSSM_DATA certTypeData; - CSSM_DATA certEncData; - CSSM_DATA printNameData; - CSSM_RETURN crtn; - CSSM_DB_UNIQUE_RECORD_PTR recordPtr; - - /* issuer and serial number required, fake 'em */ - CSSM_DATA issuer = {6, (uint8 *)"issuer"}; - CSSM_DATA serial = {6, (uint8 *)"serial"}; - - /* we spec six attributes, skipping alias */ - certTypeData.Data = (uint8 *)&certType; - certTypeData.Length = sizeof(CSSM_CERT_TYPE); - certEncData.Data = (uint8 *)&certEncoding; - certEncData.Length = sizeof(CSSM_CERT_ENCODING); - printNameData.Data = (uint8 *)printName; - printNameData.Length = strlen(printName) + 1; - - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "CertType"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_UINT32; - attr->NumberOfValues = 1; - attr->Value = &certTypeData; - - attr++; - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "CertEncoding"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_UINT32; - attr->NumberOfValues = 1; - attr->Value = &certEncData; - - attr++; - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "PrintName"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - attr->NumberOfValues = 1; - attr->Value = &printNameData; - - attr++; - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "PublicKeyHash"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - attr->NumberOfValues = 1; - attr->Value = (CSSM_DATA_PTR)publicKeyHash; - - attr++; - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "Issuer"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - attr->NumberOfValues = 1; - attr->Value = &issuer; - - attr++; - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "SerialNumber"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - attr->NumberOfValues = 1; - attr->Value = &serial; - - recordAttrs.DataRecordType = CSSM_DL_DB_RECORD_X509_CERTIFICATE; - recordAttrs.SemanticInformation = 0; - recordAttrs.NumberOfAttributes = 6; - recordAttrs.AttributeData = attrs; - - crtn = CSSM_DL_DataInsert(dlDbHand, - CSSM_DL_DB_RECORD_X509_CERTIFICATE, - &recordAttrs, - cert, - &recordPtr); - if(crtn) { - cuPrintError("CSSM_DL_DataInsert", crtn); - } - else { - CSSM_DL_FreeUniqueRecord(dlDbHand, recordPtr); - } - return crtn; -} - -static CSSM_RETURN cuAddCrlSchema( - CSSM_DL_DB_HANDLE dlDbHand); - -static void cuInferCrlLabel( - const CSSM_X509_NAME *x509Name, - CSSM_DATA *label) // not mallocd; contents are from the x509Name -{ - /* use private API for common "infer label" logic */ - const CSSM_DATA *printValue = SecInferLabelFromX509Name(x509Name); - if(printValue == NULL) { - /* punt! */ - label->Data = (uint8 *)"X509 CRL"; - label->Length = 8; - } - else { - *label = *printValue; - } -} - -/* - * Search extensions for specified OID, assumed to have underlying - * value type of uint32; returns the value and true if found. - */ -static bool cuSearchNumericExtension( - const CSSM_X509_EXTENSIONS *extens, - const CSSM_OID *oid, - uint32 *val) -{ - for(uint32 dex=0; dexnumberOfExtensions; dex++) { - const CSSM_X509_EXTENSION *exten = &extens->extensions[dex]; - if(!cuCompareOid(&exten->extnId, oid)) { - continue; - } - if(exten->format != CSSM_X509_DATAFORMAT_PARSED) { - dprintf("***Malformed extension\n"); - continue; - } - *val = *((uint32 *)exten->value.parsedValue); - return true; - } - return false; -} - -/* - * Add a CRL to an existing DL/DB. - */ -#define MAX_CRL_ATTRS 9 - -CSSM_RETURN cuAddCrlToDb( - CSSM_DL_DB_HANDLE dlDbHand, - CSSM_CL_HANDLE clHand, - const CSSM_DATA *crl, - const CSSM_DATA *URI) // optional -{ - CSSM_DB_ATTRIBUTE_DATA attrs[MAX_CRL_ATTRS]; - CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs; - CSSM_DB_ATTRIBUTE_DATA_PTR attr = &attrs[0]; - CSSM_DATA crlTypeData; - CSSM_DATA crlEncData; - CSSM_DATA printNameData; - CSSM_RETURN crtn; - CSSM_DB_UNIQUE_RECORD_PTR recordPtr; - CSSM_DATA_PTR issuer = NULL; // mallocd by CL - CSSM_DATA_PTR crlValue = NULL; // ditto - uint32 numFields; - CSSM_HANDLE result; - CSSM_CRL_ENCODING crlEnc = CSSM_CRL_ENCODING_DER; - const CSSM_X509_SIGNED_CRL *signedCrl; - const CSSM_X509_TBS_CERTLIST *tbsCrl; - CSSM_CRL_TYPE crlType; - CSSM_DATA thisUpdateData = {0, NULL}; - CSSM_DATA nextUpdateData = {0, NULL}; - char *thisUpdate = NULL; - char *nextUpdate = NULL; - unsigned timeLen; - uint32 crlNumber; - uint32 deltaCrlNumber; - CSSM_DATA crlNumberData; - CSSM_DATA deltaCrlNumberData; - bool crlNumberPresent = false; - bool deltaCrlPresent = false; - CSSM_DATA attrUri; - - /* get normalized issuer name as Issuer attr */ - crtn = CSSM_CL_CrlGetFirstFieldValue(clHand, - crl, - &CSSMOID_X509V1IssuerName, - &result, - &numFields, - &issuer); - if(crtn) { - cuPrintError("CSSM_CL_CrlGetFirstFieldValue(Issuer)", crtn); - return crtn; - } - CSSM_CL_CrlAbortQuery(clHand, result); - - /* get parsed CRL from the CL */ - crtn = CSSM_CL_CrlGetFirstFieldValue(clHand, - crl, - &CSSMOID_X509V2CRLSignedCrlCStruct, - &result, - &numFields, - &crlValue); - if(crtn) { - cuPrintError("CSSM_CL_CrlGetFirstFieldValue(Issuer)", crtn); - goto errOut; - } - CSSM_CL_CrlAbortQuery(clHand, result); - if(crlValue == NULL) { - dprintf("***CSSM_CL_CrlGetFirstFieldValue: value error (1)\n"); - crtn = CSSMERR_CL_INVALID_CRL_POINTER; - goto errOut; - } - if((crlValue->Data == NULL) || - (crlValue->Length != sizeof(CSSM_X509_SIGNED_CRL))) { - dprintf("***CSSM_CL_CrlGetFirstFieldValue: value error (2)\n"); - crtn = CSSMERR_CL_INVALID_CRL_POINTER; - goto errOut; - } - signedCrl = (const CSSM_X509_SIGNED_CRL *)crlValue->Data; - tbsCrl = &signedCrl->tbsCertList; - - /* CrlType inferred from version */ - if(tbsCrl->version.Length == 0) { - /* should never happen... */ - crlType = CSSM_CRL_TYPE_X_509v1; - } - else { - uint8 vers = tbsCrl->version.Data[tbsCrl->version.Length - 1]; - switch(vers) { - case 0: - crlType = CSSM_CRL_TYPE_X_509v1; - break; - case 1: - crlType = CSSM_CRL_TYPE_X_509v2; - break; - default: - dprintf("***Unknown version in CRL (%u)\n", vers); - crlType = CSSM_CRL_TYPE_X_509v1; - break; - } - } - crlTypeData.Data = (uint8 *)&crlType; - crlTypeData.Length = sizeof(CSSM_CRL_TYPE); - /* encoding more-or-less assumed here */ - crlEncData.Data = (uint8 *)&crlEnc; - crlEncData.Length = sizeof(CSSM_CRL_ENCODING); - - /* printName inferred from issuer */ - cuInferCrlLabel(&tbsCrl->issuer, &printNameData); - - /* cook up CSSM_TIMESTRING versions of this/next update */ - thisUpdate = cuX509TimeToCssmTimestring(&tbsCrl->thisUpdate, &timeLen); - if(thisUpdate == NULL) { - dprintf("***Badly formatted thisUpdate\n"); - } - else { - thisUpdateData.Data = (uint8 *)thisUpdate; - thisUpdateData.Length = timeLen; - } - if(tbsCrl->nextUpdate.time.Data != NULL) { - nextUpdate = cuX509TimeToCssmTimestring(&tbsCrl->nextUpdate, &timeLen); - if(nextUpdate == NULL) { - dprintf("***Badly formatted nextUpdate\n"); - } - else { - nextUpdateData.Data = (uint8 *)nextUpdate; - nextUpdateData.Length = timeLen; - } - } - else { - /* - * NextUpdate not present; fake it by using "virtual end of time" - */ - CSSM_X509_TIME tempTime = { 0, // timeType, not used - { strlen(CSSM_APPLE_CRL_END_OF_TIME), - (uint8 *)CSSM_APPLE_CRL_END_OF_TIME} }; - nextUpdate = cuX509TimeToCssmTimestring(&tempTime, &timeLen); - nextUpdateData.Data = (uint8 *)nextUpdate; - nextUpdateData.Length = CSSM_TIME_STRLEN; - } - - /* optional CrlNumber and DeltaCrlNumber */ - if(cuSearchNumericExtension(&tbsCrl->extensions, - &CSSMOID_CrlNumber, - &crlNumber)) { - crlNumberData.Data = (uint8 *)&crlNumber; - crlNumberData.Length = sizeof(uint32); - crlNumberPresent = true; - } - if(cuSearchNumericExtension(&tbsCrl->extensions, - &CSSMOID_DeltaCrlIndicator, - &deltaCrlNumber)) { - deltaCrlNumberData.Data = (uint8 *)&deltaCrlNumber; - deltaCrlNumberData.Length = sizeof(uint32); - deltaCrlPresent = true; - } - - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "CrlType"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_UINT32; - attr->NumberOfValues = 1; - attr->Value = &crlTypeData; - attr++; - - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "CrlEncoding"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_UINT32; - attr->NumberOfValues = 1; - attr->Value = &crlEncData; - attr++; - - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "PrintName"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - attr->NumberOfValues = 1; - attr->Value = &printNameData; - attr++; - - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "Issuer"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - attr->NumberOfValues = 1; - attr->Value = issuer; - attr++; - - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "ThisUpdate"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - attr->NumberOfValues = 1; - attr->Value = &thisUpdateData; - attr++; - - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "NextUpdate"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - attr->NumberOfValues = 1; - attr->Value = &nextUpdateData; - attr++; - - /* now the optional attributes */ - if(crlNumberPresent) { - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "CrlNumber"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_UINT32; - attr->NumberOfValues = 1; - attr->Value = &crlNumberData; - attr++; - } - if(deltaCrlPresent) { - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "DeltaCrlNumber"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_UINT32; - attr->NumberOfValues = 1; - attr->Value = &deltaCrlNumberData; - attr++; - } - if(URI) { - /* ensure URI string does not contain NULL */ - attrUri = *URI; - if((attrUri.Length != 0) && - (attrUri.Data[attrUri.Length - 1] == 0)) { - attrUri.Length--; - } - attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr->Info.Label.AttributeName = (char*) "URI"; - attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - attr->NumberOfValues = 1; - attr->Value = &attrUri; - attr++; - } - recordAttrs.DataRecordType = CSSM_DL_DB_RECORD_X509_CRL; - recordAttrs.SemanticInformation = 0; - recordAttrs.NumberOfAttributes = (uint32)(attr - attrs); - recordAttrs.AttributeData = attrs; - - crtn = CSSM_DL_DataInsert(dlDbHand, - CSSM_DL_DB_RECORD_X509_CRL, - &recordAttrs, - crl, - &recordPtr); - if(crtn == CSSMERR_DL_INVALID_RECORDTYPE) { - /* gross hack of inserting this "new" schema that Keychain didn't specify */ - crtn = cuAddCrlSchema(dlDbHand); - if(crtn == CSSM_OK) { - /* Retry with a fully capable DLDB */ - crtn = CSSM_DL_DataInsert(dlDbHand, - CSSM_DL_DB_RECORD_X509_CRL, - &recordAttrs, - crl, - &recordPtr); - } - } - if(crtn == CSSM_OK) { - CSSM_DL_FreeUniqueRecord(dlDbHand, recordPtr); - } - -errOut: - /* free all the stuff we allocated to get here */ - if(issuer) { - CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1IssuerName, issuer); - } - if(crlValue) { - CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V2CRLSignedCrlCStruct, crlValue); - } - if(thisUpdate) { - free(thisUpdate); - } - if(nextUpdate) { - free(nextUpdate); - } - return crtn; -} - - -/* - * Update an existing DLDB to be CRL-capable. - */ -static CSSM_RETURN cuAddCrlSchema( - CSSM_DL_DB_HANDLE dlDbHand) -{ - return CSSM_DL_CreateRelation(dlDbHand, - CSSM_DL_DB_RECORD_X509_CRL, - "CSSM_DL_DB_RECORD_X509_CRL", - Security::KeychainCore::Schema::X509CrlSchemaAttributeCount, - Security::KeychainCore::Schema::X509CrlSchemaAttributeList, - Security::KeychainCore::Schema::X509CrlSchemaIndexCount, - Security::KeychainCore::Schema::X509CrlSchemaIndexList); -} - -/* - * Search DB for all records of type CRL or cert, calling appropriate - * parse/print routine for each record. - */ -CSSM_RETURN cuDumpCrlsCerts( - CSSM_DL_DB_HANDLE dlDbHand, - CSSM_CL_HANDLE clHand, - CSSM_BOOL isCert, - unsigned &numItems, // returned - CSSM_BOOL verbose) -{ - CSSM_QUERY query; - CSSM_DB_UNIQUE_RECORD_PTR record = NULL; - CSSM_HANDLE resultHand; - CSSM_RETURN crtn; - CSSM_DATA certCrl; - const char *itemStr; - - numItems = 0; - itemStr = isCert ? "Certificate" : "CRL"; - - /* just search by recordType, no predicates, no attributes */ - if(isCert) { - query.RecordType = CSSM_DL_DB_RECORD_X509_CERTIFICATE; - } - else { - query.RecordType = CSSM_DL_DB_RECORD_X509_CRL; - } - query.Conjunctive = CSSM_DB_NONE; - query.NumSelectionPredicates = 0; - query.SelectionPredicate = NULL; - query.QueryLimits.TimeLimit = 0; // FIXME - meaningful? - query.QueryLimits.SizeLimit = 1; // FIXME - meaningful? - query.QueryFlags = 0; // CSSM_QUERY_RETURN_DATA...FIXME - used? - - certCrl.Data = NULL; - certCrl.Length = 0; - crtn = CSSM_DL_DataGetFirst(dlDbHand, - &query, - &resultHand, - NULL, // no attrs - &certCrl, - &record); - switch(crtn) { - case CSSM_OK: - break; // proceed - case CSSMERR_DL_ENDOFDATA: - /* no data, otherwise OK */ - return CSSM_OK; - case CSSMERR_DL_INVALID_RECORDTYPE: - /* invalid record type just means "this hasn't been set up - * for certs yet". */ - return crtn; - default: - cuPrintError("DataGetFirst", crtn); - return crtn; - } - - /* got one; print it */ - dprintf("%s %u:\n", itemStr, numItems); - if(isCert) { - printCert(certCrl.Data, (unsigned)certCrl.Length, verbose); - } - else { - printCrl(certCrl.Data, (unsigned)certCrl.Length, verbose); - } - CSSM_DL_FreeUniqueRecord(dlDbHand, record); - APP_FREE(certCrl.Data); - certCrl.Data = NULL; - certCrl.Length = 0; - numItems++; - - /* get the rest */ - for(;;) { - crtn = CSSM_DL_DataGetNext(dlDbHand, - resultHand, - NULL, - &certCrl, - &record); - switch(crtn) { - case CSSM_OK: - dprintf("%s %u:\n", itemStr, numItems); - if(isCert) { - printCert(certCrl.Data, (unsigned)certCrl.Length, verbose); - } - else { - printCrl(certCrl.Data, (unsigned)certCrl.Length, verbose); - } - CSSM_DL_FreeUniqueRecord(dlDbHand, record); - APP_FREE(certCrl.Data); - certCrl.Data = NULL; - certCrl.Length = 0; - numItems++; - break; // and go again - case CSSMERR_DL_ENDOFDATA: - /* normal termination */ - return CSSM_OK; - default: - cuPrintError("DataGetNext", crtn); - return crtn; - } - } - /* NOT REACHED */ -} -