Skip to content

Commit 0aaf736

Browse files
committed
Fix DecodeObjectId unknown ext parse
1 parent 5b9d0a1 commit 0aaf736

4 files changed

Lines changed: 89 additions & 7 deletions

File tree

tests/api/test_asn.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,3 +920,76 @@ int test_wc_DecodeRsaPssParams(void)
920920
#endif /* WC_RSA_PSS && !NO_RSA && !NO_ASN */
921921
return EXPECT_RESULT();
922922
}
923+
924+
int test_wc_DecodeObjectId(void)
925+
{
926+
EXPECT_DECLS;
927+
928+
#if defined(HAVE_OID_DECODING) || defined(WOLFSSL_ASN_PRINT)
929+
{
930+
/* OID 1.2.840.113549.1.1.11 (sha256WithRSAEncryption)
931+
* DER encoding: 2a 86 48 86 f7 0d 01 01 0b
932+
* First byte 0x2a = 42 => arc0 = 42/40 = 1, arc1 = 42%40 = 2
933+
* Remaining arcs: 840, 113549, 1, 1, 11
934+
*/
935+
static const byte oid_sha256rsa[] = {
936+
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b
937+
};
938+
word16 out[MAX_OID_SZ];
939+
word32 outSz;
940+
941+
/* Test 1: Normal decode */
942+
outSz = MAX_OID_SZ;
943+
ExpectIntEQ(DecodeObjectId(oid_sha256rsa, sizeof(oid_sha256rsa),
944+
out, &outSz), 0);
945+
ExpectIntEQ((int)outSz, 7);
946+
ExpectIntEQ(out[0], 1);
947+
ExpectIntEQ(out[1], 2);
948+
ExpectIntEQ(out[2], 840);
949+
ExpectIntEQ(out[3], (word16)113549); /* truncated to word16 */
950+
ExpectIntEQ(out[4], 1);
951+
ExpectIntEQ(out[5], 1);
952+
ExpectIntEQ(out[6], 11);
953+
954+
/* Test 2: NULL args */
955+
outSz = MAX_OID_SZ;
956+
ExpectIntEQ(DecodeObjectId(NULL, sizeof(oid_sha256rsa), out, &outSz),
957+
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
958+
ExpectIntEQ(DecodeObjectId(oid_sha256rsa, sizeof(oid_sha256rsa),
959+
out, NULL),
960+
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
961+
962+
/* Test 3 (Bug 1): outSz=1 must return BUFFER_E, not OOB write.
963+
* The first OID byte decodes into two arcs, so outSz must be >= 2. */
964+
outSz = 1;
965+
ExpectIntEQ(DecodeObjectId(oid_sha256rsa, sizeof(oid_sha256rsa),
966+
out, &outSz),
967+
WC_NO_ERR_TRACE(BUFFER_E));
968+
969+
/* Test 4: outSz=0 must also return BUFFER_E */
970+
outSz = 0;
971+
ExpectIntEQ(DecodeObjectId(oid_sha256rsa, sizeof(oid_sha256rsa),
972+
out, &outSz),
973+
WC_NO_ERR_TRACE(BUFFER_E));
974+
975+
/* Test 5: outSz=2 is enough for a single-byte OID (two arcs) */
976+
{
977+
static const byte oid_one_byte[] = { 0x2a }; /* 1.2 */
978+
outSz = 2;
979+
ExpectIntEQ(DecodeObjectId(oid_one_byte, sizeof(oid_one_byte),
980+
out, &outSz), 0);
981+
ExpectIntEQ((int)outSz, 2);
982+
ExpectIntEQ(out[0], 1);
983+
ExpectIntEQ(out[1], 2);
984+
}
985+
986+
/* Test 6: Buffer too small for later arcs */
987+
outSz = 3; /* only room for 3 arcs, but OID has 8 */
988+
ExpectIntEQ(DecodeObjectId(oid_sha256rsa, sizeof(oid_sha256rsa),
989+
out, &outSz),
990+
WC_NO_ERR_TRACE(BUFFER_E));
991+
}
992+
#endif /* HAVE_OID_DECODING || WOLFSSL_ASN_PRINT */
993+
994+
return EXPECT_RESULT();
995+
}

tests/api/test_asn.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ int test_GetSetShortInt(void);
2929
int test_wc_IndexSequenceOf(void);
3030
int test_wolfssl_local_MatchBaseName(void);
3131
int test_wc_DecodeRsaPssParams(void);
32+
int test_wc_DecodeObjectId(void);
3233

3334
#define TEST_ASN_DECLS \
3435
TEST_DECL_GROUP("asn", test_SetAsymKeyDer), \
3536
TEST_DECL_GROUP("asn", test_GetSetShortInt), \
3637
TEST_DECL_GROUP("asn", test_wc_IndexSequenceOf), \
3738
TEST_DECL_GROUP("asn", test_wolfssl_local_MatchBaseName), \
38-
TEST_DECL_GROUP("asn", test_wc_DecodeRsaPssParams)
39+
TEST_DECL_GROUP("asn", test_wc_DecodeRsaPssParams), \
40+
TEST_DECL_GROUP("asn", test_wc_DecodeObjectId)
3941

4042
#endif /* WOLFCRYPT_TEST_ASN_H */

wolfcrypt/src/asn.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6808,15 +6808,18 @@ int DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)
68086808
t = (t << 7) | (in[x] & 0x7F);
68096809
cnt++;
68106810
if (!(in[x] & 0x80)) {
6811-
if (y >= (int)*outSz) {
6812-
return BUFFER_E;
6813-
}
68146811
if (y == 0) {
6812+
if ((int)*outSz < 2) {
6813+
return BUFFER_E;
6814+
}
68156815
out[0] = (word16)(t / 40);
68166816
out[1] = (word16)(t % 40);
68176817
y = 2;
68186818
}
68196819
else {
6820+
if (y >= (int)*outSz) {
6821+
return BUFFER_E;
6822+
}
68206823
out[y++] = (word16)t;
68216824
}
68226825
t = 0; /* reset tmp */
@@ -6913,7 +6916,7 @@ static int DumpOID(const byte* oidData, word32 oidSz, word32 oid,
69136916
#ifdef HAVE_OID_DECODING
69146917
{
69156918
word16 decOid[MAX_OID_SZ];
6916-
word32 decOidSz = sizeof(decOid);
6919+
word32 decOidSz = MAX_OID_SZ;
69176920
/* Decode the OID into dotted form. */
69186921
ret = DecodeObjectId(oidData, oidSz, decOid, &decOidSz);
69196922
if (ret == 0) {
@@ -24060,7 +24063,7 @@ static int DecodeCertExtensions(DecodedCert* cert)
2406024063
if (isUnknownExt && (cert->unknownExtCallback != NULL ||
2406124064
cert->unknownExtCallbackEx != NULL)) {
2406224065
word16 decOid[MAX_OID_SZ];
24063-
word32 decOidSz = sizeof(decOid);
24066+
word32 decOidSz = MAX_OID_SZ;
2406424067
ret = DecodeObjectId(
2406524068
dataASN[CERTEXTASN_IDX_OID].data.oid.data,
2406624069
dataASN[CERTEXTASN_IDX_OID].data.oid.length,

wolfssl/wolfcrypt/asn.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2247,6 +2247,10 @@ typedef enum MimeStatus
22472247
#define SetAlgoID wc_SetAlgoID
22482248
#define SetAsymKeyDer wc_SetAsymKeyDer
22492249
#define CalcHashId wc_CalcHashId
2250+
#if defined(HAVE_OID_DECODING) || defined(WOLFSSL_ASN_PRINT) || \
2251+
defined(OPENSSL_ALL)
2252+
#define DecodeObjectId wc_DecodeObjectId
2253+
#endif
22502254
#if defined(WOLFSSL_AKID_NAME) && !defined(GetCAByAKID)
22512255
/* GetCAByAKID() has two implementations, a full implementation in
22522256
* src/ssl.c, and a dummy implementation in wolfcrypt/src/asn.c for
@@ -2484,7 +2488,7 @@ WOLFSSL_LOCAL word32 wc_oid_sum(const byte* input, int length);
24842488
#endif
24852489
#if defined(HAVE_OID_DECODING) || defined(WOLFSSL_ASN_PRINT) || \
24862490
defined(OPENSSL_ALL)
2487-
WOLFSSL_LOCAL int DecodeObjectId(const byte* in, word32 inSz,
2491+
WOLFSSL_TEST_VIS int DecodeObjectId(const byte* in, word32 inSz,
24882492
word16* out, word32* outSz);
24892493
#endif
24902494
WOLFSSL_LOCAL int GetASNObjectId(const byte* input, word32* inOutIdx, int* len,

0 commit comments

Comments
 (0)