2 * Copyright (c) 2003-2004,2011,2014 Apple 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.h - main PKCS12 encode/decode engine. This class
26 * corresponds to a SecPkcs12CoderRef in the public API.
29 #ifndef _PKCS12_CODER_H_
30 #define _PKCS12_CODER_H_
32 #include <security_pkcs12/SecPkcs12.h>
33 #include <security_pkcs12/pkcs12SafeBag.h>
37 * This class essentially consists of the following:
39 * -- bags of certs, CRLs, keys, and opaque blobs in the
40 * form of P12SafeBag subclasses.
42 * -- getters and setters to let the app access those bags.
44 * -- a decode routine which takes an encoded PFX, rips it apart,
45 * and drops what it finds into the bags of cert, CRLS, etc.
47 * -- an encode routine which takes the contents of the bag and
48 * creates an encoded PFX.
50 * Everything else is ephemera supporting the above four things.
55 * Memory allocation is done in three flavors:
57 * 1. Via CF objects, when exporting contents of bags to the app.
58 * 2. Via our own member variable SecNssCoder. This is used to allocate
59 * the contents of the bags (certs, etc.) which persist across
61 * 3. "Local" SecNssCoders for encode and decode. Allocated in the
62 * stack for those two exported functions and used for all decoding
65 * The contents of the bags persist as long as an instance of
68 * CF objects the app gives us (e..g, passphrases)
69 * are retained when get them and released in our destructor.
71 * CF objects we give the app are, of course, the app's responsibility.
73 * Everything else is allocd locally via the SecNssCoders in encode()
74 * and decode() and has a scope not exceeding those functions.
79 /* only constructor */
84 * These public functions more or less correspond to
85 * the public functions in SecPkcs12.h.
87 void setMacPassPhrase(
88 CFStringRef passphrase
);
89 void setEncrPassPhrase(
90 CFStringRef passphrase
);
92 const CSSM_KEY
*passKey
);
94 const CSSM_KEY
*passKey
);
96 /* main decode function */
101 * CSP and DLDB associated with keys.
102 * CSP handle is required, DLDB optional.
105 SecKeychainRef keychain
);
107 CSSM_CSP_HANDLE cspHand
) { mCspHand
= cspHand
; }
109 CSSM_DL_DB_HANDLE dlDbHand
) { mDlDbHand
= dlDbHand
; }
111 CSSM_CSP_HANDLE
cspHand() { return mCspHand
; }
113 /* private key import attributes */
115 SecAccessRef access
);
117 CSSM_KEYUSE keyUsage
) { mKeyUsage
= keyUsage
; }
119 CSSM_KEYATTR_FLAGS keyAttrs
);
121 /* High-level import/export */
123 SecPkcs12ImportFlags flags
) { mImportFlags
= flags
; }
124 SecPkcs12ImportFlags
importFlags()
125 { return mImportFlags
; }
127 void exportKeychainItems(
134 unsigned numOpaqueBlobs();
142 P12OpaqueBag
*getOpaque(
147 CFDataRef
*pfx
); // RETURNED
156 P12OpaqueBag
*opaque
);
158 /* little known, but public, functions */
159 SecPkcs12Mode
integrityMode() { return mIntegrityMode
; }
160 SecPkcs12Mode
privacyMode() { return mPrivacyMode
; }
167 * Public API calls use our coder to create P12SafeBags
169 SecNssCoder
&coder() { return mCoder
; }
171 /* encryption parameter getters/setters */
172 unsigned weakEncrIterCount() { return mWeakEncrIterCount
; }
173 unsigned strongEncrIterCount() { return mStrongEncrIterCount
; }
174 unsigned macEncrIterCount() { return mMacIterCount
; }
176 void weakEncrIterCount(
177 unsigned ic
) { mWeakEncrIterCount
= ic
; }
178 void strongEncrIterCount(
179 unsigned ic
) { mStrongEncrIterCount
= ic
; }
180 void macEncrIterCount(
181 unsigned ic
) { mMacIterCount
= ic
; }
183 CFDataRef
weakEncrAlg();
184 CFDataRef
strongEncrAlg();
191 /* panic button, delete anything stored in a DB during decode */
192 void deleteDecodedItems();
194 void limitPrivKeyImport(
198 void init(); // one-time init from all constructors
201 * Passphrase handling.
203 * These two convert the app-supplied CFStringRefs into
204 * CSSM_DATAs; if PassKeys are used, these just NULL out
207 const CSSM_DATA
*getMacPassPhrase();
208 const CSSM_DATA
*getEncrPassPhrase();
211 * These return a CSSM_KEY_PTR is the app had specified
212 * PassKeys, else they return NULL.
214 const CSSM_KEY
*getMacPassKey();
215 const CSSM_KEY
*getEncrPassKey();
217 /* in pkcs12Keychain.cpp */
218 void storeDecodeResults();
219 void setPrivateKeyHashes();
220 void notifyKeyImport();
221 P12CertBag
*findCertForKey(
227 SecCertificateRef certRef
);
229 /* Lazy evaluation of module handles. */
230 CSSM_CSP_HANDLE
rawCspHand();
231 CSSM_CL_HANDLE
clHand();
234 * A bunch of private encode/decode methods. This makes me
235 * long for ObjC-style categories so these would not
236 * have to appear in this file.
238 * See implementation for comments and descriptions.
240 void encryptedDataDecrypt(
241 const NSS_P7_EncryptedData
&edata
,
242 SecNssCoder
&localCdr
,
243 NSS_P12_PBE_Params
*pbep
,
247 const CSSM_X509_ALGORITHM_IDENTIFIER
&algId
,
248 NSS_P12_PBE_Params
*pbeParams
,
249 SecNssCoder
&localCdr
);
251 void encryptedDataParse(
252 const NSS_P7_EncryptedData
&edata
,
253 SecNssCoder
&localCdr
,
254 NSS_P12_PBE_Params
*pbep
);
256 void shroudedKeyBagParse(
257 const NSS_P12_SafeBag
&safeBag
,
258 SecNssCoder
&localCdr
);
261 const NSS_P12_SafeBag
&safeBag
,
262 SecNssCoder
&localCdr
);
265 const NSS_P12_SafeBag
&safeBag
,
266 SecNssCoder
&localCdr
);
269 const NSS_P12_SafeBag
&safeBag
,
270 SecNssCoder
&localCdr
);
273 const NSS_P12_SafeBag
&safeBag
,
274 SecNssCoder
&localCdr
);
276 void safeContentsBagParse(
277 const NSS_P12_SafeBag
&safeBag
,
278 SecNssCoder
&localCdr
);
280 void safeContentsParse(
281 const CSSM_DATA
&contentsBlob
,
282 SecNssCoder
&localCdr
);
284 void authSafeElementParse(
285 const NSS_P7_DecodedContentInfo
*info
,
286 SecNssCoder
&localCdr
);
289 const NSS_P12_MacData
&macData
,
290 SecNssCoder
&localCdr
);
293 const CSSM_DATA
&authSafeBlob
,
294 SecNssCoder
&localCdr
);
296 /* private encoding routines */
297 NSS_P7_DecodedContentInfo
*safeContentsBuild(
298 NSS_P12_SafeBag
**bags
,
299 NSS_P7_CI_Type type
, // CT_Data, CT_EncryptedData
300 CSSM_OID
*encrOid
, // only for CT_EncryptedData
301 unsigned iterCount
, // ditto
302 SecNssCoder
&localCdr
);
305 NSS_P7_DecodedContentInfo
&authSafe
,
306 SecNssCoder
&localCdr
);
309 const CSSM_DATA
&ptext
,
312 NSS_P7_EncryptedData
&ed
,
313 SecNssCoder
&localCdr
);
316 CSSM_X509_ALGORITHM_IDENTIFIER
&algId
,
317 const CSSM_OID
&algOid
,
318 const CSSM_DATA
&salt
,
320 SecNssCoder
&localCdr
);
323 NSS_P12_DecodedPFX
&pfx
,
324 SecNssCoder
&localCdr
);
326 NSS_P12_SafeBag
*certBagBuild(
328 SecNssCoder
&localCdr
);
330 NSS_P12_SafeBag
*crlBagBuild(
332 SecNssCoder
&localCdr
);
334 NSS_P12_SafeBag
*keyBagBuild(
336 SecNssCoder
&localCdr
);
338 NSS_P12_SafeBag
*opaqueBagBuild(
340 SecNssCoder
&localCdr
);
342 /* member variables */
343 SecPkcs12Mode mPrivacyMode
;
344 SecPkcs12Mode mIntegrityMode
;
346 /* passwords - as app gave us, and translated into ready-to-use
348 CFStringRef mMacPassphrase
;
349 CFStringRef mEncrPassPhrase
;
350 CSSM_DATA mMacPassData
;
351 CSSM_DATA mEncrPassData
;
353 /* passphrases in key form */
354 const CSSM_KEY
*mMacPassKey
;
355 const CSSM_KEY
*mEncrPassKey
;
358 * App has to either set mKeychain or mCspHand. In the former
359 * case we infer both mCspHand and mDlDbHand from the keychainRef.
361 SecKeychainRef mKeychain
;
362 CSSM_CSP_HANDLE mCspHand
;
363 CSSM_DL_DB_HANDLE mDlDbHand
;
366 * LimitPrivateKeyImport mechanism
369 PKIS_NoLimit
, // no limit
370 PKIS_AllowOne
, // allow import of at most one
371 PKIS_NoMore
// found one, no more allowed
372 } p12PrivKeyImportState
;
374 p12PrivKeyImportState mPrivKeyImportState
;
377 * Encryption/MAC parameters
379 CSSM_OID mWeakEncrAlg
; // for certs and CRLs
380 CSSM_OID mStrongEncrAlg
;
381 unsigned mWeakEncrIterCount
;
382 unsigned mStrongEncrIterCount
;
383 unsigned mMacIterCount
;
388 SecPkcs12ImportFlags mImportFlags
;
391 * Four individual piles of safe bags
393 vector
<P12CertBag
*> mCerts
;
394 vector
<P12CrlBag
*> mCrls
;
395 vector
<P12KeyBag
*> mKeys
;
396 vector
<P12OpaqueBag
*> mOpaques
;
399 * Internal CSSM module handles, lazily evaluated.
401 CSSM_CSP_HANDLE mRawCspHand
;
402 CSSM_CL_HANDLE mClHand
;
405 * Imported private key attributes
407 SecAccessRef mAccess
;
408 bool mNoAcl
; /* true when NULL passed to setAccess() */
409 CSSM_KEYUSE mKeyUsage
;
410 CSSM_KEYATTR_FLAGS mKeyAttrs
;
413 * The source of most (all?) of our privately allocated data
418 #endif /* _PKCS12_CODER_H_ */