22
33module RubySaml
44 module XML
5+ # Represents the information extracted from a signed document.
56 class SignedDocumentInfo
67 attr_reader :noko ,
78 :check_malformed_doc
@@ -22,16 +23,10 @@ def validate_document(idp_cert_fingerprint, options = {})
2223 # Get certificate from document
2324 if certificate_object
2425 # Calculate fingerprint using specified algorithm
25- if options [ :fingerprint_alg ]
26- fingerprint = certificate_fingerprint ( options [ :fingerprint_alg ] )
27- else
28- fingerprint = certificate_fingerprint ( 'SHA256' )
29- end
26+ fingerprint = certificate_fingerprint ( options [ :fingerprint_alg ] || 'SHA256' )
3027
3128 # Check cert matches registered idp cert fingerprint
32- if fingerprint != idp_cert_fingerprint . gsub ( /[^a-zA-Z0-9]/ , '' ) . downcase
33- raise RubySaml ::ValidationError . new ( 'Fingerprint mismatch' )
34- end
29+ raise RubySaml ::ValidationError . new ( 'Fingerprint mismatch' ) if fingerprint != idp_cert_fingerprint . gsub ( /[^a-zA-Z0-9]/ , '' ) . downcase
3530
3631 cert = certificate_object
3732 elsif options [ :cert ]
@@ -43,31 +38,25 @@ def validate_document(idp_cert_fingerprint, options = {})
4338 validate_signature ( cert )
4439 end
4540
46- def validate_document_with_cert ( idp_cert = true )
41+ def validate_document_with_cert ( idp_cert )
4742 # Check saml response cert matches provided idp cert
48- if certificate_object &.to_pem &.!=( idp_cert . to_pem )
49- raise RubySaml ::ValidationError . new ( 'Certificate of the Signature element does not match provided certificate' )
50- end
43+ raise RubySaml ::ValidationError . new ( 'Certificate of the Signature element does not match provided certificate' ) if certificate_object &.to_pem &.!=( idp_cert . to_pem )
5144
5245 validate_signature ( idp_cert )
5346 end
5447
5548 def validate_signature ( cert )
5649 # TODO: Remove this
5750 # Get certificate object
58- if cert . is_a? ( String )
59- cert = OpenSSL ::X509 ::Certificate . new ( Base64 . decode64 ( cert ) )
60- end
51+ cert = OpenSSL ::X509 ::Certificate . new ( Base64 . decode64 ( cert ) ) if cert . is_a? ( String )
6152
6253 # Compare digest
6354 calculated_digest = digest_algorithm . digest ( canonicalized_subject )
6455 # puts "calculated_digest: #{calculated_digest.bytes}"
6556 # puts "digest_value: #{digest_value.bytes}"
6657 # puts "subject" + canonicalized_subject.inspect
6758 # puts "\n\n\n\n\n\n"
68- unless calculated_digest == digest_value
69- raise RubySaml ::ValidationError . new ( 'Digest mismatch' )
70- end
59+ raise RubySaml ::ValidationError . new ( 'Digest mismatch' ) unless calculated_digest == digest_value
7160
7261 # puts "signature_hash_algorithm: #{signature_hash_algorithm}"
7362 # puts "signature_value: #{signature_value.bytes}"
@@ -126,6 +115,7 @@ def reference_node
126115 def subject_id
127116 id = uri_from_reference_node || signature_node . parent &.[]( 'ID' )
128117 return id unless !id || id . empty?
118+
129119 raise RubySaml ::ValidationError . new ( 'No signed subject ID found' )
130120 end
131121
@@ -186,6 +176,7 @@ def certificate_text
186176 # @return [OpenSSL::X509::Certificate] The certificate
187177 def certificate_object
188178 return unless certificate_text
179+
189180 OpenSSL ::X509 ::Certificate . new ( certificate_text )
190181 rescue OpenSSL ::X509 ::CertificateError => _e
191182 # TODO: include underlying error
@@ -206,23 +197,19 @@ def certificate_fingerprint(algorithm = 'SHA256')
206197 # Extract inclusive namespaces from the document
207198 # @return [Array<String>, nil] The inclusive namespaces
208199 def inclusive_namespaces
209- @inclusive_namespaces ||= begin
210- noko . at_xpath (
211- '//ec:InclusiveNamespaces' ,
212- { 'ec' => RubySaml ::XML ::C14N }
213- ) &.[]( 'PrefixList' ) &.split
214- end
200+ @inclusive_namespaces ||= noko . at_xpath (
201+ '//ec:InclusiveNamespaces' ,
202+ { 'ec' => RubySaml ::XML ::C14N }
203+ ) &.[]( 'PrefixList' ) &.split
215204 end
216205
217206 private
218207
219208 # Get the ds:Signature element from the document
220209 # @return [Nokogiri::XML::Element] The Signature element
221210 def signature_node
222- @signature_node ||= begin
223- noko . at_xpath ( '//ds:Signature' , { 'ds' => RubySaml ::XML ::DSIG } ) ||
224- ( raise RubySaml ::ValidationError . new ( 'No Signature node found' ) )
225- end
211+ @signature_node ||= noko . at_xpath ( '//ds:Signature' , { 'ds' => RubySaml ::XML ::DSIG } ) ||
212+ ( raise RubySaml ::ValidationError . new ( 'No Signature node found' ) )
226213 end
227214
228215 # Get the ds:SignedInfo element from the document
@@ -246,7 +233,7 @@ def canon_algorithm_from_signed_info
246233
247234 def canon_algorithm_from_transforms
248235 transforms = reference_node . xpath ( './ds:Transforms/ds:Transform' , { 'ds' => RubySaml ::XML ::DSIG } )
249- transform_element = transforms . reverse . detect { |transform_element | transform_element [ 'Algorithm' ] }
236+ transform_element = transforms . reverse . detect { |el | el [ 'Algorithm' ] }
250237 RubySaml ::XML . canon_algorithm ( transform_element , default : false )
251238 end
252239
0 commit comments