1 (edited by bstraehl 2021-01-13 05:57:32)

Topic: PKCS#7 CMS detached signature verification failure (ASN_PARSE_E)

I try to do a verification of a detached PKCS#7 CMS signature. The verification fails with ASN_PARSE_E (-140). I'm using function wc_PKCS7_VerifySignedData_ex. The reason why it fails is an ASN.1 parsing synchronization error. It happens after the failing attempt to read non-existing signed data (after object 1.2.840.113549.1.7.1) from the signature. Instead on this position the sequence of certificates begins, but wc_PKCS7_VerifySignedData_ex already returned with ASN_PARSE_E. In my opinion, wc_PKCS7_VerifySignedData_ex should be able to handle both situations. Either there is signed data OR an implicit[0] set of certificates.

Please find attached the binary (its SHA256 was used for signing) and the resulting signature.

I used wolfSSL from https://github.com/wolfSSL/wolfssl commit: c57fee136a40f7dcd2c8315a3c6bfe602ca98b8c

Post's attachments

signature_and_binary.zip 4.87 kb, 7 downloads since 2021-01-13 

You don't have the permssions to download the attachments of this post.

Share

2 (edited by bstraehl 2021-01-15 08:18:01)

Re: PKCS#7 CMS detached signature verification failure (ASN_PARSE_E)

I attached my test application here.

Post's attachments

main.c 2.45 kb, 4 downloads since 2021-01-15 

You don't have the permssions to download the attachments of this post.

Share

Re: PKCS#7 CMS detached signature verification failure (ASN_PARSE_E)

Hi bstraehl,

Thanks for attaching your test application.  We'll look into this and get back to you shortly.

Best Regards,
Chris

Re: PKCS#7 CMS detached signature verification failure (ASN_PARSE_E)

Hello Chris

Are there any news in this concern? If it is of any help, I have a version of the function wc_PKCS7_VerifySignedData that works. I fixed the issue mainly by removing the code, which deals with the interpretation of the embedded signed data.

Best regards,
Beat

Share

Re: PKCS#7 CMS detached signature verification failure (ASN_PARSE_E)

Hi Beat,

I had a chance to look over your examples and believe you may have just been mis-using the wc_PKCS7_VerifySignedData API for use with detached signatures.

wc_PKCS7_VerifySignedData() can verify detached signatures, but your application needs to explicitly set the content and content size using the "pkcs7.content" and "pkcs7.contentSz" structure members before doing the verification.

Internally in pkcs7.c we do some detection of empty content in the PKCS#7/CMS bundle and purposefully set our internal error state to ASN_PARSE_E.  But, we recover from that error state later on once we realize the user has set the pkcs7.content and pkcs7.contentSz correctly.

I have attached a modified version of your main.c (here as main_verifySignedData.c) where I explicitly set these two struct members before doing the verification.  Compiling this against the current version of wolfSSL, I am seeing a verification success.

I did also change wc_PKCS7_VerifySignedData_ex() to the normal wc_PKCS7_VerifySignedData() in your sample application.  wc_PKCS7_VerifySignedData_ex() requires as inputs the PKCS#7/CMS "head" and "foot" as inputs that would have been received as outputs from the corresponding call to wc_PKCS7_EncodeSignedData_ex().  My guess was that you did not have these available and meant to use wc_PKCS7_VerifySignedData() instead.  But, please correct me if I am wrong.  wc_PKCS7_VerifySignedData() also handles calculation of the message digest internally, so I removed that logic from your sample code.

Best Regards,
Chris

Post's attachments

main_verifySignedData.c 2.43 kb, 6 downloads since 2021-03-18 

You don't have the permssions to download the attachments of this post.

6 (edited by bstraehl 2021-03-19 05:59:09)

Re: PKCS#7 CMS detached signature verification failure (ASN_PARSE_E)

Hello Chris,
thank you for your information. Unfortunately I don't think that this is the solution. First of all, the functions wc_PKCS7_VerifySignedData or wc_PKCS7_VerifySignedData_ex respond with an error -140, which is ASN_PARSE_E and which is not correct, because the signature, which is attached to this topic, doesn't contain ASN1 encoding errors. This can be verified with dumpasn1 or OpenSSL.

And then in contrast to my example code, our binary to be signed is not guaranteed to be a contiguous object, but can also be a set of data junks and because of this, we sign a sha256 digest derived from those. So I modified what you suggested by replacing these lines:

/* when verifying detached signature, must set content and contentSz */
pkcs7.content = buffer;
pkcs7.contentSz = bytes_read;

with this:

/* when verifying detached signature, must set content and contentSz */
pkcs7.content = shaSumOfBinary;
pkcs7.contentSz = WC_SHA256_DIGEST_SIZE;

and then called wc_PKCS7_VerifySignedData() as you suggested. But besides the already mentionen ASN_PARSE_E, this wouldn't work, because the function calculates the hash of my hash, which is not what I want. For what I want, namely the verification of a signed hash, I need function wc_PKCS7_VerifySignedData_ex, which allows me to specify the hash that was signed. Please check the comments in the wolfSSL source code for this function:

 5621 /* variant that allows computed data hash and header/foot,
 5622  * which is useful for large data signing */

Best regards,
Beat

Post's attachments

