/* * 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; }
/* * Create a PA-PK-AS-REQ message. */ krb5_error_code krb5int_pkinit_as_req_create( krb5_context context, krb5_timestamp kctime, krb5_int32 cusec, /* microseconds */ krb5_ui_4 nonce, const krb5_checksum *cksum, krb5_pkinit_signing_cert_t client_cert, /* required */ const krb5_data *trusted_CAs, /* optional list of CA certs */ krb5_ui_4 num_trusted_CAs, const krb5_data *kdc_cert, /* optional KDC cert */ krb5_data *as_req) /* mallocd and RETURNED */ { krb5_data auth_pack = {0}; krb5_error_code krtn; krb5_data content_info = {0}; krb5int_algorithm_id *cms_types = NULL; krb5_ui_4 num_cms_types = 0; /* issuer/serial numbers for trusted_CAs and kdc_cert, if we have them */ krb5_data *ca_issuer_sn = NULL; /* issuer/serial_num for trusted_CAs */ krb5_data kdc_issuer_sn = {0}; /* issuer/serial_num for kdc_cert */ krb5_data *kdc_issuer_sn_p = NULL; /* optional platform-dependent CMS algorithm preference */ krtn = krb5int_pkinit_get_cms_types(&cms_types, &num_cms_types); if(krtn) { return krtn; } /* encode the core authPack */ krtn = krb5int_pkinit_auth_pack_encode(kctime, cusec, nonce, cksum, cms_types, num_cms_types, &auth_pack); if(krtn) { goto errOut; } /* package the AuthPack up in a SignedData inside a ContentInfo */ krtn = krb5int_pkinit_create_cms_msg(&auth_pack, client_cert, NULL, /* recip_cert */ ECT_PkAuthData, 0, NULL, /* cms_types */ &content_info); if(krtn) { goto errOut; } /* if we have trusted_CAs, get issuer/serials */ if(trusted_CAs) { unsigned dex; ca_issuer_sn = (krb5_data *)malloc(num_trusted_CAs * sizeof(krb5_data)); if(ca_issuer_sn == NULL) { krtn = ENOMEM; goto errOut; } for(dex=0; dex<num_trusted_CAs; dex++) { krtn = krb5int_pkinit_get_issuer_serial(&trusted_CAs[dex], &ca_issuer_sn[dex]); if(krtn) { goto errOut; } } } /* If we have a KDC cert, get its issuer/serial */ if(kdc_cert) { krtn = krb5int_pkinit_get_issuer_serial(kdc_cert, &kdc_issuer_sn); if(krtn) { goto errOut; } kdc_issuer_sn_p = &kdc_issuer_sn; } /* cook up PA-PK-AS-REQ */ krtn = krb5int_pkinit_pa_pk_as_req_encode(&content_info, ca_issuer_sn, num_trusted_CAs, kdc_issuer_sn_p, as_req); errOut: if(cms_types) { krb5int_pkinit_free_cms_types(cms_types, num_cms_types); } if(auth_pack.data) { free(auth_pack.data); } if(content_info.data) { free(content_info.data); } if(trusted_CAs) { unsigned dex; for(dex=0; dex<num_trusted_CAs; dex++) { free(ca_issuer_sn[dex].data); } free(ca_issuer_sn); } if(kdc_cert) { free(kdc_issuer_sn.data); } return krtn; }