int dbOpenCloseEval(TestParams *testParams) { int ourRtn = 0; for(unsigned loop=0; loop<testParams->numLoops; loop++) { if(testParams->verbose) { printf("dbOpenClose thread %d: loop %d\n", testParams->threadNum, loop); } else if(!testParams->quiet) { printChar(testParams->progressChar); } /* attach to existing DB - don't create */ CSSM_DB_HANDLE dbHand = cuDbStartupByName(dlHand, (char *)DB_NAME, CSSM_FALSE, // don't create testParams->quiet); if(dbHand == 0) { printf("***dbOpenClose: error attaching to db %s\n", DB_NAME); ourRtn = -1; break; } CSSM_DL_DB_HANDLE dlDbHand = {dlHand, dbHand}; CSSM_RETURN crtn = CSSM_DL_DbClose(dlDbHand); if(crtn) { cssmPerror("CSSM_DL_DbClose", crtn); printf("***Error closing %s\n", DB_NAME); ourRtn = -1; break; } } return ourRtn; }
/* * Verify a CRL against system anchors and intermediate certs. */ CSSM_RETURN cuCrlVerify( CSSM_TP_HANDLE tpHand, CSSM_CL_HANDLE clHand, CSSM_CSP_HANDLE cspHand, const CSSM_DATA *crlData, CSSM_DL_DB_HANDLE_PTR certKeychain, // intermediate certs const CSSM_DATA *anchors, // optional - if NULL, use Trust Settings uint32 anchorCount) { /* main job is building a CSSM_TP_VERIFY_CONTEXT and its components */ CSSM_TP_VERIFY_CONTEXT vfyCtx; CSSM_TP_CALLERAUTH_CONTEXT authCtx; memset(&vfyCtx, 0, sizeof(CSSM_TP_VERIFY_CONTEXT)); memset(&authCtx, 0, sizeof(CSSM_TP_CALLERAUTH_CONTEXT)); /* CSSM_TP_CALLERAUTH_CONTEXT components */ /* typedef struct cssm_tp_callerauth_context { CSSM_TP_POLICYINFO Policy; CSSM_TIMESTRING VerifyTime; CSSM_TP_STOP_ON VerificationAbortOn; CSSM_TP_VERIFICATION_RESULTS_CALLBACK CallbackWithVerifiedCert; uint32 NumberOfAnchorCerts; CSSM_DATA_PTR AnchorCerts; CSSM_DL_DB_LIST_PTR DBList; CSSM_ACCESS_CREDENTIALS_PTR CallerCredentials; } CSSM_TP_CALLERAUTH_CONTEXT, *CSSM_TP_CALLERAUTH_CONTEXT_PTR; */ CSSM_FIELD policyId; CSSM_APPLE_TP_CRL_OPTIONS crlOpts; policyId.FieldOid = CSSMOID_APPLE_TP_REVOCATION_CRL; policyId.FieldValue.Data = (uint8 *)&crlOpts; policyId.FieldValue.Length = sizeof(crlOpts); crlOpts.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; /* perhaps this should be user-specifiable */ crlOpts.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET; crlOpts.crlStore = NULL; authCtx.Policy.NumberOfPolicyIds = 1; authCtx.Policy.PolicyIds = &policyId; authCtx.Policy.PolicyControl = NULL; authCtx.VerifyTime = NULL; authCtx.VerificationAbortOn = CSSM_TP_STOP_ON_POLICY; authCtx.CallbackWithVerifiedCert = NULL; /* anchors */ authCtx.NumberOfAnchorCerts = anchorCount; authCtx.AnchorCerts = const_cast<CSSM_DATA_PTR>(anchors); /* DBList of intermediate certs, plus possible System.keychain and * system roots */ CSSM_DL_DB_HANDLE handles[3]; unsigned numDbs = 0; CSSM_DL_HANDLE dlHand = 0; if(certKeychain != NULL) { handles[0] = *certKeychain; numDbs++; } if(anchors == NULL) { /* Trust Settings requires two more DBs */ if(numDbs == 0) { /* new DL handle */ dlHand = cuDlStartup(); handles[numDbs].DLHandle = dlHand; handles[numDbs + 1].DLHandle = dlHand; } else { /* use the same one passed in for certKeychain */ handles[numDbs].DLHandle = handles[0].DLHandle; handles[numDbs + 1].DLHandle = handles[0].DLHandle; } handles[numDbs].DBHandle = cuDbStartupByName(handles[numDbs].DLHandle, (char*) ADMIN_CERT_STORE_PATH, CSSM_FALSE, CSSM_TRUE); numDbs++; handles[numDbs].DBHandle = cuDbStartupByName(handles[numDbs].DLHandle, (char*) SYSTEM_ROOT_STORE_PATH, CSSM_FALSE, CSSM_TRUE); numDbs++; } CSSM_DL_DB_LIST dlDbList; dlDbList.DLDBHandle = handles; dlDbList.NumHandles = numDbs; authCtx.DBList = &dlDbList; authCtx.CallerCredentials = NULL; /* CSSM_TP_VERIFY_CONTEXT */ vfyCtx.ActionData.Data = NULL; vfyCtx.ActionData.Length = 0; vfyCtx.Action = CSSM_TP_ACTION_DEFAULT; vfyCtx.Cred = &authCtx; /* CSSM_APPLE_TP_ACTION_DATA */ CSSM_APPLE_TP_ACTION_DATA tpAction; if(anchors == NULL) { /* enable Trust Settings */ tpAction.Version = CSSM_APPLE_TP_ACTION_VERSION; tpAction.ActionFlags = CSSM_TP_ACTION_TRUST_SETTINGS; vfyCtx.ActionData.Data = (uint8 *)&tpAction; vfyCtx.ActionData.Length = sizeof(tpAction); } /* cook up CSSM_ENCODED_CRL */ CSSM_ENCODED_CRL encCrl; encCrl.CrlType = CSSM_CRL_TYPE_X_509v2; encCrl.CrlEncoding = CSSM_CRL_ENCODING_DER; encCrl.CrlBlob = *crlData; /* CDSA API requires a SignerCertGroup; for us, all the certs are in * certKeyChain... */ CSSM_CERTGROUP certGroup; certGroup.CertType = CSSM_CERT_X_509v1; certGroup.CertEncoding = CSSM_CERT_ENCODING_DER; certGroup.NumCerts = 0; certGroup.GroupList.CertList = NULL; certGroup.CertGroupType = CSSM_CERTGROUP_DATA; CSSM_RETURN crtn = CSSM_TP_CrlVerify(tpHand, clHand, cspHand, &encCrl, &certGroup, &vfyCtx, NULL); // RevokerVerifyResult if(crtn) { cuPrintError("CSSM_TP_CrlVerify", crtn); } if(anchors == NULL) { /* close the DBs and maybe the DL we opened */ unsigned dexToClose = (certKeychain == NULL) ? 0 : 1; CSSM_DL_DbClose(handles[dexToClose++]); CSSM_DL_DbClose(handles[dexToClose]); if(dlHand != 0) { cuDlDetachUnload(dlHand); } } return crtn; }
int certVerify(CertVerifyArgs *vfyArgs) { if(vfyArgs->version != CERT_VFY_ARGS_VERS) { printf("***CertVerifyArgs.Version mismatch. Clean and rebuild.\n"); return -1; } /* main job is building a CSSM_TP_VERIFY_CONTEXT and its components */ CSSM_TP_VERIFY_CONTEXT vfyCtx; CSSM_TP_CALLERAUTH_CONTEXT authCtx; CSSM_TP_VERIFY_CONTEXT_RESULT vfyResult; CSSM_APPLE_TP_SSL_OPTIONS sslOpts; CSSM_APPLE_TP_SMIME_OPTIONS smimeOpts; memset(&vfyCtx, 0, sizeof(CSSM_TP_VERIFY_CONTEXT)); memset(&authCtx, 0, sizeof(CSSM_TP_CALLERAUTH_CONTEXT)); /* CSSM_TP_CALLERAUTH_CONTEXT components */ /* typedef struct cssm_tp_callerauth_context { CSSM_TP_POLICYINFO Policy; CSSM_TIMESTRING VerifyTime; CSSM_TP_STOP_ON VerificationAbortOn; CSSM_TP_VERIFICATION_RESULTS_CALLBACK CallbackWithVerifiedCert; uint32 NumberOfAnchorCerts; CSSM_DATA_PTR AnchorCerts; CSSM_DL_DB_LIST_PTR DBList; CSSM_ACCESS_CREDENTIALS_PTR CallerCredentials; } CSSM_TP_CALLERAUTH_CONTEXT, *CSSM_TP_CALLERAUTH_CONTEXT_PTR; */ /* up to 3 policies */ CSSM_FIELD policyIds[3]; CSSM_FIELD *policyPtr = &policyIds[0]; uint32 numPolicies = 0; memset(policyIds, 0, 3 * sizeof(CSSM_FIELD)); switch(vfyArgs->vfyPolicy) { case CVP_SSL: case CVP_IPSec: if(vfyArgs->vfyPolicy == CVP_SSL) { policyPtr->FieldOid = CSSMOID_APPLE_TP_SSL; } else { policyPtr->FieldOid = CSSMOID_APPLE_TP_IP_SEC; } /* otherwise these policies are identical */ /* sslOpts is optional */ if((vfyArgs->sslHost != NULL) || vfyArgs->sslClient) { memset(&sslOpts, 0, sizeof(sslOpts)); sslOpts.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION; sslOpts.ServerName = vfyArgs->sslHost; if(vfyArgs->sslHost != NULL) { sslOpts.ServerNameLen = strlen(vfyArgs->sslHost) + 1; } if(vfyArgs->sslClient) { sslOpts.Flags |= CSSM_APPLE_TP_SSL_CLIENT; } policyPtr->FieldValue.Data = (uint8 *)&sslOpts; policyPtr->FieldValue.Length = sizeof(sslOpts); } break; case CVP_SMIME: case CVP_iChat: if(vfyArgs->vfyPolicy == CVP_SMIME) { policyPtr->FieldOid = CSSMOID_APPLE_TP_SMIME; } else { policyPtr->FieldOid = CSSMOID_APPLE_TP_ICHAT; } /* otherwise these policies are identical */ /* smimeOpts is optional */ if(vfyArgs->senderEmail != NULL) { smimeOpts.Version = CSSM_APPLE_TP_SMIME_OPTS_VERSION; smimeOpts.IntendedUsage = vfyArgs->intendedKeyUse; smimeOpts.SenderEmail = vfyArgs->senderEmail; smimeOpts.SenderEmailLen = strlen(vfyArgs->senderEmail) + 1; policyPtr->FieldValue.Data = (uint8 *)&smimeOpts; policyPtr->FieldValue.Length = sizeof(smimeOpts); } break; case CVP_Basic: policyPtr->FieldOid = CSSMOID_APPLE_X509_BASIC; break; case CVP_SWUpdateSign: /* no options */ policyPtr->FieldOid = CSSMOID_APPLE_TP_SW_UPDATE_SIGNING; break; case CVP_ResourceSigning: /* no options */ policyPtr->FieldOid = CSSMOID_APPLE_TP_RESOURCE_SIGN; break; case CVP_PKINIT_Server: /* no options */ policyPtr->FieldOid = CSSMOID_APPLE_TP_PKINIT_SERVER; break; case CVP_PKINIT_Client: /* no options */ policyPtr->FieldOid = CSSMOID_APPLE_TP_PKINIT_CLIENT; break; case CVP_AppleCodeSigning: /* no options */ policyPtr->FieldOid = CSSMOID_APPLE_TP_CODE_SIGNING; break; case CVP_PackageSigning: /* no options */ policyPtr->FieldOid = CSSMOID_APPLE_TP_PACKAGE_SIGNING; break; default: printf("***certVerify: bogus vfyPolicy\n"); return 1; } if(verifySecPolicy(&policyPtr->FieldOid)) { return -1; } policyPtr++; numPolicies++; CSSM_APPLE_TP_CRL_OPTIONS crlOpts; if((vfyArgs->revokePolicy == CRP_CRL) || (vfyArgs->revokePolicy == CRP_CRL_OCSP)) { memset(&crlOpts, 0, sizeof(crlOpts)); policyPtr->FieldOid = CSSMOID_APPLE_TP_REVOCATION_CRL; crlOpts.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; crlOpts.CrlFlags = 0; crlOpts.crlStore = NULL; policyPtr->FieldValue.Data = (uint8 *)&crlOpts; policyPtr->FieldValue.Length = sizeof(crlOpts); if(vfyArgs->requireCrlForAll) { crlOpts.CrlFlags |= CSSM_TP_ACTION_REQUIRE_CRL_PER_CERT; } if(vfyArgs->crlNetFetchEnable) { crlOpts.CrlFlags |= CSSM_TP_ACTION_FETCH_CRL_FROM_NET; } if(vfyArgs->requireCrlIfPresent) { crlOpts.CrlFlags |= CSSM_TP_ACTION_REQUIRE_CRL_IF_PRESENT; } crlOpts.crlStore = vfyArgs->crlDlDb; policyPtr++; numPolicies++; } CSSM_APPLE_TP_OCSP_OPTIONS ocspOpts; CSSM_DATA respUriData; CSSM_DATA respCertData = {vfyArgs->responderCertLen, (uint8 *)vfyArgs->responderCert}; if((vfyArgs->revokePolicy == CRP_OCSP) || (vfyArgs->revokePolicy == CRP_CRL_OCSP)) { memset(&ocspOpts, 0, sizeof(ocspOpts)); policyPtr->FieldOid = CSSMOID_APPLE_TP_REVOCATION_OCSP; crlOpts.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION; policyPtr->FieldValue.Data = (uint8 *)&ocspOpts; policyPtr->FieldValue.Length = sizeof(ocspOpts); if(vfyArgs->requireOcspForAll) { ocspOpts.Flags |= CSSM_TP_ACTION_OCSP_REQUIRE_PER_CERT; } if(vfyArgs->requireOcspIfPresent) { ocspOpts.Flags |= CSSM_TP_ACTION_OCSP_REQUIRE_IF_RESP_PRESENT; } if(vfyArgs->disableCache) { ocspOpts.Flags |= (CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE | CSSM_TP_ACTION_OCSP_CACHE_WRITE_DISABLE); } if(vfyArgs->disableOcspNet) { ocspOpts.Flags |= CSSM_TP_ACTION_OCSP_DISABLE_NET; } if(vfyArgs->generateOcspNonce) { ocspOpts.Flags |= CSSM_TP_OCSP_GEN_NONCE; } if(vfyArgs->requireOcspRespNonce) { ocspOpts.Flags |= CSSM_TP_OCSP_REQUIRE_RESP_NONCE; } if(vfyArgs->responderURI != NULL) { respUriData.Data = (uint8 *)vfyArgs->responderURI; respUriData.Length = strlen(vfyArgs->responderURI); ocspOpts.LocalResponder = &respUriData; } if(vfyArgs->responderCert != NULL) { ocspOpts.LocalResponderCert = &respCertData; } /* other OCSP options here */ policyPtr++; numPolicies++; } authCtx.Policy.NumberOfPolicyIds = numPolicies; authCtx.Policy.PolicyIds = policyIds; authCtx.Policy.PolicyControl = NULL; authCtx.VerifyTime = vfyArgs->vfyTime; // may be NULL authCtx.VerificationAbortOn = CSSM_TP_STOP_ON_POLICY; authCtx.CallbackWithVerifiedCert = NULL; /* * DLDBs - the caller's optional set, plus two more we open * if trust settings are enabled and we're told to use system * anchors. (System anchors are normally passed in via * authCtx.AnchorCerts; they're passed in as DLDBs when * using TrustSettings.) */ uint32 totalNumDbs = 0; uint32 numCallerDbs = 0; CSSM_BOOL weOpenedDbs = CSSM_FALSE; if(vfyArgs->dlDbList != NULL) { totalNumDbs = numCallerDbs = vfyArgs->dlDbList->NumHandles; } if(vfyArgs->useTrustSettings && vfyArgs->useSystemAnchors) { /* we'll cook up two more DBs and possible append them */ totalNumDbs += 2; weOpenedDbs = CSSM_TRUE; } CSSM_DL_DB_HANDLE dlDbHandles[totalNumDbs]; CSSM_DL_DB_LIST dlDbList; CSSM_DL_HANDLE dlHand = 0; for(unsigned dex=0; dex<numCallerDbs; dex++) { dlDbHandles[dex] = vfyArgs->dlDbList->DLDBHandle[dex]; } if(weOpenedDbs) { /* get a DL handle, somehow */ if(numCallerDbs == 0) { /* new DL handle */ dlHand = cuDlStartup(); dlDbHandles[0].DLHandle = dlHand; dlDbHandles[1].DLHandle = dlHand; } else { /* use the same one caller passed in */ dlDbHandles[numCallerDbs].DLHandle = dlDbHandles[0].DLHandle; dlDbHandles[numCallerDbs + 1].DLHandle = dlDbHandles[0].DLHandle; } /* now open two DBs */ dlDbHandles[numCallerDbs].DBHandle = cuDbStartupByName(dlDbHandles[numCallerDbs].DLHandle, (char *)ADMIN_CERT_STORE_PATH, CSSM_FALSE, CSSM_TRUE); dlDbHandles[numCallerDbs + 1].DBHandle = cuDbStartupByName(dlDbHandles[numCallerDbs].DLHandle, (char *)SYSTEM_ROOT_STORE_PATH, CSSM_FALSE, CSSM_TRUE); } dlDbList.DLDBHandle = dlDbHandles; dlDbList.NumHandles = totalNumDbs; authCtx.DBList = &dlDbList; CFArrayRef cfAnchors = NULL; CSSM_DATA *cssmAnchors = NULL; unsigned numAnchors = 0; if(vfyArgs->useSystemAnchors) { if(!vfyArgs->useTrustSettings) { /* standard system anchors - ingore error, I'm sure the * current test will eventually fail */ getSystemAnchors(&cfAnchors, &cssmAnchors, &numAnchors); authCtx.NumberOfAnchorCerts = numAnchors; authCtx.AnchorCerts = cssmAnchors; } } else { /* anchors are our caller's roots */ if(vfyArgs->roots) { authCtx.NumberOfAnchorCerts = vfyArgs->roots->numBlobs(); authCtx.AnchorCerts = vfyArgs->roots->blobList(); } } authCtx.CallerCredentials = NULL; if(vfyArgs->crls) { /* cook up CRL group */ CSSM_CRLGROUP_PTR cssmCrls = &vfyCtx.Crls; cssmCrls->CrlType = CSSM_CRL_TYPE_X_509v1; cssmCrls->CrlEncoding = CSSM_CRL_ENCODING_DER; cssmCrls->NumberOfCrls = vfyArgs->crls->numBlobs(); cssmCrls->GroupCrlList.CrlList = vfyArgs->crls->blobList(); cssmCrls->CrlGroupType = CSSM_CRLGROUP_DATA; } /* CSSM_APPLE_TP_ACTION_DATA */ CSSM_APPLE_TP_ACTION_DATA tpAction; tpAction.Version = CSSM_APPLE_TP_ACTION_VERSION; tpAction.ActionFlags = 0; if(vfyArgs->leafCertIsCA) { tpAction.ActionFlags |= CSSM_TP_ACTION_LEAF_IS_CA; } if(vfyArgs->certNetFetchEnable) { tpAction.ActionFlags |= CSSM_TP_ACTION_FETCH_CERT_FROM_NET; } if(vfyArgs->allowExpiredRoot) { tpAction.ActionFlags |= CSSM_TP_ACTION_ALLOW_EXPIRED_ROOT; } if(!vfyArgs->allowUnverified) { tpAction.ActionFlags |= CSSM_TP_ACTION_REQUIRE_REV_PER_CERT; } if(vfyArgs->useTrustSettings) { tpAction.ActionFlags |= CSSM_TP_ACTION_TRUST_SETTINGS; } if(vfyArgs->implicitAnchors) { tpAction.ActionFlags |= CSSM_TP_ACTION_IMPLICIT_ANCHORS; } /* CSSM_TP_VERIFY_CONTEXT */ vfyCtx.ActionData.Data = (uint8 *)&tpAction; vfyCtx.ActionData.Length = sizeof(tpAction); vfyCtx.Action = CSSM_TP_ACTION_DEFAULT; vfyCtx.Cred = &authCtx; /* cook up cert group */ CSSM_CERTGROUP cssmCerts; cssmCerts.CertType = CSSM_CERT_X_509v3; cssmCerts.CertEncoding = CSSM_CERT_ENCODING_DER; cssmCerts.NumCerts = vfyArgs->certs->numBlobs(); cssmCerts.GroupList.CertList = vfyArgs->certs->blobList(); cssmCerts.CertGroupType = CSSM_CERTGROUP_DATA; int ourRtn = 0; CSSM_RETURN crtn = CSSM_TP_CertGroupVerify(vfyArgs->tpHand, vfyArgs->clHand, vfyArgs->cspHand, &cssmCerts, &vfyCtx, &vfyResult); if(vfyArgs->expectedErrStr != NULL) { const char *actRtn; if(crtn == CSSM_OK) { /* cssmErrorString munges this to "[ok]" */ actRtn = "CSSM_OK"; } else { actRtn = cssmErrToStr(crtn); } char *found = strstr(actRtn, vfyArgs->expectedErrStr); if(found) { if(!vfyArgs->quiet) { printf("...%s received as expected\n", vfyArgs->expectedErrStr); } } else { printf("***CSSM_TP_CertGroupVerify error\n"); printf(" expected rtn : %s\n", vfyArgs->expectedErrStr); printf(" actual rtn : %s\n", actRtn); ourRtn = 1; } } else { if(crtn) { if(!vfyArgs->quiet) { printError("CSSM_TP_CertGroupVerify", crtn); } ourRtn = 1; } else if(!vfyArgs->quiet) { printf("...verify successful\n"); } } if(vfyArgs->certErrors) { if(vfyCertErrors(&vfyResult, vfyArgs->numCertErrors, vfyArgs->certErrors, vfyArgs->quiet)) { ourRtn = 1; } } if(vfyArgs->certStatus) { if(vfyCertStatus(&vfyResult, vfyArgs->numCertStatus, vfyArgs->certStatus, vfyArgs->quiet)) { ourRtn = 1; } } if(vfyArgs->verbose) { dumpVfyResult(&vfyResult); } freeVfyResult(&vfyResult); if(weOpenedDbs) { /* close the DBs and maybe the DL we opened */ CSSM_DL_DbClose(dlDbHandles[numCallerDbs]); CSSM_DL_DbClose(dlDbHandles[numCallerDbs + 1]); if(dlHand != 0) { cuDlDetachUnload(dlHand); } } if(cfAnchors) { CFRelease(cfAnchors); } if(cssmAnchors) { free(cssmAnchors); } return ourRtn; }