main.c 3.17 kb, 6 downloads since 2021-03-19 

You don't have the permssions to download the attachments of this post.

Share

Re: PKCS#7 CMS detached signature verification failure (ASN_PARSE_E)

Hi Beat,

Thanks for the clarification.  I now see your desire/need to pass in only the pre-computed digest of the content rather than the content itself.

Let me revisit our wc_PKCS7_VerifySignedData_ex() code and I'll get back to you shortly.

Thanks,
Chris

Re: PKCS#7 CMS detached signature verification failure (ASN_PARSE_E)

Hi Beat,

I have put up a small fix in the following Pull Request to wolfSSL that should fix your use case:

https://github.com/wolfSSL/wolfssl/pull/3996

Testing here with your sample app, with this change, your signature correctly verifies with wc_PKCS7_VerifySignedData_ex().

Best Regards,
Chris

Re: PKCS#7 CMS detached signature verification failure (ASN_PARSE_E)

After all this time I had a chance to test your solution. I clone the actual state of the repository, where master was at "8d70594". However function wc_PKCS7_VerifySignedData_ex didn't work from the beginning with our detached pre-calculated hash. I had to recompile wolfssl with PKCS7_STREAM disabled. The problem is a missing "ret = 0" here:

index 3bcbfec6f..f4c7d596e 100644
--- a/wolfcrypt/src/pkcs7.c
+++ b/wolfcrypt/src/pkcs7.c
@@ -4679,7 +4679,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
                 idx = localIdx;
             }
             else {
-
+               ret = 0;
                 /* If either pkcs7->content and pkcs7->contentSz are set
                  * (detached signature where user has set content explicitly
                  * into pkcs7->content/contentSz) OR pkcs7->hashBuf and

Because the following code section checks for the exitence of an embedded data length information, which doesn't exist in the detached case. So the GetLength_Ex will fail, which is okay. But the ret value will be checked again in the next code section, which is guarded with #ifndef NO_PKCS7_STREAM, without beeing updated by a regular function call in between. So, we have to set it by ourselfs.

            /* get length of content in case of single part */
            if (ret == 0 && !multiPart) {
                if (tag != ASN_OCTET_STRING)
                    ret = ASN_PARSE_E;

                if (ret == 0 && GetLength_ex(pkiMsg, &localIdx,
                            &length, pkiMsgSz, NO_USER_CHECK) < 0)
                    ret = ASN_PARSE_E;
            }


Do you agree?

Share

Re: PKCS#7 CMS detached signature verification failure (ASN_PARSE_E)

Hi Beat,

I'm not sure that I am following the reasoning behind needing to reset "ret = 0" at that location in pkcs7.c.  It is expected behavior that "ret" would be set to ASN_PARSE_E in the following section of code for your use case, since tag != ASN_OCTET_STRING:

            /* get length of content in case of single part */
            if (ret == 0 && !multiPart) {
                if (tag != ASN_OCTET_STRING)
                    ret = ASN_PARSE_E;

                if (ret == 0 && GetLength_ex(pkiMsg, &localIdx,
                            &length, pkiMsgSz, NO_USER_CHECK) < 0)
                    ret = ASN_PARSE_E;
            }

Later on, we enter the "else" block like you mentioned above, where "detached" gets set to 1, "length" to 0, and "contentLen" to 0.  The next time "ret" is checked is inside the "#ifndef NO_PKCS7_STREAM" section right below that, where:

            /* content expected? */
            if ((ret == 0 && length > 0) &&
                !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0)) {
                pkcs7->stream->expected = length + ASN_TAG_SZ + MAX_LENGTH_SZ;
            }

Here, the value of "ret" won't matter since "length" has already been set to 0.  Then, just a little below that, we reset the value of "ret" with the following call:

            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
                break;
            }

I re-ran your reproducer application against wolfSSL (current master), after making the following changes and verification passed successfully without the additional reset of "ret".  Changes to main.c:

1.  Removed setting "pkcs7.content" and "pkcs7.contentSz" explicitly. No longer needed for this use case after our previous modifications.
2.  Switched wc_PKCS7_VerifySignedData() to "wc_PKCS7_VerifySignedData_ex(), passing in "shaSumOfBinary".

I have re-attached the reproducer bundle I am using here.  Steps I am using to compile/test are:

$ git clone https://github.com/wolfSSL/wolfssl.git
$ cd wolfssl
$ ./autogen.sh
$ ./configure --enable-pkcs7
$ make
$ sudo make install

$ unzip signature_and_binary_v2.zip
$ cd signature_and_binary_v2
$ gcc main.c -lwolfssl
$ ./a.out -s 4dda5fe7-55d8-481a-b6eb-cf74b1b58d4d-d319ae60-1645-42b9-a9c0-eca4395587be.bin -b test.bin

calculated SHA256 of test.bin
56 d3 bb f1 e0 a9 27 b6 57 ba 90 ea 7d c0 ec e6 
ba 60 22 39 f0 ac 00 ad 8b 87 96 af ad 20 d1 40 
Sucessfully verified

Let me know if you think I'm still overlooking something, but this looks to be working as expected for this code path to me.

Thanks,
Chris

Post's attachments

signature_and_binary_v2.zip 6.69 kb, file has never been downloaded. 

You don't have the permssions to download the attachments of this post.