From ec0035c9b8e0690f3bc21f3de089c39eae660916 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 Jul 2007 08:00:08 +0000 Subject: r23678: Update to current lorikeet-heimdal (-r 767), which should fix the panics on hosts without /dev/random. Andrew Bartlett (This used to be commit 14a4ddb131993fec72316f7e8e371638749e6f1f) --- source4/heimdal/lib/krb5/pkinit.c | 203 ++++++++++++++++++-------------------- 1 file changed, 97 insertions(+), 106 deletions(-) (limited to 'source4/heimdal/lib/krb5/pkinit.c') diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index dd82842084..105cab554d 100755 --- a/source4/heimdal/lib/krb5/pkinit.c +++ b/source4/heimdal/lib/krb5/pkinit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 - 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2003 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: pkinit.c 21004 2007-06-08 01:53:10Z lha $"); +RCSID("$Id: pkinit.c 21321 2007-06-26 05:21:56Z lha $"); struct krb5_dh_moduli { char *name; @@ -554,18 +554,13 @@ pk_mk_padata(krb5_context context, if (ret) goto out; - ret = _krb5_pk_mk_ContentInfo(context, &sd_buf, oid_id_pkcs7_signedData(), - &content_info); + ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), &sd_buf, &buf); krb5_data_free(&sd_buf); - if (ret) - goto out; - - ASN1_MALLOC_ENCODE(ContentInfo, buf.data, buf.length, - &content_info, &size, ret); - if (ret) + if (ret) { + krb5_set_error_string(context, + "ContentInfo wrapping of signedData failed"); goto out; - if (buf.length != size) - krb5_abortx(context, "Internal ASN1 encoder error"); + } if (ctx->type == COMPAT_WIN2K) { PA_PK_AS_REQ_Win2k winreq; @@ -794,6 +789,7 @@ get_reply_key_win(krb5_context context, if (ret) { krb5_set_error_string(context, "PKINIT failed copying reply key"); free(*key); + *key = NULL; } return ret; @@ -856,6 +852,7 @@ get_reply_key(krb5_context context, if (ret) { krb5_set_error_string(context, "PKINIT failed copying reply key"); free(*key); + *key = NULL; } return ret; @@ -929,6 +926,7 @@ pk_verify_host(krb5_context context, if (hi) { ret = hx509_verify_hostname(ctx->id->hx509ctx, host->cert, ctx->require_hostname_match, + HX509_HN_HOSTNAME, hi->hostname, hi->ai->ai_addr, hi->ai->ai_addrlen); @@ -942,7 +940,8 @@ pk_verify_host(krb5_context context, static krb5_error_code pk_rd_pa_reply_enckey(krb5_context context, int type, - const ContentInfo *rep, + const heim_octet_string *indata, + const heim_oid *dataType, const char *realm, krb5_pk_init_ctx ctx, krb5_enctype etype, @@ -954,27 +953,19 @@ pk_rd_pa_reply_enckey(krb5_context context, { krb5_error_code ret; struct krb5_pk_cert *host = NULL; - size_t size; - int length; - void *p; krb5_data content; heim_oid contentType = { 0, NULL }; - if (der_heim_oid_cmp(oid_id_pkcs7_envelopedData(), &rep->contentType)) { + if (der_heim_oid_cmp(oid_id_pkcs7_envelopedData(), dataType)) { krb5_set_error_string(context, "PKINIT: Invalid content type"); return EINVAL; } - if (rep->content == NULL) { - krb5_set_error_string(context, "PKINIT: No content in reply"); - return EINVAL; - } - ret = hx509_cms_unenvelope(ctx->id->hx509ctx, ctx->id->certs, HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT, - rep->content->data, - rep->content->length, + indata->data, + indata->length, NULL, &contentType, &content); @@ -983,41 +974,52 @@ pk_rd_pa_reply_enckey(krb5_context context, "Failed to unenvelope CMS data in PK-INIT reply"); return ret; } + der_free_oid(&contentType); + +#if 0 /* windows LH with interesting CMS packets, leaks memory */ + { + size_t ph = 1 + der_length_len (length); + unsigned char *ptr = malloc(length + ph); + size_t l; - p = content.data; - length = content.length; + memcpy(ptr + ph, p, length); + + ret = der_put_length_and_tag (ptr + ph - 1, ph, length, + ASN1_C_UNIV, CONS, UT_Sequence, &l); + if (ret) + return ret; + ptr += ph - l; + length += l; + p = ptr; + } +#endif /* win2k uses ContentInfo */ if (type == COMPAT_WIN2K) { - ContentInfo ci; + heim_oid type; + heim_octet_string out; - ret = decode_ContentInfo(p, length, &ci, &size); - if (ret) { - krb5_set_error_string(context, - "PKINIT: failed decoding ContentInfo: %d", - ret); - goto out; - } - - if (der_heim_oid_cmp(&ci.contentType, oid_id_pkcs7_signedData())) { + ret = hx509_cms_unwrap_ContentInfo(&content, &type, &out, NULL); + if (der_heim_oid_cmp(&type, oid_id_pkcs7_signedData())) { ret = EINVAL; /* XXX */ krb5_set_error_string(context, "PKINIT: Invalid content type"); + der_free_oid(&type); + der_free_octet_string(&out); goto out; } - if (ci.content == NULL) { - ret = EINVAL; /* XXX */ - krb5_set_error_string(context, "PKINIT: Invalid content type"); + der_free_oid(&type); + krb5_data_free(&content); + ret = krb5_data_copy(&content, out.data, out.length); + der_free_octet_string(&out); + if (ret) { + krb5_set_error_string(context, "PKINIT: out of memory"); goto out; } - krb5_data_free(&content); - content = *ci.content; - p = ci.content->data; - length = ci.content->length; } ret = _krb5_pk_verify_sign(context, - p, - length, + content.data, + content.length, ctx->id, &contentType, &content, @@ -1073,7 +1075,8 @@ pk_rd_pa_reply_enckey(krb5_context context, static krb5_error_code pk_rd_pa_reply_dh(krb5_context context, - const ContentInfo *rep, + const heim_octet_string *indata, + const heim_oid *dataType, const char *realm, krb5_pk_init_ctx ctx, krb5_enctype etype, @@ -1097,19 +1100,14 @@ pk_rd_pa_reply_dh(krb5_context context, krb5_data_zero(&content); memset(&kdc_dh_info, 0, sizeof(kdc_dh_info)); - if (der_heim_oid_cmp(oid_id_pkcs7_signedData(), &rep->contentType)) { + if (der_heim_oid_cmp(oid_id_pkcs7_signedData(), dataType)) { krb5_set_error_string(context, "PKINIT: Invalid content type"); return EINVAL; } - if (rep->content == NULL) { - krb5_set_error_string(context, "PKINIT: No content in reply"); - return EINVAL; - } - ret = _krb5_pk_verify_sign(context, - rep->content->data, - rep->content->length, + indata->data, + indata->length, ctx->id, &contentType, &content, @@ -1261,20 +1259,19 @@ _krb5_pk_rd_pa_reply(krb5_context context, { krb5_pk_init_ctx ctx = c; krb5_error_code ret; - ContentInfo ci; size_t size; /* Check for IETF PK-INIT first */ if (ctx->type == COMPAT_IETF) { PA_PK_AS_REP rep; + heim_octet_string os, data; + heim_oid oid; if (pa->padata_type != KRB5_PADATA_PK_AS_REP) { krb5_set_error_string(context, "PKINIT: wrong padata recv"); return EINVAL; } - memset(&rep, 0, sizeof(rep)); - ret = decode_PA_PK_AS_REP(pa->padata_value.data, pa->padata_value.length, &rep, @@ -1286,49 +1283,42 @@ _krb5_pk_rd_pa_reply(krb5_context context, switch (rep.element) { case choice_PA_PK_AS_REP_dhInfo: - ret = decode_ContentInfo(rep.u.dhInfo.dhSignedData.data, - rep.u.dhInfo.dhSignedData.length, - &ci, - &size); - if (ret) { - krb5_set_error_string(context, - "PKINIT: decoding failed DH " - "ContentInfo: %d", ret); - - free_PA_PK_AS_REP(&rep); - break; - } - ret = pk_rd_pa_reply_dh(context, &ci, realm, ctx, etype, hi, - ctx->clientDHNonce, - rep.u.dhInfo.serverDHNonce, - nonce, pa, key); - free_ContentInfo(&ci); - free_PA_PK_AS_REP(&rep); - + os = rep.u.dhInfo.dhSignedData; break; case choice_PA_PK_AS_REP_encKeyPack: - ret = decode_ContentInfo(rep.u.encKeyPack.data, - rep.u.encKeyPack.length, - &ci, - &size); - free_PA_PK_AS_REP(&rep); - if (ret) { - krb5_set_error_string(context, - "PKINIT: -25 decoding failed " - "ContentInfo: %d", ret); - break; - } - ret = pk_rd_pa_reply_enckey(context, COMPAT_IETF, &ci, realm, ctx, - etype, hi, nonce, req_buffer, pa, key); - free_ContentInfo(&ci); - return ret; + os = rep.u.encKeyPack; + break; default: free_PA_PK_AS_REP(&rep); krb5_set_error_string(context, "PKINIT: -27 reply " "invalid content type"); - ret = EINVAL; + return EINVAL; + } + + ret = hx509_cms_unwrap_ContentInfo(&os, &oid, &data, NULL); + if (ret) { + free_PA_PK_AS_REP(&rep); + krb5_set_error_string(context, "PKINIT: failed to unwrap CI"); + return ret; + } + + switch (rep.element) { + case choice_PA_PK_AS_REP_dhInfo: + ret = pk_rd_pa_reply_dh(context, &data, &oid, realm, ctx, etype, hi, + ctx->clientDHNonce, + rep.u.dhInfo.serverDHNonce, + nonce, pa, key); break; + case choice_PA_PK_AS_REP_encKeyPack: + ret = pk_rd_pa_reply_enckey(context, COMPAT_IETF, &data, &oid, realm, + ctx, etype, hi, nonce, req_buffer, pa, key); + break; + default: + krb5_abortx(context, "pk-init as-rep case not possible to happen"); } + der_free_octet_string(&data); + der_free_oid(&oid); + free_PA_PK_AS_REP(&rep); } else if (ctx->type == COMPAT_WIN2K) { PA_PK_AS_REP_Win2k w2krep; @@ -1357,23 +1347,25 @@ _krb5_pk_rd_pa_reply(krb5_context context, krb5_clear_error_string(context); switch (w2krep.element) { - case choice_PA_PK_AS_REP_Win2k_encKeyPack: - ret = decode_ContentInfo(w2krep.u.encKeyPack.data, - w2krep.u.encKeyPack.length, - &ci, - &size); + case choice_PA_PK_AS_REP_Win2k_encKeyPack: { + heim_octet_string data; + heim_oid oid; + + ret = hx509_cms_unwrap_ContentInfo(&w2krep.u.encKeyPack, + &oid, &data, NULL); free_PA_PK_AS_REP_Win2k(&w2krep); if (ret) { - krb5_set_error_string(context, - "PKINIT: decoding failed " - "ContentInfo: %d", - ret); + krb5_set_error_string(context, "PKINIT: failed to unwrap CI"); return ret; } - ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &ci, realm, ctx, - etype, hi, nonce, req_buffer, pa, key); - free_ContentInfo(&ci); + + ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &data, &oid, realm, + ctx, etype, hi, nonce, req_buffer, pa, key); + der_free_octet_string(&data); + der_free_oid(&oid); + break; + } default: free_PA_PK_AS_REP_Win2k(&w2krep); krb5_set_error_string(context, "PKINIT: win2k reply invalid " @@ -1473,8 +1465,7 @@ _krb5_pk_load_id(krb5_context context, id = calloc(1, sizeof(*id)); if (id == NULL) { krb5_set_error_string(context, "malloc: out of memory"); - ret = ENOMEM; - goto out; + return ENOMEM; } ret = hx509_context_init(&id->hx509ctx); -- cgit