Как проверить подпись сертификата в pyOpenSSL?

У меня есть два сертификата, root.crt, который использовался для подписи client.crt.

Я хочу убедиться, что client.crt действительно был подписан root.key.

Используя openssl на терминале, это работает так:

$ openssl verify -CAfile root.crt client.crt  
> client.crt: OK  

Однако при использовании pyOpenSSL — следуя документации и эта запись в блоге – я пробовал что-то вроде этого:

client_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, file('client.crt').read())

root_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, file('root.crt').read())  

store = OpenSSL.crypto.X509Store()  
store.add_cert(root_cert)  

ctx = OpenSSL.crypto.X509StoreContext(store, client_cert)
ctx.verify_certificate()  

Я получаю эту ошибку:

    > X509StoreContextError: [2, 1, 'unable to get issuer certificate']

Что мне не хватает?


person joaoricardo000    schedule 03.10.2017    source источник


Ответы (1)


Проблема в том, что мой root.crt на самом деле не root, а цепочка сертификатов:

-----BEGIN CERTIFICATE----- 
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- 
...
-----END CERTIFICATE-----

И OpenSSL.crypto.load_certificate просто загружает первый.

Решение состоит в том, чтобы извлечь все сертификаты из файла цепочки и добавить их в файл X509Store.

Кодовое решение выглядит так:

_PEM_RE = re.compile(b'-----BEGIN CERTIFICATE-----\r?.+?\r?-----END CERTIFICATE-----\r?\n?', re.DOTALL)


def parse_chain(chain):
    # returns a list of certificates
    return [c.group() for c in _PEM_RE.finditer(chain)]


client_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, file('server.crt').read())

store = OpenSSL.crypto.X509Store()
for cert in parse_chain(file('root.crt').read()):
    store.add_cert(OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))

ctx = OpenSSL.crypto.X509StoreContext(store, client_cert)
ctx.verify_certificate()

Адаптировано из https://github.com/hynek/pem/blob/master/src/pem/_core.py#L115

person joaoricardo000    schedule 03.10.2017
comment
Могу я узнать, что такое cr в команде store.add_cert? - person Bogota; 11.06.2020
comment
Обновил пример кода, это опечатка. Спасибо, что заметили! - person joaoricardo000; 12.06.2020