URL: https://github.com/freeipa/freeipa/pull/1110 Author: stlaz Title: #1110: csrgen: Introduce CertificateSigningRequest parameter Action: opened
PR body: """ This pull request tries to introduce a new parameter for CSRs so that these are handled properly in Python 3 and are backward-compatible with the older API which will try to send strings to the server. **NOTE**: tests for the new parameter are currently not included, it's here for the sole purpose of a review of the code and should not be pushed until the tests arrive. - [x] do the code - [ ] do the tests ----------------------- This PR includes code @flo-renaud's fix from https://github.com/freeipa/freeipa/pull/1057 """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/1110/head:pr1110 git checkout pr1110
From 6ce1d9db943327e2a41d91841537802d4381be76 Mon Sep 17 00:00:00 2001 From: Florence Blanc-Renaud <f...@redhat.com> Date: Mon, 11 Sep 2017 18:24:22 +0200 Subject: [PATCH 1/7] py3: fix ipa cert-request --database ... Fix bytes vs str issues in ipa cert-request https://pagure.io/freeipa/issue/7148 --- ipaclient/csrgen.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ipaclient/csrgen.py b/ipaclient/csrgen.py index 3f3ea1cde6..a22ccfb161 100644 --- a/ipaclient/csrgen.py +++ b/ipaclient/csrgen.py @@ -407,11 +407,11 @@ def __init__(self, key_filename, password_filename): self.password_filename = password_filename def key(self): - with open(self.key_filename, 'r') as key_file: + with open(self.key_filename, 'rb') as key_file: key_bytes = key_file.read() password = None if self.password_filename is not None: - with open(self.password_filename, 'r') as password_file: + with open(self.password_filename, 'rb') as password_file: password = password_file.read().strip() key = load_pem_private_key(key_bytes, password, default_backend()) From ca3a33e41681016620b84ebec1fbe90806238434 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka <slazn...@redhat.com> Date: Wed, 20 Sep 2017 10:50:24 +0200 Subject: [PATCH 2/7] csrgen_ffi: pass bytes where "char *" is required In Python 3, "char *" corresponds to bytes rather than string. https://pagure.io/freeipa/issue/7131 --- ipaclient/csrgen_ffi.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ipaclient/csrgen_ffi.py b/ipaclient/csrgen_ffi.py index 2d9b782945..0c9a54b561 100644 --- a/ipaclient/csrgen_ffi.py +++ b/ipaclient/csrgen_ffi.py @@ -196,11 +196,11 @@ def _parse_dn_section(subj, dn_sk): # Skip past any leading X. X: X, etc to allow for multiple instances for idx, c in enumerate(rdn_type): - if c in ':,.': + if c in b':,.': if idx+1 < len(rdn_type): rdn_type = rdn_type[idx+1:] break - if rdn_type.startswith('+'): + if rdn_type.startswith(b'+'): rdn_type = rdn_type[1:] mval = -1 else: @@ -236,7 +236,7 @@ def build_requestinfo(config, public_key_info): raise errors.CSRTemplateError( reason='Error on line %d of config file' % errorline[0]) - dn_sect = NCONF_get_string(reqdata, 'req', 'distinguished_name') + dn_sect = NCONF_get_string(reqdata, b'req', b'distinguished_name') if dn_sect == NULL: raise errors.CSRTemplateError( reason='Unable to find "distinguished_name" key in config') @@ -267,7 +267,7 @@ def build_requestinfo(config, public_key_info): X509V3_set_ctx(ext_ctx, NULL, NULL, req, NULL, 0) X509V3_set_nconf(ext_ctx, reqdata) - extn_section = NCONF_get_string(reqdata, "req", "req_extensions") + extn_section = NCONF_get_string(reqdata, b"req", b"req_extensions") if extn_section != NULL: if not X509V3_EXT_REQ_add_nconf( reqdata, ext_ctx, extn_section, req): From f1ba856d62dcb859cbf33177738c7c2483eee65d Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka <slazn...@redhat.com> Date: Wed, 20 Sep 2017 11:50:26 +0200 Subject: [PATCH 3/7] csrgen: accept public key info as Bytes cert_get_requestdata() method is meant for internal use only and is never passed a file. Make its parameter public_key_info Bytes to better represent what's actually being passed to it. https://pagure.io/freeipa/issue/7131 --- ipaclient/plugins/cert.py | 2 +- ipaclient/plugins/csrgen.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ipaclient/plugins/cert.py b/ipaclient/plugins/cert.py index d5daaf3a15..d7011e67a4 100644 --- a/ipaclient/plugins/cert.py +++ b/ipaclient/plugins/cert.py @@ -132,7 +132,7 @@ def forward(self, csr=None, **options): response = self.api.Command.cert_get_requestdata( profile_id=profile_id, principal=options.get('principal'), - public_key_info=unicode(pubkey_info_b64)) + public_key_info=pubkey_info_b64) req_info_b64 = response['result']['request_info'] req_info = base64.b64decode(req_info_b64) diff --git a/ipaclient/plugins/csrgen.py b/ipaclient/plugins/csrgen.py index d18a90c211..01c75f4bcc 100644 --- a/ipaclient/plugins/csrgen.py +++ b/ipaclient/plugins/csrgen.py @@ -11,7 +11,7 @@ from ipalib import output from ipalib import util from ipalib.frontend import Local, Str -from ipalib.parameters import File, Principal +from ipalib.parameters import Bytes, Principal from ipalib.plugable import Registry from ipalib.text import _ from ipapython import dogtag @@ -52,7 +52,7 @@ class cert_get_requestdata(Local): label=_('Profile ID'), doc=_('CSR Generation Profile to use'), ), - File( + Bytes( 'public_key_info', label=_('Subject Public Key Info'), doc=_('DER-encoded SubjectPublicKeyInfo structure'), From de2f11330fc162b50ddffaa7ba9010ca697f5dd0 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka <slazn...@redhat.com> Date: Wed, 20 Sep 2017 12:29:08 +0200 Subject: [PATCH 4/7] csrgen: update docstring for py3 https://pagure.io/freeipa/issue/7131 --- ipaclient/csrgen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipaclient/csrgen.py b/ipaclient/csrgen.py index a22ccfb161..6fc3495e6b 100644 --- a/ipaclient/csrgen.py +++ b/ipaclient/csrgen.py @@ -396,7 +396,7 @@ def get_subject_public_key_info(self): def sign_csr(self, certification_request_info): """Sign a CertificationRequestInfo. - Returns: str, a DER-encoded signed CSR. + :returns: bytes, a DER-encoded signed CSR. """ raise NotImplementedError('Use a subclass of CSRLibraryAdaptor') From 974501197d8b7c4e29b315a68a4710fa15638aff Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka <slazn...@redhat.com> Date: Wed, 20 Sep 2017 12:32:16 +0200 Subject: [PATCH 5/7] parameters: relax type checks The type checks in ipalib.parameters were too strict. An object that inherits from a type should implement its public interface. This should allow us checking for types of objects whose class implementations are private to a module but they implement a certain public interface (which is typical for e.g. python-cryptography). https://pagure.io/freeipa/issue/7131 --- ipalib/parameters.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ipalib/parameters.py b/ipalib/parameters.py index 81586e2c92..fa0c813a47 100644 --- a/ipalib/parameters.py +++ b/ipalib/parameters.py @@ -848,8 +848,10 @@ def _convert_scalar(self, value, index=None): """ Convert a single scalar value. """ - if type(value) in self.allowed_types: - return value + for t in self.allowed_types: + if isinstance(value, t): + return value + raise ConversionError(name=self.name, error=ugettext(self.type_error)) def validate(self, value, supplied=None): @@ -879,7 +881,10 @@ def validate(self, value, supplied=None): self._validate_scalar(value) def _validate_scalar(self, value, index=None): - if type(value) not in self.allowed_types: + for t in self.allowed_types: + if isinstance(value, t): + break + else: raise TypeError( TYPE_ERROR % (self.name, self.type, value, type(value)) ) From 9d7280757e9db881d760b396ad7e06c358f23ba7 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka <slazn...@redhat.com> Date: Fri, 22 Sep 2017 14:52:36 +0200 Subject: [PATCH 6/7] parameters: introduce CertificateSigningRequest Previously, CSRs were handled as a Str parameter which brought trouble to Python 3 because of its more strict type requirements. We introduce a CertificateSigningRequest parameter which allows to use python-cryptography x509.CertificateSigningRequest to represent CSRs in the framework. https://pagure.io/freeipa/issue/7131 --- API.txt | 2 +- ipaclient/plugins/cert.py | 3 -- ipalib/parameters.py | 45 +++++++++++++++++++++- ipalib/rpc.py | 5 +++ ipaserver/plugins/cert.py | 38 ++++-------------- .../test_xmlrpc/test_caacl_profile_enforcement.py | 4 +- ipatests/test_xmlrpc/test_cert_plugin.py | 10 ++--- 7 files changed, 64 insertions(+), 43 deletions(-) diff --git a/API.txt b/API.txt index 4b06a96923..0526d5a902 100644 --- a/API.txt +++ b/API.txt @@ -783,7 +783,7 @@ option: Str('version?') output: Output('result') command: cert_request/1 args: 1,9,3 -arg: Str('csr', cli_name='csr_file') +arg: CertificateSigningRequest('csr', cli_name='csr_file') option: Flag('add', autofill=True, default=False) option: Flag('all', autofill=True, cli_name='all', default=False) option: Str('cacn?', autofill=True, cli_name='ca', default=u'ipa') diff --git a/ipaclient/plugins/cert.py b/ipaclient/plugins/cert.py index d7011e67a4..0377c511c7 100644 --- a/ipaclient/plugins/cert.py +++ b/ipaclient/plugins/cert.py @@ -143,9 +143,6 @@ def forward(self, csr=None, **options): raise errors.CertificateOperationError( error=(_('Generated CSR was empty'))) - # cert_request requires the CSR to be base64-encoded (but PEM - # header and footer are not required) - csr = unicode(base64.b64encode(csr)) else: if database is not None or private_key is not None: raise errors.MutuallyExclusiveError(reason=_( diff --git a/ipalib/parameters.py b/ipalib/parameters.py index fa0c813a47..5d3bfa9fcb 100644 --- a/ipalib/parameters.py +++ b/ipalib/parameters.py @@ -115,12 +115,14 @@ from ipalib.plugable import ReadOnly, lock from ipalib.errors import ConversionError, RequirementError, ValidationError from ipalib.errors import ( - PasswordMismatch, Base64DecodeError, CertificateFormatError + PasswordMismatch, Base64DecodeError, CertificateFormatError, + CertificateOperationError ) from ipalib.constants import TYPE_ERROR, CALLABLE_ERROR, LDAP_GENERALIZED_TIME_FORMAT from ipalib.text import Gettext, FixMe from ipalib.util import json_serialize, validate_idna_domain -from ipalib.x509 import load_der_x509_certificate, IPACertificate +from ipalib.x509 import ( + load_der_x509_certificate, IPACertificate, default_backend) from ipapython import kerberos from ipapython.dn import DN from ipapython.dnsutil import DNSName @@ -1452,6 +1454,45 @@ def _convert_scalar(self, value, index=None): return super(Certificate, self)._convert_scalar(value) +class CertificateSigningRequest(Param): + type = crypto_x509.CertificateSigningRequest + type_error = _('must be a certificate signing request') + allowed_types = (crypto_x509.CertificateSigningRequest, bytes, unicode) + + def _convert_scalar(self, value, index=None): + """ + :param value: either DER csr or base64 encoded csr + :returns: bytes representing value converted to DER format + """ + if isinstance(value, bytes): + try: + value = value.decode('ascii') + except UnicodeDecodeError: + # value is possibly a DER-encoded csr + pass + + if isinstance(value, unicode): + # if we received unicodes right away or we got them after the + # decoding, we will now try to receive DER-csr + try: + value = base64.b64decode(value) + except (TypeError, ValueError) as e: + raise Base64DecodeError(reason=str(e)) + + if isinstance(value, bytes): + # we now only have either bytes or a CertificateSigningRequest + # object. If it's bytes, make it a CertificateSigningRequest object + try: + value = crypto_x509.load_der_x509_csr( + value, backend=default_backend()) + except ValueError as e: + raise CertificateOperationError( + error=_("Failure decoding Certificate Signing Request: %s") + % e) + + return super(CertificateSigningRequest, self)._convert_scalar(value) + + class Str(Data): """ A parameter for Unicode text (stored in the ``unicode`` type). diff --git a/ipalib/rpc.py b/ipalib/rpc.py index 4b81e89975..c9d47d95ff 100644 --- a/ipalib/rpc.py +++ b/ipalib/rpc.py @@ -197,6 +197,10 @@ def xml_wrap(value, version): return base64.b64encode( value.public_bytes(x509_Encoding.DER)).decode('ascii') + if isinstance(value, crypto_x509.CertificateSigningRequest): + return base64.b64encode( + value.public_bytes(x509_Encoding.DER)).decode('ascii') + assert type(value) in (unicode, float, bool, type(None)) + six.integer_types return value @@ -325,6 +329,7 @@ def __init__(self, version, _identity=_identity): tuple: self._enc_list, dict: self._enc_dict, crypto_x509.Certificate: self._enc_certificate, + crypto_x509.CertificateSigningRequest: self._enc_certificate, }) # int, long for t in six.integer_types: diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py index 202d92dfd5..e465c3a838 100644 --- a/ipaserver/plugins/cert.py +++ b/ipaserver/plugins/cert.py @@ -40,7 +40,8 @@ from ipalib.crud import Create, PKQuery, Retrieve, Search from ipalib.frontend import Method, Object from ipalib.parameters import ( - Bytes, Certificate, DateTime, DNParam, DNSNameParam, Principal + Bytes, Certificate, CertificateSigningRequest, DateTime, DNParam, + DNSNameParam, Principal ) from ipalib.plugable import Registry from .virtual import VirtualCommand @@ -254,22 +255,6 @@ def convert_pkidatetime(value): return x509.format_datetime(value) -def validate_csr(ugettext, csr): - """ - Ensure the CSR is base64-encoded and can be decoded by our PKCS#10 - parser. - """ - if api.env.context == 'cli': - # If we are passed in a pointer to a valid file on the client side - # escape and let the load_files() handle things - if csr and os.path.exists(csr): - return - try: - pkcs10.load_certificate_request(csr) - except (TypeError, ValueError) as e: - raise errors.CertificateOperationError(error=_('Failure decoding Certificate Signing Request: %s') % e) - - def normalize_serial_number(num): """ Convert a SN given in decimal or hexadecimal. @@ -616,11 +601,10 @@ class cert_request(Create, BaseCertMethod, VirtualCommand): attr_name = 'request' takes_args = ( - Str( - 'csr', validate_csr, + CertificateSigningRequest( + 'csr', label=_('CSR'), cli_name='csr_file', - noextrawhitespace=False, ), ) operation="request certificate" @@ -725,13 +709,7 @@ def execute(self, csr, all=False, raw=False, chain=False, **kw): caacl_check(principal, ca, profile_id) try: - csr_obj = pkcs10.load_certificate_request(csr) - except ValueError as e: - raise errors.CertificateOperationError( - error=_("Failure decoding Certificate Signing Request: %s") % e) - - try: - ext_san = csr_obj.extensions.get_extension_for_oid( + ext_san = csr.extensions.get_extension_for_oid( cryptography.x509.oid.ExtensionOID.SUBJECT_ALTERNATIVE_NAME) except cryptography.x509.extensions.ExtensionNotFound: ext_san = None @@ -739,7 +717,7 @@ def execute(self, csr, all=False, raw=False, chain=False, **kw): # Ensure that the DN in the CSR matches the principal # # We only look at the "most specific" CN value - cns = csr_obj.subject.get_attributes_for_oid( + cns = csr.subject.get_attributes_for_oid( cryptography.x509.oid.NameOID.COMMON_NAME) if len(cns) == 0: raise errors.ValidationError(name='csr', @@ -772,7 +750,7 @@ def execute(self, csr, all=False, raw=False, chain=False, **kw): # check email address # # fail if any email addr from DN does not appear in ldap entry - email_addrs = csr_obj.subject.get_attributes_for_oid( + email_addrs = csr.subject.get_attributes_for_oid( cryptography.x509.oid.NameOID.EMAIL_ADDRESS) csr_emails = [attr.value for attr in email_addrs] if not _emails_are_valid(csr_emails, @@ -888,7 +866,7 @@ def execute(self, csr, all=False, raw=False, chain=False, **kw): # re-serialise to PEM, in case the user-supplied data has # extraneous material that will cause Dogtag to freak out # keep it as string not bytes, it is required later - csr_pem = csr_obj.public_bytes( + csr_pem = csr.public_bytes( serialization.Encoding.PEM).decode('utf-8') result = self.Backend.ra.request_certificate( csr_pem, profile_id, ca_id, request_type=request_type) diff --git a/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py index fa474c64ae..2577b4de0b 100644 --- a/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py +++ b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py @@ -53,8 +53,8 @@ def generate_user_csr(username, domain=None): '-config', prepare_config( CERT_OPENSSL_CONFIG_TEMPLATE, csr_values)]) - with open(csr_file.name, 'r') as f: - csr = unicode(f.read()) + with open(csr_file.name, 'rb') as f: + csr = f.read() return csr diff --git a/ipatests/test_xmlrpc/test_cert_plugin.py b/ipatests/test_xmlrpc/test_cert_plugin.py index 0de5b75346..06a008a9ec 100644 --- a/ipatests/test_xmlrpc/test_cert_plugin.py +++ b/ipatests/test_xmlrpc/test_cert_plugin.py @@ -121,7 +121,7 @@ def generateCSR(self, subject): "-f", self.pwname, "-a", ]) - with open(self.reqfile, "r") as fp: + with open(self.reqfile, "rb") as fp: data = fp.read() return data @@ -149,7 +149,7 @@ def test_0001_cert_add(self): # First create the host that will use this policy assert 'result' in api.Command['host_add'](self.host_fqdn, force=True) - csr = unicode(self.generateCSR(str(self.subject))) + csr = self.generateCSR(str(self.subject)) with assert_raises(errors.NotFound): api.Command['cert_request'](csr, principal=self.service_princ) @@ -160,7 +160,7 @@ def test_0002_cert_add(self): # Our host should exist from previous test global cert, sn - csr = unicode(self.generateCSR(str(self.subject))) + csr = self.generateCSR(str(self.subject)) res = api.Command['cert_request'](csr, principal=self.service_princ, add=True)['result'] assert DN(res['subject']) == self.subject assert 'cacn' in res @@ -203,7 +203,7 @@ def test_0006_cert_renew(self): """ global newcert - csr = unicode(self.generateCSR(str(self.subject))) + csr = self.generateCSR(str(self.subject)) res = api.Command['cert_request'](csr, principal=self.service_princ)['result'] assert DN(res['subject']) == self.subject # save the cert for the service_show/find tests @@ -473,7 +473,7 @@ def revoke_cert(self, reason): assert 'result' in api.Command['host_add'](self.host_fqdn, force=True) # generate CSR, request certificate, obtain serial number - self.csr = unicode(self.generateCSR(str(self.subject))) + self.csr = self.generateCSR(str(self.subject)) res = api.Command['cert_request'](self.csr, principal=self.service_princ, add=True, all=True)['result'] From 3719b53975379047b64fc4b06c7323eb01a543d5 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka <slazn...@redhat.com> Date: Mon, 25 Sep 2017 09:18:41 +0200 Subject: [PATCH 7/7] Remove pkcs10 module contents This removes pkcs10 module contents and adds a warning message about its future removal. https://pagure.io/freeipa/issue/7131 --- ipalib/pkcs10.py | 60 ++------------- ipatests/test_pkcs10/__init__.py | 22 ------ ipatests/test_pkcs10/test0.csr | 12 --- ipatests/test_pkcs10/test1.csr | 13 ---- ipatests/test_pkcs10/test2.csr | 15 ---- ipatests/test_pkcs10/test3.csr | 3 - ipatests/test_pkcs10/test4.csr | 4 - ipatests/test_pkcs10/test5.csr | 20 ----- ipatests/test_pkcs10/test_pkcs10.py | 141 ------------------------------------ 9 files changed, 6 insertions(+), 284 deletions(-) delete mode 100644 ipatests/test_pkcs10/__init__.py delete mode 100644 ipatests/test_pkcs10/test0.csr delete mode 100644 ipatests/test_pkcs10/test1.csr delete mode 100644 ipatests/test_pkcs10/test2.csr delete mode 100644 ipatests/test_pkcs10/test3.csr delete mode 100644 ipatests/test_pkcs10/test4.csr delete mode 100644 ipatests/test_pkcs10/test5.csr delete mode 100644 ipatests/test_pkcs10/test_pkcs10.py diff --git a/ipalib/pkcs10.py b/ipalib/pkcs10.py index 39ec95c68a..2756c85682 100644 --- a/ipalib/pkcs10.py +++ b/ipalib/pkcs10.py @@ -1,56 +1,8 @@ -# Authors: -# Rob Crittenden <rcrit...@redhat.com> -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - from __future__ import print_function +import sys -import binascii -from cryptography.hazmat.backends import default_backend -import cryptography.x509 - - -def strip_header(csr): - """ - Remove the header and footer (and surrounding material) from a CSR. - """ - headerlen = 40 - s = csr.find("-----BEGIN NEW CERTIFICATE REQUEST-----") - if s == -1: - headerlen = 36 - s = csr.find("-----BEGIN CERTIFICATE REQUEST-----") - if s >= 0: - e = csr.find("-----END") - csr = csr[s+headerlen:e] - - return csr - - -def load_certificate_request(data): - """ - Load a PEM or base64-encoded PKCS #10 certificate request. - - :return: a python-cryptography ``Certificate`` object. - :raises: ``ValueError`` if unable to load the request - - """ - data = strip_header(data) - try: - data = binascii.a2b_base64(data) - except binascii.Error as e: - raise ValueError(e) - return cryptography.x509.load_der_x509_csr(data, default_backend()) +print( + "ipalib.pkcs10 module is deprecated and will be removed in FreeIPA 4.6. " + "To load CSRs, please, use python-cryptography instead.", + file=sys.stderr +) diff --git a/ipatests/test_pkcs10/__init__.py b/ipatests/test_pkcs10/__init__.py deleted file mode 100644 index cd03658cf9..0000000000 --- a/ipatests/test_pkcs10/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Authors: -# Rob Crittenden <rcrit...@redhat.com> -# -# Copyright (C) 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -""" -Sub-package containing unit tests for `pkcs10` package. -""" diff --git a/ipatests/test_pkcs10/test0.csr b/ipatests/test_pkcs10/test0.csr deleted file mode 100644 index eadfb70b4f..0000000000 --- a/ipatests/test_pkcs10/test0.csr +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -MIIBjjCB+AIBADBPMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEQ -MA4GA1UEChMHRXhhbXBsZTEZMBcGA1UEAxMQdGVzdC5leGFtcGxlLmNvbTCBnzAN -BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyxsN5dmvyKiw+5nyrcO3a61sivZRg+ja -kyNIyUo+tIUiYwTdpPESAHTWRlk0XhydauAkWfOIN7pR3a5Z+kQw8W7F+DuZze2M -6wRNmN+NTrTlqnKOiMHBXhIM0Qxrx68GDctYqtnKTVT94FvvLl9XYVdUEi2ePTc2 -Nyfr1z66+W0CAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBAIf3r+Y6WHrFnttUqDow -9/UCHtCeQlQoJqjjxi5wcjbkGwTgHbx/BPOd/8OVaHElboMXLGaZx+L/eFO6E9Yg -mDOYv3OsibDFGaEhJrU8EnfuFZKnbrGeSC9Hkqrq+3OjqacaPla5N7MHKbfLY377 -ddbOHKzR0sURZ+ro4z3fATW2 ------END NEW CERTIFICATE REQUEST----- - diff --git a/ipatests/test_pkcs10/test1.csr b/ipatests/test_pkcs10/test1.csr deleted file mode 100644 index 0dad3ae1e2..0000000000 --- a/ipatests/test_pkcs10/test1.csr +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -MIIBwDCCASkCAQAwTzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx -EDAOBgNVBAoTB0V4YW1wbGUxGTAXBgNVBAMTEHRlc3QuZXhhbXBsZS5jb20wgZ8w -DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMK+3uy1CGwek8jutw4UO62YTpkmStlw -cKPEjTER7Ra1a1wyWJTo1mMnPhVia0GODeq8ERPgcIckCVogBu8+gL6g8NevaBNv -ij1XWU08BEQqmoqAkrFiI8EdDckKYrSoXo2cg1fiTGzlG8AWtr5eT0op5jBBo0J6 -qXX5Sf6e+n+nAgMBAAGgMTAvBgkqhkiG9w0BCQ4xIjAgMB4GA1UdEQQXMBWCE3Rl -c3Rsb3cuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADgYEAwRDa7ZOaym9mAUH7 -hudbvsRkqXHehgf51uMUq0OC9hQ6vPLWqUMAod05lxn3Tnvq6a/fVK0ybgCH5Ld7 -qpAcUruYdj7YxkFfuBc1dpAK6h94rVsJXFCWIMEZm9Fe7n5RERjhO6h2IRSXBHFz -QIszvqBamm/W1ONKdQSM2g+M4BQ= ------END NEW CERTIFICATE REQUEST----- - diff --git a/ipatests/test_pkcs10/test2.csr b/ipatests/test_pkcs10/test2.csr deleted file mode 100644 index ccc47f8909..0000000000 --- a/ipatests/test_pkcs10/test2.csr +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -MIICETCCAXoCAQAwTzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx -EDAOBgNVBAoTB0V4YW1wbGUxGTAXBgNVBAMTEHRlc3QuZXhhbXBsZS5jb20wgZ8w -DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOXfP8LeiU7g6wLCclgkT1lVskK+Lxm1 -6ijE4LmEQBk5nn2P46im+E/UOgTddbDo5cdJlkoCnqXkO4RkqJckXYDxfI34KL3C -CRFPvOa5Sg02m1x5Rg3boZfS6NciP62lRp0SI+0TCt3F16wYZxMahVIOXjbJ6Lu5 -mGjNn7XaWJhFAgMBAAGggYEwfwYJKoZIhvcNAQkOMXIwcDAeBgNVHREEFzAVghN0 -ZXN0bG93LmV4YW1wbGUuY29tME4GA1UdHwRHMEUwQ6BBoD+GHGh0dHA6Ly9jYS5l -eGFtcGxlLmNvbS9teS5jcmyGH2h0dHA6Ly9vdGhlci5leGFtcGxlLmNvbS9teS5j -cmwwDQYJKoZIhvcNAQEFBQADgYEAkv8pppcgGhX7erJmvg9r2UHrRriuKaOYgKZQ -lf/eBt2N0L2mV4QvCY82H7HWuE+7T3mra9ikfvz0nYkPJQe2gntjZzECE0Jt5LWR -UZOFwX8N6wrX11U2xu0NlvsbjU6siWd6OZjZ1p5/V330lzut/q3CNzaAcW1Fx3wL -sV5SXSw= ------END NEW CERTIFICATE REQUEST----- - diff --git a/ipatests/test_pkcs10/test3.csr b/ipatests/test_pkcs10/test3.csr deleted file mode 100644 index 82c84d1543..0000000000 --- a/ipatests/test_pkcs10/test3.csr +++ /dev/null @@ -1,3 +0,0 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -VGhpcyBpcyBhbiBpbnZhbGlkIENTUg== ------END NEW CERTIFICATE REQUEST----- diff --git a/ipatests/test_pkcs10/test4.csr b/ipatests/test_pkcs10/test4.csr deleted file mode 100644 index 9f08b802b6..0000000000 --- a/ipatests/test_pkcs10/test4.csr +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -Invalidate data ------END NEW CERTIFICATE REQUEST----- - diff --git a/ipatests/test_pkcs10/test5.csr b/ipatests/test_pkcs10/test5.csr deleted file mode 100644 index 41c3c1f3d6..0000000000 --- a/ipatests/test_pkcs10/test5.csr +++ /dev/null @@ -1,20 +0,0 @@ - -Certificate request generated by Netscape certutil -Phone: (not specified) - -Common Name: test.example.com -Email: (not specified) -Organization: IPA -State: (not specified) -Country: (not specified) - ------BEGIN NEW CERTIFICATE REQUEST----- -MIIBaDCB0gIBADApMQwwCgYDVQQKEwNJUEExGTAXBgNVBAMTEHRlc3QuZXhhbXBs -ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPnSCLwl7IytP2HC7+zv -nI2fe6oRCE/J8K1jIoiqS9engx3Yfe4kaXWWzcwmuUV57VhUmWDEQIbSREPdrVSi -tWC55ilGmPOAEw+mP4qg6Ctb+d8Egmy1JVrpIYCLNXvEd3dAaimB0J+K3hKFRyHI -2MzrIuFqqohRijkDLwB8oVVdAgMBAAGgADANBgkqhkiG9w0BAQUFAAOBgQACt37K -j+RMEbqG8s0Uxs3FhcfiAx8Do99CDizY/b7hZEgMyG4dLmm+vSCBbxBrG5oMlxJD -dxnpk0PQSknNkJVrCS/J1OTpOPRTi4VKATT3tHJAfDbWZTwcSelUCLQ4lREiuT3D -WP4vKrLIxDJDb+/mwuV7WWo34E6MD9iTB1xINg== ------END NEW CERTIFICATE REQUEST----- diff --git a/ipatests/test_pkcs10/test_pkcs10.py b/ipatests/test_pkcs10/test_pkcs10.py deleted file mode 100644 index df50df0987..0000000000 --- a/ipatests/test_pkcs10/test_pkcs10.py +++ /dev/null @@ -1,141 +0,0 @@ -# Authors: -# Rob Crittenden <rcrit...@redhat.com> -# -# Copyright (C) 2009 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -""" -Test the `pkcs10.py` module. -""" - -import nose -from ipalib import pkcs10 -from ipapython import ipautil -import pytest -import os -import cryptography.x509 - - -@pytest.mark.tier0 -class test_update(object): - """ - Test the PKCS#10 Parser. - """ - - def setup(self): - self.testdir = os.path.abspath(os.path.dirname(__file__)) - if not ipautil.file_exists(os.path.join(self.testdir, - "test0.csr")): - raise nose.SkipTest("Unable to find test update files") - - def read_file(self, filename): - with open(os.path.join(self.testdir, filename), "r") as fp: - data = fp.read() - return data - - def test_0(self): - """ - Test simple CSR with no attributes - """ - csr = pkcs10.load_certificate_request(self.read_file("test0.csr")) - - subject = csr.subject - - cn = subject.get_attributes_for_oid( - cryptography.x509.NameOID.COMMON_NAME)[-1].value - assert(cn == 'test.example.com') - st = subject.get_attributes_for_oid( - cryptography.x509.NameOID.STATE_OR_PROVINCE_NAME)[-1].value - assert(st == 'California') - c = subject.get_attributes_for_oid( - cryptography.x509.NameOID.COUNTRY_NAME)[-1].value - assert(c == 'US') - - def test_1(self): - """ - Test CSR with subject alt name - """ - csr = self.read_file("test1.csr") - request = pkcs10.load_certificate_request(csr) - - subject = request.subject - - cn = subject.get_attributes_for_oid( - cryptography.x509.NameOID.COMMON_NAME)[-1].value - assert(cn == 'test.example.com') - st = subject.get_attributes_for_oid( - cryptography.x509.NameOID.STATE_OR_PROVINCE_NAME)[-1].value - assert(st == 'California') - c = subject.get_attributes_for_oid( - cryptography.x509.NameOID.COUNTRY_NAME)[-1].value - assert(c == 'US') - - san = request.extensions.get_extension_for_oid( - cryptography.x509.ExtensionOID.SUBJECT_ALTERNATIVE_NAME).value - dns = san.get_values_for_type(cryptography.x509.DNSName) - assert dns[0] == 'testlow.example.com' - - def test_2(self): - """ - Test CSR with subject alt name and a list of CRL distribution points - """ - csr = self.read_file("test2.csr") - request = pkcs10.load_certificate_request(csr) - - subject = request.subject - - cn = subject.get_attributes_for_oid( - cryptography.x509.NameOID.COMMON_NAME)[-1].value - assert(cn == 'test.example.com') - st = subject.get_attributes_for_oid( - cryptography.x509.NameOID.STATE_OR_PROVINCE_NAME)[-1].value - assert(st == 'California') - c = subject.get_attributes_for_oid( - cryptography.x509.NameOID.COUNTRY_NAME)[-1].value - assert(c == 'US') - - san = request.extensions.get_extension_for_oid( - cryptography.x509.ExtensionOID.SUBJECT_ALTERNATIVE_NAME).value - dns = san.get_values_for_type(cryptography.x509.DNSName) - assert dns[0] == 'testlow.example.com' - - crldps = request.extensions.get_extension_for_oid( - cryptography.x509.ExtensionOID.CRL_DISTRIBUTION_POINTS).value - gns = [] - for crldp in crldps: - gns.extend(crldp.full_name) - uris = [ - u'http://ca.example.com/my.crl', - u'http://other.example.com/my.crl', - ] - for uri in uris: - assert cryptography.x509.UniformResourceIdentifier(uri) in gns - - def test_3(self): - """ - Test CSR with base64-encoded bogus data - """ - csr = self.read_file("test3.csr") - - with pytest.raises(ValueError): - pkcs10.load_certificate_request(csr) - - def test_4(self): - """ - Test CSR with badly formatted base64-encoded data - """ - csr = self.read_file("test4.csr") - with pytest.raises(ValueError): - pkcs10.load_certificate_request(csr)
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org