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