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

XAdEs-T example #117

Open
GLR21 opened this issue Dec 15, 2021 · 3 comments
Open

XAdEs-T example #117

GLR21 opened this issue Dec 15, 2021 · 3 comments
Assignees

Comments

@GLR21
Copy link

GLR21 commented Dec 15, 2021

Hi, I would like to ask if is there any example I could follow to generate a XAdEs-T signature? I already have the certificates, keys and timestamp, I just haven't found any example I could use with xadesjs.

Best regards,
Gabriel Lange Ramos.

@eidins
Copy link
Contributor

eidins commented Jan 18, 2022

Looking at

xadesjs/src/signed_xml.ts

Lines 98 to 103 in 4e13cfe

get UnsignedProperties(): XAdES.UnsignedProperties {
if (!this.Properties) {
throw new XmlCore.XmlError(XmlCore.XE.XML_EXCEPTION, "Properties is empty");
}
return this.Properties.UnsignedProperties;
}

The property you want is SignatureTimeStamp

* <xsd:element name="UnsignedSignatureProperties" type="UnsignedSignaturePropertiesType"/>
* <xsd:complexType name="UnsignedSignaturePropertiesType">
* <xsd:choice maxOccurs="unbounded">
* <xsd:element name="CounterSignature" type="CounterSignatureType"/>
* <xsd:element name="SignatureTimeStamp" type="XAdESTimeStampType"/>
* <xsd:element name="CompleteCertificateRefs" type="CompleteCertificateRefsType"/>
* <xsd:element name="CompleteRevocationRefs" type="CompleteRevocationRefsType"/>
* <xsd:element name="AttributeCertificateRefs" type="CompleteCertificateRefsType"/>
* <xsd:element name="AttributeRevocationRefs" type="CompleteRevocationRefsType"/>
* <xsd:element name="SigAndRefsTimeStamp" type="XAdESTimeStampType"/>
* <xsd:element name="RefsOnlyTimeStamp" type="XAdESTimeStampType"/>
* <xsd:element name="CertificateValues" type="CertificateValuesType"/>
* <xsd:element name="RevocationValues" type="RevocationValuesType"/>
* <xsd:element name="AttrAuthoritiesCertValues" type="CertificateValuesType"/>
* <xsd:element name="AttributeRevocationValues" type="RevocationValuesType"/>
* <xsd:element name="ArchiveTimeStamp" type="XAdESTimeStampType"/>
* <xsd:any namespace="##other"/>
* </xsd:choice>
* <xsd:attribute name="Id" type="xsd:ID" use="optional"/>
* </xsd:complexType>

I think you might want something like

* <xsd:element name="EncapsulatedTimeStamp" type="EncapsulatedPKIDataType"/>

Taking this into account, I think you want to modify the Sign call from the README.md to be,

import * as XAdES from 'xadesjs';

...

  var signedXml = new XAdES.SignedXml();
  var ts = new XAdES.xml.SignatureTimeStamp();
  ts.EncapsulatedTimeStamp.Add(new XAdES.xml.EncapsulatedTimeStamp())
  signedXml.Properties.UnsignedProperties.UnsignedSignatureProperties.Add(ts)
  console.log(signedXml.Properties.UnsignedProperties.UnsignedSignatureProperties);

I imagine you have to add something to the EncapsulatedTimeStamp, but I haven't figured that out yet. Please update if you figure that part out.

@eidins
Copy link
Contributor

eidins commented Jan 18, 2022

I think you setup the EncapsultedTimeStamp by setting the value element. Parent class below,

export class EncapsulatedPKIData extends XadesObject {
@XmlAttribute({
localName: XmlXades.AttributeNames.Id,
defaultValue: "",
})
public Id: string;
@XmlAttribute({
localName: XmlXades.AttributeNames.Encoding,
defaultValue: null,
converter: XmlEncodingConverter,
})
public Encoding: EncodingType;
@XmlContent({
required: true,
converter: XmlBase64Converter,
})
public Value: Uint8Array;
}

