GSS unwrap fails using RC4 session key instead of subkey

Michael B Allen ioplex at gmail.com
Thu May 8 00:10:51 EDT 2025


On Wed, May 7, 2025 at 5:59 PM Greg Hudson <ghudson at mit.edu> wrote:

> OR
>    the acceptor subkey has a different enctype from the initiator subkey
>

Ah! Thanks for the detailed answer.

I think I figured out the problem.

TLDR; My acceptor does not "Negotiated enctype" to aes256-cts and so the
MITK initiator uses the Authenticator subkey (nevermind about the session
key being used, I must have been looking at the Authenticator subkey).

However, I think I found a minor difference between Windows Kerberos and
MITK ...

Long version:

If I run the gss-client to my acceptor with an RC4 service, I get output
like [heavily pruned]:

gdb ${GSS_CLIENT} -ex 'break make_seal_token_v1' -ex "run -port 8443 -nm
-user user1 at BUSI.CORP -pass 'Pas\$word' as5api.busi.corp
'HTTP at as5api.busi.corp' 'Hello, World!'"

ASIDE: The gdb issue was because the password had a $ symbol which needs to
be escaped in the gdb run parameters string.

Generated subkey for TGS request: aes256-cts/CBD2
etypes requested in TGS request: aes256-cts, aes128-cts, aes256-sha2,
aes128-sha2, des3-cbc-sha1, rc4-hmac, camellia128-cts, camellia256-cts
TGS reply is for user1 at BUSI.CORP -> HTTP/as5api.busi.corp at BUSI.CORP with
session key rc4-hmac/8152
Creating authenticator for user1 at BUSI.CORP -> HTTP/as5api.busi.corp@,
seqnum 7969486, subkey rc4-hmac/9579, session key rc4-hmac/8152
Read AP-REP, time 1746669048.152087, subkey rc4-hmac/387E, seqnum 334043650

Notice how my acceptor returned an rc4-hmac AS-REP subkey.

Breakpoint 1, make_seal_token_v1 (context=0x40c3f0, enc=0x413770,
seq=0x410b50, seq..._gss_oid_array>) at k5seal.c:80
80      unsigned int conflen=0, tmsglen, tlen, msglen;
(gdb) p *(krb5_key)enc
$1 = {keyblock = {magic = -1760647421, enctype = 23, length = 16, contents
= 0x40d0c0 "\311R\237\211\v\353V\334No\316t\024", <incomplete sequence
\351\246>},
  refcount = 1, derived = 0x0, cache = 0x0}
(gdb) x/16bx 0x40d0c0
0x40d0c0:   0xc9    0x52    0x9f    0x89    0x0b    0xeb    0x56    0xdc
0x40d0c8:   0x4e    0x6f    0xce    0x74    0x14    0x1f    0xe9    0xa6

So the session key used starts with C952.

Meanwhile ... my acceptor logs the following:

AcceptStepState: GssContextToken {
  mech: KRB5 (1.2.840.113554.1.2.2)
  Krb5InnerContextToken {
    tokId: 0x0001
    ApReq {
      ap-options: 0x20000000
      ticket: Ticket {
        sname: HTTP/as5api.busi.corp at BUSI.CORP
        enc-part: (23)0B36A2...
      }
      authenticator: (23)5DA124...
    }
  }
}
AcceptStepState: EncTicketPart {
  flags: 0x40A10000
  key: (23)EE19E3...
  cname: user1 at BUSI.CORP
  transited: (1)
  authtime: 20250508015048Z
  starttime: 20250508015048Z
  endtime: 20250508115048Z
  renew-till: 20250515015048Z
  authorization-data: (1)798
}
AcceptStepState: Authenticator {
  cname: user1 at BUSI.CORP
  cksum: Checksum8003 {
    channelBindings: 00000000000000000000000000000000
    gssflags: 0x00000136
        GSS_C_DELEG_FLAG
      Y GSS_C_MUTUAL_FLAG
      Y GSS_C_REPLAY_FLAG
        GSS_C_SEQUENCE_FLAG
      Y GSS_C_CONF_FLAG
      Y GSS_C_INTEG_FLAG
      Y 0x0100
        GSS_C_DCE_STYLE
        GSS_C_IDENTIFY_FLAG
        GSS_C_EXTENDED_ERROR_FLAG
  }
  cusec: 152087
  ctime: 20250508015048Z
  subkey: (23)C9529F...
  seq-number: 7969486
  authorization-data: (1)34
}
AcceptStepState: EncAPRepPart {
  ctime: 20250508015048Z
  cusec: 152087
  subkey: (23)54DDA9...
  seq-number: 334043650
}
AcceptStepState: GssContextToken {
  mech: KRB5 (1.2.840.113554.1.2.2)
  Krb5InnerContextToken {
    tokId: 0x0002
    ApRep {
      enc-part: (23)9BB121...
    }
  }
}
Rc4 unwrap: key:
00000: C9 52 9F 89 0B EB 56 DC 4E 6F CE 74 14 1F E9 A6  |ÉR...ëVÜNoÎt..é¦|
MTGS: unwrap: start=45,db=45,di=45,de=59,frame=0,tailspace=0
00000: 48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 01        |Hello, World!.  |

Indeed C952 is the Authenticator subkey.

