+++ /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.
- */
-
-
-/*
- * FEECSPUtils.h - Misc. utility function for FEE/CryptKit CSP.
- *
- * Created 2/20/2001 by dmitch.
- */
-
-#ifdef CRYPTKIT_CSP_ENABLE
-
-#include <Security/utilities.h>
-#include <Security/debugging.h>
-#include <Security/logging.h>
-#include "FEECSPUtils.h"
-#include "FEEKeys.h"
-#include <CryptKit/feeFunctions.h>
-#include <CryptKit/feePublicKey.h>
-
-#define feeMiscDebug(args...) secdebug("feeMisc", ## args)
-
-/* Given a FEE error, throw appropriate CssmError */
-void CryptKit::throwCryptKit(
- feeReturn frtn,
- const char *op) /* optional */
-{
- if(op) {
- Security::Syslog::error("Apple CSP %s: %s", op, feeReturnString(frtn));
- }
- switch(frtn) {
- case FR_Success:
- return;
- case FR_BadPubKey:
- case FR_BadPubKeyString:
- case FR_IncompatibleKey:
- case FR_BadKeyBlob:
- CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
- case FR_IllegalDepth:
- CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_SIZE);
- case FR_BadSignatureFormat: /* signature corrupted */
- CssmError::throwMe(CSSMERR_CSP_INVALID_SIGNATURE);
- case FR_InvalidSignature: /* signature intact, but not valid */
- CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED);
- case FR_IllegalArg: /* illegal argument */
- CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
- case FR_BadCipherText: /* malformed ciphertext */
- case FR_BadEnc64: /* bad enc64() format */
- CssmError::throwMe(CSSMERR_CSP_INVALID_DATA);
- case FR_Unimplemented: /* unimplemented function */
- CssmError::throwMe(CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED);
- case FR_Memory: /* unimplemented function */
- CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
- case FR_ShortPrivData:
- CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SEED);
- case FR_IllegalCurve: /* e.g., ECDSA with Montgomery curve */
- CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
-
- /* I don't think we should ever see these no matter what the
- * caller throws at us */
- case FR_WrongSignatureType: /* ElGamal vs. ECDSA */
- case FR_BadUsageName: /* bad usageName */
- case FR_BadCipherFile:
- case FR_Internal: /* internal library error */
- CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
- }
-}
-
-/*
- * Given a Context:
- * -- obtain CSSM key of specified CSSM_ATTRIBUTE_TYPE
- * -- validate keyClass
- * -- validate keyUsage
- * -- convert to feePubKey, allocating the feePubKey if necessary
- */
-feePubKey CryptKit::contextToFeeKey(
- const Context &context,
- AppleCSPSession &session,
- CSSM_ATTRIBUTE_TYPE attrType, // CSSM_ATTRIBUTE_KEY, CSSM_ATTRIBUTE_PUBLIC_KEY
- CSSM_KEYCLASS keyClass, // CSSM_KEYCLASS_{PUBLIC,PRIVATE}_KEY
- CSSM_KEYUSE usage, // CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_SIGN, etc.
- bool &mallocdKey) // RETURNED
-{
- CssmKey &cssmKey =
- context.get<CssmKey>(attrType, CSSMERR_CSP_MISSING_ATTR_KEY);
- const CSSM_KEYHEADER &hdr = cssmKey.KeyHeader;
- if(hdr.AlgorithmId != CSSM_ALGID_FEE) {
- CssmError::throwMe(CSSMERR_CSP_ALGID_MISMATCH);
- }
- if(hdr.KeyClass != keyClass) {
- CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
- }
- cspValidateIntendedKeyUsage(&hdr, usage);
- cspVerifyKeyTimes(hdr);
- return cssmKeyToFee(cssmKey, session, mallocdKey);
-}
-
-/*
- * Convert a CssmKey to a feePubKey. May result in the creation of a new
- * feePubKey (when cssmKey is a raw key); allocdKey is true in that case
- * in which case the caller generally has to free the allocd key).
- */
-feePubKey CryptKit::cssmKeyToFee(
- const CssmKey &cssmKey,
- AppleCSPSession &session,
- bool &allocdKey) // RETURNED
-{
- feePubKey feeKey = NULL;
- allocdKey = false;
-
- const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
- if(hdr->AlgorithmId != CSSM_ALGID_FEE) {
- // someone else's key (should never happen)
- CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
- }
- switch(hdr->BlobType) {
- case CSSM_KEYBLOB_RAW:
- feeKey = rawCssmKeyToFee(cssmKey);
- allocdKey = true;
- break;
- case CSSM_KEYBLOB_REFERENCE:
- {
- BinaryKey &binKey = session.lookupRefKey(cssmKey);
- FEEBinaryKey *feeBinKey = dynamic_cast<FEEBinaryKey *>(&binKey);
- /* this cast failing means that this is some other
- * kind of binary key */
- if(feeBinKey == NULL) {
- feeMiscDebug("CryptKit::cssmKeyToFee: wrong BinaryKey subclass\n");
- CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
- }
- assert(feeBinKey->feeKey() != NULL);
- feeKey = feeBinKey->feeKey();
- break;
- }
- default:
- CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
- }
- return feeKey;
-}
-
-/*
- * Convert a raw CssmKey to a newly alloc'd feePubKey.
- */
-feePubKey CryptKit::rawCssmKeyToFee(
- const CssmKey &cssmKey)
-{
- const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
- assert(hdr->BlobType == CSSM_KEYBLOB_RAW);
-
- if(hdr->AlgorithmId != CSSM_ALGID_FEE) {
- // someone else's key (should never happen)
- CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
- }
- bool derBlob;
- switch(hdr->Format) {
- case FEE_KEYBLOB_DEFAULT_FORMAT:
- derBlob = true;
- break;
- case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING:
- derBlob = false;
- break;
- default:
- feeMiscDebug("CryptKit::rawCssmKeyToFee: format mismatch\n");
- CssmError::throwMe(hdr->KeyClass == CSSM_KEYCLASS_PRIVATE_KEY ?
- CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT :
- CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT);
- }
- switch(hdr->KeyClass) {
- case CSSM_KEYCLASS_PUBLIC_KEY:
- case CSSM_KEYCLASS_PRIVATE_KEY:
- break;
- default:
- // someone else's key
- CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
- }
-
- feePubKey feeKey = feePubKeyAlloc();
- if(feeKey == NULL) {
- CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
- }
- feeReturn frtn = FR_Internal;
- switch(hdr->KeyClass) {
- case CSSM_KEYCLASS_PUBLIC_KEY:
- if(derBlob) {
- frtn = feePubKeyInitFromDERPubBlob(feeKey,
- cssmKey.KeyData.Data,
- cssmKey.KeyData.Length);
- }
- else {
- frtn = feePubKeyInitFromPubBlob(feeKey,
- cssmKey.KeyData.Data,
- cssmKey.KeyData.Length);
- }
- break;
- case CSSM_KEYCLASS_PRIVATE_KEY:
- if(derBlob) {
- frtn = feePubKeyInitFromDERPrivBlob(feeKey,
- cssmKey.KeyData.Data,
- cssmKey.KeyData.Length);
- }
- else {
- frtn = feePubKeyInitFromPrivBlob(feeKey,
- cssmKey.KeyData.Data,
- cssmKey.KeyData.Length);
- }
- }
- if(frtn) {
- feePubKeyFree(feeKey);
- throwCryptKit(frtn, "feePubKeyInitFromKeyBlob");
- }
- return feeKey;
-}
-
-/*
- * Glue function which allows C code to use AppleCSPSession
- * as an RNG. A ptr to this function gets passed down to
- * CryptKit C functions as a feeRandFcn.
- */
-feeReturn CryptKit::feeRandCallback(
- void *ref, // actually an AppleCSPSession *
- unsigned char *bytes, // must be alloc'd by caller
- unsigned numBytes)
-{
- AppleCSPSession *session =
- reinterpret_cast<AppleCSPSession *>(ref);
- try {
- session->getRandomBytes(numBytes, bytes);
- }
- catch(...) {
- return FR_Internal;
- }
- return FR_Success;
-}
-
-#endif /* CRYPTKIT_CSP_ENABLE */