• GSS unwrap fails using RC4 session key instead of subkey

    From Michael B Allen@ioplex@gmail.com to kerberos on Wed May 7 13:36:34 2025
    From Newsgroup: comp.protocols.kerberos

    When using the MIT Kebreros gss-client program to initiate an RC4 resource,
    my acceptor implementation (custom, not sun Java) fails to unwrap() because
    the MITK initiator is using the session key instead of the subkey.
    My initiator unconditionally uses the subkey which works with gss-server
    (and the Windows SSPI initiator or acceptor.

    Presumably I'm screwing up some flag during the AP-REQ/REP exchange. Unfortunately running gss-client with the -pass option results in PREAUTH_FAILED whereas without gdb it strangely works.

    Where does the MITK initiator select the session key vs the subkey?

    Bonus question: Is there a trick to getting gdb to work with gss-client
    -pass?

    Mike

    PS: Yes, RC4 is discontinued but I decided to support it so it needs to
    work 100%.
    --
    Michael B Allen
    Java AD DS Integration
    https://www.ioplex.com/ <http://www.ioplex.com/>
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Greg Hudson@ghudson@mit.edu to Michael B Allen on Wed May 7 17:59:21 2025
    From Newsgroup: comp.protocols.kerberos

    On 5/7/25 13:36, Michael B Allen wrote:
    Where does the MITK initiator select the session key vs the subkey?
    RC4 is a "not newer" enctype, so krb5_gss_wrap() calls
    make_seal_token_v1() with enc=ctx->enc.

    ctx->enc is set up by kg_setup_keys() called at init_sec_context time.
    It is called first unconditionally in kg_new_connection(), with the initiator's subkey as set by krb5_mk_req_extended(). It may be called
    again by mutual_auth() with the acceptor's subkey, but only if:

    * Mutual authentication is performed
    * The AP-REP EncAPRepPart included an acceptor subkey
    * The RFC 4121 message format is used (not for RC4), OR
    DCE-style authencation is in use, OR
    the acceptor subkey has a different enctype from the initiator subkey

    Bonus question: Is there a trick to getting gdb to work with gss-client -pass?

    I haven't needed any trick. Using the test suite, I can run (from the
    top level of a build tree):

    cd appl/gss-sample
    PYTHONPATH=../../../src/util python3 ../../../src/appl/gss-sample/t_gss_sample.py
    # Open testlog in a text editor and search for "arcfour"
    # from there, search for "-pass" and note the command number
    # for me right now that is 156, but there have been some recent
    # changes to the test script
    PYTHONPATH=../../../src/util python3 ../../../src/appl/gss-sample/t_gss_sample.py -v --debug=156
    (gdb) break krb5_gss_wrap
    (gdb) run
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael B Allen@ioplex@gmail.com to kerberos on Thu May 8 14:17:45 2025
    From Newsgroup: comp.protocols.kerberos

    On Thu, May 8, 2025 at 12:10rC>AM Michael B Allen <ioplex@gmail.com> wrote:
    So the session key used starts with C952.

    I meant to say subkey not session key.
    For completeness I ran my initiator against the Windows Server SSPI
    acceptor, and got the following:
    InitStepState: Authenticator {
    cname: TsspiUserAes256@MEGA.CORP
    cksum: Checksum8003 {
    channelBindings: 00000000000000000000000000000000
    gssflags: 0x0000403E
    GSS_C_DELEG_FLAG
    Y GSS_C_MUTUAL_FLAG
    Y GSS_C_REPLAY_FLAG
    Y GSS_C_SEQUENCE_FLAG
    Y GSS_C_CONF_FLAG
    Y GSS_C_INTEG_FLAG
    GSS_C_DCE_STYLE
    GSS_C_IDENTIFY_FLAG
    Y GSS_C_EXTENDED_ERROR_FLAG
    }
    cusec: 588294
    ctime: 20250508174734Z
    subkey: (23)412213...
    seq-number: 656590050
    }
    InitStepState: GssContextToken {
    mech: KRB5 (1.2.840.113554.1.2.2)
    Krb5InnerContextToken {
    tokId: 0x0001
    ApReq {
    ap-options: 0x20000000
    ticket: Ticket {
    sname: HOST/TsspiCompRc4.mega.corp@MEGA.CORP
    enc-part: (23)6D9EDF...
    }
    authenticator: (23)3B0B5F...
    }
    }
    }
    InitStepState: GssContextToken {
    mech: KRB5 (1.2.840.113554.1.2.2)
    Krb5InnerContextToken {
    tokId: 0x0002
    ApRep {
    enc-part: (23)8A32FD...
    }
    }
    }
    InitStepState: EncAPRepPart {
    ctime: 20250508174734Z
    cusec: 588294
    subkey: (23)412213...
    seq-number: 2110239284
    }
    Rc4 wrap: key:
    00000: 41 22 13 30 34 0D D6 44 39 7E 27 E5 91 31 30 1D |A".04.|uD9~'|N.10.
    As you can see, the SSPI acceptor simply uses the same key for the Authenticator subkey and AP-REP subkey.
    Not sure how the SSPI knows to do this.
    Maybe it's just hardcoded behavior of RC4.
    So when MITK initiates to an SSPI RC4 service, it uses the Acceptor subkey whereas the SSPI initiator will use the AP-REP subkey but it doesn't matter because the keys are the same.
    The bottom line is that if anyone writes an acceptor from scratch like me,
    and they want to support RC4, the acceptor will need to either "Negotiated enctype" to a different enctype so that the MITK initiator uses the AP-REP subkey (the MITK way), or just return the same RC4 subkey for the
    Authenticator and AP-REP subkeys (the SSPI way) so that does not matter if
    the MITK initiator uses the Authenticator subkey.
    Mike
    --
    Michael B Allen
    Java AD DS Integration
    https://www.ioplex.com/ <http://www.ioplex.com/>
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Greg Hudson@ghudson@mit.edu to Michael B Allen on Thu May 8 15:55:44 2025
    From Newsgroup: comp.protocols.kerberos

    On 5/8/25 14:17, Michael B Allen wrote:
    As you can see, the SSPI acceptor simply uses the same key for the Authenticator subkey and AP-REP subkey.
    Not sure how the SSPI knows to do this.

    The MIT krb5 acceptor will do this as well, when the enctype is older
    and it can't negotiate a better enctype (e.g. if permitted_enctypes =
    rc4-hmac on the client or server). See:

    * accept_sec_context.c:1020-1024, where cfx_generate_subkey is only set
    when the enctype is newer, when we are using DCE-style, or when
    ap_req_options contains AP_OPTS_USE_SUBKEY (which means when we can
    negotiate a better enctype; see rd_req_dec.c:766-773)

    * accept_sec_context.c:1030, where KRB5_AUTH_CONTEXT_USE_SUBKEY is only
    set when cfx_generate_subkey is set

    * mk_rep.c:96-106, where repl.subkey is set to
    auth_context->authentp->subkey when KRB5_AUTH_CONTEXT_USE_SUBKEY isn't set

    As best I can currently tell, there isn't a good reason for the
    conditional at init_sec_context.c:808-810 to be more complicated than ap_rep_data->subkey != NULL. The other conditions seem to be there out
    of an abundance of caution, preserving the behavior of release
    1.6--which had no enctype negotiation or DCE-style support, and only
    ever used the acceptor subkey for newer enctypes. But:

    * When the MIT krb5 acceptor does generate a subkey, it expects the
    initiator to use it (accept_sec_context.c:1058).

    * Heimdal appears to use the acceptor subkey for all enctypes (see wrap.c:_gsskrb5i_get_token_key() and it use in _gsskrb5_wrap()).
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael B Allen@ioplex@gmail.com to Greg Hudson on Thu May 8 17:29:21 2025
    From Newsgroup: comp.protocols.kerberos

    On Thu, May 8, 2025 at 3:55rC>PM Greg Hudson <ghudson@mit.edu> wrote:
    On 5/8/25 14:17, Michael B Allen wrote:
    As you can see, the SSPI acceptor simply uses the same key for the Authenticator subkey and AP-REP subkey.
    Not sure how the SSPI knows to do this.

    The MIT krb5 acceptor will do this as well, when the enctype is older
    and it can't negotiate a better enctype (e.g. if permitted_enctypes = rc4-hmac on the client or server). See:

    * accept_sec_context.c:1020-1024, where cfx_generate_subkey is only set
    when the enctype is newer, when we are using DCE-style, or when ap_req_options contains AP_OPTS_USE_SUBKEY (which means when we can
    negotiate a better enctype; see rd_req_dec.c:766-773)

    Wow. Thanks for the detailed run-through.
    So the reductive understanding seems to be that the AP-REP subkey defaults
    to the Authenticator subkey and doing otherwise is controlled by various
    forces like adding RFC4537 AD-ETYPE-NEGOTIATION to the authorization_data
    so that the acceptor knows to / how to upgrade the key (which is the "difference" I was seeing from the MITK initiator).
    Fortunately I don't have to implement everything. For multiple reasons I
    code to the Windows SSPI which is MUCH easier than what you're doing.
    DCE_STYLE is next on my list after I polish up IAKERB so your pointers are super helpful.
    Mike
    --
    Michael B Allen
    Java AD DS Integration
    https://www.ioplex.com/ <http://www.ioplex.com/>
    --- Synchronet 3.21d-Linux NewsLink 1.2