/* * Given a certificate, obtain the DER-encoded issuer and serial number. Result * is mallocd and must be freed by caller. */ static OSStatus pkinit_get_cert_issuer_sn( SecCertificateRef certRef, CSSM_DATA *issuerSerial) /* mallocd and RETURNED */ { OSStatus ortn; CSSM_DATA certData; krb5_data INIT_KDATA(issuerSerialKrb); krb5_data certDataKrb; krb5_error_code krtn; assert(certRef != NULL); assert(issuerSerial != NULL); ortn = SecCertificateGetData(certRef, &certData); if(ortn) { pkiCssmErr("SecCertificateGetData", ortn); return ortn; } PKI_CSSM_TO_KRB_DATA(&certData, &certDataKrb); krtn = krb5int_pkinit_get_issuer_serial(&certDataKrb, &issuerSerialKrb); if(krtn) { return CSSMERR_CL_INVALID_DATA; } PKI_KRB_TO_CSSM_DATA(&issuerSerialKrb, issuerSerial); return noErr; }
/* * 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; }