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?

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

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

I attached my test application here.

5

(2 replies, posted in wolfCrypt)

Hello Tesfa
Yes, I also think it makes sense. And regarding the internal request, don't hurry. For the time being, I can easily live with a copy-and-pasted version of GetTimeString, if necessary.
Thank you.
BR,
Beat

6

(2 replies, posted in wolfCrypt)

After a PKCS#7 CMS verification I want to read out the signing date/time from the signature. I do this as follows:

  byte buffer[1024];      
  const byte signingTimeOid[] =
          { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x05 };
  word32 bufferSize = sizeof(buffer);
  result = wc_PKCS7_GetAttributeValue(&pkcs7, signingTimeOid, sizeof(signingTimeOid), buffer, &bufferSize);
  printf("signing time result=%d\n", result);
  if (result>0) {
    char resultingDateTime[100];
    result = GetTimeString(buffer,ASN_UTC_TIME,resultingDateTime,sizeof(resultingDateTime));
    if (result) {
      printf("signing time is %s\n", resultingDateTime);
    } else {
      printf("signing time conversion failed (not UTC format?)\n");
    }
  } else {
    printf("failed to read signing time\n");
  }

While I'm allowed to use public function wc_PKCS7_GetAttributeValue, I'm not allowed to convert the result to a human readable format with GetTimeString, because latter is not for public use. So I'm forced to implement such a formatter by myself. Why's this?

Best regards,
Beat Straehl

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