SMIME.smime_load_pkcs7 (_bio): M2Crypto.SMIME.SMIME_Error: нет типа содержимого - PullRequest
1 голос
/ 06 сентября 2011

У меня проблемы с загрузкой файла pkcs # 7 и прошу вашей помощи выяснить, что я делаю неправильно.

Я запускаю M2Crypto-0.21.1 с OpenSSL 0.9.8g (как представлено в Ubuntu 9.4) и собран с SWIG 1.3.36 и python 2.6.2.

«python setup.py test --test-suite = tests.test_smime» запускает 15 тестов со статусом выхода «OK»; так что установка вроде бы в порядке.

Я создал файл pkcs # 7 в формате PEM с помощью программы для цифровой подписи и протестировал его с помощью OpenSSL из командной строки:

openssl smime -verify -inform PEM -in mandato-PEM.p7m -noverify

, который печатает содержимое, содержащееся в конверте (текстовый файл, который я подписал) и «Проверка успешна». Так что OpenSSL (та же версия, что и в M2Crypto), похоже, нравится мой файл.

Тем не менее, когда я пытаюсь сделать то же самое в M2Crypto, он сразу начинает подаваться:

p7, data = SMIME.smime_load_pkcs7 ('mandato-PEM.p7m')

Я получаю следующее исключение:

Traceback (most recent call last):
File "./sign.py", line 110, in <module>
p7, data = SMIME.smime_load_pkcs7('mandato-PEM.p7m') 
File "/usr/local/lib/python2.6/dist-packages/M2Crypto-0.21.1-py2.6-linux-i686.egg/M2Crypto/SMIME.py", line 91, in smime_load_pkcs7
p7_ptr, bio_ptr = m2.smime_read_pkcs7(bio)
M2Crypto.SMIME.SMIME_Error: no content type

Хотя я нашел информацию о проблеме в Ubuntu (https://lists.ubuntu.com/archives/ubuntu-server-bugs/2010-July/038683.html),, мне кажется, что это не может быть применимо здесь, поскольку я собрал последнюю версию M2Crypto вручную, а набор тестов работает нормально.

Любая помощь в решении моей проблемы будет принята с благодарностью!

большое спасибо

-СТРОЙ

Ответы [ 4 ]

2 голосов
/ 09 ноября 2012

Вы также можете проверить файл .p7m (в прикрепленном формате DER) напрямую, но вам нужно загрузить объект PKCS # 7 из формата DER путем прямого вызова m2 в OpenSSL (m2.pkcs7_read_bio_der(input_bio._ptr())), потому что в M2Crypto SMIME для этого нет функциимодуль.Предлагаемый патч см. Маленький патч для SMIME.py .

. Вот пример кода:

import logging

from M2Crypto import SMIME, X509, m2, BIO

certstore_path = "/etc/ssl/certs/ca-certificates.crt"
file_descriptor = open('test_file.p7m', 'rb')
input_bio = BIO.File(file_descriptor)
signer = SMIME.SMIME()
cert_store = X509.X509_Store()
cert_store.load_info(certstore_path)
signer.set_x509_store(cert_store)
try: 
    p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_bio._ptr()), 1)
except SMIME.SMIME_Error, e:
    logging.error('load pkcs7 error: ' + str(e))
sk3 = p7.get0_signers(X509.X509_Stack())
signer.set_x509_stack(sk3)
data_bio = None
try:
    v = signer.verify(p7, data_bio)
except SMIME.SMIME_Error, e:
    logging.error('smime error: ' + str(e))
except SMIME.PKCS7_Error, e:
    logging.error('pkcs7 error: ' + str(e))

Код источника: ядро ​​pysmime

2 голосов
/ 09 сентября 2011

После большого количества пота, здесь решение для тех, кто сталкивался с той же проблемой.

Я следовал рецепту http://code.activestate.com/recipes/285211/ и нашел много обсуждений в сети, которые просто "проверяют (p7) «[метод SMIME] был неправильным и« verify (p7, data) »был правильным решением.

Это относится только к документам SMIME, в которых подпись отсоединена.Мой файл pkcs # 7 и все другие итальянские документы с цифровой подписью представляют собой конверты pkcs # 7, которые содержат как подпись, так и содержимое файла (в формате DER).

