static krb5_error_code pk_mk_pa_reply_dh(krb5_context context, krb5_kdc_configuration *config, pk_client_params *cp, ContentInfo *content_info, hx509_cert *kdc_cert) { KDCDHKeyInfo dh_info; krb5_data signed_data, buf; ContentInfo contentinfo; krb5_error_code ret; hx509_cert cert; hx509_query *q; size_t size = 0; memset(&contentinfo, 0, sizeof(contentinfo)); memset(&dh_info, 0, sizeof(dh_info)); krb5_data_zero(&signed_data); krb5_data_zero(&buf); *kdc_cert = NULL; if (cp->keyex == USE_DH) { DH *kdc_dh = cp->u.dh.key; heim_integer i; ret = BN_to_integer(context, kdc_dh->pub_key, &i); if (ret) return ret; ASN1_MALLOC_ENCODE(DHPublicKey, buf.data, buf.length, &i, &size, ret); der_free_heim_integer(&i); if (ret) { krb5_set_error_message(context, ret, "ASN.1 encoding of " "DHPublicKey failed (%d)", ret); return ret; } if (buf.length != size) krb5_abortx(context, "Internal ASN.1 encoder error"); dh_info.subjectPublicKey.length = buf.length * 8; dh_info.subjectPublicKey.data = buf.data; krb5_data_zero(&buf); } else if (cp->keyex == USE_ECDH) { unsigned char *p; ret = _kdc_serialize_ecdh_key(context, cp->u.ecdh.key, &p, &dh_info.subjectPublicKey.length); dh_info.subjectPublicKey.data = p; if (ret) goto out; } else krb5_abortx(context, "no keyex selected ?"); dh_info.nonce = cp->nonce; ASN1_MALLOC_ENCODE(KDCDHKeyInfo, buf.data, buf.length, &dh_info, &size, ret); if (ret) { krb5_set_error_message(context, ret, "ASN.1 encoding of " "KdcDHKeyInfo failed (%d)", ret); goto out; } if (buf.length != size) krb5_abortx(context, "Internal ASN.1 encoder error"); /* * Create the SignedData structure and sign the KdcDHKeyInfo * filled in above */ ret = hx509_query_alloc(context->hx509ctx, &q); if (ret) goto out; hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY); if (config->pkinit_kdc_friendly_name) hx509_query_match_friendly_name(q, config->pkinit_kdc_friendly_name); ret = hx509_certs_find(context->hx509ctx, kdc_identity->certs, q, &cert); hx509_query_free(context->hx509ctx, q); if (ret) goto out; ret = hx509_cms_create_signed_1(context->hx509ctx, 0, &asn1_oid_id_pkdhkeydata, buf.data, buf.length, NULL, cert, cp->peer, cp->client_anchors, kdc_identity->certpool, &signed_data); if (ret) { kdc_log(context, config, 0, "Failed signing the DH* reply: %d", ret); goto out; } *kdc_cert = cert; ret = _krb5_pk_mk_ContentInfo(context, &signed_data, &asn1_oid_id_pkcs7_signedData, content_info); if (ret) goto out; out: if (ret && *kdc_cert) { hx509_cert_free(*kdc_cert); *kdc_cert = NULL; } krb5_data_free(&buf); krb5_data_free(&signed_data); free_KDCDHKeyInfo(&dh_info); return ret; }
static krb5_error_code pk_mk_pa_reply_dh(krb5_context context, DH *kdc_dh, pk_client_params *client_params, krb5_keyblock *reply_key, ContentInfo *content_info, hx509_cert *kdc_cert) { KDCDHKeyInfo dh_info; krb5_data signed_data, buf; ContentInfo contentinfo; krb5_error_code ret; size_t size; heim_integer i; memset(&contentinfo, 0, sizeof(contentinfo)); memset(&dh_info, 0, sizeof(dh_info)); krb5_data_zero(&buf); krb5_data_zero(&signed_data); *kdc_cert = NULL; ret = BN_to_integer(context, kdc_dh->pub_key, &i); if (ret) return ret; ASN1_MALLOC_ENCODE(DHPublicKey, buf.data, buf.length, &i, &size, ret); if (ret) { krb5_set_error_message(context, ret, "ASN.1 encoding of " "DHPublicKey failed (%d)", ret); return ret; } if (buf.length != size) krb5_abortx(context, "Internal ASN.1 encoder error"); dh_info.subjectPublicKey.length = buf.length * 8; dh_info.subjectPublicKey.data = buf.data; dh_info.nonce = client_params->nonce; ASN1_MALLOC_ENCODE(KDCDHKeyInfo, buf.data, buf.length, &dh_info, &size, ret); if (ret) { krb5_set_error_message(context, ret, "ASN.1 encoding of " "KdcDHKeyInfo failed (%d)", ret); goto out; } if (buf.length != size) krb5_abortx(context, "Internal ASN.1 encoder error"); /* * Create the SignedData structure and sign the KdcDHKeyInfo * filled in above */ { hx509_query *q; hx509_cert cert; ret = hx509_query_alloc(kdc_identity->hx509ctx, &q); if (ret) goto out; hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY); hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE); ret = hx509_certs_find(kdc_identity->hx509ctx, kdc_identity->certs, q, &cert); hx509_query_free(kdc_identity->hx509ctx, q); if (ret) goto out; ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx, 0, oid_id_pkdhkeydata(), buf.data, buf.length, NULL, cert, client_params->peer, client_params->client_anchors, kdc_identity->certpool, &signed_data); *kdc_cert = cert; } if (ret) goto out; ret = _krb5_pk_mk_ContentInfo(context, &signed_data, oid_id_pkcs7_signedData(), content_info); if (ret) goto out; out: if (ret && *kdc_cert) { hx509_cert_free(*kdc_cert); *kdc_cert = NULL; } krb5_data_free(&buf); krb5_data_free(&signed_data); free_KDCDHKeyInfo(&dh_info); return ret; }