This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: SSL/TLS pinning for the ssl module
Type: enhancement Stage: needs patch
Components: Versions: Python 3.4
process
Status: closed Resolution: duplicate
Dependencies: Superseder:
Assigned To: Nosy List: christian.heimes, giampaolo.rodola, janssen, jcea, pitrou, raymontag
Priority: normal Keywords:

Created on 2013-08-14 11:21 by raymontag, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (12)
msg195130 - (view) Author: (raymontag) Date: 2013-08-14 11:21
Hello,

I would like to see an implementation for SSL/TLS pinning in the sll module of the standard library.

At this moment it's only possible to give the client a CAcert and check if the server's certificate is signed with this CA by creating a ssl.Context object with ssl.Context("/path/to/cafile"). If I don't know the server's certificate, that is I just have the root certificate, this is okay. But if I implement my own server/client structure I know the server's certificate. And here comes pinning into play: If I know server's certificate I could not only check if it's signed with my CA but also if it is the specific certificate I've signed. This is a better protection against MITM e.g. and would be a great enhancement of the ssl module IMHO.

raymontag
msg195131 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-08-14 11:28
TLS cert pinning should be possible with the implementation of #18293
msg195132 - (view) Author: (raymontag) Date: 2013-08-14 11:43
Yep, that's exactly what I meant :)
msg195133 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-08-14 11:45
If you want to check for a specific server certificate, then I guess it should be enough to expose the cert's fingerprint in the data returned by getpeercert().
msg195134 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-08-14 11:54
getpeercert() doesn't return Subject Public Key Info yet. It's on my TODO list. Chrome uses SPKI (PK algo + mod + exp) to pin certs, https://www.imperialviolet.org/2011/05/04/pinning.html
msg195135 - (view) Author: (raymontag) Date: 2013-08-14 11:56
Yeah, this was my first idea, too.

Are there at this moment other possibilities to implement pinning myself with the options the module provides me?
msg195137 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-08-14 12:02
> Are there at this moment other possibilities to implement pinning
> myself with the options the module provides me?

I don't think so. Perhaps you could use the serialNumber, but I'm not
sure how safe it is, even when restricting to a single CA cert.
msg195138 - (view) Author: (raymontag) Date: 2013-08-14 12:03
That's not a good idea, a serial number could be faked.
msg195139 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2013-08-14 12:03
sha256(conn.getpeercert(True)) works until the cert gets e.g. more SAN fields.
msg195140 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-08-14 12:10
> sha256(conn.getpeercert(True)) works until the cert gets e.g. more
> SAN fields.

Indeed, that's simply comparing the certificate by binary value. At this
point you don't even need a CA anymore, I guess :-)
msg195142 - (view) Author: (raymontag) Date: 2013-08-14 12:17
Great, that matches my needs exactly
msg195200 - (view) Author: Jesús Cea Avión (jcea) * (Python committer) Date: 2013-08-14 19:07
This technique is used in Mercurial and I use it in my projects too.
History
Date User Action Args
2022-04-11 14:57:49adminsetgithub: 62935
2013-08-14 19:07:01jceasetmessages: + msg195200
2013-08-14 19:03:54jceasetnosy: + jcea
2013-08-14 12:17:24raymontagsetmessages: + msg195142
2013-08-14 12:10:44pitrousetmessages: + msg195140
2013-08-14 12:03:36christian.heimessetmessages: + msg195139
2013-08-14 12:03:23raymontagsetmessages: + msg195138
2013-08-14 12:02:07pitrousetmessages: + msg195137
2013-08-14 11:56:48raymontagsetmessages: + msg195135
2013-08-14 11:54:47christian.heimessetmessages: + msg195134
2013-08-14 11:45:45pitrousetmessages: + msg195133
2013-08-14 11:43:26raymontagsetstatus: open -> closed
resolution: duplicate
messages: + msg195132
2013-08-14 11:28:36christian.heimessetversions: + Python 3.4
nosy: + janssen, pitrou, giampaolo.rodola, christian.heimes

messages: + msg195131

stage: needs patch
2013-08-14 11:21:30raymontagcreate