diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index a5f2205f5..99bb4ea5a 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1569,6 +1569,7 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz) byte* cert = NULL; byte* signedAttrib = NULL; int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0; + byte degenerate; if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0) return BAD_FUNC_ARG; @@ -1614,6 +1615,7 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz) /* Skip the set. */ idx += length; + degenerate = (length == 0)? 1 : 0; /* Get the inner ContentInfo sequence */ if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) @@ -1628,24 +1630,41 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz) return PKCS7_OID_E; } - if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) - return ASN_PARSE_E; + /* Check for content info, it could be omitted when degenerate */ + { + word32 localIdx = idx; + ret = 0; + if (pkiMsg[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) + ret = ASN_PARSE_E; - if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) <= 0) - return ASN_PARSE_E; + if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, pkiMsgSz) <= 0) + ret = ASN_PARSE_E; - if (pkiMsg[idx++] != ASN_OCTET_STRING) - return ASN_PARSE_E; + if (ret == 0 && pkiMsg[localIdx++] != ASN_OCTET_STRING) + ret = ASN_PARSE_E; - if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) - return ASN_PARSE_E; + if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, pkiMsgSz) < 0) + ret = ASN_PARSE_E; - /* Save the inner data as the content. */ - if (length > 0) { - /* Local pointer for calculating hashes later */ - pkcs7->content = content = &pkiMsg[idx]; - pkcs7->contentSz = contentSz = length; - idx += length; + /* Save the inner data as the content. */ + if (length > 0) { + /* Local pointer for calculating hashes later */ + pkcs7->content = content = &pkiMsg[localIdx]; + pkcs7->contentSz = contentSz = length; + localIdx += length; + } + + /* update idx if successful */ + if (ret == 0) { + idx = localIdx; + } + } + + /* If getting the content info failed with non degenerate then return the + * error case. Otherwise with a degenerate it is ok if the content + * info was omitted */ + if (!degenerate && ret != 0) { + return ret; } /* Get the implicit[0] set of certificates */