robrichards / xmlseclibs

A PHP library for XML Security
BSD 3-Clause "New" or "Revised" License
387 stars 181 forks source link

Append Signature into 'wsse:Security' element with 'BinarySecurityToken' (pubKey) just before <Signature> #114

Closed Overtonesinger closed 7 years ago

Overtonesinger commented 7 years ago

I need to sign only a certain element of the XML - namely . Is there a way to tell the library which element is to be signed?

There is NO example anywhere on the internet - which would actually show how to sign some other element. In all examples on the internet there is only the root element called $doc->documentElement.

And how can I put the signature inside of the 'wsse:Security' element, please? I really really need it. For now I do it manually - using a terrible and very slow set of tweaks and hacks to the string representation of the signed XML! 💯 👍

A more complete example for signing soap messages would be extremely useful on the README website. 👍

My test-code is as follows:

  require_once(__DIR__ . '/vendor/autoload.php');

  use RobRichards\XMLSecLibs\XMLSecurityDSig;
  use RobRichards\XMLSecLibs\XMLSecurityKey;

  function signXML($xml, $element_to_sign = false) {

    $doc = new DOMDocument('1.0','UTF-8');
    $doc->loadXML($xml);
    $objDSig = new XMLSecurityDSig('');
    $objDSig->setCanonicalMethod (XMLSecurityDSig::EXC_C14N );

    if (($element_to_sign===null || $element_to_sign===false || $element_to_sign=="")) {
        $node = $objDSig->addObject( $doc->documentElement );  // Use root element, probably a BAD idea
    }
    else {
        $Body_nodes= $doc->getElementsByTagName('Body');  // There is only ONE such element!
        if ($Body_nodes->length == 0) return false;  // Element  TO BE SIGNED  is NOT found!
        $node = $objDSig->addObject( $Body_nodes->item(0) );  // Is another element possible HERE?   This way or HOW ???
    }

    $objDSig->addReference(
            $node,
            XMLSecurityDSig::SHA256
            );
    $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type'=>'private'));
    // PKEY of TEST-certificate for the developers of the webSvc. client
    $privkey = __DIR__ . '/../certs/04.key.pem';
    $objKey->loadKey($privkey, TRUE);
    $objDSig->sign($objKey);
    $pubkey = __DIR__ . '/../certs/04.crt.pem';  // PUB.KEY of the TEST-certificate
    $objDSig->add509Cert(file_get_contents($pubkey));
    $node->ownerDocument->encoding= 'UTF-8';
    $node->ownerDocument->save( __DIR__ . '/xml_dsig_test.xml');

    return $node->ownerDocument->saveXML();
  }
$x=
<<<XMLHERE
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <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" soap:mustUnderstand="1">
    </wsse:Security>
  </SOAP-ENV:Header>
  <soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-A72D6FD4C41B1F545F14700558808234">
    <Trzba xmlns="http://fs.mfcr.cz/eet/schema/v3">
      <Hlavicka dat_odesl="2016-08-19T19:06:37+02:00" prvni_zaslani="false" uuid_zpravy="05e283e9-e24f-47be-8d3f-be19700f5d0a"/>
      <Data celk_trzba="34113.00" cerp_zuct="679.00" cest_sluz="5460.00" dan1="-172.39" dan2="-530.73" dan3="975.65" dat_trzby="2016-08-05T00:30:12+02:00" dic_popl="CZ00000019" dic_poverujiciho="CZ683555118" id_pokl="/5546/RO24" id_provoz="273" porad_cis="0/6460/ZQ42" pouzit_zboz1="784.00" pouzit_zboz2="967.00" pouzit_zboz3="189.00" rezim="0" urceno_cerp_zuct="324.00" zakl_dan1="-820.92" zakl_dan2="-3538.20" zakl_dan3="9756.46" zakl_nepodl_dph="3036.00"/>
      <KontrolniKody>
        <pkp cipher="RSA2048" digest="SHA256" encoding="base64">n31DY0J+wXqM7b9xFtDn60BYWeXKx1eD701Oec0QvDgKMwfHJ+STps+L1rTQ314+s7Bmzb2DJDGyHqgHCz/mzSeo+vpGluufAjCmRsG+gTszeJDIZR40DFnLd1y00aj5uQP/YMcdm8WJMfEs9fWX29lkXe+3HwWiswse9rExxI3Gpu207fYNvZs56H5tcMdJ6dXIg0j1bRbRMgN4AJyn3lchxzIl8aVvkHYkGM88WxZC/g3zsnXMnWfT/Kua/6TQvVPNaNt1+wP0uEelgCS/JyPGuhZtYuPxWBVtRW3xyr73JuzLRwR33TOEaPhvgAcf7avS4FC8nWktqXoaCxUewQ==</pkp>
        <bkp digest="SHA1" encoding="base16">6DDABC85-4DDEAB38-7DA8D52C-A588BE19-15A0FBA3</bkp>
      </KontrolniKody>
    </Trzba>
  </soap:Body>
