From sebastien at FLUENDO.COM Fri Nov 30 19:01:28 2007 From: sebastien at FLUENDO.COM (=?iso-8859-1?q?S=E9bastien_Merle?=) Date: Fri, 30 Nov 2007 19:01:28 +0100 Subject: [PYTHON-CRYPTO] PKCS7 verification with CA hierarchy Message-ID: <200711301901.28338.sebastien@fluendo.com> Hi, I have a CA hierarchy with a root CA and two sub CAs, and I want to verify that the signer of a pkcs7 has been issued by one specific sub CA. If the signer has been issued by another sub CA or if the signer has been issued directly by the root CA, I want the verification to fail, even if the pkc7 contains its own certification chain. I tried to do it with M2Crypto, but I can't verify the issuer is not the root CA or that the pkcs7 contains another sub CA in it certification chain. I tried to fiddle with the certificate stack and certificate store without results. How could I do this in python ? Is it even possible ? -------------------------------------------------- from M2Crypto import BIO, SMIME, X509 rootCACertFile = "rootca/cacert.pem" ca1CertFile = "subca1/cacert.pem" ca2CertFile = "subca2/cacert.pem" rootCertFile = "rootca/testcert.pem" rootKeyFile = "rootca/testkey.pem" rootSecret = "secret" sub1CertFile = "subca1/testcert.pem" sub1KeyFile = "subca1/testkey.pem" sub1Secret = "secret" sub2CertFile = "subca2/testcert.pem" sub2KeyFile = "subca2/testkey.pem" sub2Secret = "secret" data = "some data" def sign(key, cert, secret, stack=None): signer = SMIME.SMIME() signer.load_key(key, cert, lambda x: secret) if stack: signer.set_x509_stack(stack) signerDataBuff = BIO.MemoryBuffer(data) return signer.sign(signerDataBuff) def verify(store, stack, p7): try: verifyer = SMIME.SMIME() verifyer.set_x509_store(store) verifyer.set_x509_stack(stack) result = verifyer.verify(p7) return result == data except SMIME.PKCS7_Error, e: return False rootCACert = X509.load_cert(rootCACertFile) ca1Cert = X509.load_cert(ca1CertFile) ca2Cert = X509.load_cert(ca2CertFile) stack = X509.X509_Stack() store = X509.X509_Store() store.add_cert(rootCACert) store.add_cert(ca1Cert) #store.add_cert(ca2Cert) #stack.push(rootCACert) #stack.push(ca1Cert) #stack.push(ca2Cert) # Sign with key/cert issued by sub CA 1 p7 = sign(sub1KeyFile, sub1CertFile, sub1Secret) print "Should Succeed:", verify(store, stack, p7) # Sign with key/cert issued by root CA p7 = sign(rootKeyFile, rootCertFile, rootSecret) print "Should Fail: ", verify(store, stack, p7) # Sign with key/cert issued by sub CA 2 p7 = sign(sub2KeyFile, sub2CertFile, sub2Secret) print "Should Fail: ", verify(store, stack, p7) # Sign with key/cert issued by sub CA 2 # with the sub CA 2 certificate embedded in the certification chain signerstack = X509.X509_Stack() signerstack.push(ca2Cert) p7 = sign(sub2KeyFile, sub2CertFile, sub2Secret, signerstack) print "Should Fail: ", verify(store, stack, p7) -------------------------------------------------- -- S?bastien Merle