0

I need to envelope xml in soap message, digest data from original xml and sign it. Actual algorithm of signing or digesting does not matter for now.

Example of original xml:

<TransferMsg>
   <Data>Super Important Data</Data>
</TransferMsg>

Final result must be something like that:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <soap:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="CertId">MIIIRzCCB/agAwIBAgIKSchnBgAAAAGKvDAIBgYqhQMCAgMwggFOMRgwFgYFKoUDZAESDTEwMjc3MDcwMTM4MDYxGjAYBggqhQMDgQMBARIMMDA3NzA3MzE0MDI5MTwwOgYDVQQJDDPQkS7QodGD0YXQsNGA0LXQstGB0LrQuNC5INC/0LXRgCzQtDExLNGB0YLRgDEs0L7RhDYxIzAhBgkqhkiG9w0BCQEWFGUtbW9za3ZhQGUtbW9za3ZhLnJ1MQswCQYDVQQGEwJSVTEcMBoGA1UECAwTNzcg0LMuINCc0L7RgdC60LLQsDEVMBMGA1UEBwwM0JzQvtGB0LrQstCwMTUwMwYDVQQKDCzQntCQ0J4gItCt0LvQtd=</wsse:BinarySecurityToken>
            <ds:Signature>
                <ds:SignedInfo>
                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                    <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"/>
                </ds:SignedInfo>
                <ds:SignatureValue>vnjz04yWa7DbRtC5vJAt/tsCR5m31i3e8FMxG2eOIo4DtsGhm1FgZ8wKLEEzvbYuolrosc2OKkFafqJinsTWsg==</SignatureValue>
                <ds:KeyInfo>
                    <wsse:SecurityTokenReference>
                        <wsse:Reference URI="#CertId" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
            </Signature>
        </wsse:Security>
    </soap:Header>
    <soap:Body wsu:Id="body">
        <soap:TransferMsg>
            <soap:DataToDigest>Super Important Data</soap:DataToDigest>
        </soap:TransferMsg>
    </soap:Body>
</soap:Envelope>

Right now I'm using signer builtin sign! and digest! methods like this:

require 'openssl'
require 'signer'

class MySigner
  def initialize
    @soap_envelope = File.open('./data/soap_envelope.xml') { |f| Nokogiri::XML(f) }
  end

  def sign(xml_to_sign)
    signer = Signer.new(put_in_envelope(xml_to_sign))
    signer.cert = OpenSSL::X509::Certificate.new(File.read("./data/cert.pem"))
    signer.private_key = OpenSSL::PKey.read(File.read("./data/key.pem"), "PASSWORD")
    signer.security_token_id = 'CertId'

    namespaces = {
      'soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
      'ds' => 'http://www.w3.org/2000/09/xmldsig#'
    }

    # Digest soap:Body tag
    signer.document.xpath('//TransferMsg', namespaces).each do |node|
      signer.digest!(node, id: 'body')
    end

    # Sign document itself
    signer.sign!(security_token: true, enveloped: true)

    signer.to_xml
  end

  def put_in_envelope(xml)
    xml_object = Nokogiri::XML(xml)
    valuable_data = xml_object.xpath('/TransferMsg').to_s
    @soap_envelope.xpath('//soap:Body').children.first.add_next_sibling(valuable_data)
    @soap_envelope
  end
end  

soap_envelope.xml:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                   xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                   xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <soap:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    </wsse:Security>
  </soap:Header>
  <soap:Body wsu:Id="body">
  </soap:Body>
</soap:Envelope>

But resulted code has <Signature xmlns='http://www.w3.org/2000/09/xmldsig#'> instead of <ds:Signature>:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <soap:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="CertId">MIIIRzCCB/agAwIBAgIKSchnBgAAAAGKvDAIBgYqhQMCAgMwggFOMRgwFgYFKoUDZAESDTEwMjc3MDcwMTM4MDYxGjAYBggqhQMDgQMBARIMMDA3NzA3MzE0MDI5MTwwOgYDVQQJDDPQkS7QodGD0YXQsNGA0LXQstGB0LrQuNC5INC/0LXRgCzQtDExLNGB0YLRgDEs0L7RhDYxIzAhBgkqhkiG9w0BCQEWFGUtbW9za3ZhQGUtbW9za3ZhLnJ1MQswCQYDVQQGEwJSVTEcMBoGA1UECAwTNzcg0LMuINCc0L7RgdC60LLQsDEVMBMGA1UEBwwM0JzQvtGB0LrQstCwMTUwMwYDVQQKDCzQntCQ0J4gItCt0LvQtd=</wsse:BinarySecurityToken>
            <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/2001/04/xmldsig-more#gostr34102001-gostr3411"/>
                </SignedInfo>
                <SignatureValue>vnjz04yWa7DbRtC5vJAt/tsCR5m31i3e8FMxG2eOIo4DtsGhm1FgZ8wKLEEzvbYuolrosc2OKkFafqJinsTWsg==</SignatureValue>
                <KeyInfo>
                    <wsse:SecurityTokenReference>
                        <wsse:Reference URI="#CertId" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
                    </wsse:SecurityTokenReference>
                </KeyInfo>
            </Signature>
        </wsse:Security>
    </soap:Header>
    <soap:Body wsu:Id="body">
        <soap:TransferMsg>
            <soap:DataToDigest>Super Important Data</soap:DataToDigest>
        </soap:TransferMsg>
    </soap:Body>
</soap:Envelope>

Of course I can manually change Signature node namespace and remove xmlns with nokogiri, but I prefer more automatic way to do it. Am I missing something in the docs?

xvonabur
  • 1
  • 1
  • All those `gist-s` are your code? – Tarvo Mäesepp Aug 19 '16 at 14:12
  • Hello, welcome to SO. Can you please edit your question to include the relevant part of your code? The question should stand on its own, because links rot. Also be sure your question is clearly stated. Right now I'm not sure what it is. – Wayne Conrad Aug 19 '16 at 14:36
  • The link is replaced with code. I've also added more info about the problem. – xvonabur Aug 19 '16 at 15:54

0 Answers0