class InovadoraXml::Assinador
Attributes
cert[RW]
errors[RW]
key[RW]
parametro[RW]
tag_assinar[RW]
xml_assinado[RW]
xml_assinar[RW]
Public Class Methods
new(xml, tag_assinar, cert, key)
click to toggle source
# File lib/inovadora_xml/assinador.rb, line 6 def initialize(xml, tag_assinar, cert, key) self.errors = ActiveModel::Errors.new(self) self.xml_assinar = xml.to_s self.tag_assinar = tag_assinar self.cert = cert self.key = key end
Public Instance Methods
assinar_xml()
click to toggle source
# File lib/inovadora_xml/assinador.rb, line 15 def assinar_xml() if self.valid? chave_privada = OpenSSL::PKey::RSA.new(File.read(self.key)) certificado = OpenSSL::X509::Certificate.new(File.read(self.cert)) self.xml_assinado = Nokogiri::XML(self.xml_assinar.to_s, &:noblanks) self.xml_assinado.xpath("//xmlns:#{self.tag_assinar}").each do |node| # 1. Digest Hash for all XML xml_canon = node.canonicalize(Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0) xml_digest = Base64.encode64(OpenSSL::Digest::SHA1.digest(xml_canon)).strip # 2. Add Signature Node signature = Nokogiri::XML::Node.new('Signature', self.xml_assinado) signature.default_namespace = 'http://www.w3.org/2000/09/xmldsig#' node.after(signature) # 3.1 Create Signature Info signature_info = Nokogiri::XML::Node.new('SignedInfo', self.xml_assinado) # 3.2 Add CanonicalizationMethod child_node = Nokogiri::XML::Node.new('CanonicalizationMethod', self.xml_assinado) child_node['Algorithm'] = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315' signature_info.add_child child_node # 3.3 Add SignatureMethod child_node = Nokogiri::XML::Node.new('SignatureMethod', self.xml_assinado) child_node['Algorithm'] = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1' signature_info.add_child child_node # 3.4 Create Reference reference = Nokogiri::XML::Node.new('Reference', self.xml_assinado) reference['URI'] = "##{node.first.last}" # 3.5 Add Transforms transforms = Nokogiri::XML::Node.new('Transforms', self.xml_assinado) child_node = Nokogiri::XML::Node.new('Transform', self.xml_assinado) child_node['Algorithm'] = 'http://www.w3.org/2000/09/xmldsig#enveloped-signature' transforms.add_child child_node child_node = Nokogiri::XML::Node.new('Transform', self.xml_assinado) child_node['Algorithm'] = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315' transforms.add_child child_node reference.add_child transforms # 3.6 Add Digest child_node = Nokogiri::XML::Node.new('DigestMethod', self.xml_assinado) child_node['Algorithm'] = 'http://www.w3.org/2000/09/xmldsig#sha1' reference.add_child child_node # 3.6 Add DigestValue child_node = Nokogiri::XML::Node.new('DigestValue', self.xml_assinado) child_node.content = xml_digest reference.add_child child_node # 3.7 Add Reference and Signature Info signature_info.add_child reference signature.add_child signature_info # 4 Sign Signature sign_canon = signature_info.canonicalize(Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0) signature_hash = chave_privada.sign(OpenSSL::Digest::SHA1.new, sign_canon) signature_value = Base64.encode64(signature_hash).gsub("\n", '') # 4.1 Add SignatureValue child_node = Nokogiri::XML::Node.new('SignatureValue', self.xml_assinado) child_node.content = signature_value signature.add_child child_node # 5 Create KeyInfo key_info = Nokogiri::XML::Node.new('KeyInfo', self.xml_assinado) # 5.1 Add X509 Data and Certificate x509_data = Nokogiri::XML::Node.new('X509Data', self.xml_assinado) x509_certificate = Nokogiri::XML::Node.new('X509Certificate', self.xml_assinado) x509_certificate.content = certificado.to_s.gsub(/\-\-\-\-\-[A-Z]+ CERTIFICATE\-\-\-\-\-/, "").gsub(/\n/,"") x509_data.add_child x509_certificate key_info.add_child x509_data # 5.2 Add KeyInfo signature.add_child key_info end # Return XML self.xml_assinado.canonicalize(Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0) end rescue Exception => e self.errors.add(:base, e.message) ensure return self.errors.blank? end
valid?()
click to toggle source
# File lib/inovadora_xml/assinador.rb, line 110 def valid? self.errors.add(:base, "Chave não informada" ) unless self.key.present? self.errors.add(:base, "Certificado não informado" ) unless self.cert.present? self.errors.add(:base, "Arquivo chave não encontrado") unless File.exists?(self.key.to_s) self.errors.add(:base, "Arquivo certificado não encontrado") unless File.exists?(self.cert.to_s) rescue Exception => e self.errors.add(:base, e.message) ensure return self.errors.blank? end