title: Using M2Crypto to save and load X509 certs in pem files
body: <p>I would expect that if I have a X509 cert as an object in memory, saved it as a pem file, then loaded it back in, I would end up with the same cert I started with. This seems not to be the case however. Let's call the original cert A, and the cert loaded from the pem file B. A.as_text() is identical to B.as_text(), but A.as_pem() differs from B.as_pem(). To say the least, I'm confused by this. As a side note, if A has been signed by another entity C, then A will verify against C's cert, but B will not.</p>
  
  <p>I've put together a tiny sample program to demonstrate what I'm seeing. When I run this, the second RuntimeError is raised.</p>
  
  <p>Thanks,<br>
  Brock</p>
  
  <pre><code>#!/usr/bin/python2.6
  
  import M2Crypto as m2
  import time
  
  cur_time = m2.ASN1.ASN1_UTCTIME()
  cur_time.set_time(int(time.time()) - 60*60*24)
  
  expire_time = m2.ASN1.ASN1_UTCTIME()
  # Expire certs in 1 hour.
  expire_time.set_time(int(time.time()) + 60 * 60 * 24)
  
  
  cs_rsa = m2.RSA.gen_key(1024, 65537, lambda: None)
  cs_pk = m2.EVP.PKey()
  cs_pk.assign_rsa(cs_rsa)
  cs_cert = m2.X509.X509()
  
  # These two seem the minimum necessary to make the as_text function call work
  # at all
  cs_cert.set_not_before(cur_time)
  cs_cert.set_not_after(expire_time)
  
  # This seems necessary to fill out the complete cert without errors.
  cs_cert.set_pubkey(cs_pk)
  
  # I've tried with the following set lines commented out and not commented.
  cs_name = m2.X509.X509_Name()
  cs_name.C = "US"
  cs_name.ST = "CA"
  cs_name.OU = "Fake Org CA 1"
  cs_name.CN = "www.fakeorg.dex"
  cs_name.Email = "cs1@www.fakeorg.dex"
  cs_cert.set_subject(cs_name)
  cs_cert.set_issuer_name(cs_name)
  cs_cert.sign(cs_pk, md="sha256")
  
  orig_text = cs_cert.as_text()
  orig_pem = cs_cert.as_pem()
  
  print "orig_text:\n%s" % orig_text
  
  cs_cert.save_pem("/tmp/foo")
  
  tcs = m2.X509.load_cert("/tmp/foo")
  
  tcs_text = tcs.as_text()
  tcs_pem = tcs.as_pem()
  
  if orig_text != tcs_text:
          raise RuntimeError(
              "Texts were different.\nOrig:\n%s\nAfter load:\n%s" %
              (orig_text, tcs_text))
  
  if orig_pem != tcs_pem:
          raise RuntimeError(
              "Pems were different.\nOrig:\n%s\nAfter load:\n%s" %
              (orig_pem, tcs_pem))
  </code></pre>