Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hyper HTTP2 custom SSLContext Error

I am trying to make HTTP2 request to a server(virtual hosted) which gives SSL certificates based on host header value(SNI).

    # conn = hyper.HTTP20Connection('http2.akamai.com', port=443, ssl_context=context)
    # conn.request('GET', '/path', headers={'Host': 'www.mywebsite.com'})

Hyper-h2 package for Python won't support SNI or disabling cert verification! https://hyper.readthedocs.io/en/latest/advanced.html#ssl-tls-certificate-verification

One way to disable certs verification is by having custom SSLContext, and stuck in protocol assertion error

Basic code to make HTTP2 call with custom SSLContext:

    import ssl
    import hyper

    # Custom SSLCONTEXT for not verifying SSLCertificate and Hostname
    # or need SSLCONTEXT for SNI support
    context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    context.verify_mode = ssl.CERT_NONE
    context.check_hostname = False
    hyper.tls._context = context

    conn = hyper.HTTP20Connection('http2.akamai.com', port=443, ssl_context=context)
    conn.request('GET', '/')

    print conn.get_response()

Error :

    Traceback (most recent call last):
      File "ssl_custom.py", line 32, in <module>
        conn.request('GET', '/')
      File "/usr/local/lib/python2.7/site-packages/hyper/http20/connection.py", line 281, in request
        self.endheaders(message_body=body, final=True, stream_id=stream_id)
      File "/usr/local/lib/python2.7/site-packages/hyper/http20/connection.py", line 544, in endheaders
        self.connect()
      File "/usr/local/lib/python2.7/site-packages/hyper/http20/connection.py", line 373, in connect
        assert proto in H2_NPN_PROTOCOLS or proto == H2C_PROTOCOL
    AssertionError

EDIT/UPDATE: Now that I learnt how to build context properly init_context() the problem still persists when request is made to SNI enabled server.

ssl_context = init_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_OPTIONAL

headers={'Host': 'www.opentable.com'}
conn = hyper.HTTP20Connection('ev-www.opentable.com.edgekey.net', port=443, ssl_context=ssl_context)
conn.request('GET', '/washington-dc-restaurants', headers=headers)

print conn.get_response()

Output:

assert proto in H2_NPN_PROTOCOLS or proto == H2C_PROTOCOL

Need a way to specify SNI or Curl equivalent --resolve feature in Hyper

like image 765
naren Avatar asked May 26 '26 13:05

naren


1 Answers

When using HTTP/2 over TLS, the client must negotiate the use of HTTP/2 with the server:

implementations that support HTTP/2 over TLS MUST use protocol negotiation in TLS [TLS-ALPN]

This is done via ALPN (and historically was done with NPN - hence it's appearance in the error message). That means that when the setting up the context, you must advertise that the client supports HTTP/2 in the TLS ClientHelo message.

context.set_alpn_protocols(['h2'])
like image 51
Frederik Deweerdt Avatar answered May 28 '26 02:05

Frederik Deweerdt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!