[15953] in Kerberos_V5_Development
Re: krb5-1.8 fails to verify MS PAC Checksum when AES 256 is used
daemon@ATHENA.MIT.EDU (Douglas E. Engert)
Thu Jul 1 16:28:52 2010
Message-ID: <4C2CFA81.5090804@anl.gov>
Date: Thu, 01 Jul 2010 15:28:49 -0500
From: "Douglas E. Engert" <deengert@anl.gov>
MIME-Version: 1.0
To: krbdev@mit.edu
In-Reply-To: <4749DBFD-43AE-493C-85A1-4099AC41613C@padl.com>
Content-Type: multipart/mixed; boundary="------------070700010405020307050304"
Errors-To: krbdev-bounces@mit.edu
This is a multi-part message in MIME format.
--------------070700010405020307050304
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
On 7/1/2010 9:25 AM, Luke Howard wrote:
> See attached, untested patch. This could be optimised by mapping the checksum type to an enctype (is there API for this?) and then calling krb5_kt_get_entry() rather than enumerating the keytab, but we still need to enumerate the keytab if server == NULL to handle aliases.
>
Thanks for the quick response of a patch. I applied the patch to 1.8 for testing
with some changes to replace the "for" with an if and while loop. See attached patch
with some additional debuging output added.
With the AD account entry attribute msDS-SupportedEncryptionTypes = 4 (RC4 only)
The first verify works.
With msDS-SupportedEncryptionTypes = 16 (AES256) The first verify fails
as expected, and the keytab is searched, and each key is tried. But
the RC4 key (23) gets a KRB5KRB_AP_ERR_BAD_INTEGRITY as the compare
of the computed and supplied checksums don't match.
I know the keytab keys match AD as the keys work with ssh gssapi when the PAC
is not checked.
So there is still something going on here.
Looking at [MS-KILE] v20100601 and the [MS-PAC] v20100601 The KDC should be
not be using the -138 checksum type if only AES keys are listed as being supported.
Reading the blog again:
http://blogs.msdn.com/b/openspecification/archive/2010/01/01/verifying-the-server-signature-in-kerberos-privilege-account-certificate.aspx
It says:
> Per HMAC RFC 2104 (referenced by RFC 4757), B=64 bytes is used for the padding
> for both MD5 and SHA1. The key can be of any length up to B, the block length of
> the hash function. Since the AES256 key length is 256 bits (32 bytes), the key
> material will not be truncated but appended with 32 bytes of zeroes; for AES128
> the padding would have been 48 bytes of zeros.
So this sounds like it using the padded AES key, and not an RC4 key as would
be expected if the checksum type = -138. Or am I reading this wrong?
Attached is the updated patch with debugging for pac.c, and some more
output showing the test the modified patch.
Any one from Microsoft on the list wish to comment?
> -- Luke
>
>
>
>
> _______________________________________________
> krbdev mailing list krbdev@mit.edu
> https://mailman.mit.edu/mailman/listinfo/krbdev
--
Douglas E. Engert <DEEngert@anl.gov>
Argonne National Laboratory
9700 South Cass Avenue
Argonne, Illinois 60439
(630) 252-5444
--------------070700010405020307050304
Content-Type: text/plain;
name="updated.pac.patch.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="updated.pac.patch.txt"
--- pac.patched Thu Jul 1 10:16:32 2010
+++ pac.c Thu Jul 1 14:32:35 2010
@@ -373,6 +373,7 @@
version = load_32_le(p);
p += 4;
+
if (version != 0)
return EINVAL;
@@ -394,6 +395,7 @@
pac->pac->cBuffers = cbuffers;
pac->pac->Version = version;
+fprintf(stderr,"%s:%d cbuffers=%d version=%d\n",__FUNCTION__,__LINE__, cbuffers, version);
for (i = 0; i < pac->pac->cBuffers; i++) {
PAC_INFO_BUFFER *buffer = &pac->pac->Buffers[i];
@@ -404,6 +406,9 @@
buffer->Offset = load_64_le(p);
p += 8;
+fprintf(stderr,"%s:%d i=%d ulType=%d cbBufferSize=%d Offset=%d\n",__FUNCTION__,__LINE__,
+ i, buffer->ulType, buffer->cbBufferSize, buffer->Offset) ;
+
if (buffer->Offset % PAC_ALIGNMENT) {
krb5_pac_free(context, pac);
return EINVAL;
@@ -549,6 +554,10 @@
if (buffer->cbBufferSize < PAC_SIGNATURE_DATA_LENGTH)
return KRB5_BAD_MSIZE;
+fprintf(stderr,"%s:%d type=%d %d %d\n",__FUNCTION__,__LINE__, type,
+load_32_le(data->data + buffer->Offset + PAC_SIGNATURE_DATA_LENGTH -4),
+buffer->cbBufferSize - PAC_SIGNATURE_DATA_LENGTH);
+
/* Zero out the data portion of the checksum only */
memset(data->data + buffer->Offset + PAC_SIGNATURE_DATA_LENGTH,
@@ -1093,6 +1102,8 @@
req->ticket->enc_part2->client,
key,
NULL);
+fprintf(stderr,"%s:%d First verify code=%d\n",__FUNCTION__,__LINE__,code);
+
if (code == KRB5_BAD_ENCTYPE &&
keytab != NULL &&
keytab->ops->start_seq_get != NULL) {
@@ -1100,9 +1111,9 @@
krb5_kt_cursor cursor;
krb5_keytab_entry ktent;
- for (code2 = krb5_kt_start_seq_get(kcontext, keytab, &cursor);
- code2 == 0;
- code2 = krb5_kt_next_entry(kcontext, keytab, &ktent, &cursor)) {
+ code2 = krb5_kt_start_seq_get(kcontext, keytab, &cursor);
+ if (code2 == 0) {
+ while((code2 = krb5_kt_next_entry(kcontext, keytab, &ktent, &cursor) == 0)) {
if (server != NULL &&
!krb5_principal_compare(kcontext, ktent.principal, server)) {
krb5_free_keytab_entry_contents(kcontext, &ktent);
@@ -1114,6 +1125,9 @@
req->ticket->enc_part2->client,
&ktent.key,
NULL);
+fprintf(stderr,"%s:%d retry verify code2=%d enctype=%d pac->verified=%d\n",__FUNCTION__,__LINE__,
+code2, ktent.key.enctype, pacctx->pac->verified);
+
krb5_free_keytab_entry_contents(kcontext, &ktent);
if (code2 == 0) {
code = 0;
@@ -1122,6 +1136,7 @@
}
code2 = krb5_kt_end_seq_get(kcontext, keytab, &cursor);
+ }
if (code2 != 0)
code = code2;
}
--------------070700010405020307050304
Content-Type: text/plain;
name="gdb.pac.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="gdb.pac.txt"
Running with RC4 only:
(gdb) set args host
(gdb) run
Starting program: /afs/anl.gov/appl/krb5-dev/sun4x_510/krb5m/sbin/gss-server host
[Thread debugging using libthread_db enabled]
[New Thread 1 (LWP 1)]
krb5_pac_parse:398 cbuffers=5 version=0
krb5_pac_parse:409 i=0 ulType=1 cbBufferSize=1024 Offset=0
krb5_pac_parse:409 i=1 ulType=10 cbBufferSize=22 Offset=0
krb5_pac_parse:409 i=2 ulType=12 cbBufferSize=64 Offset=0
krb5_pac_parse:409 i=3 ulType=6 cbBufferSize=20 Offset=0
krb5_pac_parse:409 i=4 ulType=7 cbBufferSize=20 Offset=0
k5_pac_zero_signature:557 type=6 -138 16
k5_pac_zero_signature:557 type=7 -138 16
mspac_verify:1105 First verify code=0
context flag: GSS_C_MUTUAL_FLAG
context flag: GSS_C_REPLAY_FLAG
context flag: GSS_C_CONF_FLAG
context flag: GSS_C_INTEG_FLAG
Accepted connection: "b17783@ANL.GOV"
Received message: "XXXX"
NOOP token
rnning with AES256 as set in msDS-Supported_encryptionTypes = 16
but checksup is still sent as -138 the RC4 version.
krb5_pac_parse:398 cbuffers=5 version=0
krb5_pac_parse:409 i=0 ulType=1 cbBufferSize=1024 Offset=0
krb5_pac_parse:409 i=1 ulType=10 cbBufferSize=22 Offset=0
krb5_pac_parse:409 i=2 ulType=12 cbBufferSize=64 Offset=0
krb5_pac_parse:409 i=3 ulType=6 cbBufferSize=20 Offset=0
krb5_pac_parse:409 i=4 ulType=7 cbBufferSize=20 Offset=0
k5_pac_zero_signature:557 type=6 -138 16
k5_pac_zero_signature:557 type=7 -138 16
mspac_verify:1105 First verify code=-1765328196
k5_pac_zero_signature:557 type=6 -138 16
k5_pac_zero_signature:557 type=7 -138 16
mspac_verify:1128 retry verify code2=-1765328353 enctype=23 pac->verified=0
Note: found the RC4 key in key file, but verify fails KRB5KRB_AP_ERR_BAD_INTEGRITY
as the provided and computed checksum don't match.
k5_pac_zero_signature:557 type=6 -138 16
k5_pac_zero_signature:557 type=7 -138 16
mspac_verify:1128 retry verify code2=-1765328196 enctype=17 pac->verified=0
k5_pac_zero_signature:557 type=6 -138 16
k5_pac_zero_signature:557 type=7 -138 16
mspac_verify:1128 retry verify code2=-1765328196 enctype=18 pac->verified=0
GSS-API error accepting context: Unspecified GSS failure. Minor code may provide more information
GSS-API error accepting context: Bad encryption type
--------------070700010405020307050304
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
krbdev mailing list krbdev@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev
--------------070700010405020307050304--