Class: XMLSecurity::SignedDocument

Inherits:
REXML::Document
  • Object
show all
Defined in:
lib/saml_2_ruby/xml_sec.rb

Instance Method Summary collapse

Instance Method Details

#validate(idp_cert_fingerprint, logger) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/saml_2_ruby/xml_sec.rb', line 39

def validate (idp_cert_fingerprint, logger)
    
  # get cert from response
  base64_cert = self.elements["//X509Certificate"].text
  cert_text = Base64.decode64(base64_cert)
  cert = OpenSSL::X509::Certificate.new(cert_text)
  
  # check cert matches registered idp cert
  fingerprint = Digest::SHA1.hexdigest(cert.to_der)
  logger.info("fingerprint = " + fingerprint) if !logger.nil?
  valid_flag = fingerprint == idp_cert_fingerprint.gsub(":", "").downcase
  
  return valid_flag if !valid_flag 
  
  validate_doc(base64_cert, logger)
end

#validate_doc(base64_cert, logger) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/saml_2_ruby/xml_sec.rb', line 56

def validate_doc(base64_cert, logger)
  
  #        
  #validate references
  #
  
  # remove signature node
  sig_element = XPath.first(self, "//ds:Signature", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"})
  sig_element.remove
  
  #check digests
  logger.info("checking digests") if !logger.nil?
  XPath.each(sig_element, "//ds:Reference", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}) do | ref |          
    uri = ref.attributes.get_attribute("URI").value
    logger.info("URI = " + uri[1,uri.size]) if !logger.nil?
    hashed_element = XPath.first(self, "//[@ID='#{uri[1,uri.size]}']")
    logger.info("hashed element = " + hashed_element.to_s) if !logger.nil?
    canoner = XML::Util::XmlCanonicalizer.new(false, true)
    canon_hashed_element = canoner.canonicalize_element(hashed_element)
    logger.info("canon hashed element = " + canon_hashed_element) if !logger.nil?
    hash = Base64.encode64(Digest::SHA1.digest(canon_hashed_element)).chomp
    digest_value = XPath.first(ref, "//ds:DigestValue", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}).text
    logger.info("hashed_element_hash = " + hash) if !logger.nil?
    logger.info("digest_value_element = " + digest_value) if !logger.nil?
    
    valid_flag = hash == digest_value 
    return valid_flag if !valid_flag
  end
 
  #
  # verify dig sig
  # 
  logger.info("checking dig sig") if !logger.nil?

  # signed_info_element.add_namespace("http://www.w3.org/2000/09/xmldsig#") if signed_info_element.namespace.nil? || signed_info_element.namespace.empty?
  canoner = XML::Util::XmlCanonicalizer.new(false, true)
  signed_info_element = XPath.first(sig_element, "//ds:SignedInfo", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"})
  canon_string = canoner.canonicalize_element(signed_info_element)
  logger.info("canon INFO = " + canon_string) if !logger.nil?

  base64_signature = XPath.first(sig_element, "//ds:SignatureValue", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}).text
  logger.info("base 64 SIG = " + base64_signature) if !logger.nil?
  signature = Base64.decode64(base64_signature)
  logger.info("SIG = " + signature) if !logger.nil?
  
  # get cert object
  cert_text = Base64.decode64(base64_cert)
  cert = OpenSSL::X509::Certificate.new(cert_text)
  
  valid_flag = cert.public_key.verify(OpenSSL::Digest::SHA1.new, signature, canon_string)
    
  return valid_flag
end