Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support sites with invalid IDN in SslStream #82934

Merged
merged 4 commits into from
Mar 10, 2023
Merged

Support sites with invalid IDN in SslStream #82934

merged 4 commits into from
Mar 10, 2023

Conversation

wfurt
Copy link
Member

@wfurt wfurt commented Mar 3, 2023

fixes #82464

This is attempt to allow TLS handshake on site with invalid IDN to match browsers and other HTTP/TLS implementations.

Since this is somewhat corner case the change is focusing on allowing the handshake go through via setting policy to ignore name. It does not try to verify that the problematic names would for example match wildcard certificates. It would be up to the caller to verify certificates as most browsers would also show warning and not proceed automatically.

Handling has been centralize to SslAuthenticationOptions and eliminated code scattered in PAL.

I'm not sure how this impacts Android @simonrozsival. I would think that doing the puny code before calling Java should be just fine since that is what should go out on wire.

@wfurt wfurt requested a review from rzikm March 3, 2023 06:50
@wfurt wfurt self-assigned this Mar 3, 2023
@ghost
Copy link

ghost commented Mar 3, 2023

Tagging subscribers to this area: @dotnet/ncl, @vcsjones
See info in area-owners.md if you want to be subscribed.

Issue Details

fixes #82464

This is attempt to allow TLS handshake on site with invalid IDN to match browsers and other HTTP/TLS implementations.

Since this is somewhat corner case the change is focusing on allowing the handshake go through via setting policy to ignore name. It does not try to verify that the problematic names would for example match wildcard certificates. It would be up to the caller to verify certificates as most browsers would also show warning and not proceed automatically.

Handling has been centralize to SslAuthenticationOptions and eliminated code scattered in PAL.

I'm not sure how this impacts Android @simonrozsival. I would think that doing the puny code before calling Java should be just fine since that is what should go out on wire.

Author: wfurt
Assignees: wfurt
Labels:

area-System.Net.Security

Milestone: -

@simonrozsival
Copy link
Member

@wfurt yeah, this change should be just fine for Android. We can run tests on Android just to make sure.

@simonrozsival
Copy link
Member

/azp run runtime-android

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@rzikm rzikm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@@ -46,6 +49,20 @@ private static unsafe bool IsValidAddress(ReadOnlySpan<char> ipSpan)
return false;
}

private static unsafe bool IsSafeDnsString(ReadOnlySpan<char> name)
{
for (int i = 0; i < name.Length; i++)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could use the new IndexOfAnyValues<T>, but not sure if the allocation of static map is worth it for such short strings.

Copy link
Member

@MihaZupan MihaZupan Mar 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this should use IndexOfAnyValues. The allocation there is very small, we'll only store a bitmap for the ASCII range.

// Alphanumeric or '-', '.', '_'
private static readonly IndexOfAnyValues<char> s_safeDnsChars =
    IndexOfAnyValues.Create("-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz");

private static bool IsSafeDnsString(ReadOnlySpan<char> name) =>
    name.IndexOfAnyExcept(s_safeDnsChars) < 0;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IndexOfAnyValues crossed my mind but the set of characters I don't want is large for Unicode. I was not aware of IndexOfAnyExcept

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated. Just to be sure: this would only match that ASCII characters, not their Unicode equivalent (if any), right @MihaZupan ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right, the set of values you pass to Create is "ordinal".

@wfurt
Copy link
Member Author

wfurt commented Mar 3, 2023

thanks @simonrozsival. I did not know you can just run Android. I use extra-platforms and that is slow, expensive and always fails. The Android run is failing but I could not figure out from the output why. Can you please check of give me hints how to investigate. I suspect that the invalid names are failing inside of the Java engine. We have either choice to disable this test on Android, relax the receiving check or strip the SNI and try to send it without it. As I mentioned this request come from crawling use case and perhaps is not even applicable to mobile devices. (of course, consistency would be nice)

@simonrozsival
Copy link
Member

@wfurt The www-. prefix will be rejected when we pass it to the java method. This is the java error in the logs:

System.err: java.lang.IllegalArgumentException: Invalid input to toASCII: www-.volal.cz
System.err:    at java.net.IDN.toASCII(IDN.java:115)
System.err:    at javax.net.ssl.SNIHostName.<init>(SNIHostName.java:99)
System.err: Caused by: The input does not conform to the STD 3 ASCII rules. line:  0. preContext:  . postContext: -
System.err:    at android.icu.impl.IDNA2003.convertToASCII(IDNA2003.java:228)
System.err:    at android.icu.impl.IDNA2003.convertIDNToASCII(IDNA2003.java:277)
System.err:    at android.icu.text.IDNA.convertIDNToASCII(IDNA.java:654)
System.err:    at java.net.IDN.toASCII(IDN.java:108)
System.err:    ... 1 more

When I comment out the SslException
that we throw when the SNI is rejected as you suggested then all 3 test inputs pass just fine.

@wfurt
Copy link
Member Author

wfurt commented Mar 8, 2023

/azp run runtime-android

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@wfurt
Copy link
Member Author

wfurt commented Mar 9, 2023

/azp run runtime-android

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@wfurt
Copy link
Member Author

wfurt commented Mar 10, 2023

test failures are unrelated

@wfurt wfurt merged commit c3df339 into dotnet:main Mar 10, 2023
@wfurt wfurt deleted the sni branch March 10, 2023 19:00
@karelz karelz added this to the 8.0.0 milestone Mar 21, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support sites with invalid IDN in SslStream
5 participants