return -1;
}
- /* Now work out output format and string type */
+ /*
+ * Now work out output format and string type.
+ * These checks should be in sync with the checks in type_str.
+ */
outform = MBSTRING_ASC;
if (mask & B_ASN1_NUMERICSTRING)
str_type = V_ASN1_NUMERICSTRING;
case MBSTRING_UTF8:
outlen = 0;
- traverse_string(in, len, inform, out_utf8, &outlen);
+ ret = traverse_string(in, len, inform, out_utf8, &outlen);
+ if (ret < 0) {
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_UTF8STRING);
+ return -1;
+ }
cpyfunc = cpy_utf8;
break;
}
static int type_str(unsigned long value, void *arg)
{
- unsigned long types = *((unsigned long *)arg);
+ unsigned long usable_types = *((unsigned long *)arg);
+ unsigned long types = usable_types;
const int native = value > INT_MAX ? INT_MAX : ossl_fromascii(value);
+ /*
+ * Clear out all the types which are not checked later. If any of those
+ * is present in the mask, then the UTF8 type will be added and checked
+ * below.
+ */
+ types &= B_ASN1_NUMERICSTRING | B_ASN1_PRINTABLESTRING
+ | B_ASN1_IA5STRING | B_ASN1_T61STRING | B_ASN1_BMPSTRING
+ | B_ASN1_UNIVERSALSTRING | B_ASN1_UTF8STRING;
+
+ /*
+ * If any other types were in the input mask, they're effectively treated
+ * as UTF8
+ */
+ if (types != usable_types)
+ types |= B_ASN1_UTF8STRING;
+
+ /*
+ * These checks should be in sync with ASN1_mbstring_ncopy.
+ */
if ((types & B_ASN1_NUMERICSTRING) && !(ossl_isdigit(native) || native == ' '))
types &= ~B_ASN1_NUMERICSTRING;
if ((types & B_ASN1_PRINTABLESTRING) && !ossl_isasn1print(native))
p = arg;
/* We already know there is enough room so pass 0xff as the length */
ret = UTF8_putc(*p, 0xff, value);
+ if (ret < 0)
+ return ret;
*p += ret;
return 1;
}
return 1;
}
+static int test_mbstring_ncopy(void)
+{
+ ASN1_STRING *str = NULL;
+ const unsigned char in[] = { 0xFF, 0xFE, 0xFF, 0xFE };
+ int inlen = 4;
+ int inform = MBSTRING_UNIV;
+
+ if (!TEST_int_eq(ASN1_mbstring_ncopy(&str, in, inlen, inform, B_ASN1_GENERALSTRING, 0, 0), -1)
+ || !TEST_int_eq(ASN1_mbstring_ncopy(&str, in, inlen, inform, B_ASN1_VISIBLESTRING, 0, 0), -1)
+ || !TEST_int_eq(ASN1_mbstring_ncopy(&str, in, inlen, inform, B_ASN1_VIDEOTEXSTRING, 0, 0), -1)
+ || !TEST_int_eq(ASN1_mbstring_ncopy(&str, in, inlen, inform, B_ASN1_GENERALIZEDTIME, 0, 0), -1))
+ return 0;
+
+ return 1;
+}
+
int setup_tests(void)
{
ADD_TEST(test_tbl_standard);
ADD_TEST(test_invalid_utf8);
ADD_TEST(test_obj_create);
ADD_TEST(test_obj_nid_undef);
+ ADD_TEST(test_mbstring_ncopy);
return 1;
}