From 878bcdebd546a5f92940f6d9e8c726a3f6adab39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Thu, 6 Sep 2018 11:07:47 +0000 Subject: [PATCH 1/5] get serialNumber from subject --- signxml/__init__.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/signxml/__init__.py b/signxml/__init__.py index a135d30..8d83f76 100644 --- a/signxml/__init__.py +++ b/signxml/__init__.py @@ -591,9 +591,17 @@ def _apply_transforms(self, payload, transforms_node, signature, c14n_algorithm) return payload - def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None, ca_pem_file=None, ca_path=None, - hmac_key=None, validate_schema=True, parser=None, uri_resolver=None, id_attribute=None, - expect_references=1): + def _get_serial_number(self, comps, serial): + for v in comps: + if len(v) == 2 \ + and v[0].decode('utf-8') in 'serialNumber' \ + and v[1].decode('utf-8') in serial: + return True + return False + + def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None, cert_subject_serial=None, + ca_pem_file=None, ca_path=None, hmac_key=None, validate_schema=True, parser=None, + uri_resolver=None, id_attribute=None, expect_references=1): """ Verify the XML signature supplied in the data and return the XML node signed by the signature, or raise an exception if the signature is not valid. By default, this requires the signature to be generated using a valid @@ -719,8 +727,10 @@ def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None signing_cert = self.x509_cert else: signing_cert = load_certificate(FILETYPE_PEM, add_pem_header(self.x509_cert)) - - if cert_subject_name and signing_cert.get_subject().commonName != cert_subject_name: + comps = signing_cert.get_subject().get_components() + has_serial = self._get_serial_number(comps, cert_subject_serial) + if (cert_subject_name and signing_cert.get_subject().commonName != cert_subject_name) \ + or not (cert_subject_serial and has_serial): raise InvalidSignature("Certificate subject common name mismatch") signature_digest_method = self._get_signature_digest_method(signature_alg).name From 2f203c6215174a06782a50be0a8dafa33262fbb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Thu, 6 Sep 2018 12:27:19 +0000 Subject: [PATCH 2/5] fix lint errors --- signxml/__init__.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/signxml/__init__.py b/signxml/__init__.py index 8d83f76..870cfba 100644 --- a/signxml/__init__.py +++ b/signxml/__init__.py @@ -593,9 +593,9 @@ def _apply_transforms(self, payload, transforms_node, signature, c14n_algorithm) def _get_serial_number(self, comps, serial): for v in comps: - if len(v) == 2 \ - and v[0].decode('utf-8') in 'serialNumber' \ - and v[1].decode('utf-8') in serial: + if len(v) == 2 and \ + v[0].decode('utf-8') in 'serialNumber' and \ + v[1].decode('utf-8') in serial: return True return False @@ -726,13 +726,16 @@ def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None elif isinstance(self.x509_cert, X509): signing_cert = self.x509_cert else: - signing_cert = load_certificate(FILETYPE_PEM, add_pem_header(self.x509_cert)) + signing_cert = load_certificate(FILETYPE_PEM, + add_pem_header(self.x509_cert)) comps = signing_cert.get_subject().get_components() - has_serial = self._get_serial_number(comps, cert_subject_serial) - if (cert_subject_name and signing_cert.get_subject().commonName != cert_subject_name) \ - or not (cert_subject_serial and has_serial): - raise InvalidSignature("Certificate subject common name mismatch") - + has_serial = self._get_serial_number(comps, + cert_subject_serial) + if (cert_subject_name and + signing_cert.get_subject().commonName != cert_subject_name) \ + or not (cert_subject_serial and has_serial): + raise InvalidSignature('Certificate subject ' + 'common name mismatch') signature_digest_method = self._get_signature_digest_method(signature_alg).name try: verify(signing_cert, raw_signature, signed_info_c14n, signature_digest_method) From bdf7ccf68cadc71f900611166dfdb0b1f710364f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Thu, 6 Sep 2018 13:02:20 +0000 Subject: [PATCH 3/5] better serial validation --- signxml/__init__.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/signxml/__init__.py b/signxml/__init__.py index 8d83f76..e44b099 100644 --- a/signxml/__init__.py +++ b/signxml/__init__.py @@ -593,9 +593,9 @@ def _apply_transforms(self, payload, transforms_node, signature, c14n_algorithm) def _get_serial_number(self, comps, serial): for v in comps: - if len(v) == 2 \ - and v[0].decode('utf-8') in 'serialNumber' \ - and v[1].decode('utf-8') in serial: + if len(v) == 2 and \ + v[0].decode('utf-8') in 'serialNumber' and \ + v[1].decode('utf-8') in serial: return True return False @@ -726,13 +726,16 @@ def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None elif isinstance(self.x509_cert, X509): signing_cert = self.x509_cert else: - signing_cert = load_certificate(FILETYPE_PEM, add_pem_header(self.x509_cert)) + signing_cert = load_certificate(FILETYPE_PEM, + add_pem_header(self.x509_cert)) comps = signing_cert.get_subject().get_components() - has_serial = self._get_serial_number(comps, cert_subject_serial) - if (cert_subject_name and signing_cert.get_subject().commonName != cert_subject_name) \ - or not (cert_subject_serial and has_serial): - raise InvalidSignature("Certificate subject common name mismatch") - + has_serial = self._get_serial_number(comps, + cert_subject_serial) + if (cert_subject_name and + signing_cert.get_subject().commonName != cert_subject_name) \ + or (cert_subject_serial and has_serial is False): + raise InvalidSignature('Certificate subject ' + 'common name mismatch') signature_digest_method = self._get_signature_digest_method(signature_alg).name try: verify(signing_cert, raw_signature, signed_info_c14n, signature_digest_method) From 73ff43d6705230f82d5d5cc8af5f0187f2dac720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Thu, 6 Sep 2018 13:05:34 +0000 Subject: [PATCH 4/5] fix typo --- signxml/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/signxml/__init__.py b/signxml/__init__.py index 135858f..e44b099 100644 --- a/signxml/__init__.py +++ b/signxml/__init__.py @@ -734,7 +734,6 @@ def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None if (cert_subject_name and signing_cert.get_subject().commonName != cert_subject_name) \ or (cert_subject_serial and has_serial is False): - or not (cert_subject_serial and has_serial): raise InvalidSignature('Certificate subject ' 'common name mismatch') signature_digest_method = self._get_signature_digest_method(signature_alg).name From 780fcf5fac25b80b6d71367662a690be9f627dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3n=20Levy?= Date: Thu, 6 Sep 2018 13:13:01 +0000 Subject: [PATCH 5/5] proper checks for cert_subject_serial parameter --- signxml/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/signxml/__init__.py b/signxml/__init__.py index e44b099..ff5fcb2 100644 --- a/signxml/__init__.py +++ b/signxml/__init__.py @@ -729,8 +729,11 @@ def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None signing_cert = load_certificate(FILETYPE_PEM, add_pem_header(self.x509_cert)) comps = signing_cert.get_subject().get_components() - has_serial = self._get_serial_number(comps, - cert_subject_serial) + if not cert_subject_serial: + has_serial = False + else: + has_serial = self._get_serial_number(comps, cert_subject_serial) + if (cert_subject_name and signing_cert.get_subject().commonName != cert_subject_name) \ or (cert_subject_serial and has_serial is False):