Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid Signature when using 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315' Canonicalization Algorithm #164

Closed
ruiaraujo1 opened this issue Nov 14, 2018 · 16 comments · Fixed by #183

Comments

@ruiaraujo1
Copy link

ruiaraujo1 commented Nov 14, 2018

Hello,

I'm using this library to sign a SAML Request, but I'm having some issues with the signature when using http://www.w3.org/TR/2001/REC-xml-c14n-20010315 as Canonicalization Algorithm.

The code I'm using is:

const sig = new xmlCrypto.SignedXml();

sig.addReference('//*[local-name(.)=\'AuthnRequest\']',
	['http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#'],
	'http://www.w3.org/2000/09/xmldsig#sha1'
);

sig.signatureAlgorithm = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1';
sig.canonicalizationAlgorithm = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315';
sig.signingKey = params.signingKey;

sig.keyInfoProvider = {
	getKeyInfo: (key, prefix) => {
		return `<${prefix}:X509Data><${prefix}:X509Certificate>${params.signingCert}</${prefix}:X509Certificate></${prefix}:X509Data>`;
	}
};

sig.computeSignature(xml, {
	location: {
		reference: '//*[local-name(.)=\'Issuer\']',
		action: 'after'
	},
	prefix: 'ds'
});

return sig.getSignedXml();

Can you please enlight me on what I might be doing wrong?

Thanks,
Rui

@LoneRifle
Copy link
Collaborator

LoneRifle commented Dec 12, 2018

Could you try doing this with version 1.0.1 of xml-crypto and see if that works? Could you also provide the xml that you were trying to sign and the error message you got in return?

@ruiaraujo1
Copy link
Author

@LoneRifle The error persists on version 1.0.1.

The server i'm connecting to tells me the signature is invalid.

@LoneRifle
Copy link
Collaborator

Can you provide the xml that you were trying to sign and the full error message that you got in return? any information relating to what the server actually is, as well as any stack traces, the exact error text etc, would be useful

@LoneRifle
Copy link
Collaborator

I've recently released version 1.1.1 of the library that appears to address a similar problem. Can you try that library and see what happens?

@ruiaraujo1
Copy link
Author

Hello @LoneRifle ,

Sorry for delay on the response.

I've updated the lib to the 1.1.1 version but the problem still persists.

Please, find enclosed the SAMLRequest I'm sending and SAMLResponse I'm getting.

Thanks for all your help.

Error_SAMLRequest.txt
Error_SAMLResponse.txt

@LoneRifle
Copy link
Collaborator

LoneRifle commented Jan 13, 2019

I've validated the SAML request against https://www.samltool.com/validate_authn_req.php and it appears that the request is actually valid. There are a couple of things we can do here:

if you are using passport-saml, #149 suggests that there may be an additional option you have to turn on in order for canonicalization to work properly. You could also use xmlsec to dissect the request before and after signing to see if the output is intended. See if that helps.

if the request is being sent to https://preprod.autenticacao.gov.pt/fa/Default.aspx , it would be useful for me to know what they are using on their end, to see if there is anything between xml-crypto and the service that I have to cater to.

@LoneRifle
Copy link
Collaborator

LoneRifle commented Jan 13, 2019

Also, could you perhaps look through the releases page at https://github.com/yaronn/xml-crypto/releases and see if there are any fixes or patches that you need? I can port those over to 0.x and release them. Otherwise just use 0.10.1 =)

@ruiaraujo1
Copy link
Author

I'm not using passport-saml, I'm sending the request directly.

Unfortunately I cannot know what the IdP I'm trying to authenticate is using.

In the next days, I'll test the releases you mentioned and get back to you.

@ruiaraujo1
Copy link
Author

Hello @LoneRifle

With the versions you mentioned, the problem still persists.

@LoneRifle
Copy link
Collaborator

Can I confirm that you also tried with 0.10.1? If so, that would imply that xml-crypto had this problem even before I was part of the project, and I would probably have to troubleshoot this with your identity provider to see what exactly is going wrong. If this is the case, this will take me a long while.

@ruiaraujo1
Copy link
Author

Yes, i've tried with the version 0.10.1 and the problem persists.

It would be great if you could solve the problem, but in the meantime I've surpassed the issue using a different canonicalization algorithm. I've just identified the issue because the "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" was the recommend algorithm for the IdP I'm using, although they support anothers.

Thanks for your help and.

LoneRifle added a commit that referenced this issue Jan 28, 2019
PR #163 modifies the root node, which may be a problem when creating
the signature value, which uses a dummy signature wrapper. Revert
first, investigate later.

This attempts to quick fix #167 and #164

This reverts commit a0de707.
@LoneRifle
Copy link
Collaborator

Hello, I recently released 1.1.2 of xml-crypto - would you be able to test this with http://www.w3.org/TR/2001/REC-xml-c14n-20010315 again and see what happens?

