问题
I am using ssl.py to connect to a webserver and I would like to verify the server certificate.
I have a ROOT_CA which signs an INTERMEDIATE_CA and this finally signs the SERVER_CERTIFICATE.
I would like to provide the client only the INTERMEDIATE_CA so it can verify all certificates signed by it. However, it appears that I need to provide the entire certificate chain ROOT_CA->INTERMEDIATE_CA in order for the verification to work.
Any insights on this ?
Here is the script I am using:
import asyncio
import pathlib
import ssl
import websockets
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_REQUIRED
server_cert = pathlib.Path(__file__).with_name("intermediate_ca_server.ca-chain.cert.pem")
ssl_context.load_verify_locations(server_cert)
async def hello():
uri = "wss://<url>"
async with websockets.connect(
uri, ssl=ssl_context
) as websocket:
await websocket.send('test data')
greeting = await websocket.recv()
print(f"< {greeting}")
回答1:
By default OpenSSL needs the full certificate chain including the root certificate. With OpenSSL 1.0.2 a new verification flag X509_V_FLAG_PARTIAL_CHAIN
was added which makes it possible to let the trust chain end in a trusted certificate even if this certificate is not a root certificate (i.e. subject and issuer differ).
It looks like Python does not have yet a constant defined for this so one needs to use the integer representation:
ctx = ssl.create_default_context()
ctx.load_verify_locations(cafile='subca.pem') # contains only sub-CA
ctx.verify_flags |= 0x80000 # set X509_V_FLAG_PARTIAL_CHAIN
ctx.ssl_wrap(...)
来源:https://stackoverflow.com/questions/59327424/python-wws-library-requires-entire-certificate-chain-to-verify-server