]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_pkcs12/lib/pkcs12Coder.h
Security-59306.80.4.tar.gz
[apple/security.git] / OSX / libsecurity_pkcs12 / lib / pkcs12Coder.h
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.h - main PKCS12 encode/decode engine. This class
26 * corresponds to a SecPkcs12CoderRef in the public API.
27 */
28
29 #ifndef _PKCS12_CODER_H_
30 #define _PKCS12_CODER_H_
31
32 #include <security_pkcs12/SecPkcs12.h>
33 #include <security_pkcs12/pkcs12SafeBag.h>
34 #include <vector>
35
36 /*
37 * This class essentially consists of the following:
38 *
39 * -- bags of certs, CRLs, keys, and opaque blobs in the
40 * form of P12SafeBag subclasses.
41 *
42 * -- getters and setters to let the app access those bags.
43 *
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.
46 *
47 * -- an encode routine which takes the contents of the bag and
48 * creates an encoded PFX.
49 *
50 * Everything else is ephemera supporting the above four things.
51 *
52 * Memory usage:
53 * -------------
54 *
55 * Memory allocation is done in three flavors:
56 *
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
60 * API calls.
61 * 3. "Local" SecNssCoders for encode and decode. Allocated in the
62 * stack for those two exported functions and used for all decoding
63 * and encoding.
64 *
65 * The contents of the bags persist as long as an instance of
66 * P12Coder does.
67 *
68 * CF objects the app gives us (e..g, passphrases)
69 * are retained when get them and released in our destructor.
70 *
71 * CF objects we give the app are, of course, the app's responsibility.
72 *
73 * Everything else is allocd locally via the SecNssCoders in encode()
74 * and decode() and has a scope not exceeding those functions.
75 */
76
77 class P12Coder {
78 public:
79 /* only constructor */
80 P12Coder();
81 ~P12Coder();
82
83 /*
84 * These public functions more or less correspond to
85 * the public functions in SecPkcs12.h.
86 */
87 void setMacPassPhrase(
88 CFStringRef passphrase);
89 void setEncrPassPhrase(
90 CFStringRef passphrase);
91 void setMacPassKey(
92 const CSSM_KEY *passKey);
93 void setEncrPassKey(
94 const CSSM_KEY *passKey);
95
96 /* main decode function */
97 void decode(
98 CFDataRef pfx);
99
100 /*
101 * CSP and DLDB associated with keys.
102 * CSP handle is required, DLDB optional.
103 */
104 void setKeychain(
105 SecKeychainRef keychain);
106 void setCsp(
107 CSSM_CSP_HANDLE cspHand) { mCspHand = cspHand; }
108 void setDlDb(
109 CSSM_DL_DB_HANDLE dlDbHand) { mDlDbHand = dlDbHand; }
110
111 CSSM_CSP_HANDLE cspHand() { return mCspHand; }
112
113 /* private key import attributes */
114 void setAccess(
115 SecAccessRef access);
116 void setKeyUsage(
117 CSSM_KEYUSE keyUsage) { mKeyUsage = keyUsage; }
118 void setKeyAttrs(
119 CSSM_KEYATTR_FLAGS keyAttrs);
120
121 /* High-level import/export */
122 void importFlags(
123 SecPkcs12ImportFlags flags) { mImportFlags = flags; }
124 SecPkcs12ImportFlags importFlags()
125 { return mImportFlags; }
126
127 void exportKeychainItems(
128 CFArrayRef items);
129
130 /* getters */
131 unsigned numCerts();
132 unsigned numCrls();
133 unsigned numKeys();
134 unsigned numOpaqueBlobs();
135
136 P12CertBag *getCert(
137 unsigned dex);
138 P12CrlBag *getCrl(
139 unsigned dex);
140 P12KeyBag *getKey(
141 unsigned dex);
142 P12OpaqueBag *getOpaque(
143 unsigned dex);
144
145 /* encoding */
146 void encode(
147 CFDataRef *pfx); // RETURNED
148
149 void addCert(
150 P12CertBag *cert);
151 void addCrl(
152 P12CrlBag *crl);
153 void addKey(
154 P12KeyBag *key);
155 void addOpaque(
156 P12OpaqueBag *opaque);
157
158 /* little known, but public, functions */
159 SecPkcs12Mode integrityMode() { return mIntegrityMode; }
160 SecPkcs12Mode privacyMode() { return mPrivacyMode; }
161 void integrityMode(
162 SecPkcs12Mode mode);
163 void privacyMode(
164 SecPkcs12Mode mode);
165
166 /*
167 * Public API calls use our coder to create P12SafeBags
168 */
169 SecNssCoder &coder() { return mCoder; }
170
171 /* encryption parameter getters/setters */
172 unsigned weakEncrIterCount() { return mWeakEncrIterCount; }
173 unsigned strongEncrIterCount() { return mStrongEncrIterCount; }
174 unsigned macEncrIterCount() { return mMacIterCount; }
175
176 void weakEncrIterCount(
177 unsigned ic) { mWeakEncrIterCount = ic; }
178 void strongEncrIterCount(
179 unsigned ic) { mStrongEncrIterCount = ic; }
180 void macEncrIterCount(
181 unsigned ic) { mMacIterCount = ic; }
182
183 CFDataRef weakEncrAlg();
184 CFDataRef strongEncrAlg();
185
186 void weakEncrAlg(
187 CFDataRef alg);
188 void strongEncrAlg(
189 CFDataRef alg);
190
191 /* panic button, delete anything stored in a DB during decode */
192 void deleteDecodedItems();
193
194 void limitPrivKeyImport(
195 bool foundOneKey);
196
197 private:
198 void init(); // one-time init from all constructors
199
200 /*
201 * Passphrase handling.
202 *
203 * These two convert the app-supplied CFStringRefs into
204 * CSSM_DATAs; if PassKeys are used, these just NULL out
205 * the returned data.
206 */
207 const CSSM_DATA *getMacPassPhrase();
208 const CSSM_DATA *getEncrPassPhrase();
209
210 /*
211 * These return a CSSM_KEY_PTR is the app had specified
212 * PassKeys, else they return NULL.
213 */
214 const CSSM_KEY *getMacPassKey();
215 const CSSM_KEY *getEncrPassKey();
216
217 /* in pkcs12Keychain.cpp */
218 void storeDecodeResults();
219 void setPrivateKeyHashes();
220 void notifyKeyImport();
221 P12CertBag *findCertForKey(
222 P12KeyBag *keyBag);
223
224 void addSecKey(
225 SecKeyRef keyRef);
226 void addSecCert(
227 SecCertificateRef certRef);
228
229 /* Lazy evaluation of module handles. */
230 CSSM_CSP_HANDLE rawCspHand();
231 CSSM_CL_HANDLE clHand();
232
233 /*
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.
237 *
238 * See implementation for comments and descriptions.
239 */
240 void encryptedDataDecrypt(
241 const NSS_P7_EncryptedData &edata,
242 SecNssCoder &localCdr,
243 NSS_P12_PBE_Params *pbep,
244 CSSM_DATA &ptext);
245
246 void algIdParse(
247 const CSSM_X509_ALGORITHM_IDENTIFIER &algId,
248 NSS_P12_PBE_Params *pbeParams,
249 SecNssCoder &localCdr);
250
251 void encryptedDataParse(
252 const NSS_P7_EncryptedData &edata,
253 SecNssCoder &localCdr,
254 NSS_P12_PBE_Params *pbep);
255
256 void shroudedKeyBagParse(
257 const NSS_P12_SafeBag &safeBag,
258 SecNssCoder &localCdr);
259
260 void keyBagParse(
261 const NSS_P12_SafeBag &safeBag,
262 SecNssCoder &localCdr);
263
264 void certBagParse(
265 const NSS_P12_SafeBag &safeBag,
266 SecNssCoder &localCdr);
267
268 void crlBagParse(
269 const NSS_P12_SafeBag &safeBag,
270 SecNssCoder &localCdr);
271
272 void secretBagParse(
273 const NSS_P12_SafeBag &safeBag,
274 SecNssCoder &localCdr);
275
276 void safeContentsBagParse(
277 const NSS_P12_SafeBag &safeBag,
278 SecNssCoder &localCdr);
279
280 void safeContentsParse(
281 const CSSM_DATA &contentsBlob,
282 SecNssCoder &localCdr);
283
284 void authSafeElementParse(
285 const NSS_P7_DecodedContentInfo *info,
286 SecNssCoder &localCdr);
287
288 void macParse(
289 const NSS_P12_MacData &macData,
290 SecNssCoder &localCdr);
291
292 void authSafeParse(
293 const CSSM_DATA &authSafeBlob,
294 SecNssCoder &localCdr);
295
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);
303
304 void authSafeBuild(
305 NSS_P7_DecodedContentInfo &authSafe,
306 SecNssCoder &localCdr);
307
308 void encryptData(
309 const CSSM_DATA &ptext,
310 CSSM_OID &encrOid,
311 unsigned iterCount,
312 NSS_P7_EncryptedData &ed,
313 SecNssCoder &localCdr);
314
315 void algIdBuild(
316 CSSM_X509_ALGORITHM_IDENTIFIER &algId,
317 const CSSM_OID &algOid,
318 const CSSM_DATA &salt,
319 unsigned iterCount,
320 SecNssCoder &localCdr);
321
322 void macSignPfx(
323 NSS_P12_DecodedPFX &pfx,
324 SecNssCoder &localCdr);
325
326 NSS_P12_SafeBag *certBagBuild(
327 P12CertBag *cert,
328 SecNssCoder &localCdr);
329
330 NSS_P12_SafeBag *crlBagBuild(
331 P12CrlBag *crl,
332 SecNssCoder &localCdr);
333
334 NSS_P12_SafeBag *keyBagBuild(
335 P12KeyBag *key,
336 SecNssCoder &localCdr);
337
338 NSS_P12_SafeBag *opaqueBagBuild(
339 P12OpaqueBag *op,
340 SecNssCoder &localCdr);
341
342 /* member variables */
343 SecPkcs12Mode mPrivacyMode;
344 SecPkcs12Mode mIntegrityMode;
345
346 /* passwords - as app gave us, and translated into ready-to-use
347 * unicode strings */
348 CFStringRef mMacPassphrase;
349 CFStringRef mEncrPassPhrase;
350 CSSM_DATA mMacPassData;
351 CSSM_DATA mEncrPassData;
352
353 /* passphrases in key form */
354 const CSSM_KEY *mMacPassKey;
355 const CSSM_KEY *mEncrPassKey;
356
357 /*
358 * App has to either set mKeychain or mCspHand. In the former
359 * case we infer both mCspHand and mDlDbHand from the keychainRef.
360 */
361 SecKeychainRef mKeychain;
362 CSSM_CSP_HANDLE mCspHand;
363 CSSM_DL_DB_HANDLE mDlDbHand;
364
365 /*
366 * LimitPrivateKeyImport mechanism
367 */
368 typedef enum {
369 PKIS_NoLimit, // no limit
370 PKIS_AllowOne, // allow import of at most one
371 PKIS_NoMore // found one, no more allowed
372 } p12PrivKeyImportState;
373
374 p12PrivKeyImportState mPrivKeyImportState;
375
376 /*
377 * Encryption/MAC parameters
378 */
379 CSSM_OID mWeakEncrAlg; // for certs and CRLs
380 CSSM_OID mStrongEncrAlg;
381 unsigned mWeakEncrIterCount;
382 unsigned mStrongEncrIterCount;
383 unsigned mMacIterCount;
384
385 /*
386 * Import flags
387 */
388 SecPkcs12ImportFlags mImportFlags;
389
390 /*
391 * Four individual piles of safe bags
392 */
393 vector<P12CertBag *> mCerts;
394 vector<P12CrlBag *> mCrls;
395 vector<P12KeyBag *> mKeys;
396 vector<P12OpaqueBag *> mOpaques;
397
398 /*
399 * Internal CSSM module handles, lazily evaluated.
400 */
401 CSSM_CSP_HANDLE mRawCspHand;
402 CSSM_CL_HANDLE mClHand;
403
404 /*
405 * Imported private key attributes
406 */
407 SecAccessRef mAccess;
408 bool mNoAcl; /* true when NULL passed to setAccess() */
409 CSSM_KEYUSE mKeyUsage;
410 CSSM_KEYATTR_FLAGS mKeyAttrs;
411
412 /*
413 * The source of most (all?) of our privately allocated data
414 */
415 SecNssCoder mCoder;
416 };
417
418 #endif /* _PKCS12_CODER_H_ */
419