forked from wolfSSL/wolfssl
add test for degenerate case and allow degenerate case by default
This commit is contained in:
@ -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 \
|
||||||
|
@ -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
BIN
certs/test-degenerate.p7b
Normal file
Binary file not shown.
37
tests/api.c
37
tests/api.c
@ -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();
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
Reference in New Issue
Block a user