1/* 2 * userTrustTest.cpp - simple test of SecTrustSetUserTrustLegacy() and 3 * SecTrustGetUserTrust() 4 */ 5 6#include <stdlib.h> 7#include <strings.h> 8#include <stdio.h> 9#include <unistd.h> 10#include <Security/Security.h> 11#include <Security/SecTrustPriv.h> 12#include <Security/SecPolicyPriv.h> 13#include <clAppUtils/tpUtils.h> 14#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h> 15 16#define IGNORE_EXISTING_STATE 0 17 18static void usage(char **argv) 19{ 20 printf("usage: %s [options] known_good_leaf_cert [ca_cert...]\n", argv[0]); 21 printf("Options:\n"); 22 printf(" -q -- quiet\n"); 23 exit(1); 24} 25 26static char *secTrustResultStr( 27 SecTrustResultType result) 28{ 29 static char unknownStr[100]; 30 31 switch(result) { 32 case kSecTrustResultInvalid: return "kSecTrustResultInvalid"; 33 case kSecTrustResultProceed: return "kSecTrustResultProceed"; 34 case kSecTrustResultConfirm: return "kSecTrustResultConfirm"; 35 case kSecTrustResultDeny: return "kSecTrustResultDeny"; 36 case kSecTrustResultUnspecified: return "kSecTrustResultUnspecified"; 37 case kSecTrustResultRecoverableTrustFailure: 38 return "kSecTrustResultRecoverableTrustFailure"; 39 case kSecTrustResultFatalTrustFailure: return "kSecTrustResultFatalTrustFailure"; 40 case kSecTrustResultOtherError: return "kSecTrustResultOtherError"; 41 default: 42 sprintf(unknownStr, "UNKNOWN ResultType (%d)\n", 43 (int)result); 44 return unknownStr; 45 } 46} 47 48/* do a SecTrustEvaluate, ensure resultType is as specified */ 49static int doEval( 50 CFArrayRef certs, 51 SecPolicyRef policy, 52 SecTrustResultType expectedResult, 53 bool quiet) 54{ 55 OSStatus ortn; 56 SecTrustRef trustRef = NULL; 57 SecTrustResultType result; 58 int ourRtn = 0; 59 60 ortn = SecTrustCreateWithCertificates(certs, policy, &trustRef); 61 if(ortn) { 62 cssmPerror("SecTrustCreateWithCertificates", ortn); 63 return -1; 64 } 65 ortn = SecTrustEvaluate(trustRef, &result); 66 if(ortn) { 67 /* shouldn't fail no matter what resultType we expect */ 68 cssmPerror("SecTrustEvaluate", ortn); 69 ourRtn = -1; 70 goto errOut; 71 } 72 if(expectedResult == result) { 73 if(!quiet) { 74 printf("...got %s as expected\n", secTrustResultStr(result)); 75 } 76 } 77 else { 78 printf("***Expected %s, got %s\n", secTrustResultStr(expectedResult), 79 secTrustResultStr(result)); 80 ourRtn = -1; 81 } 82errOut: 83 CFRelease(trustRef); 84 return ourRtn; 85} 86 87/* Do a SecTrustGetUserTrust(), ensure result is as specified */ 88static int doGetUserTrust( 89 SecCertificateRef certRef, 90 SecPolicyRef policy, 91 SecTrustResultType expectedResult) 92{ 93 SecTrustResultType foundResult; 94 OSStatus ortn = SecTrustGetUserTrust(certRef, policy, &foundResult); 95 if(ortn) { 96 cssmPerror("SecTrustGetUserTrust", ortn); 97 return -1; 98 } 99 if(foundResult != expectedResult) { 100 printf("***Expected current resultType %s; found %s\n", 101 secTrustResultStr(expectedResult), secTrustResultStr(foundResult)); 102 return -1; 103 } 104 return 0; 105} 106 107/* Do SecTrustSetUserTrustLegacy() followed by SecTrustGetUserTrust() */ 108static int doSetVerifyUserTrust( 109 SecCertificateRef certRef, 110 SecPolicyRef policy, 111 SecTrustResultType result) 112{ 113 OSStatus ortn; 114 ortn = SecTrustSetUserTrustLegacy(certRef, policy, result); 115 if(ortn) { 116 cssmPerror("SecTrustSetUserTrustLegacy", ortn); 117 return -1; 118 } 119 return doGetUserTrust(certRef, policy, result); 120} 121 122static int doTest( 123 CFArrayRef certArray, 124 SecPolicyRef policy, 125 bool quiet) 126{ 127 int ourRtn = 0; 128 SecCertificateRef leafCert = (SecCertificateRef)CFArrayGetValueAtIndex( 129 certArray, 0); 130 131 if(!quiet) { 132 printf("Verifying cert is good as is...\n"); 133 } 134 ourRtn = doEval(certArray, policy, kSecTrustResultUnspecified, quiet); 135 if(ourRtn && !IGNORE_EXISTING_STATE) { 136 return ourRtn; 137 } 138 139 if(!quiet) { 140 printf("Verifying cert currently has kSecTrustResultUnspecified...\n"); 141 } 142 if(doGetUserTrust(leafCert, policy, kSecTrustResultUnspecified)) { 143 ourRtn = -1; 144 /* but keep going */ 145 } 146 147 if(!quiet) { 148 printf("setting and verifying SecTrustResultDeny...\n"); 149 } 150 if(doSetVerifyUserTrust(leafCert, policy, kSecTrustResultDeny)) { 151 ourRtn = -1; 152 } 153 154 if(!quiet) { 155 printf("Verify cert with SecTrustResultDeny...\n"); 156 } 157 ourRtn = doEval(certArray, policy, kSecTrustResultDeny, quiet); 158 if(ourRtn) { 159 ourRtn = -1; 160 } 161 162 if(!quiet) { 163 printf("setting and verifying kSecTrustResultConfirm...\n"); 164 } 165 if(doSetVerifyUserTrust(leafCert, policy, kSecTrustResultConfirm)) { 166 ourRtn = -1; 167 } 168 169 if(!quiet) { 170 printf("Verify cert with kSecTrustResultConfirm...\n"); 171 } 172 ourRtn = doEval(certArray, policy, kSecTrustResultConfirm, quiet); 173 if(ourRtn) { 174 ourRtn = -1; 175 } 176 177 if(!quiet) { 178 printf("setting and verifying kSecTrustResultUnspecified...\n"); 179 } 180 if(doSetVerifyUserTrust(leafCert, policy, kSecTrustResultUnspecified)) { 181 ourRtn = -1; 182 } 183 184 if(!quiet) { 185 printf("Verify cert with kSecTrustResultUnspecified...\n"); 186 } 187 ourRtn = doEval(certArray, policy, kSecTrustResultUnspecified, quiet); 188 189 if(!quiet) { 190 printf("Verify SecTrustSetUserTrust(kSecTrustResultConfirm) fails...\n"); 191 } 192 /* verify Radar 4642125 - this should fail, not crash */ 193 OSStatus ortn = SecTrustSetUserTrust(leafCert, policy, kSecTrustResultConfirm); 194 if(ortn != unimpErr) { 195 printf("***SecTrustSetUserTrust returned %ld; expected %ld (unimpErr)\n", 196 (long)ortn, (long)unimpErr); 197 ourRtn = -1; 198 } 199 return ourRtn; 200} 201 202int main(int argc, char **argv) 203{ 204 bool quiet = false; 205 206 int arg; 207 while ((arg = getopt(argc, argv, "qh")) != -1) { 208 switch (arg) { 209 case 'q': 210 quiet = true; 211 break; 212 case 'h': 213 usage(argv); 214 } 215 } 216 217 unsigned numCerts = argc - optind; 218 if(numCerts == 0) { 219 usage(argv); 220 } 221 CFMutableArrayRef certArray = CFArrayCreateMutable(NULL, 0, 222 &kCFTypeArrayCallBacks); 223 for(int dex=optind; dex<argc; dex++) { 224 SecCertificateRef certRef = certFromFile(argv[dex]); 225 if(certRef == NULL) { 226 exit(1); 227 } 228 CFArrayAppendValue(certArray, certRef); 229 CFRelease(certRef); 230 } 231 232 OSStatus ortn; 233 SecPolicyRef policyRef = NULL; 234 ortn = SecPolicyCopy(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, &policyRef); 235 if(ortn) { 236 cssmPerror("SecPolicyCopy", ortn); 237 exit(1); 238 } 239 240 int ourRtn = doTest(certArray, policyRef, quiet); 241 CFRelease(policyRef); 242 CFRelease(certArray); 243 return ourRtn; 244} 245