From c29e49eb3beddab5fba37d37713486319c12df8c Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Thu, 11 Jul 2019 18:02:02 +0200 Subject: main/heimdal: security fix for CVE-2019-12098 fixes #10555 --- main/heimdal/APKBUILD | 8 +- main/heimdal/CVE-2019-12098.patch | 171 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 main/heimdal/CVE-2019-12098.patch (limited to 'main') diff --git a/main/heimdal/APKBUILD b/main/heimdal/APKBUILD index a15c4d73f4..8cbcfb168c 100644 --- a/main/heimdal/APKBUILD +++ b/main/heimdal/APKBUILD @@ -3,7 +3,7 @@ pkgname=heimdal pkgver=7.4.0 _ver=${pkgver/_rc/rc} -pkgrel=3 +pkgrel=4 pkgdesc="An implementation of Kerberos 5" arch="all" url="http://www.h5l.org/" @@ -24,10 +24,13 @@ source="https://github.com/heimdal/heimdal/releases/download/heimdal-$pkgver/hei heimdal_missing-include.patch CVE-2017-17439.patch CVE-2018-16860.patch + CVE-2019-12098.patch " builddir="$srcdir/$pkgname-$_ver" # secfixes: +# 7.4.0-r4: +# - CVE-2019-12098 # 7.4.0-r3: # - CVE-2018-16860 # 7.4.0-r2: @@ -134,4 +137,5 @@ abee8390632fa775e74900d09e5c72b02fe4f9616b43cc8d0a76175486ed6d4707fb3ce4d06ceb09 2a6b20588a86a9ea3c35209b96ef2da0b39bc3112aec1505e69a60efc9ffb9ddc1d0dbdfaf864142e9d2f81da3d2653de56d6ffa01871c20fde17e4642625c56 005_all_heimdal-suid_fix.patch e89efdc942c512363aac1d9797c6bf622324e9200e282bc5ed680300b9e1b39a4ea20f059cdac8f22f972eb0af0e625fd41f267ebcafcfec0aaa81192aff79c1 heimdal_missing-include.patch 66f92a3f0c68c7ff1f842b11ab456c94dd9fb2951b2dbb31fc4b1364d591687facd88aafadb0971a8156424470a65440111077ca02c064bdadd7490f671774b1 CVE-2017-17439.patch -36738795eb3478b55790bf1927f85a421b13b6b47dcc273daeb6630c39a4e1c1258148fa0e9f004ae59a9ac89caf54cb25efedb417e852e42a2c32d02e43fd56 CVE-2018-16860.patch" +36738795eb3478b55790bf1927f85a421b13b6b47dcc273daeb6630c39a4e1c1258148fa0e9f004ae59a9ac89caf54cb25efedb417e852e42a2c32d02e43fd56 CVE-2018-16860.patch +4cb6a268e65f11d606d72c054ffcc4bf5e4d96c15d08db0e77b9b97447a6b96d6947427d7041742221d98e86b8fa59cdb939beb541446c1136125a9528e9bc3d CVE-2019-12098.patch" diff --git a/main/heimdal/CVE-2019-12098.patch b/main/heimdal/CVE-2019-12098.patch new file mode 100644 index 0000000000..af01421861 --- /dev/null +++ b/main/heimdal/CVE-2019-12098.patch @@ -0,0 +1,171 @@ +From 2f7f3d9960aa6ea21358bdf3687cee5149aa35cf Mon Sep 17 00:00:00 2001 +From: Luke Howard +Date: Tue, 7 May 2019 13:15:15 +1000 +Subject: [PATCH] CVE-2019-12098: krb5: always confirm PA-PKINIT-KX for anon + PKINIT + +RFC8062 Section 7 requires verification of the PA-PKINIT-KX key excahnge +when anonymous PKINIT is used. Failure to do so can permit an active +attacker to become a man-in-the-middle. + +Introduced by a1ef548600c5bb51cf52a9a9ea12676506ede19f. First tagged +release Heimdal 1.4.0. + +CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N (4.8) + +Change-Id: I6cc1c0c24985936468af08693839ac6c3edda133 +Signed-off-by: Jeffrey Altman +Approved-by: Jeffrey Altman +(cherry picked from commit 38c797e1ae9b9c8f99ae4aa2e73957679031fd2b) +--- + lib/krb5/init_creds_pw.c | 20 +++++++++ + lib/krb5/krb5_locl.h | 1 + + lib/krb5/pkinit.c | 92 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 113 insertions(+) + +diff --git a/lib/krb5/init_creds_pw.c b/lib/krb5/init_creds_pw.c +index 1eece1760d..9ec07d0609 100644 +--- a/lib/krb5/init_creds_pw.c ++++ b/lib/krb5/init_creds_pw.c +@@ -2267,6 +2267,26 @@ krb5_init_creds_step(krb5_context context, + &ctx->req_buffer, + NULL, + NULL); ++ if (ret == 0 && ctx->pk_init_ctx) { ++ PA_DATA *pa_pkinit_kx; ++ int idx = 0; ++ ++ pa_pkinit_kx = ++ krb5_find_padata(rep.kdc_rep.padata->val, ++ rep.kdc_rep.padata->len, ++ KRB5_PADATA_PKINIT_KX, ++ &idx); ++ ++ ret = _krb5_pk_kx_confirm(context, ctx->pk_init_ctx, ++ ctx->fast_state.reply_key, ++ &ctx->cred.session, ++ pa_pkinit_kx); ++ if (ret) ++ krb5_set_error_message(context, ret, ++ N_("Failed to confirm PA-PKINIT-KX", "")); ++ else if (pa_pkinit_kx != NULL) ++ ctx->ic_flags |= KRB5_INIT_CREDS_PKINIT_KX_VALID; ++ } + if (ret == 0) + ret = copy_EncKDCRepPart(&rep.enc_part, &ctx->enc_part); + +diff --git a/lib/krb5/krb5_locl.h b/lib/krb5/krb5_locl.h +index 9d77b9f8a3..f61b66e999 100644 +--- a/lib/krb5/krb5_locl.h ++++ b/lib/krb5/krb5_locl.h +@@ -208,6 +208,7 @@ struct _krb5_get_init_creds_opt_private { + #define KRB5_INIT_CREDS_CANONICALIZE 1 + #define KRB5_INIT_CREDS_NO_C_CANON_CHECK 2 + #define KRB5_INIT_CREDS_NO_C_NO_EKU_CHECK 4 ++#define KRB5_INIT_CREDS_PKINIT_KX_VALID 32 + struct { + krb5_gic_process_last_req func; + void *ctx; +diff --git a/lib/krb5/pkinit.c b/lib/krb5/pkinit.c +index b16ee69d3c..e178242ea3 100644 +--- a/lib/krb5/pkinit.c ++++ b/lib/krb5/pkinit.c +@@ -1220,6 +1220,98 @@ pk_rd_pa_reply_enckey(krb5_context context, + return ret; + } + ++/* ++ * RFC 8062 section 7: ++ * ++ * The client then decrypts the KDC contribution key and verifies that ++ * the ticket session key in the returned ticket is the combined key of ++ * the KDC contribution key and the reply key. ++ */ ++KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL ++_krb5_pk_kx_confirm(krb5_context context, ++ krb5_pk_init_ctx ctx, ++ krb5_keyblock *reply_key, ++ krb5_keyblock *session_key, ++ PA_DATA *pa_pkinit_kx) ++{ ++ krb5_error_code ret; ++ EncryptedData ed; ++ krb5_keyblock ck, sk_verify; ++ krb5_crypto ck_crypto = NULL; ++ krb5_crypto rk_crypto = NULL; ++ size_t len; ++ krb5_data data; ++ krb5_data p1 = { sizeof("PKINIT") - 1, "PKINIT" }; ++ krb5_data p2 = { sizeof("KEYEXCHANGE") - 1, "KEYEXCHANGE" }; ++ ++ heim_assert(ctx != NULL, "PKINIT context is non-NULL"); ++ heim_assert(reply_key != NULL, "reply key is non-NULL"); ++ heim_assert(session_key != NULL, "session key is non-NULL"); ++ ++ /* PA-PKINIT-KX is optional unless anonymous */ ++ if (pa_pkinit_kx == NULL) ++ return ctx->anonymous ? KRB5_KDCREP_MODIFIED : 0; ++ ++ memset(&ed, 0, sizeof(ed)); ++ krb5_keyblock_zero(&ck); ++ krb5_keyblock_zero(&sk_verify); ++ krb5_data_zero(&data); ++ ++ ret = decode_EncryptedData(pa_pkinit_kx->padata_value.data, ++ pa_pkinit_kx->padata_value.length, ++ &ed, &len); ++ if (ret) ++ goto out; ++ ++ if (len != pa_pkinit_kx->padata_value.length) { ++ ret = KRB5_KDCREP_MODIFIED; ++ goto out; ++ } ++ ++ ret = krb5_crypto_init(context, reply_key, 0, &rk_crypto); ++ if (ret) ++ goto out; ++ ++ ret = krb5_decrypt_EncryptedData(context, rk_crypto, ++ KRB5_KU_PA_PKINIT_KX, ++ &ed, &data); ++ if (ret) ++ goto out; ++ ++ ret = decode_EncryptionKey(data.data, data.length, ++ &ck, &len); ++ if (ret) ++ goto out; ++ ++ ret = krb5_crypto_init(context, &ck, 0, &ck_crypto); ++ if (ret) ++ goto out; ++ ++ ret = krb5_crypto_fx_cf2(context, ck_crypto, rk_crypto, ++ &p1, &p2, session_key->keytype, ++ &sk_verify); ++ if (ret) ++ goto out; ++ ++ if (sk_verify.keytype != session_key->keytype || ++ krb5_data_ct_cmp(&sk_verify.keyvalue, &session_key->keyvalue) != 0) { ++ ret = KRB5_KDCREP_MODIFIED; ++ goto out; ++ } ++ ++out: ++ free_EncryptedData(&ed); ++ krb5_free_keyblock_contents(context, &ck); ++ krb5_free_keyblock_contents(context, &sk_verify); ++ if (ck_crypto) ++ krb5_crypto_destroy(context, ck_crypto); ++ if (rk_crypto) ++ krb5_crypto_destroy(context, rk_crypto); ++ krb5_data_free(&data); ++ ++ return ret; ++} ++ + static krb5_error_code + pk_rd_pa_reply_dh(krb5_context context, + const heim_octet_string *indata, -- cgit v1.2.3