Class: SignatureDfe::Xml

Inherits:
Object
  • Object
show all
Defined in:
lib/signature_dfe_xml.rb

Class Method Summary collapse

Class Method Details

.build_signature(options = {}) ⇒ Object



9
10
11
12
13
14
15
16
17
# File 'lib/signature_dfe_xml.rb', line 9

def self.build_signature(options = {})
  xml = File.read path('lib/signature_dfe/templates/signature.xml')
  xml.gsub!(':id', options[:id])
  xml.gsub!(':digest_value', options[:digest_value])
  xml.gsub!(':signature_value', options[:signature_value])
  cert = SignatureDfe::SSL.cert.to_s
  cert.to_s.gsub(/-----[A-Z]+ CERTIFICATE-----/, '').strip!
  xml.gsub!(':x509_certificate', cert.strip).gsub(/>\s+</, '><')
end

.build_signed_info(id, digest_value_) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/signature_dfe_xml.rb', line 19

def self.build_signed_info(id, digest_value_)
  signed_info = File.read path('lib/signature_dfe/templates/signed_info.xml')
  signed_info.gsub!(':id', id)
  signed_info.gsub!(':digest_value', digest_value_)
  signed_info_canonized = SignatureDfe::Xml.canonize signed_info
  Base64.encode64(SignatureDfe::SSL.sign(signed_info_canonized)).strip
end

.calc_digest_value(tag, xml) ⇒ Object



3
4
5
6
7
# File 'lib/signature_dfe_xml.rb', line 3

def self.calc_digest_value(tag, xml)
  xml = SignatureDfe::Xml.node(tag, xml)
  note_canonized = SignatureDfe::Xml.canonize_with_ns xml, tag
  Base64.encode64(OpenSSL::Digest::SHA1.digest(note_canonized)).strip
end

.canonize(xml, canonize_method = Nokogiri::XML::XML_C14N_1_1) ⇒ Object



80
81
82
# File 'lib/signature_dfe_xml.rb', line 80

def self.canonize(xml, canonize_method = Nokogiri::XML::XML_C14N_1_1)
  Nokogiri::XML(xml.gsub(/>\s+</, '><')).canonicalize(canonize_method)
end

.canonize_inf_nfe(xml) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/signature_dfe_xml.rb', line 63

def self.canonize_inf_nfe(xml)
  tag_inf_nfe = node('infNFe', xml)
  ns = 'xmlns="http://www.portalfiscal.inf.br/nfe"'
  rxg = Regexp.escape(ns)
  canonize(
    if tag_inf_nfe.include?(rxg.to_s)
      tag_inf_nfe
    else
      tag_inf_nfe.gsub(%(<infNFe), %(<infNFe #{ns}))
    end
  )
end

.canonize_with_ns(xml, tag) ⇒ Object



102
103
104
105
106
107
108
109
110
111
# File 'lib/signature_dfe_xml.rb', line 102

def self.canonize_with_ns(xml, tag)
  ns = %(xmlns="http://www.portalfiscal.inf.br/nfe")
  canonize(
    if xml.include?(ns.to_s)
      xml
    else
      xml.gsub(%(<#{tag}), %(<#{tag} #{ns}))
    end
  )
end

.digest_method_algorithm(xml) ⇒ Object



27
28
29
# File 'lib/signature_dfe_xml.rb', line 27

def self.digest_method_algorithm(xml)
  xml.scan(/(<DigestMethod[\s\S]*?\#)([\s\S]*?)("|')/)[0][1]
end

.get_node_by_namespace_value(value, xml) ⇒ Object



58
59
60
61
# File 'lib/signature_dfe_xml.rb', line 58

def self.get_node_by_namespace_value(value, xml)
  a = xml.match(%r{<[^<]*#{Regexp.escape(value)}[^>]*(>|/>)})[0]
  node(node_name(a), xml)
end

.namespace_value(namespace, xml) ⇒ Object



51
52
53
54
55
56
# File 'lib/signature_dfe_xml.rb', line 51

def self.namespace_value(namespace, xml)
  matches = xml.match(/#{Regexp.escape(namespace)}="([^"]*)/)
  return nil unless matches

  matches[1]
end

.node(name, xml) ⇒ Object



31
32
33
34
# File 'lib/signature_dfe_xml.rb', line 31

def self.node(name, xml)
  r = %r{<#{Regexp.escape(name)}[\s\S]*((/>)|(#{Regexp.escape(name)}>))}
  xml.match(r)[0].gsub(/>\s+</, '><')
end

.node_content(name, xml) ⇒ Object



36
37
38
39
40
41
# File 'lib/signature_dfe_xml.rb', line 36

def self.node_content(name, xml)
  full_node = xml.scan(%r{<#{name}.*?>([\s\S]*?)</#{name}>})
  return nil unless full_node[0]

  full_node[0][0]
end

.node_name(xml) ⇒ Object



43
44
45
# File 'lib/signature_dfe_xml.rb', line 43

def self.node_name(xml)
  xml.scan(%r{<[^/\s>]*})[0].gsub('<', '')
end

.public_cert(xml) ⇒ Object



84
85
86
87
88
89
90
91
92
# File 'lib/signature_dfe_xml.rb', line 84

def self.public_cert(xml)
  x509_certificate = Xml.node_content('X509Certificate', xml)
  x509_certificate = [
    '-----BEGIN CERTIFICATE-----',
    x509_certificate,
    '-----END CERTIFICATE-----'
  ].join("\n")
  OpenSSL::X509::Certificate.new x509_certificate
end

.signed_info_canonized(xml) ⇒ Object



76
77
78
# File 'lib/signature_dfe_xml.rb', line 76

def self.signed_info_canonized(xml)
  canonize(signed_info_with_ns(xml))
end

.signed_info_with_ns(xml) ⇒ Object



94
95
96
97
98
99
100
# File 'lib/signature_dfe_xml.rb', line 94

def self.signed_info_with_ns(xml)
  content = Xml.node 'SignedInfo', xml
  canonize content.gsub(
    '<SignedInfo>',
    %(<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">)
  )
end

.tag(name, xml) ⇒ Object



47
48
49
# File 'lib/signature_dfe_xml.rb', line 47

def self.tag(name, xml)
  xml.scan(%r{<#{name}[\S\s]*?[/>|>]})[0]
end