summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/krb5/pkinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/krb5/pkinit.c')
-rwxr-xr-xsource4/heimdal/lib/krb5/pkinit.c203
1 files changed, 97 insertions, 106 deletions
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);