Using M2Crypto to save and load X509 certs in pem files
        Posted  
        
            by Brock Pytlik
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Brock Pytlik
        
        
        
        Published on 2010-04-28T00:04:40Z
        Indexed on 
            2010/04/28
            5:13 UTC
        
        
        Read the original article
        Hit count: 1002
        
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.
I've put together a tiny sample program to demonstrate what I'm seeing. When I run this, the second RuntimeError is raised.
Thanks,
Brock
#!/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 = "[email protected]"
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))
        © Stack Overflow or respective owner