bseddon / xml-signer

Provides signing and verification of XML documents including support for XAdES
BSD 3-Clause "New" or "Revised" License
18 stars 7 forks source link

Call XAdES::archiveTimestamp function fails #14

Open juanmalopez opened 1 year ago

juanmalopez commented 1 year ago

Hello,

We have been using this module correctly until 2023-07-04 06:51:48 UTC, which was the last time XML sealing worked.

From then, all attempts have been unsuccessful due to the same error.

We were using version 1.0.0, and upon encountering this error, we have upgraded to the latest version, 1.12, but the same error still occurs.

This is our code:

XAdES::signDocument(
            new InputResourceInfo(
                $path_xml, // The source document
                ResourceInfo::file, // The source is a file
                $partes_ruta['dirname'], // The location to save the signed document
                $partes_ruta['filename'], // The name of the file to save the signed document in,
                null,
                false
            ),
            new CertificateResourceInfo( $certData['cert'], ResourceInfo::string | ResourceInfo::pem ),
            new KeyResourceInfo( $certData['pkey'], ResourceInfo::string ),
            new SignatureProductionPlaceV2(
                'Girona',
                null, // This is V2 only
                'Girona',
                '17001',
                'ES'
            ),
            new SignerRoleV2(
                'CEO'
            ),
            array(
                'canonicalizationMethod' => XMLSecurityDSig::C14N,
                'addTimestamp' => $tsaURL // Include a timestamp? Can specify an alternative TSA url eg 'http://mytsa.com/'
            )
        );

        XAdES::archiveTimestamp(
            new SignedDocumentResourceInfo(
                $path_xml,
                ResourceInfo::file,
                XAdES::SignatureRootId, // optional id
                $partes_ruta['dirname'],
                $partes_ruta['filename'].".xml",
                XMLSecurityDSig::generateGUID('archive-timestamp-')
            ),
            $tsaURL
        );

When we call the XAdES::archiveTimestamp function it generates the following error:

