]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/p12/p12Decode.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / p12 / p12Decode.cpp
1 /*
2 * Decode P12 PFX using either C++ P12Coder or public
3 * C API (both from SecurityNssPkcs12)
4 */
5
6 #include <security_pkcs12/pkcs12Coder.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <Security/cssmtype.h>
10 #include <security_cdsa_utils/cuPrintCert.h>
11 #include <security_cdsa_utils/cuCdsaUtils.h>
12 #include "p12GetPassKey.h"
13 #include "p12.h"
14
15 /* use this option to debug the P12Coder class directly */
16 #define P12_DECODE_VIA_CPP 0
17
18 /*
19 * Print CFString - stored as unicode, we get the C string,
20 * print it plus newline
21 */
22 static void printUcStr(
23 CFStringRef cfstr)
24 {
25 CFIndex len = CFStringGetLength(cfstr) + 1;
26 char *outStr = (char *)malloc(len);
27 if(CFStringGetCString(cfstr, outStr, len, kCFStringEncodingASCII)) {
28 printf("%s\n", outStr);
29 }
30 else {
31 printf("***Error converting from unicode to ASCII\n");
32 }
33 free(outStr);
34 }
35
36 static void printDataAsHex(
37 CFDataRef d,
38 unsigned maxToPrint = 0) // optional, 0 means print it all
39 {
40 unsigned i;
41 bool more = false;
42 uint32 len = CFDataGetLength(d);
43 const uint8 *cp = CFDataGetBytePtr(d);
44
45 if((maxToPrint != 0) && (len > maxToPrint)) {
46 len = maxToPrint;
47 more = true;
48 }
49 for(i=0; i<len; i++) {
50 printf("%02X ", ((unsigned char *)cp)[i]);
51 }
52 if(more) {
53 printf("...\n");
54 }
55 else {
56 printf("\n");
57 }
58 }
59
60 static void printAlgAsString(
61 CSSM_ALGORITHMS alg)
62 {
63 char *s = "unknown alg";
64 switch(alg) {
65 case CSSM_ALGID_RSA:
66 s = "RSA";
67 break;
68 case CSSM_ALGID_DSA:
69 s = "DSA";
70 break;
71 case CSSM_ALGID_FEE:
72 s = "FEE";
73 break;
74 default:
75 break;
76 }
77 printf("%s\n", s);
78 }
79
80 #if P12_DECODE_VIA_CPP
81
82 /* common bag attrs - friendlyName, localKeyId */
83 static void printBagAttrs(
84 P12SafeBag &bag)
85 {
86 CFStringRef friendlyName = bag.friendlyName();
87 if(friendlyName) {
88 printf(" friendlyName : ");
89 printUcStr(friendlyName);
90 CFRelease(friendlyName);
91 }
92
93 CFDataRef keyId = bag.localKeyId();
94 if(keyId) {
95 printf(" localKeyId : ");
96 printDataAsHex(keyId, 16);
97 CFRelease(keyId);
98 }
99 if((friendlyName == NULL) && (keyId == NULL)) {
100 printf(" <no attributes found>\n");
101 }
102 }
103
104 OSStatus p12Decode(
105 const CSSM_DATA &pfx,
106 CSSM_CSP_HANDLE cspHand,
107 CFStringRef pwd,
108 bool verbose,
109 unsigned loops)
110 {
111 OSStatus ourRtn;
112
113 for(unsigned loop=0; loop<loops; loop++) {
114 {
115 /* localize scope of coder for malloc test */
116 P12Coder coder;
117 CFDataRef cfd = CFDataCreate(NULL, pfx.Data, pfx.Length);
118 ourRtn = noErr;
119
120 try {
121 coder.setCsp(cspHand);
122 coder.setMacPassPhrase(pwd);
123 coder.decode(cfd);
124 }
125 catch(...) {
126 printf("***decode error\n");
127 ourRtn = 1;
128 }
129 CFRelease(cfd);
130
131 try {
132 unsigned i;
133
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);
140 if(verbose) {
141 CSSM_DATA &certData = cert->certData();
142 printCert(certData.Data, certData.Length,
143 CSSM_FALSE);
144
145 }
146 printf("\n");
147 }
148
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);
154 printBagAttrs(*crl);
155 if(verbose) {
156 CSSM_DATA &crlData = crl->crlData();
157 printCrl(crlData.Data, crlData.Length, CSSM_FALSE);
158
159 }
160 printf("\n");
161 }
162
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);
168 printBagAttrs(*key);
169 /* fix this up */
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);
176 printf("\n");
177 }
178
179 unsigned numBlobs = coder.numOpaqueBlobs();
180 printf("%u blobs found\n", numBlobs);
181 }
182 catch(...) {
183 printf("***exception extracting fields\n");
184 ourRtn = 1;
185 }
186 }
187 if(loops > 1) {
188 fpurge(stdin);
189 printf("CR to continue: ");
190 getchar();
191 }
192 if(ourRtn) {
193 return ourRtn;
194 }
195 }
196 return ourRtn;
197 }
198
199 #else /* P12_DECODE_VIA_CPP */
200
201 /* Normal decode using public API in SecPkcs12.h */
202
203 /* common bag attrs - friendlyName, localKeyId */
204 static void printBagAttrs(
205 CFStringRef friendlyName,
206 CFDataRef localKeyId)
207 {
208 if(friendlyName) {
209 printf(" friendlyName : ");
210 printUcStr(friendlyName);
211 }
212
213 if(localKeyId) {
214 printf(" localKeyId : ");
215 printDataAsHex(localKeyId, 20);
216 }
217 if((friendlyName == NULL) && (localKeyId == NULL)) {
218 printf(" <no attributes found>\n");
219 }
220 }
221
222 /* release attrs if present */
223 static void releaseAttrs(
224 CFStringRef friendlyName,
225 CFDataRef localKeyId,
226 SecPkcs12AttrsRef attrs)
227 {
228 if(friendlyName) {
229 CFRelease(friendlyName);
230 }
231 if(localKeyId) {
232 CFRelease(localKeyId);
233 }
234 if(attrs) {
235 SecPkcs12AttrsRelease(attrs);
236 }
237 }
238
239 static void printOsError(
240 const char *op,
241 OSStatus ortn)
242 {
243 /* may want to parse out CSSM errors */
244 cssmPerror(op, ortn);
245 printf("\n");
246 }
247
248 /* Sec calls all return 1 - not the fault of SecNssPkcs12 */
249 #define GET_CERTS_WORKING 1
250
251 OSStatus p12Decode(
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
256 bool verbose,
257 unsigned loops)
258 {
259 OSStatus ortn;
260 CSSM_KEY passKey;
261 CSSM_KEY_PTR passKeyPtr = NULL;
262
263 CFDataRef cfd = CFDataCreate(NULL, pfx.Data, pfx.Length);
264 if(usePassKey) {
265 ortn = p12GetPassKey(cspHand, GPK_Decode, true, &passKey);
266 if(ortn) {
267 return ortn;
268 }
269 passKeyPtr = &passKey;
270 }
271 for(unsigned loop=0; loop<loops; loop++) {
272 SecPkcs12CoderRef coder;
273 ortn = SecPkcs12CoderCreate(&coder);
274 if(ortn) {
275 printOsError("SecPkcs12CoderCreate", ortn);
276 return ortn;
277 }
278
279 ortn = SecPkcs12SetCspHandle(coder, cspHand);
280 if(ortn) {
281 printOsError("SecPkcs12SetCspHandle", ortn);
282 return ortn;
283 }
284
285 if(usePassKey) {
286 ortn = SecPkcs12SetMACPassKey(coder, passKeyPtr);
287 if(ortn) {
288 printOsError("SecPkcs12SetMACPassKey", ortn);
289 return ortn;
290 }
291 }
292 else {
293 ortn = SecPkcs12SetMACPassphrase(coder, pwd);
294 if(ortn) {
295 printOsError("SecPkcs12SetMACPassphrase", ortn);
296 return ortn;
297 }
298 }
299 ortn = SecPkcs12Decode(coder, cfd);
300 if(ortn) {
301 printOsError("SecPkcs12Decode", ortn);
302 return ortn;
303 }
304
305 CFIndex i;
306 CFStringRef fname;
307 CFDataRef keyId;
308
309 CFIndex numCerts;
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,
316 i,
317 &secCert,
318 &fname,
319 &keyId,
320 NULL); // attrs
321 if(ortn) {
322 printOsError("SecPkcs12CopyCertificate", ortn);
323 return ortn;
324 }
325 printf("Cert %ld:\n", i);
326 printBagAttrs(fname, keyId);
327 if(verbose) {
328 CSSM_DATA certData;
329 ortn = SecCertificateGetData(secCert, &certData);
330 if(ortn) {
331 printOsError("SecCertificateGetData", ortn);
332 return ortn;
333 }
334 printCert(certData.Data, certData.Length,
335 CSSM_FALSE);
336
337 }
338 releaseAttrs(fname, keyId, NULL);
339 CFRelease(secCert);
340 printf("\n");
341 }
342 #endif /* GET_CERTS_WORKING */
343
344 CFIndex numCrls;
345 SecPkcs12CrlCount(coder, &numCrls);
346 printf("=== %ld crls found ===\n", numCrls);
347 for(i=0; i<numCrls; i++) {
348 CFDataRef crl;
349 ortn = SecPkcs12CopyCrl(coder,
350 i,
351 &crl,
352 &fname,
353 &keyId,
354 NULL); // attrs
355 if(ortn) {
356 printOsError("SecPkcs12CopyCrl", ortn);
357 return ortn;
358 }
359 printf("Crl %ld:\n", i);
360 printBagAttrs(fname, keyId);
361 if(verbose) {
362 const CSSM_DATA crlData = {
363 CFDataGetLength(crl),
364 (uint8 *)CFDataGetBytePtr(crl) };
365 printCrl(crlData.Data, crlData.Length, CSSM_FALSE);
366
367 }
368 releaseAttrs(fname, keyId, NULL);
369 CFRelease(crl);
370 printf("\n");
371 }
372
373 CFIndex numKeys;
374 SecPkcs12PrivateKeyCount(coder, &numKeys);
375 printf("=== %ld keys found ===\n", numKeys);
376 for(i=0; i<numKeys; i++) {
377 CSSM_KEY_PTR key;
378 ortn = SecPkcs12GetCssmPrivateKey(coder,
379 i,
380 &key,
381 &fname,
382 &keyId,
383 NULL);
384
385 printf("Key %ld:\n", i);
386 printBagAttrs(fname, keyId);
387 /* fix this up */
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);
393 printf("\n");
394 releaseAttrs(fname, keyId, NULL);
395 }
396
397 CFIndex numBlobs;
398 SecPkcs12OpaqueBlobCount(coder, &numBlobs);
399 if(numBlobs != 0) {
400 printf("%ld blobs found\n", numBlobs);
401 }
402
403 /* this should free all memory allocated in the decode */
404 SecPkcs12CoderRelease(coder);
405
406 if(loops > 1) {
407 fpurge(stdin);
408 printf("CR to continue: ");
409 getchar();
410 }
411 }
412 return 0;
413 }
414
415
416 #endif /* P12_DECODE_VIA_CPP */