]> git.saurik.com Git - apple/security.git/blame - AppleCSP/CryptKitCSP/FEEKeys.cpp
Security-28.tar.gz
[apple/security.git] / AppleCSP / CryptKitCSP / FEEKeys.cpp
CommitLineData
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 */
45CryptKit::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
56CryptKit::FEEBinaryKey::~FEEBinaryKey()
57{
58 if(mFeeKey) {
59 feePubKeyFree(mFeeKey);
60 mFeeKey = NULL;
61 }
62}
63
64void 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 */
126void 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
151void 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 ***/
251CryptKit::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 */
274void 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 */
292void 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 */