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 create two xades:Cert additional in xades: SigningCertificate? #84

Closed
Jairos2015 opened this issue May 7, 2019 · 22 comments
Closed

Comments

@Jairos2015
Copy link

How to create two xades:Cert additional in xades: SigningCertificate?
I do:

const dataFormat = new xadesjs.xml.DataObjectFormat();
dataFormat.ObjectReference = "ojbRef";
dataFormat.Description = "description";
dataFormat.MimeType = "text/xml";
dataFormat.Encoding = "utf8";
xadesXml.SignedProperties.SignedDataObjectProperties.DataObjectFormats.Add(
dataFormat
);

analogously:
const dataCert = new xadesjs.xml.Cert()
xadesXml.SignedProperties.SignedSignatureProperties.signingCertificate.Cert.Add(dataCert)
xadesXml.SignedProperties.SignedSignatureProperties.signingCertificate.Cert.Add(dataCert)
console.log("XADESJS");

and delivery:
TypeError: Cannot read property 'Add' of undefined
at main (C:\Users\jairo\packmotos\server\lib\Factura.js:693:111)
at process._tickCallback (internal/process/next_tick.js:68:7)

How to create two xades:Cert additional in xades: SigningCertificate,
as I show it in aggregate file example: (Thank you in advance).
cert

@Jairos2015
Copy link
Author

I am learning on the fly and this topic is almost impossible to get tutorials (I appreciate your contribution) and that's why I may be out of focus. Please, if there are three certificates (issuer, intermediate, root) if the three Cert ?.

@rmhrisk
Copy link
Contributor

rmhrisk commented May 7, 2019

Here are some terms that might help:

Term Description
Root CA The root of trust, usually a self signed certificate.
Sub CA A certificate authority subordinated to a root CA.
Issuing CA A type of certificate authority that is used to issue a certificate.
Leaf The end certificate in the chain.
Certificate chain All of the certificates associated with a leaf certificate. Usually consisting of a root certificate, issuing certificate, and a leaf certificate.

When signing a document you usually include all certificates in a certificate chain other than the root CA. You do not include the root CA because for a client to trust the signature they would need this out of bound anyways, given this including it is not valuable since a client can't rely on it.

Do I understand correctly that you are asking how to include:

  • Leaf certificate (the one you signed with)
  • Issuing certificate authority certificate (the one that issued the leaf certificate)

@Jairos2015
Copy link
Author

Jairos2015 commented May 7, 2019 via email

@rmhrisk
Copy link
Contributor

rmhrisk commented May 7, 2019

Let us know if you need more help.

@Jairos2015
Copy link
Author

Thanks for your offer. I would appreciate links with information about billing processes with UBL2.1 format ( Invoice) and programmatically.
Excuse me the English then I do it with google translator

@rmhrisk
Copy link
Contributor

rmhrisk commented May 7, 2019

@Jairos2015
Copy link
Author

Ok. Thank you. Reading.

@rmhrisk
Copy link
Contributor

rmhrisk commented May 7, 2019

@microshine
Copy link
Contributor

@microshine
Copy link
Contributor

@Jairos2015 There is index.d.ts file which describes module definitions and allows to check types in IDE

image

@rmhrisk
Copy link
Contributor

rmhrisk commented May 7, 2019

Here is an XMLDSIG signed UBL invoice - https://gist.github.com/tresf/8a0622c803d4ff9ea3829499bb1d190a

@Jairos2015
Copy link
Author

@rmhrisk Thanks for your interest. Reading...

@Jairos2015
Copy link
Author

@microshine
IDE is VSCode?

@rmhrisk
Copy link
Contributor

rmhrisk commented May 7, 2019

Yes.

@Jairos2015
Copy link
Author

In the construction algorithm of the SigningCertificate element, the element SigningCertificate === Element Cert is taken.
In the XML structure signed Cert is within SigningCertificate. The Cert element is part of the SigningCertificate.
As my purpose is to repeat Cert three times within SigningCertificate, I would have to change that part of the algorithm in async ApplySigningCertificate (base64string). For example, I must change the line 2157 of index.js in the xadesjs library:

const signingCertificate = new Cert ();

In the algorithm that I need this could not be. Am I correct?.
I hope have explained me well. Thanks for your help

@rmhrisk
Copy link
Contributor

rmhrisk commented May 16, 2019

What are you trying to accomplish?

@Jairos2015
Copy link
Author

