diff options
author | guenther <> | 2014-05-20 01:21:52 +0000 |
---|---|---|
committer | guenther <> | 2014-05-20 01:21:52 +0000 |
commit | b19e47792ae015b7179921c106605e9b7861cb0c (patch) | |
tree | d009a3ee2d810a28ee368be1fe06aaab046f09b1 /src/lib/libcrypto/asn1/a_mbstr.c | |
parent | 4dc1407574fb45b0e8985f2b8149b94dd4704437 (diff) | |
download | openbsd-b19e47792ae015b7179921c106605e9b7861cb0c.tar.gz openbsd-b19e47792ae015b7179921c106605e9b7861cb0c.tar.bz2 openbsd-b19e47792ae015b7179921c106605e9b7861cb0c.zip |
Bring UTF8_{getc,putc} up-to-date: it's been a decade since 5- and 6-byte
encodings and encoding of surrogate pair code points were banned. Add
checks for those, both to those functions and to the code decoding the
BMP and UNIV encodings.
ok miod@
Diffstat (limited to 'src/lib/libcrypto/asn1/a_mbstr.c')
-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 | ||