class Xmldsig::Signature

Attributes

signature[RW]

Public Class Methods

new(signature, id_attr = nil, referenced_documents = {}) click to toggle source
# File lib/xmldsig/signature.rb, line 5
def initialize(signature, id_attr = nil, referenced_documents = {})
  @signature = signature
  @id_attr = id_attr
  @referenced_documents = referenced_documents
end

Public Instance Methods

errors() click to toggle source
# File lib/xmldsig/signature.rb, line 17
def errors
  references.flat_map(&:errors) + @errors
end
references() click to toggle source
# File lib/xmldsig/signature.rb, line 11
def references
  @references ||= signature.xpath("descendant::ds:Reference", NAMESPACES).map do |node|
    Reference.new(node, @id_attr, @referenced_documents)
  end
end
sign(private_key = nil, &block) click to toggle source
# File lib/xmldsig/signature.rb, line 21
def sign(private_key = nil, &block)
  references.each { |reference| reference.sign }
  self.signature_value = calculate_signature_value(private_key, &block)
end
signature_value() click to toggle source
# File lib/xmldsig/signature.rb, line 30
def signature_value
  Base64.decode64 signature.at_xpath("descendant::ds:SignatureValue", NAMESPACES).content
end
signed?() click to toggle source
# File lib/xmldsig/signature.rb, line 43
def signed?
  !unsigned?
end
signed_info() click to toggle source
# File lib/xmldsig/signature.rb, line 26
def signed_info
  signature.at_xpath("descendant::ds:SignedInfo", NAMESPACES)
end
unsigned?() click to toggle source
# File lib/xmldsig/signature.rb, line 47
def unsigned?
  self.signature_value.to_s.empty?
end
valid?(certificate = nil, schema = nil, &block) click to toggle source
# File lib/xmldsig/signature.rb, line 34
def valid?(certificate = nil, schema = nil, &block)
  @errors = []
  references.each { |r| r.errors = [] }
  validate_schema(schema)
  validate_digest_values
  validate_signature_value(certificate, &block)
  errors.empty?
end

Private Instance Methods

calculate_signature_value(private_key) { |canonicalized_signed_info, signature_algorithm| ... } click to toggle source
# File lib/xmldsig/signature.rb, line 74
def calculate_signature_value(private_key, &block)
  if private_key
    private_key.sign(signature_method.new, canonicalized_signed_info)
  else
    yield(canonicalized_signed_info, signature_algorithm)
  end
end
canonicalization_method() click to toggle source
# File lib/xmldsig/signature.rb, line 53
def canonicalization_method
  signed_info.at_xpath("descendant::ds:CanonicalizationMethod", NAMESPACES).get_attribute("Algorithm")
end
canonicalized_signed_info() click to toggle source
# File lib/xmldsig/signature.rb, line 57
def canonicalized_signed_info
  Canonicalizer.new(
    signed_info,
    canonicalization_method,
    inclusive_namespaces_for_canonicalization
  ).canonicalize
end
inclusive_namespaces_for_canonicalization() click to toggle source
# File lib/xmldsig/signature.rb, line 65
def inclusive_namespaces_for_canonicalization
  namespaces_node = signed_info.at_xpath(
    'descendant::ds:CanonicalizationMethod/ec:InclusiveNamespaces',
    NAMESPACES
  )
  return unless namespaces_node && namespaces_node.get_attribute('PrefixList')
  namespaces_node.get_attribute('PrefixList').split(/\W+/)
end
signature_algorithm() click to toggle source
# File lib/xmldsig/signature.rb, line 82
def signature_algorithm
  signed_info.at_xpath("descendant::ds:SignatureMethod", NAMESPACES).get_attribute("Algorithm")
end
signature_method() click to toggle source
# File lib/xmldsig/signature.rb, line 86
def signature_method
  algorithm = signature_algorithm && signature_algorithm =~ /sha(.*?)$/i && $1.to_i
  case algorithm
    when 512
      OpenSSL::Digest::SHA512
    when 384
      OpenSSL::Digest::SHA384
    when 256 then
      OpenSSL::Digest::SHA256
    else
      OpenSSL::Digest::SHA1
  end
end
signature_value=(signature_value) click to toggle source
# File lib/xmldsig/signature.rb, line 100
def signature_value=(signature_value)
  signature.at_xpath("descendant::ds:SignatureValue", NAMESPACES).content =
      Base64.strict_encode64(signature_value).chomp
end
validate_digest_values() click to toggle source
# File lib/xmldsig/signature.rb, line 111
def validate_digest_values
  references.each(&:validate_digest_value)
end
validate_schema(schema) click to toggle source
# File lib/xmldsig/signature.rb, line 105
def validate_schema(schema)
  doc = Nokogiri::XML::Document.parse(signature.canonicalize)
  errors = Nokogiri::XML::Schema.new(schema || Xmldsig::XSD_FILE).validate(doc)
  raise Xmldsig::SchemaError.new(errors.first.message) if errors.any?
end
validate_signature_value(certificate) { |signature_value, canonicalized_signed_info, signature_algorithm| ... } click to toggle source
# File lib/xmldsig/signature.rb, line 115
def validate_signature_value(certificate)
  signature_valid = if certificate
    certificate.public_key.verify(signature_method.new, signature_value, canonicalized_signed_info)
  else
    yield(signature_value, canonicalized_signed_info, signature_algorithm)
  end

  unless signature_valid
    @errors << :signature
  end
end