Re: [Security-sig] Unified TLS API for Python: Draft 3
On 26 Jan 2017, at 01:33, Steve Dower <steve.dower@python.org> wrote:
Looks good to me, but I wonder why we need to define all the algorithms in the PEP (by reference)? Could they also use a similar model to certificates, where the implementation provides a constructor that takes a string (in a format defined here, e.g. "OpenSSL style") and does the best it can to return something it will know how to use later? It involves some trust, but I honestly don't see a world where we end up with implementations deliberately trying to be incompatible with each other (which would seem to be the only reason to define the full enum ahead of time).
There’s a thread running through this PEP which I’d call a rejection of “stringly-typed” APIs. I have never liked OpenSSL’s cipher string format: it’s a constant source of footguns where a given cipher string provides an extremely non-deterministic result. Because OpenSSL needs to tolerate the possibility that you are referring to ciphers that are only present in older or newer versions of OpenSSL, there is little error checking done on a cipher string. You can see this by running the openssl ciphers command on two very similar cipher strings: openssl ciphers "ECDHE+AESGCM:RSA+AESGCM" ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-GCM-SHA256 vs openssl ciphers "ECDHE+AESGCM:RSA+AESGMC" ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256 Note that the typo in the second string wipes out a whole bunch of cipher suites, but OpenSSL doesn’t flag this as a problem because it doesn’t know whether AESGMC is a thing that might appear in the future or have appeared in the past. The only way to actually error check this is to compare to the hard-coded list of what cipher suites you expect, except of course at that point you may as well have just written the full list of cipher suites out or, more aptly, used a typed API. OpenSSL only errors out on a cipher string if it leads to no ciphers being supported, which is an extremely unlikely outcome for any project taking rigorous control of their cipher string. The other problem here is that we need to define a grammar of how to translate the cipher string into a list of actual ciphers. This grammar needs to be forward-looking, which is a problem that OpenSSL is running directly into as we speak[0]. For this reason I’m inclined to lean towards the more verbose approach of just writing down what all of the cipher suites are in an enum. That way, it gets much easier to validate what’s going on. There’s still no requirement to actually support them all: an implementation is allowed to quietly ignore any cipher suites it doesn’t support. But that can no longer happen due to typos, because typos now cause AttributeErrors at runtime in a way that is very obvious and clear. Does that make sense? Cory [0]: This is a digression, but worth harping on about. OpenSSL’s cipher suite names have traditionally been of the form “key exchange-signing algo-stream cipher-mode-MAC”. However, OpenSSL has allowed some of those to be unspecified and to mean their defaults (e.g. AES128-GCM-SHA256 actually means RSA-RSA-AES128-GCM-SHA256). This has caused them problems with TLSv1.3, which has defined all new cipher suites that no longer include their key exchange mechanism (e.g. TLS_AES_128_GCM_SHA256 is now a complete cipher string). Because of OpenSSL’s weird defaulty grammar, right now their cipher string assumes that this new cipher uses RSA key exchange, even though it absolutely does not. All of this is a very long form way of saying that defining a stable string-to-cipher-suite parser is very hard unless we define it as saying “just use the actual IANA names for the cipher suites”, and the second we’ve done that we may as well have just defined an enum and called it good. ;)
On Jan 26, 2017, at 4:18 AM, Cory Benfield <cory@lukasa.co.uk> wrote:
For this reason I’m inclined to lean towards the more verbose approach of just writing down what all of the cipher suites are in an enum. That way, it gets much easier to validate what’s going on. There’s still no requirement to actually support them all: an implementation is allowed to quietly ignore any cipher suites it doesn’t support. But that can no longer happen due to typos, because typos now cause AttributeErrors at runtime in a way that is very obvious and clear.
I’d say additionally that given the verbose approach a third party library could provide this OpenSSL like API and be responsible for “compiling” it down to the actual list of ciphers for input into the verbose API. If one of those got popular and seemed stable enough to add it, we could always add it in later as a higher level API for cipher selection without the backends needing to change anything since the output of such a function would still be a list of all of the desired ciphers which would be the input to the backends. — Donald Stufft
On 26 Jan 2017, at 21:17, Donald Stufft <donald@stufft.io> wrote:
On Jan 26, 2017, at 4:18 AM, Cory Benfield <cory@lukasa.co.uk <mailto:cory@lukasa.co.uk>> wrote:
For this reason I’m inclined to lean towards the more verbose approach of just writing down what all of the cipher suites are in an enum. That way, it gets much easier to validate what’s going on. There’s still no requirement to actually support them all: an implementation is allowed to quietly ignore any cipher suites it doesn’t support. But that can no longer happen due to typos, because typos now cause AttributeErrors at runtime in a way that is very obvious and clear.
I’d say additionally that given the verbose approach a third party library could provide this OpenSSL like API and be responsible for “compiling” it down to the actual list of ciphers for input into the verbose API. If one of those got popular and seemed stable enough to add it, we could always add it in later as a higher level API for cipher selection without the backends needing to change anything since the output of such a function would still be a list of all of the desired ciphers which would be the input to the backends.
Yup, strongly agreed. Cory
On Fri, Jan 27, 2017 at 3:10 AM, Cory Benfield <cory@lukasa.co.uk> wrote:
On 26 Jan 2017, at 21:17, Donald Stufft <donald@stufft.io> wrote:
On Jan 26, 2017, at 4:18 AM, Cory Benfield <cory@lukasa.co.uk> wrote:
For this reason I’m inclined to lean towards the more verbose approach of just writing down what all of the cipher suites are in an enum. That way, it gets much easier to validate what’s going on. There’s still no requirement to actually support them all: an implementation is allowed to quietly ignore any cipher suites it doesn’t support. But that can no longer happen due to typos, because typos now cause AttributeErrors at runtime in a way that is very obvious and clear.
I’d say additionally that given the verbose approach a third party library could provide this OpenSSL like API and be responsible for “compiling” it down to the actual list of ciphers for input into the verbose API. If one of those got popular and seemed stable enough to add it, we could always add it in later as a higher level API for cipher selection without the backends needing to change anything since the output of such a function would still be a list of all of the desired ciphers which would be the input to the backends.
Yup, strongly agreed.
https://github.com/tiran/tlsdb/blob/master/tlsdb.py - [ ] ENH: tlsdb.py: add parsers/datasources for {SChannel, SecureTransport} - [x] openssl-master - [x] openssl-1.02 - [x] gnutls-master - [x] nss-tip - [x] mod_nss-master - [x] **iana** - [x] mozilla-server-side - [ ] SChannel - [ ] SecureTransport - [ ] ENH: tlsdb.py: add OpenSSL-workalike lookup method - [ ] BLD: tls.config.__: generate Enums?
Cory
_______________________________________________ Security-SIG mailing list Security-SIG@python.org https://mail.python.org/mailman/listinfo/security-sig
On Fri, Jan 27, 2017 at 9:30 AM, Wes Turner <wes.turner@gmail.com> wrote:
On Fri, Jan 27, 2017 at 3:10 AM, Cory Benfield <cory@lukasa.co.uk> wrote:
On 26 Jan 2017, at 21:17, Donald Stufft <donald@stufft.io> wrote:
On Jan 26, 2017, at 4:18 AM, Cory Benfield <cory@lukasa.co.uk> wrote:
For this reason I’m inclined to lean towards the more verbose approach of just writing down what all of the cipher suites are in an enum. That way, it gets much easier to validate what’s going on. There’s still no requirement to actually support them all: an implementation is allowed to quietly ignore any cipher suites it doesn’t support. But that can no longer happen due to typos, because typos now cause AttributeErrors at runtime in a way that is very obvious and clear.
I’d say additionally that given the verbose approach a third party library could provide this OpenSSL like API and be responsible for “compiling” it down to the actual list of ciphers for input into the verbose API. If one of those got popular and seemed stable enough to add it, we could always add it in later as a higher level API for cipher selection without the backends needing to change anything since the output of such a function would still be a list of all of the desired ciphers which would be the input to the backends.
Yup, strongly agreed.
https://github.com/tiran/tlsdb/blob/master/tlsdb.py
- [ ] ENH: tlsdb.py: add parsers/datasources for {SChannel, SecureTransport}
- [x] openssl-master - [x] openssl-1.02 - [x] gnutls-master - [x] nss-tip - [x] mod_nss-master - [x] **iana** - [x] mozilla-server-side - [ ] SChannel - [ ] SecureTransport
- [ ] ENH: tlsdb.py: add OpenSSL-workalike lookup method - [ ] BLD: tls.config.__: generate Enums?
To be clear, I don't have the resources necessary to complete these tasks. Would these tasks be necessary/helpful? Reading: https://github.com/mathiasertl/django-ca/blob/master/requirements.txt I learned about oscrypto: - oscrypto: "TLS (SSL) sockets, key generation, encryption, decryption, signing, verification and KDFs using the OS crypto libraries. Does not require a compiler, and relies on the OS for patching. Works on Windows, OS X and Linux/BSD." - src: https://github.com/wbond/oscrypto - pypi: https://pypi.python.org/pypi/oscrypto - docs: https://github.com/wbond/oscrypto/blob/master/docs/readme.md#modern-cryptogr... Is oscrypto useful or relevant to this effort?
Cory
_______________________________________________ Security-SIG mailing list Security-SIG@python.org https://mail.python.org/mailman/listinfo/security-sig
On 10 Feb 2017, at 17:20, Wes Turner <wes.turner@gmail.com> wrote:
I learned about oscrypto:
- oscrypto: "TLS (SSL) sockets, key generation, encryption, decryption, signing, verification and KDFs using the OS crypto libraries. Does not require a compiler, and relies on the OS for patching. Works on Windows, OS X and Linux/BSD." - src: https://github.com/wbond/oscrypto <https://github.com/wbond/oscrypto> - pypi: https://pypi.python.org/pypi/oscrypto <https://pypi.python.org/pypi/oscrypto> - docs: https://github.com/wbond/oscrypto/blob/master/docs/readme.md#modern-cryptogr... <https://github.com/wbond/oscrypto/blob/master/docs/readme.md#modern-cryptography>
Is oscrypto useful or relevant to this effort?
You’ll note that the PEP credits Will Bond with review and oversight. oscrypto could absolutely be a backend that supports these APIs if Will wants it to be. =) Cory
On Fri, Feb 10, 2017 at 11:22 AM, Cory Benfield <cory@lukasa.co.uk> wrote:
On 10 Feb 2017, at 17:20, Wes Turner <wes.turner@gmail.com> wrote:
I learned about oscrypto:
- oscrypto: "TLS (SSL) sockets, key generation, encryption, decryption, signing, verification and KDFs using the OS crypto libraries. Does not require a compiler, and relies on the OS for patching. Works on Windows, OS X and Linux/BSD." - src: https://github.com/wbond/oscrypto - pypi: https://pypi.python.org/pypi/oscrypto - docs: https://github.com/wbond/oscrypto/blob/master/ docs/readme.md#modern-cryptography
Is oscrypto useful or relevant to this effort?
You’ll note that the PEP credits Will Bond with review and oversight. oscrypto could absolutely be a backend that supports these APIs if Will wants it to be. =)
thanks! docs: - https://github.com/wbond/oscrypto/blob/master/docs/tls.md src: - https://github.com/wbond/oscrypto/blob/master/oscrypto/tls.py - https://github.com/wbond/oscrypto/blob/master/oscrypto/_tls.py - https://github.com/wbond/oscrypto/blob/master/oscrypto/_linux_bsd/trust_list... - https://github.com/wbond/oscrypto/blob/master/oscrypto/_openssl/tls.py - https://github.com/wbond/oscrypto/blob/master/oscrypto/_osx/tls.py - https://github.com/wbond/oscrypto/blob/master/oscrypto/_win/tls.py constants / enums - _PROTOCOL_MAP - https://github.com/wbond/oscrypto/blob/master/oscrypto/_cipher_suites.py - https://github.com/tiran/tlsdb/blob/master/tlsdb.py > tlsdb.json - see: [ ] SChannel, [ ] Secure Transport tasks brainstormed above - [ ] @IETF @W3C are there / should there be URIs / URNs for these?
Cory
participants (3)
-
Cory Benfield
-
Donald Stufft
-
Wes Turner