2 * Decode P12 PFX using either C++ P12Coder or public
3 * C API (both from SecurityNssPkcs12)
6 #include <security_pkcs12/pkcs12Coder.h>
9 #include <Security/cssmtype.h>
10 #include <security_cdsa_utils/cuPrintCert.h>
11 #include <security_cdsa_utils/cuCdsaUtils.h>
12 #include "p12GetPassKey.h"
15 /* use this option to debug the P12Coder class directly */
16 #define P12_DECODE_VIA_CPP 0
19 * Print CFString - stored as unicode, we get the C string,
20 * print it plus newline
22 static void printUcStr(
25 CFIndex len
= CFStringGetLength(cfstr
) + 1;
26 char *outStr
= (char *)malloc(len
);
27 if(CFStringGetCString(cfstr
, outStr
, len
, kCFStringEncodingASCII
)) {
28 printf("%s\n", outStr
);
31 printf("***Error converting from unicode to ASCII\n");
36 static void printDataAsHex(
38 unsigned maxToPrint
= 0) // optional, 0 means print it all
42 uint32 len
= CFDataGetLength(d
);
43 const uint8
*cp
= CFDataGetBytePtr(d
);
45 if((maxToPrint
!= 0) && (len
> maxToPrint
)) {
49 for(i
=0; i
<len
; i
++) {
50 printf("%02X ", ((unsigned char *)cp
)[i
]);
60 static void printAlgAsString(
63 char *s
= "unknown alg";
80 #if P12_DECODE_VIA_CPP
82 /* common bag attrs - friendlyName, localKeyId */
83 static void printBagAttrs(
86 CFStringRef friendlyName
= bag
.friendlyName();
88 printf(" friendlyName : ");
89 printUcStr(friendlyName
);
90 CFRelease(friendlyName
);
93 CFDataRef keyId
= bag
.localKeyId();
95 printf(" localKeyId : ");
96 printDataAsHex(keyId
, 16);
99 if((friendlyName
== NULL
) && (keyId
== NULL
)) {
100 printf(" <no attributes found>\n");
105 const CSSM_DATA
&pfx
,
106 CSSM_CSP_HANDLE cspHand
,
113 for(unsigned loop
=0; loop
<loops
; loop
++) {
115 /* localize scope of coder for malloc test */
117 CFDataRef cfd
= CFDataCreate(NULL
, pfx
.Data
, pfx
.Length
);
121 coder
.setCsp(cspHand
);
122 coder
.setMacPassPhrase(pwd
);
126 printf("***decode error\n");
134 unsigned numCerts
= coder
.numCerts();
135 printf("\n%u certs found\n", numCerts
);
136 for(i
=0; i
<numCerts
; i
++) {
137 P12CertBag
*cert
= coder
.getCert(i
);
138 printf("=== Cert %u ===\n", i
);
139 printBagAttrs(*cert
);
141 CSSM_DATA
&certData
= cert
->certData();
142 printCert(certData
.Data
, certData
.Length
,
149 unsigned numCrls
= coder
.numCrls();
150 printf("%u crls found\n", numCrls
);
151 for(i
=0; i
<numCrls
; i
++) {
152 P12CrlBag
*crl
= coder
.getCrl(i
);
153 printf("=== Crl %u ===\n", i
);
156 CSSM_DATA
&crlData
= crl
->crlData();
157 printCrl(crlData
.Data
, crlData
.Length
, CSSM_FALSE
);
163 unsigned numKeys
= coder
.numKeys();
164 printf("%u keys found\n", numKeys
);
165 for(i
=0; i
<numKeys
; i
++) {
166 P12KeyBag
*key
= coder
.getKey(i
);
167 printf("\n=== Key %u ===\n", i
);
170 CSSM_KEY_PTR ckey
= key
->key();
171 CSSM_KEYHEADER
&hdr
= ckey
->KeyHeader
;
172 printf(" Key Alg : ");
173 printAlgAsString(hdr
.AlgorithmId
);
174 printf(" Key Size : %u bits\n",
175 (unsigned)hdr
.LogicalKeySizeInBits
);
179 unsigned numBlobs
= coder
.numOpaqueBlobs();
180 printf("%u blobs found\n", numBlobs
);
183 printf("***exception extracting fields\n");
189 printf("CR to continue: ");
199 #else /* P12_DECODE_VIA_CPP */
201 /* Normal decode using public API in SecPkcs12.h */
203 /* common bag attrs - friendlyName, localKeyId */
204 static void printBagAttrs(
205 CFStringRef friendlyName
,
206 CFDataRef localKeyId
)
209 printf(" friendlyName : ");
210 printUcStr(friendlyName
);
214 printf(" localKeyId : ");
215 printDataAsHex(localKeyId
, 20);
217 if((friendlyName
== NULL
) && (localKeyId
== NULL
)) {
218 printf(" <no attributes found>\n");
222 /* release attrs if present */
223 static void releaseAttrs(
224 CFStringRef friendlyName
,
225 CFDataRef localKeyId
,
226 SecPkcs12AttrsRef attrs
)
229 CFRelease(friendlyName
);
232 CFRelease(localKeyId
);
235 SecPkcs12AttrsRelease(attrs
);
239 static void printOsError(
243 /* may want to parse out CSSM errors */
244 cssmPerror(op
, ortn
);
248 /* Sec calls all return 1 - not the fault of SecNssPkcs12 */
249 #define GET_CERTS_WORKING 1
252 const CSSM_DATA
&pfx
,
253 CSSM_CSP_HANDLE cspHand
,
254 CFStringRef pwd
, // explicit passphrase, mutually exclusive with...
255 bool usePassKey
, // use SECURE_PASSPHRASE key
261 CSSM_KEY_PTR passKeyPtr
= NULL
;
263 CFDataRef cfd
= CFDataCreate(NULL
, pfx
.Data
, pfx
.Length
);
265 ortn
= p12GetPassKey(cspHand
, GPK_Decode
, true, &passKey
);
269 passKeyPtr
= &passKey
;
271 for(unsigned loop
=0; loop
<loops
; loop
++) {
272 SecPkcs12CoderRef coder
;
273 ortn
= SecPkcs12CoderCreate(&coder
);
275 printOsError("SecPkcs12CoderCreate", ortn
);
279 ortn
= SecPkcs12SetCspHandle(coder
, cspHand
);
281 printOsError("SecPkcs12SetCspHandle", ortn
);
286 ortn
= SecPkcs12SetMACPassKey(coder
, passKeyPtr
);
288 printOsError("SecPkcs12SetMACPassKey", ortn
);
293 ortn
= SecPkcs12SetMACPassphrase(coder
, pwd
);
295 printOsError("SecPkcs12SetMACPassphrase", ortn
);
299 ortn
= SecPkcs12Decode(coder
, cfd
);
301 printOsError("SecPkcs12Decode", ortn
);
310 SecPkcs12CertificateCount(coder
, &numCerts
);
311 printf("\n=== %ld certs found ===\n", numCerts
);
312 #if GET_CERTS_WORKING
313 for(i
=0; i
<numCerts
; i
++) {
314 SecCertificateRef secCert
;
315 ortn
= SecPkcs12CopyCertificate(coder
,
322 printOsError("SecPkcs12CopyCertificate", ortn
);
325 printf("Cert %ld:\n", i
);
326 printBagAttrs(fname
, keyId
);
329 ortn
= SecCertificateGetData(secCert
, &certData
);
331 printOsError("SecCertificateGetData", ortn
);
334 printCert(certData
.Data
, certData
.Length
,
338 releaseAttrs(fname
, keyId
, NULL
);
342 #endif /* GET_CERTS_WORKING */
345 SecPkcs12CrlCount(coder
, &numCrls
);
346 printf("=== %ld crls found ===\n", numCrls
);
347 for(i
=0; i
<numCrls
; i
++) {
349 ortn
= SecPkcs12CopyCrl(coder
,
356 printOsError("SecPkcs12CopyCrl", ortn
);
359 printf("Crl %ld:\n", i
);
360 printBagAttrs(fname
, keyId
);
362 const CSSM_DATA crlData
= {
363 CFDataGetLength(crl
),
364 (uint8
*)CFDataGetBytePtr(crl
) };
365 printCrl(crlData
.Data
, crlData
.Length
, CSSM_FALSE
);
368 releaseAttrs(fname
, keyId
, NULL
);
374 SecPkcs12PrivateKeyCount(coder
, &numKeys
);
375 printf("=== %ld keys found ===\n", numKeys
);
376 for(i
=0; i
<numKeys
; i
++) {
378 ortn
= SecPkcs12GetCssmPrivateKey(coder
,
385 printf("Key %ld:\n", i
);
386 printBagAttrs(fname
, keyId
);
388 CSSM_KEYHEADER
&hdr
= key
->KeyHeader
;
389 printf(" Key Alg : ");
390 printAlgAsString(hdr
.AlgorithmId
);
391 printf(" Key Size : %u bits\n",
392 (unsigned)hdr
.LogicalKeySizeInBits
);
394 releaseAttrs(fname
, keyId
, NULL
);
398 SecPkcs12OpaqueBlobCount(coder
, &numBlobs
);
400 printf("%ld blobs found\n", numBlobs
);
403 /* this should free all memory allocated in the decode */
404 SecPkcs12CoderRelease(coder
);
408 printf("CR to continue: ");
416 #endif /* P12_DECODE_VIA_CPP */