Class: Identizer::Saml::Signer

Inherits:
Object
  • Object
show all
Defined in:
lib/identizer/saml/signer.rb

Overview

Enveloped XML-DSig signing (exclusive C14N, RSA-SHA256, SHA-256 digest) of a SAML element. The Signature is inserted right after the element’s Issuer, as the SAML schema requires. Validated against ruby-saml in the specs.

Constant Summary collapse

DS =
"http://www.w3.org/2000/09/xmldsig#"
EXC_C14N =
"http://www.w3.org/2001/10/xml-exc-c14n#"
ENVELOPED =
"http://www.w3.org/2000/09/xmldsig#enveloped-signature"
SHA256 =
"http://www.w3.org/2001/04/xmlenc#sha256"
RSA_SHA256 =
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"

Instance Method Summary collapse

Constructor Details

#initialize(keypair) ⇒ Signer

Returns a new instance of Signer.



17
18
19
# File 'lib/identizer/saml/signer.rb', line 17

def initialize(keypair)
  @keypair = keypair
end

Instance Method Details

#sign!(element) ⇒ Object

Signs ‘element` (a Nokogiri node with an “ID” attribute) in place.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/identizer/saml/signer.rb', line 22

def sign!(element)
  reference_id = element["ID"]
  # Digest is over the element BEFORE the signature exists (enveloped transform).
  digest_value = base64(OpenSSL::Digest::SHA256.digest(canonicalize(element)))

  signature = build_signature(element.document, reference_id, digest_value)
  insert_signature(element, signature)

  # Canonicalize SignedInfo in its FINAL document context, then sign it — the
  # namespace context must match what the verifier sees.
  signed_info = signature.at_xpath("./ds:SignedInfo", "ds" => DS)
  signature_value = base64(@keypair.key.sign(OpenSSL::Digest.new("SHA256"), canonicalize(signed_info)))
  signature.at_xpath("./ds:SignatureValue", "ds" => DS).content = signature_value

  element
end