diff --git a/signxml/__init__.py b/signxml/__init__.py index a135d30..ff5fcb2 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 @@ -718,11 +726,19 @@ 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)) - - if cert_subject_name and signing_cert.get_subject().commonName != cert_subject_name: - raise InvalidSignature("Certificate subject common name mismatch") + signing_cert = load_certificate(FILETYPE_PEM, + add_pem_header(self.x509_cert)) + comps = signing_cert.get_subject().get_components() + 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): + 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)