mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 12:50:51 +02:00
Merge pull request #10595 from miyazakh/f5381_RSASSA-PSS_trailerField
f5381 enforce trailerField==1 in DecodeRsaPssParams
This commit is contained in:
@@ -2,6 +2,17 @@
|
||||
|
||||
## Enhancements
|
||||
|
||||
* **Behavioral change (RSA-PSS trailerField enforcement)**: `DecodeRsaPssParams`
|
||||
(and its public wrapper `wc_DecodeRsaPssParams`) now enforces RFC 8017 A.2.3,
|
||||
which mandates `trailerField == trailerFieldBC(1)`. In the default build
|
||||
(i.e., without `WOLFSSL_NO_ASN_STRICT`), any certificate or CMS/PKCS#7
|
||||
structure whose RSA-PSS parameters contain a `trailerField` value other than 1
|
||||
is now rejected with `ASN_PARSE_E`. Previously, any positive integer value was
|
||||
silently accepted. This affects all call paths that decode RSA-PSS algorithm
|
||||
parameters, including X.509 certificate parsing and PKCS#7 signature
|
||||
verification. Users who need to interoperate with non-conformant peers can
|
||||
define `WOLFSSL_NO_ASN_STRICT` to restore the previous permissive behavior.
|
||||
|
||||
* **BREAKING (FIPS 205 SLH-DSA)**: `wc_SlhDsaKey_SignHash`,
|
||||
`wc_SlhDsaKey_SignHashDeterministic`, `wc_SlhDsaKey_SignHashWithRandom`, and
|
||||
`wc_SlhDsaKey_VerifyHash` now take the **caller-pre-hashed message digest**
|
||||
|
||||
@@ -1318,6 +1318,61 @@ int test_wc_DecodeRsaPssParams(void)
|
||||
&hash, &mgf, &saltLen), WC_NO_ERR_TRACE(ASN_PARSE_E));
|
||||
}
|
||||
|
||||
/* --- Test 9: trailerField = 1 (trailerFieldBC) => valid in all modes --- */
|
||||
/* SEQUENCE { [3] CONSTRUCTED { INTEGER 1 } } = 30 05 a3 03 02 01 01 */
|
||||
{
|
||||
static const byte trailerValid[] = {
|
||||
0x30, 0x05, 0xa3, 0x03, 0x02, 0x01, 0x01
|
||||
};
|
||||
hash = WC_HASH_TYPE_NONE;
|
||||
mgf = 0;
|
||||
saltLen = 0;
|
||||
ExpectIntEQ(wc_DecodeRsaPssParams(trailerValid,
|
||||
(word32)sizeof(trailerValid), &hash, &mgf, &saltLen), 0);
|
||||
ExpectIntEQ((int)hash, (int)WC_HASH_TYPE_SHA);
|
||||
ExpectIntEQ(mgf, WC_MGF1SHA1);
|
||||
ExpectIntEQ(saltLen, 20);
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_NO_ASN_STRICT
|
||||
/* --- Test 10: trailerField = 2 => ASN_PARSE_E (strict mode) --- */
|
||||
/* RFC 8017 A.2.3: trailerField SHALL be trailerFieldBC(1). */
|
||||
/* SEQUENCE { [3] CONSTRUCTED { INTEGER 2 } } = 30 05 a3 03 02 01 02 */
|
||||
{
|
||||
static const byte trailerTwo[] = {
|
||||
0x30, 0x05, 0xa3, 0x03, 0x02, 0x01, 0x02
|
||||
};
|
||||
ExpectIntEQ(wc_DecodeRsaPssParams(trailerTwo,
|
||||
(word32)sizeof(trailerTwo), &hash, &mgf, &saltLen),
|
||||
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
||||
}
|
||||
|
||||
/* --- Test 11: trailerField = 0 => ASN_PARSE_E (strict mode) --- */
|
||||
/* SEQUENCE { [3] CONSTRUCTED { INTEGER 0 } } = 30 05 a3 03 02 01 00 */
|
||||
{
|
||||
static const byte trailerZero[] = {
|
||||
0x30, 0x05, 0xa3, 0x03, 0x02, 0x01, 0x00
|
||||
};
|
||||
ExpectIntEQ(wc_DecodeRsaPssParams(trailerZero,
|
||||
(word32)sizeof(trailerZero), &hash, &mgf, &saltLen),
|
||||
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
||||
}
|
||||
|
||||
/* --- Test 12: trailerField = 256 (multi-byte INTEGER) => ASN_PARSE_E ---
|
||||
* Exercises the 2-byte integer branch in GetInteger16Bit (non-template)
|
||||
* and the len==2 case of ASN_DATA_TYPE_WORD16 (template path).
|
||||
* SEQUENCE { [3] CONSTRUCTED { INTEGER 256 } } = 30 06 a3 04 02 02 01 00
|
||||
*/
|
||||
{
|
||||
static const byte trailerMultiByte[] = {
|
||||
0x30, 0x06, 0xa3, 0x04, 0x02, 0x02, 0x01, 0x00
|
||||
};
|
||||
ExpectIntEQ(wc_DecodeRsaPssParams(trailerMultiByte,
|
||||
(word32)sizeof(trailerMultiByte), &hash, &mgf, &saltLen),
|
||||
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
||||
}
|
||||
#endif /* !WOLFSSL_NO_ASN_STRICT */
|
||||
|
||||
#endif /* WC_RSA_PSS && !NO_RSA && !NO_ASN */
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
@@ -8074,6 +8074,9 @@ static int DecodeRsaPssParams(const byte* params, word32 sz,
|
||||
{
|
||||
DECL_ASNGETDATA(dataASN, rsaPssParamsASN_Length);
|
||||
int ret = 0;
|
||||
#ifndef WOLFSSL_NO_ASN_STRICT
|
||||
word16 trailerVal = 1;
|
||||
#endif
|
||||
word16 sLen = 20;
|
||||
|
||||
/* Default values. */
|
||||
@@ -8089,6 +8092,10 @@ static int DecodeRsaPssParams(const byte* params, word32 sz,
|
||||
GetASN_OID(&dataASN[RSAPSSPARAMSASN_IDX_MGFHOID], oidHashType);
|
||||
/* Place the salt length into 16-bit var sLen. */
|
||||
GetASN_Int16Bit(&dataASN[RSAPSSPARAMSASN_IDX_SALTLENINT], &sLen);
|
||||
#ifndef WOLFSSL_NO_ASN_STRICT
|
||||
/* Capture trailerField value for RFC 8017 A.2.3 validation. */
|
||||
GetASN_Int16Bit(&dataASN[RSAPSSPARAMSASN_IDX_TRAILERINT], &trailerVal);
|
||||
#endif
|
||||
/* Decode the algorithm identifier. */
|
||||
ret = GetASN_Items(rsaPssParamsASN, dataASN, rsaPssParamsASN_Length, 1,
|
||||
params, &inOutIdx, sz);
|
||||
@@ -8105,6 +8112,15 @@ static int DecodeRsaPssParams(const byte* params, word32 sz,
|
||||
word32 oid = dataASN[RSAPSSPARAMSASN_IDX_MGFHOID].data.oid.sum;
|
||||
ret = RsaPssHashOidToMgf1(oid, mgf);
|
||||
}
|
||||
#ifndef WOLFSSL_NO_ASN_STRICT
|
||||
/* RFC 8017 A.2.3: trailerField SHALL be trailerFieldBC(1). */
|
||||
if ((ret == 0) && (dataASN[RSAPSSPARAMSASN_IDX_TRAILERINT].tag != 0)) {
|
||||
if (trailerVal != 1) {
|
||||
WOLFSSL_MSG("DecodeRsaPssParams: trailerField must be 1");
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
*saltLen = sLen;
|
||||
}
|
||||
@@ -8251,12 +8267,26 @@ static int DecodeRsaPssParams(const byte* params, word32 sz,
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = GetInteger16Bit(params, &idx, sz);
|
||||
#ifndef WOLFSSL_NO_ASN_STRICT
|
||||
/* RFC 8017 A.2.3: trailerField SHALL be trailerFieldBC(1). */
|
||||
if (ret == 1) {
|
||||
ret = 0;
|
||||
}
|
||||
else if (ret >= 0) {
|
||||
WOLFSSL_MSG("DecodeRsaPssParams: trailerField must be 1");
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("DecodeRsaPssParams: fail at trailer_value");
|
||||
}
|
||||
#else
|
||||
if (ret > 0) {
|
||||
ret = 0;
|
||||
}
|
||||
else if (ret != 0) {
|
||||
WOLFSSL_MSG("DecodeRsaPssParams: fail at trailer_value");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user