How to sign xml with X509Certificate in Ruby? - ruby-on-rails

I'm trying to sign a xml with a X509Certificate, i'm using the signer gem.
private_key_file = File.join(File.dirname(__FILE__), '/cert/1234567890001_priKEY.pem')
cert_file = File.join(File.dirname(__FILE__), '/cert/1234567890001_certKEY.pem')
input_xml_file = File.join(File.dirname(__FILE__), 'nfce_xml.xml')
signer = Signer.new(File.read(input_xml_file))
signer.cert = OpenSSL::X509::Certificate.new(File.read(cert_file))
signer.private_key = OpenSSL::PKey::RSA.new(File.read(private_key_file), "")
signer.security_node = signer.document.root
signer.security_token_id = ""
signer.digest!(signer.document.root, :id => "NFe51150501882109000162650010000000011064552496", :enveloped => true)
signer.sign!(:issuer_serial => true)
signed_xml = signer.to_xml
File.open("signed.xml", 'w') {|f| f.write(signed_xml) }
the signature:
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#NFe51150501882109000162650010000000011064552496">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>xgvKmWBZeQSt0vue30DzzBvc494=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>DE8BKKsxBAh/zEnX/N/P0f/xOZD7O...</SignatureValue>
<KeyInfo>
<X509Data>
<X509IssuerSerial>
<X509IssuerName>System.Security.Cryptography.X509Certificates.X500DistinguishedName</X509IssuerName>
<X509SerialNumber>2701224559233645315</X509SerialNumber>
</X509IssuerSerial>
<X509Certificate>MIIIHzCCBgegAwIBAgIIJXytbMe...</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
but i need remove the X509IssuerSerial tag, add this transform:
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
and also change CanonicalizationMethod to:
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
Someone can help?
Thanks.

There is not much you can do about format.
Captain obvious suggests to disable issuer_serial in signer.sign!(:issuer_serial => true) to remove the X509IssuerSerial tag?

Related

XML generation using Nokogiri involving nested tags and namespace

Using gem Nokogiri I'm trying to generate XML like:
<?xml version='1.0'?>
<env:Envelope xmln:env = "http://abc.ca">
<env:Header>
<mm7:TransactionID xmlns:mm7="http://def.ca"> Some Text Here </mm7:TransactionID>
</env:Header>
</env:Envelope>
The code I have is:
env_ns = {
"xmlns:env" => "http://abc.ca"
}
mm7_ns = {
"xmlns:mm7" => "http://def.ca"
}
env_header = Nokogiri::XML::Builder.new do |xml|
xml['mm7'].TransactionID(mm7_ns) do
"Some Text Here"
end
end
builder = Nokogiri::XML::Builder.new { |xml|
xml['env'].Envelope(env_ns) do
xml.Header do
env_header
end
end
}
puts env_header.to_xml
puts "----------------------"
puts builder.to_xml
However, the output is not as desired because the value "Some Text Here" did not go inside the mm7:TranactionID tag. The mm7 tag did not go inside the header tag. Also, the header tag did not go inside the envelope tag.
<?xml version="1.0"?>
<mm7:TransactionID xmlns:mm7="http://def.ca"/>
-----------------------------------------------------------
<?xml version="1.0"?>
<env:Envelope xmlns:env="http://abc.ca">
<env:Header/>
</env:Envelope>
Thanks.
You only need 1 builder:
env_ns = {
"xmlns:env" => "http://abc.ca"
}
mm7_ns = {
"xmlns:mm7" => "http://def.ca"
}
builder = Nokogiri::XML::Builder.new do |xml|
xml['env'].Envelope(env_ns) do
xml.Header do
xml['mm7'].TransactionID(mm7_ns, "Some Text Here")
end
end
end
puts builder.to_xml
# will render the following:
# <?xml version="1.0"?>
# <env:Envelope xmlns:env="http://abc.ca">
# <env:Header>
# <mm7:TransactionID xmlns:mm7="http://def.ca">Some Text Here</mm7:TransactionID>
# </env:Header>
# </env:Envelope>

How to nest params using Nokogiri

I want to create XML like this:
<categories>
<category id=1>Sound</category>
<category id=2 parentId=1>Speakers</category>
</categories>
I used:
require 'nokogiri'
#builder = Nokogiri::XML::Builder.new do |xml|
xml.root {
xml.categories{
Category.all.each do |c|
xml.category# here i should insert my needs
end
}
}
end
I used an example from "docs about Tag Attribute Short Cuts" but it gave me class and id instead what I want.
How do I do it properly?
This code will add the id attribute to the category tag:
require 'nokogiri'
#builder = Nokogiri::XML::Builder.new do |xml|
xml.root {
xml.categories{
Category.all.each do |c|
xml.category(c.name, "id" => c.id)
end
}
}
end
Output should be like:
<categories>
<category id=1>Sound</category>
<category id=2>Speakers</category>
</categories

How do I create this element using Nokogiri builder?

