URL: https://github.com/freeipa/freeipa/pull/360 Author: jcholast Title: #360: x509: use PyASN1 to parse PKCS#7 Action: opened
PR body: """ Use PyASN1 with the PKCS#7 definitions from `pyasn1_modules` to parse PKCS#7 in `pkcs7_to_pems()` instead of calling `openssl pkcs7` in a subprocess. https://fedorahosted.org/freeipa/ticket/6550 """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/360/head:pr360 git checkout pr360
From e795b5d53d1a58ea1247668e13be9b45e0652298 Mon Sep 17 00:00:00 2001 From: Jan Cholasta <jchol...@redhat.com> Date: Wed, 21 Dec 2016 14:05:57 +0100 Subject: [PATCH] x509: use PyASN1 to parse PKCS#7 Use PyASN1 with the PKCS#7 definitions from `pyasn1_modules` to parse PKCS#7 in `pkcs7_to_pems()` instead of calling `openssl pkcs7` in a subprocess. https://fedorahosted.org/freeipa/ticket/6550 --- ipalib/x509.py | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/ipalib/x509.py b/ipalib/x509.py index 851af5a..13327c1 100644 --- a/ipalib/x509.py +++ b/ipalib/x509.py @@ -42,21 +42,13 @@ import cryptography.x509 from pyasn1.type import univ, char, namedtype, tag from pyasn1.codec.der import decoder, encoder -from pyasn1_modules import rfc2459 +from pyasn1_modules import rfc2315, rfc2459 import six from ipalib import api from ipalib import util from ipalib import errors from ipapython.dn import DN -from ipapython import ipautil - -try: - from ipaplatform.paths import paths -except ImportError: - OPENSSL = '/usr/bin/openssl' -else: - OPENSSL = paths.OPENSSL if six.PY3: unicode = str @@ -160,16 +152,38 @@ def pkcs7_to_pems(data, datatype=PEM): Extract certificates from a PKCS #7 object. Return a ``list`` of X.509 PEM strings. + """ + if datatype == PEM: + match = re.match( + r'-----BEGIN PKCS7-----(.*?)-----END PKCS7-----', + data, + re.DOTALL) + if not match: + raise ValueError("not a valid PKCS#7 PEM") - May throw ``ipautil.CalledProcessError`` on invalid data. + data = base64.b64decode(match.group(1)) - """ - cmd = [ - OPENSSL, "pkcs7", "-print_certs", - "-inform", "PEM" if datatype == PEM else "DER", - ] - result = ipautil.run(cmd, stdin=data, capture_output=True) - return PEM_REGEX.findall(result.output) + content_info, tail = decoder.decode(data, rfc2315.ContentInfo()) + if tail: + raise ValueError("not a valid PKCS#7 message") + + if content_info['contentType'] != rfc2315.signedData: + raise ValueError("not a PKCS#7 signed data message") + + signed_data, tail = decoder.decode(bytes(content_info['content']), + rfc2315.SignedData()) + if tail: + raise ValueError("not a valid PKCS#7 signed data message") + + result = [] + + for certificate in signed_data['certificates']: + certificate = encoder.encode(certificate) + certificate = base64.b64encode(certificate) + certificate = make_pem(certificate) + result.append(certificate) + + return result def is_self_signed(certificate, datatype=PEM):
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code