Skip to content

Commit 0d10629

Browse files
committed
Make code beautiful
1 parent 73c8f25 commit 0d10629

File tree

1 file changed

+41
-47
lines changed

1 file changed

+41
-47
lines changed

lib/ruby_saml/xml/document.rb

Lines changed: 41 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,28 @@ class Document < BaseDocument
4343
# <Object />
4444
# </Signature>
4545
def sign_document(private_key, certificate, signature_method = RubySaml::XML::Crypto::RSA_SHA256, digest_method = RubySaml::XML::Crypto::SHA256)
46+
signature_element = build_signature_element(private_key, certificate, signature_method, digest_method)
47+
signature_element = convert_nokogiri_to_rexml(signature_element)
48+
issuer_element = elements['//saml:Issuer']
49+
if issuer_element
50+
root.insert_after(issuer_element, signature_element)
51+
elsif (first_child = root.children[0])
52+
root.insert_before(first_child, signature_element)
53+
else
54+
root.add_element(signature_element)
55+
end
56+
end
57+
58+
private
59+
60+
def build_signature_element(private_key, certificate, signature_method, digest_method)
61+
# Parse the original document
4662
noko = Nokogiri::XML(to_s) do |config|
4763
config.options = RubySaml::XML::BaseDocument::NOKOGIRI_OPTIONS
4864
end
4965

50-
# Create the signature structure using Builder
51-
builder = Nokogiri::XML::Builder.new do |xml|
66+
# Build the Signature element
67+
signature_element = Nokogiri::XML::Builder.new do |xml|
5268
xml['ds'].Signature('xmlns:ds' => RubySaml::XML::Crypto::DSIG) do
5369
xml['ds'].SignedInfo do
5470
xml['ds'].CanonicalizationMethod(Algorithm: RubySaml::XML::Crypto::C14N)
@@ -64,68 +80,46 @@ def sign_document(private_key, certificate, signature_method = RubySaml::XML::Cr
6480
end
6581
end
6682
xml['ds'].DigestMethod(Algorithm: digest_method)
67-
68-
# We'll compute and add DigestValue after creating the structure
69-
xml['ds'].DigestValue
83+
xml['ds'].DigestValue(digest_value(noko, digest_method))
7084
end
7185
end
72-
73-
# We'll add these after the digest computation
74-
xml['ds'].SignatureValue
86+
xml['ds'].SignatureValue # Value is added below
7587
xml['ds'].KeyInfo do
7688
xml['ds'].X509Data do
77-
xml['ds'].X509Certificate
89+
xml['ds'].X509Certificate(certificate_value(certificate))
7890
end
7991
end
8092
end
81-
end
82-
83-
# Extract the signature element from the builder
84-
signature_element = builder.doc.root
85-
86-
# Calculate digest
87-
inclusive_namespaces = INC_PREFIX_LIST.split
88-
canon_doc = noko.canonicalize(RubySaml::XML::Crypto.canon_algorithm(RubySaml::XML::Crypto::C14N), inclusive_namespaces)
89-
digest_value = compute_digest(canon_doc, RubySaml::XML::Crypto.hash_algorithm(digest_method))
90-
91-
digest_value_element = signature_element.at_xpath('//ds:DigestValue', 'ds' => RubySaml::XML::Crypto::DSIG)
92-
digest_value_element.content = digest_value
93-
94-
# Canonicalize the SignedInfo element for signing
95-
signed_info_element = signature_element.at_xpath('//ds:SignedInfo', 'ds' => RubySaml::XML::Crypto::DSIG)
96-
canon_string = signed_info_element.canonicalize(RubySaml::XML::Crypto.canon_algorithm(RubySaml::XML::Crypto::C14N))
97-
signature = compute_signature(private_key, RubySaml::XML::Crypto.hash_algorithm(signature_method).new, canon_string)
93+
end.doc.root
9894

9995
# Set the signature value
96+
signed_info_element = signature_element.at_xpath('//ds:SignedInfo', 'ds' => RubySaml::XML::Crypto::DSIG)
10097
sig_value_element = signature_element.at_xpath('//ds:SignatureValue', 'ds' => RubySaml::XML::Crypto::DSIG)
101-
sig_value_element.content = signature
98+
sig_value_element.content = signature_value(signed_info_element, private_key, signature_method)
10299

103-
# Set the certificate
104-
certificate = OpenSSL::X509::Certificate.new(certificate) if certificate.is_a?(String)
105-
x509_cert_element = signature_element.at_xpath('//ds:X509Certificate', 'ds' => RubySaml::XML::Crypto::DSIG)
106-
x509_cert_element.content = Base64.encode64(certificate.to_der).delete("\n")
100+
signature_element
101+
end
107102

108-
# add the signature
109-
signature_element = convert_nokogiri_to_rexml(signature_element)
110-
issuer_element = elements['//saml:Issuer']
111-
if issuer_element
112-
root.insert_after(issuer_element, signature_element)
113-
elsif (first_child = root.children[0])
114-
root.insert_before(first_child, signature_element)
115-
else
116-
root.add_element(signature_element)
117-
end
103+
def digest_value(document, digest_method)
104+
inclusive_namespaces = INC_PREFIX_LIST.split
105+
canon_algorithm = RubySaml::XML::Crypto.canon_algorithm(RubySaml::XML::Crypto::C14N)
106+
hash_algorithm = RubySaml::XML::Crypto.hash_algorithm(digest_method)
107+
108+
canon_doc = document.canonicalize(canon_algorithm, inclusive_namespaces)
109+
Base64.encode64(hash_algorithm.digest(canon_doc)).strip
118110
end
119111

120-
private
112+
def signature_value(signed_info_element, private_key, signature_method)
113+
canon_algorithm = RubySaml::XML::Crypto.canon_algorithm(RubySaml::XML::Crypto::C14N)
114+
hash_algorithm = RubySaml::XML::Crypto.hash_algorithm(signature_method).new
121115

122-
def compute_signature(private_key, signature_hash_algorithm, document)
123-
Base64.encode64(private_key.sign(signature_hash_algorithm, document)).delete("\n")
116+
canon_string = signed_info_element.canonicalize(canon_algorithm)
117+
Base64.encode64(private_key.sign(hash_algorithm, canon_string)).delete("\n")
124118
end
125119

126-
def compute_digest(document, digest_algorithm)
127-
digest = digest_algorithm.digest(document)
128-
Base64.encode64(digest).strip
120+
def certificate_value(certificate)
121+
certificate = OpenSSL::X509::Certificate.new(certificate) if certificate.is_a?(String)
122+
Base64.encode64(certificate.to_der).delete("\n")
129123
end
130124

131125
# TODO: This is a shim method which will be removed when the

0 commit comments

Comments
 (0)