]> git.saurik.com Git - apple/security.git/blob - AppleCSP/RSA_DSA/RSA_DSA_utils.cpp
Security-54.1.tar.gz
[apple/security.git] / AppleCSP / RSA_DSA / RSA_DSA_utils.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 * RSA_DSA_utils.cpp
21 */
22
23 #include "RSA_DSA_utils.h"
24 #include "RSA_DSA_keys.h"
25 #include <opensslUtils/openRsaSnacc.h>
26 #include <Security/logging.h>
27 #include <Security/debugging.h>
28 #include <open_ssl/opensslUtils/opensslUtils.h>
29 #include <openssl/bn.h>
30 #include <openssl/rsa.h>
31 #include <openssl/dsa.h>
32 #include <openssl/err.h>
33
34 #define rsaMiscDebug(args...) debug("rsaMisc", ## args)
35
36 /*
37 * Given a Context:
38 * -- obtain CSSM key (there must only be one)
39 * -- validate keyClass
40 * -- validate keyUsage
41 * -- convert to RSA *, allocating the RSA key if necessary
42 */
43 RSA *contextToRsaKey(
44 const Context &context,
45 AppleCSPSession &session,
46 CSSM_KEYCLASS keyClass, // CSSM_KEYCLASS_{PUBLIC,PRIVATE}_KEY
47 CSSM_KEYUSE usage, // CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_SIGN, etc.
48 bool &mallocdKey) // RETURNED
49 {
50 CssmKey &cssmKey =
51 context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY);
52 const CSSM_KEYHEADER &hdr = cssmKey.KeyHeader;
53 if(hdr.AlgorithmId != CSSM_ALGID_RSA) {
54 CssmError::throwMe(CSSMERR_CSP_ALGID_MISMATCH);
55 }
56 if(hdr.KeyClass != keyClass) {
57 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
58 }
59 cspValidateIntendedKeyUsage(&hdr, usage);
60 return cssmKeyToRsa(cssmKey, session, mallocdKey);
61 }
62 /*
63 * Convert a CssmKey to an RSA * key. May result in the creation of a new
64 * RSA (when cssmKey is a raw key); allocdKey is true in that case
65 * in which case the caller generally has to free the allocd key).
66 */
67 RSA *cssmKeyToRsa(
68 const CssmKey &cssmKey,
69 AppleCSPSession &session,
70 bool &allocdKey) // RETURNED
71 {
72 RSA *rsaKey = NULL;
73 allocdKey = false;
74
75 const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
76 if(hdr->AlgorithmId != CSSM_ALGID_RSA) {
77 // someone else's key (should never happen)
78 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
79 }
80 switch(hdr->BlobType) {
81 case CSSM_KEYBLOB_RAW:
82 rsaKey = rawCssmKeyToRsa(cssmKey);
83 allocdKey = true;
84 break;
85 case CSSM_KEYBLOB_REFERENCE:
86 {
87 BinaryKey &binKey = session.lookupRefKey(cssmKey);
88 RSABinaryKey *rsaBinKey = dynamic_cast<RSABinaryKey *>(&binKey);
89 /* this cast failing means that this is some other
90 * kind of binary key */
91 if(rsaBinKey == NULL) {
92 rsaMiscDebug("cssmKeyToRsa: wrong BinaryKey subclass\n");
93 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
94 }
95 assert(rsaBinKey->mRsaKey != NULL);
96 rsaKey = rsaBinKey->mRsaKey;
97 break;
98 }
99 default:
100 CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
101 }
102 return rsaKey;
103 }
104
105 /*
106 * Convert a raw CssmKey to a newly alloc'd RSA key.
107 */
108 RSA *rawCssmKeyToRsa(
109 const CssmKey &cssmKey)
110 {
111 const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
112 bool isPub;
113
114 assert(hdr->BlobType == CSSM_KEYBLOB_RAW);
115
116 if(hdr->AlgorithmId != CSSM_ALGID_RSA) {
117 // someone else's key (should never happen)
118 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
119 }
120 switch(hdr->KeyClass) {
121 case CSSM_KEYCLASS_PUBLIC_KEY:
122 if(hdr->Format != RSA_PUB_KEY_FORMAT) {
123 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT);
124 }
125 isPub = true;
126 break;
127 case CSSM_KEYCLASS_PRIVATE_KEY:
128 if(hdr->Format != RSA_PRIV_KEY_FORMAT) {
129 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT);
130 }
131 isPub = false;
132 break;
133 default:
134 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
135 }
136
137 RSA *rsaKey = RSA_new();
138 if(rsaKey == NULL) {
139 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
140 }
141 CSSM_RETURN crtn;
142 if(isPub) {
143 crtn = RSAPublicKeyDecode(rsaKey,
144 cssmKey.KeyData.Data,
145 cssmKey.KeyData.Length);
146 }
147 else {
148 crtn = RSAPrivateKeyDecode(rsaKey,
149 cssmKey.KeyData.Data,
150 cssmKey.KeyData.Length);
151 }
152 if(crtn) {
153 CssmError::throwMe(crtn);
154 }
155 return rsaKey;
156 }
157
158 /*
159 * Given a Context:
160 * -- obtain CSSM key (there must only be one)
161 * -- validate keyClass
162 * -- validate keyUsage
163 * -- convert to DSA *, allocating the DSA key if necessary
164 */
165 DSA *contextToDsaKey(
166 const Context &context,
167 AppleCSPSession &session,
168 CSSM_KEYCLASS keyClass, // CSSM_KEYCLASS_{PUBLIC,PRIVATE}_KEY
169 CSSM_KEYUSE usage, // CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_SIGN, etc.
170 bool &mallocdKey) // RETURNED
171 {
172 CssmKey &cssmKey =
173 context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY);
174 const CSSM_KEYHEADER &hdr = cssmKey.KeyHeader;
175 if(hdr.AlgorithmId != CSSM_ALGID_DSA) {
176 CssmError::throwMe(CSSMERR_CSP_ALGID_MISMATCH);
177 }
178 if(hdr.KeyClass != keyClass) {
179 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
180 }
181 cspValidateIntendedKeyUsage(&hdr, usage);
182 return cssmKeyToDsa(cssmKey, session, mallocdKey);
183 }
184 /*
185 * Convert a CssmKey to an DSA * key. May result in the creation of a new
186 * DSA (when cssmKey is a raw key); allocdKey is true in that case
187 * in which case the caller generally has to free the allocd key).
188 */
189 DSA *cssmKeyToDsa(
190 const CssmKey &cssmKey,
191 AppleCSPSession &session,
192 bool &allocdKey) // RETURNED
193 {
194 DSA *dsaKey = NULL;
195 allocdKey = false;
196
197 const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
198 if(hdr->AlgorithmId != CSSM_ALGID_DSA) {
199 // someone else's key (should never happen)
200 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
201 }
202 switch(hdr->BlobType) {
203 case CSSM_KEYBLOB_RAW:
204 dsaKey = rawCssmKeyToDsa(cssmKey);
205 allocdKey = true;
206 break;
207 case CSSM_KEYBLOB_REFERENCE:
208 {
209 BinaryKey &binKey = session.lookupRefKey(cssmKey);
210 DSABinaryKey *dsaBinKey = dynamic_cast<DSABinaryKey *>(&binKey);
211 /* this cast failing means that this is some other
212 * kind of binary key */
213 if(dsaBinKey == NULL) {
214 rsaMiscDebug("cssmKeyToDsa: wrong BinaryKey subclass\n");
215 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
216 }
217 assert(dsaBinKey->mDsaKey != NULL);
218 dsaKey = dsaBinKey->mDsaKey;
219 break;
220 }
221 default:
222 CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
223 }
224 return dsaKey;
225 }
226
227 /*
228 * Convert a raw CssmKey to a newly alloc'd DSA key.
229 */
230 DSA *rawCssmKeyToDsa(
231 const CssmKey &cssmKey)
232 {
233 const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
234 bool isPub;
235
236 assert(hdr->BlobType == CSSM_KEYBLOB_RAW);
237
238 if(hdr->AlgorithmId != CSSM_ALGID_DSA) {
239 // someone else's key (should never happen)
240 CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
241 }
242 switch(hdr->KeyClass) {
243 case CSSM_KEYCLASS_PUBLIC_KEY:
244 if(hdr->Format != DSA_PUB_KEY_FORMAT) {
245 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT);
246 }
247 isPub = true;
248 break;
249 case CSSM_KEYCLASS_PRIVATE_KEY:
250 if(hdr->Format != DSA_PRIV_KEY_FORMAT) {
251 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT);
252 }
253 isPub = false;
254 break;
255 default:
256 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
257 }
258
259 DSA *dsaKey = DSA_new();
260 if(dsaKey == NULL) {
261 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
262 }
263 CSSM_RETURN crtn;
264 if(isPub) {
265 crtn = DSAPublicKeyDecode(dsaKey,
266 cssmKey.KeyData.Data,
267 cssmKey.KeyData.Length);
268 }
269 else {
270 crtn = DSAPrivateKeyDecode(dsaKey,
271 cssmKey.KeyData.Data,
272 cssmKey.KeyData.Length);
273 }
274 if(crtn) {
275 CssmError::throwMe(crtn);
276 }
277 return dsaKey;
278 }