@@ -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