aiohttp icon indicating copy to clipboard operation
aiohttp copied to clipboard

Feature request: add functionality to retrieve the the server certificate in a client request

Open obeleh opened this issue 7 years ago • 8 comments

Rationale

This request is related to this SO Question where I asked whether or not it is possible to get the peer certificate when running a client request.

It is quite logical that the implemented hack is not going to be supported. I do, however, have use-cases in which it is required to retrieve the peer certificate. And I was hoping on working together to find a clean solution.

In protocols like Kerberos and NTLM the server certificate is used in followup steps of the authentication protocol.

A possible solution

If there is a better solution that would be great as well. Just trying to offer something workable

An extra parameter like retrieve_peer_certificate to the method aiohttp.Client._request which is default False and would make sure that a property like peer_certificate would be set in the response object. It would it be possible internally use a _get_transport that would return the SSLSocket if the connection is SSL/TLS on which you would be able to call getpeercert

obeleh avatar Mar 08 '18 14:03 obeleh

Maybe add a getpeercert() method is enough.

hubo1016 avatar Mar 18 '18 03:03 hubo1016

Unfortunately no.

  1. Peer cert can be retrieved in two forms: binary and dict.
  2. Peer name could be interested in case of rotating DNS
  3. Used cipher and other SSL options list selected ALPN/NPN protocols are also very important in some cases.

asvetlov avatar Mar 18 '18 07:03 asvetlov

@asvetlov Maybe we can expose the underlying socket (SSLSocket) object from a specified interface? They can be useful in many ways.

hubo1016 avatar Mar 18 '18 09:03 hubo1016

This feature would be very useful!

blark avatar May 28 '19 14:05 blark

This feature would be very useful!

I definitely agree.

There are five SSL related things available by transport.get_extra_info(): peercert, cipher, compression, ssl_object.

Honestly, I have no idea are they valid and available after the transport closing and SSLObject shutting down. Would somebody come with a test and investigate?

asvetlov avatar May 28 '19 16:05 asvetlov

I can retrieve the certificate on aiohttp 3.8.3 with:

async with aiohttp.ClientSession() as session:
    r = await session.get('https://bbc.com')
    cert = r.connection.transport.get_extra_info('peercert')

so this looks resolved to me.

auxsvr avatar Jan 14 '23 10:01 auxsvr

I think this should be reopened, as the connection is closed in client_reqrep.ClientResponse._response_eof and the third line may execute after that, which will make the code above fail. After a little testing, the proper solution seems to be to add ClientResponse.certificate and populate it inside _response_eof, if the connection is still valid. Should I prepare a PR for this?

auxsvr avatar Jan 21 '23 14:01 auxsvr

Should I prepare a PR for this?

Sure, we can take a look.

Dreamsorcerer avatar Jan 22 '23 14:01 Dreamsorcerer