@microshine
Copy link
Contributor

Here is a simple example of XAdES-T creation.

TypeScript

const crypto = new Crypto();
const alg: globalThis.RsaHashedKeyGenParams = {
    name: "RSASSA-PKCS1-v1_5",
    hash: "SHA-256",
    publicExponent: new Uint8Array([1, 0, 1]),
    modulusLength: 2048,
};
const dataRaw = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
const tsRaw = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);

// Generate RSA keypair
const keys = await crypto.subtle.generateKey(alg, false, ["sign", "verify"]) as Required<CryptoKeyPair>;

// Create self-signed certificate
const cert = await x509.X509CertificateGenerator.createSelfSigned({
    name: "CN=Test",
    keys,
    serialNumber: "010203",
    signingAlgorithm: alg,
    notBefore: new Date("2022-01-18"),
    notAfter: new Date("2022-01-19"),
}, crypto);

XAdES.Application.setEngine("NodeJS", crypto);

// Create XAdES-T signature
const signedXml = new XAdES.SignedXml();
const ts = new XAdES.xml.SignatureTimeStamp();
const ets = new XAdES.xml.EncapsulatedTimeStamp();
ets.Encoding = "ber";
ets.Value = tsRaw;
ts.EncapsulatedTimeStamp.Add(ets);
signedXml.UnsignedProperties.UnsignedSignatureProperties.Add(ts);

const signingCertString = cert.toString("base64");
await signedXml.Sign(alg, keys.privateKey, dataRaw, {
    keyValue: keys.publicKey,
    x509: [signingCertString],
    references: [
        {
            hash: "SHA-256",
            uri: "some.txt",
        }
    ],
    signingCertificate: signingCertString,
});

console.log(signedXml.toString());

Output (formatted)

