title: How to validate / verify an X509 Certificate chain of trust in Python?
body: <p>I am working on implementing a web application that utilizes an API. During a response, the API server sends over a link to an X509 certificate (in PEM format, composed of a signing certificate and one or more intermediate certificates to a root CA certificate ) that I must download and use to do further verification. </p>
  
  <p>Before using the certificate, I need to ensure that all certificates in the chain combine to create a chain of trust to a trusted root CA certificate (to detect and avoid any malicious requests). I am having a hard time doing this in python and my research into the subject is not yielding anything useful.</p>
  
  <p>The certificate is easily grabbed and loaded using requests and M2Crypto</p>
  
  <pre><code>import requests
  from M2Crypto import RSA, X509
  
  mypem = requests.get('https://server.com/my_certificate.pem')   
  cert = X509.load_cert_string(str(mypem.text), X509.FORMAT_PEM)
  </code></pre>
  
  <p>However, validating the certificate chain is a problem. It is not feasible for me to write the certificate to disk in order to use a command line utility like <code>openssl</code> through something like subprocess, so it must be done through python. I also do not have any open connections and so using a connection based validation solution (like is mentioned in this answer / thread: <a href="https://stackoverflow.com/a/1088224/4984533">https://stackoverflow.com/a/1088224/4984533</a>) will not work either.</p>
  
  <p>On another thread about this problem (at <a href="https://stackoverflow.com/a/4427081">https://stackoverflow.com/a/4427081</a>) abbot explains that m2crypto is incapable of doing this validation and says that he has written an extension to allow validation (using the module <code>m2ext</code>) but his patch never seems work, always returning false even though I know it's valid:</p>
  
  <pre><code>from m2ext import SSL
  ctx = SSL.Context()
  ctx.load_verify_locations(capath='/etc/ssl/certs/') # I have run c_rehash in this directory to generate a list of cert files with signature based names
  if not ctx.validate_certificate(cert): # always happens
      print('Invalid certificate!') 
  </code></pre>
  
  <p>There's also this answer on a similar thread here <a href="https://stackoverflow.com/a/9007764/4984533">https://stackoverflow.com/a/9007764/4984533</a> in which John Matthews claims to have a patch written which will do it, but unfortunately the patch link is now dead -- and anyway there is a comment on that thread stating that the patch did not work with openssl 0.9.8e.</p>
  
  <p>All answers relating to validating a certificates chain of trust in python seem to either link to the dead patch or go back to <code>m2ext</code>.</p>
  
  <p>Is there a simple, straightforward way to go about validating my certificates chain of trust in Python? </p>