Repository: mitmproxy/mitmproxy

Issue:
Failed to proxy HTTPS request to unicode domains
#### Problem Description
Just like issue https://github.com/mitmproxy/mitmproxy/issues/6381.

#### Steps to reproduce the behavior:
1. start mitmproxy: `mitmproxy -p 8080`
2. browse url with proxy setup, for example: `https://tt.广西阀门.net`

and then mitmproxy throws following exception:

```
Addon error: DNSName values should be passed as an A-label string. This means unicode characters should be encoded via a library like idna.                                                         
Traceback (most recent call last):                                                                                                                                                                                 
  File "/home/pan/.local/lib/python3.10/site-packages/mitmproxy/addons/tlsconfig.py", line 526, in _ip_or_dns_name                                                                                                 
    ip = ipaddress.ip_address(val)                                                                                                                                                                                 
  File "/usr/lib/python3.10/ipaddress.py", line 54, in ip_address                                                                                                                                                  
    raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address')                                                                                                                                 
ValueError: 'tt.广西阀门.net' does not appear to be an IPv4 or IPv6 address                                                                                                                                        
                                                                                                                                                                                                                   
During handling of the above exception, another exception occurred:                                                                                                                                                
                                                                                                                                                                                                                   
Traceback (most recent call last):                                                                                                                                                                                 
  File "/home/pan/.local/lib/python3.10/site-packages/cryptography/x509/general_name.py", line 85, in __init__                                                                                                     
    value.encode("ascii")                                                                                                                                                                                          
UnicodeEncodeError: 'ascii' codec can't encode characters in position 3-6: ordinal not in range(128)                                                                                                               
                                                                                                                                                                                                                   
During handling of the above exception, another exception occurred:                                                                                                                                                
                                                                                                                                                                                                                   
Traceback (most recent call last):                                                                                                                                                                                 
  File "/home/pan/.local/lib/python3.10/site-packages/mitmproxy/addons/tlsconfig.py", line 178, in tls_start_client                                                                                                
    entry = self.get_cert(tls_start.context)                                                                                                                                                                       
  File "/home/pan/.local/lib/python3.10/site-packages/mitmproxy/addons/tlsconfig.py", line 512, in get_cert                                                                                                        
    altnames.append(_ip_or_dns_name(conn_context.server.address[0]))                                                                                                                                               
  File "/home/pan/.local/lib/python3.10/site-packages/mitmproxy/addons/tlsconfig.py", line 528, in _ip_or_dns_name                                                                                                 
    return x509.DNSName(val)                                                                                                                                                                                       
  File "/home/pan/.local/lib/python3.10/site-packages/cryptography/x509/general_name.py", line 87, in __init__                                                                                                     
    raise ValueError(                                                                                                                                                                                              
ValueError: DNSName values should be passed as an A-label string. This means unicode characters should be encoded via a library like idna.                                                                         
[16:31:32.448][127.0.0.1:53048] No TLS context was provided, failing connection.                        
```

#### System Information

```sh
$ mitmproxy --version
Mitmproxy: 10.2.4
Python:    3.10.12
OpenSSL:   OpenSSL 3.2.1 30 Jan 2024
Platform:  Linux-6.5.0-21-generic-x86_64-with-glibc2.35
```

Browser:
```
Google Chrome	122.0.6261.94 (Official Build) (64-bit) 
Revision	880dbf29479c6152d5e4f08dfd3a96b30f919e56-refs/branch-heads/6261@{#960}
OS	Linux
JavaScript	V8 12.2.281.19
User Agent	Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Command Line	/usr/bin/google-chrome-stable --flag-switches-begin --flag-switches-end --desktop-startup-id=gnome-shell/Google Chrome/2430-1-PC_TIME219086
```



Discussion:

Resolving patch:
diff --git a/mitmproxy/addons/tlsconfig.py b/mitmproxy/addons/tlsconfig.py
--- a/mitmproxy/addons/tlsconfig.py
+++ b/mitmproxy/addons/tlsconfig.py
@@ -525,6 +525,6 @@ def _ip_or_dns_name(val: str) -> x509.GeneralName:
     try:
         ip = ipaddress.ip_address(val)
     except ValueError:
-        return x509.DNSName(val)
+        return x509.DNSName(val.encode("idna").decode())
     else:
         return x509.IPAddress(ip)


Test patch:
diff --git a/test/mitmproxy/addons/test_tlsconfig.py b/test/mitmproxy/addons/test_tlsconfig.py
--- a/test/mitmproxy/addons/test_tlsconfig.py
+++ b/test/mitmproxy/addons/test_tlsconfig.py
@@ -138,12 +138,12 @@ def test_get_cert(self, tdata):
             )
 
             # And now we also incorporate SNI.
-            ctx.client.sni = "sni.example"
+            ctx.client.sni = "🌈.sni.example"
             entry = ta.get_cert(ctx)
             assert entry.cert.altnames == x509.GeneralNames(
                 [
                     x509.DNSName("example.mitmproxy.org"),
-                    x509.DNSName("sni.example"),
+                    x509.DNSName("xn--og8h.sni.example"),
                     x509.DNSName("server-address.example"),
                 ]
             )