How to Include the Full Certificate Chain in xades:SigningCertificate Using the xades4j Library in Java

I am working on signing an XML document using the xades4j library in Java. My goal is to have the xades:SigningCertificate field include the entire certificate chain instead of just the signing certificate. Specifically, I want multiple xades:Cert elements within the xades:SigningCertificate element to represent the full chain of certificates.

So far, I have been able to generate the basic signature, but only the signing certificate is included without the full chain. Below is a portion of my current implementation:


public String signXml(
            String xmlString,
            String certificatePath,
            String certificatePassword) throws Exception {

        // Initialize the DocumentBuilderFactory and enable namespace awareness
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();

        // Parse the XML string into a Document object
        Document doc = db.parse(new ByteArrayInputStream(xmlString.getBytes("UTF-8")));
        Element rootElement = doc.getDocumentElement();

        // Retrieve the UBLExtensions element using its namespace
        NodeList ublextensionsList = doc.getElementsByTagNameNS(
                "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2",
                "UBLExtensions");

        Element ublextensions = (Element) ublextensionsList.item(0);

        // Create a new UBLExtension element and its content
        Element newExtension = doc.createElementNS(
                "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2",
                "ext:UBLExtension");
        Element extensionContent = doc.createElementNS(
                "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2",
                "ext:ExtensionContent");
        newExtension.appendChild(extensionContent);
        ublextensions.appendChild(newExtension);


        // Configure the KeyingDataProvider using the provided PKCS12 certificate
        KeyingDataProvider keyStoreProvider = FileSystemKeyStoreKeyingDataProvider
                .builder("PKCS12", certificatePath, new FirstCertificateSelector())
                .storePassword(new DirectPasswordProvider(certificatePassword))
                .entryPassword(new DirectPasswordProvider(certificatePassword))
                .fullChain(true)
                .build();

        // Define the signature policy information
        SignaturePolicyInfoProvider policyInfoProvider = new SignaturePolicyInfoProvider() {
            @Override
            public SignaturePolicyBase getSignaturePolicy() {
                return new SignaturePolicyIdentifierProperty(
                        new ObjectIdentifier(
                                "https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf",
                                IdentifierType.URI,
                                "Política de firma para facturas electrónicas de la República de Colombia"),
                        new ByteArrayInputStream("Politica de Factura Digital".getBytes()));
            }
        };

        // Initialize the XadesSigner with the signing profile and properties
        XadesSigner signer = new XadesEpesSigningProfile(keyStoreProvider, policyInfoProvider)
                .withSignaturePropertiesProvider(new SignaturePropertiesProvider() {
                    @Override
                    public void provideProperties(SignaturePropertiesCollector arg0) {
                        SigningTimeProperty sigTime = new SigningTimeProperty();
                        arg0.setSignerRole(
                                new SignerRoleProperty().withClaimedRole("supplier"));
                        arg0.setSigningTime(sigTime);
                    }
                })
                .withBasicSignatureOptions(
                        new BasicSignatureOptions()
                                .signKeyInfo(true)
                                .includeSigningCertificate(SigningCertificateMode.FULL_CHAIN)
                                .includeIssuerSerial(true))
                                
                .newSigner();

        // Define the data object to be signed with the enveloped signature transform
        DataObjectDesc dataObject = new DataObjectReference("")
                .withTransform(new EnvelopedSignatureTransform());

        SignedDataObjects dataObjs = new SignedDataObjects(dataObject);

        // Perform the signing operation and append the signature to the extension content
        signer.sign(dataObjs, extensionContent);

        // Convert the signed Document back to a string and return
        return documentToString(doc);
    }

When I sign the XML document, the resulting signature includes only a single xades:Cert element within xades:SigningCertificate, like this:

<xades:SigningCertificate>
  <xades:Cert>
    <!-- Signing Certificate Details -->
  </xades:Cert>
</xades:SigningCertificate>

I would like the xades:SigningCertificate section to include the full certificate chain with multiple xades:Cert elements, as shown below:

<xades:SigningCertificate>
  <xades:Cert>
    <!-- Signing Certificate Details -->
  </xades:Cert>
  <xades:Cert>
    <!-- Intermediate Certificate Details -->
  </xades:Cert>
  <xades:Cert>
    <!-- Root Certificate Details -->
  </xades:Cert>
</xades:SigningCertificate>

Upvotes: 0

Views: 45

Answers (0)

Related Questions