2  * secTrustTime.cpp - measure performance of SecTrust and TP cert verify 
   9 #include <CoreFoundation/CoreFoundation.h> 
  10 #include <Security/Security.h> 
  11 #include <Security/TrustSettingsSchema.h> 
  12 #include <security_cdsa_utils/cuFileIo.h> 
  13 #include <utilLib/common.h> 
  14 #include <clAppUtils/clutils.h> 
  15 #include <clAppUtils/tpUtils.h> 
  19 const char *certFiles
[] = { 
  20         "keybank_v3.100.cer", "keybank_v3.101.cer", "keybank_v3.102.cer" 
  23 #define NUM_CERTS (sizeof(certFiles) / sizeof(certFiles[0])) 
  25 static void usage(char **argv
) 
  27         printf("usage: %s [options]\n", argv
[0]); 
  29         printf("  -l loops        -- loops; default %d; 0=forever\n", LOOPS_DEF
); 
  30         printf("  -k              -- open and hold keychains\n"); 
  31         printf("  -t              -- TP, not SecTrust\n"); 
  32         printf("  -T              -- TP, no Trust Settings\n"); 
  33         printf("  -n              -- don't include root in cert chain\n"); 
  34         printf("  -K              -- set empty KC list\n"); 
  39 static SecCertificateRef 
readCertFile( 
  42         unsigned char *cp 
= NULL
; 
  47         if(readFile(fileName
, &cp
, &len
)) { 
  48                 printf("***Error reading file %s\n", fileName
); 
  51         certData
.Length 
= len
; 
  53         SecCertificateRef certRef
; 
  55         ortn 
= SecCertificateCreateFromData(&certData
,  
  56                         CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
, &certRef
); 
  58                 cssmPerror("SecCertificateCreateFromData", ortn
); 
  65 /* perfrom one cert chain evaluation using SecTrust */ 
  66 static OSStatus 
doEval( 
  68         SecPolicyRef policyRef
, 
  74         ortn 
= SecTrustCreateWithCertificates(certArray
, policyRef
, &trustRef
); 
  76                 cssmPerror("SecTrustCreateWithCertificates", ortn
); 
  80                 ortn 
= SecTrustSetKeychains(trustRef
, kcList
); 
  82                         cssmPerror("SecTrustCreateWithCertificates", ortn
); 
  86         SecTrustResultType secTrustResult
; 
  87         ortn 
= SecTrustEvaluate(trustRef
, &secTrustResult
); 
  89                 cssmPerror("SecTrustEvaluate", ortn
); 
  92         switch(secTrustResult
) { 
  93                 case kSecTrustResultProceed
: 
  94                 case kSecTrustResultUnspecified
: 
  97                         printf("***Unexpected SecTrustResultType (%d)\n", (int)secTrustResult
); 
 104 /* cached CSSM anchors - simulate old SecTrustGetCSSMAnchorCertificates() */  
 105 static CFArrayRef cachedRootArray 
= NULL
; 
 106 static CSSM_DATA 
*cachedAnchors 
= NULL
; 
 107 static unsigned cachedNumAnchors 
= 0; 
 109 static OSStatus 
getAnchors( 
 110         CSSM_DATA 
**anchors
,    /* RETURNED */ 
 111         unsigned *numAnchors
)   /* RETURNED */ 
 113         if(cachedRootArray 
== NULL
) { 
 115                 OSStatus ortn 
= getSystemAnchors(&cachedRootArray
, &cachedAnchors
,  
 121         *anchors 
= cachedAnchors
; 
 122         *numAnchors 
= cachedNumAnchors
; 
 126 /* perfrom one cert chain evaluation using CSSM_TP_CertGroupVerify */ 
 127 static CSSM_RETURN 
doTpEval( 
 128         CSSM_TP_HANDLE tpHand
, 
 129         CSSM_CL_HANDLE clHand
, 
 130         CSSM_CSP_HANDLE cspHand
, 
 133         bool useTrustSettings
) 
 137         policyId
.FieldOid 
= CSSMOID_APPLE_X509_BASIC
; 
 138         policyId
.FieldValue
.Data 
= NULL
; 
 139         policyId
.FieldValue
.Length 
= 0; 
 141         CSSM_TP_CALLERAUTH_CONTEXT              authCtx
; 
 142         memset(&authCtx
, 0, sizeof(CSSM_TP_CALLERAUTH_CONTEXT
)); 
 143         authCtx
.Policy
.NumberOfPolicyIds 
= 1; 
 144         authCtx
.Policy
.PolicyIds 
= &policyId
;    
 145         authCtx
.VerificationAbortOn 
= CSSM_TP_STOP_ON_POLICY
; 
 146         if(!useTrustSettings
) { 
 147                 OSStatus ortn 
= getAnchors(&authCtx
.AnchorCerts
,  
 148                         &authCtx
.NumberOfAnchorCerts
); 
 153         CSSM_APPLE_TP_ACTION_DATA tpAction
; 
 154         tpAction
.Version 
= CSSM_APPLE_TP_ACTION_VERSION
; 
 155         if(useTrustSettings
) { 
 156                 tpAction
.ActionFlags 
= CSSM_TP_ACTION_TRUST_SETTINGS
; 
 159                 tpAction
.ActionFlags 
= 0; 
 162         CSSM_TP_VERIFY_CONTEXT vfyCtx
; 
 163         memset(&vfyCtx
, 0, sizeof(CSSM_TP_VERIFY_CONTEXT
)); 
 164         vfyCtx
.ActionData
.Data   
= (uint8 
*)&tpAction
; 
 165         vfyCtx
.ActionData
.Length 
= sizeof(tpAction
); 
 166         vfyCtx
.Action 
= CSSM_TP_ACTION_DEFAULT
; 
 167         vfyCtx
.Cred 
= &authCtx
; 
 169         CSSM_CERTGROUP cssmCerts
; 
 170         cssmCerts
.CertType 
= CSSM_CERT_X_509v3
; 
 171         cssmCerts
.CertEncoding 
= CSSM_CERT_ENCODING_DER
; 
 172         cssmCerts
.NumCerts 
= numCerts
; 
 173         cssmCerts
.GroupList
.CertList 
= certs
; 
 174         cssmCerts
.CertGroupType 
= CSSM_CERTGROUP_DATA
; 
 176         CSSM_RETURN crtn 
= CSSM_TP_CertGroupVerify(tpHand
, clHand
, cspHand
, 
 179                 NULL
);          /* no results */ 
 181                 cssmPerror("CSSM_TP_CertGroupVerify", crtn
); 
 186 int main(int argc
, char **argv
) 
 191         /* common SecTrust args */ 
 192         CFMutableArrayRef       kcList 
= NULL
; 
 193         CFMutableArrayRef       certArray 
= NULL
; 
 194         SecPolicyRef            policyRef 
= NULL
; 
 195         unsigned                        numCerts 
= NUM_CERTS
; 
 196         CFArrayRef                      emptyKCList 
= NULL
; 
 199         CSSM_TP_HANDLE tpHand
; 
 200         CSSM_CL_HANDLE clHand
; 
 201         CSSM_CSP_HANDLE cspHand
; 
 202         CSSM_DATA cssmCerts
[NUM_CERTS
]; 
 204         /* user-spec'd variables */ 
 205         unsigned loops 
= LOOPS_DEF
; 
 206         bool holdKeychains 
= false;             /* hold references to KC list during operation */ 
 207         bool useTp 
= false;                             /* TP, not SecTrust */ 
 208         bool useTrustSettings 
= true;   /* TP w/TrustSettings; false = old school TP way */ 
 209         bool noRoot 
= false;                    /* don't include root in chain to be verified */ 
 210         bool emptyList 
= false;                 /* SecTrust only: specify empty KC list */ 
 214         while ((arg 
= getopt(argc
, argv
, "l:ktTnKh")) != -1) { 
 217                                 loops 
= atoi(optarg
); 
 220                                 holdKeychains 
= true; 
 227                                 useTrustSettings 
= false; 
 235                                 emptyKCList 
= CFArrayCreate(NULL
, NULL
, 0, &kCFTypeArrayCallBacks
); 
 245         /* gather certs to verify */ 
 246         certArray 
= CFArrayCreateMutable(NULL
, 3, &kCFTypeArrayCallBacks
); 
 247         for(dex
=0; dex
<numCerts
; dex
++) { 
 248                 SecCertificateRef certRef 
= readCertFile(certFiles
[dex
]); 
 249                 if(certRef 
== NULL
) { 
 252                 CFArrayInsertValueAtIndex(certArray
, dex
, certRef
); 
 256         /* prepare for one method or another */ 
 258                 for(dex
=0; dex
<numCerts
; dex
++) { 
 259                         crtn 
= SecCertificateGetData( 
 260                                 (SecCertificateRef
)CFArrayGetValueAtIndex(certArray
, dex
), 
 263                                 cssmPerror("SecCertificateGetData", crtn
); 
 267                 tpHand  
= tpStartup(); 
 268                 clHand  
= clStartup(); 
 269                 cspHand 
= cspStartup(); 
 272                 /* cook up reusable policy object */ 
 273                 SecPolicySearchRef      policySearch 
= NULL
; 
 274                 OSStatus ortn 
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, 
 275                         &CSSMOID_APPLE_X509_BASIC
, 
 279                         cssmPerror("SecPolicySearchCreate", ortn
); 
 282                 ortn 
= SecPolicySearchCopyNext(policySearch
, &policyRef
); 
 284                         cssmPerror("SecPolicySearchCopyNext", ortn
); 
 287                 CFRelease(policySearch
); 
 290                         /* the standard keychains */ 
 291                         ortn 
= SecKeychainCopySearchList((CFArrayRef 
*)&kcList
); 
 293                                 cssmPerror("SecKeychainCopySearchList", ortn
); 
 297                         /* plus the ones TrustSettings needs */ 
 298                         SecKeychainRef rootKc
; 
 299                         ortn 
= SecKeychainOpen(SYSTEM_ROOT_STORE_PATH
, &rootKc
); 
 301                                 cssmPerror("SecKeychainOpen", ortn
); 
 304                         CFArrayAppendValue(kcList
, rootKc
); 
 309         CFAbsoluteTime startTimeFirst
; 
 310         CFAbsoluteTime endTimeFirst
; 
 311         CFAbsoluteTime startTimeMulti
; 
 312         CFAbsoluteTime endTimeMulti
; 
 314         /* print a banner describing current test parameters */ 
 315         printf("Starting test: mode = "); 
 317                 if(useTrustSettings
) { 
 318                         printf("TP w/TrustSettings"); 
 321                         printf("TP w/o TrustSettings"); 
 327                         printf("; hold KC refs"); 
 330                         printf("; empty KC list"); 
 334                 printf("; no root in input certs\n"); 
 341         startTimeFirst 
= CFAbsoluteTimeGetCurrent(); 
 343                 if(doTpEval(tpHand
, clHand
, cspHand
, cssmCerts
, numCerts
, 
 347                 endTimeFirst 
= CFAbsoluteTimeGetCurrent(); 
 349                 startTimeMulti 
= CFAbsoluteTimeGetCurrent(); 
 350                 for(dex
=0; dex
<loops
; dex
++) { 
 351                         if(doTpEval(tpHand
, clHand
, cspHand
, cssmCerts
, numCerts
, 
 358                 if(doEval(certArray
, policyRef
, emptyKCList
)) { 
 361                 endTimeFirst 
= CFAbsoluteTimeGetCurrent(); 
 363                 startTimeMulti 
= CFAbsoluteTimeGetCurrent(); 
 364                 for(dex
=0; dex
<loops
; dex
++) { 
 365                         if(doEval(certArray
, policyRef
, emptyKCList
)) { 
 370         endTimeMulti 
= CFAbsoluteTimeGetCurrent(); 
 371         CFTimeInterval elapsed 
= endTimeMulti 
- startTimeMulti
; 
 373         printf("First eval = %4.1f ms\n", (endTimeFirst 
- startTimeFirst
) * 1000.0); 
 374         printf("Next evals = %4.2f ms/op (%f s total for %u loops)\n", 
 375                 elapsed 
* 1000.0 / loops
, elapsed
, loops
);