diff options
author | Rob Austein <sra@hactrn.net> | 2008-01-13 00:45:25 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2008-01-13 00:45:25 +0000 |
commit | 15154022374f02c3b05a6df95967ff2c941112e5 (patch) | |
tree | bf4372bee94dba60f081b87e5a9d9b4249a667b8 /scripts/rpki/cms.py | |
parent | 2cdfd3e59c2c6fd6f12cb9a95a51f8d78d372fcc (diff) |
Start cleaning CMS code now that we can handle it internally
svn path=/scripts/rpki/cms.py; revision=1477
Diffstat (limited to 'scripts/rpki/cms.py')
-rw-r--r-- | scripts/rpki/cms.py | 155 |
1 files changed, 15 insertions, 140 deletions
diff --git a/scripts/rpki/cms.py b/scripts/rpki/cms.py index bf8531c1..f8027504 100644 --- a/scripts/rpki/cms.py +++ b/scripts/rpki/cms.py @@ -16,14 +16,14 @@ """CMS routines. -For the moment these just call the OpenSSL CLI tool, which is slow, -requires disk I/O, and likes PEM format. Fix this later. +These used to use the OpenSSL CLI too, which was slow. I've since +added minimal PKCS #7 / CMS capability to POW, so we now use that +instead. I should write a pretty DER_object wrapper around the POW +code and include it in x509.py, but I haven't gotten to that yet. """ import os, rpki.x509, rpki.exceptions, lxml.etree, rpki.log, POW -cmstest = False - debug = 1 # openssl smime -sign -nodetach -outform DER -signer biz-certs/Alice-EE.cer @@ -37,102 +37,9 @@ def sign(plaintext, keypair, certs): OpenSSL CLI tool will accept them. rpki.x509 handles that for us. """ - certs.chainsort() - - if not cmstest: - - rpki.log.info("Running old CMS signer") - - mypid = str(os.getpid()) - - rpki.log.trace() - - signer_filename = "cms.tmp." + mypid + ".signer.pem" - certfile_filename = "cms.tmp." + mypid + ".certfile.pem" - plaintext_filename = "cms.tmp." + mypid + ".plaintext" - signed_filename = "cms.tmp." + mypid + ".signed" - key_filename = "cms.tmp." + mypid + ".key.pem" - - rpki.log.trace() - - f = open(signer_filename, "w") - f.write(certs[0].get_PEM()) - f.close() - - rpki.log.trace() - - f = open(certfile_filename, "w") - for cert in certs[1:]: - f.write(cert.get_PEM()) - f.close() - - rpki.log.trace() - - f = open(plaintext_filename, "w") - f.write(plaintext) - f.close() - - rpki.log.trace() - - # This is evil, key should NOT be on disk, but OpenSSL CLI goes into - # a spin wait sometimes and I now suspect it's an I/O problem. - # So we whack this with chmod() to minimize the risk. - - f = open(key_filename, "w") - f.close() - os.chmod(key_filename, 0600) - f = open(key_filename, "w") - f.write(keypair.get_PEM()) - f.close() - os.chmod(key_filename, 0600) - - cmd = ("openssl", "smime", "-sign", "-nodetach", "-outform", "DER", "-binary", - "-inkey", key_filename, - "-signer", signer_filename, - "-certfile", certfile_filename, - "-in", plaintext_filename, - "-out", signed_filename) - - rpki.log.trace() - - pid = os.fork() - - if pid == 0: - rpki.log.trace() - os.execvp(cmd[0], cmd) - raise rpki.exceptions.SubprocessError, "os.execvp() returned, which should never happen" - - rpki.log.trace() - - assert pid != 0 - - retpid, status = os.waitpid(pid, 0) - - rpki.log.trace() - - if status != 0: - raise rpki.exceptions.SubprocessError, "CMS signing command returned status 0x%x" % status - - rpki.log.trace() - - f = open(signed_filename, "r") - cms = f.read() - f.close() - - rpki.log.trace() - - for f in (key_filename, signer_filename, certfile_filename, plaintext_filename, signed_filename): - os.unlink(f) - - else: # cmstest - - rpki.log.info("Running new CMS signer") - - p7 = POW.PKCS7() - p7.sign(certs[0].get_POW(), keypair.get_POW(), [x.get_POW() for x in certs[1:]], plaintext) - cms = p7.derWrite() - - rpki.log.trace() + p7 = POW.PKCS7() + p7.sign(certs[0].get_POW(), keypair.get_POW(), [x.get_POW() for x in certs[1:]], plaintext) + cms = p7.derWrite() if debug >= 2: print @@ -146,8 +53,7 @@ def sign(plaintext, keypair, certs): def verify(cms, ta): """Verify the signature of a chunk of CMS. - Returns the plaintext on success. If OpenSSL CLI tool reports - anything other than successful verification, we raise an exception. + Returns the plaintext on success, otherwise raise an exception. """ if debug >= 2: @@ -155,45 +61,15 @@ def verify(cms, ta): print "Verifying CMS:" dumpasn1(cms) - if not cmstest: - - rpki.log.info("Running old CMS verifier") + p7 = POW.derRead(POW.PKCS7_MESSAGE, cms) - mypid = str(os.getpid()) + store = POW.X509Store() + store.addTrust(ta.get_POW()) - ta_filename = "cms.tmp." + mypid + ".ta.pem" - - f = open(ta_filename, "w") - f.write(ta.get_PEM()) - f.close() - - i,o,e = os.popen3(("openssl", "smime", "-verify", "-inform", "DER", "-binary", "-CAfile", ta_filename)) - i.write(cms) - i.close() - plaintext = o.read() - o.close() - status = e.read() - e.close() - - os.unlink(ta_filename) - - else: # cmstest - - rpki.log.info("Running new CMS verifier") - - p7 = POW.derRead(POW.PKCS7_MESSAGE, cms) - - store = POW.X509Store() - store.addTrust(ta.get_POW()) - - plaintext = p7.verify(store) - return plaintext - - # never get here with new verifier, throws exception + try: + return p7.verify(store) - if status == "Verification successful\n": - return plaintext - else: + except: if debug >= 1: print "CMS verification failed, dumping inputs:" print @@ -202,8 +78,7 @@ def verify(cms, ta): print print "CMS:" dumpasn1(cms) - raise rpki.exceptions.CMSVerificationFailed, "CMS verification failed with status %s" % status - + raise rpki.exceptions.CMSVerificationFailed, "CMS verification failed" def xml_verify(cms, ta): """Composite routine to verify CMS-wrapped XML.""" |