I hacked my acceptor in this case to use the Authenticator subkey whereas
normally it uses the AP-REP subkey and unwrap() fails w/ checksum failure.

-

If I run the MITK gss-client against the MITK gss-server, I get output like
[heavily pruned]:

Starting program: /ioplex/krb5-1.21.1/src/appl/gss-sample/gss-client -port
8443 -nm -user user1 at BUSI.CORP -pass 'Pas$word' rky9as1.busi.corp
'HTTP at rky9as1.busi.corp' 'Hello, World!'
Selected etype info: etype aes256-cts, salt "BUSI.CORPdev", params ""
AS key obtained for encrypted timestamp: aes256-cts/49BF
Selected etype info: etype aes256-cts, salt "BUSI.CORPdev", params ""
AS key determined by preauth: aes256-cts/49BF
Decrypted AS reply; session key is: aes256-cts/5A73
Generated subkey for TGS request: aes256-cts/97B5
etypes requested in TGS request: aes256-cts, aes128-cts, aes256-sha2,
aes128-sha2, des3-cbc-sha1, rc4-hmac, camellia128-cts, camellia256-cts
TGS reply is for user1 at BUSI.CORP -> HTTP/rky9as1.busi.corp at BUSI.CORP with
session key rc4-hmac/0FC8
Creating authenticator for user1 at BUSI.CORP -> HTTP/rky9as1.busi.corp@,
seqnum 854939001, subkey rc4-hmac/7A54, session key rc4-hmac/0FC8
Read AP-REP, time 1746669951.877933, subkey aes256-cts/7F1F, seqnum
1042191560

Notice how the MITK acceptor returns an aes256-cts AP-REP subkey.

Meanwhile ... the MITK acceptor logs the following:

Decrypted AP-REQ with server principal HTTP/rky9as1.busi.corp at BUSI.CORP:
rc4-hmac/C6A3
AP-REQ ticket: user1 at BUSI.CORP -> HTTP/rky9as1.busi.corp at BUSI.CORP, session
key rc4-hmac/0FC8
Negotiated enctype based on authenticator: aes256-cts
Authenticator contains subkey: rc4-hmac/7A54
Creating AP-REP, time 1746669951.877933, subkey aes256-cts/7F1F, seqnum
1042191560
Sending accept_sec_context token (size=152):

The MITK acceptor "Negotiated enctype" to aes256-cts and thus, because "the
acceptor subkey has a different enctype from the initiator subkey" the MITK
initiator uses the AP-REP subkey.

-

If I run the Windows SSPI initiator to my acceptor (don't have code to do
Windows SSPI to MITK gss-server), I get the following:

AcceptStepState: GssContextToken {
  mech: KRB5 (1.2.840.113554.1.2.2)
  Krb5InnerContextToken {
    tokId: 0x0001
    ApReq {
      ap-options: 0x20000000
      ticket: Ticket {
        sname: HOST/TsspiCompRc4.mega.corp at MEGA.CORP
        enc-part: (23)1DF8CE...
      }
      authenticator: (23)860718...
    }
  }
}
AcceptStepState: EncTicketPart {
  flags: 0x40A10000
  key: (23)D5C724...
  cname: TsspiUser5 at MEGA.CORP
  transited: (1)
  authtime: 20250508025530Z
  starttime: 20250508025530Z
  endtime: 20250508125530Z
  renew-till: 20250515025530Z
  authorization-data: (1)750,(1)67
}
AcceptStepState: Authenticator {
  cname: TsspiUser6 at MEGA.CORP
  cksum: Checksum8003 {
    channelBindings: 00000000000000000000000000000000
    gssflags: 0x0000402E
        GSS_C_DELEG_FLAG
      Y GSS_C_MUTUAL_FLAG
      Y GSS_C_REPLAY_FLAG
      Y GSS_C_SEQUENCE_FLAG
        GSS_C_CONF_FLAG
      Y GSS_C_INTEG_FLAG
        GSS_C_DCE_STYLE
        GSS_C_IDENTIFY_FLAG
      Y GSS_C_EXTENDED_ERROR_FLAG
  }
  cusec: 8264
  ctime: 20250508025900Z
  subkey: (23)9C4977...
  seq-number: 781048158
  authorization-data: (1)127
}
AcceptStepState: EncAPRepPart {
  ctime: 20250508025900Z
  cusec: 8264
  subkey: (23)36662C...
  seq-number: 703851114
}
AcceptStepState: GssContextToken {
  mech: KRB5 (1.2.840.113554.1.2.2)
  Krb5InnerContextToken {
    tokId: 0x0002
    ApRep {
      enc-part: (23)17EE50...
    }
  }
}

This is with my acceptor just unconditionally using the AP-REP subkey which
works with the Windows SSPI initiator and unwrap() is successful.

So the SSPI initiator does not appear to use the Authenticator subkey if
the enctypes are the same.

I guess this isn't much of a problem since it would only occur if the
acceptor doesn't properly "Negotiated enctype" to aes256-cts.

But technically this would be a difference in behavior between Windows SSPI
and MIT Kerberos.

Mike

-- 
Michael B Allen
Java AD DS Integration
https://www.ioplex.com/ <http://www.ioplex.com/>


More information about the Kerberos mailing list