xades:SigningCertificate
xades:Cert
xades:CertDigest
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512" />
ds:DigestValue</ds:DigestValue>
</xades:CertDigest>
xades:IssuerSerial
ds:X509IssuerName</ds:X509IssuerName>
ds:X509SerialNumber</ds:X509SerialNumber>
</xades:IssuerSerial>
</xades:Cert>
xades:Cert
xades:CertDigest
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512" />
ds:DigestValue</ds:DigestValue>
</xades:CertDigest>
xades:IssuerSerial
ds:X509IssuerName</ds:X509IssuerName>
ds:X509SerialNumber</ds:X509SerialNumber>
</xades:IssuerSerial>
</xades:Cert>
xades:Cert
xades:CertDigest
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512" />
ds:DigestValue</ds:DigestValue>
</xades:CertDigest>
xades:IssuerSerial
ds:X509IssuerName</ds:X509IssuerName>
ds:X509SerialNumber</ds:X509SerialNumber>
</xades:IssuerSerial>
</xades:Cert>
</xades:SigningCertificate>

Three Cert groups within the SigningCertificate group.

@rmhrisk
Copy link
Contributor

rmhrisk commented May 16, 2019

Why? What does each certificate represent? There is only one signature, right?

@Jairos2015
Copy link
Author

Thank you. Example:
An invoice. One signature and group SigningCertificate three groups Cert. Three certificates. A certificate is required to invoice. The other two I have found out but they have the same structure of information, summary and encryption.

GS_Invoice_DIAN-UBL21_Generica.zip

Thank you.

@di-baggio
Copy link

@Jairos2015 Good morning, did you manage to solve this case?

@microshine
Copy link
Contributor

I created an example for adding multiple signing certificates.

SigningCertificate is a list of Cert with digest values SHA-1, SHA-256, and SHA-512

TypeScript

import * as xmldsig from "xmldsigjs";
import { Crypto } from "@peculiar/webcrypto";
import * as x509 from "@peculiar/x509";
import * as xmldom from "xmldom";
import * as xades from "xadesjs";

const crypto = new Crypto();
x509.cryptoProvider.set(crypto);

const alg = {
  name: "RSASSA-PKCS1-v1_5",
  hash: "SHA-256",
  publicExponent: new Uint8Array([1, 0, 1]),
  modulusLength: 2048,
}
const keys = await crypto.subtle.generateKey(alg, false, ["sign", "verify"]);
const cert = await x509.X509CertificateGenerator.createSelfSigned({
  keys,
  notBefore: new Date("2021-07-21"),
  notAfter: new Date("2022-07-21"),
  signingAlgorithm: alg,
  name: "CN=Test",
  serialNumber: "010203",
});

const simpleDoc = xades.Parse(`<Major xmlns="some:namespace:"><Body><header xmlns="another:namespace" xmlns:xsi="yet:another:namesapce"> <test>Some data</test></header><Actual xmlns="test:namespace"><document>this is to be signed</document></Actual></Body></Major>`);
const signedXml = new xades.SignedXml();
signedXml.XmlSignature.KeyInfo.Id = "KeyInfo001";
const keyInfoRef = new xmldsig.Reference("#KeyInfo001");
keyInfoRef.DigestMethod.Algorithm = xmldsig.SHA1_NAMESPACE;
signedXml.XmlSignature.SignedInfo.References.Add(keyInfoRef);

async function addSigningCert(signedXml: xades.SignedXml, cert: x509.X509Certificate, hash = "SHA-256") {
  const signedProperties = signedXml.SignedProperties;

  const xmlCert = new xades.xml.Cert();
  xmlCert.IssuerSerial.X509IssuerName = cert.issuer;
  xmlCert.IssuerSerial.X509SerialNumber = cert.serialNumber;
  const alg = xmldsig.CryptoConfig.GetHashAlgorithm(hash);
  xmlCert.CertDigest.DigestMethod.Algorithm = alg.namespaceURI;
  const thumbprint = await cert.getThumbprint(hash);
  xmlCert.CertDigest.DigestValue = new Uint8Array(thumbprint);

  signedProperties.SignedSignatureProperties.SigningCertificate.Add(xmlCert)
}

await addSigningCert(signedXml, cert, "SHA-1");
await addSigningCert(signedXml, cert, "SHA-256");
await addSigningCert(signedXml, cert, "SHA-512");

const signature = await signedXml.Sign(alg, // algorithm
  keys.privateKey, // key
  simpleDoc, // document
  {
    keyValue: keys.publicKey,
    id: "Signature001",
    references: [
      { hash: "SHA-256", transforms: ["enveloped"], uri: "/" }
    ]
  });

simpleDoc.documentElement.appendChild(signature.GetXml()!);

console.log(new xmldom.XMLSerializer().serializeToString(simpleDoc));

XML (formatted)

