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-cert.pem \
certs/server-revoked-key.pem \ certs/server-revoked-key.pem \
certs/wolfssl-website-ca.pem \ certs/wolfssl-website-ca.pem \
certs/test-degenerate.p7b \
certs/test-servercert.p12 \ certs/test-servercert.p12 \
certs/ecc-rsa-server.p12 \ certs/ecc-rsa-server.p12 \
certs/dsaparams.pem \ certs/dsaparams.pem \

View File

@ -30,6 +30,9 @@
# crl/crl.revoked # crl/crl.revoked
# crl/eccCliCRL.pem # crl/eccCliCRL.pem
# crl/eccSrvCRL.pem # crl/eccSrvCRL.pem
#
# pkcs7:
# test-degenerate.p7b
# if HAVE_NTRU # if HAVE_NTRU
# ntru-cert.pem # ntru-cert.pem
# ntru-key.raw # ntru-key.raw
@ -570,6 +573,19 @@ run_renewcerts(){
echo "ran ./gencrls.sh" echo "ran ./gencrls.sh"
echo "" 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 #cleanup the file system now that we're done
echo "Performing final steps, cleaning up the file system..." echo "Performing final steps, cleaning up the file system..."
echo "" 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 #endif
} /* END test_wc_PKCS7_EncodeEncryptedData() */ } /* 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 */ /* Testing wc_SignatureGetSize() for signature type ECC */
static int test_wc_SignatureGetSize_ecc(void) static int test_wc_SignatureGetSize_ecc(void)
{ {
@ -22474,6 +22510,7 @@ void ApiTest(void)
test_wc_PKCS7_VerifySignedData(); test_wc_PKCS7_VerifySignedData();
test_wc_PKCS7_EncodeDecodeEnvelopedData(); test_wc_PKCS7_EncodeDecodeEnvelopedData();
test_wc_PKCS7_EncodeEncryptedData(); test_wc_PKCS7_EncodeEncryptedData();
test_wc_PKCS7_Degenerate();
test_wolfSSL_CTX_LoadCRL(); test_wolfSSL_CTX_LoadCRL();

View File

@ -1897,7 +1897,33 @@ static int wc_PKCS7_ParseAttribs(PKCS7* pkcs7, byte* in, int inSz)
return found; 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, static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
word32 hashSz, byte* pkiMsg, word32 pkiMsgSz, word32 hashSz, byte* pkiMsg, word32 pkiMsgSz,
byte* pkiMsg2, word32 pkiMsg2Sz) byte* pkiMsg2, word32 pkiMsg2Sz)
@ -1993,6 +2019,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
/* Skip the set. */ /* Skip the set. */
idx += length; idx += length;
degenerate = (length == 0)? 1 : 0; degenerate = (length == 0)? 1 : 0;
if (pkcs7->noDegenerate == 1 && degenerate == 1) {
return PKCS7_NO_SIGNER_E;
}
/* Get the inner ContentInfo sequence */ /* Get the inner ContentInfo sequence */
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0) if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
@ -2135,8 +2164,10 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
/* update idx if successful */ /* update idx if successful */
if (ret == 0) if (ret == 0)
idx = localIdx; idx = localIdx;
else else {
pkiMsg2 = pkiMsg; pkiMsg2 = pkiMsg;
pkiMsg2Sz = pkiMsgSz;
}
/* If getting the content info failed with non degenerate then return the /* If getting the content info failed with non degenerate then return the
* error case. Otherwise with a degenerate it is ok if the content * 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) if (GetSet(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E; 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; return PKCS7_NO_SIGNER_E;
/* Get the sequence of the first signerInfo */ if (degenerate == 0 && length == 0) {
if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) WOLFSSL_MSG("PKCS7 signers expected");
return ASN_PARSE_E; return PKCS7_NO_SIGNER_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;
} }
/* Get the sequence of IssuerAndSerialNumber */ if (length > 0 && degenerate == 0) {
if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) /* Get the sequence of the first signerInfo */
return ASN_PARSE_E; if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
/* 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; return ASN_PARSE_E;
/* save pointer and length */ /* Get the version */
signedAttrib = &pkiMsg2[idx]; if (GetMyVersion(pkiMsg2, &idx, &version, pkiMsg2Sz) < 0)
signedAttribSz = length; return ASN_PARSE_E;
if (wc_PKCS7_ParseAttribs(pkcs7, signedAttrib, signedAttribSz) <0) { if (version != 1) {
WOLFSSL_MSG("Error parsing signed attributes"); 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; 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 */ /* Get the signature */
if (GetAlgoId(pkiMsg2, &idx, &sigOID, oidSigType, pkiMsg2Sz) < 0) { if (pkiMsg2[idx] == ASN_OCTET_STRING) {
return ASN_PARSE_E; idx++;
}
/* store public key type based on digestEncryptionAlgorithm */ if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID); return ASN_PARSE_E;
if (ret <= 0) {
WOLFSSL_MSG("Failed to set public key OID from signature");
return ret;
}
/* Get the signature */ /* save pointer and length */
if (pkiMsg2[idx] == ASN_OCTET_STRING) { sig = &pkiMsg2[idx];
idx++; sigSz = length;
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) idx += length;
return ASN_PARSE_E; }
/* save pointer and length */ pkcs7->content = content;
sig = &pkiMsg2[idx]; pkcs7->contentSz = contentSz;
sigSz = length;
idx += length; ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
}
pkcs7->content = content;
pkcs7->contentSz = contentSz;
ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
signedAttrib, signedAttribSz, signedAttrib, signedAttribSz,
hashBuf, hashSz); hashBuf, hashSz);
if (ret < 0) if (ret < 0)
return ret; return ret;
}
return 0; return 0;
} }

View File

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