Open
Description
Hi,
First of all I would like to apologize if my issue is redundant, I am not very experienced in xml signatures.
I would like to sign my document with only enveloped-signature as transform
I have based my code on #93 solution
I use this function to sign
const forge = require('node-forge'),
pki = forge.pki,
select = require('xml-crypto').xpath
, dom = require('xmldom').DOMParser
, SignedXml = require('xml-crypto').SignedXml
, FileKeyInfo = require('xml-crypto').FileKeyInfo
, fs = require('fs');
function signXML(){
let sig = new SignedXml()
sig.addReference("//*[local-name(.)='elmo']",[
'http://www.w3.org/2000/09/xmldsig#enveloped-signature',]
//'http://www.w3.org/TR/2001/REC-xml-c14n-20010315'
,'http://www.w3.org/2001/04/xmlenc#sha256',"","","",true)
sig.signingKey = RSA_key
sig.keyInfoProvider = new KeyInfoProvider(RSA_cert)
sig.canonicalizationAlgorithm = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315';
sig.signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
sig.computeSignature(xml )
fs.writeFileSync("signed.xml", sig.getSignedXml())
}
// and this to validate the signed xml
function testValidate(){
var xml = fs.readFileSync("signed.xml").toString()
var doc = new dom().parseFromString(xml)
var signature = select(doc, "//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")
var sig = new SignedXml()
sig.keyInfoProvider = new KeyInfoProvider(fs.readFileSync("client_public.pem"))
sig.loadSignature(signature[0].toString())
var res = sig.checkSignature(xml)
if (!res) console.log(sig.validationErrors)
console.log(res);
return res
}
It shouldn't be relevant I am have taken this from another issue #47 to create the X509Data
function KeyInfoProvider(certificatePEM) {
if (!this instanceof KeyInfoProvider) {
return new KeyInfoProvider();
}
if (Buffer.isBuffer(certificatePEM)) {
certificatePEM = certificatePEM.toString('ascii');
}
if (certificatePEM == null || typeof certificatePEM !== 'string') {
throw new Error('certificatePEM must be a valid certificate in PEM format');
}
this._certificatePEM = certificatePEM;
this.getKeyInfo = function(key, prefix) {
var keyInfoXml,
certObj,
certBodyInB64;
prefix = prefix || '';
prefix = prefix ? prefix + ':' : prefix;
certBodyInB64 = forge.util.encode64(forge.pem.decode(this._certificatePEM)[0].body);
certObj = pki.certificateFromPem(this._certificatePEM);
keyInfoXml = '<' + prefix + 'X509Data>';
keyInfoXml += '<' + prefix + 'X509SubjectName>';
keyInfoXml += getSubjectName(certObj);
keyInfoXml += '</' + prefix + 'X509SubjectName>';
keyInfoXml += '<' + prefix + 'X509Certificate>';
keyInfoXml += certBodyInB64;
keyInfoXml += '</' + prefix + 'X509Certificate>';
keyInfoXml += '</' + prefix + 'X509Data>';
return keyInfoXml;
};
this.getKey = function() {
return this._certificatePEM;
};
}
function getSubjectName(certObj) {
var subjectFields,
fields = ['CN', 'OU', 'O', 'L', 'ST', 'C'];
if (certObj.subject) {
subjectFields = fields.reduce(function(subjects, fieldName) {
var certAttr = certObj.subject.getField(fieldName);
if (certAttr) {
subjects.push(fieldName + '=' + certAttr.value);
}
return subjects;
}, []);
}
return Array.isArray(subjectFields) ? subjectFields.join(',') : '';
}
, but when I run with REC-xml-c14n-20010315 transform everything is ok
but when I remove it from the transforms I get this error:
'invalid signature: for uri calculated digest is 4iuVYZhLYEepzst9YiHiGQmV9mk= but the xml to validate supplies digest 5g4Z1MB1xEH45DlQwOmsxgM1GpA='
It it possible to make signature with only enveloped signature as transform?