SignedXML codeunit

t_craccot_cracco Member Posts: 32
Hi

I'm creating an integration from Business Central (SAAS) with the eHealth platform (Belgium) and I need to sign my created XML with 3 references.
I've created the following xml document (manually with the XML objects):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:be:fgov:ehealth:platformintegrationconsumertest:v1" xmlns:urn1="urn:be:fgov:ehealth:platformintegrationconsumertest:types:v1">
  <soapenv:Header>
    <wsse:Security 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">
      <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" 
								id="BST01">
		certificate in Base64
	  </wsse:BinarySecurityToken>
      <wsu:Timestamp id="TMS01">
        <wsu:Created>2024-02-27T14:01:59.626Z</wsu:Created>
        <wsu:Expires>2024-02-27T14:06:59.626Z</wsu:Expires>
      </wsu:Timestamp>
    </wsse:Security>
  </soapenv:Header>
  <soapenv:Body id="BDY01" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <urn:CheckAccessControlRequest Context="08909DF9F504A430">
      <urn1:Message>Hello World</urn1:Message>
      <urn1:Timestamp>2024-02-27T15:02:00.137+01:00</urn1:Timestamp>
    </urn:CheckAccessControlRequest>
  </soapenv:Body>
</soapenv:Envelope> 

When the xml was created I've used the codeunit SignedXML to sign the created XML document. I need to sign blocs BinarySecurityToken, Timestamp and the body. As I needed to use 3 references and 1 signature value I used the above mentioned codeunit and indicated all information needed by the example from Belgium eHealth.
SignedXml.InitializeSignedXml(XMLDocToSign);

SignedXml.InitializeReference('#BST01'); 
SignedXml.AddXmlDsigExcC14NTransformToReference(''); 
SignedXml.AddReferenceToSignedXML();

SignedXml.InitializeReference('#TMS01'); 
SignedXml.AddXmlDsigExcC14NTransformToReference('wsse soapenv urn urn1'); 
SignedXml.AddReferenceToSignedXML();

SignedXml.InitializeReference('#BDY01'); 
SignedXml.AddXmlDsigExcC14NTransformToReference('urn urn1'); 
SignedXml.AddReferenceToSignedXML();

SignedXml.SetXmlDsigExcC14NTransformAsCanonicalizationMethod('soapenv urn urn1');
SignedXml.SetSignatureMethod(SignedXml.GetXmlDsigRSASHA256Url());

SignedXml.InitializeKeyInfo(); 
xmlElemKeyInfo := XmlElement.Create('KeyInfo'); xmlElemKeyInfo.Add(XmlAttribute.Create('Id', 'KI01'));
xmlElemSecTokenRef := XmlElement.Create('SecurityTokenReference', EHealthNamespaceInfo.xmlns_wsse());
xmlElemSecTokenRef.Add(XmlAttribute.Create('Id', 'KI02'));
xmlElemReference := XmlElement.Create('Reference', EHealthNamespaceInfo.xmlns_wsse());
xmlElemReference.Add(XmlAttribute.Create('URI', '#BST01'));
xmlElemReference.Add(XmlAttribute.Create('ValueType', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3'));
xmlElemSecTokenRef.Add(xmlElemReference);
xmlElemKeyInfo.Add(xmlElemSecTokenRef); 
SignedXml.AddClause(xmlElemSecTokenRef);

SignedXml.InitializeDataObject();
SignedXml.SetSigningKey(eHealthUserSetup.getPrivateKey(), Enum::SignatureAlgorithm::RSA);

SignedXml.ComputeSignature(); xmlElemSignature := SignedXml.GetXml();


After that my signature was added after the "BinarySecurityToken"-tag in the "soapenv:Header"-tag so I ended up with the following XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:be:fgov:ehealth:platformintegrationconsumertest:v1" xmlns:urn1="urn:be:fgov:ehealth:platformintegrationconsumertest:types:v1">
  <soapenv:Header>
    <wsse:Security 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">
      <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" 
								id="BST01">
		certificate in Base 64
	  </wsse:BinarySecurityToken>
      <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
          <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
            <InclusiveNamespaces PrefixList="soapenv urn urn1" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
          </CanonicalizationMethod>
          <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
          <Reference URI="#BST01">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <InclusiveNamespaces PrefixList="" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
              </Transform>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
            <DigestValue>CERg/cYpC6jWB5P14KTLM22rvgNn//WhSp9Rm1X/5+w=</DigestValue>
          </Reference>
          <Reference URI="#TMS01">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <InclusiveNamespaces PrefixList="wsse soapenv urn urn1" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
              </Transform>
              <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
            <DigestValue>6OLAvmYDl06+w1duOba5K0f9VRqgMzWYKyyhRRI+dyY=</DigestValue>
          </Reference>
          <Reference URI="#BDY01">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <InclusiveNamespaces PrefixList="urn urn1" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
              </Transform>
              <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
            <DigestValue>Jc3qklxiLvKuGTWFXhV1RHkhj+uV7mHs4nETwIA7kDc=</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>signature value</SignatureValue>
        <KeyInfo>
          <SecurityTokenReference Id="KI02" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <Reference URI="#BST01" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
          </SecurityTokenReference>
        </KeyInfo>
      </Signature>
      <wsu:Timestamp id="TMS01">
        <wsu:Created>2024-02-27T14:01:59.626Z</wsu:Created>
        <wsu:Expires>2024-02-27T14:06:59.626Z</wsu:Expires>
      </wsu:Timestamp>
    </wsse:Security>
  </soapenv:Header>
  <soapenv:Body id="BDY01" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <urn:CheckAccessControlRequest Context="08909DF9F504A430">
      <urn1:Message>Hello World</urn1:Message>
      <urn1:Timestamp>2024-02-27T15:02:00.137+01:00</urn1:Timestamp>
    </urn:CheckAccessControlRequest>
  </soapenv:Body>
</soapenv:Envelope> 

When I now use a validator to check the generated signature I've get a result where 2 of 3 references are invalid:
Signature is Invalid
Number of Reference Digests = 3
Reference 1 digest is valid.
Reference 2 digest is invalid because the computed digest differs from the digest in the XML.
Reference 3 digest is invalid because the computed digest differs from the digest in the XML.

Can someone help me finding out how to get a correct XMLSignature on 3 references or if someone has experience with the eHealth integration not using the DLLs in Business Central?

Kind Regards
Tom
Sign In or Register to comment.