Use hx509_cms_unwrap_ContentInfo.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@21321 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -554,18 +554,13 @@ pk_mk_padata(krb5_context context,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = _krb5_pk_mk_ContentInfo(context, &sd_buf, oid_id_pkcs7_signedData(),
|
ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), &sd_buf, &buf);
|
||||||
&content_info);
|
|
||||||
krb5_data_free(&sd_buf);
|
krb5_data_free(&sd_buf);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_set_error_string(context,
|
||||||
|
"ContentInfo wrapping of signedData failed");
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
ASN1_MALLOC_ENCODE(ContentInfo, buf.data, buf.length,
|
|
||||||
&content_info, &size, ret);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
if (buf.length != size)
|
|
||||||
krb5_abortx(context, "Internal ASN1 encoder error");
|
|
||||||
|
|
||||||
if (ctx->type == COMPAT_WIN2K) {
|
if (ctx->type == COMPAT_WIN2K) {
|
||||||
PA_PK_AS_REQ_Win2k winreq;
|
PA_PK_AS_REQ_Win2k winreq;
|
||||||
@@ -945,7 +940,8 @@ pk_verify_host(krb5_context context,
|
|||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
pk_rd_pa_reply_enckey(krb5_context context,
|
pk_rd_pa_reply_enckey(krb5_context context,
|
||||||
int type,
|
int type,
|
||||||
const ContentInfo *rep,
|
const heim_octet_string *indata,
|
||||||
|
const heim_oid *dataType,
|
||||||
const char *realm,
|
const char *realm,
|
||||||
krb5_pk_init_ctx ctx,
|
krb5_pk_init_ctx ctx,
|
||||||
krb5_enctype etype,
|
krb5_enctype etype,
|
||||||
@@ -957,25 +953,19 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
|||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
struct krb5_pk_cert *host = NULL;
|
struct krb5_pk_cert *host = NULL;
|
||||||
size_t size;
|
|
||||||
krb5_data content;
|
krb5_data content;
|
||||||
heim_oid contentType = { 0, NULL };
|
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");
|
krb5_set_error_string(context, "PKINIT: Invalid content type");
|
||||||
return EINVAL;
|
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,
|
ret = hx509_cms_unenvelope(ctx->id->hx509ctx,
|
||||||
ctx->id->certs,
|
ctx->id->certs,
|
||||||
HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT,
|
HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT,
|
||||||
rep->content->data,
|
indata->data,
|
||||||
rep->content->length,
|
indata->length,
|
||||||
NULL,
|
NULL,
|
||||||
&contentType,
|
&contentType,
|
||||||
&content);
|
&content);
|
||||||
@@ -1006,29 +996,21 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
|||||||
|
|
||||||
/* win2k uses ContentInfo */
|
/* win2k uses ContentInfo */
|
||||||
if (type == COMPAT_WIN2K) {
|
if (type == COMPAT_WIN2K) {
|
||||||
ContentInfo ci;
|
heim_oid type;
|
||||||
|
heim_octet_string out;
|
||||||
|
|
||||||
ret = decode_ContentInfo(content.data, content.length, &ci, &size);
|
ret = hx509_cms_unwrap_ContentInfo(&content, &type, &out, NULL);
|
||||||
if (ret) {
|
if (der_heim_oid_cmp(&type, oid_id_pkcs7_signedData())) {
|
||||||
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 = EINVAL; /* XXX */
|
|
||||||
krb5_set_error_string(context, "PKINIT: Invalid content type");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (ci.content == NULL) {
|
|
||||||
ret = EINVAL; /* XXX */
|
ret = EINVAL; /* XXX */
|
||||||
krb5_set_error_string(context, "PKINIT: Invalid content type");
|
krb5_set_error_string(context, "PKINIT: Invalid content type");
|
||||||
|
der_free_oid(&type);
|
||||||
|
der_free_octet_string(&out);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
der_free_oid(&type);
|
||||||
krb5_data_free(&content);
|
krb5_data_free(&content);
|
||||||
ret = krb5_data_copy(&content, ci.content->data, ci.content->length);
|
ret = krb5_data_copy(&content, out.data, out.length);
|
||||||
free_ContentInfo(&ci);
|
der_free_octet_string(&out);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
krb5_set_error_string(context, "PKINIT: out of memory");
|
krb5_set_error_string(context, "PKINIT: out of memory");
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1093,7 +1075,8 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
|||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
pk_rd_pa_reply_dh(krb5_context context,
|
pk_rd_pa_reply_dh(krb5_context context,
|
||||||
const ContentInfo *rep,
|
const heim_octet_string *indata,
|
||||||
|
const heim_oid *dataType,
|
||||||
const char *realm,
|
const char *realm,
|
||||||
krb5_pk_init_ctx ctx,
|
krb5_pk_init_ctx ctx,
|
||||||
krb5_enctype etype,
|
krb5_enctype etype,
|
||||||
@@ -1117,19 +1100,14 @@ pk_rd_pa_reply_dh(krb5_context context,
|
|||||||
krb5_data_zero(&content);
|
krb5_data_zero(&content);
|
||||||
memset(&kdc_dh_info, 0, sizeof(kdc_dh_info));
|
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");
|
krb5_set_error_string(context, "PKINIT: Invalid content type");
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rep->content == NULL) {
|
|
||||||
krb5_set_error_string(context, "PKINIT: No content in reply");
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = _krb5_pk_verify_sign(context,
|
ret = _krb5_pk_verify_sign(context,
|
||||||
rep->content->data,
|
indata->data,
|
||||||
rep->content->length,
|
indata->length,
|
||||||
ctx->id,
|
ctx->id,
|
||||||
&contentType,
|
&contentType,
|
||||||
&content,
|
&content,
|
||||||
@@ -1281,20 +1259,19 @@ _krb5_pk_rd_pa_reply(krb5_context context,
|
|||||||
{
|
{
|
||||||
krb5_pk_init_ctx ctx = c;
|
krb5_pk_init_ctx ctx = c;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
ContentInfo ci;
|
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
/* Check for IETF PK-INIT first */
|
/* Check for IETF PK-INIT first */
|
||||||
if (ctx->type == COMPAT_IETF) {
|
if (ctx->type == COMPAT_IETF) {
|
||||||
PA_PK_AS_REP rep;
|
PA_PK_AS_REP rep;
|
||||||
|
heim_octet_string os, data;
|
||||||
|
heim_oid oid;
|
||||||
|
|
||||||
if (pa->padata_type != KRB5_PADATA_PK_AS_REP) {
|
if (pa->padata_type != KRB5_PADATA_PK_AS_REP) {
|
||||||
krb5_set_error_string(context, "PKINIT: wrong padata recv");
|
krb5_set_error_string(context, "PKINIT: wrong padata recv");
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&rep, 0, sizeof(rep));
|
|
||||||
|
|
||||||
ret = decode_PA_PK_AS_REP(pa->padata_value.data,
|
ret = decode_PA_PK_AS_REP(pa->padata_value.data,
|
||||||
pa->padata_value.length,
|
pa->padata_value.length,
|
||||||
&rep,
|
&rep,
|
||||||
@@ -1306,50 +1283,43 @@ _krb5_pk_rd_pa_reply(krb5_context context,
|
|||||||
|
|
||||||
switch (rep.element) {
|
switch (rep.element) {
|
||||||
case choice_PA_PK_AS_REP_dhInfo:
|
case choice_PA_PK_AS_REP_dhInfo:
|
||||||
ret = decode_ContentInfo(rep.u.dhInfo.dhSignedData.data,
|
os = rep.u.dhInfo.dhSignedData;
|
||||||
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);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case choice_PA_PK_AS_REP_encKeyPack:
|
case choice_PA_PK_AS_REP_encKeyPack:
|
||||||
ret = decode_ContentInfo(rep.u.encKeyPack.data,
|
os = rep.u.encKeyPack;
|
||||||
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;
|
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;
|
|
||||||
default:
|
default:
|
||||||
free_PA_PK_AS_REP(&rep);
|
free_PA_PK_AS_REP(&rep);
|
||||||
krb5_set_error_string(context, "PKINIT: -27 reply "
|
krb5_set_error_string(context, "PKINIT: -27 reply "
|
||||||
"invalid content type");
|
"invalid content type");
|
||||||
ret = EINVAL;
|
return EINVAL;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
} else if (ctx->type == COMPAT_WIN2K) {
|
||||||
PA_PK_AS_REP_Win2k w2krep;
|
PA_PK_AS_REP_Win2k w2krep;
|
||||||
|
|
||||||
@@ -1377,23 +1347,25 @@ _krb5_pk_rd_pa_reply(krb5_context context,
|
|||||||
krb5_clear_error_string(context);
|
krb5_clear_error_string(context);
|
||||||
|
|
||||||
switch (w2krep.element) {
|
switch (w2krep.element) {
|
||||||
case choice_PA_PK_AS_REP_Win2k_encKeyPack:
|
case choice_PA_PK_AS_REP_Win2k_encKeyPack: {
|
||||||
ret = decode_ContentInfo(w2krep.u.encKeyPack.data,
|
heim_octet_string data;
|
||||||
w2krep.u.encKeyPack.length,
|
heim_oid oid;
|
||||||
&ci,
|
|
||||||
&size);
|
ret = hx509_cms_unwrap_ContentInfo(&w2krep.u.encKeyPack,
|
||||||
|
&oid, &data, NULL);
|
||||||
free_PA_PK_AS_REP_Win2k(&w2krep);
|
free_PA_PK_AS_REP_Win2k(&w2krep);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
krb5_set_error_string(context,
|
krb5_set_error_string(context, "PKINIT: failed to unwrap CI");
|
||||||
"PKINIT: decoding failed "
|
|
||||||
"ContentInfo: %d",
|
|
||||||
ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &ci, realm, ctx,
|
|
||||||
etype, hi, nonce, req_buffer, pa, key);
|
ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &data, &oid, realm,
|
||||||
free_ContentInfo(&ci);
|
ctx, etype, hi, nonce, req_buffer, pa, key);
|
||||||
|
der_free_octet_string(&data);
|
||||||
|
der_free_oid(&oid);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
free_PA_PK_AS_REP_Win2k(&w2krep);
|
free_PA_PK_AS_REP_Win2k(&w2krep);
|
||||||
krb5_set_error_string(context, "PKINIT: win2k reply invalid "
|
krb5_set_error_string(context, "PKINIT: win2k reply invalid "
|
||||||
|
Reference in New Issue
Block a user