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

How to include <X509Certificate> in the signature? #47

Closed
whirp opened this issue Mar 30, 2015 · 8 comments
Closed

How to include <X509Certificate> in the signature? #47

whirp opened this issue Mar 30, 2015 · 8 comments

Comments

@whirp
Copy link

whirp commented Mar 30, 2015

I've signed my xml with this code :

var sig = new 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", "", "", "", true)
 sig.signingKey = fs.readFileSync("./config/saml.key");
sig.computeSignature(xml_authnRequest);
return sig.getSignedXml();

But i don't know how to put the element <keyinfo> and <X509Certificate> in the signature-
Would you please help me?

@yaronn
Copy link
Contributor

yaronn commented Mar 31, 2015

xml-crypto automatically puts them for you in the signature. If you want to add them in a different format you can implement your own 'key info provider' (the readme contains explanation).

@giulianoifollow
Copy link

Hi,

I have the same info on xml output but when follow your example (README) nothing happens. I'm trying like this:

function MyKeyInfo() {
    this.getKeyInfo = function(key) {
        return "<X509Data></X509Data>"
    };
    this.getKey = function(keyInfo) {
        return fs.readFileSync("file.pub", 'utf-8');
    };
}
var xml = fs.readFileSync('./nfse/xml.xml', 'utf8');

var sig = new SignedXml();
sig.keyInfoProvider = new MyKeyInfo();
sig.addReference("//*[local-name(.)='InfNfse']");
sig.signingKey = fs.readFileSync("file.pem");
sig.computeSignature(xml);
fs.writeFileSync("signed.xml", sig.getSignedXml());

With code above we get:

<KeyInfo>
      <X509Data/>
</KeyInfo>

But need somehing like:

