]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/rootStoreTool/rootStoreTool.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / rootStoreTool / rootStoreTool.cpp
1 /*
2 * rootStoreTool.cpp - exercise SecTrustSettings API
3 */
4
5 #include <stdlib.h>
6 #include <strings.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <Security/Security.h>
10 #include <Security/SecTrustSettings.h>
11 #include <Security/SecTrustPriv.h>
12 #include <Security/TrustSettingsSchema.h>
13 #include <Security/SecTrustSettingsPriv.h>
14 #include <Security/cssmapplePriv.h>
15 #include <Security/SecPolicyPriv.h>
16 #include <security_cdsa_utils/cuFileIo.h>
17 #include <security_utilities/cfutilities.h>
18 #include <security_cdsa_utils/cuPrintCert.h>
19 #include <security_cdsa_utils/cuOidParser.h>
20 #include "parseTrustedRootList.h"
21 #include <Security/TrustSettingsSchema.h> /* private header */
22 #include "rootUtils.h"
23 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
24 #include <pthread.h>
25 #include <sys/param.h>
26
27 static void usage(char **argv)
28 {
29 printf("usage: %s op [options]\n", argv[0]);
30 printf("Op values:\n");
31 printf(" a -- add cert\n");
32 printf(" p -- parse TrustSettings record\n");
33 printf(" r -- get certs from TS & display\n");
34 printf(" d -- delete entries from TS interactively\n");
35 printf(" D -- delete ALL certs from TS (requires -R argument)\n");
36 printf(" R -- remove legacy User Trust setting\n");
37
38 printf("Options:\n");
39 printf(" -c certFile -- specify cert\n");
40 printf(" -s -- system TrustSettings; default is user\n");
41 printf(" -d -- Admin TrustSettings; default is user\n");
42 printf(" -t settingsFile -- settings from file; default is user\n");
43 printf(" -T settingsFileOut -- settings to file\n");
44 printf(" -a appPath -- specify app constraints\n");
45 printf(" -p policy -- specify policy constraint\n");
46 printf(" policy = ssl, smime, swuSign, codeSign, IPSec, iChat\n");
47 printf(" -P appPath policy -- specify app AND policy constraint\n");
48 printf(" -e emailAddress -- specify SMIME policy plus email address\n");
49 printf(" -L hostname -- specify SSL policy plus hostname\n");
50 printf(" -r resultType -- resultType = trust, trustAsRoot, deny, unspecified\n");
51 printf(" -w allowErr -- allowed error, an integer; implies result unspecified\n");
52 printf(" -W allowErr policy -- allowed error AND policy AND implies result unspecified\n");
53 printf(" -u keyUsage -- key usage, an integer\n");
54 printf(" -k keychain -- Default is default keychain.\n");
55 printf(" -R -- Really. For Delete All op.\n");
56 printf(" -v -- verbose cert display\n");
57 printf(" -A -- add cert to keychain\n");
58 printf(" -U -- use SecTrustSetUserTrust\n");
59 printf(" -2 -- use SecTrustSetUserTrustLegacy\n");
60 printf(" -l -- loop and pause for malloc debug\n");
61 printf(" -h -- help\n");
62 exit(1);
63 }
64
65 /*
66 * Start up a CFRunLoop. This is needed to field keychain event callbacks, used
67 * to maintain root cert cache coherency. This operation is only needed in command
68 * line tools; regular GUI apps already have a CFRunLoop.
69 */
70
71 /* first we need something to register so we *have* a run loop */
72 static OSStatus kcCacheCallback (
73 SecKeychainEvent keychainEvent,
74 SecKeychainCallbackInfo *info,
75 void *context)
76 {
77 return noErr;
78 }
79
80 /* main thread has to wait for this to be set to know a run loop has been set up */
81 static int runLoopInitialized = 0;
82
83 /* this is the thread which actually runs the CFRunLoop */
84 void *cfRunLoopThread(void *arg)
85 {
86 OSStatus ortn = SecKeychainAddCallback(kcCacheCallback,
87 kSecTrustSettingsChangedEventMask, NULL);
88 if(ortn) {
89 printf("registerCacheCallbacks: SecKeychainAddCallback returned %ld", ortn);
90 /* Not sure how this could ever happen - maybe if there is no run loop active? */
91 return NULL;
92 }
93 runLoopInitialized = 1;
94 CFRunLoopRun();
95 /* should not be reached */
96 printf("\n*** Hey! CFRunLoopRun() exited!***\n");
97 return NULL;
98 }
99
100 static int startCFRunLoop()
101 {
102 pthread_t runLoopThread;
103
104 int result = pthread_create(&runLoopThread, NULL, cfRunLoopThread, NULL);
105 if(result) {
106 printf("***pthread_create returned %d, aborting\n", result);
107 return -1;
108 }
109 return 0;
110 }
111
112 static SecCertificateRef certFromFile(
113 const char *fileName)
114 {
115 unsigned char *cp = NULL;
116 unsigned len = 0;
117 if(readFile(fileName, &cp, &len)) {
118 printf("***Error reading file %s\n", fileName);
119 return NULL;
120 }
121 SecCertificateRef certRef;
122 CSSM_DATA certData = {len, cp};
123 OSStatus ortn = SecCertificateCreateFromData(&certData,
124 CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &certRef);
125 if(ortn) {
126 cssmPerror("SecCertificateCreateFromData", ortn);
127 return NULL;
128 }
129 free(cp);
130 return certRef;
131 }
132
133 /*
134 * Display usage constraints array as obtained from
135 * SecTrustSettingsCopyTrustSettings().
136 */
137 static int displayTrustSettings(
138 CFArrayRef trustSettings,
139 OidParser &parser)
140 {
141 /* must always be there though it may be empty */
142 if(trustSettings == NULL) {
143 printf("***displayTrustSettings: missing trust settings array");
144 return -1;
145 }
146 if(CFGetTypeID(trustSettings) != CFArrayGetTypeID()) {
147 printf("***displayTrustSettings: malformed trust settings array");
148 return -1;
149 }
150
151 int ourRtn = 0;
152 CFIndex numUseConstraints = CFArrayGetCount(trustSettings);
153 indentIncr();
154 indent(); printf("Number of trust settings : %ld\n", numUseConstraints);
155 OSStatus ortn;
156 SecPolicyRef certPolicy;
157 SecTrustedApplicationRef certApp;
158 CFDictionaryRef ucDict;
159 CFStringRef policyStr;
160 CFNumberRef cfNum;
161
162 /* grind thru the trust settings dictionaries */
163 for(CFIndex ucDex=0; ucDex<numUseConstraints; ucDex++) {
164 indent(); printf("Trust Setting %ld:\n", ucDex);
165 indentIncr();
166
167 ucDict = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, ucDex);
168 if(CFGetTypeID(ucDict) != CFDictionaryGetTypeID()) {
169 printf("***displayTrustSettings: malformed usage constraints dictionary");
170 ourRtn = -1;
171 goto nextAp;
172 }
173
174 /* policy - optional */
175 certPolicy = (SecPolicyRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsPolicy);
176 if(certPolicy != NULL) {
177 if(CFGetTypeID(certPolicy) != SecPolicyGetTypeID()) {
178 printf("***displayTrustSettings: malformed certPolicy");
179 ourRtn = -1;
180 goto nextAp;
181 }
182 CSSM_OID policyOid;
183 ortn = SecPolicyGetOID(certPolicy, &policyOid);
184 if(ortn) {
185 cssmPerror("SecPolicyGetOID", ortn);
186 ourRtn = -1;
187 goto nextAp;
188 }
189 indent(); printf("Policy OID : ");
190 printOid(policyOid.Data, policyOid.Length, parser);
191 printf("\n");
192 }
193
194 /* app - optional */
195 certApp = (SecTrustedApplicationRef)CFDictionaryGetValue(ucDict,
196 kSecTrustSettingsApplication);
197 if(certApp != NULL) {
198 if(CFGetTypeID(certApp) != SecTrustedApplicationGetTypeID()) {
199 printf("***displayTrustSettings: malformed certApp");
200 ourRtn = -1;
201 goto nextAp;
202 }
203 CFRef<CFDataRef> appPath;
204 ortn = SecTrustedApplicationCopyData(certApp, appPath.take());
205 if(ortn) {
206 cssmPerror("SecTrustedApplicationCopyData", ortn);
207 ourRtn = -1;
208 goto nextAp;
209 }
210 indent(); printf("Application : %s", CFDataGetBytePtr(appPath));
211 printf("\n");
212 }
213
214 /* policy string */
215 policyStr = (CFStringRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsPolicyString);
216 if(policyStr != NULL) {
217 if(CFGetTypeID(policyStr) != CFStringGetTypeID()) {
218 printf("***displayTrustSettings: malformed policyStr");
219 ourRtn = -1;
220 goto nextAp;
221 }
222 indent(); printf("Policy String : ");
223 printCfStr(policyStr); printf("\n");
224 }
225
226 /* Allowed error */
227 cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsAllowedError);
228 if(cfNum != NULL) {
229 if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) {
230 printf("***displayTrustSettings: malformed allowedError");
231 ourRtn = -1;
232 goto nextAp;
233 }
234 indent(); printf("Allowed Error : ");
235 printCssmErr(cfNum); printf("\n");
236 }
237
238 /* Result */
239 cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsResult);
240 if(cfNum != NULL) {
241 if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) {
242 printf("***displayTrustSettings: malformed Result");
243 ourRtn = -1;
244 goto nextAp;
245 }
246 indent(); printf("Result Type : ");
247 printResult(cfNum); printf("\n");
248 }
249
250 /* key usage */
251 cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsKeyUsage);
252 if(cfNum != NULL) {
253 if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) {
254 printf("***displayTrustSettings: malformed keyUsage");
255 ourRtn = -1;
256 goto nextAp;
257 }
258 indent(); printf("Key Usage : ");
259 printKeyUsage(cfNum); printf("\n");
260 }
261
262 nextAp:
263 indentDecr();
264 }
265 indentDecr();
266 return ourRtn;
267 }
268
269 /* convert an OID to a SecPolicyRef */
270 static SecPolicyRef oidToPolicy(
271 const CSSM_OID &oid)
272 {
273 SecPolicyRef policyRef = NULL;
274
275 OSStatus ortn = SecPolicyCopy(CSSM_CERT_X_509v3, &oid, &policyRef);
276 if(ortn) {
277 cssmPerror("SecPolicyCopy", ortn);
278 return NULL;
279 }
280 return policyRef;
281 }
282
283 /* Convert cmdline policy string to SecPolicyRef */
284 static SecPolicyRef policyStringToPolicy(
285 const char *policy)
286 {
287 if(policy == NULL) {
288 return NULL;
289 }
290 const CSSM_OID *oid = NULL;
291 if(!strcmp(policy, "ssl")) {
292 oid = &CSSMOID_APPLE_TP_SSL;
293 }
294 else if(!strcmp(policy, "smime")) {
295 oid = &CSSMOID_APPLE_TP_SMIME;
296 }
297 else if(!strcmp(policy, "codeSign")) {
298 oid = &CSSMOID_APPLE_TP_CODE_SIGNING;
299 }
300 else if(!strcmp(policy, "swuSign")) {
301 oid = &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING;
302 }
303 else if(!strcmp(policy, "IPSec")) {
304 oid = &CSSMOID_APPLE_TP_IP_SEC;
305 }
306 else if(!strcmp(policy, "iChat")) {
307 oid = &CSSMOID_APPLE_TP_ICHAT;
308 }
309 else {
310 printf("***Unknown policy string (%s)\n", policy);
311 return NULL;
312 }
313
314 /* OID to SecPolicyRef */
315 return oidToPolicy(*oid);
316 }
317
318 static int appendConstraintToArray(
319 const char *appPath, /* optional, "-" means ensure apArray is nonempty */
320 const char *policy, /* optional (ssl/smime), "-" as above */
321 const char *policyStr, /* optional policy string */
322 const SInt32 *allowErr, /* optional allowed error */
323 const char *resultType, /* optional allow/confirm/deny */
324 SecTrustSettingsKeyUsage keyUse, /* optional key use */
325 CFMutableArrayRef &array) /* result RETURNED here, created if necessary */
326 {
327 if(array == NULL) {
328 array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
329 }
330
331 CFMutableDictionaryRef outDict = CFDictionaryCreateMutable(NULL,
332 0, // capacity
333 &kCFTypeDictionaryKeyCallBacks,
334 &kCFTypeDictionaryValueCallBacks);
335
336 if((policy != NULL) && (strcmp(policy, "-"))) {
337
338 /* policy string to SecPolicyRef */
339 SecPolicyRef policyRef = policyStringToPolicy(policy);
340 if(policyRef == NULL) {
341 return -1;
342 }
343 CFDictionaryAddValue(outDict, kSecTrustSettingsPolicy, policyRef);
344 CFRelease(policyRef);
345 }
346
347 /* app string to SecTrustedApplicationRef */
348 if((appPath != NULL) && (strcmp(appPath, "-"))) {
349 SecTrustedApplicationRef appRef;
350 OSStatus ortn = SecTrustedApplicationCreateFromPath(appPath, &appRef);
351 if(ortn) {
352 cssmPerror("SecTrustedApplicationCreateFromPath", ortn);
353 return -1;
354 }
355 CFDictionaryAddValue(outDict, kSecTrustSettingsApplication, appRef);
356 CFRelease(appRef);
357 }
358
359 if(policyStr != NULL) {
360 CFStringRef pstr = CFStringCreateWithCString(NULL, policyStr, kCFStringEncodingASCII);
361 CFDictionaryAddValue(outDict, kSecTrustSettingsPolicyString, pstr);
362 CFRelease(pstr);
363 }
364
365 if(allowErr != NULL) {
366 CFNumberRef cfNum = CFNumberCreate(NULL, kCFNumberSInt32Type, allowErr);
367 CFDictionaryAddValue(outDict, kSecTrustSettingsAllowedError, cfNum);
368 CFRelease(cfNum);
369 }
370
371 if(keyUse != 0) {
372 SInt32 ku = (SInt32)ku;
373 CFNumberRef cfNum = CFNumberCreate(NULL, kCFNumberSInt32Type, &ku);
374 CFDictionaryAddValue(outDict, kSecTrustSettingsKeyUsage, cfNum);
375 CFRelease(cfNum);
376 }
377
378 if(resultType != NULL) {
379 SInt32 n;
380
381 if(!strcmp(resultType, "trust")) {
382 n = kSecTrustSettingsResultTrustRoot;
383 }
384 else if(!strcmp(resultType, "trustAsRoot")) {
385 n = kSecTrustSettingsResultTrustAsRoot;
386 }
387 else if(!strcmp(resultType, "deny")) {
388 n = kSecTrustSettingsResultDeny;
389 }
390 else if(!strcmp(resultType, "unspecified")) {
391 n = kSecTrustSettingsResultUnspecified;
392 }
393 else {
394 printf("***unknown resultType spec (%s)\n", resultType);
395 return -1;
396 }
397 CFNumberRef cfNum = CFNumberCreate(NULL, kCFNumberSInt32Type, &n);
398 CFDictionaryAddValue(outDict, kSecTrustSettingsResult, cfNum);
399 CFRelease(cfNum);
400 }
401
402 /* append dictionary to output */
403 CFArrayAppendValue(array, outDict);
404 /* array owns the dictionary now */
405 CFRelease(outDict);
406 return 0;
407 }
408
409 /* read a file --> CFDataRef */
410 CFDataRef readFileCFData(
411 const char *fileName)
412 {
413 int rtn;
414 unsigned char *fileData = NULL;
415 unsigned fileDataLen = 0;
416
417 rtn = readFile(fileName, &fileData, &fileDataLen);
418 if(rtn) {
419 printf("Error (%d) reading %s.\n", rtn, fileName);
420 return NULL;
421 }
422 CFDataRef cfd = CFDataCreate(NULL, (const UInt8 *)fileData, fileDataLen);
423 free(fileData);
424 return cfd;
425 }
426
427 static int fetchParseTrustRecord(
428 SecTrustSettingsDomain domain,
429 char *settingsFile) /* optional, ignore domain if present */
430 {
431 CFDataRef trustSettings = NULL;
432
433 if(settingsFile) {
434 trustSettings = readFileCFData(settingsFile);
435 if(trustSettings == NULL) {
436 return -1;
437 }
438 }
439 else {
440 OSStatus ortn = SecTrustSettingsCreateExternalRepresentation(domain, &trustSettings);
441 if(ortn) {
442 cssmPerror("SecTrustSettingsCreateExternalRepresentation", ortn);
443 return -1;
444 }
445 }
446 int rtn = parseTrustedRootList(trustSettings);
447 CFRelease(trustSettings);
448 return rtn;
449 }
450
451 static int copyCertsAndDisplay(
452 bool verbose,
453 SecTrustSettingsDomain domain)
454 {
455 OSStatus ortn;
456
457 auto_ptr<OidParser> parser(NULL);
458
459 if(verbose) {
460 parser.reset(new OidParser);
461 }
462
463 CFArrayRef certArray = NULL;
464 ortn = SecTrustSettingsCopyCertificates(domain, &certArray);
465 if(ortn) {
466 cssmPerror("SecTrustSettingsCopyCertificates", ortn);
467 return ortn;
468 }
469
470 CFIndex numCerts = CFArrayGetCount(certArray);
471 indent();
472 printf("Num certs = %ld\n", numCerts);
473 int ourRtn = 0;
474 for(CFIndex dex=0; dex<numCerts; dex++) {
475 SecCertificateRef certRef = (SecCertificateRef)CFArrayGetValueAtIndex(certArray, dex);
476 if(CFGetTypeID(certRef) != SecCertificateGetTypeID()) {
477 printf("***Bad CFGetTypeID for cert\n");
478 return -1;
479 }
480 indent();
481 printf("Cert %ld: ", dex);
482 printCertLabel(certRef);
483 printf("\n");
484 if(verbose) {
485 CFRef<CFArrayRef> appPolicies;
486 ortn = SecTrustSettingsCopyTrustSettings(certRef, domain, appPolicies.take());
487 if(ortn) {
488 cssmPerror("SecRootCertificateCopyAppPolicyConstraints", ortn);
489 ourRtn = -1;
490 continue;
491 }
492 if(displayTrustSettings(appPolicies, *parser.get())) {
493 ourRtn = -1;
494 }
495 }
496 }
497 CFRelease(certArray);
498 return ourRtn;
499 }
500
501 static int deleteCerts(
502 SecTrustSettingsDomain domain,
503 bool deleteAll)
504 {
505 OSStatus ortn;
506
507 CFArrayRef certArray = NULL;
508 ortn = SecTrustSettingsCopyCertificates(domain, &certArray);
509 if(ortn) {
510 cssmPerror("SecTrustSettingsCopyCertificates", ortn);
511 return ortn;
512 }
513
514 CFIndex numCerts = CFArrayGetCount(certArray);
515 unsigned numDeleted = 0;
516
517 for(CFIndex dex=0; dex<numCerts; dex++) {
518 SecCertificateRef certRef = (SecCertificateRef)CFArrayGetValueAtIndex(certArray, dex);
519 if(CFGetTypeID(certRef) != SecCertificateGetTypeID()) {
520 printf("***Bad CFGetTypeID for cert\n");
521 return -1;
522 }
523 bool doDelete = false;
524
525 if(deleteAll) {
526 printf("DELETING: ");
527 printCertLabel(certRef);
528 printf("\n");
529 doDelete = true;
530 }
531 else {
532 indent();
533 printf("Cert %ld: ", dex);
534 printCertLabel(certRef);
535 printf("\n");
536 fpurge(stdin);
537 printf("Delete (y/anything)? ");
538 char resp = getchar();
539 if(resp == 'y') {
540 doDelete = true;
541 }
542 }
543 if(doDelete) {
544 ortn = SecTrustSettingsRemoveTrustSettings(certRef, domain);
545 if(ortn) {
546 cssmPerror("SecTrustSettingsRemoveTrustSettings", ortn);
547 fpurge(stdin);
548 printf("Continue deleting (y/anything)? ");
549 char resp = getchar();
550 fflush(stdout);
551 if(resp != 'y') {
552 return ortn;
553 }
554 }
555 else {
556 numDeleted++;
557 }
558 }
559 }
560 CFRelease(certArray);
561 printf("...%u certs deleted\n", numDeleted);
562 return noErr;
563 }
564
565 /* add a cert to trust list */
566 static int addCert(
567 SecCertificateRef certRef,
568 SecTrustSettingsDomain domain,
569 bool addToKc, // import cert to keychain
570 const char *kcName, // only for addToKC option
571 CFArrayRef trustSettings,
572 CFDataRef settingsIn, // optional, requires settingsFileOut
573 CFDataRef *settingsOut)
574 {
575 OSStatus ortn;
576 char *domainName;
577
578 if(settingsIn && !settingsOut) {
579 printf("Modifying trust settings as file requires output file\n");
580 return -1;
581 }
582 switch(domain) {
583 case kSecTrustSettingsDomainSystem:
584 printf("***Can't modify system trust settings.\n");
585 return -1;
586 case kSecTrustSettingsDomainAdmin:
587 kcName = "/Library/Keychains/System.keychain";
588 domainName = "Admin";
589 break;
590 default:
591 domainName = "User";
592 break;
593 }
594 if(addToKc) {
595 SecKeychainRef kcRef = NULL;
596 if(kcName) {
597 ortn = SecKeychainOpen(kcName, &kcRef);
598 if(ortn) {
599 cssmPerror("SecKeychainOpen", ortn);
600 return -1;
601 }
602 }
603 ortn = SecCertificateAddToKeychain(certRef, kcRef);
604 if(ortn) {
605 cssmPerror("SecCertificateAddToKeychain", ortn);
606 return -1;
607 }
608 printf("...cert added to keychain %s\n", (kcName ? kcName : "<default>"));
609 }
610 if(settingsIn) {
611 ortn = SecTrustSettingsSetTrustSettingsExternal(settingsIn,
612 certRef, trustSettings, settingsOut);
613 if(ortn) {
614 cssmPerror("SecTrustSettingsSetTrustSettingsExternal", ortn);
615 return -1;
616 }
617 }
618 else {
619 ortn = SecTrustSettingsSetTrustSettings(certRef, domain, trustSettings);
620 if(ortn) {
621 cssmPerror("SecTrustSettingsSetTrustSettings", ortn);
622 return -1;
623 }
624 printf("...cert added to %s TrustList.\n", domainName);
625 }
626 return 0;
627 }
628
629 static int addCertLegacy(
630 SecCertificateRef certRef,
631 const char *policy,
632 const char *resultStr,
633 bool useLegacy)
634 {
635 /* OID string to an OID pointer */
636 if(policy == NULL) {
637 printf("***You must specify a policy to set legacy User Trust\n");
638 return 1;
639 }
640 SecPolicyRef policyRef = policyStringToPolicy(policy);
641 if(policyRef == NULL) {
642 return -1;
643 }
644
645 /* result string to legacy SecTrustUserSetting */
646 SecTrustUserSetting setting = kSecTrustResultInvalid;
647 if(resultStr == NULL) {
648 setting = kSecTrustResultProceed;
649 }
650 else if(!strcmp(resultStr, "trust")) {
651 setting = kSecTrustResultProceed;
652 }
653 else if(!strcmp(resultStr, "trustAsRoot")) {
654 setting = kSecTrustResultProceed;
655 }
656 else if(!strcmp(resultStr, "deny")) {
657 setting = kSecTrustResultDeny;
658 }
659 else if (!strcmp(resultStr, "unspecified")) {
660 setting = kSecTrustResultUnspecified;
661 }
662 else {
663 printf("***Can't map %s to a SecTrustUserSetting\n", resultStr);
664 return -1;
665 }
666 OSStatus ortn;
667 if(useLegacy) {
668 ortn = SecTrustSetUserTrustLegacy(certRef, policyRef, setting);
669 if(ortn) {
670 cssmPerror("SecTrustSetUserTrustLegacy", ortn);
671 }
672 else {
673 if(setting == kSecTrustResultUnspecified) {
674 printf("...User Trust removed via SecTrustSetUserTrustLegacy().\n");
675 }
676 else {
677 printf("...User Trust set via SecTrustSetUserTrustLegacy().\n");
678 }
679 }
680 }
681 else {
682 #if 1
683 printf("...Legacy implementation needs Makefile work to avoid deprecation error\n");
684 exit(1);
685 #else
686 ortn = SecTrustSetUserTrust(certRef, policyRef, setting);
687 if(ortn) {
688 cssmPerror("SecTrustSetUserTrust", ortn);
689 }
690 else {
691 printf("...trust setting set via SecTrustSetUserTrust().\n");
692 }
693 #endif
694 }
695 if(policyRef != NULL) {
696 CFRelease(policyRef);
697 }
698 return ortn;
699 }
700
701 int main(int argc, char **argv)
702 {
703 int arg;
704 CFMutableArrayRef appPolicies = NULL;
705 CFDataRef settingsIn = NULL;
706 CFDataRef settingsOut = NULL;
707
708 /* user-spec'd variables */
709 bool loopPause = false;
710 bool really = false;
711 bool verbose = false;
712 char *kcName = NULL;
713 SecTrustSettingsDomain domain = kSecTrustSettingsDomainUser;
714 SecCertificateRef certRef = NULL;
715 bool addToKeychain = false;
716 char *settingsFileIn = NULL;
717 char *settingsFileOut = NULL;
718 bool userTrustLegacy = false;
719 char *policyStr = NULL;
720 char *resultStr = NULL;
721 bool userTrust = false;
722
723 extern char *optarg;
724 extern int optind;
725 optind = 2;
726 while ((arg = getopt(argc, argv, "c:sdt:T:a:p:P:e:L:r:w:W:k:u:RvAU2lh")) != -1) {
727 switch (arg) {
728 case 'c':
729 if(certRef) {
730 printf("***Only one cert at a time, please.\n");
731 usage(argv);
732 }
733 certRef = certFromFile(optarg);
734 if(certRef == NULL) {
735 exit(1);
736 }
737 break;
738 case 's':
739 domain = kSecTrustSettingsDomainSystem;
740 break;
741 case 'd':
742 domain = kSecTrustSettingsDomainAdmin;
743 break;
744 case 't':
745 settingsFileIn = optarg;
746 break;
747 case 'T':
748 settingsFileOut = optarg;
749 break;
750 case 'a':
751 if(appendConstraintToArray(optarg, NULL, NULL, NULL, NULL, 0, appPolicies)) {
752 exit(1);
753 }
754 break;
755 case 'p':
756 if(appendConstraintToArray(NULL, optarg, NULL, NULL, NULL, 0, appPolicies)) {
757 exit(1);
758 }
759 policyStr = optarg;
760 break;
761 case 'P':
762 /* this takes an additional argument */
763 if(optind > (argc - 1)) {
764 usage(argv);
765 }
766 if(appendConstraintToArray(optarg, argv[optind], NULL, NULL, NULL,
767 0, appPolicies)) {
768 exit(1);
769 }
770 optind++;
771 break;
772 case 'e':
773 if(appendConstraintToArray(NULL, "smime", optarg, NULL, NULL,
774 0, appPolicies)) {
775 exit(1);
776 }
777 policyStr = "smime";
778 break;
779 case 'L':
780 if(appendConstraintToArray(NULL, "ssl", optarg, NULL, NULL, 0, appPolicies)) {
781 exit(1);
782 }
783 policyStr = "ssl";
784 break;
785 case 'r':
786 if(appendConstraintToArray(NULL, NULL, NULL, NULL, optarg, 0, appPolicies)) {
787 exit(1);
788 }
789 resultStr = optarg;
790 break;
791 case 'w':
792 {
793 SInt32 l = atol(optarg);
794 if(appendConstraintToArray(NULL, NULL, NULL, &l, "unspecified", 0, appPolicies)) {
795 exit(1);
796 }
797 break;
798 }
799 case 'W':
800 {
801 /* this takes an additional argument */
802 if(optind > (argc - 1)) {
803 usage(argv);
804 }
805 SInt32 l = atol(optarg);
806 if(appendConstraintToArray(NULL, argv[optind], NULL, &l, "unspecified", 0,
807 appPolicies)) {
808 exit(1);
809 }
810 optind++;
811 break;
812 }
813 case 'u':
814 {
815 SInt32 l = atol(optarg);
816 SecTrustSettingsKeyUsage ku = (SecTrustSettingsKeyUsage)l;
817 if(appendConstraintToArray(NULL, NULL, NULL, NULL, NULL, ku, appPolicies)) {
818 exit(1);
819 }
820 break;
821 }
822 case 'k':
823 kcName = optarg;
824 break;
825 case 'R':
826 really = true;
827 break;
828 case 'v':
829 verbose = true;
830 break;
831 case 'A':
832 addToKeychain = true;
833 break;
834 case 'l':
835 loopPause = true;
836 break;
837 case '2':
838 userTrustLegacy = true;
839 break;
840 case 'U':
841 userTrust = true;
842 break;
843 default:
844 case 'h':
845 usage(argv);
846 }
847 }
848 if(optind != argc) {
849 usage(argv);
850 }
851 if(startCFRunLoop()) {
852 /* enable reception of KC event messages */
853 exit(1);
854 }
855
856 /* give that thread a chance right now */
857 while(!runLoopInitialized) {
858 usleep(1000);
859 };
860
861 int ortn = 0;
862 do {
863 switch(argv[1][0]) {
864 case 'a':
865 if(certRef == NULL) {
866 printf("You must supply a cert.\n");
867 usage(argv);
868 }
869 if(settingsFileIn) {
870 if(!settingsFileOut) {
871 printf("Modifying trust settings as file requires output file\n");
872 return -1;
873 }
874 settingsIn = readFileCFData(settingsFileIn);
875 if(!settingsIn) {
876 return -1;
877 }
878 }
879 if(userTrustLegacy || userTrust) {
880 ortn = addCertLegacy(certRef, policyStr, resultStr, userTrustLegacy);
881 }
882 else {
883 ortn = addCert(certRef, domain, addToKeychain, kcName, appPolicies,
884 settingsIn, &settingsOut);
885 if((ortn == noErr) && (settingsOut != NULL)) {
886 unsigned len = CFDataGetLength(settingsOut);
887 if(writeFile(settingsFileOut, CFDataGetBytePtr(settingsOut), len)) {
888 printf("***Error writing settings to %s\n", settingsFileOut);
889 }
890 else {
891 printf("...wrote %u bytes to %s\n", len, settingsFileOut);
892 }
893 }
894 }
895 if(settingsIn) {
896 CFRelease(settingsIn);
897 }
898 if(settingsOut) {
899 CFRelease(settingsOut);
900 }
901 break;
902 case 'p':
903 ortn = fetchParseTrustRecord(domain, settingsFileIn);
904 break;
905 case 'r':
906 ortn = copyCertsAndDisplay(verbose, domain);
907 break;
908 case 'd':
909 ortn = deleteCerts(domain, false);
910 break;
911 case 'D':
912 if(!really) {
913 printf("I do not believe you. Specify -D option to delete all roots.\n");
914 exit(1);
915 }
916 ortn = deleteCerts(domain, true);
917 break;
918 case 'R':
919 ortn = addCertLegacy(certRef, policyStr, "unspecified", true);
920 break;
921 default:
922 usage(argv);
923 }
924 if(loopPause) {
925 fpurge(stdin);
926 printf("Pausing for MallocDebug. Hit CR to continue: ");
927 fflush(stdout);
928 getchar();
929 }
930 } while(loopPause);
931 return (int)ortn;
932 }