[2023-07-11 10:13:21] preview.ERROR: App\Jobs\EvidenceCertification@handle: Fails when certificate evidence {"message":"All <EncapsulatedCRLValues> children must be of type EncapsulatedCRLValue","error_trace":"#0 /var/www/mensagia/laravel/vendor/lyquidity/xml-signer/src/xml/RevocationValues.php(146): lyquidity\\xmldsig\\xml\\CRLValues->validateElement()
#1 /var/www/mensagia/laravel/vendor/lyquidity/xml-signer/src/xml/PropertiesCollection.php(202): lyquidity\\xmldsig\\xml\\RevocationValues->validateElement()
#2 /var/www/mensagia/laravel/vendor/lyquidity/xml-signer/src/xml/UnsignedSignatureProperties.php(98): lyquidity\\xmldsig\\xml\\PropertiesCollection->validateElement()
#3 /var/www/mensagia/laravel/vendor/lyquidity/xml-signer/src/XAdES.php(1834): lyquidity\\xmldsig\\xml\\UnsignedSignatureProperties->validateElement()
#4 /var/www/mensagia/laravel/vendor/lyquidity/xml-signer/src/XAdES.php(319): lyquidity\\xmldsig\\XAdES->addArchiveTimestamp()
#5 /var/www/mensagia/laravel/vendor/lyquidity/xml-signer/src/XAdES.php(257): lyquidity\\xmldsig\\XAdES::internalTimestamp()
#6 /var/www/mensagia/laravel/app/Mensagia/Certifications/XMLUtils.php(113): lyquidity\\xmldsig\\XAdES::archiveTimestamp()
#7 /var/www/mensagia/laravel/app/Mensagia/Certifications/CertificationService.php(69): App\\Mensagia\\Certifications\\XMLUtils->signAndTimpestampWithXADES()
#8 /var/www/mensagia/laravel/app/Jobs/EvidenceCertification.php(57): Mensagia\\Certifications\\CertificationService->certificateEvidence()}

Could you help us with this?

Thanks, Juanma

bseddon commented 1 year ago

Hi It's hard to try to answer your question because there is not enough information. A first guess is that the document you are signing is already signed and/or the document already contains one or more elements of type EncapsulatedCRLValue but the elements inside are not value.

Are you in a position to share the document you are trying to sign? I know you may not be able to share if it contains sensitive but it will help to try to understand the problem.

bseddon commented 1 year ago

Some more thoughts. The CRL (from EncapsulatedCRLValue) is the certificate revocation list. When signing using an archive timestamp, there are several potential sources of a CRL. One is from the authority that issued the certificate you are using to sign. If the CRL is being retrieved from an OCSP run by the certificate authority then it may have a CRL as well. Also there is the time stamp authority (TSA). The signature has to include a validated time stamp and the time stamp has to be signed so the authority of the certificate used to sign the time stamp also has a CRL.

Have you changed your signing certificate recently? Have you changed your time stamp authority?

juanmalopez commented 1 year ago

We attach the XML file so you can see an example of the problem.

xml_test.zip

Until July 4th, the signatures in the XML were generated with OCSP keys, and it worked correctly.

As of mid-morning July 4th, there is no OCSP key in the XML to be generated and it tries to write CRLValues keys, and at this point it throws the error.

Since the last CRLValues block contains 2 entries of the EncapsulatedPKIData type, and since the validation tells it that they must be EncapsulatedCRLValues, it throws an exception and generates the error.

We have spoken with our provider and they have shown us traces where we see that the module correctly makes requests to its OCSP service, so we do not understand why these keys are not used, and the CRLValues are being used that are not working well for us .

Can you help us? Thank you so much!

juanmalopez commented 1 year ago

We have spoken with our signing provider and they have told us that they actually made a change on July 4 in relation to OCSP certificates, in which they no longer include the validation URL to validate themselves.

However, they do include a "nocheck" parameter to indicate that they should not be validated.

From what I understand, you are not taking this "nocheck" parameter into account and you are trying to validate these OCSPs?

We attach the certificate as an example:

https://crl.firmaprofesional.com/ocsp/ocsp-fp-subtsa.crt

Could you make this modification to take into account the "nocheck"?

Thank you so much!

bseddon commented 1 year ago

In section 6.6.3 of this ETSI publication does say:

A TSP can decide to use the id-pkix-ocsp-nocheck extension in the certificate profile of a delegated OCSP responder as described in clause 4.2.2.2.1 (Revocation Checking of an Authorized Responder) of IETF RFC 6960 [11]. In that case, no revocation status information is required for determining the status of the corresponding responder certificate which may be considered as useful for various reasons.

However, it goes on to say:

As stipulated in IETF RFC 6960 [11], an OCSP responder key compromise is, in this case, as severe as a compromise of the corresponding issuing CA key. To this reason, the TSP carefully considers OCSP responder key management and particularly considers reducing responder certificate lifetime to a reasonable duration. ETSI 45 ETSI EN 319 411-1 V1.3.1 (2021-05)

Third party applications like SVAs that rely on the TSP's certificate status information services may not be able to handle this non-critical extension. Consequently they can end up with operational issues when no fall back scenario like complementary provisioning of a CRL is implemented for revealing the responder status, or can end up in invalidating the signature.

While the IETF RFC 6960 may allow a TSP to use nocheck for its CRL, the specification of the ArchiveTimestamp by ETSI is one of those SVA and does not. This is for the same reasons give above. If the TSA offers no OCSP then it cannot be checked and the timestamp generated could be forged. The purpose of the ArchiveTimestamp is to date the archive and to demonstrate to future users that at the time the timestamp was generated the certificates used were valid and to include the evidence. The CRL is a vital part of the evidence which can show the certificate was not revoked at the time of signing.

For these reasons I cannot update the software exclude the OCSP CRL because the TSA wants to be lazy and use the nocheck option. My recommendation is to use a different TSA.

jmanzano commented 1 year ago

Bill

This is the TSA provider. In order to clarify, we do offer both OCSP and CRL validation for the OCSP responder certificate, but we no longer include the crlDistributionPoints or the authorityInformationAccess in it, this means that a library can not automatically retrieve this values.

We had to do this change to comply with the CA/Browser Forum Baseline Requirements

ocsp responder extensions

We have successfully tested LTA signatures with the DSS Library.

Can we help you with anything? Maybe providing you with test credentials for out timestamp service?

bseddon commented 1 year ago

Fair enough. Two things: one is that the DSS is not normative. Second, in my reading of the specification of the ArchiveTimestamp, it requires the OCSP CRL as evidence for the reasons ETSI make clear in their comments I reproduced above. Without that evidence, going all the way to the CA, the timestamp is meaningless because it could have been spoofed or the TSA certificate used could have been revoked.

The archive is intended to be as safe as possible years in the future when everyone has forgotten about specific certificates and TSAs so the evidence is important.

Making a change to accommodate a change to the OCSP policy of a TSA is not something I'm willing to do. However, the project is open source so it can be forked and modified to forgive the lack of a CRL.