<ds:Signature Id="id-0d84c844c447"
  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="some.txt">
      <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
      <ds:DigestValue>monGjExeKLjEpVZ2c9Ri//UV20YRb5kAYk0JxHT1k/s=</ds:DigestValue>
    </ds:Reference>
    <ds:Reference URI="#xades-id-0d84c844c447" Type="http://uri.etsi.org/01903#SignedProperties">
      <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
      <ds:DigestValue>GDeoqLDJBs5CkKJMTkvX41TuRob98fxji8cAFbfcDxQ=</ds:DigestValue>
    </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>e1Kwra0HwQFTnZ+vRyJaGgPedJlhvf1pn6s4jKMMW6zGYJn3Sz0xmW+bso7bXSkMw1DsmOaObRwVKb01EZrufTgw8cYFQbe7Ks6Q3WKx07+URrdQVBqER12iXaAFx5VsfARaXAxzK4jk1RtV4CJTufF58B2cY3At4VnDAZlLvO3rfhqsaWkPF3foBSN4ompzqPk/emQVb/WYL5jTJhLmM6eHqEGQbDg2I1M2Wzq1byA+ks1FBXww3eRVLinQIbZtoLBCTi9XZ6VxHsKxbeM7yLyG87TXuSDNGz2nDLLhfWM7D78fGHK+n9wepH2ly3+ygl6lrbiXS3M69Pqu11EkCA==</ds:SignatureValue>
  <ds:KeyInfo>
    <ds:KeyValue>
      <ds:RSAKeyValue>
        <ds:Modulus>3EpI4qi0J3v5OXBHh8e5AEDd7y71lT9r3RwR+ApON9W5+jGsuea9lCQjU9SGIYKwCeUs6x/TIsTxsbYsnIFxX7ZX4ag6xIfC9rPscnTHfaCxpZ1nbz1hkUqF6MilNVK27EwIIyu0EHmIaJdKyUSOKXhEBJDUWO8M345Dn49ySspm1FpHD+Q4sio0QSfW+btqby1+FCVERund+It9xX4IfQWr8S2PsnnGLRzPYL5s1dRL/04sPg2WaAN8JzmoyeO+1uGxNYYjB227L6NsX6JAgDFcyEAKCsL5hpb3smC/XOYGVmTvvL355tFB8SXdx838AFmziUWhLDpvJjWZeMoTmQ==</ds:Modulus>
        <ds:Exponent>AQAB</ds:Exponent>
      </ds:RSAKeyValue>
    </ds:KeyValue>
    <ds:X509Data>
      <ds:X509Certificate>MIICnTCCAYWgAwIBAgIDAQIDMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNVBAMTBFRlc3QwHhcNMjIwMTE4MDAwMDAwWhcNMjIwMTE5MDAwMDAwWjAPMQ0wCwYDVQQDEwRUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3EpI4qi0J3v5OXBHh8e5AEDd7y71lT9r3RwR+ApON9W5+jGsuea9lCQjU9SGIYKwCeUs6x/TIsTxsbYsnIFxX7ZX4ag6xIfC9rPscnTHfaCxpZ1nbz1hkUqF6MilNVK27EwIIyu0EHmIaJdKyUSOKXhEBJDUWO8M345Dn49ySspm1FpHD+Q4sio0QSfW+btqby1+FCVERund+It9xX4IfQWr8S2PsnnGLRzPYL5s1dRL/04sPg2WaAN8JzmoyeO+1uGxNYYjB227L6NsX6JAgDFcyEAKCsL5hpb3smC/XOYGVmTvvL355tFB8SXdx838AFmziUWhLDpvJjWZeMoTmQIDAQABowIwADANBgkqhkiG9w0BAQsFAAOCAQEATel2jf8g9s+HLq5vPRUMNfI8zcSokYPzNQveIZ2NJAOwh3vXhH3MiXBQ4kpsOUaUOCB6KxZ6xvpeAc/LkI2rjxetbGfyRfN5GCQ5kHIL7ArGSNsZjRlxjy/JeiXRDHIPQ5S5IKGVy+FEkenmD6Sn7jgD1FpjVw3CV1zUc+5QT5MMX0150sKCkGd1KAMsYrFdY6FGQ2JbF7jk1ib/LF+HwnZWg5VJBpAwlPAq/EOf/iNhsXtbA+60jhnFJZE/iUjB4ha/IO+4kBbhjEVA4nuzlK9Dox0IQBc/7MtHo9Ysf2BOshAGC35jvRj10qoRvOa6C/HyziL57pdOoLI3SIQAFQ==</ds:X509Certificate>
    </ds:X509Data>
  </ds:KeyInfo>
  <ds:Object>
    <xades:QualifyingProperties Target="#id-0d84c844c447"
      xmlns:xades="http://uri.etsi.org/01903/v1.3.2#">
      <xades:SignedProperties Id="xades-id-0d84c844c447">
        <xades:SignedSignatureProperties>
          <xades:SigningTime>2022-01-18T15:33:10.634Z</xades:SigningTime>
          <xades:SigningCertificate>
            <xades:Cert>
              <xades:CertDigest>
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                <ds:DigestValue>9uR1h3fw2wxkwXXcM/FRr4BCpgppjph0l51JBcYwFEg=</ds:DigestValue>
              </xades:CertDigest>
              <xades:IssuerSerial>
                <ds:X509IssuerName>CN=Test</ds:X509IssuerName>
                <ds:X509SerialNumber>66051</ds:X509SerialNumber>
              </xades:IssuerSerial>
            </xades:Cert>
          </xades:SigningCertificate>
        </xades:SignedSignatureProperties>
      </xades:SignedProperties>
      <xades:UnsignedProperties>
        <xades:UnsignedSignatureProperties>
          <xades:SignatureTimeStamp>
            <xades:EncapsulatedTimeStamp Encoding="http://uri.etsi.org/01903/v1.2.2#BER">AQIDBAUGBwgJAA==</xades:EncapsulatedTimeStamp>
          </xades:SignatureTimeStamp>
        </xades:UnsignedSignatureProperties>
      </xades:UnsignedProperties>
    </xades:QualifyingProperties>
  </ds:Object>
</ds:Signature>

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

3 participants