From 4e47b5d703c54215804d595980be028f47a87cbf Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 7 Dec 2016 11:18:59 +0100
Subject: [PATCH] CVE-2016-2126: auth/kerberos: only allow known checksum types
 in check_pac_checksum()

AES based checksums can only be checked with the corresponding AES based
keytype.

Otherwise we may trigger an undefined code path deep in the kerberos
libraries, which can leed to segmentation faults.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12446

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Backported-by: Andreas Schneider <asn@samba.org>
---
 source3/include/smb_krb5.h | 12 ++++++++++++
 source3/libads/authdata.c  | 22 ++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/source3/include/smb_krb5.h b/source3/include/smb_krb5.h
index 5a55d3040d5..2780622f512 100644
--- a/source3/include/smb_krb5.h
+++ b/source3/include/smb_krb5.h
@@ -61,6 +61,18 @@
 #define ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC_MD5
 #endif
 
+#if !defined(CKSUMTYPE_HMAC_MD5_ARCFOUR) && defined(CKSUMTYPE_HMAC_MD5)
+#define CKSUMTYPE_HMAC_MD5_ARCFOUR CKSUMTYPE_HMAC_MD5
+#endif
+
+#if !defined(CKSUMTYPE_HMAC_SHA1_96_AES256) && defined(CKSUMTYPE_HMAC_SHA1_96_AES_256)
+#define CKSUMTYPE_HMAC_SHA1_96_AES256 CKSUMTYPE_HMAC_SHA1_96_AES_256
+#endif
+
+#if !defined(CKSUMTYPE_HMAC_SHA1_96_AES128) && defined(CKSUMTYPE_HMAC_SHA1_96_AES_128)
+#define CKSUMTYPE_HMAC_SHA1_96_AES128 CKSUMTYPE_HMAC_SHA1_96_AES_128
+#endif
+
 /* The older versions of heimdal that don't have this
    define don't seem to use it anyway.  I'm told they
    always use a subkey */
diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c
index 0d877ddef89..30622843f1d 100644
--- a/source3/libads/authdata.c
+++ b/source3/libads/authdata.c
@@ -42,6 +42,28 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
 	krb5_checksum cksum;
 	krb5_keyusage usage = 0;
 
+	switch (sig->type) {
+	case CKSUMTYPE_HMAC_MD5_ARCFOUR:
+		/* ignores the key type */
+		break;
+	case CKSUMTYPE_HMAC_SHA1_96_AES256:
+		if (KRB5_KEY_TYPE(keyblock) != ENCTYPE_AES256_CTS_HMAC_SHA1_96) {
+			return EINVAL;
+		}
+		/* ok */
+		break;
+	case CKSUMTYPE_HMAC_SHA1_96_AES128:
+		if (KRB5_KEY_TYPE(keyblock) != ENCTYPE_AES128_CTS_HMAC_SHA1_96) {
+			return EINVAL;
+		}
+		/* ok */
+		break;
+	default:
+		DEBUG(2,("check_pac_checksum: Checksum Type %d is not supported\n",
+			(int)sig->type));
+		return EINVAL;
+	}
+
 	smb_krb5_checksum_from_pac_sig(&cksum, sig);
 
 #ifdef HAVE_KRB5_KU_OTHER_CKSUM /* Heimdal */
-- 
2.11.0

