If you think they are easy, you are (probably) doing them wrong. A presentation about issues with TLS and X.509 certificates for Tampere security people (TreSec, @TreSecCommunity) meetup on 21st of March 2018.
4. It is more complicated than that...
>>> import httplib
>>> conn = httplib.HTTPSConnection("www.python.org")
>>> conn.request("GET", "/")
>>> r1 = conn.getresponse()
>>> print r1.status, r1.reason
200 OK
Who is this www.python.org? What DNS are we
using? What is the IP of this www.python.org in
the DNS we are using? Do these match, do we
get exception if they don’t? Do we verify the
certificate? Who do we accept as certifiers for
the certificate? What is the allowed use of
certificate? What TLS/SSL version we are
using? What encryption? Do we have Perfect
Forward Secrecy? What are the other TLS
connection parameters? What wrapper,
TLS/SSL library we are using and what are their
defaults? ...
5. Making the connection...
class httplib.HTTPSConnection(host[, port[, key_file[, cert_file[, strict[, timeout[, source_address[, context]]]]]]])
A subclass of HTTPConnection that uses SSL for communication with secure servers. Default port is 443. If
context is specified, it must be a ssl.SSLContextinstance describing the various SSL options.
key_file and cert_file are deprecated, please use ssl.SSLContext.load_cert_chain() instead, or let
ssl.create_default_context() select the system’s trusted CA certificates for you.
Please read Security considerations for more information on best practices.
New in version 2.0.
Changed in version 2.6: timeout was added.
Changed in version 2.7: source_address was added.
Changed in version 2.7.9: context was added.
This class now performs all the necessary certificate and hostname checks by default. To revert to the previous,
unverified, behavior ssl._create_unverified_context() can be passed to the context parameter.
CVE-2014-9365 – HTTPS man-in-the-middle attack
against Python clients using default settings
6. Checking context...
ssl.create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None, capath=None, cadata=None)
Return a new SSLContext object with default settings for the given purpose. The settings are chosen by the ssl module,
and usually represent a higher security level than when calling the SSLContext constructor directly.
cafile, capath, cadata represent optional CA certificates to trust for certificate verification, as in
SSLContext.load_verify_locations(). If all three are None, this function can choose to trust the system’s default CA
certificates instead.
The settings are: PROTOCOL_SSLv23, OP_NO_SSLv2, and OP_NO_SSLv3 with high encryption cipher suites without
RC4 and without unauthenticated cipher suites. Passing SERVER_AUTH as purpose sets verify_mode to
CERT_REQUIRED and either loads CA certificates (when at least one of cafile, capath or cadata is given) or uses
SSLContext.load_default_certs() to load default CA certificates.
Note The protocol, options, cipher and other settings may change to more restrictive values anytime without prior
deprecation. The values represent a fair balance between compatibility and security. If your application needs specific
settings, you should create a SSLContext and apply the settings yourself.
Who can be the certifier?
What TLS protocols are allowed?
To ensure consistent settings, DIY?
Purpose here is not the X.509 certificate
extended parameter purpose
7. This does not feel so difficult...
So I make my own context correctly, make the
connection, check the possible exceptions and
then it is no worries mate?
10. Certificate revocation check (against CRL)
SSLContext.verify_flags
The flags for certificate
verification operations. You
can set flags like
VERIFY_CRL_CHECK_LEAF
by ORing them together. By
default OpenSSL does
neither require nor verify
certificate revocation lists
(CRLs). Available only with
openssl version 0.9.8+.
#!/usr/bin/env python
import httplib
import ssl
context=ssl.create_default_context()
context.verify_flags=context.verify_flags|ssl.VERIFY_CRL_CHECK_CHAIN
conn = httplib.HTTPSConnection("www.python.org",context=context)
conn.request("GET", "/")
r1 = conn.getresponse()
print r1.status, r1.reason
The code works, I was able to see connection to crl servers, but soon the
CRL was cached by the OpenSSL and could not get a dump with contents
to see if anything was transferred.
11. Certificate revocation lists (CRL)
● Are retrieved and cached the first time a
request to check the certificate chain is made
● SSL library handles caching
● CRLs have LastUpdate and NextUpdate Fields
to control caching
● But what if first time CRL cannot be retrieved?
12. Case: Internet Explorer and Wi-Fi captive portals
● Internet Explorer users were complaining that getting to web
authentication page took too long. Other browser users were
fine.
● It was discovered that Internet Explorer wanted to check the
CRL of the captive portal WWW server and because it could
not get it, it waited until all of its tries timeouted.
● The solution was to define at least some of the CRL server
IPs as pass through addresses in the captive portal.
● When Internet Explorer was able to get and verify CRLs, the
delay vanished.
13. HTTPS is easy compared to other TLS services
● In most cases everybody just trusts all CA certificates in
browser or operating system certificate store.
● With HTTPS one usually has enough network connectivity to
retrieve CRLs or even use Online Certificate Status Protocol
(OCSP).
● DNS-IP Address-Certificate verification (and others even
better verifications) can be performed against used service.
● With other TLS services everything is not so straight forward.
14. Securing TLS services
● For VPN or network access accepting any CA signed
certificates is probably not a good idea.
● For email, instant messaging, software updates etc.
accepting any CA signed certificates will mean that at least
state actors can have access to your data and devices.
● The certifying CA, purpose of the certificate and checking
what it really verifies becomes increasingly important.
● Methods that help detecting service certificate changes
(certificate pinning) and verify certificates offline (OCSP
stapling) help to prevent MitM attacks.
15. Case: TLS VPN with certificate authentication
● PKI with Root CA and separate Intermediate CAs for People and
Servers
● VPN termination point misconfigured to trust Root CA verified
certificates, VPN clients misconfigured to trust Root CA
● Now Root, Servers and People CA signed client certificates can
authenticate successfully against VPN termination point, VPN
clients accept any certificates certified by previous CAs as VPN
termination point.
● This is made possible by not being careful in configuring CA
settings, hostname, certificate and certificate purpose checks.
Think about if we would in addition trust to any CA in system?
16. Case: WPA Enterprise Wi-Fi authentication
● Without IP connectivity terminal starts authentication process with
RADIUS server.
● Terminal is supposed to verify RADIUS server certificate and
certificate details (usually hostname) against certain CA certificate.
● Often these checks are bypassed, sometimes they are not even
configurable without creating and deploying separate device
management configuration profiles in devices.
● At least username and password hash are in danger to be
captured by anyone setting up Wi-Fi AP and RADIUS server with a
certificate and network name accepted by the client device.
● Once again certificate checks and configuration matter.
17. Securing WPA Enterprise Wi-Fi Authentication
● Certificate check and configuration, (forcing) device
profiles
● Switching from username-password to client
certificate, SIM or elliptic curves (EAP-PWD) based
authentication
● Using certificate pinning for RADIUS server certificate
● Using OCSP stapling [1]
[1] http://radiatorcookbook.open.com.au/2018/02/new-feature-ocsp-and-ocsp-stapling.html
18. Summary
● TLS and certificates are not easy. They require careful design,
implementation, testing, configuration and deployment.
● This presentation did not cover everything. It barely scratched PKI
and more advanced certificate verification.
● Hopefully this presentation raised more concern or interest in
ensuring that TLS and certificates are properly done in your
projects, services and systems.
● Doing everything properly needs understanding of the whole stack
(PKI, users, application/service, programming language, TLS
wrappers, TLS library, configurations and Internet/transport in
between service and terminal).
19. Thank you. Questions?
For more information:
Karri Huhtanen
Radiator Software Oy
https://radiatorsoftware.com/