feat(kerberos): add support for IAKerb extension for Kerberos client - #751
Rostyslav-Romanets wants to merge 1 commit into
Conversation
| proptest = "1.6" | ||
| cfg-if = "1" | ||
|
|
||
| [patch.crates-io] |
There was a problem hiding this comment.
These patches of picky-rs can be removed once a new version containing the following changes will be released: (Devolutions/picky-rs#531) will be released.
| } | ||
|
|
||
| let neg_result = if !negotiate.mic_needed || negotiate.mic_verified { | ||
| // TODO(FIX): The client rejects the server's `mechListMIC`: https://github.com/Devolutions/sspi-rs/issues/748 |
There was a problem hiding this comment.
I disabled the MIC token verification due to this issue: #748
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Dependency resolution, workspace compilation, cross-realm transitions, state preservation, mechanism framing, and SPNEGO MIC verification contain blocking issues.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 4
Open (6)
CI fails because required sibling picky-rs checkout is unavailable · New Referral processing repeats TGS response instead of requesting next realm · New Removing kdc_url breaks dpapi-web KerberosConfig initialization · New Server mechListMIC is accepted without signature verification · New Fallible state transition corrupts context on error · New IAKERB final AP-REQ uses incorrect Kerberos mechanism OID · New
What changed in this PR
Adds IAKERB proxy support to Kerberos authentication and restructures AS/TGS exchanges into resumable state machines.
Changes:
- Adds IAKERB configuration, framing, cookies, transcript checksums, and SPNEGO negotiation.
- Splits Kerberos client/server exchange states and secures DH private keys.
- Updates callers, tests, FFI, and picky dependencies.
| File | Description |
|---|---|
tests/sspi/client_server/kerberos/mod.rs |
Updates Kerberos configurations and exchange counts. |
tests/sspi/client_server/credssp.rs |
Updates configuration and CredSSP step count. |
src/utils.rs |
Maps IAKERB proxy errors. |
src/pku2u/server.rs |
Wraps DH private keys as secrets. |
src/pku2u/mod.rs |
Reads secret DH keys. |
src/pku2u/generators.rs |
Generates secret DH keys. |
src/pk_init.rs |
Secures DH parameters. |
src/negotiate/server.rs |
Adjusts final MIC handling. |
src/negotiate/mod.rs |
Adds IAKERB mechanism selection. |
src/negotiate/generators.rs |
Advertises the IAKERB mechanism. |
src/negotiate/client.rs |
Integrates IAKERB and MIC exchange behavior. |
src/lib.rs |
Exports KDC resolution configuration. |
src/kerberos/tests.rs |
Updates test contexts for new state fields. |
src/kerberos/server/mod.rs |
Introduces server-specific states. |
src/kerberos/server/as_exchange.rs |
Hosts transport-based AS exchange logic. |
src/kerberos/pa_datas.rs |
Reads protected DH keys. |
src/kerberos/mod.rs |
Adds split states and IAKERB context data. |
src/kerberos/messages.rs |
Encodes IAKERB proxy messages. |
src/kerberos/config.rs |
Adds KDC resolution strategies. |
src/kerberos/client/mod.rs |
Implements resumable Kerberos client exchanges. |
src/kerberos/client/kdc/tgs_exchange.rs |
Adds the TGS exchange state machine. |
src/kerberos/client/kdc/mod.rs |
Decodes direct and proxied KDC replies. |
src/kerberos/client/kdc/as_exchange.rs |
Adds the AS exchange state machine. |
src/kerberos/client/generators.rs |
Serializes authenticator extensions. |
src/kerberos/client/extractors.rs |
Validates preauthentication errors. |
src/kerberos/client/change_password.rs |
Rejects IAKERB password changes. |
src/kerberos/client/as_exchange.rs |
Removes the previous AS exchange implementation. |
src/auth_identity.rs |
Adds protected password extraction. |
ffi/src/sspi/sec_handle.rs |
Migrates FFI configuration construction. |
examples/kerberos.rs |
Updates the Kerberos example constructor. |
Cargo.toml |
Adds local picky dependency patches. |
Cargo.lock |
Records locally patched picky packages. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| [patch.crates-io] | ||
| picky = { path = "../picky-rs/picky" } | ||
| picky-asn1 = { path = "../picky-rs/picky-asn1" } | ||
| picky-asn1-der = { path = "../picky-rs/picky-asn1-der" } | ||
| picky-asn1-x509 = { path = "../picky-rs/picky-asn1-x509" } | ||
| picky-krb = { path = "../picky-rs/picky-krb" } |
There was a problem hiding this comment.
These patches will be removed once the IAKERB changes in the picky-rs project have been merged.
| self.ticket = Some(tgs_rep.0.ticket.0.clone()); | ||
| self.tgt_session_key = session_key; | ||
| self.auth_rep = tgs_rep.0; | ||
| self.realm = next_realm; |
| pub struct KerberosConfig { | ||
| /// Strategy for resolving the KDC to use for Kerberos authentication. | ||
| pub kdc_resolution: KdcResolution, |
| // TODO(FIX): The client rejects the server's `mechListMIC`: https://github.com/Devolutions/sspi-rs/issues/748 | ||
| // if negotiate.mic_needed { | ||
| // negotiate.verify_mic_token(mech_list_mic.as_deref())?; | ||
| // } | ||
| negotiate.mic_verified = true; |
There was a problem hiding this comment.
The MIC token verification has an issue which is not fixed yet: #752.
The verification is commented for now, since the authentication fails.
|
|
||
| client.state = KerberosState::Preauthentication; | ||
| loop { | ||
| let status = match std::mem::replace(&mut client.state, KerberosState::Client(Box::default())) { |
| let (tgt_ticket, mech_id) = | ||
| if let Some((tbt_ticket, mech_oid)) = extract_tgt_ticket_with_oid(input_token)? { | ||
| (Some(tbt_ticket), mech_oid.0) | ||
| } else { | ||
| (None, oids::krb5()) | ||
| }; |


This PR adds support for the IAKERB extension according to the IAKERB specification.
The main changes are focused on the
Kerberosstate machine. Previously, thePreauthenticationstate handled the entire KDC message exchange withing a single asyncintialize_security_contextcall. This approach does not work with IAKERB, where KDC messages are exchanged via a server that acts as a proxy. ThePreauthenticationstate has therefore been split into multiple states, allowing the state machine to saveKerberosstate between KDC message exchanges.Additionaly, the
ASandTGSexchanges have been extracted into separate state machines. These new state machines are KDC transport-agnostic and can be used with both external KDC and an IAKERB proxy.What is IAKERB
IAKERB extends Kerberos to support scenarios where the client cannot directly access the KDC. Instead, KDC messages are encapsulated in GSS-API tokens and exchanged through an IAKERB proxy. The server forwards these messages to the LocalKDC, allowing the client to obtain the required Kerberos tickets without direct network access to the KDC.
Microsoft recently introduced IAKERB support in Windows Insider builds as part of its effort to reduce NTLM dependency: https://techcommunity.microsoft.com/blog/windows-itpro-blog/reducing-ntlm-dependency-iakerb-and-localkdc-in-windows-insider-preview/4524615.
Related PRs
KdcResolutionenum instead of KDC url IronRDP#1987