diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index 39bedeccc..eed51ba35 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -506,6 +506,9 @@ const char* wc_GetErrorString(int error) case CRYPTOCB_UNAVAILABLE: return "Crypto callback unavailable"; + case PKCS7_SIGNEEDS_CHECK: + return "Signature found but no certificate to verify"; + default: return "unknown error number"; diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index a4e5d7e6f..cbaf5de60 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1159,6 +1159,17 @@ void wc_PKCS7_Free(PKCS7* pkcs7) pkcs7->isDynamic = 0; XFREE(pkcs7, pkcs7->heap, DYNAMIC_TYPE_PKCS7); } + + if (pkcs7->signature) { + XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGANTURE); + pkcs7->signature = NULL; + pkcs7->signatureSz = 0; + } + if (pkcs7->plainDigest) { + XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST); + pkcs7->plainDigest = NULL; + pkcs7->plainDigestSz = 0; + } } @@ -3282,6 +3293,58 @@ static int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig, return ret; } + /* If no certificates are available then store the signature and hash for + * user to verify. Make sure that different return value than success is + * returned because the signature was not verified here. */ + if (ret == 0) { + byte haveCert = 0; + int i; + + for (i = 0; i < MAX_PKCS7_CERTS; i++) { + if (pkcs7->certSz[i] == 0) + continue; + haveCert = 1; + } + + if (!haveCert) { + WOLFSSL_MSG("No certificates in bundle to verify signature"); + + /* store signature */ + XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGANTURE); + pkcs7->signature = NULL; + pkcs7->signatureSz = 0; + pkcs7->signature = (byte*)XMALLOC(sigSz, pkcs7->heap, + DYNAMIC_TYPE_SIGNATURE); + if (pkcs7->signature == NULL) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return MEMORY_E; + } + XMEMCPY(pkcs7->signature, sig, sigSz); + pkcs7->signatureSz = sigSz; + + /* store digest */ + XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST); + pkcs7->plainDigest = NULL; + pkcs7->plainDigestSz = 0; + pkcs7->plainDigest = (byte*)XMALLOC(sigSz, pkcs7->heap, + DYNAMIC_TYPE_DIGEST); + if (pkcs7->plainDigest == NULL) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return MEMORY_E; + } + XMEMCPY(pkcs7->plainDigest, plainDigest, plainDigestSz); + pkcs7->plainDigestSz = plainDigestSz; + + return PKCS7_SIGNEEDS_CHECK; + } + } + + + switch (pkcs7->publicKeyOID) { #ifndef NO_RSA @@ -4461,10 +4524,6 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, ret = wc_PKCS7_ParseSignerInfo(pkcs7, pkiMsg2, pkiMsg2Sz, &idx, degenerate, &signedAttrib, &signedAttribSz); - /* @TODO if version 3 with RFC 4108 there must be exactly 1 - SignerInfo*/ - - /* parse out the signature if present and verify it */ if (ret == 0 && length > 0 && degenerate == 0) { WOLFSSL_MSG("Parsing signature and verifying"); @@ -7203,7 +7262,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) int ret, idx = 0; int totalSz, padSz, encryptedOutSz; - int contentInfoSeqSz, outerContentTypeSz = 0, outerContentSz; + int contentInfoSeqSz = 0, outerContentTypeSz = 0, outerContentSz; byte contentInfoSeq[MAX_SEQ_SZ]; byte outerContentType[MAX_ALGO_SZ]; byte outerContent[MAX_SEQ_SZ]; diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index 891f4c088..e91fe8fdf 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -225,8 +225,9 @@ enum { WC_PKCS7_WANT_READ_E= -270, /* PKCS7 operations wants more input */ CRYPTOCB_UNAVAILABLE= -271, /* Crypto callback unavailable */ + PKCS7_SIGNEEDS_CHECK= -272, /* signature needs verified by caller */ - WC_LAST_E = -271, /* Update this to indicate last error */ + WC_LAST_E = -272, /* Update this to indicate last error */ MIN_CODE_E = -300 /* errors -101 - -299 */ /* add new companion error id strings for any new error codes diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index cc6d9f4d7..d3e284dff 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -308,6 +308,11 @@ struct PKCS7 { CallbackDecryptContent decryptionCb; CallbackWrapCEK wrapCEKCb; void* decryptionCtx; + + byte* signature; + byte* plainDigest; + word32 signatureSz; + word32 plainDigestSz; /* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */ };