]>
Commit | Line | Data |
---|---|---|
bac41a7b A |
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 | * FEEKeys.cpp - FEE-related asymmetric key pair classes. | |
21 | * | |
22 | * Created 2/21/2001 by dmitch. | |
23 | */ | |
24 | ||
25 | #ifdef CRYPTKIT_CSP_ENABLE | |
26 | ||
27 | #include "FEEKeys.h" | |
28 | #include "FEECSPUtils.h" | |
29 | #include "CryptKitSpace.h" | |
30 | #include <CryptKit/feePublicKey.h> | |
31 | #include <CryptKit/falloc.h> | |
32 | #include <Security/cssmdata.h> | |
33 | #include "AppleCSPSession.h" | |
34 | #include "AppleCSPUtils.h" | |
35 | #include <assert.h> | |
36 | #include <Security/debugging.h> | |
37 | ||
38 | #define feeKeyDebug(args...) debug("feeKey", ## args) | |
39 | ||
40 | /*** | |
41 | *** FEE-style BinaryKey | |
42 | ***/ | |
43 | ||
44 | /* constructor with optional existing feePubKey */ | |
45 | CryptKit::FEEBinaryKey::FEEBinaryKey(feePubKey feeKey) | |
46 | : mFeeKey(feeKey) | |
47 | { | |
48 | if(mFeeKey == NULL) { | |
49 | mFeeKey = feePubKeyAlloc(); | |
50 | if(mFeeKey == NULL) { | |
51 | CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR); | |
52 | } | |
53 | } | |
54 | } | |
55 | ||
56 | CryptKit::FEEBinaryKey::~FEEBinaryKey() | |
57 | { | |
58 | if(mFeeKey) { | |
59 | feePubKeyFree(mFeeKey); | |
60 | mFeeKey = NULL; | |
61 | } | |
62 | } | |
63 | ||
64 | void CryptKit::FEEBinaryKey::generateKeyBlob( | |
65 | CssmAllocator &allocator, | |
66 | CssmData &blob, | |
67 | CSSM_KEYBLOB_FORMAT &format) | |
68 | { | |
69 | unsigned char *keyBlob; | |
70 | unsigned len; | |
71 | feeReturn frtn; | |
72 | bool derBlob; | |
73 | ||
74 | assert(mFeeKey != NULL); | |
75 | switch(format) { | |
76 | /* also case FEE_KEYBLOB_DEFAULT_FORMAT: */ | |
77 | case CSSM_KEYBLOB_RAW_FORMAT_NONE: | |
78 | derBlob = true; | |
79 | break; | |
80 | case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING: | |
81 | /* native non-DER-encoded blob */ | |
82 | derBlob = false; | |
83 | break; | |
84 | default: | |
85 | feeKeyDebug("FEEBinaryKey::generateKeyBlob: bad format (%ld)\n", format); | |
86 | CssmError::throwMe(feePubKeyIsPrivate(mFeeKey) ? | |
87 | CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT : | |
88 | CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT); | |
89 | } | |
90 | if(feePubKeyIsPrivate(mFeeKey)) { | |
91 | if(derBlob) { | |
92 | frtn = feePubKeyCreateDERPrivBlob(mFeeKey, &keyBlob, &len); | |
93 | } | |
94 | else { | |
95 | frtn = feePubKeyCreatePrivBlob(mFeeKey, &keyBlob, &len); | |
96 | } | |
97 | } | |
98 | else { | |
99 | if(derBlob) { | |
100 | frtn = feePubKeyCreateDERPubBlob(mFeeKey, &keyBlob, &len); | |
101 | } | |
102 | else { | |
103 | frtn = feePubKeyCreatePubBlob(mFeeKey, &keyBlob, &len); | |
104 | } | |
105 | } | |
106 | if(frtn) { | |
107 | throwCryptKit(frtn, "feePubKeyCreate*Blob"); | |
108 | } | |
109 | setUpCssmData(blob, len, allocator); | |
110 | memmove(blob.data(), keyBlob, len); | |
111 | blob.length(len); | |
112 | ffree(keyBlob); | |
113 | format = derBlob ? FEE_KEYBLOB_DEFAULT_FORMAT : | |
114 | CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING; | |
115 | } | |
116 | ||
117 | /*** | |
118 | *** FEE-style AppleKeyPairGenContext | |
119 | ***/ | |
120 | ||
121 | /* | |
122 | * This one is specified in, and called from, CSPFullPluginSession. Our | |
123 | * only job is to prepare two subclass-specific BinaryKeys and call up to | |
124 | * AppleKeyPairGenContext. | |
125 | */ | |
126 | void CryptKit::FEEKeyPairGenContext::generate( | |
127 | const Context &context, | |
128 | CssmKey &pubKey, | |
129 | CssmKey &privKey) | |
130 | { | |
131 | FEEBinaryKey *pubBinKey = new FEEBinaryKey(); | |
132 | FEEBinaryKey *privBinKey = new FEEBinaryKey(); | |
133 | ||
134 | try { | |
135 | AppleKeyPairGenContext::generate(context, | |
136 | session(), | |
137 | pubKey, | |
138 | pubBinKey, | |
139 | privKey, | |
140 | privBinKey); | |
141 | } | |
142 | catch (...) { | |
143 | delete pubBinKey; | |
144 | delete privBinKey; | |
145 | throw; | |
146 | } | |
147 | ||
148 | } | |
149 | ||
150 | // this one is specified in, and called from, AppleKeyPairGenContext | |
151 | void CryptKit::FEEKeyPairGenContext::generate( | |
152 | const Context &context, | |
153 | BinaryKey &pubBinKey, | |
154 | BinaryKey &privBinKey, | |
155 | uint32 &keyBits) | |
156 | { | |
157 | /* | |
158 | * These casts throw exceptions if the keys are of the | |
159 | * wrong classes, which would be a major bogon, since we created | |
160 | * the keys in the above generate() function. | |
161 | */ | |
162 | FEEBinaryKey &fPubBinKey = | |
163 | dynamic_cast<FEEBinaryKey &>(pubBinKey); | |
164 | FEEBinaryKey &fPrivBinKey = | |
165 | dynamic_cast<FEEBinaryKey &>(privBinKey); | |
166 | ||
167 | /* | |
168 | * Two parameters from context. Key size in bits is required; | |
169 | * seed is optional. If not present, we cook up random private data. | |
170 | */ | |
171 | keyBits = context.getInt(CSSM_ATTRIBUTE_KEY_LENGTH, | |
172 | CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH); | |
173 | CssmCryptoData *cseed = context.get<CssmCryptoData>(CSSM_ATTRIBUTE_SEED); | |
174 | CssmData *seed; | |
175 | bool haveSeed; | |
176 | CssmAutoData aSeed(session()); // malloc on demand | |
177 | if(cseed) { | |
178 | /* caller specified seed */ | |
179 | haveSeed = true; | |
180 | seed = &cseed->param(); | |
181 | } | |
182 | else { | |
183 | /* generate random seed */ | |
184 | haveSeed = false; | |
185 | unsigned keyBytes = ((keyBits + 7) / 8) + 1; | |
186 | aSeed.malloc(keyBytes); | |
187 | session().getRandomBytes(keyBytes, aSeed); | |
188 | seed = &aSeed.get(); | |
189 | } | |
190 | ||
191 | /* Curve and prime types - optional */ | |
192 | feePrimeType primeType = FPT_Default; | |
193 | uint32 uPrimeType = context.getInt(CSSM_ATTRIBUTE_FEE_PRIME_TYPE); | |
194 | switch(uPrimeType) { | |
195 | case CSSM_FEE_PRIME_TYPE_DEFAULT: | |
196 | break; | |
197 | case CSSM_FEE_PRIME_TYPE_MERSENNE: | |
198 | primeType = FPT_Mersenne; | |
199 | break; | |
200 | case CSSM_FEE_PRIME_TYPE_FEE: | |
201 | primeType = FPT_FEE; | |
202 | break; | |
203 | case CSSM_FEE_PRIME_TYPE_GENERAL: | |
204 | primeType = FPT_General; | |
205 | break; | |
206 | default: | |
207 | /* FIXME - maybe we should be more specific */ | |
208 | CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS); | |
209 | } | |
210 | feeCurveType curveType = FCT_Default; | |
211 | uint32 uCurveType = context.getInt(CSSM_ATTRIBUTE_FEE_CURVE_TYPE); | |
212 | switch(uCurveType) { | |
213 | case CSSM_FEE_CURVE_TYPE_DEFAULT: | |
214 | break; | |
215 | case CSSM_FEE_CURVE_TYPE_MONTGOMERY: | |
216 | curveType = FCT_Montgomery; | |
217 | break; | |
218 | case CSSM_FEE_CURVE_TYPE_WEIERSTRASS: | |
219 | curveType = FCT_Weierstrass; | |
220 | break; | |
221 | default: | |
222 | /* FIXME - maybe we should be more specific */ | |
223 | CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS); | |
224 | } | |
225 | feeReturn frtn = feePubKeyInitFromPrivDataKeyBits( | |
226 | fPrivBinKey.feeKey(), | |
227 | (unsigned char *)seed->data(), | |
228 | seed->length(), | |
229 | keyBits, | |
230 | primeType, | |
231 | curveType, | |
232 | /* | |
233 | * our random seed: trust it | |
234 | * caller's seed: hash it | |
235 | */ | |
236 | haveSeed ? 1 : 0); | |
237 | if(frtn) { | |
238 | throwCryptKit(frtn, "feePubKeyInitFromPrivDataKeyBits"); | |
239 | } | |
240 | frtn = feePubKeyInitPubKeyFromPriv(fPrivBinKey.feeKey(), | |
241 | fPubBinKey.feeKey()); | |
242 | if(frtn) { | |
243 | throwCryptKit(frtn, "feePubKeyInitPubKeyFromPriv"); | |
244 | } | |
245 | } | |
246 | ||
247 | ||
248 | /*** | |
249 | *** FEE-style CSPKeyInfoProvider. | |
250 | ***/ | |
251 | CryptKit::FEEKeyInfoProvider::FEEKeyInfoProvider( | |
252 | const CssmKey &cssmKey) : | |
253 | CSPKeyInfoProvider(cssmKey) | |
254 | { | |
255 | switch(cssmKey.algorithm()) { | |
256 | case CSSM_ALGID_FEE: | |
257 | break; | |
258 | default: | |
259 | CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); | |
260 | } | |
261 | switch(cssmKey.keyClass()) { | |
262 | case CSSM_KEYCLASS_PUBLIC_KEY: | |
263 | case CSSM_KEYCLASS_PRIVATE_KEY: | |
264 | /* FIXME - verify proper CSSM_KEYBLOB_RAW_FORMAT_xx */ | |
265 | break; | |
266 | default: | |
267 | CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); | |
268 | } | |
269 | /* OK, we'll handle this one */ | |
270 | return; | |
271 | } | |
272 | ||
273 | /* Given a raw key, cook up a Binary key */ | |
274 | void CryptKit::FEEKeyInfoProvider::CssmKeyToBinary( | |
275 | BinaryKey **binKey) | |
276 | { | |
277 | *binKey = NULL; | |
278 | feePubKey feeKey = NULL; | |
279 | ||
280 | /* first cook up a feePubKey, then drop that into a BinaryKey */ | |
281 | feeKey = rawCssmKeyToFee(mKey); | |
282 | FEEBinaryKey *feeBinKey = new FEEBinaryKey(feeKey); | |
283 | *binKey = feeBinKey; | |
284 | } | |
285 | ||
286 | /* | |
287 | * Obtain key size in bits. | |
288 | * Currently only raw public keys are dealt with (they're the ones | |
289 | * which come from certs, the only current use for this function). | |
290 | * Note that if we need to handle ref keys, we'll need a session ref... | |
291 | */ | |
292 | void CryptKit::FEEKeyInfoProvider::QueryKeySizeInBits( | |
293 | CSSM_KEY_SIZE &keySize) | |
294 | { | |
295 | feePubKey feeKey = NULL; | |
296 | ||
297 | if(mKey.blobType() != CSSM_KEYBLOB_RAW) { | |
298 | CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT); | |
299 | } | |
300 | feeKey = rawCssmKeyToFee(mKey); | |
301 | keySize.LogicalKeySizeInBits = feePubKeyBitsize(feeKey); | |
302 | keySize.EffectiveKeySizeInBits = keySize.LogicalKeySizeInBits; | |
303 | feePubKeyFree(feeKey); | |
304 | } | |
305 | ||
306 | #endif /* CRYPTKIT_CSP_ENABLE */ |