<Major xmlns="some:namespace:">
  <Body>
    <header xmlns="another:namespace"
      xmlns:xsi="yet:another:namesapce">
      <test>Some data</test>
    </header>
    <Actual xmlns="test:namespace">
      <document>this is to be signed</document>
    </Actual>
  </Body>
  <ds:Signature Id="Signature001"
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
      <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
      <ds:Reference URI="#KeyInfo001">
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <ds:DigestValue>wyxb9Mx3eXRLbonx7wyGr4ToDU4=</ds:DigestValue>
      </ds:Reference>
      <ds:Reference URI="/">
        <ds:Transforms>
          <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
        <ds:DigestValue>/i3lfAkXorhcushyn0f5BqfI0ms1B2Ccom0bycrkMag=</ds:DigestValue>
      </ds:Reference>
      <ds:Reference URI="#xades-id-b85c87b51384" Type="http://uri.etsi.org/01903#SignedProperties">
        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
        <ds:DigestValue>rMnjKaBmGT+Lm7mE+6YoFj+C3fO4PiB2TN5pnaFFNBo=</ds:DigestValue>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>RbfJ9WS56RFKDf03m/6KRzF/26PXEPJ3VHxQ5LnxGXHCM06PZTlrTUU4z2xyE85AI9M4wgOv2zb9DbKvLkT2VrfDfNEBfAXI0+01//OoHHGYS6w3EQMnnDxGSsoYOo1rx6WLLzbkfkw7zXtVlyOUAYvnjq91VdO1Zu4+OOn8rCMJXjxJrReSeBsrUxXiD1As+RWaR3mIK6uAQ7v0dNcXHJ5E24o4rD2Ib/0v4Yg8kvV26jYt4BdMS1PlJW5HUwSx+FzqTumP6kJWs/U8RpRlA5f60K/Ot9NXWgWdz1H/HL+flYPfYlIDFy42lZ1+vgTJfKP0pTKnjxHXCwkPB8b/2Q==</ds:SignatureValue>
    <ds:KeyInfo Id="KeyInfo001">
      <ds:KeyValue>
        <ds:RSAKeyValue>
          <ds:Modulus>qqecyZpoRMs2HLIVZlaPaeJzf7jdOKjj68jYxmP+KjrpvQ+ocyyVAq0WT5Nc0LmZMrwMxFNIP1NoxgaUMpR+GMQQzB78KFzrcuggLOtzRxHBnIiamZYYSmI62t1HIsbe071UAlQq6mz0lW3DdwlNB+UGx7nbGFMm2bTac2CkWqEHUHfeVjudDtLdR1wExEnn2cl4SlqCjipYyKE6CRoS9R1jIZYmO0yfkwYrhFoZKGnmXskgUUomPhT5yizgfIxEwzZjLL0qCzyDOtf4nmgs11XJI8mxFBTbiK53MjJ7AiGzGrydJZOLW+AlgcIC03lbEPzAxofM6zyG84kI+j3Gww==</ds:Modulus>
          <ds:Exponent>AQAB</ds:Exponent>
        </ds:RSAKeyValue>
      </ds:KeyValue>
    </ds:KeyInfo>
    <ds:Object>
      <xades:QualifyingProperties Target="#id-b85c87b51384"
        xmlns:xades="http://uri.etsi.org/01903/v1.3.2#">
        <xades:SignedProperties Id="xades-id-b85c87b51384">
          <xades:SignedSignatureProperties>
            <xades:SigningTime>2021-07-21T08:28:09.117Z</xades:SigningTime>
            <xades:SigningCertificate>
              <xades:Cert>
                <xades:CertDigest>
                  <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                  <ds:DigestValue>kTzLLV37fI6TJN/+x2D3e2MAmgg=</ds:DigestValue>
                </xades:CertDigest>
                <xades:IssuerSerial>
                  <ds:X509IssuerName>CN=Test</ds:X509IssuerName>
                  <ds:X509SerialNumber>010203</ds:X509SerialNumber>
                </xades:IssuerSerial>
              </xades:Cert>
              <xades:Cert>
                <xades:CertDigest>
                  <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                  <ds:DigestValue>PFVWSZYpKRGbqjtu3jzVApMxfWU2H2YnyBzTO+9GwWk=</ds:DigestValue>
                </xades:CertDigest>
                <xades:IssuerSerial>
                  <ds:X509IssuerName>CN=Test</ds:X509IssuerName>
                  <ds:X509SerialNumber>010203</ds:X509SerialNumber>
                </xades:IssuerSerial>
              </xades:Cert>
              <xades:Cert>
                <xades:CertDigest>
                  <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
                  <ds:DigestValue>8uYL5iptPIUchLDAKs3mpm/92dnjT2G0Ezy5otRzA7qRiVVt0GH6T0aJWFMqY1TdAjtoS7eHb5AWFzYnO4HgrQ==</ds:DigestValue>
                </xades:CertDigest>
                <xades:IssuerSerial>
                  <ds:X509IssuerName>CN=Test</ds:X509IssuerName>
                  <ds:X509SerialNumber>010203</ds:X509SerialNumber>
                </xades:IssuerSerial>
              </xades:Cert>
            </xades:SigningCertificate>
          </xades:SignedSignatureProperties>
        </xades:SignedProperties>
      </xades:QualifyingProperties>
    </ds:Object>
  </ds:Signature>
</Major>

@di-baggio
Copy link

@microshine Thank you.
Amazing work!

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

4 participants