]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_pkcs12/lib/pkcs12Coder.cpp
Security-57337.50.23.tar.gz
[apple/security.git] / OSX / libsecurity_pkcs12 / lib / pkcs12Coder.cpp
CommitLineData
b1ab9ed8 1/*
d8f41ccd 2 * Copyright (c) 2003-2004,2011-2014 Apple Inc. All Rights Reserved.
b1ab9ed8
A
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>
b1ab9ed8 33#include <Security/oidsalg.h>
427c49bc 34#include <Security/SecBase.h>
b1ab9ed8
A
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
50P12Coder::P12Coder()
51{
52 init();
53}
54
55/* one-time init from all constructors */
56void 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
102P12Coder::~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
129void 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
144void 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
163void 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 */
175const 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
189const 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 */
206const CSSM_KEY *P12Coder::getMacPassKey()
207{
208 return mMacPassKey;
209}
210
211const 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 */
224CSSM_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
236CSSM_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 */
252void P12Coder::setMacPassPhrase(
253 CFStringRef passphrase)
254{
255 CFRetain(passphrase);
256 mMacPassphrase = passphrase;
257}
258
259void P12Coder::setEncrPassPhrase(
260 CFStringRef passphrase)
261{
262 CFRetain(passphrase);
263 mEncrPassPhrase = passphrase;
264}
265
266void P12Coder::setMacPassKey(
267 const CSSM_KEY *passKey)
268{
269 mMacPassKey = passKey;
270}
271
272void P12Coder::setEncrPassKey(
273 const CSSM_KEY *passKey)
274{
275 mEncrPassKey = passKey;
276}
277
278/* getters */
279unsigned P12Coder::numCerts()
280{
427c49bc 281 return (unsigned)mCerts.size();
b1ab9ed8
A
282}
283
284unsigned P12Coder::numCrls()
285{
427c49bc 286 return (unsigned)mCrls.size();
b1ab9ed8
A
287}
288
289unsigned P12Coder::numKeys()
290{
427c49bc 291 return (unsigned)mKeys.size();
b1ab9ed8
A
292}
293
294unsigned P12Coder::numOpaqueBlobs()
295{
427c49bc 296 return (unsigned)mOpaques.size();
b1ab9ed8
A
297}
298
299P12CertBag *P12Coder::getCert(
300 unsigned dex)
301{
302 if(mCerts.size() < (dex + 1)) {
427c49bc 303 MacOSError::throwMe(errSecParam);
b1ab9ed8
A
304 }
305 return mCerts[dex];
306}
307
308P12CrlBag *P12Coder::getCrl(
309 unsigned dex)
310{
311 if(mCrls.size() < (dex + 1)) {
427c49bc 312 MacOSError::throwMe(errSecParam);
b1ab9ed8
A
313 }
314 return mCrls[dex];
315}
316
317P12KeyBag *P12Coder::getKey(
318 unsigned dex)
319{
320 if(mKeys.size() < (dex + 1)) {
427c49bc 321 MacOSError::throwMe(errSecParam);
b1ab9ed8
A
322 }
323 return mKeys[dex];
324}
325
326P12OpaqueBag *P12Coder::getOpaque(
327 unsigned dex)
328{
329 if(mOpaques.size() < (dex + 1)) {
427c49bc 330 MacOSError::throwMe(errSecParam);
b1ab9ed8
A
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 */
339void P12Coder::addCert(
340 P12CertBag *cert)
341{
342 mCerts.push_back(cert);
343}
344
345void P12Coder::addCrl(
346 P12CrlBag *crl)
347{
348 mCrls.push_back(crl);
349}
350
351void P12Coder::addKey(
352 P12KeyBag *key)
353{
354 mKeys.push_back(key);
355}
356
357void P12Coder::addOpaque(
358 P12OpaqueBag *opaque)
359{
360 mOpaques.push_back(opaque);
361}
362
363
364/* little known, but public, functions */
365void P12Coder::integrityMode(
366 SecPkcs12Mode mode)
367{
368 if(mode != kSecPkcs12ModePassword) {
427c49bc 369 MacOSError::throwMe(errSecParam);
b1ab9ed8
A
370 }
371 mIntegrityMode = mode;
372}
373
374void P12Coder::privacyMode(
375 SecPkcs12Mode mode)
376{
377 if(mode != kSecPkcs12ModePassword) {
427c49bc 378 MacOSError::throwMe(errSecParam);
b1ab9ed8
A
379 }
380 mPrivacyMode = mode;
381}
382
383CFDataRef P12Coder::weakEncrAlg()
384{
385 return p12CssmDataToCf(mWeakEncrAlg);
386}
387
388CFDataRef P12Coder::strongEncrAlg()
389{
390 return p12CssmDataToCf(mStrongEncrAlg);
391}
392
393void P12Coder::weakEncrAlg(
394 CFDataRef alg)
395{
396 p12CfDataToCssm(alg, mWeakEncrAlg, mCoder);
397}
398
399void P12Coder::strongEncrAlg(
400 CFDataRef alg)
401{
402 p12CfDataToCssm(alg, mStrongEncrAlg, mCoder);
403}
404
405void P12Coder::limitPrivKeyImport(
406 bool foundOneKey)
407{
408 if(foundOneKey) {
409 mPrivKeyImportState = PKIS_NoMore;
410 }
411 else {
412 mPrivKeyImportState = PKIS_AllowOne;
413 }
414}