1/* 2 * Copyright (c) 2003-2004 Apple Computer, 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 77class P12Coder { 78public: 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 197private: 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 420