1/* 2 * Copyright (c) 2003-2009 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 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 11 * file. 12 * 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. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 * 23 * trusted_cert_dump.c 24 */ 25 26#include "trusted_cert_dump.h" 27#include "trusted_cert_utils.h" 28 29#include <errno.h> 30#include <unistd.h> 31#include <Security/Security.h> 32#include <Security/cssmapple.h> 33#include <Security/SecTrustSettings.h> 34#include <Security/oidsalg.h> 35#include <security_cdsa_utils/cuFileIo.h> 36#include <CoreFoundation/CoreFoundation.h> 37 38// SecCertificateInferLabel 39#include <Security/SecCertificatePriv.h> 40 41 42/* print cert's label (the one SecCertificate infers) */ 43static OSStatus printCertLabel( 44 SecCertificateRef certRef) 45{ 46 OSStatus ortn; 47 CFStringRef label; 48 49 ortn = SecCertificateInferLabel(certRef, &label); 50 if(ortn) { 51 cssmPerror("SecCertificateInferLabel", ortn); 52 return ortn; 53 } 54 printCfStr(label); 55 CFRelease(label); 56 return noErr; 57} 58 59/* 60 * Display a Trust Settings array as obtained from 61 * SecTrustSettingsCopyTrustSettings(). 62 */ 63static int displayTrustSettings( 64 CFArrayRef trustSettings) 65{ 66 /* must always be there though it may be empty */ 67 if(trustSettings == NULL) { 68 fprintf(stderr, "***displayTrustSettings: missing trust settings array"); 69 return -1; 70 } 71 if(CFGetTypeID(trustSettings) != CFArrayGetTypeID()) { 72 fprintf(stderr, "***displayTrustSettings: malformed trust settings array"); 73 return -1; 74 } 75 76 int ourRtn = 0; 77 CFIndex numUseConstraints = CFArrayGetCount(trustSettings); 78 indentIncr(); 79 indent(); printf("Number of trust settings : %ld\n", (long)numUseConstraints); 80 OSStatus ortn; 81 SecPolicyRef certPolicy; 82 SecTrustedApplicationRef certApp; 83 CFDictionaryRef ucDict; 84 CFStringRef policyStr; 85 CFNumberRef cfNum; 86 CFIndex ucDex; 87 88 /* grind thru the trust settings dictionaries */ 89 for(ucDex=0; ucDex<numUseConstraints; ucDex++) { 90 indent(); printf("Trust Setting %ld:\n", (long)ucDex); 91 indentIncr(); 92 93 ucDict = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, ucDex); 94 if(CFGetTypeID(ucDict) != CFDictionaryGetTypeID()) { 95 fprintf(stderr, "***displayTrustSettings: malformed usage constraints dictionary"); 96 ourRtn = -1; 97 goto nextAp; 98 } 99 100 /* policy - optional */ 101 certPolicy = (SecPolicyRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsPolicy); 102 if(certPolicy != NULL) { 103 if(CFGetTypeID(certPolicy) != SecPolicyGetTypeID()) { 104 fprintf(stderr, "***displayTrustSettings: malformed certPolicy"); 105 ourRtn = -1; 106 goto nextAp; 107 } 108 CSSM_OID policyOid; 109 ortn = SecPolicyGetOID(certPolicy, &policyOid); 110 if(ortn) { 111 cssmPerror("SecPolicyGetOID", ortn); 112 ourRtn = -1; 113 goto nextAp; 114 } 115 indent(); printf("Policy OID : %s\n", 116 oidToOidString(&policyOid)); 117 } 118 119 /* app - optional */ 120 certApp = (SecTrustedApplicationRef)CFDictionaryGetValue(ucDict, 121 kSecTrustSettingsApplication); 122 if(certApp != NULL) { 123 if(CFGetTypeID(certApp) != SecTrustedApplicationGetTypeID()) { 124 fprintf(stderr, "***displayTrustSettings: malformed certApp"); 125 ourRtn = -1; 126 goto nextAp; 127 } 128 CFDataRef appPath = NULL; 129 ortn = SecTrustedApplicationCopyData(certApp, &appPath); 130 if(ortn) { 131 cssmPerror("SecTrustedApplicationCopyData", ortn); 132 ourRtn = -1; 133 goto nextAp; 134 } 135 indent(); printf("Application : %s", CFDataGetBytePtr(appPath)); 136 printf("\n"); 137 CFRelease(appPath); 138 } 139 140 /* policy string */ 141 policyStr = (CFStringRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsPolicyString); 142 if(policyStr != NULL) { 143 if(CFGetTypeID(policyStr) != CFStringGetTypeID()) { 144 fprintf(stderr, "***displayTrustSettings: malformed policyStr"); 145 ourRtn = -1; 146 goto nextAp; 147 } 148 indent(); printf("Policy String : "); 149 printCfStr(policyStr); printf("\n"); 150 } 151 152 /* Allowed error */ 153 cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsAllowedError); 154 if(cfNum != NULL) { 155 if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) { 156 fprintf(stderr, "***displayTrustSettings: malformed allowedError"); 157 ourRtn = -1; 158 goto nextAp; 159 } 160 indent(); printf("Allowed Error : "); 161 printCssmErr(cfNum); printf("\n"); 162 } 163 164 /* ResultType */ 165 cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsResult); 166 if(cfNum != NULL) { 167 if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) { 168 fprintf(stderr, "***displayTrustSettings: malformed ResultType"); 169 ourRtn = -1; 170 goto nextAp; 171 } 172 indent(); printf("Result Type : "); 173 printResultType(cfNum); printf("\n"); 174 } 175 176 /* key usage */ 177 cfNum = (CFNumberRef)CFDictionaryGetValue(ucDict, kSecTrustSettingsKeyUsage); 178 if(cfNum != NULL) { 179 if(CFGetTypeID(cfNum) != CFNumberGetTypeID()) { 180 fprintf(stderr, "***displayTrustSettings: malformed keyUsage"); 181 ourRtn = -1; 182 goto nextAp; 183 } 184 indent(); printf("Key Usage : "); 185 printKeyUsage(cfNum); printf("\n"); 186 } 187 188 nextAp: 189 indentDecr(); 190 } 191 indentDecr(); 192 return ourRtn; 193} 194 195int 196trusted_cert_dump(int argc, char * const *argv) 197{ 198 CFArrayRef certArray = NULL; 199 OSStatus ortn = noErr; 200 CFIndex numCerts; 201 CFIndex dex; 202 CFArrayRef trustSettings; 203 int ourRtn = 0; 204 SecTrustSettingsDomain domain = kSecTrustSettingsDomainUser; 205 206 extern char *optarg; 207 extern int optind; 208 int arg; 209 210 optind = 1; 211 while ((arg = getopt(argc, argv, "sdh")) != -1) { 212 switch (arg) { 213 case 's': 214 domain = kSecTrustSettingsDomainSystem; 215 break; 216 case 'd': 217 domain = kSecTrustSettingsDomainAdmin; 218 break; 219 default: 220 case 'h': 221 return 2; /* @@@ Return 2 triggers usage message. */ 222 } 223 } 224 225 if(optind != argc) { 226 return 2; /* @@@ Return 2 triggers usage message. */ 227 } 228 229 ortn = SecTrustSettingsCopyCertificates(domain, &certArray); 230 if(ortn) { 231 cssmPerror("SecTrustSettingsCopyCertificates", ortn); 232 return 1; 233 } 234 numCerts = CFArrayGetCount(certArray); 235 printf("Number of trusted certs = %ld\n", (long)numCerts); 236 237 for(dex=0; dex<numCerts; dex++) { 238 SecCertificateRef certRef = 239 (SecCertificateRef)CFArrayGetValueAtIndex(certArray, dex); 240 if(CFGetTypeID(certRef) != SecCertificateGetTypeID()) { 241 fprintf(stderr, "***Bad CFGetTypeID for cert %ld\n", (long)dex); 242 ourRtn = -1; 243 break; 244 } 245 246 /* always print the cert's label */ 247 printf("Cert %ld: ", dex); 248 printCertLabel(certRef); 249 printf("\n"); 250 251 /* see if the cert has any usage constraints (it should!) */ 252 ortn = SecTrustSettingsCopyTrustSettings(certRef, domain, &trustSettings); 253 if(ortn) { 254 cssmPerror("SecTrustSettingsCopyTrustSettings", ortn); 255 ourRtn = -1; 256 continue; 257 } 258 if(displayTrustSettings(trustSettings)) { 259 ourRtn = -1; 260 } 261 } 262 CFRelease(certArray); 263 264 return ourRtn; 265} 266