Pobieranie łańcucha certyfikatów za pomocą modułu SSL Python 3.3
Mogę uzyskać standardowe informacje o certyfikacie dla połączenia SSL w Pythonie 3.3 za pomocą metody getpeercert () na gnieździe SSL. Jednak wydaje się, że nie dostarcza łańcucha, jak to robi narzędzie OpenSSL „s_client”.
Czy jest jakiś sposób, w jaki mogę to uzyskać, aby zobaczyć, czy mój certyfikat IA został prawidłowo skonfigurowany?
wiersz polecenia s_client:
openssl s_client -connect google.com:443
wynik s_client (tylko pierwsze kilka wierszy):
$ openssl s_client -connect google.com:443
CONNECTED(00000003)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Kod Pythona 3.3:
import socket
from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23
from ssl import SSLContext # Modern SSL?
from ssl import HAS_SNI # Has SNI?
from pprint import pprint
def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
ca_certs=None, server_hostname=None,
ssl_version=None):
context = SSLContext(ssl_version)
context.verify_mode = cert_reqs
if ca_certs:
try:
context.load_verify_locations(ca_certs)
# Py32 raises IOError
# Py33 raises FileNotFoundError
except Exception as e: # Reraise as SSLError
raise SSLError(e)
if certfile:
# FIXME: This block needs a test.
context.load_cert_chain(certfile, keyfile)
if HAS_SNI: # Platform-specific: OpenSSL with enabled SNI
return context.wrap_socket(sock, server_hostname=server_hostname)
return context.wrap_socket(sock)
hostname = 'www.google.com'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((hostname, 443))
sslSocket = ssl_wrap_socket(s,
ssl_version=2,
cert_reqs=2,
ca_certs='/usr/local/lib/python3.3/dist-packages/requests/cacert.pem',
server_hostname=hostname)
pprint(sslSocket.getpeercert())
s.close()
Wynik kodu:
{'issuer': ((('countryName', 'US'),),
(('organizationName', 'Google Inc'),),
(('commonName', 'Google Internet Authority G2'),)),
'notAfter': 'Sep 25 15:09:31 2014 GMT',
'notBefore': 'Sep 25 15:09:31 2013 GMT',
'serialNumber': '13A87ADB3E733D3B',
'subject': ((('countryName', 'US'),),
(('stateOrProvinceName', 'California'),),
(('localityName', 'Mountain View'),),
(('organizationName', 'Google Inc'),),
(('commonName', 'www.google.com'),)),
'subjectAltName': (('DNS', 'www.google.com'),),
'version': 3}