(_kdc_pk_mk_pa_reply): send back ocsp response if it seems to be

valid, simplfy the pkinit-windows DH case (it doesn't exists).


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17410 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2006-05-02 14:04:34 +00:00
parent 5eb2dd8d17
commit 044719a5bd

View File

@@ -82,6 +82,12 @@ static struct krb5_pk_identity *kdc_identity;
static struct pk_principal_mapping principal_mappings;
static struct krb5_dh_moduli **moduli;
static struct {
krb5_data data;
time_t expire;
time_t next_update;
} ocsp;
/*
*
*/
@@ -754,7 +760,8 @@ pk_mk_pa_reply_dh(krb5_context context,
DH *kdc_dh,
pk_client_params *client_params,
krb5_keyblock *reply_key,
ContentInfo *content_info)
ContentInfo *content_info,
hx509_cert *kdc_cert)
{
KDCDHKeyInfo dh_info;
krb5_data signed_data, buf;
@@ -768,6 +775,8 @@ pk_mk_pa_reply_dh(krb5_context context,
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;
@@ -803,8 +812,8 @@ pk_mk_pa_reply_dh(krb5_context context,
*/
{
hx509_cert cert;
hx509_query *q;
hx509_cert cert;
ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
if (ret)
@@ -830,7 +839,7 @@ pk_mk_pa_reply_dh(krb5_context context,
kdc_identity->anchors,
kdc_identity->certpool,
&signed_data);
hx509_cert_free(cert);
*kdc_cert = cert;
}
if (ret)
goto out;
@@ -843,6 +852,11 @@ pk_mk_pa_reply_dh(krb5_context context,
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);
@@ -869,6 +883,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
size_t len, size;
krb5_enctype enctype;
int pa_type;
hx509_cert kdc_cert = NULL;
int i;
if (!config->enable_pkinit) {
@@ -947,7 +962,8 @@ _kdc_pk_mk_pa_reply(krb5_context context,
ret = pk_mk_pa_reply_dh(context, client_params->dh,
client_params,
&client_params->reply_key,
&info);
&info,
&kdc_cert);
ASN1_MALLOC_ENCODE(ContentInfo, rep.u.dhInfo.dhSignedData.data,
rep.u.dhInfo.dhSignedData.length, &info, &size,
@@ -982,48 +998,43 @@ _kdc_pk_mk_pa_reply(krb5_context context,
} else if (client_params->type == PKINIT_COMPAT_WIN2K) {
PA_PK_AS_REP_Win2k rep;
ContentInfo info;
pa_type = KRB5_PADATA_PK_AS_REP_19;
if (client_params->dh) {
krb5_set_error_string(context, "Windows PK-INIT doesn't support DH");
ret = KRB5KRB_ERR_GENERIC;
goto out;
}
memset(&rep, 0, sizeof(rep));
if (client_params->dh) {
krb5_set_error_string(context, "DH -27 not implemented");
ret = KRB5KRB_ERR_GENERIC;
} else {
rep.element = choice_PA_PK_AS_REP_encKeyPack;
ContentInfo info;
pa_type = KRB5_PADATA_PK_AS_REP_19;
rep.element = choice_PA_PK_AS_REP_encKeyPack;
krb5_generate_random_keyblock(context, enctype,
&client_params->reply_key);
ret = pk_mk_pa_reply_enckey(context,
client_params,
req,
req_buffer,
&client_params->reply_key,
&info);
if (ret) {
free_PA_PK_AS_REP_Win2k(&rep);
goto out;
}
ASN1_MALLOC_ENCODE(ContentInfo, rep.u.encKeyPack.data,
rep.u.encKeyPack.length, &info, &size,
ret);
free_ContentInfo(&info);
if (ret) {
krb5_set_error_string(context, "encoding of Key ContentInfo "
"failed %d", ret);
free_PA_PK_AS_REP_Win2k(&rep);
goto out;
}
if (rep.u.encKeyPack.length != size)
krb5_abortx(context, "Internal ASN.1 encoder error");
}
krb5_generate_random_keyblock(context, enctype,
&client_params->reply_key);
ret = pk_mk_pa_reply_enckey(context,
client_params,
req,
req_buffer,
&client_params->reply_key,
&info);
if (ret) {
free_PA_PK_AS_REP_Win2k(&rep);
goto out;
}
ASN1_MALLOC_ENCODE(ContentInfo, rep.u.encKeyPack.data,
rep.u.encKeyPack.length, &info, &size,
ret);
free_ContentInfo(&info);
if (ret) {
krb5_set_error_string(context, "encoding of Key ContentInfo "
"failed %d", ret);
free_PA_PK_AS_REP_Win2k(&rep);
goto out;
}
if (rep.u.encKeyPack.length != size)
krb5_abortx(context, "Internal ASN.1 encoder error");
ASN1_MALLOC_ENCODE(PA_PK_AS_REP_Win2k, buf, len, &rep, &size, ret);
free_PA_PK_AS_REP_Win2k(&rep);
@@ -1041,11 +1052,88 @@ _kdc_pk_mk_pa_reply(krb5_context context,
ret = krb5_padata_add(context, md, pa_type, buf, len);
if (ret) {
krb5_set_error_string(context, "failed adding "
"PA-PK-AS-REP-19 %d", ret);
krb5_set_error_string(context, "failed adding PA-PK-AS-REP %d", ret);
free(buf);
goto out;
}
out:
if (config->pkinit_kdc_ocsp_file) {
if (ocsp.expire == 0 && ocsp.next_update > kdc_time) {
struct stat sb;
int fd;
krb5_data_free(&ocsp.data);
ocsp.expire = 0;
fd = open(config->pkinit_kdc_ocsp_file, O_RDONLY);
if (fd < 0) {
kdc_log(context, config, 0,
"PK-INIT failed to open ocsp data file %d", errno);
goto out_ocsp;
}
ret = fstat(fd, &sb);
if (ret) {
ret = errno;
close(fd);
kdc_log(context, config, 0,
"PK-INIT failed to stat ocsp data %d", ret);
goto out_ocsp;
}
ret = krb5_data_alloc(&ocsp.data, sb.st_size);
if (ret) {
close(fd);
kdc_log(context, config, 0,
"PK-INIT failed to stat ocsp data %d", ret);
goto out_ocsp;
}
ocsp.data.length = sb.st_size;
ret = read(fd, ocsp.data.data, sb.st_size);
close(fd);
if (ret != sb.st_size) {
kdc_log(context, config, 0,
"PK-INIT failed to read ocsp data %d", errno);
goto out_ocsp;
}
ret = hx509_ocsp_verify(kdc_identity->hx509ctx,
kdc_time,
kdc_cert,
0,
ocsp.data.data, ocsp.data.length,
&ocsp.expire);
if (ret) {
kdc_log(context, config, 0,
"PK-INIT failed to verify ocsp data %d", ret);
krb5_data_free(&ocsp.data);
ocsp.expire = 0;
} else if (ocsp.expire > 180)
ocsp.expire -= 180; /* refetch the ocsp before it expire */
out_ocsp:
ocsp.next_update = kdc_time + 3600;
ret = 0;
}
if (ocsp.expire != 0 && ocsp.expire > kdc_time) {
ret = krb5_padata_add(context, md,
KRB5_PADATA_PA_PK_OCSP_RESPONSE,
ocsp.data.data, ocsp.data.length);
if (ret) {
krb5_set_error_string(context,
"Failed adding OCSP response %d", ret);
goto out;
}
}
}
out:
if (kdc_cert)
hx509_cert_free(kdc_cert);
if (ret == 0)
*reply_key = &client_params->reply_key;
return ret;