Add GSS channel binding support per RFC 4121 section 4.1.1.2 for AP-REQ and TGS-REQ#422
Conversation
|
@dotnet-policy-service agree company="Microsoft" |
| /// Accepts a raw SEC_CHANNEL_BINDINGS buffer | ||
| /// and converts it to <see cref="ExpectedChannelBindings"/>. | ||
| /// </summary> | ||
| public ReadOnlyMemory<byte> ExpectedRawChannelBindings |
There was a problem hiding this comment.
Nit: I feel like intention might be clearer with a setter method instead of a setter-only field. Or you could just make the caller call GssChannelBindings.FromSecChannelBindings. But no strong opinion on this.
There was a problem hiding this comment.
Agree, should be a function at a minimum
There was a problem hiding this comment.
updated to SetExpectedChannelBindingsFromSecChannelBindings
| /// Convenience property that accepts a raw SEC_CHANNEL_BINDINGS buffer (as returned by Windows SSPI) | ||
| /// and converts it to <see cref="ExpectedChannelBindings"/>. | ||
| /// </summary> | ||
| public ReadOnlyMemory<byte> ExpectedRawChannelBindings |
There was a problem hiding this comment.
Converted it to SetExpectedChannelBindingsFromSecChannelBindings
|
|
||
| var delegationInfo = checksum.DecodeDelegation(); | ||
|
|
||
| this.ChannelBindingHash = delegationInfo.ChannelBinding; |
There was a problem hiding this comment.
Probably needs a null check: this.ChannelBindingHash = delegationInfo?.ChannelBinding;
| /// Accepts a raw SEC_CHANNEL_BINDINGS buffer | ||
| /// and converts it to <see cref="ExpectedChannelBindings"/>. | ||
| /// </summary> | ||
| public ReadOnlyMemory<byte> ExpectedRawChannelBindings |
There was a problem hiding this comment.
Agree, should be a function at a minimum
|
|
||
| protected KdcServerOptions Options { get; } | ||
|
|
||
| /// <summary> |
There was a problem hiding this comment.
Actually this can go away entirely. KDC has no concept of channel bindings.
There was a problem hiding this comment.
Removed completely from both KDC ans PreAuthContext, as the CBT property in PreAuthContext was added for KDC leg only
What's the problem?
TLS Channel Binding Tokens solve authentication relay attacks (MITM).
Without CBT attacker intercepts a client's connection, terminates the TLS session, and establishes a separate TLS session to the real server. The attacker then relays the client's Kerberos AP-REQ (which is valid and properly encrypted) to the server. The server accepts it because the Kerberos ticket itself is perfectly legitimate and it has no knowledge that it arrived through an intermediary.
RFC 4121 describes Channel Binding Tokens for Kerberos.
What's the solution?
CBT ties the Kerberos authentication to the specific TLS channel it was intended for:
application_dataof thegss_channel_bindings_struct, computes the MD5 Bnd hash, and embeds it inside the authenticator checksum of the AP-REQ (encrypted, so the attacker can't modify it).If an attacker is relaying, the two TLS sessions have different certificates, the attacker's certificate on the client side vs. the real server's certificate on the server side. The hashes won't match, and the server rejects the request.
As such we are introducing:
DecryptedKrbApReq.ExpectedChannelBindingsto allow the server to specify the expected Channel Binding information in the AP-REQKerberosValidator.ExpectedChannelBindingswhich is symmetrical toDecryptedKrbApReqto facilitate the usage of this featureValidationActions.ChannelBindingthat triggersValidateChannelBinding()duringValidate()ValidateChannelBinding()uses the propertyDecryptedKrbApReq.ExpectedChannelBindingsto ensure that the unique material present in the AP-REQ.On server side the intended usage is
On client side
As of this PR, Channel Binding validation is enabled by default and follow an opt‑out model. Validation is bypassed only when ExpectedChannelBindings is unset, or when Channel Bindings are explicitly excluded through flags:
decrypted.Validate(ValidationActions.All & ~ValidationActions.ChannelBinding);Describe the solution here.