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@
27 #include "SecPkcs12.h"
28 #include "pkcs12Coder.h"
29 #include "pkcs12BagAttrs.h"
30 #include "pkcs12SafeBag.h"
31 #include "pkcs12Utils.h"
32 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
33 #include <security_cdsa_utilities/cssmerrors.h>
34 #include <Security/SecBasePriv.h>
37 * API function call wrappers, impermeable to C++ exceptions
39 #define BEGIN_P12API \
44 catch (const MacOSError &err) { return err.osStatus(); } \
45 catch (const CommonError &err) { return SecKeychainErrFromOSStatus(err.osStatus()); } \
46 catch (const std::bad_alloc &) { return memFullErr; } \
47 catch (...) { return internalComponentErr; } \
50 /* catch incoming NULL parameters */
51 static inline void required(
55 MacOSError::throwMe(paramErr
);
60 * Standard means of casting a SecPkcs12CoderRef to a P12Coder *
62 static inline P12Coder
*P12CoderCast(
63 SecPkcs12CoderRef coder
)
66 return reinterpret_cast<P12Coder
*>(coder
);
70 * Standard means of casting a SecPkcs12AttrsRef to a P12BagAttrs *
71 * This one uses the P12BagAttrsStandAlone version, not tied to
72 * a specific P12Coder (actually, to a P12Coder's SecNssCoder).
74 static inline P12BagAttrsStandAlone
*P12AttrsCast(
75 SecPkcs12AttrsRef attrs
)
78 MacOSError::throwMe(paramErr
);
80 return reinterpret_cast<P12BagAttrsStandAlone
*>(attrs
);
83 /* optional flavor used in SecPkcs12Add*() */
84 static inline P12BagAttrs
*P12AttrsCastOpt(
85 SecPkcs12AttrsRef attrs
)
87 return reinterpret_cast<P12BagAttrs
*>(attrs
);
90 #pragma mark --- SecPkcs12CoderRef create/destroy ---
93 * Basic SecPkcs12CoderRef create/destroy.
95 OSStatus
SecPkcs12CoderCreate(
96 SecPkcs12CoderRef
*coder
) // RETURNED
101 P12Coder
*p12coder
= new P12Coder
;
108 * Destroy object created in SecPkcs12CoderCreate.
109 * This will go away if we make this object a CoreFoundation type.
111 OSStatus
SecPkcs12CoderRelease(
112 SecPkcs12CoderRef coder
)
116 P12Coder
*p12coder
= P12CoderCast(coder
);
122 OSStatus
SecPkcs12SetMACPassphrase(
123 SecPkcs12CoderRef coder
,
124 CFStringRef passphrase
)
128 P12Coder
*p12coder
= P12CoderCast(coder
);
129 required(passphrase
);
130 p12coder
->setMacPassPhrase(passphrase
);
135 OSStatus
SecPkcs12SetMACPassKey(
136 SecPkcs12CoderRef coder
,
137 const CSSM_KEY
*passKey
)
141 P12Coder
*p12coder
= P12CoderCast(coder
);
143 p12coder
->setMacPassKey(passKey
);
149 * Specify separate passphrase for encrypt/decrypt.
151 OSStatus
SecPkcs12SetCryptPassphrase(
152 SecPkcs12CoderRef coder
,
153 CFStringRef passphrase
)
157 P12Coder
*p12coder
= P12CoderCast(coder
);
158 required(passphrase
);
159 p12coder
->setEncrPassPhrase(passphrase
);
164 OSStatus
SecPkcs12SetCryptPassKey(
165 SecPkcs12CoderRef coder
,
166 const CSSM_KEY
*passKey
)
170 P12Coder
*p12coder
= P12CoderCast(coder
);
172 p12coder
->setEncrPassKey(passKey
);
179 * Target location of decoded keys and certs.
181 OSStatus
SecPkcs12SetKeychain(
182 SecPkcs12CoderRef coder
,
183 SecKeychainRef keychain
)
187 P12Coder
*p12coder
= P12CoderCast(coder
);
189 p12coder
->setKeychain(keychain
);
195 * Required iff SecPkcs12SetKeychain() not called.
197 OSStatus
SecPkcs12SetCspHandle(
198 SecPkcs12CoderRef coder
,
199 CSSM_CSP_HANDLE cspHandle
)
203 P12Coder
*p12coder
= P12CoderCast(coder
);
204 p12coder
->setCsp(cspHandle
);
209 OSStatus
SecPkcs12SetImportToKeychain(
210 SecPkcs12CoderRef coder
,
211 SecPkcs12ImportFlags flags
)
215 P12Coder
*p12coder
= P12CoderCast(coder
);
216 p12coder
->importFlags(flags
);
221 OSStatus
SecPkcs12GetImportToKeychain(
222 SecPkcs12CoderRef coder
,
223 SecPkcs12ImportFlags
*flags
) // RETURNED
227 P12Coder
*p12coder
= P12CoderCast(coder
);
229 *flags
= p12coder
->importFlags();
234 OSStatus
SecPkcs12ExportKeychainItems(
235 SecPkcs12CoderRef coder
,
240 P12Coder
*p12coder
= P12CoderCast(coder
);
242 p12coder
->exportKeychainItems(items
);
247 OSStatus
SecPkcs12SetAccess(
248 SecPkcs12CoderRef coder
,
253 P12Coder
*p12coder
= P12CoderCast(coder
);
254 p12coder
->setAccess(access
);
259 OSStatus
SecPkcs12SetKeyUsage(
260 SecPkcs12CoderRef coder
,
261 CSSM_KEYUSE keyUsage
)
265 P12Coder
*p12coder
= P12CoderCast(coder
);
266 p12coder
->setKeyUsage(keyUsage
);
271 OSStatus
SecPkcs12SetKeyAttrs(
272 SecPkcs12CoderRef coder
,
273 CSSM_KEYATTR_FLAGS keyAttrs
)
277 P12Coder
*p12coder
= P12CoderCast(coder
);
278 p12coder
->setKeyAttrs(keyAttrs
);
283 #pragma mark --- Decoder Functions ---
288 OSStatus
SecPkcs12Decode(
289 SecPkcs12CoderRef coder
,
294 P12Coder
*p12coder
= P12CoderCast(coder
);
297 p12coder
->decode(pfx
);
300 /* abort - clean up - delete stored keys */
301 p12coder
->deleteDecodedItems();
308 * Subsequent to decoding, obtain the components.
309 * These functions can also be used as "getter" functions while encoding.
313 OSStatus
SecPkcs12CertificateCount(
314 SecPkcs12CoderRef coder
,
315 CFIndex
*numCerts
) // RETURNED
319 P12Coder
*p12coder
= P12CoderCast(coder
);
321 *numCerts
= p12coder
->numCerts();
326 OSStatus
SecPkcs12CopyCertificate(
327 SecPkcs12CoderRef coder
,
329 SecCertificateRef
*secCert
, // RETURNED
330 CFStringRef
*friendlyName
, // RETURNED
331 CFDataRef
*localKeyId
, // RETURNED
332 SecPkcs12AttrsRef
*attrs
) // RETURNED
336 P12Coder
*p12coder
= P12CoderCast(coder
);
338 /* others are optional - if NULL, we don't return that param */
339 P12CertBag
*bag
= p12coder
->getCert(certNum
);
340 *secCert
= bag
->getSecCert();
342 /* now the optional attrs */
343 P12BagAttrs
*p12Attrs
= NULL
;
344 bag
->copyAllAttrs(friendlyName
, localKeyId
,
345 attrs
? &p12Attrs
: NULL
);
353 * CRLs. The might change if a SecCrl type is defined elsewhere.
354 * We'll typedef it here to preserve the semantics of this function.
356 OSStatus
SecPkcs12CrlCount(
357 SecPkcs12CoderRef coder
,
358 CFIndex
*numCrls
) // RETURNED
362 P12Coder
*p12coder
= P12CoderCast(coder
);
364 *numCrls
= p12coder
->numCrls();
369 OSStatus
SecPkcs12CopyCrl(
370 SecPkcs12CoderRef coder
,
372 SecCrlRef
*crl
, // RETURNED
373 CFStringRef
*friendlyName
, // RETURNED
374 CFDataRef
*localKeyId
, // RETURNED
375 SecPkcs12AttrsRef
*attrs
) // RETURNED
379 P12Coder
*p12coder
= P12CoderCast(coder
);
381 /* others are optional - if NULL, we don't return that param */
382 P12CrlBag
*bag
= p12coder
->getCrl(crlNum
);
383 *crl
= p12CssmDataToCf(bag
->crlData());
385 /* now the optional attrs */
386 P12BagAttrs
*p12Attrs
= NULL
;
387 bag
->copyAllAttrs(friendlyName
, localKeyId
,
388 attrs
? &p12Attrs
: NULL
);
399 OSStatus
SecPkcs12PrivateKeyCount(
400 SecPkcs12CoderRef coder
,
401 CFIndex
*numKeys
) // RETURNED
405 P12Coder
*p12coder
= P12CoderCast(coder
);
407 *numKeys
= p12coder
->numKeys();
412 OSStatus
SecPkcs12CopyPrivateKey(
413 SecPkcs12CoderRef coder
,
415 SecKeyRef
*privateKey
, // RETURNED
416 CFStringRef
*friendlyName
, // RETURNED
417 CFDataRef
*localKeyId
, // RETURNED
418 SecPkcs12AttrsRef
*attrs
) // RETURNED
421 /*P12Coder *p12coder = P12CoderCast(coder); */
426 OSStatus
SecPkcs12GetCssmPrivateKey(
427 SecPkcs12CoderRef coder
,
429 CSSM_KEY_PTR
*privateKey
, // RETURNED
430 CFStringRef
*friendlyName
, // RETURNED
431 CFDataRef
*localKeyId
, // RETURNED
432 SecPkcs12AttrsRef
*attrs
) // RETURNED
435 P12Coder
*p12coder
= P12CoderCast(coder
);
436 required(privateKey
);
437 /* others are optional - if NULL, we don't return that param */
438 P12KeyBag
*bag
= p12coder
->getKey(keyNum
);
439 *privateKey
= bag
->key();
441 /* now the optional attrs */
442 P12BagAttrs
*p12Attrs
= NULL
;
443 bag
->copyAllAttrs(friendlyName
, localKeyId
,
444 attrs
? &p12Attrs
: NULL
);
453 * Catch-all for other components not currently understood
454 * or supported by this library. An "opaque blob" component
455 * is identified by an OID and is obtained as an opaque data
458 OSStatus
SecPkcs12OpaqueBlobCount(
459 SecPkcs12CoderRef coder
,
460 CFIndex
*numBlobs
) // RETURNED
464 P12Coder
*p12coder
= P12CoderCast(coder
);
466 *numBlobs
= p12coder
->numOpaqueBlobs();
471 OSStatus
SecPkcs12CopyOpaqueBlob(
472 SecPkcs12CoderRef coder
,
474 CFDataRef
*blobOid
, // RETURNED
475 CFDataRef
*opaqueBlob
, // RETURNED
476 CFStringRef
*friendlyName
, // RETURNED
477 CFDataRef
*localKeyId
, // RETURNED
478 SecPkcs12AttrsRef
*attrs
) // RETURNED
482 P12Coder
*p12coder
= P12CoderCast(coder
);
484 required(opaqueBlob
);
486 /* others are optional - if NULL, we don't return that param */
487 P12OpaqueBag
*bag
= p12coder
->getOpaque(blobNum
);
488 *opaqueBlob
= p12CssmDataToCf(bag
->blob());
489 *blobOid
= p12CssmDataToCf(bag
->oid());
491 /* now the optional attrs */
492 P12BagAttrs
*p12Attrs
= NULL
;
493 bag
->copyAllAttrs(friendlyName
, localKeyId
,
494 attrs
? &p12Attrs
: NULL
);
502 #pragma mark --- Encoder Functions ---
505 * This the final step to create an encoded PKCS12 PFX blob,
506 * after calling some number of SecPkcs12Set* functions below.
507 * The result is a DER_encoded PFX in PKCS12 lingo.
509 OSStatus
SecPkcs12Encode(
510 SecPkcs12CoderRef coder
,
511 CFDataRef
*pfx
) // RETURNED
514 P12Coder
*p12coder
= P12CoderCast(coder
);
516 p12coder
->encode(pfx
);
521 * Add individual components. "Getter" functions are available
522 * as described above (under "Functions used for decoding").
524 OSStatus
SecPkcs12AddCertificate(
525 SecPkcs12CoderRef coder
,
526 SecCertificateRef cert
,
527 CFStringRef friendlyName
, // optional
528 CFDataRef localKeyId
, // optional
529 SecPkcs12AttrsRef attrs
) // optional
532 P12Coder
*p12coder
= P12CoderCast(coder
);
535 OSStatus ortn
= SecCertificateGetData(cert
, &certData
);
539 CSSM_CERT_TYPE certType
;
540 ortn
= SecCertificateGetType(cert
, &certType
);
544 NSS_P12_CertBagType type
;
546 case CSSM_CERT_X_509v1
:
547 case CSSM_CERT_X_509v2
:
548 case CSSM_CERT_X_509v3
:
551 case CSSM_CERT_SDSIv1
:
558 P12CertBag
*bag
= new P12CertBag(type
, certData
, friendlyName
,
559 localKeyId
, P12AttrsCastOpt(attrs
), p12coder
->coder());
560 p12coder
->addCert(bag
);
564 OSStatus
SecPkcs12AddCrl(
565 SecPkcs12CoderRef coder
,
567 CFStringRef friendlyName
, // optional
568 CFDataRef localKeyId
, // optional
569 SecPkcs12AttrsRef attrs
) // optional
572 P12Coder
*p12coder
= P12CoderCast(coder
);
574 P12CrlBag
*bag
= new P12CrlBag(CRT_X509
, crl
, friendlyName
,
575 localKeyId
, P12AttrsCastOpt(attrs
), p12coder
->coder());
576 p12coder
->addCrl(bag
);
580 OSStatus
SecPkcs12AddPrivateKey(
581 SecPkcs12CoderRef coder
,
582 SecKeyRef privateKey
,
583 CFStringRef friendlyName
, // optional
584 CFDataRef localKeyId
, // optional
585 SecPkcs12AttrsRef attrs
) // optional
589 P12Coder
*p12coder
= P12CoderCast(coder
);
590 required(privateKey
);
591 const CSSM_KEY
*cssmKey
;
592 OSStatus ortn
= SecKeyGetCSSMKey(privateKey
, &cssmKey
);
596 P12KeyBag
*bag
= new P12KeyBag(cssmKey
, p12coder
->cspHand(),
597 friendlyName
, localKeyId
, P12AttrsCastOpt(attrs
), p12coder
->coder());
598 p12coder
->addKey(bag
);
603 OSStatus
SecPkcs12AddCssmPrivateKey(
604 SecPkcs12CoderRef coder
,
605 CSSM_KEY_PTR cssmKey
,
606 CFStringRef friendlyName
, // optional
607 CFDataRef localKeyId
, // optional
608 SecPkcs12AttrsRef attrs
) // optional
612 P12Coder
*p12coder
= P12CoderCast(coder
);
614 P12KeyBag
*bag
= new P12KeyBag(cssmKey
, p12coder
->cspHand(),
615 friendlyName
, localKeyId
, P12AttrsCastOpt(attrs
), p12coder
->coder());
616 p12coder
->addKey(bag
);
621 OSStatus
SecPkcs12AddOpaqueBlob(
622 SecPkcs12CoderRef coder
,
624 CFDataRef opaqueBlob
,
625 CFStringRef friendlyName
, // optional
626 CFDataRef localKeyId
, // optional
627 SecPkcs12AttrsRef attrs
) // optional
631 P12Coder
*p12coder
= P12CoderCast(coder
);
633 required(opaqueBlob
);
634 P12OpaqueBag
*bag
= new P12OpaqueBag(blobOid
, opaqueBlob
, friendlyName
,
635 localKeyId
, P12AttrsCastOpt(attrs
), p12coder
->coder());
636 p12coder
->addOpaque(bag
);
641 #pragma mark --- Optional Functions ---
644 *** SecPkcs12AttrsRef manipulation. Optional and in fact expected to
645 *** be rarely used, if ever.
651 OSStatus
SecPkcs12AttrsCreate(
652 SecPkcs12AttrsRef
*attrs
) // RETURNED
657 P12BagAttrsStandAlone
*bagAttrs
= new P12BagAttrsStandAlone
;
658 *attrs
= (SecPkcs12AttrsRef
)bagAttrs
;
663 OSStatus
SecPkcs12AttrsRelease(
664 SecPkcs12AttrsRef attrs
)
668 P12BagAttrsStandAlone
*bagAttrs
= P12AttrsCast(attrs
);
675 * Add an OID/value set to an existing SecPkcs12AttrsRef.
676 * Values are a CFArray containing an arbitrary number of
679 OSStatus
SecPkcs12AttrsAddAttr(
680 SecPkcs12AttrsRef attrs
,
682 CFArrayRef attrValues
)
686 P12BagAttrsStandAlone
*bagAttrs
= P12AttrsCast(attrs
);
687 bagAttrs
->addAttr(attrOid
, attrValues
);
692 OSStatus
SecPkcs12AttrCount(
693 SecPkcs12AttrsRef attrs
,
694 CFIndex
*numAttrs
) // RETURNED
698 P12BagAttrsStandAlone
*bagAttrs
= P12AttrsCast(attrs
);
700 *numAttrs
= bagAttrs
->numAttrs();
706 * Obtain n'th oid/value set from an existing SecPkcs12AttrsRef.
708 OSStatus
SecPkcs12AttrsGetAttr(
709 SecPkcs12AttrsRef attrs
,
711 CFDataRef
*attrOid
, // RETURNED
712 CFArrayRef
*attrValues
) // RETURNED
716 P12BagAttrsStandAlone
*bagAttrs
= P12AttrsCast(attrs
);
718 required(attrValues
);
719 bagAttrs
->getAttr(attrNum
, attrOid
, attrValues
);
723 OSStatus
SecPkcs12SetIntegrityMode(
724 SecPkcs12CoderRef coder
,
729 P12Coder
*p12coder
= P12CoderCast(coder
);
730 p12coder
->integrityMode(mode
);
735 OSStatus
SecPkcs12GetIntegrityMode(
736 SecPkcs12CoderRef coder
,
737 SecPkcs12Mode
*mode
) // RETURNED
741 P12Coder
*p12coder
= P12CoderCast(coder
);
743 *mode
= p12coder
->integrityMode();
748 OSStatus
SecPkcs12SetPrivacyMode(
749 SecPkcs12CoderRef coder
,
754 P12Coder
*p12coder
= P12CoderCast(coder
);
755 p12coder
->privacyMode(mode
);
760 OSStatus
SecPkcs12GetPrivacyMode(
761 SecPkcs12CoderRef coder
,
762 SecPkcs12Mode
*mode
) // RETURNED
766 P12Coder
*p12coder
= P12CoderCast(coder
);
768 *mode
= p12coder
->privacyMode();
774 *** Encryption algorithms
776 OSStatus
SecPkcs12SetKeyEncryptionAlg(
777 SecPkcs12CoderRef coder
,
778 CFDataRef encryptionAlg
)
782 P12Coder
*p12coder
= P12CoderCast(coder
);
783 required(encryptionAlg
);
784 p12coder
->strongEncrAlg(encryptionAlg
);
789 OSStatus
SecPkcs12SetCertCrlEncryptionAlg(
790 SecPkcs12CoderRef coder
,
791 CFDataRef encryptionAlg
)
795 P12Coder
*p12coder
= P12CoderCast(coder
);
796 required(encryptionAlg
);
797 p12coder
->weakEncrAlg(encryptionAlg
);
802 OSStatus
SecPkcs12SetKeyEncryptionIterCount(
803 SecPkcs12CoderRef coder
,
808 P12Coder
*p12coder
= P12CoderCast(coder
);
809 p12coder
->strongEncrIterCount(iterCount
);
814 OSStatus
SecPkcs12SetCertCrlEncryptionIterCount(
815 SecPkcs12CoderRef coder
,
820 P12Coder
*p12coder
= P12CoderCast(coder
);
821 p12coder
->weakEncrIterCount(iterCount
);
826 OSStatus
SecPkcs12SetMacIterCount(
827 SecPkcs12CoderRef coder
,
832 P12Coder
*p12coder
= P12CoderCast(coder
);
833 p12coder
->macEncrIterCount(iterCount
);
838 OSStatus
SecPkcs12CopyKeyEncryptionAlg(
839 SecPkcs12CoderRef coder
,
840 CFDataRef
*encryptionAlg
) // RETURNED
844 P12Coder
*p12coder
= P12CoderCast(coder
);
845 required(encryptionAlg
);
846 *encryptionAlg
= p12coder
->strongEncrAlg();
851 OSStatus
SecPkcs12CopyCertCrlEncryptionAlg(
852 SecPkcs12CoderRef coder
,
853 CFDataRef
*encryptionAlg
) // RETURNED
857 P12Coder
*p12coder
= P12CoderCast(coder
);
858 required(encryptionAlg
);
859 *encryptionAlg
= p12coder
->weakEncrAlg();
864 OSStatus
SecPkcs12CopyKeyEncryptionIterCount(
865 SecPkcs12CoderRef coder
,
866 unsigned *iterCount
) // RETURNED
870 P12Coder
*p12coder
= P12CoderCast(coder
);
872 *iterCount
= p12coder
->strongEncrIterCount();
877 OSStatus
SecPkcs12CopyCertCrlEncryptionIterCount(
878 SecPkcs12CoderRef coder
,
879 unsigned *iterCount
) // RETURNED
883 P12Coder
*p12coder
= P12CoderCast(coder
);
885 *iterCount
= p12coder
->weakEncrIterCount();
890 OSStatus
SecPkcs12CopyMacIterCount(
891 SecPkcs12CoderRef coder
,
892 unsigned *iterCount
) // RETURNED
896 P12Coder
*p12coder
= P12CoderCast(coder
);
898 *iterCount
= p12coder
->macEncrIterCount();
903 OSStatus
SecPkcs12LimitPrivateKeyImport(
904 SecPkcs12CoderRef coder
,
909 P12Coder
*p12coder
= P12CoderCast(coder
);
910 p12coder
->limitPrivKeyImport(foundOneKey
);