]> git.saurik.com Git - apple/security.git/blob - AppleCSP/CryptKitCSP/FEECSPUtils.cpp
Security-163.tar.gz
[apple/security.git] / AppleCSP / CryptKitCSP / FEECSPUtils.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 /*
20 * FEECSPUtils.h - Misc. utility function for FEE/CryptKit CSP.
21 *
22 * Created 2/20/2001 by dmitch.
23 */
24
25 #ifdef CRYPTKIT_CSP_ENABLE
26
27 #include <Security/utilities.h>
28 #include <Security/debugging.h>
29 #include <Security/logging.h>
30 #include "FEECSPUtils.h"
31 #include "FEEKeys.h"
32 #include <CryptKit/feeFunctions.h>
33 #include <CryptKit/feePublicKey.h>
34
35 #define feeMiscDebug(args...) secdebug("feeMisc", ## args)
36
37 /* Given a FEE error, throw appropriate CssmError */
38 void CryptKit::throwCryptKit(
39 feeReturn frtn,
40 const char *op) /* optional */
41 {
42 if(op) {
43 Security::Syslog::error("Apple CSP %s: %s", op, feeReturnString(frtn));
44 }
45 switch(frtn) {
46 case FR_Success:
47 return;
48 case FR_BadPubKey:
49 case FR_BadPubKeyString:
50 case FR_IncompatibleKey:
51 case FR_BadKeyBlob:
52 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
53 case FR_IllegalDepth:
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);
72
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);
80 }
81 }
82
83 /*
84 * Given a Context:
85 * -- obtain CSSM key of specified CSSM_ATTRIBUTE_TYPE
86 * -- validate keyClass
87 * -- validate keyUsage
88 * -- convert to feePubKey, allocating the feePubKey if necessary
89 */
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
97 {
98 CssmKey &cssmKey =
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);
103 }
104 if(hdr.KeyClass != keyClass) {
105 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
106 }
107 cspValidateIntendedKeyUsage(&hdr, usage);
108 cspVerifyKeyTimes(hdr);
109 return cssmKeyToFee(cssmKey, session, mallocdKey);
110 }
111
112 /*
113 * Convert a CssmKey to a feePubKey. May result in the creation of a new
114 * feePubKey (when cssmKey is a raw key); allocdKey is true in that case
115 * in which case the caller generally has to free the allocd key).
116 */
117 feePubKey CryptKit::cssmKeyToFee(
118 const CssmKey &cssmKey,
119 AppleCSPSession &session,
120 bool &allocdKey) // RETURNED
121 {
122 feePubKey feeKey = NULL;
123 allocdKey = false;
124
125 const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
126 if(hdr->AlgorithmId != CSSM_ALGID_FEE) {
127 // someone else's key (should never happen)
128 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
129 }
130 switch(hdr->BlobType) {
131 case CSSM_KEYBLOB_RAW:
132 feeKey = rawCssmKeyToFee(cssmKey);
133 allocdKey = true;
134 break;
135 case CSSM_KEYBLOB_REFERENCE:
136 {
137 BinaryKey &binKey = session.lookupRefKey(cssmKey);
138 FEEBinaryKey *feeBinKey = dynamic_cast<FEEBinaryKey *>(&binKey);
139 /* this cast failing means that this is some other
140 * kind of binary key */
141 if(feeBinKey == NULL) {
142 feeMiscDebug("CryptKit::cssmKeyToFee: wrong BinaryKey subclass\n");
143 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
144 }
145 assert(feeBinKey->feeKey() != NULL);
146 feeKey = feeBinKey->feeKey();
147 break;
148 }
149 default:
150 CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
151 }
152 return feeKey;
153 }
154
155 /*
156 * Convert a raw CssmKey to a newly alloc'd feePubKey.
157 */
158 feePubKey CryptKit::rawCssmKeyToFee(
159 const CssmKey &cssmKey)
160 {
161 const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
162 assert(hdr->BlobType == CSSM_KEYBLOB_RAW);
163
164 if(hdr->AlgorithmId != CSSM_ALGID_FEE) {
165 // someone else's key (should never happen)
166 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
167 }
168 bool derBlob;
169 switch(hdr->Format) {
170 case FEE_KEYBLOB_DEFAULT_FORMAT:
171 derBlob = true;
172 break;
173 case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING:
174 derBlob = false;
175 break;
176 default:
177 feeMiscDebug("CryptKit::rawCssmKeyToFee: format mismatch\n");
178 CssmError::throwMe(hdr->KeyClass == CSSM_KEYCLASS_PRIVATE_KEY ?
179 CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT :
180 CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT);
181 }
182 switch(hdr->KeyClass) {
183 case CSSM_KEYCLASS_PUBLIC_KEY:
184 case CSSM_KEYCLASS_PRIVATE_KEY:
185 break;
186 default:
187 // someone else's key
188 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
189 }
190
191 feePubKey feeKey = feePubKeyAlloc();
192 if(feeKey == NULL) {
193 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
194 }
195 feeReturn frtn = FR_Internal;
196 switch(hdr->KeyClass) {
197 case CSSM_KEYCLASS_PUBLIC_KEY:
198 if(derBlob) {
199 frtn = feePubKeyInitFromDERPubBlob(feeKey,
200 cssmKey.KeyData.Data,
201 cssmKey.KeyData.Length);
202 }
203 else {
204 frtn = feePubKeyInitFromPubBlob(feeKey,
205 cssmKey.KeyData.Data,
206 cssmKey.KeyData.Length);
207 }
208 break;
209 case CSSM_KEYCLASS_PRIVATE_KEY:
210 if(derBlob) {
211 frtn = feePubKeyInitFromDERPrivBlob(feeKey,
212 cssmKey.KeyData.Data,
213 cssmKey.KeyData.Length);
214 }
215 else {
216 frtn = feePubKeyInitFromPrivBlob(feeKey,
217 cssmKey.KeyData.Data,
218 cssmKey.KeyData.Length);
219 }
220 }
221 if(frtn) {
222 feePubKeyFree(feeKey);
223 throwCryptKit(frtn, "feePubKeyInitFromKeyBlob");
224 }
225 return feeKey;
226 }
227
228 /*
229 * Glue function which allows C code to use AppleCSPSession
230 * as an RNG. A ptr to this function gets passed down to
231 * CryptKit C functions as a feeRandFcn.
232 */
233 feeReturn CryptKit::feeRandCallback(
234 void *ref, // actually an AppleCSPSession *
235 unsigned char *bytes, // must be alloc'd by caller
236 unsigned numBytes)
237 {
238 AppleCSPSession *session =
239 reinterpret_cast<AppleCSPSession *>(ref);
240 try {
241 session->getRandomBytes(numBytes, bytes);
242 }
243 catch(...) {
244 return FR_Internal;
245 }
246 return FR_Success;
247 }
248
249 #endif /* CRYPTKIT_CSP_ENABLE */