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

XAdES validation fails with Reference URI=“” for document with stylesheet processing instruction #94

Closed
realtomaszkula opened this issue Dec 30, 2019 · 3 comments · Fixed by PeculiarVentures/xmldsigjs#45

Comments

@realtomaszkula
Copy link

The document I am signing looks like this.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="CDA_PL_IG_1.3.1.xsl" type="text/xsl"?>
<ClinicalDocument></ClinicalDocument>

I am using xadesjs to sign this XML with the following code:

const crypto = new Crypto();
xadesjs.Application.setEngine('NodeJS', crypto);

export async function sign(xml: string, { publicKey, privateKey }: any) {
	const hash = 'SHA-1';
	const alg = {
		name: 'RSASSA-PKCS1-v1_5',
		hash
	};
	const keyDer = pem2der(privateKey.toString());
	const key = await crypto.subtle.importKey('pkcs8', keyDer, alg, true, [ 'sign' ]);
	const parsed = xadesjs.Parse(xml.trim());
	const xadesXml = new xadesjs.SignedXml();
	const signature = await xadesXml.Sign(alg, key, parsed, {
		signingCertificate: preparePem(publicKey.toString()),
		references: [ { uri: '', hash, transforms: [ 'enveloped' ] } ],
		x509: [ preparePem(publicKey.toString()) ]
	});

	parsed.documentElement.appendChild(signature.GetXml()!);
	return parsed.toString();
}

function preparePem(pem: string) {
	return pem.replace(/-----(BEGIN|END)[\w\d\s]+-----/g, '').replace(/[\r\n]/g, '');
}

function pem2der(pem: string) {
	pem = preparePem(pem);
	return new Uint8Array(Buffer.from(pem, 'base64')).buffer;
}

The generated signature is valid only if I remove the xml declaration and stylesheet instruction. So only signing this returns a correctly signed document:

<ClinicalDocument></ClinicalDocument>

Signing this

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="CDA_PL_IG_1.3.1.xsl" type="text/xsl"?>
<ClinicalDocument></ClinicalDocument>

errors with message saying that not the entire document is signed.

I assume the problem is with the URI="" reference. It signs only the <ClinicalDocument> and leaves the <?xml version> and <?xml-stylesheet> with no signature.

I am not sure if this is an issue with the library or the incorrect usage on my part. I've also started related bounty on stackoverflow.

How do I sign everything?

@realtomaszkula
Copy link
Author

realtomaszkula commented Jan 7, 2020

I've traced this issue to the problem with canonicalization of processing instruction in the xmldsigj library. Currently there is a commented out test case dealing with this.

it("2.1 PIs, Comments, and Outside of Document Element", () => {
      const xml = `<?xml version="1.0"?>
            <?xml-stylesheet   href="doc.xsl"
               type="text/xsl"   ?>
            <!DOCTYPE doc SYSTEM "doc.dtd">
            <doc>Hello, world!<!-- Comment 1 --></doc>
            <?pi-without-data     ?>
            <!-- Comment 2 -->
            <!-- Comment 3 -->`;
      const xpath = "//*";
      C14N(xml, xpath, `<?xml-stylesheet href="doc.xsl"
            type="text/xsl"   ?>
         <doc>Hello, world!</doc>
         <?pi-without-data?>`);
    });

Currently the test case is failing by returning only the <doc>Hello, world!</doc> element without the <?xml-stylesheet href="doc.xsl" type="text/xsl" ?>. That would explain why the signature for element with processing instruction ends up invalid.

Am I on the right track? @microshine @alexey-pelykh @rmhrisk

@microshine
Copy link
Contributor

@zetsnotdead Please try a new version of xmldsigjs. I published next version.

npm i xmldsigjs@next

Also, I found that xmldom has got some problems with PI elements parsing. xmldom/xmldom#42

@realtomaszkula
Copy link
Author

I am still seeing the issue.

Testing with:

  • xmldsigjs@2.0.29-next.0
  • xadesjs@2.0.17

I can share the failing xml document privately if you'd like.

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.

2 participants