<KeyInfo>
        <X509Data>
          <X509Certificate>
            MIIIWjCCBkKgAwIBAgIQZWsH7xnbsvLrhvPOQQeIKzANBgkqhkiG9w0BAQsFADB4MQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE2MDQGA1UECxMtU2VjcmV0YXJpYSBkYSBSZWNlaXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMRwwGgYDVQQDExNBQyBDZXJ0aXNpZ24gUkZCIEc0MB4XDTE1MDEwNjAwMDAwMFoXDTE2MDEwNTIzNTk1OVowgfExCzAJBgNVBAYTAkJSMRMwEQYDVQQKFApJQ1AtQnJhc2lsMQswCQYDVQQIEwJSUzEVMBMGA1UEBxQMUG9ydG8gQWxlZ3JlMTYwNAYDVQQLFC1TZWNyZXRhcmlhIGRhIFJlY2VpdGEgRmVkZXJhbCBkbyBCcmFzaWwgLSBSRkIxFjAUBgNVBAsUDVJGQiBlLUNOUEogQTExJjAkBgNVBAsUHUF1dGVudGljYWRvIHBvciBBUiBCREkgQnJhc2lsMTEwLwYDVQQDEyhNVU5JQ0lQSU8gREUgUE9SVE8gQUxFR1JFOjkyOTYzNTYwMDAwMTYwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnOjUFzmmGowLglM+OBz+uonXJBZBpX5MRM1mFhFBJHbWFa3H8pdopOhwjx28WYj2v+tefTyDHjT+TwlEJ90LzfvXOGdARsDJd5YXxLTd15r7KB+9cojJk2LtDHqmVO5MHhECDBXJiBenYEtWTXWB6dioyg1H6gqNwOUlMKh9vGwSEC5+TmBTVixk7cjiA39P3BTCxtmweJODcgJmTJNBH8Xd+INGqegBdz5iSZCdTzMz8B3xUYIEHYj1zMhRltx89IfLrGtSuo7B3QtjLeKNGp8OZ8ObyZX1/0BSMienc/dRe7kZO7xJmETd4GTIMC/3JJHb8iJvFLSXy6d6lnOA8QIDAQABo4IDZDCCA2AwgckGA1UdEQSBwTCBvqA9BgVgTAEDBKA0BDIyNDEwMTk1NTIwMDQzNDY1MDcyMDAwMDAwMDAwMDAwMDAwMDEwMDU4ODg5MjhDTkhSU6AmBgVgTAEDAqAdBBtKT1NFIEFMQkVSVE8gUkVVUyBGT1JUVU5BVEmgGQYFYEwBAwOgEAQOOTI5NjM1NjAwMDAxNjCgFwYFYEwBAwegDgQMMDAwMDAwMDAwMDAwgSFhZHJpYW5hLnJvZHJpZ3Vlc0Bwcm9jZW1wYS5jb20uYnIwCQYDVR0TBAIwADAfBgNVHSMEGDAWgBQukerWbeWyWYLcOIUpdjQWVjzQPjAOBgNVHQ8BAf8EBAMCBeAwfwYDVR0gBHgwdjB0BgZgTAECAQwwajBoBggrBgEFBQcCARZcaHR0cDovL2ljcC1icmFzaWwuY2VydGlzaWduLmNvbS5ici9yZXBvc2l0b3Jpby9kcGMvQUNfQ2VydGlzaWduX1JGQi9EUENfQUNfQ2VydGlzaWduX1JGQi5wZGYwggEWBgNVHR8EggENMIIBCTBXoFWgU4ZRaHR0cDovL2ljcC1icmFzaWwuY2VydGlzaWduLmNvbS5ici9yZXBvc2l0b3Jpby9sY3IvQUNDZXJ0aXNpZ25SRkJHNC9MYXRlc3RDUkwuY3JsMFagVKBShlBodHRwOi8vaWNwLWJyYXNpbC5vdXRyYWxjci5jb20uYnIvcmVwb3NpdG9yaW8vbGNyL0FDQ2VydGlzaWduUkZCRzQvTGF0ZXN0Q1JMLmNybDBWoFSgUoZQaHR0cDovL3JlcG9zaXRvcmlvLmljcGJyYXNpbC5nb3YuYnIvbGNyL0NlcnRpc2lnbi9BQ0NlcnRpc2lnblJGQkc0L0xhdGVzdENSTC5jcmwwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMIGbBggrBgEFBQcBAQSBjjCBizBfBggrBgEFBQcwAoZTaHR0cDovL2ljcC1icmFzaWwuY2VydGlzaWduLmNvbS5ici9yZXBvc2l0b3Jpby9jZXJ0aWZpY2Fkb3MvQUNfQ2VydGlzaWduX1JGQl9HNC5wN2MwKAYIKwYBBQUHMAGGHGh0dHA6Ly9vY3NwLmNlcnRpc2lnbi5jb20uYnIwDQYJKoZIhvcNAQELBQADggIBADz3+QOBPSA9lNk12bTciNhr1d+8HrGT92LxL96vcdWEZQ95UbGQhBA2xKYgblscnZ2YPrAlDP2sn/MwNZ59DgOIOrdPWIoTvovjCv58sU5K3iCKxAqEG7HD5RjJ0nDY25uNz5n1dbAFzv/InpLHdPGHvZRbqyKzD4WCZaqh0pAF4t8MQZLeI92yQ2AVe8gGbqFQA2iqQFdpaUi9yWGgVyrnkF/KK/M0Ja0cGXzeTNk1vgDyXtGNxHmaVTTAtAIah43ZA1+kFxtVCWQhulwXjlS4PbRH2Zq3lVb3L0FzZnhbjmysfmW/GWUxmW4Jzc140lPHvi2GlLLrYhorFesxSOR4SL69sph/xRfzRUi9/ypr8lmXYa0xLorNzgO6Mysn2wanE/6rCDmx8hvBKT1gWLlAUXaF6SCAGVjrn9aU5ftFrrYCRJV4kFEqvvQGRFq8kwshJg4npu/May3Ka/KzPAqiSvPPZ7XiUcRsk+pr9KByc1/FRHkr7gQUg6GaSKwB6CbSveiVvdh1TYvarpeS2IDCYl09KwqfYAE17j14MYvuqMXcd0Lu52jYvJKsR/1WuzaEwp4PJBY4hmI9BytU4su22SSkKrTzITc2XJvbxPYU0qgYw1slv23H9iJHdFJVw/K+4mnU3Tss4ZMwdoBY4i1JtYu9USKryAiBHJ89mKUk
          </X509Certificate>
        </X509Data>
      </KeyInfo>

What's wrong?

@bjrmatos
Copy link
Contributor

@giulianoifollow i share with you a keyInfo implementation that i use in production

i use the module node-forge because it has a certificate parser, i could have replaced with another tiny module but i'm too lazy :)

'use strict';

var forge = require('node-forge'),
    pki = forge.pki;

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(',') : '';
}

module.exports = KeyInfoProvider;

@mpbgodinho
Copy link

@giulianoifollow Did you find a way to fix that problem?

@RogerMito
Copy link

The same problem here... :(

@QAnders
Copy link

QAnders commented Aug 21, 2019

Old thread but if someone needs it still:

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

@andersonAlmeida
Copy link

@QAnders tks man

@harshil15999
Copy link

harshil15999 commented Jul 8, 2024

Did not help in achieving the goal

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

No branches or pull requests

9 participants