Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to authenticate a public key with certificate authority using Python?

import OpenSSL

key = ...
signature = ...
data = ...

x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, key)
OpenSSL.crypto.verify(x509, signature, data, 'sha1')

So far, I am able to do all of this without any problems. However, it doesn't feel like this is enough security, since the key itself is given to me via an URL (that I am supposed to trust*), and the method to build the signature is publicly available.

So, say the key is said to be verified by "VeriSign Class 3 Code Signing 2010 CA", can anyone tell me how I can go about checking that this is a valid claim?

I'm guessing I need to have the VeriSign certificate locally on my machine. Assuming that I do, where do I go from there?

Thanks!

*the URL is given to me as a parameter in a JSON request. Sure, the URL will be HTTPS and I can check the domain name and all that. But it seems like I should be doing checks on the certificate itself

like image 629
badideas Avatar asked Jan 20 '15 12:01

badideas


People also ask

How does the certification authority certify your public key?

The certificate is digitally signed by the CA that issued the certificate. The signature is created using the CA's private key and ensures the validity of the certificate. Because only the certificate is signed, not the data sent in the TLS transaction, TLS does not provide for nonrepudiation.

How do I trust a public key from a certificate?

The certificate authorities(CA) or web of trust(WOT) model shall help you in ensuring the authenticity of public key. The Certificate authority is a centralized entity that issues digital certificate that certifies the ownership of a public key by the named subject of the certificate.

How do public and private keys work with certificates?

The public key is made available to anyone who wants to verify the identity of the certificate holder, while the private key is a unique key that is kept secret. This enables the certificate holder to digitally sign documents, emails and other information without a third party being able to impersonate them.


1 Answers

You are right that you should check the certificate itself. And yes, you need the VeriSign root certificate(s) (and any other intermediate certificates to have the complete chain of trust) which signed the certificate to be checked.

Current Symantec (VeriSign) root certificates can be found here in zipfile.

Download and unzip the zip file and find all certificates you wish to trust and put them together (in pem format) into one certificate bundle file.

Now you need to do the actual verification. Unfortunately, the OpenSSL call you need is X509_verify_certificate. I looked at the source for both pyopenssl and M2Crypto and neither expose that call, so there's no direct Python code you can call to verify the certificate with either of those packages.

However, since you are using pyopenssl you obviously have the openssl library available. Thus you probably already have or can easily install the openssl command-line tool set. If so, you can call the openssl verify command through a pipe by doing something like this:

cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, key)
# the command like likes pem format
cert_pem = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)

# the bundle that you created from the zip extraction
certificate_bundle = 'verisign-root-bundle.pem'

# Pipe the cert to the openssl verify command and check the return code
# a return code of 0 is successful verify
import subprocess
p = subprocess.Popen(['openssl', 'verify', '-CAfile', certificate_bundle],
                     stdin=subprocess.PIPE)
p.communicate(input=cert_pem)
p.wait()
if (p.returncode == 0):
    print('Certificate Verified.')
else:
    print('Problem with certificate')

The above pipe runs the command

openssl verify -CAfile ca.bundle certificate.pem

Finally, if you're not familiar with openssl, the command to show certificates is

openssl x509 -inform PEM -text -in certificate.pem

Hope this helps!

like image 155
random8 Avatar answered Oct 22 '22 22:10

random8