erdincyavas / sd-dss

Automatically exported from code.google.com/p/sd-dss
0 stars 0 forks source link

Impossible to add certificate chain on Xades SigningCertificate element (and bug on signingCertificate tag implementation) #2

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create a XAdES signature with certificate and chain certificates. 

What is the expected output? What do you see instead?
Expected output is a xml including a SigningCertificate element that includes a 
list of cert elements, but only one is included.

What version of the product are you using? 4.1.0

I have patch a pair of classes to solve the problem:

eu.europa.ec.markt.dss.signature.xades.SignatureBuilder:

private void incorporateSigningCertificate() {

        final Element signingCertificateDom = DSSXMLUtils.addElement(documentDom, signedSignaturePropertiesDom, xPathQueryHolder.XADES_NAMESPACE, "xades:SigningCertificate");

        final List<X509Certificate> certificates = new ArrayList<X509Certificate>();

        final X509Certificate signingCertificate = params.getSigningCertificate();
        certificates.add(signingCertificate);

        if (params.getCertificateChain()!=null && (!params.getCertificateChain().isEmpty())) {
            for (int i=0; i<params.getCertificateChain().size(); i++) {
                if (params.getCertificateChain().get(i)!=null) {
                    certificates.add(params.getCertificateChain().get(i));
                }
            }
        }

        incorporateCertificateRef(signingCertificateDom, certificates);
    }

With that is possible to add multiple certificates, but there is also a bug 
with XAdESBuilder class, in incorporateCertificateRef method beecause you are 
writing a list of certificates with the same Cert parent tag instead of 
creating one cert parent tagfor each certificate. The method patched look like:

protected void incorporateCertificateRef(final Element signingCertificateDom, 
final List<X509Certificate> certificates) {

        for (final X509Certificate certificate : certificates) {

            final Element certDom = DSSXMLUtils.addElement(documentDom, signingCertificateDom, xPathQueryHolder.XADES_NAMESPACE, "xades:Cert");

            final Element certDigestDom = DSSXMLUtils.addElement(documentDom, certDom, xPathQueryHolder.XADES_NAMESPACE, "xades:CertDigest");

            final DigestAlgorithm signingCertificateDigestMethod = params.bLevel().getSigningCertificateDigestMethod();
            incorporateDigestMethod(certDigestDom, signingCertificateDigestMethod);

            final byte[] encodedSigningCertificate = DSSUtils.getEncoded(certificate);
            incorporateDigestValue(certDigestDom, signingCertificateDigestMethod, encodedSigningCertificate);

            final Element issuerSerialDom = DSSXMLUtils.addElement(documentDom, certDom, xPathQueryHolder.XADES_NAMESPACE, "xades:IssuerSerial");

            final Element x509IssuerNameDom = DSSXMLUtils.addElement(documentDom, issuerSerialDom, xPathQueryHolder.XMLDSIG_NAMESPACE, "ds:X509IssuerName");
            final String issuerX500PrincipalName = certificate.getIssuerX500Principal().getName();
            DSSXMLUtils.setTextNode(documentDom, x509IssuerNameDom, issuerX500PrincipalName);

            final Element x509SerialNumberDom = DSSXMLUtils.addElement(documentDom, issuerSerialDom, xPathQueryHolder.XMLDSIG_NAMESPACE, "ds:X509SerialNumber");
            final BigInteger serialNumber = certificate.getSerialNumber();
            final String serialNumberString = new String(serialNumber.toString());
            DSSXMLUtils.setTextNode(documentDom, x509SerialNumberDom, serialNumberString);
        }
    }

I get the definition of signingCertificate element in 
http://docbox.etsi.org/ESI/Open/Latest_Drafts/prEN-319132-1v004-XAdES-core-STABL
E-DRAFT.pdf:

