esig / dss-demonstrations

Examples of DSS integration
GNU Lesser General Public License v2.1
92 stars 70 forks source link

SigningCertificateV2 error in DSS verification #52

Closed IonutCorbu closed 8 months ago

IonutCorbu commented 9 months ago

Hello! I'm trying to develop an API for PAdES Signatures using OpenSSL and I have an issue while adding signingCertificatev2 attribute which is required by PAdES standard. The slice of code where i work with signing certificate is this one:

ESS_SIGNING_CERT_V2* signing_cert = OSSL_ESS_signing_cert_v2_new_init(EVP_get_digestbyname(this->hash_type.c_str()), this->x509_cert, this->x509_chain, -1);

    int len_sign_cert = i2d_ESS_SIGNING_CERT_V2(signing_cert, NULL);

    unsigned char* encoded_data = (unsigned char*)malloc(len_sign_cert * sizeof(unsigned char));
    unsigned char* copy = encoded_data;
    i2d_ESS_SIGNING_CERT_V2(signing_cert, &encoded_data);

    ASN1_OCTET_STRING* octet_string = ASN1_OCTET_STRING_new();
    ASN1_OCTET_STRING_set(octet_string, copy, len_sign_cert);

    PKCS7_add_signed_attribute(p7Si, NID_id_smime_aa_signingCertificateV2, V_ASN1_OCTET_STRING, octet_string);

Now, the issue is that my signature is recognized by FoxitReader, but not by AdobeReader. The error that I encounter is this one: image

In FoxitReader, the signature does not have any problem: image

Using DSS Verification I obtained the following results: image image

The strange thing is that I can find the signingcertificatev2 field in the signature when I use cyberchef: image

I was thinking that maybe I'm using wrong ESS_SIGNING_CERT_V2. I attach the signature prettified with Cyberchef after decoding DER. decoded asn1_signature.txt

I attach here also the report of DSS: DSS-Detailed-report.pdf

I used a GemBox PKCS12 for testing.

Could you help me? Best Wishes, Ionut Corbu

bsanchezb commented 9 months ago

Hi,

It seems like the structure of the applied signingCertificateV2 element is not correct. In your sample, it starts from an OCTETSTRING, while it should begin with a SEQUENCE, see RFC 5035. See below an example of a valid signingCertificateV2 attribute:

SEQUENCE
  ObjectIdentifier signingCertificateV2 (1 2 840 113549 1 9 16 2 47)
  SET
    SEQUENCE
      SEQUENCE
        SEQUENCE
          OCTETSTRING d2db2 <...> b5dad
          SEQUENCE
            SEQUENCE
              [4]
                SEQUENCE
                  SET
                    SEQUENCE
                      ObjectIdentifier countryName (2 5 4 6)
                      PrintableString 'SI'
                  SET
                    SEQUENCE
                      ObjectIdentifier organizationName (2 5 4 10)
                      PrintableString 'Ha'
                  SET
                    SEQUENCE
                      ObjectIdentifier organizationIdentifier (2 5 4 97)
                      PrintableString 'VA'
                  SET
                    SEQUENCE
                      ObjectIdentifier commonName (2 5 4 3)
                      PrintableString 'TEST'
            INTEGER 33ae

Best regards, Aleksandr

IonutCorbu commented 8 months ago

Thank you! I'm still trying to solve the problem!

IonutCorbu commented 8 months ago

I figured it out! The correct way to add the ess_signing_certificate is using OpenSSL is:

ESS_SIGNING_CERT_V2* signing_cert = OSSL_ESS_signing_cert_v2_new_init(EVP_get_digestbyname(this->hash_type.c_str()), this->x509_cert, this->x509_chain, -1);

int len_sign_cert = i2d_ESS_SIGNING_CERT_V2(signing_cert, NULL);

unsigned char* encoded_data = (unsigned char*)malloc(len_sign_cert * sizeof(unsigned char));

unsigned char* p = encoded_data; // i2d function is moving the pointer so we have to save the initial position
i2d_ESS_SIGNING_CERT_V2(signing_cert, &p);

ASN1_STRING* seq = ASN1_STRING_new();
ASN1_STRING_set(seq, encoded_data, len_sign_cert);
PKCS7_add_signed_attribute(p7Si, NID_id_smime_aa_signingCertificateV2, V_ASN1_SEQUENCE, seq);

This is a slice of code, some attributes are initialized as members of a class. I hope this would help other people who will have the same issue!