AppleCSPContext.cpp [plain text]
#include "AppleCSPContext.h"
#include "AppleCSPSession.h"
#include "AppleCSPUtils.h"
AppleCSPContext::~AppleCSPContext()
{ }
void AppleCSPContext::symmetricKeyBits(
const Context &context,
AppleCSPSession &session,
CSSM_ALGORITHMS requiredAlg, CSSM_KEYUSE intendedUse, uint8 *&keyBits, CSSM_SIZE &keyLen) {
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);
switch(key.blobType()) {
case CSSM_KEYBLOB_RAW:
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:
{
BinaryKey &binKey = session.lookupRefKey(key);
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()
{ }
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();
pubStorage = cspParseKeyAttr(CKT_Public, pubHdr.KeyAttr);
privStorage = cspParseKeyAttr(CKT_Private, privHdr.KeyAttr);
cspValidateKeyUsageBits(CKT_Public, pubHdr.KeyUsage);
cspValidateKeyUsageBits(CKT_Private, privHdr.KeyUsage);
generate(context, *pubBinKey, *privBinKey, keySize);
pubHdr.LogicalKeySizeInBits =
privHdr.LogicalKeySizeInBits = keySize;
pubHdr.KeyAttr &= ~KEY_ATTR_RETURN_MASK;
privHdr.KeyAttr &= ~KEY_ATTR_RETURN_MASK;
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(), CssmData::overlay(pubKey.KeyData),
pubHdr.Format,
session,
NULL, 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(), 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;
}
}
void AppleSymmKeyGenContext::generateSymKey(
const Context &context,
AppleCSPSession &session, CssmKey &cssmKey) {
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);
}
}
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:
CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
case CKS_Ref:
binKey = new SymmetricBinaryKey(reqKeySize);
keyData = &binKey->mKeyData;
break;
case CKS_Data:
keyData = &(CssmData::overlay(cssmKey.KeyData));
setUpCssmData(*keyData, keySizeInBytes,
session.normAlloc());
break;
}
session.getRandomBytes(keySizeInBytes, keyData->Data);
if(keyStorage == CKS_Ref) {
session.addRefKey(*binKey, cssmKey);
}
else {
hdr.BlobType = CSSM_KEYBLOB_RAW;
hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
}
}
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, AppleCSPSession &session,
const CssmKey *paramKey,
CSSM_KEYATTR_FLAGS &attrFlags)
{
switch(format) {
case CSSM_KEYBLOB_RAW_FORMAT_NONE: case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING: case CSSM_KEYBLOB_RAW_FORMAT_DIGEST: break;
default:
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SYMMETRIC_KEY_FORMAT);
}
copyCssmData(mKeyData, blob, allocator);
format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
}