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

enveloped signature transform without c14n-20010315 workaround #210

Open
Flyingpeanut opened this issue Apr 27, 2020 · 4 comments
Open

enveloped signature transform without c14n-20010315 workaround #210

Flyingpeanut opened this issue Apr 27, 2020 · 4 comments

Comments

@Flyingpeanut
Copy link

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?

@HariAmbadi
Copy link

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

@clucher91
Copy link

Any solutions ? I Have the same problem

@iaguedo
Copy link

iaguedo commented Nov 17, 2022

alguien lo logro soluionar?

@cjbarth
Copy link
Contributor

cjbarth commented May 29, 2023

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants