+++ /dev/null
-/*
- * certTime - measure performacne of cert parse and build.
- */
-
-#include <security_cdsa_utils/cuFileIo.h>
-#include <clAppUtils/CertBuilderApp.h>
-#include <utilLib/common.h>
-#include <utilLib/cspwrap.h>
-#include <clAppUtils/clutils.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <Security/cssm.h>
-#include <Security/x509defs.h>
-#include <Security/oidsattr.h>
-#include <Security/oidscert.h>
-#include <Security/certextensions.h>
-#include <CoreFoundation/CoreFoundation.h>
-#include "extenCooker.h"
-
-#define KEYSIZE_DEF 1024
-#define CL_KEY_VIA_GET_KEY 0
-
-static void usage(char **argv)
-{
- printf("Usage: %s op loops [options]\n", argv[0]);
- printf("Op:\n");
- printf(" p parse\n");
- printf(" g parse & get all fields\n");
- #if CL_KEY_VIA_GET_KEY
- printf(" t parse & get some fields, emulating TPCertInfo, GetKeyInfo\n");
- #else
- printf(" t parse & get some fields, emulating TPCertInfo, fetchField(key)\n");
- #endif
- printf(" c create\n");
- printf(" s create & sign\n");
- printf(" v verify\n");
- printf("Options:\n");
- printf(" b RSA blinding on\n");
- printf(" k=keysize (default = %d)\n", KEYSIZE_DEF);
- exit(1);
-}
-
-/*
- * The certs we'll be parsing
- */
-static const char *certNames[] =
-{
- "anchor_0", // GTE CyberTrust Root, no extens
- "anchor_9", // VeriSign, no extens
- "anchor_34", // TrustCenter, 6 extens
- "anchor_44", // USERTRUST, 5 extens, incl. cRLDistributionPoints
- "anchor_76", // QuoVadis, 6 extens, incl. authorityInfoAccess
- "anchor_80", // KMD-CA Kvalificeret3 6 extens
-};
-
-#define NUM_PARSED_CERTS (sizeof(certNames) / sizeof(certNames[0]))
-
-/* dummy RDN - subject and issuer - we aren't testing this */
-CB_NameOid dummyRdn[] =
-{
- { "Apple Computer", &CSSMOID_OrganizationName },
- { "Doug Mitchell", &CSSMOID_CommonName }
-};
-#define NUM_DUMMY_NAMES (sizeof(dummyRdn) / sizeof(CB_NameOid))
-
-#define KEY_ALG CSSM_ALGID_RSA
-#define SIG_ALG CSSM_ALGID_SHA1WithRSA
-#define SUBJ_KEY_LABEL "subjectKey"
-
-
-/*
- * Set of extensions we'll be creating
- */
-/* empty freeFcn means no extension-specific resources to free */
-#define NO_FREE NULL
-
-static ExtenTest extenTests[] = {
- { kuCreate, kuCompare, NO_FREE,
- sizeof(CE_KeyUsage), CSSMOID_KeyUsage,
- "KeyUsage", 'k' },
- { ekuCreate, ekuCompare, NO_FREE,
- sizeof(CE_ExtendedKeyUsage), CSSMOID_ExtendedKeyUsage,
- "ExtendedKeyUsage", 'x' },
- { authKeyIdCreate, authKeyIdCompare, authKeyIdFree,
- sizeof(CE_AuthorityKeyID), CSSMOID_AuthorityKeyIdentifier,
- "AuthorityKeyID", 'a' },
- { genNamesCreate, genNamesCompare, genNamesFree,
- sizeof(CE_GeneralNames), CSSMOID_SubjectAltName,
- "SubjectAltName", 't' },
-};
-
-#define MAX_EXTENSIONS (sizeof(extenTests) / sizeof(ExtenTest))
-
-static int doParse(
- CSSM_CL_HANDLE clHand,
- const CSSM_DATA &cert,
- unsigned loops)
-{
- CSSM_HANDLE cacheHand;
- CSSM_RETURN crtn;
-
- for(unsigned loop=0; loop<loops; loop++) {
- crtn = CSSM_CL_CertCache(clHand, &cert, &cacheHand);
- if(crtn) {
- printError("CSSM_CL_CertCache", crtn);
- return 1;
- }
- crtn = CSSM_CL_CertAbortCache(clHand, cacheHand);
- if(crtn) {
- printError("CSSM_CL_CrlAbortCache", crtn);
- return 1;
- }
- }
- return 0;
-}
-
-/* Emulate TPCertInfo constructor */
-
-static CSSM_RETURN fetchCertField(
- CSSM_CL_HANDLE clHand,
- CSSM_HANDLE certHand,
- const CSSM_OID *fieldOid,
- CSSM_DATA_PTR *fieldData) // mallocd by CL and RETURNED
-{
- CSSM_RETURN crtn;
-
- uint32 NumberOfFields = 0;
- CSSM_HANDLE resultHand = 0;
- *fieldData = NULL;
- crtn = CSSM_CL_CertGetFirstCachedFieldValue(
- clHand,
- certHand,
- fieldOid,
- &resultHand,
- &NumberOfFields,
- fieldData);
- if(crtn) {
- printError("fetchCertField", crtn);
- return crtn;
- }
- if(NumberOfFields != 1) {
- printf("***fetchCertField: numFields %d, expected 1\n",
- (int)NumberOfFields);
- }
- CSSM_CL_CertAbortQuery(clHand, resultHand);
- return CSSM_OK;
-}
-
-
-static int doGetSomeFields(
- CSSM_CL_HANDLE clHand,
- const CSSM_DATA &cert,
- unsigned loops)
-{
- CSSM_HANDLE cacheHand;
- CSSM_RETURN crtn;
-
- /* fetched by TPClItemInfo constructor */
- CSSM_DATA_PTR issuerName;
- CSSM_DATA_PTR sigAlg;
- CSSM_DATA_PTR notBefore;
- CSSM_DATA_PTR notAfter;
- /* fetched by TPCertInfo */
- CSSM_DATA_PTR subjectName;
- #if CL_KEY_VIA_GET_KEY
- CSSM_KEY_PTR subjPubKey;
- #else
- CSSM_DATA_PTR subjPubKeyData;
- #endif
-
- for(unsigned loop=0; loop<loops; loop++) {
- /* parse and cache */
- crtn = CSSM_CL_CertCache(clHand, &cert, &cacheHand);
- if(crtn) {
- printError("CSSM_CL_CertCache", crtn);
- return 1;
- }
- /* fetch the fields */
- fetchCertField(clHand, cacheHand, &CSSMOID_X509V1IssuerName, &issuerName);
- fetchCertField(clHand, cacheHand, &CSSMOID_X509V1SignatureAlgorithmTBS,
- &sigAlg);
- fetchCertField(clHand, cacheHand, &CSSMOID_X509V1ValidityNotBefore,
- ¬Before);
- fetchCertField(clHand, cacheHand, &CSSMOID_X509V1ValidityNotAfter, ¬After);
- fetchCertField(clHand, cacheHand, &CSSMOID_X509V1SubjectName, &subjectName);
- #if CL_KEY_VIA_GET_KEY
- CSSM_CL_CertGetKeyInfo(clHand, &cert, &subjPubKey);
- #else
- fetchCertField(clHand, cacheHand, &CSSMOID_CSSMKeyStruct, &subjPubKeyData);
- #endif
-
- /* free the fields */
- CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1IssuerName, issuerName);
- CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SignatureAlgorithmTBS, sigAlg);
- CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1ValidityNotBefore, notBefore);
- CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1ValidityNotAfter, notAfter);
- CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SubjectName, subjectName);
- #if CL_KEY_VIA_GET_KEY
- appFree(subjPubKey->KeyData.Data, 0);
- appFree(subjPubKey, 0);
- #else
- CSSM_CL_FreeFieldValue(clHand, &CSSMOID_CSSMKeyStruct, subjPubKeyData);
- #endif
-
- crtn = CSSM_CL_CertAbortCache(clHand, cacheHand);
- if(crtn) {
- printError("CSSM_CL_CrlAbortCache", crtn);
- return 1;
- }
- }
- return 0;
-}
-
-static int doGetFields(
- CSSM_CL_HANDLE clHand,
- const CSSM_DATA &cert,
- unsigned loops)
-{
- uint32 numFields;
- CSSM_FIELD_PTR certFields;
- CSSM_RETURN crtn;
-
- for(unsigned loop=0; loop<loops; loop++) {
- crtn = CSSM_CL_CertGetAllFields(clHand, &cert, &numFields,
- &certFields);
- if(crtn) {
- printError("CSSM_CL_CertGetAllFields", crtn);
- return 1;
- }
- crtn = CSSM_CL_FreeFields(clHand, numFields, &certFields);
- if(crtn) {
- printError("CSSM_CL_FreeFields", crtn);
- return 1;
- }
- }
- return 0;
-}
-
-static int doVerify(
- CSSM_CL_HANDLE clHand,
- const CSSM_DATA &cert,
- unsigned loops)
-{
- CSSM_RETURN crtn;
-
- for(unsigned loop=0; loop<loops; loop++) {
- crtn = CSSM_CL_CertVerify(clHand,
- CSSM_INVALID_HANDLE,
- &cert,
- &cert,
- NULL, // VerifyScope
- 0); // ScopeSize
- if(crtn) {
- printError("CSSM_CL_CertVerify", crtn);
- return 1;
- }
- }
- return 0;
-}
-
-/*
- * Stuff to be created before entering the timed cert create routine.
- */
-typedef struct {
- CSSM_KEY privKey;
- CSSM_KEY pubKey;
- CSSM_X509_NAME *dummyName;
- CSSM_X509_TIME *notBefore;
- CSSM_X509_TIME *notAfter;
- CSSM_X509_EXTENSION extens[MAX_EXTENSIONS];
-} PresetParams;
-
-/*
- * One-time only setup of cert creation params.
- */
- static int createSetup(
- CSSM_CL_HANDLE clHand,
- CSSM_CSP_HANDLE cspHand,
- unsigned keySize,
- PresetParams ¶ms)
-{
- CSSM_RETURN crtn;
-
- crtn = cspGenKeyPair(cspHand,
- KEY_ALG,
- SUBJ_KEY_LABEL,
- strlen(SUBJ_KEY_LABEL),
- keySize,
- ¶ms.pubKey,
- CSSM_FALSE, // pubIsRef
- CSSM_KEYUSE_VERIFY,
- CSSM_KEYBLOB_RAW_FORMAT_NONE,
- ¶ms.privKey,
- CSSM_TRUE, // privIsRef - doesn't matter
- CSSM_KEYUSE_SIGN,
- CSSM_KEYBLOB_RAW_FORMAT_NONE,
- CSSM_FALSE);
- if(crtn) {
- return 1;
- }
- params.dummyName = CB_BuildX509Name(dummyRdn, NUM_DUMMY_NAMES);
- if(params.dummyName == NULL) {
- printf("CB_BuildX509Name failure");
- return 1;
- }
- params.notBefore = CB_BuildX509Time(0);
- params.notAfter = CB_BuildX509Time(10000);
-
- /* now some extensions */
- for(unsigned dex=0; dex<MAX_EXTENSIONS; dex++) {
- CSSM_X509_EXTENSION &extn = params.extens[dex];
- ExtenTest &etest = extenTests[dex];
-
- void *extVal = CSSM_MALLOC(etest.extenSize);
- memset(extVal, 0, etest.extenSize);
- etest.createFcn(extVal);
-
- extn.extnId = etest.extenOid;
- extn.critical = randBool();
- extn.format = CSSM_X509_DATAFORMAT_PARSED;
- extn.value.parsedValue = extVal;
- extn.BERvalue.Data = NULL;
- extn.BERvalue.Length = 0;
- }
- return 0;
-}
-
-static int doCreate(
- CSSM_CL_HANDLE clHand,
- CSSM_CSP_HANDLE cspHand,
- unsigned loops,
- PresetParams ¶ms,
- bool doSign,
- bool rsaBlind)
-{
- for(unsigned loop=0; loop<loops; loop++) {
- CSSM_DATA_PTR rawCert = CB_MakeCertTemplate(clHand,
- 0x12345678, // serial number
- params.dummyName,
- params.dummyName,
- params.notBefore,
- params.notAfter,
- ¶ms.pubKey,
- SIG_ALG,
- NULL, // subjUniqueId
- NULL, // issuerUniqueId
- params.extens, // extensions
- /* vary numExtensions per loop */
- loop % MAX_EXTENSIONS);
- if(rawCert == NULL) {
- printf("Error creating cert template.\n");
- return 1;
- }
- if(doSign) {
- CSSM_DATA signedCert = {0, NULL};
- CSSM_CC_HANDLE sigHand;
- CSSM_RETURN crtn = CSSM_CSP_CreateSignatureContext(cspHand,
- SIG_ALG,
- NULL, // no passphrase for now
- ¶ms.privKey,
- &sigHand);
- if(crtn) {
- printError("CreateSignatureContext", crtn);
- return 1;
- }
-
- if(rsaBlind) {
- CSSM_CONTEXT_ATTRIBUTE newAttr;
- newAttr.AttributeType = CSSM_ATTRIBUTE_RSA_BLINDING;
- newAttr.AttributeLength = sizeof(uint32);
- newAttr.Attribute.Uint32 = 1;
- crtn = CSSM_UpdateContextAttributes(sigHand, 1, &newAttr);
- if(crtn) {
- printError("CSSM_UpdateContextAttributes", crtn);
- return crtn;
- }
- }
-
- crtn = CSSM_CL_CertSign(clHand,
- sigHand,
- rawCert, // CertToBeSigned
- NULL, // SignScope per spec
- 0, // ScopeSize per spec
- &signedCert);
- if(crtn) {
- printError("CSSM_CL_CertSign", crtn);
- return 1;
- }
- CSSM_DeleteContext(sigHand);
- CSSM_FREE(signedCert.Data);
- }
- CSSM_FREE(rawCert->Data);
- CSSM_FREE(rawCert);
- }
- return 0;
-}
-
-typedef enum {
- CTO_Parse,
- CTO_GetFields,
- CTO_GetSomeFields,
- CTO_Create, // sign is an option for this one
- CTO_Verify
-} CT_Op;
-
-int main(int argc, char **argv)
-{
- CSSM_CL_HANDLE clHand;
- CSSM_CSP_HANDLE cspHand;
- int arg;
- int rtn;
- char *argp;
- unsigned i;
- PresetParams params;
- CSSM_DATA certData[NUM_PARSED_CERTS];
-
- /* user-specificied params */
- CT_Op op;
- unsigned loops = 0;
- bool doSign = false;
- const char *opStr = NULL;
- bool rsaBlinding = false;
- unsigned keySize = KEYSIZE_DEF;
-
- if(argc < 3) {
- usage(argv);
- }
- switch(argv[1][0]) {
- case 'p':
- op = CTO_Parse;
- opStr = "Parsed";
- break;
- case 'g':
- op = CTO_GetFields;
- opStr = "Parsed with GetAllFields";
- break;
- case 't':
- op = CTO_GetSomeFields;
- #if CL_KEY_VIA_GET_KEY
- opStr = "Parsed with some GetFields and GetKeyInfo";
- #else
- opStr = "Parsed with some GetFields";
- #endif
- break;
- case 'c':
- op = CTO_Create;
- opStr = "Created";
- break;
- case 's':
- op = CTO_Create;
- opStr = "Created and Signed";
- doSign = true;
- break;
- case 'v':
- op = CTO_Verify;
- opStr = "Verified";
- break;
- default:
- usage(argv);
- }
-
- loops = atoi(argv[2]);
- for(arg=3; arg<argc; arg++) {
- argp = argv[arg];
- switch(argp[0]) {
- case 'b':
- rsaBlinding = true;
- break;
- case 'k':
- keySize = atoi(&argp[2]);
- break;
- default:
- usage(argv);
- }
- }
-
- /* common setup */
- clHand = clStartup();
- if(clHand == 0) {
- return 0;
- }
- cspHand = cspStartup();
- if(cspHand == 0) {
- return 0;
- }
-
- /* per-test setup */
- switch(op) {
- unsigned dex;
- unsigned len;
-
- case CTO_Parse:
- case CTO_GetFields:
- case CTO_GetSomeFields:
- case CTO_Verify:
- /* read in the certs */
- for(dex=0; dex<NUM_PARSED_CERTS; dex++) {
- CSSM_DATA &cdata = certData[dex];
- if(readFile(certNames[dex],
- (unsigned char **)&cdata.Data,
- &len)) {
- printf("Error reading cert %s. Aborting.\n",
- certNames[dex]);
- exit(1);
- }
- cdata.Length = len;
- }
- break;
- case CTO_Create:
- /* set up keys, names */
- if(createSetup(clHand, cspHand, keySize, params)) {
- exit(1);
- }
- break;
- }
-
- /* one loop outside of timer to heat up test bed */
- switch(op) {
- case CTO_Parse:
- rtn = doParse(clHand, certData[0], 1);
- break;
- case CTO_GetFields:
- rtn = doGetFields(clHand, certData[0], 1);
- break;
- case CTO_GetSomeFields:
- rtn = doGetSomeFields(clHand, certData[0], 1);
- break;
- case CTO_Verify:
- rtn = doVerify(clHand, certData[0], 1);
- break;
- case CTO_Create:
- rtn = doCreate(clHand, cspHand, 1, params, true, rsaBlinding);
- break;
- }
- if(rtn) {
- printf("This program needs work. Try again.\n");
- return 1;
- }
-
- CFAbsoluteTime startTime, endTime;
- startTime = CFAbsoluteTimeGetCurrent();
-
- /* begin timed loop */
- switch(op) {
- case CTO_Parse:
- for(i=0; i<NUM_PARSED_CERTS; i++) {
- rtn = doParse(clHand, certData[i], loops);
- if(rtn) {
- break;
- }
- }
- break;
- case CTO_GetFields:
- for(i=0; i<NUM_PARSED_CERTS; i++) {
- rtn = doGetFields(clHand, certData[i], loops);
- if(rtn) {
- break;
- }
- }
- break;
- case CTO_GetSomeFields:
- for(i=0; i<NUM_PARSED_CERTS; i++) {
- rtn = doGetSomeFields(clHand, certData[i], loops);
- if(rtn) {
- break;
- }
- }
- break;
- case CTO_Verify:
- for(i=0; i<NUM_PARSED_CERTS; i++) {
- rtn = doVerify(clHand, certData[i], loops);
- if(rtn) {
- break;
- }
- }
- break;
- case CTO_Create:
- rtn = doCreate(clHand, cspHand, loops, params, doSign,
- rsaBlinding);
- break;
- }
- endTime = CFAbsoluteTimeGetCurrent();
- CFAbsoluteTime deltaTime = endTime - startTime;
-
- if(rtn) {
- printf("Error in main loop. Try again.\n");
- return 1;
- }
-
- unsigned numCerts = loops;
- if(op != CTO_Create) {
- numCerts *= NUM_PARSED_CERTS;
- }
-
- printf("=== %u certs %s ===\n", numCerts, opStr);
- printf("Total time %g s\n", deltaTime);
- printf("%g ms per cert\n", (deltaTime / (double)numCerts) * 1000.0);
-
- /* cleanup */
- if(op == CTO_Create) {
- CB_FreeX509Name(params.dummyName);
- CB_FreeX509Time(params.notBefore);
- CB_FreeX509Time(params.notAfter);
- cspFreeKey(cspHand, ¶ms.pubKey);
- cspFreeKey(cspHand, ¶ms.privKey);
- }
- else {
- for(i=0; i<NUM_PARSED_CERTS; i++) {
- free(certData[i].Data);
- }
- }
- CSSM_ModuleDetach(cspHand);
- CSSM_ModuleDetach(clHand);
- return 0;
-}
-