diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/libcrypto/asn1/a_mbstr.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/lib/libcrypto/asn1/a_mbstr.c b/src/lib/libcrypto/asn1/a_mbstr.c index 9945ede2ac..ebc7f2681c 100644 --- a/src/lib/libcrypto/asn1/a_mbstr.c +++ b/src/lib/libcrypto/asn1/a_mbstr.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #include <ctype.h> | 60 | #include <ctype.h> |
61 | #include "cryptlib.h" | 61 | #include "cryptlib.h" |
62 | #include <openssl/asn1.h> | 62 | #include <openssl/asn1.h> |
63 | #include "asn1_locl.h" | ||
63 | 64 | ||
64 | static int traverse_string(const unsigned char *p, int len, int inform, | 65 | static int traverse_string(const unsigned char *p, int len, int inform, |
65 | int (*rfunc)(unsigned long value, void *in), void *arg); | 66 | int (*rfunc)(unsigned long value, void *in), void *arg); |
@@ -232,7 +233,11 @@ ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, | |||
232 | 233 | ||
233 | case MBSTRING_UTF8: | 234 | case MBSTRING_UTF8: |
234 | outlen = 0; | 235 | outlen = 0; |
235 | traverse_string(in, len, inform, out_utf8, &outlen); | 236 | if (traverse_string(in, len, inform, out_utf8, &outlen) < 0) { |
237 | ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, | ||
238 | ASN1_R_ILLEGAL_CHARACTERS); | ||
239 | return -1; | ||
240 | } | ||
236 | cpyfunc = cpy_utf8; | 241 | cpyfunc = cpy_utf8; |
237 | break; | 242 | break; |
238 | } | 243 | } |
@@ -267,12 +272,17 @@ traverse_string(const unsigned char *p, int len, int inform, | |||
267 | } else if (inform == MBSTRING_BMP) { | 272 | } else if (inform == MBSTRING_BMP) { |
268 | value = *p++ << 8; | 273 | value = *p++ << 8; |
269 | value |= *p++; | 274 | value |= *p++; |
275 | /* BMP is explictly defined to not support surrogates */ | ||
276 | if (UNICODE_IS_SURROGATE(value)) | ||
277 | return -1; | ||
270 | len -= 2; | 278 | len -= 2; |
271 | } else if (inform == MBSTRING_UNIV) { | 279 | } else if (inform == MBSTRING_UNIV) { |
272 | value = ((unsigned long)*p++) << 24; | 280 | value = ((unsigned long)*p++) << 24; |
273 | value |= ((unsigned long)*p++) << 16; | 281 | value |= ((unsigned long)*p++) << 16; |
274 | value |= *p++ << 8; | 282 | value |= *p++ << 8; |
275 | value |= *p++; | 283 | value |= *p++; |
284 | if (value > UNICODE_MAX || UNICODE_IS_SURROGATE(value)) | ||
285 | return -1; | ||
276 | len -= 4; | 286 | len -= 4; |
277 | } else { | 287 | } else { |
278 | ret = UTF8_getc(p, len, &value); | 288 | ret = UTF8_getc(p, len, &value); |
@@ -310,9 +320,13 @@ static int | |||
310 | out_utf8(unsigned long value, void *arg) | 320 | out_utf8(unsigned long value, void *arg) |
311 | { | 321 | { |
312 | int *outlen; | 322 | int *outlen; |
323 | int ret; | ||
313 | 324 | ||
314 | outlen = arg; | 325 | outlen = arg; |
315 | *outlen += UTF8_putc(NULL, -1, value); | 326 | ret = UTF8_putc(NULL, -1, value); |
327 | if (ret < 0) | ||
328 | return ret; | ||
329 | *outlen += ret; | ||
316 | return 1; | 330 | return 1; |
317 | } | 331 | } |
318 | 332 | ||