Verifying peer in SSL using python
From the comments to my first reply I see that there is a general misunderstanding what does 'verify a certificate mean'. I will try to write a brief explanation here to eliminate some of the illusions.
Certificate verification is about checking a signature on the certificate metadata (i.e. subject, validity period, extensions and such) against some cryptographic signature.
If all you have for the validation is a self-signed certificate you cannot distinguish it from another self-signed certificate with exactly the same metadata, but the different key, unless you know the key certificate's key in advance. And don't forget that you establish all this verification procedure to remove the requirement to have this pre-shared knowledge. With regular certificate verification you cannot completely remove the requirement to have some pre-shared knowlege, which is a set of third-party certificates, also known as 'CA certificates'. Since this knowledge is pre-shared, those certificates may be self-signed, but remember that you have received information about validity of those certificates not from the verification process, but from some outer knowledge.
When you have a set of trusted 'CA certificates' distributed between peers, you can use those to sign other certificates and check signatures against that pre-shared knowledge of trusted CAs.
But if you have no additional knowledge about a self-signed certificate except the certificate itself you can make no assumptions about trust to this particular certificate, because it can be issued by some evil hacker as well as by you trustworthy server.
Please, acquire some knowledge about Man in the middle attack, Public key infrastructure and Public key cryptography in general before implementing any kind of certificate verification processes.
Please understand that blind verification of a self-signed certificate will not protect you even from a clever hacker in your own network, not even considering internet security in general.
Edit: question author clarified that he was actually looking for how to verify a verisign (or other CA) signature on a certificate using M2Crypto bindings. Here are two examples:
from M2Crypto import X509, SSL
# manual validation of a signature on a certificate using a given CA cert:
ca = X509.load_cert('/path/to/ca_cert.pem')
cert = X509.load_cert('certificate_to_validate.pem')
print "Verification results:", cert.verify(ca.get_pubkey())
# adding a given CA cert to the SSL Context for verification
ctx = SSL.Context()
# load a certificate from file
ctx.load_verify_locations(cafile='/path/to/ca_cert.pem')
# or use all certificate in a CA directory
ctx.load_verify_locations(capath='/path/to/ca/dir')
# or you can specify both options at the same time.
If you are going to use a directory with many CA certificates (which is often more convenient) you must rename each certificate to <hash>.0
where <hash>
is the hash of the certificate subject (obtained with openssl x509 -noout -hash -in cert.pem
).
I assume you use some OpenSSL binding. I see 2 ways to solve your problem.
- You can add your certificate to openssl directory (run
openssl version -d
to see it for your system). This will affect all programs using openssl on your machine. - Load certificate and add it run-time (the code sketch below is for PyOpenSSL, but it should be similar for other bindings):
.
x509 = OpenSSL.crypto.load_certificate(...)
ctx = OpenSSL.SSL.Context(...)
store = ctx.get_cert_store()
store.add_cert(x509)
ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, ...)