Skip to content

Commit 448378c

Browse files
authored
Merge pull request #7306 from SparkiDev/asn1_validate_fix_1
ASN.1 template: validate UTF8STRING and OBJECT IDENTIFER data
2 parents 924c0fd + 084338d commit 448378c

1 file changed

Lines changed: 108 additions & 5 deletions

File tree

wolfcrypt/src/asn.c

Lines changed: 108 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,100 @@ static int GetASN_BitString(const byte* input, word32 idx, int length)
11161116
return 0;
11171117
}
11181118

1119+
#ifndef WOLFSSL_NO_ASN_STRICT
1120+
/* Check a UTF8STRING's data is valid.
1121+
*
1122+
* @param [in] input BER encoded data.
1123+
* @param [in] idx Index of UTF8STRING data.
1124+
* @param [in] length Length of input data.
1125+
* @return 0 on success.
1126+
* @return ASN_PARSE_E when data is invalid.
1127+
*/
1128+
static int GetASN_UTF8String(const byte* input, word32 idx, int length)
1129+
{
1130+
int ret = 0;
1131+
int i = 0;
1132+
1133+
while ((ret == 0) && (i < length)) {
1134+
int cnt;
1135+
1136+
/* Check code points and get count of following bytes. */
1137+
if ((input[idx + i] & 0x80) == 0x00) {
1138+
cnt = 0;
1139+
}
1140+
else if ((input[idx + i] & 0xe0) == 0xc0) {
1141+
cnt = 1;
1142+
}
1143+
else if ((input[idx + i] & 0xf0) == 0xe0) {
1144+
cnt = 2;
1145+
}
1146+
else if ((input[idx + i] & 0xf8) == 0xf0) {
1147+
cnt = 3;
1148+
}
1149+
else {
1150+
WOLFSSL_MSG("Invalid character in UTF8STRING\n");
1151+
ret = ASN_PARSE_E;
1152+
break;
1153+
}
1154+
1155+
/* Have checked first byte. */
1156+
i++;
1157+
/* Check each following byte. */
1158+
for (; cnt > 0; cnt--) {
1159+
/* Check we have enough data. */
1160+
if (i == length) {
1161+
WOLFSSL_MSG("Missing character in UTF8STRING\n");
1162+
ret = ASN_PARSE_E;
1163+
break;
1164+
}
1165+
/* Check following byte has top bit set. */
1166+
if ((input[idx + i] & 0x80) != 0x80) {
1167+
WOLFSSL_MSG("Invalid character in UTF8STRING\n");
1168+
ret = ASN_PARSE_E;
1169+
break;
1170+
}
1171+
i++;
1172+
}
1173+
}
1174+
1175+
return ret;
1176+
}
1177+
#endif
1178+
1179+
/* Check an OBJECT IDENTIFIER's data is valid.
1180+
*
1181+
* X.690 8.19
1182+
*
1183+
* @param [in] input BER encoded data.
1184+
* @param [in] idx Index of OBJECT IDENTIFIER data.
1185+
* @param [in] length Length of input data.
1186+
* @return 0 on success.
1187+
* @return ASN_PARSE_E when data is invalid.
1188+
*/
1189+
static int GetASN_ObjectId(const byte* input, word32 idx, int length)
1190+
{
1191+
int ret = 0;
1192+
1193+
/* OID data must be at least 3 bytes. */
1194+
if (length < 3) {
1195+
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1196+
WOLFSSL_MSG_VSNPRINTF("OID length must be 3 or more: %d", len);
1197+
#else
1198+
WOLFSSL_MSG("OID length less than 3");
1199+
#endif
1200+
ret = ASN_PARSE_E;
1201+
}
1202+
/* Last octet of a subidentifier has bit 8 clear. Last octet must be last
1203+
* of a subidentifier. Ensure last octet hasn't got top bit set indicating.
1204+
*/
1205+
else if ((input[idx + length - 1] & 0x80) != 0x00) {
1206+
WOLFSSL_MSG("OID last octet has top bit set");
1207+
ret = ASN_PARSE_E;
1208+
}
1209+
1210+
return ret;
1211+
}
1212+
11191213
/* Get the ASN.1 items from the BER encoding.
11201214
*
11211215
* @param [in] asn ASN.1 item expected.
@@ -1581,11 +1675,20 @@ int GetASN_Items(const ASNItem* asn, ASNGetData *data, int count, int complete,
15811675
idx++;
15821676
len--;
15831677
}
1584-
else if ((asn[i].tag == ASN_OBJECT_ID) && (len < 3)) {
1585-
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1586-
WOLFSSL_MSG_VSNPRINTF("OID length must be 3 or more: %d", len);
1587-
#endif
1588-
return ASN_PARSE_E;
1678+
#ifndef WOLFSSL_NO_ASN_STRICT
1679+
else if ((asn[i].tag == ASN_UTF8STRING) ||
1680+
(data[i].tag == ASN_UTF8STRING)) {
1681+
/* Check validity of data. */
1682+
err = GetASN_UTF8String(input, idx, len);
1683+
if (err != 0)
1684+
return err;
1685+
}
1686+
#endif
1687+
else if (asn[i].tag == ASN_OBJECT_ID) {
1688+
/* Check validity of data. */
1689+
err = GetASN_ObjectId(input, idx, len);
1690+
if (err != 0)
1691+
return err;
15891692
}
15901693

15911694
/* Don't parse data if only header required. */

0 commit comments

Comments
 (0)