この質問が他の場所で回答されていないかどうか、オンラインで広範囲に調べました。
Python openssl ライブラリで CRL を使用しようとすると、「証明書が不明です」というエラーが発生します。具体的には、ssl 接続のハンドシェイクで使用されていない証明書の失効が crl にある場合でも、エラーが発生します。代わりに空の CRL を使用すると、エラーは発生せず、デバイスは socket.connect() を完了することができます。
問題を説明するための単純なクライアント/サーバー モデル:
サーバ:
def createServerSideSocket(port, backlog=5):
context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile="cert.pem", keyfile="key.pem", password='tempPassword')
context.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF #specifying flag to check crl
context.load_verify_locations(cafile = "crl.pem") #loading crl
sock = socket.socket()
sock.bind(('', port))
sock.listen(backlog) #listen on port 5000
return sock, context
port = 5000
sock, context = createServerSideSocket(port)
newSocket, fromAddr = sock.accept()
connStream = context.wrap_socket(newSocket, server_side=True)
print(bytes.decode(connStream.recv(1024))) #receive and print data
クライアント:
def createClientSideSocket(server_ip):
context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH, cafile="cacert.pem")
context.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF #specifying flag to check crl
context.load_verify_locations("crl.pem") #loading crl
conn = context.wrap_socket(socket.socket(), server_hostname=server_ip)
return conn
conn = createClientSideSocket("192.168.1.7") #our IP address of the server
conn.connect(("192.168.1.7", 5000))
conn.sendall(str.encode("test data"))
crl.pem に取り消された証明書が 0 個ある場合、接続は機能します。crl.pem に失効がある場合 (ハンドシェイクで使用されていない失効であっても)、次のエラーで失敗します。
クライアント上:
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)
サーバー上:
[SSL: SSLV3_ALERT_CERTIFICATE_UNKNOWN] sslv3 alert certificate unknown (_ssl.c:777)