1417 <xsd:element name="SigningCertificate" type="CertIDListType"/> 
1418 
1419 <xsd:complexType name="CertIDListType"> 
1420 <xsd:sequence> 
1421 <xsd:element name="Cert" type="CertIDType" 
1422 maxOccurs="unbounded"/> 
1423 </xsd:sequence> 
1424 </xsd:complexType> 
1425 
1426 <xsd:complexType name="CertIDType"> 
1427 <xsd:sequence> 
1428 <xsd:element name="CertDigest" type="DigestAlgAndValueType"/> 
1429 <xsd:element name="IssuerSerial" type="ds:X509IssuerSerialType"/> 
1430 </xsd:sequence> 
1431 <xsd:attribute name="URI" type="xsd:anyURI" use="optional"/> 
1432 </xsd:complexType> 
1433 
1434 <xsd:complexType name="DigestAlgAndValueType"> 
1435 <xsd:sequence> 
1436 <xsd:element ref="ds:DigestMethod"/> 
1437 <xsd:element ref="ds:DigestValue"/> 
1438 </xsd:sequence> 
1439 </xsd:complexType> 

Original issue reported on code.google.com by eb.j...@gmail.com on 13 Aug 2014 at 4:20

GoogleCodeExporter commented 9 years ago
Sorry, I wrote the code for version 4.0.4. For your new version 4.1.0 is:

private void incorporateSigningCertificate() {

        final Element signingCertificateDom = DSSXMLUtils.addElement(documentDom, signedSignaturePropertiesDom, XAdESNamespaces.XAdES, "xades:SigningCertificate");

        final List<X509Certificate> certificates = new ArrayList<X509Certificate>();

        final X509Certificate signingCertificate = params.getSigningCertificate();
        certificates.add(signingCertificate);

        if (params.getCertificateChain()!=null && (!params.getCertificateChain().isEmpty())) {
            for (int i=0; i<params.getCertificateChain().size(); i++) {
                if (params.getCertificateChain().get(i)!=null && (!params.getCertificateChain().get(i).getSerialNumber().equals(certificates.get(0).getSerialNumber()))) {
                    certificates.add(params.getCertificateChain().get(i));
                }
            }
        }

        incorporateCertificateRef(signingCertificateDom, certificates);
    }

///////////////////////////////////////////////

protected void incorporateCertificateRef(final Element signingCertificateDom, 
final List<X509Certificate> certificates) {     
        for (final X509Certificate certificate : certificates) {

            final Element certDom = DSSXMLUtils.addElement(documentDom, signingCertificateDom, XAdESNamespaces.XAdES, "xades:Cert");

            final Element certDigestDom = DSSXMLUtils.addElement(documentDom, certDom, XAdESNamespaces.XAdES, "xades:CertDigest");

            final DigestAlgorithm signingCertificateDigestMethod = params.bLevel().getSigningCertificateDigestMethod();
            incorporateDigestMethod(certDigestDom, signingCertificateDigestMethod);

            final InMemoryDocument inMemoryCertificate = new InMemoryDocument(DSSUtils.getEncoded(certificate));
            incorporateDigestValue(certDigestDom, signingCertificateDigestMethod, inMemoryCertificate);

            final Element issuerSerialDom = DSSXMLUtils.addElement(documentDom, certDom, XAdESNamespaces.XAdES, "xades:IssuerSerial");

            final Element x509IssuerNameDom = DSSXMLUtils.addElement(documentDom, issuerSerialDom, XMLSignature.XMLNS, "ds:X509IssuerName");
            final String issuerX500PrincipalName = DSSUtils.getIssuerX500PrincipalName(certificate);
            DSSXMLUtils.setTextNode(documentDom, x509IssuerNameDom, issuerX500PrincipalName);

            final Element x509SerialNumberDom = DSSXMLUtils.addElement(documentDom, issuerSerialDom, XMLSignature.XMLNS, "ds:X509SerialNumber");
            final BigInteger serialNumber = certificate.getSerialNumber();
            final String serialNumberString = new String(serialNumber.toString());
            DSSXMLUtils.setTextNode(documentDom, x509SerialNumberDom, serialNumberString);
        }
    }

Original comment by eb.j...@gmail.com on 18 Aug 2014 at 10:36

GoogleCodeExporter commented 9 years ago
Please follow:
https://joinup.ec.europa.eu/asset/sd-dss/issue/impossible-add-certificate-chain-
xades-signingcertificate-element-and-bug-signing

Original comment by bielecki...@gmail.com on 17 Sep 2014 at 10:39