Конвертированные файлы p7m должны быть проверены следующим образом:

s=SMIME.SMIME()    
st = X509.X509_Store()   
st.load_info(trustedCAsPEMfileName)    
s.set_x509_store(st)    
p7bio = BIO.MemoryBuffer(p7strPEM)
p7 = SMIME.load_pkcs7_bio(p7bio)
certStack = p7.get0_signers(X509.X509_Stack())
s.set_x509_stack(certStack)
try:
    docContent = s.verify(p7)
except SMIME.PKCS7_Error, e:
    print "An exception occurred!!!!"
    print e

Чтобы проверить, что это работает, я отредактировал файл p7m так, чтобы подпись больше не проверялась, и он правильно печатал «сбой дайджеста».

0 голосов
/ 20 декабря 2018

Если вы хотите извлечь только исходный файл из файла .p7m (без его проверки), вам нужно установить M2Crypto с pip install M2Crypto (вы, вероятно, должны запустить sudo apt-get install libssl-dev раньше), а затем запустить этот код Python:

from M2Crypto import BIO, SMIME, X509

# Load file in memory just to showcase BIO usage
with open('file.p7m', 'rb') as file:
    p7m = file.read()

smime = SMIME.SMIME()
smime.set_x509_store(X509.X509_Store())
smime.set_x509_stack(X509.X509_Stack())
original_file_content = smime.verify(
    SMIME.load_pkcs7_bio_der(BIO.MemoryBuffer(p7m)),
    flags=SMIME.PKCS7_NOVERIFY
)

Вы можете использовать SMIME.load_pkcs7, SMIME.load_pkcs7_bio, SMIME.load_pkcs7_der вместо SMIME.load_pkcs7_bio_der в соответствии с вашим вариантом использования: в памяти (_bio) или в файловой системе .p7m, иPEM или DER (_der) формат.

0 голосов
/ 14 ноября 2012

Лучшая ссылка, которую я нашел для подписи и неподписания, это тесты M2Crypto здесь:

http://svn.osafoundation.org/m2crypto/trunk/tests/test_smime.py

def test_sign(self):
    buf = BIO.MemoryBuffer(self.cleartext)
    s = SMIME.SMIME()
    s.load_key('tests/signer_key.pem', 'tests/signer.pem')
    p7 = s.sign(buf, SMIME.PKCS7_DETACHED)
    assert len(buf) == 0
    assert p7.type() == SMIME.PKCS7_SIGNED, p7.type()
    assert isinstance(p7, SMIME.PKCS7), p7
    out = BIO.MemoryBuffer()
    p7.write(out)

    buf = out.read()

    assert buf[:len('-----BEGIN PKCS7-----')] == '-----BEGIN PKCS7-----'
    buf = buf.strip()
    assert buf[-len('-----END PKCS7-----'):] == '-----END PKCS7-----', buf[-len('-----END PKCS7-----'):]
    assert len(buf) > len('-----END PKCS7-----') + len('-----BEGIN PKCS7-----')

    s.write(out, p7, BIO.MemoryBuffer(self.cleartext))
    return out

def test_verify(self):
    s = SMIME.SMIME()

    x509 = X509.load_cert('tests/signer.pem')
    sk = X509.X509_Stack()
    sk.push(x509)
    s.set_x509_stack(sk)

    st = X509.X509_Store()
    st.load_info('tests/ca.pem')
    s.set_x509_store(st)

    p7, data = SMIME.smime_load_pkcs7_bio(self.signed)

    assert isinstance(p7, SMIME.PKCS7), p7
    v = s.verify(p7, data)
    assert v == self.cleartext

    t = p7.get0_signers(sk)
    assert len(t) == 1
    assert t[0].as_pem() == x509.as_pem(), t[0].as_text()

Будьте внимательны с документацией (http://svn.osafoundation.org/m2crypto/trunk/doc/howto.smime.html), поскольку она не обновлена.

Смотрите этот патч:

https://bugzilla.osafoundation.org/show_bug.cgi?id=13020

...