X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b04fe171f0375ecd5d8a24747ca1dff85720a0ca..6b200bc335dc93c5516ccb52f14bd896d8c7fad7:/SecurityTests/cspxutils/dbTool/dbCert.cpp?ds=inline diff --git a/SecurityTests/cspxutils/dbTool/dbCert.cpp b/SecurityTests/cspxutils/dbTool/dbCert.cpp deleted file mode 100644 index aa73443d..00000000 --- a/SecurityTests/cspxutils/dbTool/dbCert.cpp +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (c) 2003-2005,2008 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. - */ - -/* - * dbCert.cpp - import a possibly bad cert along with its private key - */ - -#include "dbCert.h" -#include -#include -#include -#include -#include -#include -#include -#include - -/* Copied from clxutils/clAppUtils/tpUtils */ -/* defined in SecKeychainAPIPriv.h */ -static const int kSecAliasItemAttr = 'alis'; - -/* Macro to declare a CSSM_DB_SCHEMA_ATTRIBUTE_INFO */ -#define SCHEMA_ATTR_INFO(id, name, type) \ - { id, (char *)name, {0, NULL}, CSSM_DB_ATTRIBUTE_FORMAT_ ## type } - -/* Too bad we can't get this from inside of the Security framework. */ -static CSSM_DB_SCHEMA_ATTRIBUTE_INFO certSchemaAttrInfo[] = -{ - SCHEMA_ATTR_INFO(kSecCertTypeItemAttr, "CertType", UINT32), - SCHEMA_ATTR_INFO(kSecCertEncodingItemAttr, "CertEncoding", UINT32), - SCHEMA_ATTR_INFO(kSecLabelItemAttr, "PrintName", BLOB), - SCHEMA_ATTR_INFO(kSecAliasItemAttr, "Alias", BLOB), - SCHEMA_ATTR_INFO(kSecSubjectItemAttr, "Subject", BLOB), - SCHEMA_ATTR_INFO(kSecIssuerItemAttr, "Issuer", BLOB), - SCHEMA_ATTR_INFO(kSecSerialNumberItemAttr, "SerialNumber", BLOB), - SCHEMA_ATTR_INFO(kSecSubjectKeyIdentifierItemAttr, "SubjectKeyIdentifier", BLOB), - SCHEMA_ATTR_INFO(kSecPublicKeyHashItemAttr, "PublicKeyHash", BLOB) -}; -#define NUM_CERT_SCHEMA_ATTRS \ - (sizeof(certSchemaAttrInfo) / sizeof(CSSM_DB_SCHEMA_ATTRIBUTE_INFO)) - -/* Macro to declare a CSSM_DB_SCHEMA_INDEX_INFO */ -#define SCHEMA_INDEX_INFO(id, indexNum, indexType) \ - { id, CSSM_DB_INDEX_ ## indexType, CSSM_DB_INDEX_ON_ATTRIBUTE } - - -static CSSM_DB_SCHEMA_INDEX_INFO certSchemaIndices[] = -{ - SCHEMA_INDEX_INFO(kSecCertTypeItemAttr, 0, UNIQUE), - SCHEMA_INDEX_INFO(kSecIssuerItemAttr, 0, UNIQUE), - SCHEMA_INDEX_INFO(kSecSerialNumberItemAttr, 0, UNIQUE), - SCHEMA_INDEX_INFO(kSecCertTypeItemAttr, 1, NONUNIQUE), - SCHEMA_INDEX_INFO(kSecSubjectItemAttr, 2, NONUNIQUE), - SCHEMA_INDEX_INFO(kSecIssuerItemAttr, 3, NONUNIQUE), - SCHEMA_INDEX_INFO(kSecSerialNumberItemAttr, 4, NONUNIQUE), - SCHEMA_INDEX_INFO(kSecSubjectKeyIdentifierItemAttr, 5, NONUNIQUE), - SCHEMA_INDEX_INFO(kSecPublicKeyHashItemAttr, 6, NONUNIQUE) -}; -#define NUM_CERT_INDICES \ - (sizeof(certSchemaIndices) / sizeof(CSSM_DB_SCHEMA_INDEX_INFO)) - - -CSSM_RETURN tpAddCertSchema( - CSSM_DL_DB_HANDLE dlDbHand) -{ - return CSSM_DL_CreateRelation(dlDbHand, - CSSM_DL_DB_RECORD_X509_CERTIFICATE, - "CSSM_DL_DB_RECORD_X509_CERTIFICATE", - NUM_CERT_SCHEMA_ATTRS, - certSchemaAttrInfo, - NUM_CERT_INDICES, - certSchemaIndices); -} - - -/* copied verbatim from certTool */ - -/* - * Find private key by label, modify its Label attr to be the - * hash of the associated public key. - */ -static CSSM_RETURN setPubKeyHash( - CSSM_CSP_HANDLE cspHand, - CSSM_DL_DB_HANDLE dlDbHand, - const char *keyLabel, // look up by this - CSSM_DATA *rtnKeyDigest) // optionally RETURNED, if so, - // caller owns and must cuAppFree -{ - CSSM_QUERY query; - CSSM_SELECTION_PREDICATE predicate; - CSSM_DB_UNIQUE_RECORD_PTR record = NULL; - CSSM_RETURN crtn; - CSSM_DATA labelData; - CSSM_HANDLE resultHand; - - labelData.Data = (uint8 *)keyLabel; - labelData.Length = strlen(keyLabel) + 1; // incl. NULL - query.RecordType = CSSM_DL_DB_RECORD_PRIVATE_KEY; - query.Conjunctive = CSSM_DB_NONE; - query.NumSelectionPredicates = 1; - predicate.DbOperator = CSSM_DB_EQUAL; - - predicate.Attribute.Info.AttributeNameFormat = - CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - predicate.Attribute.Info.Label.AttributeName = (char *)"Label"; - predicate.Attribute.Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - /* hope this cast is OK */ - predicate.Attribute.Value = &labelData; - query.SelectionPredicate = &predicate; - - query.QueryLimits.TimeLimit = 0; // FIXME - meaningful? - query.QueryLimits.SizeLimit = 1; // FIXME - meaningful? - query.QueryFlags = 0; // CSSM_QUERY_RETURN_DATA; // FIXME - used? - - /* build Record attribute with one attr */ - CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs; - CSSM_DB_ATTRIBUTE_DATA attr; - attr.Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; - attr.Info.Label.AttributeName = (char *)"Label"; - attr.Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - - recordAttrs.DataRecordType = CSSM_DL_DB_RECORD_PRIVATE_KEY; - recordAttrs.NumberOfAttributes = 1; - recordAttrs.AttributeData = &attr; - - CSSM_DATA recordData = {0, NULL}; - crtn = CSSM_DL_DataGetFirst(dlDbHand, - &query, - &resultHand, - &recordAttrs, - &recordData, - &record); - /* abort only on success */ - if(crtn != CSSM_OK) { - cuPrintError("CSSM_DL_DataGetFirst", crtn); - return crtn; - } - - CSSM_KEY_PTR keyToDigest = (CSSM_KEY_PTR)recordData.Data; - CSSM_DATA_PTR keyDigest = NULL; - CSSM_CC_HANDLE ccHand; - crtn = CSSM_CSP_CreatePassThroughContext(cspHand, - keyToDigest, - &ccHand); - if(crtn) { - cuPrintError("CSSM_CSP_CreatePassThroughContext", crtn); - return crtn; - } - crtn = CSSM_CSP_PassThrough(ccHand, - CSSM_APPLECSP_KEYDIGEST, - NULL, - (void **)&keyDigest); - if(crtn) { - cuPrintError("CSSM_CSP_PassThrough(PUBKEYHASH)", crtn); - return -1; - } - CSSM_FreeKey(cspHand, NULL, keyToDigest, CSSM_FALSE); - CSSM_DeleteContext(ccHand); - - /* - * Replace Label attr data with hash. - * NOTE: the module which allocated this attribute data - a DL - - * was loaded and attached by the Sec layer, not by us. Thus - * we can't use the memory allocator functions *we* used when - * attaching to the CSPDL - we have to use the ones - * which the Sec layer registered with the DL. - */ - CSSM_API_MEMORY_FUNCS memFuncs; - crtn = CSSM_GetAPIMemoryFunctions(dlDbHand.DLHandle, &memFuncs); - if(crtn) { - cuPrintError("CSSM_GetAPIMemoryFunctions(DLHandle)", crtn); - /* oh well, leak and continue */ - } - else { - memFuncs.free_func(attr.Value->Data, memFuncs.AllocRef); - memFuncs.free_func(attr.Value, memFuncs.AllocRef); - } - attr.Value = keyDigest; - - /* modify key attributes */ - crtn = CSSM_DL_DataModify(dlDbHand, - CSSM_DL_DB_RECORD_PRIVATE_KEY, - record, - &recordAttrs, - NULL, // DataToBeModified - CSSM_DB_MODIFY_ATTRIBUTE_REPLACE); - if(crtn) { - cuPrintError("CSSM_DL_DataModify(PUBKEYHASH)", crtn); - return crtn; - } - crtn = CSSM_DL_DataAbortQuery(dlDbHand, resultHand); - if(crtn) { - cuPrintError("CSSM_DL_DataAbortQuery", crtn); - /* let's keep going in this case */ - } - crtn = CSSM_DL_FreeUniqueRecord(dlDbHand, record); - if(crtn) { - cuPrintError("CSSM_DL_FreeUniqueRecord", crtn); - /* let's keep going in this case */ - crtn = CSSM_OK; - } - - /* free resources */ - if(rtnKeyDigest) { - *rtnKeyDigest = *keyDigest; - } - else { - cuAppFree(keyDigest->Data, NULL); - /* FIXME - don't we have to free keyDigest itself? */ - } - return CSSM_OK; -} - -static CSSM_RETURN importPrivateKey( - CSSM_DL_DB_HANDLE dlDbHand, - CSSM_CSP_HANDLE cspHand, - const char *privKeyFileName, - CSSM_ALGORITHMS keyAlg, - CSSM_BOOL pemFormat, // of the file - CSSM_KEYBLOB_FORMAT keyFormat, // of the key blob itself, NONE means - // use default - CSSM_DATA *keyHash) // OPTIONALLY RETURNED - if so, caller - // owns and must cuAppFree() -{ - unsigned char *derKey = NULL; - unsigned derKeyLen; - unsigned char *pemKey = NULL; - unsigned pemKeyLen; - CSSM_KEY wrappedKey; - CSSM_KEY unwrappedKey; - CSSM_ACCESS_CREDENTIALS creds; - CSSM_CC_HANDLE ccHand = 0; - CSSM_RETURN crtn; - CSSM_DATA labelData; - CSSM_KEYHEADER_PTR hdr = &wrappedKey.KeyHeader; - CSSM_DATA descData = {0, NULL}; - CSSM_CSP_HANDLE rawCspHand = 0; - const char *privKeyLabel = NULL; - - /* - * Validate specified format for clarity - */ - switch(keyAlg) { - case CSSM_ALGID_RSA: - switch(keyFormat) { - case CSSM_KEYBLOB_RAW_FORMAT_NONE: - keyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; // default - break; - case CSSM_KEYBLOB_RAW_FORMAT_PKCS1: - case CSSM_KEYBLOB_RAW_FORMAT_PKCS8: - break; - default: - printf("***RSA Private key must be in PKCS1 or PKCS8 " - "format\n"); - return CSSMERR_CSSM_INTERNAL_ERROR; - } - privKeyLabel = "Imported RSA key"; - break; - case CSSM_ALGID_DSA: - switch(keyFormat) { - case CSSM_KEYBLOB_RAW_FORMAT_NONE: - keyFormat = CSSM_KEYBLOB_RAW_FORMAT_OPENSSL; - // default - break; - case CSSM_KEYBLOB_RAW_FORMAT_FIPS186: - case CSSM_KEYBLOB_RAW_FORMAT_OPENSSL: - case CSSM_KEYBLOB_RAW_FORMAT_PKCS8: - break; - default: - printf("***DSA Private key must be in openssl, FIPS186, " - "or PKCS8 format\n"); - return CSSMERR_CSSM_INTERNAL_ERROR; - } - privKeyLabel = "Imported DSA key"; - break; - case CSSM_ALGID_DH: - switch(keyFormat) { - case CSSM_KEYBLOB_RAW_FORMAT_NONE: - keyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS8; // default - break; - case CSSM_KEYBLOB_RAW_FORMAT_PKCS8: - break; - default: - printf("***Diffie-Hellman Private key must be in" - "PKCS8 format.\n"); - return CSSMERR_CSSM_INTERNAL_ERROR; - } - privKeyLabel = "Imported Diffie-Hellman key"; - break; - } - if(readFile(privKeyFileName, &pemKey, &pemKeyLen)) { - printf("***Error reading private key from file %s. Aborting.\n", - privKeyFileName); - return CSSMERR_CSSM_INTERNAL_ERROR; - } - /* subsequent errors to done: */ - if(pemFormat) { - int rtn = pemDecode(pemKey, pemKeyLen, &derKey, &derKeyLen); - if(rtn) { - printf("***%s: Bad PEM formatting. Aborting.\n", - privKeyFileName); - crtn = CSSMERR_CSP_INVALID_KEY; - goto done; - } - } - else { - derKey = pemKey; - derKeyLen = pemKeyLen; - } - - /* importing a raw key into the CSPDL involves a NULL unwrap */ - memset(&unwrappedKey, 0, sizeof(CSSM_KEY)); - memset(&wrappedKey, 0, sizeof(CSSM_KEY)); - - /* set up the imported key to look like a CSSM_KEY */ - hdr->HeaderVersion = CSSM_KEYHEADER_VERSION; - hdr->BlobType = CSSM_KEYBLOB_RAW; - hdr->AlgorithmId = keyAlg; - hdr->KeyClass = CSSM_KEYCLASS_PRIVATE_KEY; - hdr->KeyAttr = CSSM_KEYATTR_EXTRACTABLE; - hdr->KeyUsage = CSSM_KEYUSE_ANY; - hdr->Format = keyFormat; - wrappedKey.KeyData.Data = derKey; - wrappedKey.KeyData.Length = derKeyLen; - - /* get key size in bits from raw CSP */ - rawCspHand = cuCspStartup(CSSM_TRUE); - if(rawCspHand == 0) { - printf("***Error attaching to CSP. Aborting.\n"); - crtn = CSSMERR_CSSM_INTERNAL_ERROR; - goto done; - } - CSSM_KEY_SIZE keySize; - crtn = CSSM_QueryKeySizeInBits(rawCspHand, CSSM_INVALID_HANDLE, &wrappedKey, &keySize); - if(crtn) { - cuPrintError("CSSM_QueryKeySizeInBits",crtn); - goto done; - } - hdr->LogicalKeySizeInBits = keySize.LogicalKeySizeInBits; - - memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS)); - crtn = CSSM_CSP_CreateSymmetricContext(cspHand, - CSSM_ALGID_NONE, // unwrapAlg - CSSM_ALGMODE_NONE, // unwrapMode - &creds, - NULL, // unwrappingKey - NULL, // initVector - CSSM_PADDING_NONE, // unwrapPad - 0, // Params - &ccHand); - if(crtn) { - cuPrintError("CSSM_CSP_CreateSymmetricContext", crtn); - goto done; - } - - /* add DL/DB to context */ - CSSM_CONTEXT_ATTRIBUTE newAttr; - newAttr.AttributeType = CSSM_ATTRIBUTE_DL_DB_HANDLE; - newAttr.AttributeLength = sizeof(CSSM_DL_DB_HANDLE); - newAttr.Attribute.Data = (CSSM_DATA_PTR)&dlDbHand; - crtn = CSSM_UpdateContextAttributes(ccHand, 1, &newAttr); - if(crtn) { - cuPrintError("CSSM_UpdateContextAttributes", crtn); - goto done; - } - - /* do the NULL unwrap */ - labelData.Data = (uint8 *)privKeyLabel; - labelData.Length = strlen(privKeyLabel) + 1; - crtn = CSSM_UnwrapKey(ccHand, - NULL, // PublicKey - &wrappedKey, - CSSM_KEYUSE_ANY, - CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT | - CSSM_KEYATTR_SENSITIVE |CSSM_KEYATTR_EXTRACTABLE, - &labelData, - NULL, // CredAndAclEntry - &unwrappedKey, - &descData); // required - if(crtn != CSSM_OK) { - cuPrintError("CSSM_UnwrapKey", crtn); - goto done; - } - - /* one more thing: bind this private key to its public key */ - crtn = setPubKeyHash(cspHand, dlDbHand, privKeyLabel, keyHash); - - /* We don't need the unwrapped key any more */ - CSSM_FreeKey(cspHand, - NULL, // access cred - &unwrappedKey, - CSSM_FALSE); // delete - -done: - if(ccHand) { - CSSM_DeleteContext(ccHand); - } - if(derKey) { - free(derKey); // mallocd by readFile() */ - } - if(pemFormat && pemKey) { - free(pemKey); - } - if(rawCspHand) { - CSSM_ModuleDetach(rawCspHand); - } - return crtn; -} - - -CSSM_RETURN importBadCert( - CSSM_DL_HANDLE dlHand, - const char *dbFileName, - const char *certFile, - const char *keyFile, - CSSM_ALGORITHMS keyAlg, - CSSM_BOOL pemFormat, // of the file - CSSM_KEYBLOB_FORMAT keyFormat, // of the key blob itself, NONE means - // use default - CSSM_BOOL verbose) -{ - CSSM_DL_DB_HANDLE dlDbHand = {dlHand, 0}; - CSSM_RETURN crtn; - CSSM_DATA keyDigest = {0, NULL}; - CSSM_DATA certData = {0, NULL}; - unsigned len; - - CSSM_CSP_HANDLE cspHand = cuCspStartup(CSSM_FALSE); - if(cspHand == 0) { - printf("***Error attaching to CSPDL. Aborting.\n"); - return CSSMERR_CSSM_ADDIN_LOAD_FAILED; - } - - /* - * 1. Open the (already existing) DB. - */ - dlDbHand.DBHandle = cuDbStartupByName(dlHand, - (char *)dbFileName, // bogus non-const prototype - CSSM_FALSE, // do NOT create it - CSSM_FALSE); // quiet - if(dlDbHand.DBHandle == 0) { - printf("Error opening %s. Aborting.\n", dbFileName); - return CSSMERR_DL_DATASTORE_DOESNOT_EXIST; - } - - /* - * Import key to DB, snagging its key digest along the way. - */ - crtn = importPrivateKey(dlDbHand, cspHand, - keyFile, keyAlg, pemFormat, keyFormat, - &keyDigest); - if(crtn) { - printf("***Error importing key %s. Aborting.\n", keyFile); - goto errOut; - } - - /* - * Now the cert. - */ - if(readFile(certFile, &certData.Data, &len)) { - printf("***Error reading cert from %s. Aborting.\n", certFile); - goto errOut; - } - certData.Length = len; - crtn = cuAddCertToDb(dlDbHand, &certData, - CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, - certFile, // printName - &keyDigest); - if(crtn == CSSMERR_DL_INVALID_RECORDTYPE) { - /* virgin DB, no cert schema: add schema and retry */ - crtn = tpAddCertSchema(dlDbHand); - if(crtn == CSSM_OK) { - crtn = cuAddCertToDb(dlDbHand, &certData, - CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, - certFile, // printName - &keyDigest); - } - } - if(crtn) { - printf("***Error importing cert %s. Aborting.\n", certFile); - } -errOut: - if(keyDigest.Data) { - cuAppFree(keyDigest.Data, NULL); - } - if(dlDbHand.DBHandle) { - CSSM_DL_DbClose(dlDbHand); - } - if(certData.Data) { - free(certData.Data); - } - return crtn; -}