Search code examples
itextdigital-signaturebouncycastlepades

IssuerSerial Matching in Pades Signature with IText 8.0.3


I'm signing a pdf document with PdfPadesSigner's SignWithBaselineLTAProfile method in IText 8.0.3. I use my certificate in the USB token as ExternalSignature (pkcs11library). Everything is very simple. The only problem is that there is no IssuerSerial match in the signature structure. I can't solve this problem. Thank you from now.


var padesSigner = new PdfPadesSigner(new PdfReader(content.Document.Stream), signedStream);

IList<IX509Certificate> trusted = new List<IX509Certificate>();

        foreach (var crnCert in parameters.TrustedCertificates)
            trusted.Add(new X509CertificateBC(crnCert));

padesSigner.SetTrustedCertificates(trusted);

    TSAClientBouncyCastle timeStampInfo = null;

        if (parameters.TimeStampSettings != null)
            timeStampInfo = new TSAClientBouncyCastle(parameters.TimeStampSettings.HostUrl, parameters.TimeStampSettings.LoginId, parameters.TimeStampSettings.Password);

  var certificates = new IX509Certificate[]
        {
            new X509CertificateBC(parameters.SigningCertificate)
        };

padesSigner.SignWithBaselineLTAProfile(properties, certificates, this, timeStampInfo);

Must be;

<RelatedCertificate Certificate="CERTIFICATE_FATİH-POLAT_20231017-0920">
                     <Origin>SIGNED_DATA</Origin>
                     <Origin>DSS_DICTIONARY</Origin>
                     <Origin>VRI_DICTIONARY</Origin>
                     <CertificateRef>
                         <Origin>SIGNING_CERTIFICATE</Origin>
                         **<IssuerSerial match="true">MIIBAzCB86SB8DCB7TELMAKGI....</IssuerSerial>**
                         <DigestAlgoAndValue match="true">
                             <DigestMethod>SHA256</DigestMethod>
                             <DigestValue>Fuxst8SamhghugBDp/6FD+kzENHiYzqEyKOXaFZL2jc=</DigestValue>
                         </DigestAlgoAndValue>
                     </CertificateRef>
                 </RelatedCertificate>

What i have;

<RelatedCertificate Certificate="CERTIFICATE_FATİH-POLAT_20231017-0920">
                    <Origin>SIGNED_DATA</Origin>
                    <Origin>DSS_DICTIONARY</Origin>
                    <Origin>VRI_DICTIONARY</Origin>
                    <CertificateRef>
                        <Origin>SIGNING_CERTIFICATE</Origin>
                        <DigestAlgoAndValue match="true">
                            <DigestMethod>SHA256</DigestMethod>
                            <DigestValue>Fuxst8SamhghugBDp/6FD+kzENHiYzqEyKOXaFZL2jc=</DigestValue>
                        </DigestAlgoAndValue>
                    </CertificateRef>
                </RelatedCertificate>

Solution

  • The XML excerpts you show appear to be diagnostic data generated by eSig DSS. Thus, I'll explain here what the missing entry means and why it is ok that it is missing.

    What does this missing element indicate?

    That CertificateRef element inside the RelatedCertificate here indicates that the certificate is referenced as signer certificate from a signingCertificateV2 signed attribute of the signature.

    The value of that attribute is specified in RFC 5035 as

    SigningCertificateV2 ::=  SEQUENCE {
        certs        SEQUENCE OF ESSCertIDv2,
        policies     SEQUENCE OF PolicyInformation OPTIONAL
    }
    
    ESSCertIDv2 ::=  SEQUENCE {
        hashAlgorithm           AlgorithmIdentifier
               DEFAULT {algorithm id-sha256},
        certHash                 Hash,
        issuerSerial             IssuerSerial OPTIONAL
    }
    
    Hash ::= OCTET STRING
    
    IssuerSerial ::= SEQUENCE {
        issuer                   GeneralNames,
        serialNumber             CertificateSerialNumber
    }
    

    The IssuerSerial element inside the CertificateRef element you are missing in your iText created signatures refers to the issuerSerial member of the ESSCertIDv2 in the attribute value.

    As you can already see in the definition, this issuerSerial member is marked OPTIONAL.

    Thus, the observation that the IssuerSerial element is missing shows that iText makes use of that OPTIONALity and does not include a issuerSerial member in the signingCertificateV2 attribute.

    Is it ok that iText does not include a issuerSerial here?

    First of all, as remarked above, according to RFC 5035 the element is optional, so any signature processor (e.g. a validator) must expect signatures to not include a issuerSerial member in their signingCertificateV2 attribute.

    But do the specifications in question go into more detail on this?

    RFC 5035 says

    The first certificate identified in the sequence of certificate identifiers MUST be the certificate used to verify the signature. The encoding of the ESSCertIDv2 for this certificate SHOULD include the issuerSerial field.

    I.e. it recommends inclusion of the field which at first glance would make iText's decision not to do so look inappropriate.

    But RFC 5035 here is used in the context of a CAdES signature container in a PAdES signature, so the CAdES and PAdES specification may modify this recommendation.

    The CAdES specification (ETSI EN 319 122-1) says

    The information in the IssuerSerial element is only a hint that can help to identify the certificate whose digest matches the value present in the reference. But the binding information is the digest of the certificate.

    (section 5.2.2.3 "ESS signing-certificate-v2 attribute")

    Furthermore, in the requirements for baseline profiles, that specification even says

    The issuerSerial field should not be included

    (section 6.3 "Requirements on components and services", "Additional requirements", item g)

    The PAdES specification (ETSI EN 319 142-1) here merely says

    Generators shall use either the signing certificate or the signing-certificate-v2 attribute, depending on the hash function, in accordance with ETSI EN 319 122-1

    Thus, taken all together the issuerSerial member is optional and its use, if anything, is not recommended.

    What does this mean in your case?

    The signatures you create with PdfPadesSigner's SignWithBaselineLTAProfile method in IText 8.0.3 are good, at least in respect to the aspect we discussed here, and the excerpt you called a "Must be" actually only is a "Can be" or even a "Should not be".

    Also your comment "I found out that this is used to verify signatures" indicates that the verifier who told you so does not correctly handle the attribute in question, in particular not in the context of PAdES signatures.

    An aside: an error in the time stamps in your example

    The time stamps (both the signature time stamp and the document time stamp) incorrectly encode their signed attributes: The signingCertificateV2 attribute in them is encoded like this:

    SEQUENCE (2 elem)
      OBJECT IDENTIFIER 1.2.840.113549.1.9.16.2.47 signingCertificateV2 (S/MIME Authenticated Attributes)
      SET (1 elem)
        SEQUENCE (1 elem)
          SEQUENCE (1 elem)
            SEQUENCE (2 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 (NIST Algorithm)
                NULL
              OCTET STRING (32 byte) 2E8EFCDD4C13BCB9F18E2AAD1A5391EEF0415D041171794C51EBD9BB8C5E23EE
    

    The signed attributes must be DER encoded. DER encoding in particular means that DEFAULT values are not included.

    The hash algorithm SHA-256 indicated there in your time stamps is the default value (see my quote from RFC 5035 above), so the encoding above is erroneous.

    (Not many validators actually check the DER encoding of the signed attributes in this depth, but some do. In the recent ETSI plug test the software of at least one participant did check this. Thus, with those time stamps your signatures may often be accepted but sometimes suddenly not.)

    By the way, these signingCertificateV2 attributes in your time stamps also don't include the optional issuerSerial member... ;)