2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 * FEECSPUtils.h - Misc. utility function for FEE/CryptKit CSP.
22 * Created 2/20/2001 by dmitch.
25 #ifdef CRYPTKIT_CSP_ENABLE
27 #include <Security/utilities.h>
28 #include <Security/debugging.h>
29 #include <Security/logging.h>
30 #include "FEECSPUtils.h"
32 #include <CryptKit/feeFunctions.h>
33 #include <CryptKit/feePublicKey.h>
35 #define feeMiscDebug(args...) debug("feeMisc", ## args)
37 /* Given a FEE error, throw appropriate CssmError */
38 void CryptKit::throwCryptKit(
40 const char *op
) /* optional */
43 Security::Syslog::error("Apple CSP %s: %s", op
, feeReturnString(frtn
));
49 case FR_BadPubKeyString
:
50 case FR_IncompatibleKey
:
52 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY
);
54 CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_SIZE
);
55 case FR_BadSignatureFormat
: /* signature corrupted */
56 CssmError::throwMe(CSSMERR_CSP_INVALID_SIGNATURE
);
57 case FR_InvalidSignature
: /* signature intact, but not valid */
58 CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED
);
59 case FR_IllegalArg
: /* illegal argument */
60 CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT
);
61 case FR_BadCipherText
: /* malformed ciphertext */
62 case FR_BadEnc64
: /* bad enc64() format */
63 CssmError::throwMe(CSSMERR_CSP_INVALID_DATA
);
64 case FR_Unimplemented
: /* unimplemented function */
65 CssmError::throwMe(CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED
);
66 case FR_Memory
: /* unimplemented function */
67 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR
);
68 case FR_ShortPrivData
:
69 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SEED
);
70 case FR_IllegalCurve
: /* e.g., ECDSA with Montgomery curve */
71 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY
);
73 /* I don't think we should ever see these no matter what the
74 * caller throws at us */
75 case FR_WrongSignatureType
: /* ElGamal vs. ECDSA */
76 case FR_BadUsageName
: /* bad usageName */
77 case FR_BadCipherFile
:
78 case FR_Internal
: /* internal library error */
79 CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR
);
85 * -- obtain CSSM key of specified CSSM_ATTRIBUTE_TYPE
86 * -- validate keyClass
87 * -- validate keyUsage
88 * -- convert to feePubKey, allocating the feePubKey if necessary
90 feePubKey
CryptKit::contextToFeeKey(
91 const Context
&context
,
92 AppleCSPSession
&session
,
93 CSSM_ATTRIBUTE_TYPE attrType
, // CSSM_ATTRIBUTE_KEY, CSSM_ATTRIBUTE_PUBLIC_KEY
94 CSSM_KEYCLASS keyClass
, // CSSM_KEYCLASS_{PUBLIC,PRIVATE}_KEY
95 CSSM_KEYUSE usage
, // CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_SIGN, etc.
96 bool &mallocdKey
) // RETURNED
99 context
.get
<CssmKey
>(attrType
, CSSMERR_CSP_MISSING_ATTR_KEY
);
100 const CSSM_KEYHEADER
&hdr
= cssmKey
.KeyHeader
;
101 if(hdr
.AlgorithmId
!= CSSM_ALGID_FEE
) {
102 CssmError::throwMe(CSSMERR_CSP_ALGID_MISMATCH
);
104 if(hdr
.KeyClass
!= keyClass
) {
105 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS
);
107 cspValidateIntendedKeyUsage(&hdr
, usage
);
108 return cssmKeyToFee(cssmKey
, session
, mallocdKey
);
112 * Convert a CssmKey to a feePubKey. May result in the creation of a new
113 * feePubKey (when cssmKey is a raw key); allocdKey is true in that case
114 * in which case the caller generally has to free the allocd key).
116 feePubKey
CryptKit::cssmKeyToFee(
117 const CssmKey
&cssmKey
,
118 AppleCSPSession
&session
,
119 bool &allocdKey
) // RETURNED
121 feePubKey feeKey
= NULL
;
124 const CSSM_KEYHEADER
*hdr
= &cssmKey
.KeyHeader
;
125 if(hdr
->AlgorithmId
!= CSSM_ALGID_FEE
) {
126 // someone else's key (should never happen)
127 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM
);
129 switch(hdr
->BlobType
) {
130 case CSSM_KEYBLOB_RAW
:
131 feeKey
= rawCssmKeyToFee(cssmKey
);
134 case CSSM_KEYBLOB_REFERENCE
:
136 BinaryKey
&binKey
= session
.lookupRefKey(cssmKey
);
137 FEEBinaryKey
*feeBinKey
= dynamic_cast<FEEBinaryKey
*>(&binKey
);
138 /* this cast failing means that this is some other
139 * kind of binary key */
140 if(feeBinKey
== NULL
) {
141 feeMiscDebug("CryptKit::cssmKeyToFee: wrong BinaryKey subclass\n");
142 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY
);
144 assert(feeBinKey
->feeKey() != NULL
);
145 feeKey
= feeBinKey
->feeKey();
149 CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT
);
155 * Convert a raw CssmKey to a newly alloc'd feePubKey.
157 feePubKey
CryptKit::rawCssmKeyToFee(
158 const CssmKey
&cssmKey
)
160 const CSSM_KEYHEADER
*hdr
= &cssmKey
.KeyHeader
;
161 assert(hdr
->BlobType
== CSSM_KEYBLOB_RAW
);
163 if(hdr
->AlgorithmId
!= CSSM_ALGID_FEE
) {
164 // someone else's key (should never happen)
165 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM
);
168 switch(hdr
->Format
) {
169 case FEE_KEYBLOB_DEFAULT_FORMAT
:
172 case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING
:
176 feeMiscDebug("CryptKit::rawCssmKeyToFee: format mismatch\n");
177 CssmError::throwMe(hdr
->KeyClass
== CSSM_KEYCLASS_PRIVATE_KEY
?
178 CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT
:
179 CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT
);
181 switch(hdr
->KeyClass
) {
182 case CSSM_KEYCLASS_PUBLIC_KEY
:
183 case CSSM_KEYCLASS_PRIVATE_KEY
:
186 // someone else's key
187 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS
);
190 feePubKey feeKey
= feePubKeyAlloc();
192 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR
);
194 feeReturn frtn
= FR_Internal
;
195 switch(hdr
->KeyClass
) {
196 case CSSM_KEYCLASS_PUBLIC_KEY
:
198 frtn
= feePubKeyInitFromDERPubBlob(feeKey
,
199 cssmKey
.KeyData
.Data
,
200 cssmKey
.KeyData
.Length
);
203 frtn
= feePubKeyInitFromPubBlob(feeKey
,
204 cssmKey
.KeyData
.Data
,
205 cssmKey
.KeyData
.Length
);
208 case CSSM_KEYCLASS_PRIVATE_KEY
:
210 frtn
= feePubKeyInitFromDERPrivBlob(feeKey
,
211 cssmKey
.KeyData
.Data
,
212 cssmKey
.KeyData
.Length
);
215 frtn
= feePubKeyInitFromPrivBlob(feeKey
,
216 cssmKey
.KeyData
.Data
,
217 cssmKey
.KeyData
.Length
);
221 feePubKeyFree(feeKey
);
222 throwCryptKit(frtn
, "feePubKeyInitFromKeyBlob");
228 * Glue function which allows C code to use AppleCSPSession
229 * as an RNG. A ptr to this function gets passed down to
230 * CryptKit C functions as a feeRandFcn.
232 feeReturn
CryptKit::feeRandCallback(
233 void *ref
, // actually an AppleCSPSession *
234 unsigned char *bytes
, // must be alloc'd by caller
237 AppleCSPSession
*session
=
238 reinterpret_cast<AppleCSPSession
*>(ref
);
240 session
->getRandomBytes(numBytes
, bytes
);
248 #endif /* CRYPTKIT_CSP_ENABLE */