]> git.saurik.com Git - apple/security.git/blob - libsecurity_pkcs12/lib/pkcs12Coder.cpp
d2be98a20209892dd90458453cbd9886a1acec35
[apple/security.git] / libsecurity_pkcs12 / lib / pkcs12Coder.cpp
1 /*
2 * Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * pkcs12Coder.cpp - Public P12Coder coder functions.
26 */
27
28 #include "pkcs12Coder.h"
29 #include "pkcs12Debug.h"
30 #include "pkcs12Utils.h"
31 #include <Security/cssmerr.h>
32 #include <security_cdsa_utils/cuCdsaUtils.h>
33 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
34 #include <Security/oidsalg.h>
35
36 /*
37 * Default encryption parameters
38 */
39 #define P12_ENCR_ITER_COUNT 2048
40 #define P12_MAC_ITER_COUNT 1
41 #define P12_WEAK_ENCR_ALG CSSMOID_PKCS12_pbewithSHAAnd40BitRC2CBC
42 #define P12_STRONG_ENCR_ALG CSSMOID_PKCS12_pbeWithSHAAnd3Key3DESCBC
43
44 /*
45 * Default import flags.
46 */
47 #define P12_KC_IMPORT_DEFAULT (kSecImportCertificates | \
48 kSecImportCRLs | \
49 kSecImportKeys)
50
51 P12Coder::P12Coder()
52 {
53 init();
54 }
55
56 /* one-time init from all constructors */
57 void P12Coder::init()
58 {
59 mPrivacyMode = kSecPkcs12ModePassword;
60 mIntegrityMode = kSecPkcs12ModePassword;
61 mMacPassphrase = NULL;
62 mEncrPassPhrase = NULL;
63 mMacPassData.Data = NULL;
64 mMacPassData.Length = 0;
65 mEncrPassData.Data = NULL;
66 mEncrPassData.Length = 0;
67 mMacPassKey = NULL;
68 mEncrPassKey = NULL;
69 mKeychain = NULL;
70 mCspHand = 0;
71 mDlDbHand.DLHandle = 0;
72 mDlDbHand.DBHandle = 0;
73 mPrivKeyImportState = PKIS_NoLimit;
74 mWeakEncrAlg = P12_WEAK_ENCR_ALG;
75 mStrongEncrAlg = P12_STRONG_ENCR_ALG;
76 mWeakEncrIterCount = P12_ENCR_ITER_COUNT;
77 mStrongEncrIterCount = P12_ENCR_ITER_COUNT;
78 mMacIterCount = P12_MAC_ITER_COUNT;
79 mImportFlags = P12_KC_IMPORT_DEFAULT;
80 mRawCspHand = 0;
81 mClHand = 0;
82 mAccess = NULL;
83 mNoAcl = false;
84 mKeyUsage = CSSM_KEYUSE_ANY; /* default */
85 /* default key attrs; we add CSSM_KEYATTR_PERMANENT if importing to
86 * a keychain */
87 mKeyAttrs = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE |
88 CSSM_KEYATTR_SENSITIVE;
89 }
90
91 /*
92 * FIXME - can't we get vector's destructor to do this?
93 */
94 #define deleteVect(v) \
95 { \
96 while(v.size()) { \
97 delete v[0]; \
98 v.erase(v.begin()); \
99 } \
100 v.clear(); \
101 }
102
103 P12Coder::~P12Coder()
104 {
105 if(mMacPassphrase) {
106 CFRelease(mMacPassphrase);
107 }
108 if(mEncrPassPhrase) {
109 CFRelease(mEncrPassPhrase);
110 }
111 if(mAccess) {
112 CFRelease(mAccess);
113 }
114 deleteVect(mCerts);
115 deleteVect(mCrls);
116 deleteVect(mKeys);
117 deleteVect(mOpaques);
118
119 if(mKeychain) {
120 CFRelease(mKeychain);
121 }
122 if(mRawCspHand) {
123 cuCspDetachUnload(mRawCspHand, CSSM_TRUE);
124 }
125 if(mClHand) {
126 cuClDetachUnload(mClHand);
127 }
128 }
129
130 void P12Coder::setKeychain(
131 SecKeychainRef keychain)
132 {
133 OSStatus ortn = SecKeychainGetCSPHandle(keychain, &mCspHand);
134 if(ortn) {
135 MacOSError::throwMe(ortn);
136 }
137 ortn = SecKeychainGetDLDBHandle(keychain, &mDlDbHand);
138 if(ortn) {
139 MacOSError::throwMe(ortn);
140 }
141 CFRetain(keychain);
142 mKeychain = keychain;
143 }
144
145 void P12Coder::setAccess(
146 SecAccessRef access)
147 {
148 if(mAccess) {
149 CFRelease(mAccess);
150 }
151 mAccess = access;
152 if(mAccess) {
153 CFRetain(mAccess);
154 }
155 else {
156 /* NULL ==> no ACL */
157 mNoAcl = true;
158 }
159 }
160
161 #define SEC_KEYATTR_RETURN_MASK \
162 (CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_RETURN_NONE)
163
164 void P12Coder::setKeyAttrs(
165 CSSM_KEYATTR_FLAGS keyAttrs)
166 {
167 /* ensure we're generating a ref key no matter what caller asks for */
168 mKeyAttrs = keyAttrs;
169 mKeyAttrs &= ~SEC_KEYATTR_RETURN_MASK;
170 mKeyAttrs |= CSSM_KEYATTR_RETURN_REF;
171 }
172
173 /*
174 * Private methods for obtaining passprases in CSSM_DATA form.
175 */
176 const CSSM_DATA *P12Coder::getMacPassPhrase()
177 {
178 if(mMacPassData.Data != NULL) {
179 return &mMacPassData;
180 }
181 else if (mMacPassphrase) {
182 p12ImportPassPhrase(mMacPassphrase, mCoder, mMacPassData);
183 return &mMacPassData;
184 }
185 else {
186 return NULL;
187 }
188 }
189
190 const CSSM_DATA *P12Coder::getEncrPassPhrase()
191 {
192 if(mEncrPassData.Data != NULL) {
193 return &mEncrPassData;
194 }
195 else if (mEncrPassPhrase) {
196 p12ImportPassPhrase(mEncrPassPhrase, mCoder, mEncrPassData);
197 return &mEncrPassData;
198 }
199 /* no separate passphrase found, use MAC passphrase */
200 return getMacPassPhrase();
201 }
202
203 /*
204 * These return a CSSM_KEY_PTR is the app had specified
205 * PassKeys, else they return NULL.
206 */
207 const CSSM_KEY *P12Coder::getMacPassKey()
208 {
209 return mMacPassKey;
210 }
211
212 const CSSM_KEY *P12Coder::getEncrPassKey()
213 {
214 if(mEncrPassKey != NULL) {
215 return mEncrPassKey;
216 }
217 else {
218 return getMacPassKey();
219 }
220 }
221
222 /*
223 * Lazy evaluation of module handles.
224 */
225 CSSM_CSP_HANDLE P12Coder::rawCspHand()
226 {
227 if(mRawCspHand != 0) {
228 return mRawCspHand;
229 }
230 mRawCspHand = cuCspStartup(CSSM_TRUE);
231 if(mRawCspHand == 0) {
232 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
233 }
234 return mRawCspHand;
235 }
236
237 CSSM_CL_HANDLE P12Coder::clHand()
238 {
239 if(mClHand != 0) {
240 return mClHand;
241 }
242 mClHand = cuClStartup();
243 if(mClHand == 0) {
244 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
245 }
246 return mClHand;
247 }
248
249 /*
250 * These public functions more or less correspond to
251 * the public functions in SecPkcs12.h.
252 */
253 void P12Coder::setMacPassPhrase(
254 CFStringRef passphrase)
255 {
256 CFRetain(passphrase);
257 mMacPassphrase = passphrase;
258 }
259
260 void P12Coder::setEncrPassPhrase(
261 CFStringRef passphrase)
262 {
263 CFRetain(passphrase);
264 mEncrPassPhrase = passphrase;
265 }
266
267 void P12Coder::setMacPassKey(
268 const CSSM_KEY *passKey)
269 {
270 mMacPassKey = passKey;
271 }
272
273 void P12Coder::setEncrPassKey(
274 const CSSM_KEY *passKey)
275 {
276 mEncrPassKey = passKey;
277 }
278
279 /* getters */
280 unsigned P12Coder::numCerts()
281 {
282 return mCerts.size();
283 }
284
285 unsigned P12Coder::numCrls()
286 {
287 return mCrls.size();
288 }
289
290 unsigned P12Coder::numKeys()
291 {
292 return mKeys.size();
293 }
294
295 unsigned P12Coder::numOpaqueBlobs()
296 {
297 return mOpaques.size();
298 }
299
300 P12CertBag *P12Coder::getCert(
301 unsigned dex)
302 {
303 if(mCerts.size() < (dex + 1)) {
304 MacOSError::throwMe(paramErr);
305 }
306 return mCerts[dex];
307 }
308
309 P12CrlBag *P12Coder::getCrl(
310 unsigned dex)
311 {
312 if(mCrls.size() < (dex + 1)) {
313 MacOSError::throwMe(paramErr);
314 }
315 return mCrls[dex];
316 }
317
318 P12KeyBag *P12Coder::getKey(
319 unsigned dex)
320 {
321 if(mKeys.size() < (dex + 1)) {
322 MacOSError::throwMe(paramErr);
323 }
324 return mKeys[dex];
325 }
326
327 P12OpaqueBag *P12Coder::getOpaque(
328 unsigned dex)
329 {
330 if(mOpaques.size() < (dex + 1)) {
331 MacOSError::throwMe(paramErr);
332 }
333 return mOpaques[dex];
334 }
335
336 /*
337 * These four "add" functions are invoked by the app prior to encoding
338 * and by our decoder while decoding.
339 */
340 void P12Coder::addCert(
341 P12CertBag *cert)
342 {
343 mCerts.push_back(cert);
344 }
345
346 void P12Coder::addCrl(
347 P12CrlBag *crl)
348 {
349 mCrls.push_back(crl);
350 }
351
352 void P12Coder::addKey(
353 P12KeyBag *key)
354 {
355 mKeys.push_back(key);
356 }
357
358 void P12Coder::addOpaque(
359 P12OpaqueBag *opaque)
360 {
361 mOpaques.push_back(opaque);
362 }
363
364
365 /* little known, but public, functions */
366 void P12Coder::integrityMode(
367 SecPkcs12Mode mode)
368 {
369 if(mode != kSecPkcs12ModePassword) {
370 MacOSError::throwMe(paramErr);
371 }
372 mIntegrityMode = mode;
373 }
374
375 void P12Coder::privacyMode(
376 SecPkcs12Mode mode)
377 {
378 if(mode != kSecPkcs12ModePassword) {
379 MacOSError::throwMe(paramErr);
380 }
381 mPrivacyMode = mode;
382 }
383
384 CFDataRef P12Coder::weakEncrAlg()
385 {
386 return p12CssmDataToCf(mWeakEncrAlg);
387 }
388
389 CFDataRef P12Coder::strongEncrAlg()
390 {
391 return p12CssmDataToCf(mStrongEncrAlg);
392 }
393
394 void P12Coder::weakEncrAlg(
395 CFDataRef alg)
396 {
397 p12CfDataToCssm(alg, mWeakEncrAlg, mCoder);
398 }
399
400 void P12Coder::strongEncrAlg(
401 CFDataRef alg)
402 {
403 p12CfDataToCssm(alg, mStrongEncrAlg, mCoder);
404 }
405
406 void P12Coder::limitPrivKeyImport(
407 bool foundOneKey)
408 {
409 if(foundOneKey) {
410 mPrivKeyImportState = PKIS_NoMore;
411 }
412 else {
413 mPrivKeyImportState = PKIS_AllowOne;
414 }
415 }