+++ /dev/null
-/*
- * 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.
- */
-
-
-//
-// AppleCSPContext.cpp - CSP-wide contexts
-//
-
-#include "AppleCSPContext.h"
-#include "AppleCSPSession.h"
-#include "AppleCSPUtils.h"
-
-/*
- * Empty destructor (just to avoid out-of-line copies)
- */
-AppleCSPContext::~AppleCSPContext()
-{ }
-
-/*
- * get symmetric key bits - context.key can be either ref or raw.
- * A convenience routine typically used by subclass's init().
- */
-void AppleCSPContext::symmetricKeyBits(
- const Context &context,
- AppleCSPSession &session,
- CSSM_ALGORITHMS requiredAlg, // throws if this doesn't match key alg
- CSSM_KEYUSE intendedUse, // throws if key usage doesn't match this
- uint8 *&keyBits, // RETURNED (not mallocd or copied)
- CSSM_SIZE &keyLen) // RETURNED
-{
- /* key must be present and it must be a session key matching caller's spec */
- CssmKey &key =
- context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY);
- if(key.keyClass() != CSSM_KEYCLASS_SESSION_KEY) {
- CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
- }
- if(key.algorithm() != requiredAlg) {
- CssmError::throwMe(CSSMERR_CSP_ALGID_MISMATCH);
- }
- cspValidateIntendedKeyUsage(&key.KeyHeader, intendedUse);
- cspVerifyKeyTimes(key.KeyHeader);
-
- /* extract raw bits one way or the other */
- switch(key.blobType()) {
- case CSSM_KEYBLOB_RAW:
- /* easy case, the bits are right there in the CssmKey */
- if(key.blobFormat() != CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING) {
- CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
- }
- keyLen = key.length();
- keyBits = key.KeyData.Data;
- break;
-
- case CSSM_KEYBLOB_REFERENCE:
- {
- /* do a lookup to get a binary key */
- BinaryKey &binKey = session.lookupRefKey(key);
- /* fails if this is not a SymmetricBinaryKey */
- SymmetricBinaryKey *symBinKey =
- dynamic_cast<SymmetricBinaryKey *>(&binKey);
- if(symBinKey == NULL) {
- CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
- }
- keyLen = symBinKey->mKeyData.Length;
- keyBits = symBinKey->mKeyData.Data;
- break;
- }
- default:
- CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT);
- }
- return;
-}
-
-AppleKeyPairGenContext::~AppleKeyPairGenContext()
-{ /* virtual */ }
-
-// Called from subclass after it allocates its BinaryKeys.
-// Caller frees BinaryKeys if we throw any exception.
-void AppleKeyPairGenContext::generate(
- const Context &context,
- AppleCSPSession &session,
- CssmKey &pubKey,
- BinaryKey *pubBinKey,
- CssmKey &privKey,
- BinaryKey *privBinKey)
-{
- uint32 keySize;
- cspKeyStorage privStorage;
- cspKeyStorage pubStorage;
- CssmKey::Header &pubHdr = pubKey.header();
- CssmKey::Header &privHdr = privKey.header();
-
- // validate context and key header args
- pubStorage = cspParseKeyAttr(CKT_Public, pubHdr.KeyAttr);
- privStorage = cspParseKeyAttr(CKT_Private, privHdr.KeyAttr);
- cspValidateKeyUsageBits(CKT_Public, pubHdr.KeyUsage);
- cspValidateKeyUsageBits(CKT_Private, privHdr.KeyUsage);
-
- // have subclass generate the key pairs in the form of
- // its native BinaryKeys
- generate(context, *pubBinKey, *privBinKey, keySize);
-
- // FIXME - Any other header setup?
- pubHdr.LogicalKeySizeInBits =
- privHdr.LogicalKeySizeInBits = keySize;
- pubHdr.KeyAttr &= ~KEY_ATTR_RETURN_MASK;
- privHdr.KeyAttr &= ~KEY_ATTR_RETURN_MASK;
-
- // Handle key formatting. Delete the BinaryKeys if
- // we're not creating ref keys, after safe completion of
- // generateKeyBlob (which may throw, in which case the binary keys
- // get deleted by our caller).
- CSSM_KEYATTR_FLAGS attrFlags = 0;
- switch(pubStorage) {
- case CKS_Ref:
- session.addRefKey(*pubBinKey, pubKey);
- break;
- case CKS_Data:
- pubHdr.Format = requestedKeyFormat(context, pubKey);
- pubBinKey->mKeyHeader = pubHdr;
- pubBinKey->generateKeyBlob(
- session.normAlloc(), // alloc in user space
- CssmData::overlay(pubKey.KeyData),
- pubHdr.Format,
- session,
- NULL, // no paramKey here!
- attrFlags);
- break;
- case CKS_None:
- break;
- }
- switch(privStorage) {
- case CKS_Ref:
- session.addRefKey(*privBinKey, privKey);
- break;
- case CKS_Data:
- privHdr.Format = requestedKeyFormat(context, privKey);
- privBinKey->mKeyHeader = privHdr;
- privBinKey->generateKeyBlob(
- session.normAlloc(), // alloc in user space
- CssmData::overlay(privKey.KeyData),
- privHdr.Format,
- session,
- NULL,
- attrFlags);
- break;
- case CKS_None:
- break;
- }
- if(pubStorage != CKS_Ref) {
- delete pubBinKey;
- }
- if(privStorage != CKS_Ref) {
- delete privBinKey;
- }
-}
-
-/*
- * Called from subclass's generate method. Subclass is also a
- * AppleCSPContext.
- */
-void AppleSymmKeyGenContext::generateSymKey(
- const Context &context,
- AppleCSPSession &session, // for ref keys
- CssmKey &cssmKey) // RETURNED
-{
- /* there really is no legal way this should throw... */
- uint32 reqKeySize = context.getInt(
- CSSM_ATTRIBUTE_KEY_LENGTH,
- CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH);
- if((reqKeySize < minSizeInBits) ||
- (reqKeySize > maxSizeInBits)) {
- CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_SIZE);
- }
- if(mustBeByteSized) {
- if((reqKeySize & 0x7) != 0) {
- CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_SIZE);
- }
- }
-
- // validate KeyAtrr and KeyUsage already present in header
- cspKeyStorage keyStorage;
- CssmKey::Header &hdr = cssmKey.header();
-
- keyStorage = cspParseKeyAttr(CKT_Session, hdr.KeyAttr);
- cspValidateKeyUsageBits(CKT_Session, hdr.KeyUsage);
- hdr.KeyAttr &= ~KEY_ATTR_RETURN_MASK;
-
- hdr.LogicalKeySizeInBits = reqKeySize;
- uint32 keySizeInBytes = (reqKeySize + 7) / 8;
- SymmetricBinaryKey *binKey = NULL;
- CssmData *keyData = NULL;
-
- switch(keyStorage) {
- case CKS_None:
- /* no way */
- CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
- case CKS_Ref:
- /* cook up a symmetric binary key */
- binKey = new SymmetricBinaryKey(reqKeySize);
- keyData = &binKey->mKeyData;
- break;
- case CKS_Data:
- /* key bytes --> caller's cssmKey */
- keyData = &(CssmData::overlay(cssmKey.KeyData));
- setUpCssmData(*keyData, keySizeInBytes,
- session.normAlloc());
- break;
- }
-
- // in any case, fill key bytes with random data
- session.getRandomBytes(keySizeInBytes, keyData->Data);
-
- if(keyStorage == CKS_Ref) {
- session.addRefKey(*binKey, cssmKey);
- }
- else {
- /* Raw data */
- hdr.BlobType = CSSM_KEYBLOB_RAW;
- hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
- }
-
- // FIXME - any other header fields?
-}
-
-//
-// Symmetric Binary Key support
-//
-SymmetricBinaryKey::SymmetricBinaryKey(
- unsigned keySizeInBits) :
- mAllocator(Allocator::standard(Allocator::sensitive))
-{
- setUpCssmData(mKeyData, (keySizeInBits + 7) / 8, mAllocator);
-}
-
-SymmetricBinaryKey::~SymmetricBinaryKey()
-{
- freeCssmData(mKeyData, mAllocator);
-}
-
-void SymmetricBinaryKey::generateKeyBlob(
- Allocator &allocator,
- CssmData &blob,
- CSSM_KEYBLOB_FORMAT &format, // CSSM_KEYBLOB_RAW_FORMAT_PKCS1, etc.
- AppleCSPSession &session,
- const CssmKey *paramKey, /* optional, unused here */
- CSSM_KEYATTR_FLAGS &attrFlags) /* IN/OUT */
-{
- switch(format) {
- case CSSM_KEYBLOB_RAW_FORMAT_NONE: // default
- case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING: // the one we can do
- case CSSM_KEYBLOB_RAW_FORMAT_DIGEST: // same thing
- break;
- default:
- CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SYMMETRIC_KEY_FORMAT);
- }
- copyCssmData(mKeyData, blob, allocator);
- format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
-}
-