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 <Security/oidsalg.h>
34 #include <Security/SecBase.h>
36 * Default encryption parameters
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
44 * Default import flags.
46 #define P12_KC_IMPORT_DEFAULT (kSecImportCertificates | \
55 /* one-time init from all constructors */
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;
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
;
83 mKeyUsage
= CSSM_KEYUSE_ANY
; /* default */
84 /* default key attrs; we add CSSM_KEYATTR_PERMANENT if importing to
86 mKeyAttrs
= CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_EXTRACTABLE
|
87 CSSM_KEYATTR_SENSITIVE
;
91 * FIXME - can't we get vector's destructor to do this?
93 #define deleteVect(v) \
102 P12Coder::~P12Coder()
105 CFRelease(mMacPassphrase
);
107 if(mEncrPassPhrase
) {
108 CFRelease(mEncrPassPhrase
);
116 deleteVect(mOpaques
);
119 CFRelease(mKeychain
);
122 cuCspDetachUnload(mRawCspHand
, CSSM_TRUE
);
125 cuClDetachUnload(mClHand
);
129 void P12Coder::setKeychain(
130 SecKeychainRef keychain
)
132 OSStatus ortn
= SecKeychainGetCSPHandle(keychain
, &mCspHand
);
134 MacOSError::throwMe(ortn
);
136 ortn
= SecKeychainGetDLDBHandle(keychain
, &mDlDbHand
);
138 MacOSError::throwMe(ortn
);
141 mKeychain
= keychain
;
144 void P12Coder::setAccess(
155 /* NULL ==> no ACL */
160 #define SEC_KEYATTR_RETURN_MASK \
161 (CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_RETURN_NONE)
163 void P12Coder::setKeyAttrs(
164 CSSM_KEYATTR_FLAGS keyAttrs
)
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
;
173 * Private methods for obtaining passprases in CSSM_DATA form.
175 const CSSM_DATA
*P12Coder::getMacPassPhrase()
177 if(mMacPassData
.Data
!= NULL
) {
178 return &mMacPassData
;
180 else if (mMacPassphrase
) {
181 p12ImportPassPhrase(mMacPassphrase
, mCoder
, mMacPassData
);
182 return &mMacPassData
;
189 const CSSM_DATA
*P12Coder::getEncrPassPhrase()
191 if(mEncrPassData
.Data
!= NULL
) {
192 return &mEncrPassData
;
194 else if (mEncrPassPhrase
) {
195 p12ImportPassPhrase(mEncrPassPhrase
, mCoder
, mEncrPassData
);
196 return &mEncrPassData
;
198 /* no separate passphrase found, use MAC passphrase */
199 return getMacPassPhrase();
203 * These return a CSSM_KEY_PTR is the app had specified
204 * PassKeys, else they return NULL.
206 const CSSM_KEY
*P12Coder::getMacPassKey()
211 const CSSM_KEY
*P12Coder::getEncrPassKey()
213 if(mEncrPassKey
!= NULL
) {
217 return getMacPassKey();
222 * Lazy evaluation of module handles.
224 CSSM_CSP_HANDLE
P12Coder::rawCspHand()
226 if(mRawCspHand
!= 0) {
229 mRawCspHand
= cuCspStartup(CSSM_TRUE
);
230 if(mRawCspHand
== 0) {
231 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
236 CSSM_CL_HANDLE
P12Coder::clHand()
241 mClHand
= cuClStartup();
243 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
249 * These public functions more or less correspond to
250 * the public functions in SecPkcs12.h.
252 void P12Coder::setMacPassPhrase(
253 CFStringRef passphrase
)
255 CFRetain(passphrase
);
256 mMacPassphrase
= passphrase
;
259 void P12Coder::setEncrPassPhrase(
260 CFStringRef passphrase
)
262 CFRetain(passphrase
);
263 mEncrPassPhrase
= passphrase
;
266 void P12Coder::setMacPassKey(
267 const CSSM_KEY
*passKey
)
269 mMacPassKey
= passKey
;
272 void P12Coder::setEncrPassKey(
273 const CSSM_KEY
*passKey
)
275 mEncrPassKey
= passKey
;
279 unsigned P12Coder::numCerts()
281 return (unsigned)mCerts
.size();
284 unsigned P12Coder::numCrls()
286 return (unsigned)mCrls
.size();
289 unsigned P12Coder::numKeys()
291 return (unsigned)mKeys
.size();
294 unsigned P12Coder::numOpaqueBlobs()
296 return (unsigned)mOpaques
.size();
299 P12CertBag
*P12Coder::getCert(
302 if(mCerts
.size() < (dex
+ 1)) {
303 MacOSError::throwMe(errSecParam
);
308 P12CrlBag
*P12Coder::getCrl(
311 if(mCrls
.size() < (dex
+ 1)) {
312 MacOSError::throwMe(errSecParam
);
317 P12KeyBag
*P12Coder::getKey(
320 if(mKeys
.size() < (dex
+ 1)) {
321 MacOSError::throwMe(errSecParam
);
326 P12OpaqueBag
*P12Coder::getOpaque(
329 if(mOpaques
.size() < (dex
+ 1)) {
330 MacOSError::throwMe(errSecParam
);
332 return mOpaques
[dex
];
336 * These four "add" functions are invoked by the app prior to encoding
337 * and by our decoder while decoding.
339 void P12Coder::addCert(
342 mCerts
.push_back(cert
);
345 void P12Coder::addCrl(
348 mCrls
.push_back(crl
);
351 void P12Coder::addKey(
354 mKeys
.push_back(key
);
357 void P12Coder::addOpaque(
358 P12OpaqueBag
*opaque
)
360 mOpaques
.push_back(opaque
);
364 /* little known, but public, functions */
365 void P12Coder::integrityMode(
368 if(mode
!= kSecPkcs12ModePassword
) {
369 MacOSError::throwMe(errSecParam
);
371 mIntegrityMode
= mode
;
374 void P12Coder::privacyMode(
377 if(mode
!= kSecPkcs12ModePassword
) {
378 MacOSError::throwMe(errSecParam
);
383 CFDataRef
P12Coder::weakEncrAlg()
385 return p12CssmDataToCf(mWeakEncrAlg
);
388 CFDataRef
P12Coder::strongEncrAlg()
390 return p12CssmDataToCf(mStrongEncrAlg
);
393 void P12Coder::weakEncrAlg(
396 p12CfDataToCssm(alg
, mWeakEncrAlg
, mCoder
);
399 void P12Coder::strongEncrAlg(
402 p12CfDataToCssm(alg
, mStrongEncrAlg
, mCoder
);
405 void P12Coder::limitPrivKeyImport(
409 mPrivKeyImportState
= PKIS_NoMore
;
412 mPrivKeyImportState
= PKIS_AllowOne
;