I have an element in my XML but I am not sure how to get it generated in Nokogiri::XML::Builder.
<ns0:SearchCondition expressionLanguage='String'expressionType='PartyNumber'>31955854</ns0:SearchCondition>
I tried this:
def test_xml
builder = Nokogiri::XML::Builder.new do |xml|
xml.root {
xml.products {
xml.widget {
xml.id_ "10"
xml.name "Awesome widget"
xml.SearchCondition('expressionLanguage' => 'String', 'expressionType' => 'PartyNumber')
}
}
}
end
puts builder.to_xml
This produces the following
<?xml version="1.0"?>
<root>
<products>
<widget>
<id>10</id>
<name>Awesome widget</name>
<SearchCondition expressionLanguage="String" expressionType="PartyNumber"/>
</widget>
</products>
</root>
But I am not sure how I pass the value to the PartyNumber.
Not sure if this is what you are asking, but you can use the builder text method to create a text element inside another:
xml.SearchCondition('expressionLanguage' => 'String', 'expressionType' => 'PartyNumber') {
xml.text "31955854"
}
You're not using the namespace in your example, but you don't mention that, so I guess that is not an issue.

How to update user status message to IBM Connections (Lotus connection API)?

Ive just read the manual(source:http://www-10.lotus.com/ldd/lcwiki.nsf/dx/Updating_a_status_message_ic301) of Lotus Connection API on updating a status message however I did not find
a sample script on how to update user status message?
I have made a basic Ruby scripts. See below:
url = "https://w3-connections.ibm.com/profiles/atom/mv/theboard/entry/status.do?userid=#{username}"
auth = 'Basic ' + Base64.encode64( "#{username}:#{password}" ).chomp
message = '<entry xmlns="http://www.w3.org/2005/Atom">
<title type="text">Hi!</title>
<category term="entry" scheme="http://www.ibm.com/xmlns/prod/sn/type" />
<category term="status" scheme="http://www.ibm.com/xmlns/prod/sn/message-type" />
<content type="text">Morning! Have a nice day ahead!</content>
</entry>'
resource = RestClient::Resource.new(url, { :headers => { 'Authorization' => auth } } )
response = resource.put message, :content_type => 'application/atom+xml'
puts response.inspect
I'm using RestClient(rest-client (1.6.7)) in Ruby for HTTP Authentication.
However, it didnt work as I expected. The error says "...400 Bad Request (RestClient::BadRequest)"
Is there something I'm missing?
Any help/ideas from you guys would greatly be appreciated. Thanks!
Thanks for the help and suggestion guys. After tinkering an hour, I've successfully made it. Heres the updated code that works!
class IbmConnections
def initialize(username, password)
#username = username
#password = password
end
def post_status_message
require 'rest_client'
atom = "
<entry xmlns='http://www.w3.org/2005/Atom'>
<title type='text'>Hi</title>
<category term='entry' scheme='http://www.ibm.com/xmlns/prod/sn/type' />
<category term='status' scheme='http://www.ibm.com/xmlns/prod/sn/message-type' />
<content type='text'>Morning! Have a nice day ahead!</content>
</entry>"
begin
url = "https://w3-connections.ibm.com/profiles/atom/mv/theboard/entry/status.do"
resource = authenticate url, #username, #password
response = resource.put atom, :content_type => 'application/atom+xml'
if response.empty?
return {:success => 'true', :message => "Successfully update your status!", :data => atom}
else
return {:success => 'false', :message => "Error occurred while posting to Connections! <br /> Please contact the administrator.", :data => atom}
end
rescue => error
logger.debug "Error: IbmConnections.post_it_connections(2)"
logger.debug error.inspect
return {:success => 'false', :message => "Error occurred while posting to Connections! <br /> Please contact the administrator.", :data => error.inspect}
end
end
def authenticate url, username, password
auth = 'Basic ' + Base64.strict_encode64("#{username}:#{password}")
RestClient::Resource.new(url, { :headers => { 'Authorization' => auth } } )
end
end

Magento - adding custom attribute to extended core Customer module

hi have to add a custom attribute to the Customer. so i've extended the core Customer module, these are files involved and directory tree:
//app/code/local/Nauba/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Nauba_Customer>
<version>0.0.1</version>
</Nauba_Customer>
</modules>
<global>
<models>
<customer>
<rewrite>
<customer>Nauba_Customer_Model_Customer</customer>
</rewrite>
</customer>
</models>
</global>
</config>
// app/code/local/Nauba/Customer/Model/Customer.php
class Nauba_Customer_Model_Customer extends Mage_Customer_Model_Customer
{
function _construct()
{
parent::__construct();
}
}
// app/etc/modules/Nauba_Customer.xml
<?xml version="1.0"?>
<config>
<modules>
<Nauba_Customer>
<active>true</active>
<codePool>local</codePool>
</Nauba_Customer>
</modules>
</config>
//app/code/local/Nauba/Customer/sql/nauba_customer_setup/mysql4-upgrade-1.6.2.0.2-1.6.2.0.3.php
$installer = $this;
$installer->startSetup();
/**
* Adding custom attributes to customer
*/
$installer->addAttribute('customer', 'elite_invitation', array(
'label' => 'ID prodotto invito Elite',
'type' => 'varchar',
'visible' => true,
'visible_on_front' => false,
'required' => false,
'backend' => '',
'frontend' => '',
'input' => 'text',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE
));
$installer->endSetup();
Now the module is enabled and new custom model is used instead of core Mage_Customer, but sql upgrade is not executed. any idea of what is wrong?
thanx luke
you must define "resources" in xml under global
<resources>
<nauba_customer_setup>
<setup>
<module>your module name</module>
</setup>
</nauba_customer_setup>
</resources>

Resources