2 * Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * pkcs12Coder.cpp - Public P12Coder coder functions.
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>
37 * Default encryption parameters
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
45 * Default import flags.
47 #define P12_KC_IMPORT_DEFAULT (kSecImportCertificates | \
56 /* one-time init from all constructors */
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;
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
;
84 mKeyUsage
= CSSM_KEYUSE_ANY
; /* default */
85 /* default key attrs; we add CSSM_KEYATTR_PERMANENT if importing to
87 mKeyAttrs
= CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_EXTRACTABLE
|
88 CSSM_KEYATTR_SENSITIVE
;
92 * FIXME - can't we get vector's destructor to do this?
94 #define deleteVect(v) \
103 P12Coder::~P12Coder()
106 CFRelease(mMacPassphrase
);
108 if(mEncrPassPhrase
) {
109 CFRelease(mEncrPassPhrase
);
117 deleteVect(mOpaques
);
120 CFRelease(mKeychain
);
123 cuCspDetachUnload(mRawCspHand
, CSSM_TRUE
);
126 cuClDetachUnload(mClHand
);
130 void P12Coder::setKeychain(
131 SecKeychainRef keychain
)
133 OSStatus ortn
= SecKeychainGetCSPHandle(keychain
, &mCspHand
);
135 MacOSError::throwMe(ortn
);
137 ortn
= SecKeychainGetDLDBHandle(keychain
, &mDlDbHand
);
139 MacOSError::throwMe(ortn
);
142 mKeychain
= keychain
;
145 void P12Coder::setAccess(
156 /* NULL ==> no ACL */
161 #define SEC_KEYATTR_RETURN_MASK \
162 (CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_RETURN_NONE)
164 void P12Coder::setKeyAttrs(
165 CSSM_KEYATTR_FLAGS keyAttrs
)
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
;
174 * Private methods for obtaining passprases in CSSM_DATA form.
176 const CSSM_DATA
*P12Coder::getMacPassPhrase()
178 if(mMacPassData
.Data
!= NULL
) {
179 return &mMacPassData
;
181 else if (mMacPassphrase
) {
182 p12ImportPassPhrase(mMacPassphrase
, mCoder
, mMacPassData
);
183 return &mMacPassData
;
190 const CSSM_DATA
*P12Coder::getEncrPassPhrase()
192 if(mEncrPassData
.Data
!= NULL
) {
193 return &mEncrPassData
;
195 else if (mEncrPassPhrase
) {
196 p12ImportPassPhrase(mEncrPassPhrase
, mCoder
, mEncrPassData
);
197 return &mEncrPassData
;
199 /* no separate passphrase found, use MAC passphrase */
200 return getMacPassPhrase();
204 * These return a CSSM_KEY_PTR is the app had specified
205 * PassKeys, else they return NULL.
207 const CSSM_KEY
*P12Coder::getMacPassKey()
212 const CSSM_KEY
*P12Coder::getEncrPassKey()
214 if(mEncrPassKey
!= NULL
) {
218 return getMacPassKey();
223 * Lazy evaluation of module handles.
225 CSSM_CSP_HANDLE
P12Coder::rawCspHand()
227 if(mRawCspHand
!= 0) {
230 mRawCspHand
= cuCspStartup(CSSM_TRUE
);
231 if(mRawCspHand
== 0) {
232 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
237 CSSM_CL_HANDLE
P12Coder::clHand()
242 mClHand
= cuClStartup();
244 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
250 * These public functions more or less correspond to
251 * the public functions in SecPkcs12.h.
253 void P12Coder::setMacPassPhrase(
254 CFStringRef passphrase
)
256 CFRetain(passphrase
);
257 mMacPassphrase
= passphrase
;
260 void P12Coder::setEncrPassPhrase(
261 CFStringRef passphrase
)
263 CFRetain(passphrase
);
264 mEncrPassPhrase
= passphrase
;
267 void P12Coder::setMacPassKey(
268 const CSSM_KEY
*passKey
)
270 mMacPassKey
= passKey
;
273 void P12Coder::setEncrPassKey(
274 const CSSM_KEY
*passKey
)
276 mEncrPassKey
= passKey
;
280 unsigned P12Coder::numCerts()
282 return mCerts
.size();
285 unsigned P12Coder::numCrls()
290 unsigned P12Coder::numKeys()
295 unsigned P12Coder::numOpaqueBlobs()
297 return mOpaques
.size();
300 P12CertBag
*P12Coder::getCert(
303 if(mCerts
.size() < (dex
+ 1)) {
304 MacOSError::throwMe(paramErr
);
309 P12CrlBag
*P12Coder::getCrl(
312 if(mCrls
.size() < (dex
+ 1)) {
313 MacOSError::throwMe(paramErr
);
318 P12KeyBag
*P12Coder::getKey(
321 if(mKeys
.size() < (dex
+ 1)) {
322 MacOSError::throwMe(paramErr
);
327 P12OpaqueBag
*P12Coder::getOpaque(
330 if(mOpaques
.size() < (dex
+ 1)) {
331 MacOSError::throwMe(paramErr
);
333 return mOpaques
[dex
];
337 * These four "add" functions are invoked by the app prior to encoding
338 * and by our decoder while decoding.
340 void P12Coder::addCert(
343 mCerts
.push_back(cert
);
346 void P12Coder::addCrl(
349 mCrls
.push_back(crl
);
352 void P12Coder::addKey(
355 mKeys
.push_back(key
);
358 void P12Coder::addOpaque(
359 P12OpaqueBag
*opaque
)
361 mOpaques
.push_back(opaque
);
365 /* little known, but public, functions */
366 void P12Coder::integrityMode(
369 if(mode
!= kSecPkcs12ModePassword
) {
370 MacOSError::throwMe(paramErr
);
372 mIntegrityMode
= mode
;
375 void P12Coder::privacyMode(
378 if(mode
!= kSecPkcs12ModePassword
) {
379 MacOSError::throwMe(paramErr
);
384 CFDataRef
P12Coder::weakEncrAlg()
386 return p12CssmDataToCf(mWeakEncrAlg
);
389 CFDataRef
P12Coder::strongEncrAlg()
391 return p12CssmDataToCf(mStrongEncrAlg
);
394 void P12Coder::weakEncrAlg(
397 p12CfDataToCssm(alg
, mWeakEncrAlg
, mCoder
);
400 void P12Coder::strongEncrAlg(
403 p12CfDataToCssm(alg
, mStrongEncrAlg
, mCoder
);
406 void P12Coder::limitPrivKeyImport(
410 mPrivKeyImportState
= PKIS_NoMore
;
413 mPrivKeyImportState
= PKIS_AllowOne
;