Skip to content

should catch ssl.CertificateError and reraise ClientConnectionError #1116

Closed
@jwilk

Description

@jwilk

Long story short

I'd like to catch all client errors, including certificate errors, but except aiohttp.errors.ClientError is not sufficient.

Expected behaviour

All kinds of certificate error should cause an instance of (a subclass of) aiohttp.errors.ClientConnectionError to be raised.

Actual behaviour

When there's mismatch between the hostname and the certificate's CN/SAN, ssl.CertificateError is raised.
(And, for some reason, its traceback is printed on stderr, even when I catch it. 😬)

Steps to reproduce

Run the following code:

import asyncio
import aiohttp

async def main(url):
    async with aiohttp.ClientSession() as session:
        try:
            async with session.get(url):
                await response.read()
        except aiohttp.errors.ClientError as exc:
            pass
        except Exception as exc:
            print('Unexpected {!r}'.format(exc))

url = 'https://wrong.host.badssl.com'
loop = asyncio.get_event_loop()
loop.run_until_complete(main(url))
loop.close()

You will get:

Exception in callback None
handle: <Handle cancelled>
Traceback (most recent call last):
  File "/usr/lib/python3.5/asyncio/events.py", line 125, in _run
    self._callback(*self._args)
  File "/usr/lib/python3.5/asyncio/selector_events.py", line 677, in _read_ready
    self._protocol.data_received(data)
  File "/usr/lib/python3.5/asyncio/sslproto.py", line 493, in data_received
    ssldata, appdata = self._sslpipe.feed_ssldata(data)
  File "/usr/lib/python3.5/asyncio/sslproto.py", line 201, in feed_ssldata
    self._sslobj.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 638, in do_handshake
    match_hostname(self.getpeercert(), self.server_hostname)
  File "/usr/lib/python3.5/ssl.py", line 297, in match_hostname
    % (hostname, ', '.join(map(repr, dnsnames))))
ssl.CertificateError: hostname 'wrong.host.badssl.com' doesn't match either of '*.badssl.com', 'badssl.com'
Unexpected CertificateError("hostname 'wrong.host.badssl.com' doesn't match either of '*.badssl.com', 'badssl.com'",)

Your environment

aiohttp from git master (d8848dd), Python 3.5.2, Linux.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions