X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_csp/lib/RSA_DSA_keys.cpp?ds=inline diff --git a/libsecurity_apple_csp/lib/RSA_DSA_keys.cpp b/libsecurity_apple_csp/lib/RSA_DSA_keys.cpp deleted file mode 100644 index b73fc470..00000000 --- a/libsecurity_apple_csp/lib/RSA_DSA_keys.cpp +++ /dev/null @@ -1,829 +0,0 @@ -/* - * Copyright (c) 2000-2001 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. - */ - - -/* - * RSA_DSA_Keys.cpp - RSA, DSA related asymmetric key pair classes. - */ - -#include "RSA_DSA_keys.h" -#include -#include -#include -#include -#include -#include -#include -#include "RSA_DSA_utils.h" -#include -#include - -#define RSA_PUB_EXPONENT 0x10001 /* recommended by RSA */ - -#define rsaKeyDebug(args...) secdebug("rsaKey", ## args) - - -/*** - *** RSA-style BinaryKey - ***/ - -/* constructor with optional existing RSA key */ -/* FIXME how to transmit OAEP params? */ -RSABinaryKey::RSABinaryKey(RSA *rsaKey) - : mRsaKey(rsaKey), - mOaep(false), - mLabel(Allocator::standard()) -{ -} - -RSABinaryKey::~RSABinaryKey() -{ - if(mRsaKey) { - RSA_free(mRsaKey); - mRsaKey = NULL; - } -} - -void RSABinaryKey::setOaep( - const CSSM_DATA &label) -{ - mLabel.copy(label); - mOaep = true; -} - -void RSABinaryKey::generateKeyBlob( - Allocator &allocator, - CssmData &blob, - CSSM_KEYBLOB_FORMAT &format, /* IN/OUT */ - AppleCSPSession &session, - const CssmKey *paramKey, /* optional, unused here */ - CSSM_KEYATTR_FLAGS &attrFlags) /* IN/OUT */ -{ - bool isPub; - CSSM_RETURN crtn; - - /* FIXME get label from context here for OAEP */ - - /* - * Here, the incoming default of CSSM_KEYBLOB_RAW_FORMAT_NONE - * is translated to our AppleCSP-custom defaults. App can override. - */ - switch(mKeyHeader.KeyClass) { - case CSSM_KEYCLASS_PUBLIC_KEY: - isPub = true; - switch(format) { - case CSSM_KEYBLOB_RAW_FORMAT_NONE: - format = RSA_PUB_KEY_FORMAT; // default - break; - case CSSM_KEYBLOB_RAW_FORMAT_DIGEST: - if(mOaep) { - /* have to take digest of the whole thing including label */ - format = CSSM_KEYBLOB_RAW_FORMAT_X509; - } - else { - /* calculate digest on PKCS1 blob */ - format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; - } - break; - case CSSM_KEYBLOB_RAW_FORMAT_PKCS1: - case CSSM_KEYBLOB_RAW_FORMAT_X509: - case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH: - case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2: - break; - default: - CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_FORMAT); - } - break; - case CSSM_KEYCLASS_PRIVATE_KEY: - isPub = false; - switch(format) { - case CSSM_KEYBLOB_RAW_FORMAT_NONE: // default - format = RSA_PRIV_KEY_FORMAT; - break; - case CSSM_KEYBLOB_RAW_FORMAT_DIGEST: - if(mOaep) { - /* have to take digest of the whole thing including label */ - format = CSSM_KEYBLOB_RAW_FORMAT_X509; - } - else { - /* calculate digest on PKCS1 blob */ - format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; - } - isPub = true; - break; - case CSSM_KEYBLOB_RAW_FORMAT_PKCS1: - case CSSM_KEYBLOB_RAW_FORMAT_PKCS8: - case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH: - break; - default: - CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_FORMAT); - } - break; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); - } - - CssmAutoData encodedKey(allocator); - if(mOaep) { - CSSM_DATA label = mLabel; - if(isPub) { - crtn = RSAOAEPPublicKeyEncode(mRsaKey, &label, encodedKey); - } - else { - crtn = RSAOAEPPrivateKeyEncode(mRsaKey, &label, encodedKey); - } - } - else { - if(isPub) { - crtn = RSAPublicKeyEncode(mRsaKey, format, descData(), encodedKey); - } - else { - crtn = RSAPrivateKeyEncode(mRsaKey, format, descData(), encodedKey); - } - } - if(crtn) { - CssmError::throwMe(crtn); - } - blob = encodedKey.release(); -} - -/*** - *** RSA-style AppleKeyPairGenContext - ***/ - -/* - * This one is specified in, and called from, CSPFullPluginSession. Our - * only job is to prepare two subclass-specific BinaryKeys and call up to - * AppleKeyPairGenContext. - */ -void RSAKeyPairGenContext::generate( - const Context &context, - CssmKey &pubKey, - CssmKey &privKey) -{ - RSABinaryKey *pubBinKey = new RSABinaryKey(); - RSABinaryKey *privBinKey = new RSABinaryKey(); - - try { - AppleKeyPairGenContext::generate(context, - session(), - pubKey, - pubBinKey, - privKey, - privBinKey); - } - catch (...) { - delete pubBinKey; - delete privBinKey; - throw; - } - -} - -// this one is specified in, and called from, AppleKeyPairGenContext -void RSAKeyPairGenContext::generate( - const Context &context, - BinaryKey &pubBinKey, - BinaryKey &privBinKey, - uint32 &keyBits) -{ - /* - * These casts throw exceptions if the keys are of the - * wrong classes, which would be a major bogon, since we created - * the keys in the above generate() function. - */ - RSABinaryKey &rPubBinKey = - dynamic_cast(pubBinKey); - RSABinaryKey &rPrivBinKey = - dynamic_cast(privBinKey); - - /* - * One parameter from context: Key size in bits is required. - * FIXME - get public exponent from context? - */ - keyBits = context.getInt(CSSM_ATTRIBUTE_KEY_LENGTH, - CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH); - if(keyBits > rsaMaxKeySize()) { - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH); - } - - /* generate the private key */ - rPrivBinKey.mRsaKey = RSA_generate_key(keyBits, - RSA_PUB_EXPONENT, - NULL, // no callback - NULL); - if(rPrivBinKey.mRsaKey == NULL) { - rsaKeyDebug("RSA_generate_key returned NULL"); - CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR); // ??? - } - - /* public key is subset of private key */ - rPubBinKey.mRsaKey = RSA_new(); - if(rPrivBinKey.mRsaKey == NULL) { - CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR); - } - RSA *pub = rPubBinKey.mRsaKey; - RSA *priv = rPrivBinKey.mRsaKey; - pub->n = BN_dup(priv->n); - pub->e = BN_dup(priv->e); - if((pub->n == NULL) || (pub->e == NULL)) { - CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR); - } -} - - -/*** - *** RSA-style CSPKeyInfoProvider. - ***/ -RSAKeyInfoProvider::RSAKeyInfoProvider( - const CssmKey &cssmKey, - AppleCSPSession &session) : - CSPKeyInfoProvider(cssmKey, session) -{ -} - -CSPKeyInfoProvider *RSAKeyInfoProvider::provider( - const CssmKey &cssmKey, - AppleCSPSession &session) -{ - switch(cssmKey.algorithm()) { - case CSSM_ALGID_RSA: - case CSSM_ALGMODE_PKCS1_EME_OAEP: - break; - default: - return NULL; - } - switch(cssmKey.keyClass()) { - case CSSM_KEYCLASS_PUBLIC_KEY: - case CSSM_KEYCLASS_PRIVATE_KEY: - break; - default: - return NULL; - } - /* OK, we'll handle this one */ - return new RSAKeyInfoProvider(cssmKey, session); -} - -/* Given a raw key, cook up a Binary key */ -void RSAKeyInfoProvider::CssmKeyToBinary( - CssmKey *paramKey, // ignored - CSSM_KEYATTR_FLAGS &attrFlags, // IN/OUT, unused here - BinaryKey **binKey) -{ - *binKey = NULL; - RSA *rsaKey = NULL; - CSSM_DATA label = {0, NULL}; - - /* first cook up an RSA key */ - rsaKey = rawCssmKeyToRsa(mKey, label); - - /* now drop that into a BinaryKey */ - RSABinaryKey *rsaBinKey = new RSABinaryKey(rsaKey); - *binKey = rsaBinKey; - if(label.Data) { - rsaBinKey->setOaep(label); - free(label.Data); - } -} - -/* - * Obtain key size in bits. - */ -void RSAKeyInfoProvider::QueryKeySizeInBits( - CSSM_KEY_SIZE &keySize) -{ - RSA *rsaKey = NULL; - CSSM_DATA label = {0, NULL}; - - if(mKey.blobType() != CSSM_KEYBLOB_RAW) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT); - } - rsaKey = rawCssmKeyToRsa(mKey, label); - keySize.LogicalKeySizeInBits = RSA_size(rsaKey) * 8; - keySize.EffectiveKeySizeInBits = keySize.LogicalKeySizeInBits; - RSA_free(rsaKey); - if(label.Data) { - free(label.Data); - } -} - -/* - * Obtain blob suitable for hashing in CSSM_APPLECSP_KEYDIGEST - * passthrough. - */ -bool RSAKeyInfoProvider::getHashableBlob( - Allocator &allocator, - CssmData &blob) // blob to hash goes here -{ - /* - * The optimized case, a raw key in the "proper" format already. - * Only public keys in PKCS1 format fit this bill. - */ - assert(mKey.blobType() == CSSM_KEYBLOB_RAW); - bool useAsIs = false; - - switch(mKey.keyClass()) { - case CSSM_KEYCLASS_PUBLIC_KEY: - if(mKey.blobFormat() == CSSM_KEYBLOB_RAW_FORMAT_PKCS1) { - useAsIs = true; - } - break; - case CSSM_KEYCLASS_PRIVATE_KEY: - break; - default: - /* shouldn't be here */ - assert(0); - CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); - } - if(useAsIs) { - const CssmData &keyBlob = CssmData::overlay(mKey.KeyData); - copyCssmData(keyBlob, blob, allocator); - return true; - } - - /* caller converts to binary and proceeds */ - return false; -} - -/*** - *** DSA key support - ***/ - - -/*** - *** DSA-style BinaryKey - ***/ - -/* constructor with optional existing DSA key */ -DSABinaryKey::DSABinaryKey(DSA *dsaKey) - : mDsaKey(dsaKey) -{ -} - -DSABinaryKey::~DSABinaryKey() -{ - if(mDsaKey) { - DSA_free(mDsaKey); - mDsaKey = NULL; - } -} - -void DSABinaryKey::generateKeyBlob( - Allocator &allocator, - CssmData &blob, - CSSM_KEYBLOB_FORMAT &format, - AppleCSPSession &session, - const CssmKey *paramKey, /* optional */ - CSSM_KEYATTR_FLAGS &attrFlags) /* IN/OUT */ -{ - bool isPub; - CSSM_RETURN crtn; - - /* - * Here, the incoming default of CSSM_KEYBLOB_RAW_FORMAT_NONE - * is translated to our AppleCSP-custom defaults. App can override. - */ - switch(mKeyHeader.KeyClass) { - case CSSM_KEYCLASS_PUBLIC_KEY: - isPub = true; - switch(format) { - case CSSM_KEYBLOB_RAW_FORMAT_NONE: - format = DSA_PUB_KEY_FORMAT; // default - break; - case CSSM_KEYBLOB_RAW_FORMAT_FIPS186: - case CSSM_KEYBLOB_RAW_FORMAT_X509: - case CSSM_KEYBLOB_RAW_FORMAT_DIGEST: - case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2: - break; - default: - CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_FORMAT); - } - break; - case CSSM_KEYCLASS_PRIVATE_KEY: - isPub = false; - switch(format) { - case CSSM_KEYBLOB_RAW_FORMAT_NONE: - format = DSA_PRIV_KEY_FORMAT; // default - break; - case CSSM_KEYBLOB_RAW_FORMAT_DIGEST: - /* - * This is calculated on the public key, which - * is not always part of a DSA private key's encoding... - * so first calculate the public key. - */ - dsaKeyPrivToPub(mDsaKey); - isPub = true; - break; - case CSSM_KEYBLOB_RAW_FORMAT_FIPS186: - case CSSM_KEYBLOB_RAW_FORMAT_PKCS8: - case CSSM_KEYBLOB_RAW_FORMAT_OPENSSL: - break; - default: - CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_FORMAT); - } - break; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); - } - - /* possible conversion from partial binary key to fully - * formed blob */ - DSA *dsaToEncode = mDsaKey; - DSA *dsaUpgrade = NULL; - if(isPub && - (mDsaKey->p == NULL) && - (paramKey != NULL)) { - /* - * Don't modify BinaryKey; make a copy. - */ - dsaUpgrade = DSA_new(); - if(dsaUpgrade == NULL) { - CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR); - } - dsaUpgrade->pub_key = BN_dup(mDsaKey->pub_key); - crtn = dsaGetParamsFromKey(dsaUpgrade, *paramKey, session); - if(crtn) { - DSA_free(dsaUpgrade); - CssmError::throwMe(crtn); - } - - /* success - switch keys and inform caller of attr change */ - dsaToEncode = dsaUpgrade; - attrFlags &= ~CSSM_KEYATTR_PARTIAL; - } - - /* - * DSA private keys originating from BSAFE form - e.g., DSA private - * keys wrapped in a keychain (which have format FIPS186 by default) - * have no public key component. Generate the public key if we don't - * have one. - */ - if(!isPub && (dsaToEncode->pub_key == NULL)) { - dsaKeyPrivToPub(dsaToEncode); - } - - CssmAutoData encodedKey(allocator); - if(isPub) { - crtn = DSAPublicKeyEncode(dsaToEncode, format, descData(), encodedKey); - } - else { - crtn = DSAPrivateKeyEncode(dsaToEncode, format, descData(), encodedKey); - } - if(dsaUpgrade != NULL) { - /* temp key, get rid of it */ - DSA_free(dsaUpgrade); - } - if(crtn) { - CssmError::throwMe(crtn); - } - blob = encodedKey.release(); -} - -/*** - *** DSA-style AppleKeyPairGenContext - ***/ - -/* - * This one is specified in, and called from, CSPFullPluginSession. Our - * only job is to prepare two subclass-specific BinaryKeys and call up to - * AppleKeyPairGenContext. - */ -void DSAKeyPairGenContext::generate( - const Context &context, - CssmKey &pubKey, - CssmKey &privKey) -{ - DSABinaryKey *pubBinKey = new DSABinaryKey(); - DSABinaryKey *privBinKey = new DSABinaryKey(); - - try { - AppleKeyPairGenContext::generate(context, - session(), - pubKey, - pubBinKey, - privKey, - privBinKey); - } - catch (...) { - delete pubBinKey; - delete privBinKey; - throw; - } - -} - -/* - * This one is specified in, and called from, AppleKeyPairGenContext - */ -void DSAKeyPairGenContext::generate( - const Context &context, - BinaryKey &pubBinKey, - BinaryKey &privBinKey, - uint32 &keyBits) -{ - /* - * These casts throw exceptions if the keys are of the - * wrong classes, which would be a major bogon, since we created - * the keys in the above generate() function. - */ - DSABinaryKey &rPubBinKey = - dynamic_cast(pubBinKey); - DSABinaryKey &rPrivBinKey = - dynamic_cast(privBinKey); - - /* - * Parameters from context: - * Key size in bits, required; - * {p,q,g} from generateParams, optional - */ - keyBits = context.getInt(CSSM_ATTRIBUTE_KEY_LENGTH, - CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH); - if(keyBits > DSA_MAX_KEY_SIZE) { - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH); - } - CssmData *paramData = context.get(CSSM_ATTRIBUTE_ALG_PARAMS); - - NSS_DSAAlgParams algParams; - SecNssCoder coder; // generated algParams mallocd from here - if(paramData != NULL) { - /* this contains the DER encoding of a NSS_DSAAlgParams */ - CSSM_RETURN crtn = DSADecodeAlgParams(algParams, paramData->Data, - (unsigned)paramData->Length, coder); - if(crtn) { - CssmError::throwMe(crtn); - } - } - else { - /* no alg params specified; generate them now using null (random) seed */ - dsaGenParams(keyBits, NULL, 0, algParams, coder); - } - - /* create key, stuff params into it */ - rPrivBinKey.mDsaKey = DSA_new(); - if(rPrivBinKey.mDsaKey == NULL) { - CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR); - } - DSA *dsaKey = rPrivBinKey.mDsaKey; - dsaKey->p = cssmDataToBn(algParams.p); - dsaKey->q = cssmDataToBn(algParams.q); - dsaKey->g = cssmDataToBn(algParams.g); - - /* generate the key (both public and private capabilities) */ - int irtn = DSA_generate_key(dsaKey); - if(!irtn) { - throwRsaDsa("DSA_generate_key"); - } - - /* public key is subset of private key */ - rPubBinKey.mDsaKey = DSA_new(); - if(rPrivBinKey.mDsaKey == NULL) { - CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR); - } - DSA *pub = rPubBinKey.mDsaKey; - DSA *priv = rPrivBinKey.mDsaKey; - pub->p = BN_dup(priv->p); - pub->q = BN_dup(priv->q); - pub->g = BN_dup(priv->g); - pub->pub_key = BN_dup(priv->pub_key); - if((pub->p == NULL) || (pub->q == NULL) || (pub->g == NULL) || - (pub->pub_key == NULL)) { - CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR); - } -} - -/* - * Generate keygen parameters, stash them in a context attr array for later use - * when actually generating the keys. - */ -void DSAKeyPairGenContext::generate( - const Context &context, - uint32 bitSize, - CssmData ¶ms, - uint32 &attrCount, - Context::Attr * &attrs) -{ - void *seed = NULL; - unsigned seedLen = 0; - - /* optional seed from context */ - CssmData *seedData = context.get(CSSM_ATTRIBUTE_SEED); - if(seedData) { - seed = seedData->data(); - seedLen = (unsigned)seedData->length(); - } - - /* generate the params, temp alloc from SecNssCoder */ - NSS_DSAAlgParams algParams; - SecNssCoder coder; - dsaGenParams(bitSize, seed, seedLen, algParams, coder); - - /* - * Here comes the fun part. - * We "return" the DER encoding of these generated params in two ways: - * 1. Copy out to app via the params argument, mallocing if Data ptr is NULL. - * The app must free this. - * 2. Cook up a 1-element Context::attr array containing one ALG_PARAM attr, - * a CSSM_DATA_PTR containing the DER encoding. We have to save a ptr to - * this attr array and free it, the CSSM_DATA it points to, and the DER - * encoding *that* points to, in our destructor. - * - * First, DER encode. - */ - CssmAutoData aDerData(session()); - DSAEncodeAlgParams(algParams, aDerData); - - /* copy/release that into a mallocd CSSM_DATA. */ - CSSM_DATA_PTR derData = (CSSM_DATA_PTR)session().malloc(sizeof(CSSM_DATA)); - *derData = aDerData.release(); - - /* stuff that into a one-element Attr array which we keep after returning */ - freeGenAttrs(); - mGenAttrs = (Context::Attr *)session().malloc(sizeof(Context::Attr)); - mGenAttrs->AttributeType = CSSM_ATTRIBUTE_ALG_PARAMS; - mGenAttrs->AttributeLength = sizeof(CSSM_DATA); - mGenAttrs->Attribute.Data = derData; - - /* and "return" this stuff */ - copyCssmData(CssmData::overlay(*derData), params, session()); - attrCount = 1; - attrs = mGenAttrs; -} - -/* free mGenAttrs and its referents if present */ -void DSAKeyPairGenContext::freeGenAttrs() -{ - if(mGenAttrs == NULL) { - return; - } - if(mGenAttrs->Attribute.Data) { - if(mGenAttrs->Attribute.Data->Data) { - session().free(mGenAttrs->Attribute.Data->Data); - } - session().free(mGenAttrs->Attribute.Data); - } - session().free(mGenAttrs); -} - -/* - * Generate DSA algorithm parameters from optional seed input, returning result - * into NSS_DSAAlgParamss.[pqg]. This is called from both GenerateParameters and from - * KeyPairGenerate (if no GenerateParameters has yet been called). - */ -void DSAKeyPairGenContext::dsaGenParams( - uint32 keySizeInBits, - const void *inSeed, // optional - unsigned inSeedLen, - NSS_DSAAlgParams &algParams, - SecNssCoder &coder) // contents of algParams mallocd from here -{ - unsigned char seedBuf[SHA1_DIGEST_SIZE]; - void *seedPtr; - - /* validate key size */ - if((keySizeInBits < DSA_MIN_KEY_SIZE) || - (keySizeInBits > DSA_MAX_KEY_SIZE) || - (keySizeInBits & DSA_KEY_BITS_MASK)) { - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH); - } - - /* seed from one of three sources */ - if(inSeed == NULL) { - /* 20 random seed bytes */ - session().getRandomBytes(SHA1_DIGEST_SIZE, seedBuf); - seedPtr = seedBuf; - } - else if(inSeedLen == SHA1_DIGEST_SIZE) { - /* perfect */ - seedPtr = (void *)inSeed; - } - else { - /* hash caller's seed */ - cspGenSha1Hash(inSeed, inSeedLen, seedBuf); - seedPtr = seedBuf; - } - - DSA *dsaKey = DSA_generate_parameters(keySizeInBits, - (unsigned char *)seedPtr, - SHA1_DIGEST_SIZE, - NULL, // counter_ret - NULL, // h_ret - NULL, - NULL); - if(dsaKey == NULL) { - throwRsaDsa("DSA_generate_parameters"); - } - - /* stuff dsaKey->[pqg] into a caller's NSS_DSAAlgParams */ - bnToCssmData(dsaKey->p, algParams.p, coder); - bnToCssmData(dsaKey->q, algParams.q, coder); - bnToCssmData(dsaKey->g, algParams.g, coder); - - DSA_free(dsaKey); -} - -/*** - *** DSA-style CSPKeyInfoProvider. - ***/ -DSAKeyInfoProvider::DSAKeyInfoProvider( - const CssmKey &cssmKey, - AppleCSPSession &session) : - CSPKeyInfoProvider(cssmKey, session) -{ - -} -CSPKeyInfoProvider *DSAKeyInfoProvider::provider( - const CssmKey &cssmKey, - AppleCSPSession &session) -{ - switch(cssmKey.algorithm()) { - case CSSM_ALGID_DSA: - break; - default: - return NULL; - } - switch(cssmKey.keyClass()) { - case CSSM_KEYCLASS_PUBLIC_KEY: - case CSSM_KEYCLASS_PRIVATE_KEY: - break; - default: - return NULL; - } - /* OK, we'll handle this one */ - return new DSAKeyInfoProvider(cssmKey, session); -} - -/* Given a raw key, cook up a Binary key */ -void DSAKeyInfoProvider::CssmKeyToBinary( - CssmKey *paramKey, // optional - CSSM_KEYATTR_FLAGS &attrFlags, // IN/OUT - BinaryKey **binKey) -{ - *binKey = NULL; - DSA *dsaKey = NULL; - - /* first cook up an DSA key, then drop that into a BinaryKey */ - dsaKey = rawCssmKeyToDsa(mKey, mSession, paramKey); - if(dsaKey->p == NULL) { - attrFlags |= CSSM_KEYATTR_PARTIAL; - } - else { - attrFlags &= ~CSSM_KEYATTR_PARTIAL; - } - DSABinaryKey *dsaBinKey = new DSABinaryKey(dsaKey); - *binKey = dsaBinKey; -} - -/* - * Obtain key size in bits. - */ -void DSAKeyInfoProvider::QueryKeySizeInBits( - CSSM_KEY_SIZE &keySize) -{ - DSA *dsaKey = NULL; - - if(mKey.blobType() != CSSM_KEYBLOB_RAW) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT); - } - dsaKey = rawCssmKeyToDsa(mKey, - mSession, - NULL); // no param key allowed here - if(dsaKey->p != NULL) { - /* normal fully-formed key */ - keySize.LogicalKeySizeInBits = BN_num_bits(dsaKey->p); - keySize.EffectiveKeySizeInBits = keySize.LogicalKeySizeInBits; - DSA_free(dsaKey); - } - else { - /* partial key, get an approximation from pub_key */ - keySize.LogicalKeySizeInBits = BN_num_bits(dsaKey->pub_key); - DSA_free(dsaKey); - /* and indicate this anomaly like so */ - CssmError::throwMe(CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE); - } -} - -/* - * Obtain blob suitable for hashing in CSSM_APPLECSP_KEYDIGEST - * passthrough. - */ -bool DSAKeyInfoProvider::getHashableBlob( - Allocator &allocator, - CssmData &blob) // blob to hash goes here -{ - /* No optimized case for DSA keys */ - return false; -}