add test for degenerate case and allow degenerate case by default

This commit is contained in:
Jacob Barthelmeh
2018-10-30 17:04:33 -06:00
parent ba90674357
commit cc3ccbaf0c
6 changed files with 162 additions and 67 deletions

View File

@ -37,6 +37,7 @@ EXTRA_DIST += \
certs/server-revoked-cert.pem \
certs/server-revoked-key.pem \
certs/wolfssl-website-ca.pem \
certs/test-degenerate.p7b \
certs/test-servercert.p12 \
certs/ecc-rsa-server.p12 \
certs/dsaparams.pem \

View File

@ -30,6 +30,9 @@
# crl/crl.revoked
# crl/eccCliCRL.pem
# crl/eccSrvCRL.pem
#
# pkcs7:
# test-degenerate.p7b
# if HAVE_NTRU
# ntru-cert.pem
# ntru-key.raw
@ -570,6 +573,19 @@ run_renewcerts(){
echo "ran ./gencrls.sh"
echo ""
############################################################
########## generate PKCS7 bundles ##########################
############################################################
echo "Changing directory to wolfssl certs..."
echo ""
cd ../ || exit 1
echo "Creating test-degenerate.p7b..."
echo ""
openssl crl2pkcs7 -nocrl -certfile ./client-cert.pem -out test-degenerate.p7b -outform DER
check_result $? ""
echo "End of section"
echo "---------------------------------------------------------------------"
#cleanup the file system now that we're done
echo "Performing final steps, cleaning up the file system..."
echo ""

BIN
certs/test-degenerate.p7b Normal file

Binary file not shown.

View File

@ -15897,6 +15897,42 @@ static void test_wc_PKCS7_EncodeEncryptedData (void)
#endif
} /* END test_wc_PKCS7_EncodeEncryptedData() */
/*
* Testing wc_PKCS7_Degenerate()
*/
static void test_wc_PKCS7_Degenerate(void)
{
#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM)
PKCS7 pkcs7;
char fName[] = "./certs/test-degenerate.p7b";
XFILE f;
byte der[4096];
word32 derSz;
printf(testingFmt, "wc_PKCS7_Degenerate()");
AssertNotNull(f = XFOPEN(fName, "rb"));
AssertIntGT((derSz = fread(der, 1, sizeof(der), f)), 0);
XFCLOSE(f);
/* test degenerate success */
AssertIntEQ(wc_PKCS7_Init(&pkcs7, HEAP_HINT, INVALID_DEVID), 0);
AssertIntEQ(wc_PKCS7_InitWithCert(&pkcs7, NULL, 0), 0);
AssertIntEQ(wc_PKCS7_VerifySignedData(&pkcs7, der, derSz), 0);
wc_PKCS7_Free(&pkcs7);
/* test with turning off degenerate cases */
AssertIntEQ(wc_PKCS7_Init(&pkcs7, HEAP_HINT, INVALID_DEVID), 0);
AssertIntEQ(wc_PKCS7_InitWithCert(&pkcs7, NULL, 0), 0);
wc_PKCS7_AllowDegenerate(&pkcs7, 0); /* override allowing degenerate case */
AssertIntEQ(wc_PKCS7_VerifySignedData(&pkcs7, der, derSz), PKCS7_NO_SIGNER_E);
wc_PKCS7_Free(&pkcs7);
printf(resultFmt, passed);
#endif
} /* END test_wc_PKCS7_Degenerate() */
/* Testing wc_SignatureGetSize() for signature type ECC */
static int test_wc_SignatureGetSize_ecc(void)
{
@ -22474,6 +22510,7 @@ void ApiTest(void)
test_wc_PKCS7_VerifySignedData();
test_wc_PKCS7_EncodeDecodeEnvelopedData();
test_wc_PKCS7_EncodeEncryptedData();
test_wc_PKCS7_Degenerate();
test_wolfSSL_CTX_LoadCRL();

View File

@ -1897,7 +1897,33 @@ static int wc_PKCS7_ParseAttribs(PKCS7* pkcs7, byte* in, int inSz)
return found;
}
/* Finds the certificates in the message and saves it. */
/* option to turn off support for degenerate cases
* flag 0 turns off support
* flag 1 turns on support
*
* by default support for SignedData degenerate cases is on
*/
void wc_PKCS7_AllowDegenerate(PKCS7* pkcs7, word16 flag)
{
if (pkcs7) {
if (flag) { /* flag of 1 turns on support for degenerate */
pkcs7->noDegenerate = 0;
}
else { /* flag of 0 turns off support */
pkcs7->noDegenerate = 1;
}
}
}
/* Finds the certificates in the message and saves it. By default allows
* degenerate cases which can have no signer.
*
* By default expects type SIGNED_DATA (SignedData) which can have any number of
* elements in signerInfos collection, inluding zero. (RFC2315 section 9.1)
* When adding support for the case of SignedAndEnvelopedData content types a
* signer is required. In this case the PKCS7 flag noDegenerate could be set.
*/
static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
word32 hashSz, byte* pkiMsg, word32 pkiMsgSz,
byte* pkiMsg2, word32 pkiMsg2Sz)
@ -1993,6 +2019,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
/* Skip the set. */
idx += length;
degenerate = (length == 0)? 1 : 0;
if (pkcs7->noDegenerate == 1 && degenerate == 1) {
return PKCS7_NO_SIGNER_E;
}
/* Get the inner ContentInfo sequence */
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
@ -2135,8 +2164,10 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
/* update idx if successful */
if (ret == 0)
idx = localIdx;
else
pkiMsg2 = pkiMsg;
else {
pkiMsg2 = pkiMsg;
pkiMsg2Sz = pkiMsgSz;
}
/* If getting the content info failed with non degenerate then return the
* error case. Otherwise with a degenerate it is ok if the content
@ -2223,88 +2254,96 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
if (GetSet(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E;
if (length == 0)
/* require a signer if degenerate case not allowed */
if (length == 0 && pkcs7->noDegenerate == 1)
return PKCS7_NO_SIGNER_E;
/* Get the sequence of the first signerInfo */
if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E;
/* Get the version */
if (GetMyVersion(pkiMsg2, &idx, &version, pkiMsg2Sz) < 0)
return ASN_PARSE_E;
if (version != 1) {
WOLFSSL_MSG("PKCS#7 signerInfo needs to be of version 1");
return ASN_VERSION_E;
if (degenerate == 0 && length == 0) {
WOLFSSL_MSG("PKCS7 signers expected");
return PKCS7_NO_SIGNER_E;
}
/* Get the sequence of IssuerAndSerialNumber */
if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E;
/* Skip it */
idx += length;
/* Get the sequence of digestAlgorithm */
if (GetAlgoId(pkiMsg2, &idx, &hashOID, oidHashType, pkiMsg2Sz) < 0) {
return ASN_PARSE_E;
}
pkcs7->hashOID = (int)hashOID;
/* Get the IMPLICIT[0] SET OF signedAttributes */
if (pkiMsg2[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
idx++;
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
if (length > 0 && degenerate == 0) {
/* Get the sequence of the first signerInfo */
if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E;
/* save pointer and length */
signedAttrib = &pkiMsg2[idx];
signedAttribSz = length;
/* Get the version */
if (GetMyVersion(pkiMsg2, &idx, &version, pkiMsg2Sz) < 0)
return ASN_PARSE_E;
if (wc_PKCS7_ParseAttribs(pkcs7, signedAttrib, signedAttribSz) <0) {
WOLFSSL_MSG("Error parsing signed attributes");
if (version != 1) {
WOLFSSL_MSG("PKCS#7 signerInfo needs to be of version 1");
return ASN_VERSION_E;
}
/* Get the sequence of IssuerAndSerialNumber */
if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E;
/* Skip it */
idx += length;
/* Get the sequence of digestAlgorithm */
if (GetAlgoId(pkiMsg2, &idx, &hashOID, oidHashType, pkiMsg2Sz) < 0) {
return ASN_PARSE_E;
}
pkcs7->hashOID = (int)hashOID;
/* Get the IMPLICIT[0] SET OF signedAttributes */
if (pkiMsg2[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
idx++;
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E;
/* save pointer and length */
signedAttrib = &pkiMsg2[idx];
signedAttribSz = length;
if (wc_PKCS7_ParseAttribs(pkcs7, signedAttrib, signedAttribSz) <0) {
WOLFSSL_MSG("Error parsing signed attributes");
return ASN_PARSE_E;
}
idx += length;
}
/* Get digestEncryptionAlgorithm */
if (GetAlgoId(pkiMsg2, &idx, &sigOID, oidSigType, pkiMsg2Sz) < 0) {
return ASN_PARSE_E;
}
idx += length;
}
/* store public key type based on digestEncryptionAlgorithm */
ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID);
if (ret <= 0) {
WOLFSSL_MSG("Failed to set public key OID from signature");
return ret;
}
/* Get digestEncryptionAlgorithm */
if (GetAlgoId(pkiMsg2, &idx, &sigOID, oidSigType, pkiMsg2Sz) < 0) {
return ASN_PARSE_E;
}
/* Get the signature */
if (pkiMsg2[idx] == ASN_OCTET_STRING) {
idx++;
/* store public key type based on digestEncryptionAlgorithm */
ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID);
if (ret <= 0) {
WOLFSSL_MSG("Failed to set public key OID from signature");
return ret;
}
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E;
/* Get the signature */
if (pkiMsg2[idx] == ASN_OCTET_STRING) {
idx++;
/* save pointer and length */
sig = &pkiMsg2[idx];
sigSz = length;
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E;
idx += length;
}
/* save pointer and length */
sig = &pkiMsg2[idx];
sigSz = length;
pkcs7->content = content;
pkcs7->contentSz = contentSz;
idx += length;
}
pkcs7->content = content;
pkcs7->contentSz = contentSz;
ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
signedAttrib, signedAttribSz,
hashBuf, hashSz);
if (ret < 0)
return ret;
if (ret < 0)
return ret;
}
return 0;
}

View File

@ -145,6 +145,7 @@ typedef struct PKCS7 {
/* flags - up to 16-bits */
word16 isDynamic:1;
word16 noDegenerate:1; /* allow degenerate case in verify function */
/* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */
} PKCS7;
@ -164,6 +165,7 @@ WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
WOLFSSL_API int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
word32 hashSz, byte* outputHead, word32* outputHeadSz, byte* outputFoot,
word32* outputFootSz);
WOLFSSL_API void wc_PKCS7_AllowDegenerate(PKCS7* pkcs7, word16 flag);
WOLFSSL_API int wc_PKCS7_VerifySignedData(PKCS7* pkcs7,
byte* pkiMsg, word32 pkiMsgSz);
WOLFSSL_API int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,