Hello,
This is the first time I've posted on a mailing list, so sorry if the tone isn't correct.
I'm in the process of finalising a project to update OpenSSL 1.1.1 to 3.5.X with the purpose of doing ASN1 decoding and PKCS7 signing where I integrate my own cryptography via providers (digest, cipher, mac, signature, asym_cipher, keymgmt and kdf).
When implementing the detached PKCS7 signature, I tried to use ‘PKCS7_sign’ or ‘CMS_sign(NULL, NULL, NULL, NULL, CMS_PARTIAL|CMS_DETACHED) + CMS_add1_signer(...) + CMS_final(...)’, but the problem was that I systematically came across the ‘EVP_get_digestbyname’ function in the base layers.
If I understand correctly, the ‘EVP_get_digestbyname’ function is incompatible with the OpenSSL 3+ provider system. I wanted to know if there was a trick to make ‘EVP_get_digestbyname’ work or if there is a method that I haven't seen to make a detached signature in DER format.
Thank you for reading and your time.
Thank you for reading and your time.
--
You received this message because you are subscribed to the Google Groups "openssl-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openssl-user...@openssl.org.
To view this discussion visit https://groups.google.com/a/openssl.org/d/msgid/openssl-users/e3df5e46-f50d-4dcc-a852-38f2ca2014afn%40openssl.org.
Thank you for your reply and sorry for the length of mine, but I think I need to be exhaustive.
For more detail, I've tried quite a few things to make myself compatible. The executed code looks like this (I don't include error handling so as not to make the code too heavy but I handle each function return correctly):
EVP_MD *md=EVP_MD_fetch(NULL, "SHA256", NULL);
CMS_ContentInfo *pCMS=CMS_sign(NULL, NULL, NULL, NULL, CMS_PARTIAL |
CMS_DETACHED);
CMS_add1_signer(pCMS, PX509Cert, pPrivKey, md, CMS_NOATTR);
CMS_final(pCMS, pDataBIOIn, NULL, SMIME_BINARY);
If I don't prepare anything before, when I call ‘CMS_final’ I get the following error "lib(46): ossl_cms_DigestAlgorithm_init_bio(149)‘ which corresponds to ’ERR_raise(ERR_LIB_CMS, CMS_R_UNKOWN_DIGEST_ALGORITHM);".
Of the attempts I have tried, the one that seems the least
bad was to add ‘EVP_add_digest(EVP_MD_fetch(NULL, “SHA256”, NULL));’ after
initialising my providers. In this case ‘CMS_final’ does not cause an error,
but when I retrieve my signature via ‘cbP7Data=id2_CMS_ContentInfo(pCMS,
NULL);’ I get ‘cbP7Data==-1’ and the error "lib(13) : asn1_template_ex
:reason(222)' which corresponds to 'ERR_raise(ERR_LIB_ASN1,
ASN1_R_ILLEGAL_ZERO_CONTENT);" but I can't find out which one it
corresponds to.
I have the impression that something is missing when calling ‘CMS_final’ but I
can't say what.
With regard to the digest providers that I define, I implement PROV_NAMES_SHA1, PROV_NAMES_SHA256, PROV_NAMES_512 and PROV_NAMES_MD5.
Finally, I'm not sure this is very useful but, as I'm in a restricted environment, I had to limit as much as possible the modules compiled with these options when generating my OpenSSL lib (it's not impossible that I removed something too much but I don't know what):
« no-autoalginit no-afalgeng no-aria no-asan no-asm no-async no-autoload-config no-bf no-blake2 no-camellia no-capieng no-cast no-chacha no-cmac no-cmp no-crypto-mdebug-backtrace no-ct no-deprecated no-des no-dgram no-dh no-dsa no-ec no-dynamic-engine no-ec no-ec2m no-ecdh no-ecdsa no-err no-external-tests no-filenames no-fuzz-libfuzzer no-fuzz-afl no-gost no-heartbeats no-hw no-idea no-makedepend no-md2 no-md4 no-mdc2 no-msan no-multiblock no-nextprotoneg no-pinshared no-ocb no-ocsp no-pic no-posix-io no-psk no-poly1305 no-rc2 no-rc4 no-rc5 no-rdrand no-rfc3779 no-rmd160 no-scrypt no-siphash no-sm2 no-sm3 no-sm4 no-srp no-srtp no-sse2 no-ssl no-ssl-trace no-static-engine no-stdio no-tests no-threads no-ts no-ui no-ubsan no-ui-console no-unit-test no-winstore no-whirlpool no-comp no-sctp no-seed no-shared no-ec_nistp_64_gcc_128 no-egd no-dsa no-dso no-dtls no-dtls1 no-dtls1_2 no-legacy no-sock no-tls no-tls1 no-tls1_1 no-tls1_2 no-tls1_3 »
Mad
Hello,
I found the source of the problem and the solution, although it's not very elegant and there may be better ways to do it.
My goal is to create a detached PKCS7 signature, so I'm keeping the PKCS7_sign function and I have the following code (simplified, without error handling):
/* Create my own provider */
EVP_MD *md=EVP_MD_fetch(NULL, "SHA256", NULL) ;
/* Modern providers do not have this field, but it is essential for the
signature to work. We add it in a dirty way for compatibility. */
md->type=NID_sha256 ;
/* Like PKCS7_sign_ex but lighter */
PKCS7 *pP7=PKCS7_new_ex(NULL, NULL);
PKCS7_set_type(pP7, NID_pkcs7_signed) ;
PKCS7_content_new(pP7, NID_pkcs7_data) ;
/* Adding information */
PKCS7_sign_add_signer(pP7, PX509Cert, pPrivKey, md, PKCS7_NOATTR);
PKCS7_set_detached(pP7, 1) ;
/* Signature */
PKCS7_final(pP7, pDataBIOIn, NULL, PKCS7_BINARY);
The problem is caused by this call stack:
EVP_MD_get_type
PKCS7_SIGNER_INFO_set
PKCS7_add_signature
PKCS7_sign_add_signer
Since an OpenSSL 3.0+ provider does not have a “type” field when fetched, the ‘EVP_MD_get_type’ function always returns 0 and corrupts all subsequent processing because "X509_ALGOR_set0(..., OBJ_nid2obj(EVP_MD_get_type(...)), ...)“ does not set the ”digest_alg" field of my PKCS7 structure.