@@ -566,7 +566,7 @@ def _verify_signature_with_pubkey(self, signed_info_c14n, raw_signature, key_val
566566        if  der_encoded_key_value  is  not None :
567567            key  =  load_der_public_key (b64decode (der_encoded_key_value .text ), backend = default_backend ())
568568        if  "ecdsa-"  in  signature_alg :
569-             if  key_value :
569+             if  key_value   is   not   None :
570570                ec_key_value  =  self ._find (key_value , "ECKeyValue" , namespace = "dsig11" )
571571                named_curve  =  self ._find (ec_key_value , "NamedCurve" , namespace = "dsig11" )
572572                public_key  =  self ._find (ec_key_value , "PublicKey" , namespace = "dsig11" )
@@ -586,7 +586,7 @@ def _verify_signature_with_pubkey(self, signed_info_c14n, raw_signature, key_val
586586                ),
587587            )
588588        elif  "dsa-"  in  signature_alg :
589-             if  key_value :
589+             if  key_value   is   not   None :
590590                dsa_key_value  =  self ._find (key_value , "DSAKeyValue" )
591591                p  =  self ._get_long (dsa_key_value , "P" )
592592                q  =  self ._get_long (dsa_key_value , "Q" )
@@ -602,7 +602,7 @@ def _verify_signature_with_pubkey(self, signed_info_c14n, raw_signature, key_val
602602                       data = signed_info_c14n ,
603603                       algorithm = self ._get_signature_digest_method (signature_alg ))
604604        elif  "rsa-"  in  signature_alg :
605-             if  key_value :
605+             if  key_value   is   not   None :
606606                rsa_key_value  =  self ._find (key_value , "RSAKeyValue" )
607607                modulus  =  self ._get_long (rsa_key_value , "Modulus" )
608608                exponent  =  self ._get_long (rsa_key_value , "Exponent" )
@@ -660,8 +660,8 @@ def _apply_transforms(self, payload, transforms_node, signature, c14n_algorithm)
660660
661661        return  payload 
662662
663-     def  verify (self , data , require_x509 = True , x509_cert = None , cert_subject_name = None , ca_pem_file = None ,  ca_path = None ,
664-                hmac_key = None , validate_schema = True , parser = None , uri_resolver = None ,  cert_resolver = None ,
663+     def  verify (self , data , require_x509 = True , x509_cert = None , cert_subject_name = None , cert_resolver = None ,
664+                ca_pem_file = None ,  ca_path = None ,  hmac_key = None , validate_schema = True , parser = None , uri_resolver = None ,
665665               id_attribute = None , expect_references = 1 , ignore_ambiguous_key_info = False ):
666666        """ 
667667        Verify the XML signature supplied in the data and return the XML node signed by the signature, or raise an 
@@ -704,6 +704,16 @@ def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None
704704            ``None``, requires that the signature supply a valid X.509 certificate chain that validates against the 
705705            known certificate authorities. Implies **require_x509=True**. 
706706        :type x509_cert: string or OpenSSL.crypto.X509 
707+         :param cert_subject_name: 
708+             Subject Common Name to check the signing X.509 certificate against. Implies **require_x509=True**. 
709+         :type cert_subject_name: string 
710+         :param cert_resolver: 
711+             Function to use to resolve trusted X.509 certificates when X509IssuerSerial and X509Digest references are 
712+             found in the signature. The function is called with the keyword arguments ``x509_issuer_name``, 
713+             ``x509_serial_number`` and ``x509_digest``, and is expected to return an iterable of one or more 
714+             strings containing a PEM-formatted certificate and a chain of intermediate certificates, if needed. 
715+             Implies **require_x509=True**. 
716+         :type cert_resolver: callable 
707717        :param ca_pem_file: 
708718            Filename of a PEM file containing certificate authority information to use when verifying certificate-based 
709719            signatures. 
@@ -713,9 +723,6 @@ def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None
713723            certificate-based signatures. If neither **ca_pem_file** nor **ca_path** is given, the Mozilla CA bundle 
714724            provided by :py:mod:`certifi` will be loaded. 
715725        :type ca_path: string 
716-         :param cert_subject_name: 
717-             Subject Common Name to check the signing X.509 certificate against. Implies **require_x509=True**. 
718-         :type cert_subject_name: string 
719726        :param hmac_key: If using HMAC, a string containing the shared secret. 
720727        :type hmac_key: string 
721728        :param validate_schema: Whether to validate **data** against the XML Signature schema. 
@@ -728,12 +735,6 @@ def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None
728735            Function to use to resolve reference URIs that don't start with "#". The function is called with a single 
729736            string argument containing the URI to be resolved, and is expected to return a lxml.etree node or string. 
730737        :type uri_resolver: callable 
731-         :param cert_resolver: 
732-             Function to use to resolve X.509 certificates when X509IssuerSerial and X509Digest references are found in 
733-             the signature. The function is called with the keyword arguments ``x509_issuer_name``, 
734-             ``x509_serial_number`` and ``x509_digest``, and is expected to return an iterable of one or more 
735-             strings containing PEM-formatted certificates. 
736-         :type cert_resolver: callable 
737738        :param id_attribute: 
738739            Name of the attribute whose value ``URI`` refers to. By default, SignXML will search for "Id", then "ID". 
739740        :type id_attribute: string 
@@ -761,7 +762,7 @@ def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None
761762        self .x509_cert  =  x509_cert 
762763        self ._parser  =  parser 
763764
764-         if  x509_cert :
765+         if  x509_cert   or   cert_resolver :
765766            self .require_x509  =  True 
766767
767768        if  id_attribute  is  not None :
@@ -803,15 +804,20 @@ def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None
803804                    x509_iss  =  x509_data .find ("ds:X509IssuerSerial/ds:X509IssuerName" , namespaces = namespaces )
804805                    x509_sn  =  x509_data .find ("ds:X509IssuerSerial/ds:X509SerialNumber" , namespaces = namespaces )
805806                    x509_digest  =  x509_data .find ("dsig11:X509Digest" , namespaces = namespaces )
806-                     if  cert_resolver  is  not None  and  (x509_iss  or  x509_sn  or  x509_digest ):
807-                         certs  =  cert_resolver (x509_issuer_name = x509_iss .text  if  x509_iss  is  not None  else  None ,
808-                                               x509_serial_number = x509_sn .text  if  x509_sn  is  not None  else  None ,
809-                                               x509_digest = x509_digest .text  if  x509_digest  is  not None  else  None )
807+                     if  cert_resolver  and  any (i  is  not None  for  i  in  (x509_iss , x509_sn , x509_digest )):
808+                         cert_chain  =  cert_resolver (x509_issuer_name = x509_iss .text  if  x509_iss  is  not None  else  None ,
809+                                                    x509_serial_number = x509_sn .text  if  x509_sn  is  not None  else  None ,
810+                                                    x509_digest = x509_digest .text  if  x509_digest  is  not None  else  None )
811+                         if  len (cert_chain ) ==  0 :
812+                             raise  InvalidCertificate ("No certificate found for given X509 data" )
813+                         if  not  all (isinstance (c , X509 ) for  c  in  cert_chain ):
814+                             cert_chain  =  [load_certificate (FILETYPE_PEM , add_pem_header (cert )) for  cert  in  cert_chain ]
810815                    else :
811816                        msg  =  "Expected to find an X509Certificate element in the signature" 
812817                        msg  +=  " (X509SubjectName, X509SKI are not supported)" 
813818                        raise  InvalidInput (msg )
814-                 cert_chain  =  [load_certificate (FILETYPE_PEM , add_pem_header (cert )) for  cert  in  certs ]
819+                 else :
820+                     cert_chain  =  [load_certificate (FILETYPE_PEM , add_pem_header (cert )) for  cert  in  certs ]
815821                signing_cert  =  verify_x509_cert_chain (cert_chain , ca_pem_file = ca_pem_file , ca_path = ca_path )
816822            elif  isinstance (self .x509_cert , X509 ):
817823                signing_cert  =  self .x509_cert 
0 commit comments