xml-crypto icon indicating copy to clipboard operation
xml-crypto copied to clipboard

enveloped signature transform without c14n-20010315 workaround

Open Flyingpeanut opened this issue 4 years ago • 4 comments

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?

Flyingpeanut avatar Apr 27 '20 11:04 Flyingpeanut

I am also facing this exact issue. It it possible to make sign and verify with only enveloped signature as transform algorithm?

Any help on this will be highly appreciated

HariAmbadi avatar Oct 15 '20 05:10 HariAmbadi

Any solutions ? I Have the same problem

clucher91 avatar Oct 01 '22 13:10 clucher91

alguien lo logro soluionar?

iaguedo avatar Nov 17 '22 17:11 iaguedo

Off hand, I don't know if what you're asking for is possible, but if you created a PR with a test that fails that clearly shows what you're after, it will speed up the process of getting a fix and will ensure that the feature/fix that you're after stays working. @Flyingpeanut , @HariAmbadi , @clucher91 or @iaguedo would any of you be willing to do that?

cjbarth avatar May 29 '23 23:05 cjbarth