</soap:Envelope>
XMLHERE;

  $elem_to_sign= 'soap:Body';
  $out= signXML($x, $elem_to_sign);  // Sign this DAMNED ELEMENT "soap:Body", P L E A S E !!!
  // output the result into linux console:
  echo "Signed XML:\n";
  print $out;  // var_dump did NOT print all 4014 chars

  $target_format_of_XML= <<<GOALXML
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><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" soap:mustUnderstand="1"><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="X509-A72D6FD4C41B1F545F14700558808131">MIID7DCCAtSgAwIBAgIEAQAABDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJDWjEaMBgGA1UEAwwRR0ZSIEVFVCB0ZXN0IENBIDExLTArBgNVBAoMJEdlbmVyw6FsbsOtIGZpbmFuxI1uw60gxZllZGl0ZWxzdHbDrTAeFw0xNjA1MTkxMjQ4MjVaFw0xODA1MTkxMjQ4MjVaMFQxCzAJBgNVBAYTAkNaMRMwEQYDVQQDDApDWjAwMDAwMDE5MRowGAYDVQQKDBFQcsOhdm5pY2vDoSBvc29iYTEUMBIGA1UEBRMLVDAwMDAwMDAwMDQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDFCIfnLl3YjNyxM3y2FAVovKQMetfyyj/lfLY3DoN1z/8gaVRfcqTZbwh9Btg0HafSmrWBvfgjEC/pG9HNawYZ9nPE+WIP9bXkoOfDTmmVtX4n6OLi2Di+U7+FmPJzykV0ujsOsfcGnQ0f63xZYoGJIwLJuz3gmAF//DfnOeTT7OUZeOKobBSYkQOKv1j05QqQZ7HP+5oq7+hNylFrjuEi5OAeVgJAYScE4COvcpqPKpb7OeR9f78knYFffg5zp/6bi6qkP5uGYEuuQvbW1mATjoqbAWz8c7HNA56uNFlz8V+z9bL0f/xwQjgy4d+5qelTX46tq0vJ2XM9dJaF8ytJAgMBAAGjgcEwgb4wHgYDVR0RBBcwFYETZXBvZHBvcmFAZnMubWZjci5jejAfBgNVHSMEGDAWgBR6WvwNy+w2pg3aaRlmjJvvgsOpNDAdBgNVHQ4EFgQU8oKPLNlNY0/h8jWEmz3EZ1O3bBMwTAYDVR0gBEUwQzBBBgpghkgBZQMCATACMDMwMQYIKwYBBQUHAgIwJRojVGVudG8gY2VydGlmaWthdCBKRSBQT1VaRSBURVNUT1ZBQ0kwDgYDVR0PAQH/BAQDAgbAMA0GCSqGSIb3DQEBCwUAA4IBAQBVulEYg6noEHqAW3DfNWLvW9XdHFZQj3L5EE3Nwdd0CtMZm4/RZ/CvSENkk+GWv0YCUqHPJzhcKs0NETMKW7L6CI+hY17rD5SHhuoCYzSMlcuMA6gZJr8wIxSWerQrvuZ4uAUMistWG9cgwETZjkGU9JK+H98wdAm2co7WaRweDsNx04aSXagUMDAmRY/jNe7c8/HvwIdnXftbIl56wbYlYiCIG2qS+6lVO+09EIEP40kz1PXlqFZbPLCSlT2YsYiqizfkCX/Ka+AebJykAQ3pOqD6PQ+Y2AMAIRX8AypcN6Yj9p+oof9rda8boA8rA7wwzlJs/+ipWt2ceqPPuL9x</wsse:BinarySecurityToken><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-A72D6FD4C41B1F545F14700558808305"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="soap"/></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#id-A72D6FD4C41B1F545F14700558808234"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList=""/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>4hn06sSS2yurIiUmWaV36JQJZrwbWf36sG9bOHH/ycM=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>UYlpZoc59wKG/ooAY8qXzTNegAvEDtEtmPq4zZ7sGAkJj2un8EcAeLJgfG+ACVGCv6sW8mHYstmpHAYq24lq9979NhJ5gDnt0pzJ9yvjpt04H9nW7Av5YhwTcHOs47YPboZglclNqi3XGiwmE5CtNCusE++D9bEvBzeF8Ohny1WWkWHmABrnMktqYZFp9cp68Dks30V85T39EvjneKrxjtxNtLdBDHNPlba1t7RbELSRi4WTcwBF3qyk45BfYrvhemLTw41R+DWlTT8Se9G9RAwQbKxYq/aBHE96j2d+afLQUMuVEIxPf6BbE2wHT3UyMYvfQ3zULYjTpnrudw4C+A==</ds:SignatureValue><ds:KeyInfo Id="KI-A72D6FD4C41B1F545F14700558808162"><wsse:SecurityTokenReference 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" wsu:Id="STR-A72D6FD4C41B1F545F14700558808183"><wsse:Reference URI="#X509-A72D6FD4C41B1F545F14700558808131" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature></wsse:Security></SOAP-ENV:Header><soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-A72D6FD4C41B1F545F14700558808234"><Trzba xmlns="http://fs.mfcr.cz/eet/schema/v3"><Hlavicka dat_odesl="2016-08-19T19:06:37+02:00" prvni_zaslani="false" uuid_zpravy="05e283e9-e24f-47be-8d3f-be19700f5d0a"/><Data celk_trzba="34113.00" cerp_zuct="679.00" cest_sluz="5460.00" dan1="-172.39" dan2="-530.73" dan3="975.65" dat_trzby="2016-08-05T00:30:12+02:00" dic_popl="CZ00000019" dic_poverujiciho="CZ683555118" id_pokl="/5546/RO24" id_provoz="273" porad_cis="0/6460/ZQ42" pouzit_zboz1="784.00" pouzit_zboz2="967.00" pouzit_zboz3="189.00" rezim="0" urceno_cerp_zuct="324.00" zakl_dan1="-820.92" zakl_dan2="-3538.20" zakl_dan3="9756.46" zakl_nepodl_dph="3036.00"/><KontrolniKody><pkp cipher="RSA2048" digest="SHA256" encoding="base64">n31DY0J+wXqM7b9xFtDn60BYWeXKx1eD701Oec0QvDgKMwfHJ+STps+L1rTQ314+s7Bmzb2DJDGyHqgHCz/mzSeo+vpGluufAjCmRsG+gTszeJDIZR40DFnLd1y00aj5uQP/YMcdm8WJMfEs9fWX29lkXe+3HwWiswse9rExxI3Gpu207fYNvZs56H5tcMdJ6dXIg0j1bRbRMgN4AJyn3lchxzIl8aVvkHYkGM88WxZC/g3zsnXMnWfT/Kua/6TQvVPNaNt1+wP0uEelgCS/JyPGuhZtYuPxWBVtRW3xyr73JuzLRwR33TOEaPhvgAcf7avS4FC8nWktqXoaCxUewQ==</pkp><bkp digest="SHA1" encoding="base16">6DDABC85-4DDEAB38-7DA8D52C-A588BE19-15A0FBA3</bkp></KontrolniKody></Trzba></soap:Body></soap:Envelope>
GOALXML;
  print "\n\nNEEDED FORMAT:  (Which I call 'IBM Secure-WebService Format')\n\n";
  print $target_format_of_XML;

//--- END ---

robrichards commented 7 years ago

Take a look at the WSSE project especially the node here: https://github.com/robrichards/wse-php/blob/master/src/WSSESoap.php#L220