wrong behaviour of m2crypto compared to openssl
I have to consolidate and possibly rewrite a bunch of bash scripts that verify that incoming smime messages are valid (i.e. encrypted with company's private key and signed a certain set of public keys)
This bunch of bash is going to be replaced by a small application, written possibly in Python with the help of M2Crypto.
Until now, the decryption part is really going well, but I'm having a problem with 开发者_如何学Csignature verification.
I need to write python code that will replace this single bash line
openssl smime -verify -in to_verify.txt -CAfile signer_pubkey.pem -out verified.txt
The content of to_verify.txt is the "usual" multipart/signed p7, that can have the signature attached or not.
The previous command exits with 0 when the verification is successfull and extract the content from the smime envelope.
now, back on python, taken from m2crypto examples:
import os
from M2Crypto import BIO, Rand, SMIME, X509
cert_dir = '/home/niphlod/certs'
doc_dir = '/home/niphlod/datastore'
signer = os.path.join(cert_dir, 'signer_pubkey.pem')
letter = os.path.join(doc_dir,'out_decrypt.txt')
# Instantiate an SMIME object.
s = SMIME.SMIME()
# Load the signer's cert.
x509 = X509.load_cert(signer)
sk = X509.X509_Stack()
sk.push(x509)
s.set_x509_stack(sk)
# Load the signer's CA cert. They're all self-signed, hence the following
st = X509.X509_Store()
st.load_info(signer)
s.set_x509_store(st)
# Load the data, verify it.
p7, data = SMIME.smime_load_pkcs7(letter)
v = s.verify(p7)
print v
print data
print data.read()
Well.... surprise, I get
Traceback (most recent call last):
File "m2crypto_verify.py", line 28, in <module>
v = s.verify(p7)
File "/usr/lib/pymodules/python2.6/M2Crypto/SMIME.py", line 215, in verify
blob = m2.pkcs7_verify0(p7, self.x509_stack._ptr(), self.x509_store._ptr(), flags)
M2Crypto.SMIME.PKCS7_Error: no content
Openssl is reading, extracting and verifying this files correctly, but how can m2crypto report that there is no content ?
BUMP: noone interested in this ?
I've worked around a similar problem using M2Crypto v0.17 by changing the line:
v= s.verify(p7)
to
v = s.verify(p7,data)
Kevin's answer is right.
v = s.verify(p7,data)
The verify() method needs to compare the two parts of the signed message (the plain text against the encrypted one).
This function takes a few argument as mentioned in the M2Crypto doc. It calls openssl PKCS7_verify method documented in OpenSSL's doc. It's unfortunate that M2Crypto's tutorial contains erroneous default values (at least with the v0.20.1 in my environment).
This is the mechanism I'm using for doing S/Mime verification with M2Crypto
# Load the data
#
try:
p7, data = SMIME.smime_load_pkcs7( letter )
except SMIME.SMIME_Error, e:
print 'Error: could not load {file} because {error}'.format(file=letter,error=e)
sys.exit()
# Verify the data
#
try:
if data is not None:
v = s.verify(p7, data)
else:
v = s.verify(p7)
if v:
print 'Client signature verified'
except SMIME.SMIME_Error, e:
print 'Error: message verification failed %s' % e
精彩评论