@@ -600,25 +600,37 @@ def validate_subject_confirmation
600600 # @raise [ValidationError] if soft == false and validation fails
601601 #
602602 def validate_signature
603- fingerprint = settings . get_fingerprint
604- idp_cert = settings . get_idp_cert
603+ error_msg = "Invalid Signature on SAML Response"
605604
606605 # If the response contains the signature, and the assertion was encrypted, validate the original SAML Response
607606 # otherwise, review if the decrypted assertion contains a signature
608- response_signed = REXML ::XPath . first (
607+ sig_elements = REXML ::XPath . match (
609608 document ,
610- "/p:Response[@ID=$id ]" ,
609+ "/p:Response/ds:Signature ]" ,
611610 { "p" => PROTOCOL , "ds" => DSIG } ,
612- { 'id' => document . signed_element_id }
613611 )
614- doc = ( response_signed || decrypted_document . nil? ) ? document : decrypted_document
612+
613+ doc = ( sig_elements . size == 1 || decrypted_document . nil? ) ? document : decrypted_document
614+
615+ # Check signature nodes
616+ if sig_elements . nil? || sig_elements . size == 0
617+ sig_elements = REXML ::XPath . match (
618+ doc ,
619+ "/p:Response/a:Assertion/ds:Signature" ,
620+ { "p" => PROTOCOL , "a" => ASSERTION , "ds" => DSIG }
621+ )
622+ end
623+
624+ if sig_elements . size != 1
625+ return append_error ( error_msg )
626+ end
615627
616628 opts = { }
617629 opts [ :fingerprint_alg ] = settings . idp_cert_fingerprint_algorithm
618- opts [ :cert ] = idp_cert
630+ opts [ :cert ] = settings . get_idp_cert
631+ fingerprint = settings . get_fingerprint
619632
620- unless fingerprint && doc . validate_document ( fingerprint , @soft , opts )
621- error_msg = "Invalid Signature on SAML Response"
633+ unless fingerprint && doc . validate_document ( fingerprint , @soft , opts )
622634 return append_error ( error_msg )
623635 end
624636
0 commit comments