static int checkOneField( CSSM_CL_HANDLE clHand, CSSM_HANDLE cacheHand1, CSSM_HANDLE cacheHand2, const CSSM_OID *fieldOid) { CSSM_DATA_PTR fieldData1 = NULL; CSSM_DATA_PTR fieldData2 = NULL; CSSM_RETURN crtn; CSSM_HANDLE resultHand1 = 0; CSSM_HANDLE resultHand2 = 0; uint32 numFields = 0; int rtn; crtn = CSSM_CL_CertGetFirstCachedFieldValue( clHand, cacheHand1, fieldOid, &resultHand1, &numFields, &fieldData1); if(crtn) { return crtn; } if(numFields != 1) { printf("Fiedl not present; try another cert\n"); return 1; } crtn = CSSM_CL_CertGetFirstCachedFieldValue( clHand, cacheHand2, fieldOid, &resultHand2, &numFields, &fieldData2); if(crtn) { return crtn; } rtn = compareFields(fieldOid, fieldData1, fieldData2); CSSM_CL_CertAbortQuery(clHand, resultHand1); CSSM_CL_CertAbortQuery(clHand, resultHand2); CSSM_CL_FreeFieldValue(clHand, fieldOid, fieldData1); CSSM_CL_FreeFieldValue(clHand, fieldOid, fieldData2); return rtn; }
static void printOneCertName( CSSM_CL_HANDLE clHand, CSSM_HANDLE cacheHand, const char *title, const CSSM_OID *oid) { CSSM_HANDLE resultHand = 0; CSSM_DATA_PTR field = NULL; uint32 numFields; CSSM_RETURN crtn; crtn = CSSM_CL_CertGetFirstCachedFieldValue(clHand, cacheHand, oid, &resultHand, &numFields, &field); if(crtn) { printf("***Error parsing cert\n"); cssmPerror("CSSM_CL_CertGetFirstCachedFieldValue", crtn); return; } printName(title, field->Data, field->Length); CSSM_CL_FreeFieldValue(clHand, oid, field); }
/* * Obtain atrbitrary field from cached cert. This class takes care of freeing * the field in its destructor. * * Returns NULL if field not found (not exception). * * Caller optionally specifies field length to check - specifying zero means * "don't care, don't check". Actual field length always returned in fieldLength. */ const void *CertParser::fieldForOid( const CSSM_OID &oid, CSSM_SIZE &fieldLength) // IN/OUT { CSSM_RETURN crtn; uint32 NumberOfFields = 0; CSSM_HANDLE resultHand = 0; CSSM_DATA_PTR fieldData = NULL; assert(mClHand != 0); assert(mCacheHand != 0); crtn = CSSM_CL_CertGetFirstCachedFieldValue( mClHand, mCacheHand, &oid, &resultHand, &NumberOfFields, &fieldData); if(crtn) { /* not an error; just means that the cert doesn't have this field */ return NULL; } assert(NumberOfFields == 1); CSSM_CL_CertAbortQuery(mClHand, resultHand); if(fieldLength) { if(fieldLength != fieldData->Length) { /* FIXME what's a good way to log in this situation? */ printf("***CertParser::fieldForOid: field length mismatch\n"); return NULL; } } /* Store the OID and the field for autorelease */ CP_FetchedField *cpField = new CP_FetchedField(oid, fieldData, mClHand); mFetchedFields.push_back(cpField); fieldLength = fieldData->Length; return fieldData->Data; }
/* * Given a DER encoded certificate, obtain the associated IssuerAndSerialNumber. */ krb5_error_code krb5int_pkinit_get_issuer_serial( const krb5_data *cert, krb5_data *issuer_and_serial) { CSSM_HANDLE cacheHand = 0; CSSM_RETURN crtn = CSSM_OK; CSSM_DATA certData = { cert->length, (uint8 *)cert->data }; CSSM_HANDLE resultHand = 0; CSSM_DATA_PTR derIssuer = NULL; CSSM_DATA_PTR serial; krb5_data krb_serial; krb5_data krb_issuer; uint32 numFields; krb5_error_code ourRtn = 0; CSSM_CL_HANDLE clHand = pkiClStartup(); if(clHand == 0) { return CSSMERR_CSSM_ADDIN_LOAD_FAILED; } /* subsequent errors to errOut: */ crtn = CSSM_CL_CertCache(clHand, &certData, &cacheHand); if(crtn) { pkiCssmErr("CSSM_CL_CertCache", crtn); ourRtn = ASN1_PARSE_ERROR; goto errOut; } /* obtain the two fields; issuer is DER encoded */ crtn = CSSM_CL_CertGetFirstCachedFieldValue(clHand, cacheHand, &CSSMOID_X509V1IssuerNameStd, &resultHand, &numFields, &derIssuer); if(crtn) { pkiCssmErr("CSSM_CL_CertGetFirstCachedFieldValue(issuer)", crtn); ourRtn = ASN1_PARSE_ERROR; goto errOut; } crtn = CSSM_CL_CertGetFirstCachedFieldValue(clHand, cacheHand, &CSSMOID_X509V1SerialNumber, &resultHand, &numFields, &serial); if(crtn) { pkiCssmErr("CSSM_CL_CertGetFirstCachedFieldValue(serial)", crtn); ourRtn = ASN1_PARSE_ERROR; goto errOut; } PKI_CSSM_TO_KRB_DATA(derIssuer, &krb_issuer); PKI_CSSM_TO_KRB_DATA(serial, &krb_serial); ourRtn = krb5int_pkinit_issuer_serial_encode(&krb_issuer, &krb_serial, issuer_and_serial); errOut: if(derIssuer) { CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1IssuerNameStd, derIssuer); } if(serial) { CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SerialNumber, serial); } if(cacheHand) { CSSM_CL_CertAbortCache(clHand, cacheHand); } if(clHand) { pkiClDetachUnload(clHand); } return ourRtn; }