2 * certTime - measure performacne of cert parse and build.
5 #include <security_cdsa_utils/cuFileIo.h>
6 #include <clAppUtils/CertBuilderApp.h>
7 #include <utilLib/common.h>
8 #include <utilLib/cspwrap.h>
9 #include <clAppUtils/clutils.h>
14 #include <Security/cssm.h>
15 #include <Security/x509defs.h>
16 #include <Security/oidsattr.h>
17 #include <Security/oidscert.h>
18 #include <Security/certextensions.h>
19 #include <CoreFoundation/CoreFoundation.h>
20 #include "extenCooker.h"
22 #define KEYSIZE_DEF 1024
23 #define CL_KEY_VIA_GET_KEY 0
25 static void usage(char **argv
)
27 printf("Usage: %s op loops [options]\n", argv
[0]);
30 printf(" g parse & get all fields\n");
31 #if CL_KEY_VIA_GET_KEY
32 printf(" t parse & get some fields, emulating TPCertInfo, GetKeyInfo\n");
34 printf(" t parse & get some fields, emulating TPCertInfo, fetchField(key)\n");
36 printf(" c create\n");
37 printf(" s create & sign\n");
38 printf(" v verify\n");
40 printf(" b RSA blinding on\n");
41 printf(" k=keysize (default = %d)\n", KEYSIZE_DEF
);
46 * The certs we'll be parsing
48 static const char *certNames
[] =
50 "anchor_0", // GTE CyberTrust Root, no extens
51 "anchor_9", // VeriSign, no extens
52 "anchor_34", // TrustCenter, 6 extens
53 "anchor_44", // USERTRUST, 5 extens, incl. cRLDistributionPoints
54 "anchor_76", // QuoVadis, 6 extens, incl. authorityInfoAccess
55 "anchor_80", // KMD-CA Kvalificeret3 6 extens
58 #define NUM_PARSED_CERTS (sizeof(certNames) / sizeof(certNames[0]))
60 /* dummy RDN - subject and issuer - we aren't testing this */
61 CB_NameOid dummyRdn
[] =
63 { "Apple Computer", &CSSMOID_OrganizationName
},
64 { "Doug Mitchell", &CSSMOID_CommonName
}
66 #define NUM_DUMMY_NAMES (sizeof(dummyRdn) / sizeof(CB_NameOid))
68 #define KEY_ALG CSSM_ALGID_RSA
69 #define SIG_ALG CSSM_ALGID_SHA1WithRSA
70 #define SUBJ_KEY_LABEL "subjectKey"
74 * Set of extensions we'll be creating
76 /* empty freeFcn means no extension-specific resources to free */
79 static ExtenTest extenTests
[] = {
80 { kuCreate
, kuCompare
, NO_FREE
,
81 sizeof(CE_KeyUsage
), CSSMOID_KeyUsage
,
83 { ekuCreate
, ekuCompare
, NO_FREE
,
84 sizeof(CE_ExtendedKeyUsage
), CSSMOID_ExtendedKeyUsage
,
85 "ExtendedKeyUsage", 'x' },
86 { authKeyIdCreate
, authKeyIdCompare
, authKeyIdFree
,
87 sizeof(CE_AuthorityKeyID
), CSSMOID_AuthorityKeyIdentifier
,
88 "AuthorityKeyID", 'a' },
89 { genNamesCreate
, genNamesCompare
, genNamesFree
,
90 sizeof(CE_GeneralNames
), CSSMOID_SubjectAltName
,
91 "SubjectAltName", 't' },
94 #define MAX_EXTENSIONS (sizeof(extenTests) / sizeof(ExtenTest))
97 CSSM_CL_HANDLE clHand
,
98 const CSSM_DATA
&cert
,
101 CSSM_HANDLE cacheHand
;
104 for(unsigned loop
=0; loop
<loops
; loop
++) {
105 crtn
= CSSM_CL_CertCache(clHand
, &cert
, &cacheHand
);
107 printError("CSSM_CL_CertCache", crtn
);
110 crtn
= CSSM_CL_CertAbortCache(clHand
, cacheHand
);
112 printError("CSSM_CL_CrlAbortCache", crtn
);
119 /* Emulate TPCertInfo constructor */
121 static CSSM_RETURN
fetchCertField(
122 CSSM_CL_HANDLE clHand
,
123 CSSM_HANDLE certHand
,
124 const CSSM_OID
*fieldOid
,
125 CSSM_DATA_PTR
*fieldData
) // mallocd by CL and RETURNED
129 uint32 NumberOfFields
= 0;
130 CSSM_HANDLE resultHand
= 0;
132 crtn
= CSSM_CL_CertGetFirstCachedFieldValue(
140 printError("fetchCertField", crtn
);
143 if(NumberOfFields
!= 1) {
144 printf("***fetchCertField: numFields %d, expected 1\n",
145 (int)NumberOfFields
);
147 CSSM_CL_CertAbortQuery(clHand
, resultHand
);
152 static int doGetSomeFields(
153 CSSM_CL_HANDLE clHand
,
154 const CSSM_DATA
&cert
,
157 CSSM_HANDLE cacheHand
;
160 /* fetched by TPClItemInfo constructor */
161 CSSM_DATA_PTR issuerName
;
162 CSSM_DATA_PTR sigAlg
;
163 CSSM_DATA_PTR notBefore
;
164 CSSM_DATA_PTR notAfter
;
165 /* fetched by TPCertInfo */
166 CSSM_DATA_PTR subjectName
;
167 #if CL_KEY_VIA_GET_KEY
168 CSSM_KEY_PTR subjPubKey
;
170 CSSM_DATA_PTR subjPubKeyData
;
173 for(unsigned loop
=0; loop
<loops
; loop
++) {
174 /* parse and cache */
175 crtn
= CSSM_CL_CertCache(clHand
, &cert
, &cacheHand
);
177 printError("CSSM_CL_CertCache", crtn
);
180 /* fetch the fields */
181 fetchCertField(clHand
, cacheHand
, &CSSMOID_X509V1IssuerName
, &issuerName
);
182 fetchCertField(clHand
, cacheHand
, &CSSMOID_X509V1SignatureAlgorithmTBS
,
184 fetchCertField(clHand
, cacheHand
, &CSSMOID_X509V1ValidityNotBefore
,
186 fetchCertField(clHand
, cacheHand
, &CSSMOID_X509V1ValidityNotAfter
, ¬After
);
187 fetchCertField(clHand
, cacheHand
, &CSSMOID_X509V1SubjectName
, &subjectName
);
188 #if CL_KEY_VIA_GET_KEY
189 CSSM_CL_CertGetKeyInfo(clHand
, &cert
, &subjPubKey
);
191 fetchCertField(clHand
, cacheHand
, &CSSMOID_CSSMKeyStruct
, &subjPubKeyData
);
194 /* free the fields */
195 CSSM_CL_FreeFieldValue(clHand
, &CSSMOID_X509V1IssuerName
, issuerName
);
196 CSSM_CL_FreeFieldValue(clHand
, &CSSMOID_X509V1SignatureAlgorithmTBS
, sigAlg
);
197 CSSM_CL_FreeFieldValue(clHand
, &CSSMOID_X509V1ValidityNotBefore
, notBefore
);
198 CSSM_CL_FreeFieldValue(clHand
, &CSSMOID_X509V1ValidityNotAfter
, notAfter
);
199 CSSM_CL_FreeFieldValue(clHand
, &CSSMOID_X509V1SubjectName
, subjectName
);
200 #if CL_KEY_VIA_GET_KEY
201 appFree(subjPubKey
->KeyData
.Data
, 0);
202 appFree(subjPubKey
, 0);
204 CSSM_CL_FreeFieldValue(clHand
, &CSSMOID_CSSMKeyStruct
, subjPubKeyData
);
207 crtn
= CSSM_CL_CertAbortCache(clHand
, cacheHand
);
209 printError("CSSM_CL_CrlAbortCache", crtn
);
216 static int doGetFields(
217 CSSM_CL_HANDLE clHand
,
218 const CSSM_DATA
&cert
,
222 CSSM_FIELD_PTR certFields
;
225 for(unsigned loop
=0; loop
<loops
; loop
++) {
226 crtn
= CSSM_CL_CertGetAllFields(clHand
, &cert
, &numFields
,
229 printError("CSSM_CL_CertGetAllFields", crtn
);
232 crtn
= CSSM_CL_FreeFields(clHand
, numFields
, &certFields
);
234 printError("CSSM_CL_FreeFields", crtn
);
242 CSSM_CL_HANDLE clHand
,
243 const CSSM_DATA
&cert
,
248 for(unsigned loop
=0; loop
<loops
; loop
++) {
249 crtn
= CSSM_CL_CertVerify(clHand
,
256 printError("CSSM_CL_CertVerify", crtn
);
264 * Stuff to be created before entering the timed cert create routine.
269 CSSM_X509_NAME
*dummyName
;
270 CSSM_X509_TIME
*notBefore
;
271 CSSM_X509_TIME
*notAfter
;
272 CSSM_X509_EXTENSION extens
[MAX_EXTENSIONS
];
276 * One-time only setup of cert creation params.
278 static int createSetup(
279 CSSM_CL_HANDLE clHand
,
280 CSSM_CSP_HANDLE cspHand
,
282 PresetParams
¶ms
)
286 crtn
= cspGenKeyPair(cspHand
,
289 strlen(SUBJ_KEY_LABEL
),
292 CSSM_FALSE
, // pubIsRef
294 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
296 CSSM_TRUE
, // privIsRef - doesn't matter
298 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
303 params
.dummyName
= CB_BuildX509Name(dummyRdn
, NUM_DUMMY_NAMES
);
304 if(params
.dummyName
== NULL
) {
305 printf("CB_BuildX509Name failure");
308 params
.notBefore
= CB_BuildX509Time(0);
309 params
.notAfter
= CB_BuildX509Time(10000);
311 /* now some extensions */
312 for(unsigned dex
=0; dex
<MAX_EXTENSIONS
; dex
++) {
313 CSSM_X509_EXTENSION
&extn
= params
.extens
[dex
];
314 ExtenTest
&etest
= extenTests
[dex
];
316 void *extVal
= CSSM_MALLOC(etest
.extenSize
);
317 memset(extVal
, 0, etest
.extenSize
);
318 etest
.createFcn(extVal
);
320 extn
.extnId
= etest
.extenOid
;
321 extn
.critical
= randBool();
322 extn
.format
= CSSM_X509_DATAFORMAT_PARSED
;
323 extn
.value
.parsedValue
= extVal
;
324 extn
.BERvalue
.Data
= NULL
;
325 extn
.BERvalue
.Length
= 0;
331 CSSM_CL_HANDLE clHand
,
332 CSSM_CSP_HANDLE cspHand
,
334 PresetParams
¶ms
,
338 for(unsigned loop
=0; loop
<loops
; loop
++) {
339 CSSM_DATA_PTR rawCert
= CB_MakeCertTemplate(clHand
,
340 0x12345678, // serial number
347 NULL
, // subjUniqueId
348 NULL
, // issuerUniqueId
349 params
.extens
, // extensions
350 /* vary numExtensions per loop */
351 loop
% MAX_EXTENSIONS
);
352 if(rawCert
== NULL
) {
353 printf("Error creating cert template.\n");
357 CSSM_DATA signedCert
= {0, NULL
};
358 CSSM_CC_HANDLE sigHand
;
359 CSSM_RETURN crtn
= CSSM_CSP_CreateSignatureContext(cspHand
,
361 NULL
, // no passphrase for now
365 printError("CreateSignatureContext", crtn
);
370 CSSM_CONTEXT_ATTRIBUTE newAttr
;
371 newAttr
.AttributeType
= CSSM_ATTRIBUTE_RSA_BLINDING
;
372 newAttr
.AttributeLength
= sizeof(uint32
);
373 newAttr
.Attribute
.Uint32
= 1;
374 crtn
= CSSM_UpdateContextAttributes(sigHand
, 1, &newAttr
);
376 printError("CSSM_UpdateContextAttributes", crtn
);
381 crtn
= CSSM_CL_CertSign(clHand
,
383 rawCert
, // CertToBeSigned
384 NULL
, // SignScope per spec
385 0, // ScopeSize per spec
388 printError("CSSM_CL_CertSign", crtn
);
391 CSSM_DeleteContext(sigHand
);
392 CSSM_FREE(signedCert
.Data
);
394 CSSM_FREE(rawCert
->Data
);
404 CTO_Create
, // sign is an option for this one
408 int main(int argc
, char **argv
)
410 CSSM_CL_HANDLE clHand
;
411 CSSM_CSP_HANDLE cspHand
;
417 CSSM_DATA certData
[NUM_PARSED_CERTS
];
419 /* user-specificied params */
423 const char *opStr
= NULL
;
424 bool rsaBlinding
= false;
425 unsigned keySize
= KEYSIZE_DEF
;
437 opStr
= "Parsed with GetAllFields";
440 op
= CTO_GetSomeFields
;
441 #if CL_KEY_VIA_GET_KEY
442 opStr
= "Parsed with some GetFields and GetKeyInfo";
444 opStr
= "Parsed with some GetFields";
453 opStr
= "Created and Signed";
464 loops
= atoi(argv
[2]);
465 for(arg
=3; arg
<argc
; arg
++) {
472 keySize
= atoi(&argp
[2]);
480 clHand
= clStartup();
484 cspHand
= cspStartup();
496 case CTO_GetSomeFields
:
498 /* read in the certs */
499 for(dex
=0; dex
<NUM_PARSED_CERTS
; dex
++) {
500 CSSM_DATA
&cdata
= certData
[dex
];
501 if(readFile(certNames
[dex
],
502 (unsigned char **)&cdata
.Data
,
504 printf("Error reading cert %s. Aborting.\n",
512 /* set up keys, names */
513 if(createSetup(clHand
, cspHand
, keySize
, params
)) {
519 /* one loop outside of timer to heat up test bed */
522 rtn
= doParse(clHand
, certData
[0], 1);
525 rtn
= doGetFields(clHand
, certData
[0], 1);
527 case CTO_GetSomeFields
:
528 rtn
= doGetSomeFields(clHand
, certData
[0], 1);
531 rtn
= doVerify(clHand
, certData
[0], 1);
534 rtn
= doCreate(clHand
, cspHand
, 1, params
, true, rsaBlinding
);
538 printf("This program needs work. Try again.\n");
542 CFAbsoluteTime startTime
, endTime
;
543 startTime
= CFAbsoluteTimeGetCurrent();
545 /* begin timed loop */
548 for(i
=0; i
<NUM_PARSED_CERTS
; i
++) {
549 rtn
= doParse(clHand
, certData
[i
], loops
);
556 for(i
=0; i
<NUM_PARSED_CERTS
; i
++) {
557 rtn
= doGetFields(clHand
, certData
[i
], loops
);
563 case CTO_GetSomeFields
:
564 for(i
=0; i
<NUM_PARSED_CERTS
; i
++) {
565 rtn
= doGetSomeFields(clHand
, certData
[i
], loops
);
572 for(i
=0; i
<NUM_PARSED_CERTS
; i
++) {
573 rtn
= doVerify(clHand
, certData
[i
], loops
);
580 rtn
= doCreate(clHand
, cspHand
, loops
, params
, doSign
,
584 endTime
= CFAbsoluteTimeGetCurrent();
585 CFAbsoluteTime deltaTime
= endTime
- startTime
;
588 printf("Error in main loop. Try again.\n");
592 unsigned numCerts
= loops
;
593 if(op
!= CTO_Create
) {
594 numCerts
*= NUM_PARSED_CERTS
;
597 printf("=== %u certs %s ===\n", numCerts
, opStr
);
598 printf("Total time %g s\n", deltaTime
);
599 printf("%g ms per cert\n", (deltaTime
/ (double)numCerts
) * 1000.0);
602 if(op
== CTO_Create
) {
603 CB_FreeX509Name(params
.dummyName
);
604 CB_FreeX509Time(params
.notBefore
);
605 CB_FreeX509Time(params
.notAfter
);
606 cspFreeKey(cspHand
, ¶ms
.pubKey
);
607 cspFreeKey(cspHand
, ¶ms
.privKey
);
610 for(i
=0; i
<NUM_PARSED_CERTS
; i
++) {
611 free(certData
[i
].Data
);
614 CSSM_ModuleDetach(cspHand
);
615 CSSM_ModuleDetach(clHand
);