1 /* 2 * tpVerifyParsed.cpp - wrapper for CSSM_TP_CertGroupVerify using parsd anchors. 3 */ 4 5#include <Security/Security.h> 6#include "tpVerifyParsed.h" 7#include <Security/SecRootCertStorePriv.h> 8#include <Security/RootCertCachePriv.h> 9#include <string.h> 10#include <stdlib.h> 11#include <stdio.h> 12#include <clAppUtils/CertParser.h> 13#include <utilLib/common.h> 14 15/* 16 * The main task is converting a set of CSSM_DATA-style anchors into a 17 * SecParsedRootCertArrayRef. 18 */ 19 20/* raw cert --> SecParsedRootCert */ 21static int parseRootCert( 22 CSSM_CL_HANDLE clHand, 23 const CSSM_DATA &certData, 24 SecParsedRootCert &parsedRoot) 25{ 26 try { 27 CertParser cert(clHand, certData); 28 uint32 len = 0; 29 const void *p = cert.fieldForOid(CSSMOID_X509V1SubjectName, len); 30 appCopyData(p, len, &parsedRoot.subject); 31 32 /* skip key and times, I think they are going away */ 33 appCopyCssmData(&certData, &parsedRoot.certData); 34 return 0; 35 } 36 catch(...) { 37 printf("CertParser threw!\n"); 38 return -1; 39 } 40} 41 42static void freeParsedRoot( 43 SecParsedRootCert &parsedRoot) 44{ 45 if(parsedRoot.subject.Data) { 46 CSSM_FREE(parsedRoot.subject.Data); 47 } 48 if(parsedRoot.certData.Data) { 49 CSSM_FREE(parsedRoot.certData.Data); 50 } 51} 52 53static int createParsedCertArray( 54 CSSM_CL_HANDLE clHand, 55 unsigned numAnchorCerts, 56 CSSM_DATA_PTR anchorCerts, 57 SecParsedRootCertArrayRef *arrayRef) // RETURNED 58{ 59 SecParsedRootCertArray *outArray = (SecParsedRootCertArray *)malloc(sizeof(*outArray)); 60 memset(outArray, 0, sizeof(*outArray)); 61 unsigned len = sizeof(SecParsedRootCert) * numAnchorCerts; 62 outArray->roots = (SecParsedRootCert *)malloc(len); 63 memset(outArray->roots, 0, len); 64 for(unsigned dex=0; dex<numAnchorCerts; dex++) { 65 if(parseRootCert(clHand, anchorCerts[dex], outArray->roots[dex])) { 66 return -1; 67 } 68 } 69 outArray->numRoots = numAnchorCerts; 70 *arrayRef = outArray; 71 return 0; 72} 73 74static void freeParsedCertArray( 75 SecParsedRootCertArrayRef arrayRef) 76{ 77 for(unsigned dex=0; dex<arrayRef->numRoots; dex++) { 78 freeParsedRoot(arrayRef->roots[dex]); 79 } 80 free(arrayRef->roots); 81 free((void *)arrayRef); 82} 83 84CSSM_RETURN tpCertGroupVerifyParsed( 85 CSSM_TP_HANDLE tpHand, 86 CSSM_CL_HANDLE clHand, 87 CSSM_CSP_HANDLE cspHand, 88 CSSM_DL_DB_LIST_PTR dbListPtr, 89 const CSSM_OID *policy, // optional 90 const CSSM_DATA *fieldOpts, // optional 91 const CSSM_DATA *actionData, // optional 92 void *policyOpts, 93 const CSSM_CERTGROUP *certGroup, 94 CSSM_DATA_PTR anchorCerts, 95 unsigned numAnchorCerts, 96 CSSM_TP_STOP_ON stopOn, // CSSM_TP_STOP_ON_POLICY, etc. 97 CSSM_TIMESTRING cssmTimeStr,// optional 98 CSSM_TP_VERIFY_CONTEXT_RESULT_PTR result) // optional, RETURNED 99{ 100 /* main job is building a CSSM_TP_VERIFY_CONTEXT and its components */ 101 CSSM_TP_VERIFY_CONTEXT vfyCtx; 102 CSSM_TP_CALLERAUTH_CONTEXT authCtx; 103 104 memset(&vfyCtx, 0, sizeof(CSSM_TP_VERIFY_CONTEXT)); 105 vfyCtx.Action = CSSM_TP_ACTION_DEFAULT; 106 if(actionData) { 107 vfyCtx.ActionData = *actionData; 108 } 109 else { 110 vfyCtx.ActionData.Data = NULL; 111 vfyCtx.ActionData.Length = 0; 112 } 113 vfyCtx.Cred = &authCtx; 114 115 /* CSSM_TP_CALLERAUTH_CONTEXT components */ 116 /* 117 typedef struct cssm_tp_callerauth_context { 118 CSSM_TP_POLICYINFO Policy; 119 CSSM_TIMESTRING VerifyTime; 120 CSSM_TP_STOP_ON VerificationAbortOn; 121 CSSM_TP_VERIFICATION_RESULTS_CALLBACK CallbackWithVerifiedCert; 122 uint32 NumberOfAnchorCerts; 123 CSSM_DATA_PTR AnchorCerts; 124 CSSM_DL_DB_LIST_PTR DBList; 125 CSSM_ACCESS_CREDENTIALS_PTR CallerCredentials; 126 } CSSM_TP_CALLERAUTH_CONTEXT, *CSSM_TP_CALLERAUTH_CONTEXT_PTR; 127 */ 128 /* zero or one policy here */ 129 CSSM_FIELD policyId; 130 if(policy != NULL) { 131 policyId.FieldOid = (CSSM_OID)*policy; 132 authCtx.Policy.NumberOfPolicyIds = 1; 133 authCtx.Policy.PolicyIds = &policyId; 134 if(fieldOpts != NULL) { 135 policyId.FieldValue = *fieldOpts; 136 } 137 else { 138 policyId.FieldValue.Data = NULL; 139 policyId.FieldValue.Length = 0; 140 } 141 } 142 else { 143 authCtx.Policy.NumberOfPolicyIds = 0; 144 authCtx.Policy.PolicyIds = NULL; 145 } 146 authCtx.Policy.PolicyControl = policyOpts; 147 authCtx.VerifyTime = cssmTimeStr; // may be NULL 148 authCtx.VerificationAbortOn = stopOn; 149 authCtx.CallbackWithVerifiedCert = NULL; 150 151 /* here's the difference between this and tpCertGroupVerify */ 152 SecParsedRootCertArrayRef arrayRef = NULL; 153 if(numAnchorCerts) { 154 if(createParsedCertArray(clHand, numAnchorCerts, anchorCerts, &arrayRef)) { 155 return -1; 156 } 157 authCtx.NumberOfAnchorCerts = APPLE_TP_PARSED_ANCHOR_INDICATOR; 158 authCtx.AnchorCerts = (CSSM_DATA_PTR)arrayRef; 159 } 160 else { 161 authCtx.NumberOfAnchorCerts = 0; 162 authCtx.AnchorCerts = NULL; 163 } 164 authCtx.DBList = dbListPtr; 165 authCtx.CallerCredentials = NULL; 166 167 CSSM_RETURN crtn = CSSM_TP_CertGroupVerify(tpHand, 168 clHand, 169 cspHand, 170 certGroup, 171 &vfyCtx, 172 result); 173 174 if(arrayRef) { 175 freeParsedCertArray(arrayRef); 176 } 177 return crtn; 178} 179