PeculiarVentures / xadesjs

A pure Typescript/Javascript implementation of XAdES based on XMLDSIGjs. (Keywords: WebCrypto, XMLDSIG, XADES, eIDAS, Trust List, X.509, CRL, OCSP)
https://xadesjs.com
MIT License
141 stars 49 forks source link

How to create two xades:Cert additional in xades: SigningCertificate? #84

Closed Jairos2015 closed 3 years ago

Jairos2015 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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:

Jairos2015 commented 5 years ago

Thank you.

El lun., 6 may. 2019 8:51 p. m., Ryan Hurst notifications@github.com escribió:

Here are some terms that might help: 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)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/PeculiarVentures/xadesjs/issues/84#issuecomment-489875462, or mute the thread https://github.com/notifications/unsubscribe-auth/ACSH4KSCMZPMUREGVKPJQMTPUDOD5ANCNFSM4HLEM5YQ .

rmhrisk commented 5 years ago

Let us know if you need more help.

Jairos2015 commented 5 years ago

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 commented 5 years ago

We’re not familiar with UBL 2.1 but we found this : http://docs.oasis-open.org/ubl/UBL-2.1.html

And

http://docs.oasis-open.org/ubl/os-UBL-2.2/xml/UBL-Invoice-2.1-Example.xml

Jairos2015 commented 5 years ago

Ok. Thank you. Reading.

rmhrisk commented 5 years ago

Here are a few more examples: https://github.com/Tradeshift/tradeshift-ubl-examples/tree/master/src/main/resources/org/oasis-open/ubl/examples

microshine commented 5 years ago

@Jairos2015 See ApplySigningCertificate

microshine commented 5 years ago

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

image

rmhrisk commented 5 years ago

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

Jairos2015 commented 5 years ago

@rmhrisk Thanks for your interest. Reading...

Jairos2015 commented 5 years ago

@microshine IDE is VSCode?

rmhrisk commented 5 years ago

Yes.

Jairos2015 commented 5 years ago

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 commented 5 years ago

What are you trying to accomplish?

Jairos2015 commented 5 years ago
Three Cert groups within the SigningCertificate group.
rmhrisk commented 5 years ago

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

Jairos2015 commented 5 years ago

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 commented 3 years ago

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

microshine commented 3 years ago

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 commented 3 years ago

@microshine Thank you. Amazing work!