64 lines
1.9 KiB
Diff
64 lines
1.9 KiB
Diff
diff --git a/crypto/asn1/a_mbstr.c b/crypto/asn1/a_mbstr.c
|
|
index 05b8ac8706f..7221e843b03 100644
|
|
--- a/crypto/asn1/a_mbstr.c
|
|
+++ b/crypto/asn1/a_mbstr.c
|
|
@@ -185,11 +185,27 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
|
|
break;
|
|
|
|
case MBSTRING_BMP:
|
|
+ if (nchar > INT_MAX / 2) {
|
|
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG);
|
|
+ if (free_out) {
|
|
+ ASN1_STRING_free(dest);
|
|
+ *out = NULL;
|
|
+ }
|
|
+ return -1;
|
|
+ }
|
|
outlen = nchar << 1;
|
|
cpyfunc = cpy_bmp;
|
|
break;
|
|
|
|
case MBSTRING_UNIV:
|
|
+ if (nchar > INT_MAX / 4) {
|
|
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG);
|
|
+ if (free_out) {
|
|
+ ASN1_STRING_free(dest);
|
|
+ *out = NULL;
|
|
+ }
|
|
+ return -1;
|
|
+ }
|
|
outlen = nchar << 2;
|
|
cpyfunc = cpy_univ;
|
|
break;
|
|
@@ -197,8 +213,11 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
|
|
case MBSTRING_UTF8:
|
|
outlen = 0;
|
|
ret = traverse_string(in, len, inform, out_utf8, &outlen);
|
|
- if (ret < 0) {
|
|
- ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_UTF8STRING);
|
|
+ if (ret < 0) { /* error already raised in out_utf8() */
|
|
+ if (free_out) {
|
|
+ ASN1_STRING_free(dest);
|
|
+ *out = NULL;
|
|
+ }
|
|
return -1;
|
|
}
|
|
cpyfunc = cpy_utf8;
|
|
@@ -281,9 +300,15 @@ static int out_utf8(unsigned long value, void *arg)
|
|
int *outlen, len;
|
|
|
|
len = UTF8_putc(NULL, -1, value);
|
|
- if (len <= 0)
|
|
+ if (len <= 0) {
|
|
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_UTF8STRING);
|
|
return len;
|
|
+ }
|
|
outlen = arg;
|
|
+ if (*outlen > INT_MAX - len) {
|
|
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG);
|
|
+ return -1;
|
|
+ }
|
|
*outlen += len;
|
|
return 1;
|
|
}
|