tags:

views:

515

answers:

3

Hi, I was trying to find out how I can go about verifying a self-signed certificate by a server in python. I could not find much data in google. I also want to make sure that the server url

Thanks in advance for any insights.

+1  A: 

It is impossible to verify a self-signed certificate because of its very nature: it is self-signed.

You have to sign a certificate by some other trusted third party's certificate to be able to verify anything, and after this you can add that third party's certificate to the list of your trusted CAs and then you will be able to verify certificates signed by that certificate/CA.

If you want recommendations about how to do this in Python, you should provide the name of the SSL library you are using, since there is a choice of SSL libraries for Python.

abbot
All top-level CA certificates are self-signed and there is no problem no verify (trust) them.
Denis Otkidach
of course you can verify a self signed certificate, you just need the have the certificate copied locally. It's basically is a public/private key authentication at that point. Many local authentication systems work this way, verifying that the host is legitimate by using the x.509 cert. Look at certmaster and func for python examples
JimB
+1  A: 

I assume you use some OpenSSL binding. I see 2 ways to solve your problem.

  1. 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.
  2. 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, ...)
Denis Otkidach
Using this code you are not verifying self-signed certificate, you are explicitly adding it to a trusted certificate store thus it will 'verify' itself. Adding the certificate to openssl directory does exactly the same.Again, it is impossible to verify a self-signed certificate: any self-signed certificate will pass your verification test.
abbot
+4  A: 

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).

abbot
Sorry, my question was wrong.
Bhargava
I was actually looking for verisign-signed certificate verification using M2Crypto.
Bhargava
I've updated the answer with M2Crypto examples.
abbot
Upvoted for mentioning that you can verify a cert if you already have trusted pre-shared knowledge of the certificate.
JimB
Another thing to remember when working with SSL (especially SSL clients) is that you often also want to verify that you are talking to the right host. M2Crypto does that automatically.
Heikki Toivonen