]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/dotMacTool/dotMacTool.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / dotMacTool / dotMacTool.cpp
1 /*
2 * dotMacTool.cpp - .mac TP exerciser
3 */
4
5 #include <Security/Security.h>
6 #include <Security/SecKeyPriv.h>
7 #include <security_cdsa_utils/cuCdsaUtils.h>
8 #include <security_cdsa_utils/cuFileIo.h>
9 #include <security_cdsa_utils/cuPem.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <unistd.h>
13 //#include <security_dotmac_tp/dotMacTp.h>
14 #include <dotMacTp.h>
15 #include <security_cdsa_utils/cuPrintCert.h>
16
17 #include "keyPicker.h"
18 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
19
20 #define USER_DEFAULT "dmitchtest@mac.com"
21 #define PWD_DEF "123456"
22
23 static void usage(char **argv)
24 {
25 printf("usage: %s op [options]\n", argv[0]);
26 printf("Op:\n");
27 printf(" g generate identity cert\n");
28 printf(" G generate email signing cert\n");
29 printf(" e generate email encrypting cert\n");
30 printf(" l lookup cert (requires -f)\n");
31 printf(" L lookup identity cert (via -u)\n");
32 printf(" M lookup email signing cert (via -u)\n");
33 printf(" N lookup encrypting cert (via -u)\n");
34 printf("Options:\n");
35 printf(" -g Generate keypair\n");
36 printf(" -p pick key pair from existing\n");
37 printf(" -u username Default = %s\n", USER_DEFAULT);
38 printf(" -Z password Specify password immediately\n");
39 printf(" -z Use default password %s\n", PWD_DEF);
40 printf(" -k keychain Source/destination of keys and certs\n");
41 printf(" -c filename Write CSR to filename\n");
42 printf(" -C filename Use existing CSR (no keygen)\n");
43 printf(" -f refIdFile RefId file for cert lookup\n");
44 printf(" -n Do NOT post the CSR to the .mac server\n");
45 printf(" -H hostname Alternate .mac server host name (default %s)\n",
46 DOT_MAC_SIGN_HOST_NAME);
47 printf(" -o outFile Write output cert or refId (if any) to outFile\n");
48 printf(" -r Renew (default is new)\n");
49 printf(" -M Pause for MallocDebug\n");
50 printf(" -q Quiet\n");
51 printf(" -v Verbose\n");
52 printf(" -h Usage\n");
53 exit(1);
54 }
55
56 static CSSM_VERSION vers = {2, 0};
57
58 static CSSM_API_MEMORY_FUNCS memFuncs = {
59 cuAppMalloc,
60 cuAppFree,
61 cuAppRealloc,
62 cuAppCalloc,
63 NULL
64 };
65
66 static CSSM_TP_HANDLE dotMacStartup()
67 {
68 CSSM_TP_HANDLE tpHand;
69 CSSM_RETURN crtn;
70
71 if(cuCssmStartup() == CSSM_FALSE) {
72 return 0;
73 }
74 crtn = CSSM_ModuleLoad(&gGuidAppleDotMacTP,
75 CSSM_KEY_HIERARCHY_NONE,
76 NULL, // eventHandler
77 NULL); // AppNotifyCallbackCtx
78 if(crtn) {
79 cuPrintError("CSSM_ModuleLoad(DotMacTP)", crtn);
80 return 0;
81 }
82 crtn = CSSM_ModuleAttach (&gGuidAppleDotMacTP,
83 &vers,
84 &memFuncs, // memFuncs
85 0, // SubserviceID
86 CSSM_SERVICE_TP, // SubserviceFlags
87 0, // AttachFlags
88 CSSM_KEY_HIERARCHY_NONE,
89 NULL, // FunctionTable
90 0, // NumFuncTable
91 NULL, // reserved
92 &tpHand);
93 if(crtn) {
94 cuPrintError("CSSM_ModuleAttach(DotMacTP)", crtn);
95 return 0;
96 }
97 else {
98 return tpHand;
99 }
100 }
101
102 /* print text, safely */
103 static void snDumpText(
104 const unsigned char *rcvBuf,
105 unsigned len)
106 {
107 char *cp = (char *)rcvBuf;
108 unsigned i;
109 char c;
110
111 for(i=0; i<len; i++) {
112 c = *cp++;
113 if(c == '\0') {
114 break;
115 }
116 switch(c) {
117 case '\n':
118 printf("\\n\n"); // graphic and liternal newline
119 break;
120 case '\r':
121 printf("\\r\n");
122 break;
123 default:
124 if(isprint(c) && (c != '\n')) {
125 printf("%c", c);
126 }
127 else {
128 printf("<%02X>", ((unsigned)c) & 0xff);
129 }
130 break;
131 }
132
133 }
134 }
135
136 static OSStatus genKeyPair(
137 SecKeychainRef kcRef, // NULL means the default list
138 SecKeyRef *pubKey, // RETURNED
139 SecKeyRef *privKey) // RETURNED
140 {
141 OSStatus ortn;
142
143 ortn = SecKeyCreatePair(kcRef,
144 DOT_MAC_KEY_ALG,
145 DOT_MAC_KEY_SIZE,
146 0, // context handle
147 /* public key usage and attrs */
148 CSSM_KEYUSE_ANY,
149 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE,
150 /* private key usage and attrs */
151 CSSM_KEYUSE_ANY,
152 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE |
153 CSSM_KEYATTR_SENSITIVE,
154 NULL, // initial access
155 pubKey,
156 privKey);
157 if(ortn) {
158 cssmPerror("SecKeyCreatePair", ortn);
159 }
160 return ortn;
161 }
162
163 /* Lookup via ReferenceID, obtained from CSSM_TP_SubmitCredRequest() */
164 OSStatus doLookupViaRefId(
165 CSSM_TP_HANDLE tpHand,
166 unsigned char *refId,
167 unsigned refIdLen,
168 char *outFile,
169 bool verbose)
170 {
171 CSSM_DATA refIdData = { refIdLen, refId };
172 sint32 EstimatedTime;
173 CSSM_BOOL ConfirmationRequired;
174 CSSM_TP_RESULT_SET_PTR resultSet = NULL;
175 CSSM_RETURN crtn;
176
177 crtn = CSSM_TP_RetrieveCredResult(tpHand, &refIdData, NULL,
178 &EstimatedTime, &ConfirmationRequired, &resultSet);
179 if(crtn) {
180 cssmPerror("CSSM_TP_RetrieveCredResult", crtn);
181 return crtn;
182 }
183 if(resultSet == NULL) {
184 printf("***CSSM_TP_RetrieveCredResult OK, but no result set\n");
185 return -1;
186 }
187 if(resultSet->NumberOfResults != 1) {
188 printf("***CSSM_TP_RetrieveCredResult OK, NumberOfResults (%u)\n",
189 (unsigned)resultSet->NumberOfResults);
190 return -1;
191 }
192 if(resultSet->Results == NULL) {
193 printf("***CSSM_TP_RetrieveCredResult OK, but empty result set\n");
194 return -1;
195 }
196 CSSM_DATA_PTR certData = (CSSM_DATA_PTR)resultSet->Results;
197
198 printf("...cert retrieval complete\n");
199 if(outFile) {
200 if(!writeFile(outFile, certData->Data, certData->Length)) {
201 printf("...%lu bytes of cert data written to %s\n",
202 certData->Length, outFile);
203 }
204 else {
205 printf("***Error writing cert to %s\n", outFile);
206 crtn = ioErr;
207 }
208 }
209 else if(verbose) {
210 unsigned char *der;
211 unsigned derLen;
212 if(pemDecode(certData->Data, certData->Length, &der, &derLen)) {
213 printf("***Error PEM decoding returned cert\n");
214 }
215 else {
216 printCert(der, derLen, CSSM_FALSE);
217 free(der);
218 }
219 }
220 return noErr;
221 }
222
223 /*
224 * Lookup via user name, a greatly simplified form of CSSM_TP_SubmitCredRequest()
225 */
226 OSStatus doLookupViaUserName(
227 CSSM_TP_HANDLE tpHand,
228 const CSSM_OID *opOid,
229 const char *userName,
230 const char *hostName, // optional
231 char *outFile,
232 bool verbose)
233 {
234 CSSM_APPLE_DOTMAC_TP_CERT_REQUEST certReq;
235 CSSM_TP_AUTHORITY_ID tpAuthority;
236 CSSM_TP_AUTHORITY_ID *tpAuthPtr = NULL;
237 CSSM_NET_ADDRESS tpNetAddrs;
238 CSSM_TP_REQUEST_SET reqSet;
239 CSSM_FIELD policyField;
240 CSSM_DATA certData = {0, NULL};
241 sint32 estTime;
242 CSSM_TP_CALLERAUTH_CONTEXT callerAuth;
243
244 memset(&certReq, 0, sizeof(certReq));
245 certReq.userName.Data = (uint8 *)userName;
246 certReq.userName.Length = strlen(userName);
247 if(hostName != NULL) {
248 tpAuthority.AuthorityCert = NULL;
249 tpAuthority.AuthorityLocation = &tpNetAddrs;
250 tpNetAddrs.AddressType = CSSM_ADDR_NAME;
251 tpNetAddrs.Address.Data = (uint8 *)hostName;
252 tpNetAddrs.Address.Length = strlen(hostName);
253 tpAuthPtr = &tpAuthority;
254 };
255
256 certReq.version = CSSM_DOT_MAC_TP_REQ_VERSION;
257 reqSet.NumberOfRequests = 1;
258 reqSet.Requests = &certReq;
259 policyField.FieldOid = *opOid;
260 policyField.FieldValue.Data = NULL;
261 policyField.FieldValue.Length = 0;
262 memset(&callerAuth, 0, sizeof(callerAuth));
263 callerAuth.Policy.NumberOfPolicyIds = 1;
264 callerAuth.Policy.PolicyIds = &policyField;
265
266 CSSM_RETURN crtn = CSSM_TP_SubmitCredRequest (tpHand,
267 tpAuthPtr,
268 CSSM_TP_AUTHORITY_REQUEST_CERTLOOKUP,
269 &reqSet, // const CSSM_TP_REQUEST_SET *RequestInput,
270 &callerAuth,
271 &estTime, // sint32 *EstimatedTime,
272 &certData); // CSSM_DATA_PTR ReferenceIdentifier
273
274 if(crtn) {
275 cssmPerror("CSSM_TP_SubmitCredRequest(lookup)", crtn);
276 return crtn;
277 }
278
279 printf("...cert lookup complete\n");
280 if(outFile) {
281 if(!writeFile(outFile, certData.Data, certData.Length)) {
282 printf("...%lu bytes of cert data written to %s\n",
283 certData.Length, outFile);
284 }
285 else {
286 printf("***Error writing cert to %s\n", outFile);
287 crtn = ioErr;
288 }
289 }
290 if(verbose) {
291 /* This one returns the cert in DER format, we might revisit that */
292 printCert(certData.Data, certData.Length, CSSM_FALSE);
293 }
294 return crtn;
295 }
296
297 #define FULL_EMAIL_ADDRESS 1
298
299 int main(int argc, char **argv)
300 {
301 CSSM_RETURN crtn;
302 CSSM_TP_AUTHORITY_ID tpAuthority;
303 CSSM_TP_AUTHORITY_ID *tpAuthPtr = NULL;
304 CSSM_NET_ADDRESS tpNetAddrs;
305 CSSM_APPLE_DOTMAC_TP_CERT_REQUEST certReq;
306 CSSM_TP_REQUEST_SET reqSet;
307 CSSM_CSP_HANDLE cspHand = 0;
308 CSSM_X509_TYPE_VALUE_PAIR tvp;
309 char pwdBuf[1000];
310 CSSM_TP_CALLERAUTH_CONTEXT callerAuth;
311 sint32 estTime;
312 CSSM_DATA refId = {0, NULL};
313 OSStatus ortn;
314 SecKeyRef pubKeyRef = NULL;
315 SecKeyRef privKeyRef = NULL;
316 const CSSM_KEY *privKey = NULL;
317 const CSSM_KEY *pubKey = NULL;
318 SecKeychainRef kcRef = NULL;
319 CSSM_FIELD policyField;
320
321 /* user-spec'd variables */
322 bool genKeys = false;
323 bool pickKeys = false;
324 char *keychainName = NULL;
325 char *csrOutName = NULL;
326 char *csrInName = NULL;
327 const char *userName = USER_DEFAULT;
328 char *password = NULL;
329 char *hostName = NULL;
330 bool doNotPost = false;
331 bool doRenew = false;
332 const CSSM_OID *opOid = NULL;
333 char *outFile = NULL;
334 bool quiet = false;
335 bool verbose = false;
336 bool lookupViaRefId = false;
337 bool lookupViaUserName = false;
338 char *refIdFile = NULL;
339 bool doPause = false;
340
341 if(argc < 2) {
342 usage(argv);
343 }
344 switch(argv[1][0]) {
345 case 'L':
346 lookupViaUserName = true;
347 /* drop thru */
348 case 'g':
349 opOid = &CSSMOID_DOTMAC_CERT_REQ_IDENTITY;
350 break;
351
352 case 'M':
353 lookupViaUserName = true;
354 /* drop thru */
355 case 'G':
356 opOid = &CSSMOID_DOTMAC_CERT_REQ_EMAIL_SIGN;
357 break;
358
359 case 'N':
360 lookupViaUserName = true;
361 /* drop thru */
362 case 'e':
363 opOid = &CSSMOID_DOTMAC_CERT_REQ_EMAIL_ENCRYPT;
364 break;
365
366 case 'l':
367 lookupViaRefId = true;
368 break;
369 default:
370 usage(argv);
371 }
372
373 extern char *optarg;
374 extern int optind;
375 optind = 2;
376 int arg;
377 while ((arg = getopt(argc, argv, "gpk:c:u:Z:H:nzrC:o:hf:Mqv")) != -1) {
378 switch (arg) {
379 case 'g':
380 genKeys = true;
381 break;
382 case 'p':
383 pickKeys = true;
384 break;
385 case 'u':
386 userName = optarg;
387 break;
388 case 'Z':
389 password = optarg;
390 break;
391 case 'z':
392 password = (char *)PWD_DEF;
393 break;
394 case 'k':
395 keychainName = optarg;
396 break;
397 case 'c':
398 csrOutName = optarg;
399 break;
400 case 'C':
401 csrInName = optarg;
402 break;
403 case 'H':
404 hostName = optarg;
405 break;
406 case 'n':
407 doNotPost = true;
408 break;
409 case 'r':
410 doRenew = true;
411 break;
412 case 'o':
413 outFile = optarg;
414 break;
415 case 'f':
416 refIdFile = optarg;
417 break;
418 case 'M':
419 doPause = true;
420 break;
421 case 'v':
422 verbose = true;
423 break;
424 case 'q':
425 quiet = true;
426 break;
427 case 'h':
428 usage(argv);
429 }
430 }
431
432 if(doPause) {
433 fpurge(stdin);
434 printf("Pausing for MallocDebug attach; CR to continue: ");
435 getchar();
436 }
437
438 CSSM_TP_HANDLE tpHand = dotMacStartup();
439 if(tpHand == 0) {
440 printf("Error attaching to the .mac TP. Check your MDS file.\n");
441 exit(1);
442 }
443
444 if(lookupViaRefId) {
445 if(refIdFile == NULL) {
446 printf("I need a refIdFile to do a lookup.\n");
447 usage(argv);
448 }
449 unsigned char *refId;
450 unsigned refIdLen;
451 int irtn = readFile(refIdFile, &refId, &refIdLen);
452 if(irtn) {
453 printf("***Error reading refId from %s. Aborting.\n", refIdFile);
454 exit(1);
455 }
456 ortn = doLookupViaRefId(tpHand, refId, refIdLen, outFile, verbose);
457 free(refId);
458 goto done;
459 }
460 if(lookupViaUserName) {
461 ortn = doLookupViaUserName(tpHand, opOid, userName, hostName, outFile, verbose);
462 goto done;
463 }
464 if(!pickKeys && !genKeys && (csrInName == NULL)) {
465 printf("***You must specify either the -p (pick keys) or -g (generate keys)"
466 " arguments, or provide a CSR (-C).\n");
467 exit(1);
468 }
469
470 memset(&certReq, 0, sizeof(certReq));
471
472 /* all of the subsequest argument are superfluous for lookupViaUserName, except for
473 * the user name itself, which has a default */
474 if(keychainName != NULL) {
475 /* pick a keychain (optional) */
476 ortn = SecKeychainOpen(keychainName, &kcRef);
477 if(ortn) {
478 cssmPerror("SecKeychainOpen", ortn);
479 exit(1);
480 }
481
482 /* make sure it's there since a successful SecKeychainOpen proves nothing */
483 SecKeychainStatus kcStat;
484 ortn = SecKeychainGetStatus(kcRef, &kcStat);
485 if(ortn) {
486 cssmPerror("SecKeychainGetStatus", ortn);
487 goto done;
488 }
489 }
490
491 if(password == NULL) {
492 const char *pwdp = getpass("Enter .mac password: ");
493 if(pwdp == NULL) {
494 printf("Aboerting.\n");
495 ortn = paramErr;
496 goto done;
497 }
498 memmove(pwdBuf, pwdp, strlen(pwdp) + 1);
499 password = pwdBuf;
500 }
501 certReq.password.Data = (uint8 *)password;
502 certReq.password.Length = strlen(password);
503 certReq.userName.Data = (uint8 *)userName;
504 certReq.userName.Length = strlen(userName);
505
506 if(csrInName) {
507 unsigned len;
508 if(readFile(csrInName, &certReq.csr.Data, &len)) {
509 printf("***Error reading CSR from %s. Aborting.\n", csrInName);
510 exit(1);
511 }
512 certReq.csr.Length = len;
513 certReq.flags |= CSSM_DOTMAC_TP_EXIST_CSR;
514 }
515 else {
516 /*
517 * All the stuff the TP needs to actually generate a CSR.
518 *
519 * Get a key pair, somehow.
520 */
521 if(genKeys) {
522 ortn = genKeyPair(kcRef, &pubKeyRef, &privKeyRef);
523 }
524 else {
525 ortn = keyPicker(kcRef, &pubKeyRef, &privKeyRef);
526 }
527 if(ortn) {
528 printf("Can't proceed without a keypair. Aborting.\n");
529 exit(1);
530 }
531 ortn = SecKeyGetCSSMKey(pubKeyRef, &pubKey);
532 if(ortn) {
533 cssmPerror("SecKeyGetCSSMKey", ortn);
534 goto done;
535 }
536 ortn = SecKeyGetCSSMKey(privKeyRef, &privKey);
537 if(ortn) {
538 cssmPerror("SecKeyGetCSSMKey", ortn);
539 goto done;
540 }
541 ortn = SecKeyGetCSPHandle(privKeyRef, &cspHand);
542 if(ortn) {
543 cssmPerror("SecKeyGetCSPHandle", ortn);
544 goto done;
545 }
546
547 /* CSSM_X509_TYPE_VALUE_PAIR - one pair for now */
548 // tvp.type = CSSMOID_EmailAddress;
549 tvp.type = CSSMOID_CommonName;
550 tvp.valueType = BER_TAG_PRINTABLE_STRING;
551 #if FULL_EMAIL_ADDRESS
552 {
553 unsigned nameLen = strlen(userName);
554 tvp.value.Data = (uint8 *)malloc(nameLen + strlen("@mac.com") + 1);
555 strcpy((char *)tvp.value.Data, userName);
556 strcpy((char *)tvp.value.Data + nameLen, "@mac.com");
557 tvp.value.Length = strlen((char *)tvp.value.Data);
558 }
559 #else
560 tvp.value.Data = (uint8 *)userName;
561 tvp.value.Length = strlen(userName);
562 #endif
563 }
564 /* set up args for CSSM_TP_SubmitCredRequest */
565 if(hostName != NULL) {
566 tpAuthority.AuthorityCert = NULL;
567 tpAuthority.AuthorityLocation = &tpNetAddrs;
568 tpNetAddrs.AddressType = CSSM_ADDR_NAME;
569 tpNetAddrs.Address.Data = (uint8 *)hostName;
570 tpNetAddrs.Address.Length = strlen(hostName);
571 tpAuthPtr = &tpAuthority;
572 };
573
574 certReq.version = CSSM_DOT_MAC_TP_REQ_VERSION;
575 if(!csrInName) {
576 certReq.cspHand = cspHand;
577 certReq.clHand = cuClStartup();
578 certReq.numTypeValuePairs = 1;
579 certReq.typeValuePairs = &tvp;
580 certReq.publicKey = (CSSM_KEY_PTR)pubKey;
581 certReq.privateKey = (CSSM_KEY_PTR)privKey;
582 }
583 if(doNotPost) {
584 certReq.flags |= CSSM_DOTMAC_TP_DO_NOT_POST;
585 }
586 if(csrOutName != NULL) {
587 certReq.flags |= CSSM_DOTMAC_TP_RETURN_CSR;
588 }
589 if(doRenew) {
590 certReq.flags |= CSSM_DOTMAC_TP_SIGN_RENEW;
591 }
592
593 reqSet.NumberOfRequests = 1;
594 reqSet.Requests = &certReq;
595
596 policyField.FieldOid = *opOid;
597 policyField.FieldValue.Data = NULL;
598 policyField.FieldValue.Length = 0;
599 memset(&callerAuth, 0, sizeof(callerAuth));
600 callerAuth.Policy.NumberOfPolicyIds = 1;
601 callerAuth.Policy.PolicyIds = &policyField;
602 if(!csrInName) {
603 ortn = SecKeyGetCredentials(privKeyRef,
604 CSSM_ACL_AUTHORIZATION_SIGN,
605 kSecCredentialTypeDefault,
606 const_cast<const CSSM_ACCESS_CREDENTIALS **>(&callerAuth.CallerCredentials));
607 if(ortn) {
608 cssmPerror("SecKeyGetCredentials", crtn);
609 goto done;
610 }
611 }
612
613 crtn = CSSM_TP_SubmitCredRequest (tpHand,
614 tpAuthPtr,
615 CSSM_TP_AUTHORITY_REQUEST_CERTISSUE, // CSSM_TP_AUTHORITY_REQUEST_TYPE
616 &reqSet, // const CSSM_TP_REQUEST_SET *RequestInput,
617 &callerAuth,
618 &estTime, // sint32 *EstimatedTime,
619 &refId); // CSSM_DATA_PTR ReferenceIdentifier
620 switch(crtn) {
621 case CSSM_OK:
622 case CSSMERR_APPLE_DOTMAC_REQ_QUEUED:
623 {
624 /*
625 * refId should be a cert or RefId
626 */
627 const char *itemType = "Cert";
628 const char *statStr = "OK";
629 if(crtn != CSSM_OK) {
630 itemType = "RefId";
631 statStr = "Cert";
632 }
633 if((refId.Data == NULL) || (refId.Length == 0)) {
634 printf("CSSM_TP_SubmitCredRequest returned %s but no data\n", statStr);
635 break;
636 }
637 if(crtn == CSSM_OK) {
638 printf("...cert acquisition complete\n");
639 }
640 else {
641 printf("...Cert request QUEUED\n");
642 }
643 if(outFile) {
644 if(!writeFile(outFile, refId.Data, refId.Length)) {
645 if(!quiet) {
646 printf("...%lu bytes of %s written to %s\n",
647 refId.Length, itemType, outFile);
648 }
649 }
650 else {
651 printf("***Error writing %s to %s\n", itemType, outFile);
652 crtn = ioErr;
653 }
654 }
655 else if(verbose) {
656 if(crtn == CSSM_OK) {
657 unsigned char *der;
658 unsigned derLen;
659 if(pemDecode(refId.Data, refId.Length, &der, &derLen)) {
660 printf("***Error PEM decoding returned cert\n");
661 }
662 else {
663 printCert(der, derLen, CSSM_FALSE);
664 free(der);
665 }
666 }
667 else {
668 printf("RefId data:\n");
669 snDumpText(refId.Data, refId.Length);
670 }
671 }
672 break;
673 }
674 case CSSMERR_APPLE_DOTMAC_REQ_REDIRECT:
675 if((refId.Data == NULL) || (refId.Length == 0)) {
676 printf("CSSM_TP_SubmitCredRequest returned REDIRECT but no data\n");
677 break;
678 }
679 printf("...cert acquisition : REDIRECTED to: ");
680 snDumpText(refId.Data, refId.Length);
681 printf("\n");
682 break;
683 default:
684 cssmPerror("CSSM_TP_SubmitCredRequest", crtn);
685 break;
686 }
687 if(csrOutName) {
688 if((certReq.csr.Data == NULL) || (certReq.csr.Length == 0)) {
689 printf("***Asked for CSR but didn't get one\n");
690 ortn = paramErr;
691 goto done;
692 }
693 if(writeFile(csrOutName, certReq.csr.Data, certReq.csr.Length)) {
694 printf("***Error writing CSR to %s.\n", csrOutName);
695 }
696 else {
697 printf("...%lu bytes written as CSR to %s\n", certReq.csr.Length, csrOutName);
698 }
699 }
700 done:
701 /* cleanup */
702 CSSM_ModuleDetach(tpHand);
703 if(certReq.clHand) {
704 CSSM_ModuleDetach(certReq.clHand);
705 }
706 if(kcRef) {
707 CFRelease(kcRef);
708 }
709 if(csrInName) {
710 free(certReq.csr.Data);
711 }
712 if(privKeyRef) {
713 CFRelease(privKeyRef);
714 }
715 if(pubKeyRef) {
716 CFRelease(pubKeyRef);
717 }
718 if(refId.Data) {
719 cuAppFree(refId.Data, NULL);
720 }
721 if(doPause) {
722 fpurge(stdin);
723 printf("Pausing for MallocDebug measurement; CR to continue: ");
724 getchar();
725 }
726
727 return ortn;
728 }