@ruiaraujo1
Copy link
Author

Hello @LoneRifle,

Thanks for your attention but the problem still persists with this version. The IdP still returns an "Invalid Signature" error.

@LoneRifle
Copy link
Collaborator

I've just noticed that you were using the enveloped-signature transform, which had a bug introduced by me and which was only resolved in #174 (as 1.1.4). Would you be happy to try canonicalization again with this release?

@ruiaraujo1
Copy link
Author

Hello @LoneRifle ,

First, thanks for your consideration on trying to solve this issue!

I have updated to version 1.1.4 and made a new test, but unfortunately the IdP still returns an "Invalid Signature" error :/

@feliposz
Copy link

feliposz commented Mar 20, 2019

Hi there,

I guess I'm experiencing a similar problem.

Here is the code I'm using based on the example provided (I'm also using certificates from the example):

var select = require('xml-crypto').xpath
  , dom = require('xmldom').DOMParser
  , SignedXml = require('xml-crypto').SignedXml
  , FileKeyInfo = require('xml-crypto').FileKeyInfo
  , fs = require('fs')

function signXml(xml, xpath, key, dest) {
  var sig = new SignedXml()
  sig.signingKey = fs.readFileSync(key)

  // not working:
  sig.canonicalizationAlgorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
  sig.signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
  sig.addReference(xpath, ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"])

  // working:
  // sig.addReference(xpath)

  sig.computeSignature(xml)
  fs.writeFileSync(dest, sig.getSignedXml())
}

function validateXml(xml, key) {
  var doc = new dom().parseFromString(xml)
  var signature = select(doc, "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0]
  var sig = new SignedXml()
  sig.keyInfoProvider = new FileKeyInfo(key)
  sig.loadSignature(signature.toString())
  var res = sig.checkSignature(xml)
  if (!res) console.log(sig.validationErrors)
  return res;
}

var xml = '<ns1:ReqConsultaNotas ' +
              'xmlns:ns1="http://localhost:8080/WsNFe2/lote" ' +
              'xmlns:tipos="http://localhost:8080/WsNFe2/tp" ' +
              'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
              'xsi:schemaLocation="http://localhost:8080/WsNFe2/lote http://localhost:8080/WsNFe2/xsd/ReqConsultaNotas.xsd">' +
            '<Cabecalho Id="Consulta:notas">' +
              '<CodCidade>7145</CodCidade>' +
              '<CPFCNPJRemetente>29525566000119</CPFCNPJRemetente>' +
              '<InscricaoMunicipalPrestador>000356721</InscricaoMunicipalPrestador>' +
              '<dtInicio>2019-01-01</dtInicio>' +
              '<dtFim>2019-02-01</dtFim>' +
              '<NotaInicial>1</NotaInicial>' +
              '<Versao>1</Versao>' +
            '</Cabecalho>' +
          '</ns1:ReqConsultaNotas>'

//sign an xml document
signXml(xml,
  "//*[@Id='Consulta:notas']",
  "client.pem",
  "result.xml")

console.log("xml signed succesfully")

var signedXml = fs.readFileSync("result.xml").toString()
console.log("validating signature...")

//validate an xml document
if (validateXml(signedXml, "client_public.pem"))
  console.log("signature is valid")
else
  console.log("signature not valid")

The signing/validation works fine for the default algorithms but the validation fails when using REC-xml-c14n-20010315.

Result is:

[ 'invalid signature: for uri #Consulta:notas calculated digest is cKQcfT1V+I6Lbfk6JSixHR/hPNg= but the xml to validate supplies digest AySau/TndphdIGBJqVRB6RgOAdY=' ]

I'm new to XML Signature and maybe I'm doing something wrong, but I can't figure out what it is. I've been trying to debug xml-crypto and it appears to be something related to the way getCanonXml is called with c14nOptions in validateSignatureValue and validateReferences and without it in createReferences.

Any help would be much appreciated.

Thanks,
Felipo

PS: I'm using 1.2.0 but have also tried other versions (1.0.1, 1.1.1, 1.1.4) as suggested with no success.

My package.json:

{
  "name": "xml-crypto-test",
  "version": "1.0.0",
  "description": "",
  "main": "example.js",
  "dependencies": {
    "node-forge": "^0.8.2",
    "xml-crypto": "^1.2.0",
    "xmldom": "^0.1.27"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

vadimavdeev added a commit to vadimavdeev/xml-crypto that referenced this issue Apr 25, 2019
…fying

When computing the signature, ancestor namespaces of SignedInfo and
reference node were not passed into the 'getCanonXml' method like
they were during signature verification

This attempts to fix node-saml#164
LoneRifle pushed a commit that referenced this issue Apr 26, 2019
…fying (#183)

When computing the signature, ancestor namespaces of SignedInfo and
reference node were not passed into the 'getCanonXml' method like
they were during signature verification

This attempts to fix #164
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants