Topic: PKCS#7 (CMS) - Failed to verify CMS signed-data with OpenSSL
Hi all,
I need to use CMS signed-data (RFC 5652 chapter 5) with signed attributes and parameters PKCS1 V1.5 for signature algorithm and SHA-256 for hash algorithm.
I make prototypes for testing this with your library and OpenSSL library. The CMS signed-data contain the same data to sign "This is data to test the CMS signed data", doesn't contain any signed attribute and are signed and verify respectively by client-key.der and client-cert.der found in the certs folder of the wolfSSL library.
wolfSSL CMS signed-data sample code:
// Initialize CMS
ret = wc_PKCS7_InitWithCert (&pkcs7, cert, (word32)cert_file_len);
if (ret != 0) {
printf ("wc_PKCS7_InitWithCert failed: %d\n", ret);
goto error;
}
pkcs7.privateKey = key;
pkcs7.privateKeySz = key_file_len;
pkcs7.content = (byte*)data;
pkcs7.contentSz = (word32)strlen (data);
pkcs7.contentOID = DATA;
pkcs7.hashOID = SHA256h; // SHAh
pkcs7.encryptOID = RSAk;
/*pkcs7.signedAttribs = attribs;
pkcs7.signedAttribsSz = sizeof (attribs) / sizeof (PKCS7Attrib);*/
pkcs7.rng = &rng;
// Encode CMS signed-data
int signed_data_size = wc_PKCS7_EncodeSignedData (&pkcs7, signed_data, 4096);
if (signed_data_size <= 0) {
printf ("wc_PKCS7_EncodeSignedData failed: %d\n", ret);
goto error;
}
OpenSSL verify sample code:
// Load certificate (public key)
STACK_OF (X509) *pcerts = sk_X509_new_null ();
if (!sk_X509_push (pcerts, cert)) {
printf ("sk_X509_push error");
goto error;
}
// Load CMS signed-data
bio_in_cms = BIO_new_file (CMS_SIGN_FILE, "rb");
cms_content_info_signed_data = d2i_CMS_bio (bio_in_cms, NULL);
if (!cms_content_info_signed_data) {
printf ("d2i_CMS_bio error");
goto error;
}
// Verify CMS signed-data
if (!CMS_verify (cms_content_info_signed_data, pcerts, NULL, NULL, bio_stdout, CMS_NO_SIGNER_CERT_VERIFY)) {
printf ("CMS_decrypt error");
goto error;
}
Below are the results:
wolfSSL PKCS7 encode signed-data -> wolfSSL PKCS7 verify signed-data: Works.
OpenSSL CMS sign -> OpenSSL CMS verify: Works.
wolfSSL PKCS7 encode signed-data -> OpenSSL CMS verify: Doesn't work.
OpenSSL errors:
"2648:error:04091068:rsa routines:int_rsa_verify:bad signature:crypto\rsa\rsa_sign.c:207:
2648:error:2E09A09E:CMS routines:CMS_SignerInfo_verify_content:verification failure:crypto\cms\cms_sd.c:839:
2648:error:2E09D06D:CMS routines:CMS_verify:content verify error:crypto\cms\cms_smime.c:393:"
OpenSSL CMS sign-> wolfSSL PKCS7 verify signed-data: Doesn't work.
wolfSSL error:
"wc_PKCS7_VerifySignedData failed: -173"
In error-crypt.h: "BAD_FUNC_ARG = -173, /* Bad function argument provided */"
You will found an archive file attached with :
wolfssl_cmsproject_main.c: code of CMS signed-data with wolfSSL ;
openssl_cmsproject_main.c: code of CMS signed-data with OpenSSL ;
wolfssl_data_sign.p7: CMS signed-data with wolfSSL (1806 bytes) ;
openssl_data_sign.p7: CMS signed-data with OpenSSL (1802 bytes) ;
wolfssl_data_sign_asn1parse.txt: CMS signed-data with wolfSSL parsed (openssl asn1parse -inform der -in wolfssl_data_sign.p7) ;
openssl_data_sign_asn1parse.txt: CMS signed-data with OpenSSL parsed (openssl asn1parse -inform der -in openssl_data_sign.p7).
This doesn't work with SHA-256 as well with SHA1.
The wolfSSL CMS signed-data has a different signature than the OpenSSL CMS signed-data. It has also 4 bytes more than OpenSSL with 2 bytes (0x0500) added 2 times after SHA-256 defined as you can see on wolfssl_data_sign_asn1parse.txt (41:d=5 hl=2 l= 0 prim: NULL and 1529:d=6 hl=2 l= 0 prim: NULL).
On wolfssl_data_sign_asn1parse.txt:
" 28:d=4 hl=2 l= 13 cons: SEQUENCE
30:d=5 hl=2 l= 9 prim: OBJECT :sha256
41:d=5 hl=2 l= 0 prim: NULL
43:d=3 hl=2 l= 51 cons: SEQUENCE
45:d=4 hl=2 l= 9 prim: OBJECT :pkcs7-data
...
1516:d=5 hl=2 l= 13 cons: SEQUENCE
1518:d=6 hl=2 l= 9 prim: OBJECT :sha256
1529:d=6 hl=2 l= 0 prim: NULL
1531:d=5 hl=2 l= 13 cons: SEQUENCE
1533:d=6 hl=2 l= 9 prim: OBJECT :rsaEncryption
1544:d=6 hl=2 l= 0 prim: NULL
1546:d=5 hl=4 l= 256 prim: OCTET STRING [HEX DUMP]:7E100189F79F351F878EAAD159C14AF8B74C41A4C87FD48CFB24B244D49C6DF1A14F891D73D8C36B023883DAB2F8B81810A89D4FB269CD7F8AF5E3567DF0562C20E09D80FD9FD8C2C1596D3FD2B2B550C5DBC4E7A95992B31CED7BE44B9FD261333D4F76E10C78C1656EDE6E89A54EEB4C643DAD8D9F08C999694B877D34C3470D83FAC22CBAAC833174D9B118451157B048314C0A4E28BCEDE9D53BFA007FEAF38D757EF83454EE29CAD609D350075BF5F5D95083C9064C06C6675061C465DBA05B9902EC6C6F1289920826B377035730A7A71E2863E78C47E9873837DBACC0A778B3D1C3B40577E962E5F7B97B8432DABD6A9104A8173EE90B98E04CCA0A6A"
On openssl_data_sign_asn1parse.txt:
" 28:d=4 hl=2 l= 11 cons: SEQUENCE
30:d=5 hl=2 l= 9 prim: OBJECT :sha256
41:d=3 hl=2 l= 51 cons: SEQUENCE
43:d=4 hl=2 l= 9 prim: OBJECT :pkcs7-data
...
1514:d=5 hl=2 l= 11 cons: SEQUENCE
1516:d=6 hl=2 l= 9 prim: OBJECT :sha256
1527:d=5 hl=2 l= 13 cons: SEQUENCE
1529:d=6 hl=2 l= 9 prim: OBJECT :rsaEncryption
1540:d=6 hl=2 l= 0 prim: NULL
1542:d=5 hl=4 l= 256 prim: OCTET STRING [HEX DUMP]:3FBB4D48720A6B9A92E2CA2D1E7EE3B484D4780A6DA973DA8800FC4D1F4153BD859D24E4015F9139D90BC8B26E9963223373A97D91CC0E53D4913F5DAC03802812AE4E83A7992481BB76B309497872DA12CB1EE950D053BBB0BBF827C75412EDF556FCF7C1643879E6C181BFA42496BA1F8DE5E7075DC364FF89A13FF9DB365776935C50E5E673E9AF99879D61EDA85902AB6D7179810760D8EA5E116F35389D2C8BF5C82646CD716B760AD35BFE2C1F742FF8A7ABE90B87C2F3A7F311EB001126CA7BF7443EE19928FAA006E3B15A2DFB696E17EB29AF1545ED0104C8E7BB3BC8CFD98577F4041C23212CA5CCE7592281812644BFF0093D9F93E0DA61E457E2"
Does wolfSSL sign different data than OpenSSL? It should not be compatible?
Also, I see in your function wc_PKCS7_EncodeSignedData() that you use the macro SHA_DIGEST_SIZE which is specific to SHA1.
wc_ShaUpdate(&esd->sha, pkcs7->content, pkcs7->contentSz);
esd->contentDigest[0] = ASN_OCTET_STRING;
esd->contentDigest[1] = SHA_DIGEST_SIZE;
wc_ShaFinal(&esd->sha, &esd->contentDigest[2]);
RsaKey stack_privKey;
RsaKey* privKey = &stack_privKey;
byte digestInfo[MAX_SEQ_SZ + MAX_ALGO_SZ +
MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE];
Does this mean that you don't support CMS signed-data with SHA-256?
Best regards.