Implement verification of asChecksum, now client side code is using
-27 of the pk-init draft. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@15919 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -58,7 +58,7 @@ RCSID("$Id$");
|
|||||||
enum {
|
enum {
|
||||||
COMPAT_WIN2K = 1,
|
COMPAT_WIN2K = 1,
|
||||||
COMPAT_19 = 2,
|
COMPAT_19 = 2,
|
||||||
COMPAT_25 = 3
|
COMPAT_27 = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -716,7 +716,7 @@ pk_mk_padata(krb5_context context,
|
|||||||
krb5_abortx(context, "internal ASN1 encoder error");
|
krb5_abortx(context, "internal ASN1 encoder error");
|
||||||
|
|
||||||
oid = oid_id_pkauthdata();
|
oid = oid_id_pkauthdata();
|
||||||
} else if (compat == COMPAT_25) {
|
} else if (compat == COMPAT_27) {
|
||||||
AuthPack ap;
|
AuthPack ap;
|
||||||
|
|
||||||
memset(&ap, 0, sizeof(ap));
|
memset(&ap, 0, sizeof(ap));
|
||||||
@@ -802,7 +802,7 @@ pk_mk_padata(krb5_context context,
|
|||||||
|
|
||||||
free_PA_PK_AS_REQ_19(&req_19);
|
free_PA_PK_AS_REQ_19(&req_19);
|
||||||
|
|
||||||
} else if (compat == COMPAT_25) {
|
} else if (compat == COMPAT_27) {
|
||||||
|
|
||||||
pa_type = KRB5_PADATA_PK_AS_REQ;
|
pa_type = KRB5_PADATA_PK_AS_REQ;
|
||||||
|
|
||||||
@@ -871,7 +871,7 @@ _krb5_pk_mk_padata(krb5_context context,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = pk_mk_padata(context, COMPAT_25, ctx, req_body, nonce, md);
|
ret = pk_mk_padata(context, COMPAT_27, ctx, req_body, nonce, md);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1280,7 +1280,7 @@ _krb5_pk_verify_sign(krb5_context context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
get_reply_key(krb5_context context,
|
get_reply_key_19(krb5_context context,
|
||||||
const krb5_data *content,
|
const krb5_data *content,
|
||||||
unsigned nonce,
|
unsigned nonce,
|
||||||
krb5_keyblock **key)
|
krb5_keyblock **key)
|
||||||
@@ -1323,6 +1323,69 @@ get_reply_key(krb5_context context,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
get_reply_key(krb5_context context,
|
||||||
|
const krb5_data *content,
|
||||||
|
const krb5_data *req_buffer,
|
||||||
|
krb5_keyblock **key)
|
||||||
|
{
|
||||||
|
ReplyKeyPack key_pack;
|
||||||
|
krb5_error_code ret;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
ret = decode_ReplyKeyPack(content->data,
|
||||||
|
content->length,
|
||||||
|
&key_pack,
|
||||||
|
&size);
|
||||||
|
if (ret) {
|
||||||
|
krb5_set_error_string(context, "PKINIT decoding reply key failed");
|
||||||
|
free_ReplyKeyPack(&key_pack);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
krb5_crypto crypto;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX Verify kp.replyKey is a allowed enctype in the
|
||||||
|
* configuration file
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = krb5_crypto_init(context, &key_pack.replyKey, 0, &crypto);
|
||||||
|
if (ret) {
|
||||||
|
free_ReplyKeyPack(&key_pack);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = krb5_verify_checksum(context, crypto, 6,
|
||||||
|
req_buffer->data, req_buffer->length,
|
||||||
|
&key_pack.asChecksum);
|
||||||
|
krb5_crypto_destroy(context, crypto);
|
||||||
|
if (ret) {
|
||||||
|
free_ReplyKeyPack(&key_pack);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*key = malloc (sizeof (**key));
|
||||||
|
if (*key == NULL) {
|
||||||
|
krb5_set_error_string(context, "PKINIT failed allocating reply key");
|
||||||
|
free_ReplyKeyPack(&key_pack);
|
||||||
|
krb5_set_error_string(context, "malloc: out of memory");
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = copy_EncryptionKey(&key_pack.replyKey, *key);
|
||||||
|
free_ReplyKeyPack(&key_pack);
|
||||||
|
if (ret) {
|
||||||
|
krb5_set_error_string(context, "PKINIT failed copying reply key");
|
||||||
|
free(*key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
pk_verify_host(krb5_context context, struct krb5_pk_cert *host)
|
pk_verify_host(krb5_context context, struct krb5_pk_cert *host)
|
||||||
{
|
{
|
||||||
@@ -1332,11 +1395,12 @@ pk_verify_host(krb5_context context, struct krb5_pk_cert *host)
|
|||||||
|
|
||||||
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 win2k_compat,
|
int type,
|
||||||
ContentInfo *rep,
|
ContentInfo *rep,
|
||||||
krb5_pk_init_ctx ctx,
|
krb5_pk_init_ctx ctx,
|
||||||
krb5_enctype etype,
|
krb5_enctype etype,
|
||||||
unsigned nonce,
|
unsigned nonce,
|
||||||
|
const krb5_data *req_buffer,
|
||||||
PA_DATA *pa,
|
PA_DATA *pa,
|
||||||
krb5_keyblock **key)
|
krb5_keyblock **key)
|
||||||
{
|
{
|
||||||
@@ -1418,7 +1482,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
|||||||
|
|
||||||
|
|
||||||
/* verify content type */
|
/* verify content type */
|
||||||
if (win2k_compat) {
|
if (type == COMPAT_WIN2K) {
|
||||||
if (heim_oid_cmp(&ed.encryptedContentInfo.contentType, oid_id_pkcs7_data())) {
|
if (heim_oid_cmp(&ed.encryptedContentInfo.contentType, oid_id_pkcs7_data())) {
|
||||||
ret = KRB5KRB_AP_ERR_MSG_TYPE;
|
ret = KRB5KRB_AP_ERR_MSG_TYPE;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1481,7 +1545,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
|||||||
length = plain.length;
|
length = plain.length;
|
||||||
|
|
||||||
/* win2k uses ContentInfo */
|
/* win2k uses ContentInfo */
|
||||||
if (win2k_compat) {
|
if (type == COMPAT_WIN2K) {
|
||||||
ContentInfo ci;
|
ContentInfo ci;
|
||||||
|
|
||||||
ret = decode_ContentInfo(p, length, &ci, &size);
|
ret = decode_ContentInfo(p, length, &ci, &size);
|
||||||
@@ -1518,7 +1582,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (win2k_compat) {
|
if (type == COMPAT_WIN2K) {
|
||||||
if (heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) {
|
if (heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) {
|
||||||
krb5_set_error_string(context, "PKINIT: reply key, wrong oid");
|
krb5_set_error_string(context, "PKINIT: reply key, wrong oid");
|
||||||
ret = KRB5KRB_AP_ERR_MSG_TYPE;
|
ret = KRB5KRB_AP_ERR_MSG_TYPE;
|
||||||
@@ -1532,7 +1596,15 @@ pk_rd_pa_reply_enckey(krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = get_reply_key(context, &content, nonce, key);
|
switch(type) {
|
||||||
|
case COMPAT_WIN2K:
|
||||||
|
case COMPAT_19:
|
||||||
|
ret = get_reply_key_19(context, &content, nonce, key);
|
||||||
|
break;
|
||||||
|
case COMPAT_27:
|
||||||
|
ret = get_reply_key(context, &content, req_buffer, key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -1728,6 +1800,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
|
|||||||
void *c,
|
void *c,
|
||||||
krb5_enctype etype,
|
krb5_enctype etype,
|
||||||
unsigned nonce,
|
unsigned nonce,
|
||||||
|
const krb5_data *req_buffer,
|
||||||
PA_DATA *pa,
|
PA_DATA *pa,
|
||||||
krb5_keyblock **key)
|
krb5_keyblock **key)
|
||||||
{
|
{
|
||||||
@@ -1736,7 +1809,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
|
|||||||
ContentInfo ci;
|
ContentInfo ci;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
/* Check for PK-INIT -25 */
|
/* Check for PK-INIT -27 */
|
||||||
if (pa->padata_type == KRB5_PADATA_PK_AS_REP) {
|
if (pa->padata_type == KRB5_PADATA_PK_AS_REP) {
|
||||||
PA_PK_AS_REP rep;
|
PA_PK_AS_REP rep;
|
||||||
|
|
||||||
@@ -1781,8 +1854,8 @@ _krb5_pk_rd_pa_reply(krb5_context context,
|
|||||||
"ContentInfo: %d", ret);
|
"ContentInfo: %d", ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = pk_rd_pa_reply_enckey(context, 0, &ci, ctx,
|
ret = pk_rd_pa_reply_enckey(context, COMPAT_27, &ci, ctx,
|
||||||
etype, nonce, pa, key);
|
etype, nonce, req_buffer, pa, key);
|
||||||
free_ContentInfo(&ci);
|
free_ContentInfo(&ci);
|
||||||
return ret;
|
return ret;
|
||||||
default:
|
default:
|
||||||
@@ -1811,9 +1884,9 @@ _krb5_pk_rd_pa_reply(krb5_context context,
|
|||||||
nonce, pa, key);
|
nonce, pa, key);
|
||||||
break;
|
break;
|
||||||
case choice_PA_PK_AS_REP_19_encKeyPack:
|
case choice_PA_PK_AS_REP_19_encKeyPack:
|
||||||
ret = pk_rd_pa_reply_enckey(context, 0,
|
ret = pk_rd_pa_reply_enckey(context, COMPAT_19,
|
||||||
&rep19.u.encKeyPack, ctx,
|
&rep19.u.encKeyPack, ctx,
|
||||||
etype, nonce, pa, key);
|
etype, nonce, NULL, pa, key);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
krb5_set_error_string(context, "PKINIT: -19 reply invalid "
|
krb5_set_error_string(context, "PKINIT: -19 reply invalid "
|
||||||
@@ -1857,8 +1930,8 @@ _krb5_pk_rd_pa_reply(krb5_context context,
|
|||||||
ret);
|
ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = pk_rd_pa_reply_enckey(context, 1, &ci, ctx,
|
ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &ci, ctx,
|
||||||
etype, nonce, pa, key);
|
etype, nonce, NULL, pa, key);
|
||||||
free_ContentInfo(&ci);
|
free_ContentInfo(&ci);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Reference in New Issue
Block a user