diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2014-05-20 01:21:53 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2014-05-20 01:21:53 +0000 |
commit | 6528dae50ba093f4181f4a89208c682ee5a13724 (patch) | |
tree | 3eea288918d741e4af93c7178c89c738c7b2db23 /lib/libcrypto/asn1/a_mbstr.c | |
parent | 3e07080ac10db207f0ceb7f41e77794e17799c9e (diff) |
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 'lib/libcrypto/asn1/a_mbstr.c')
-rw-r--r-- | lib/libcrypto/asn1/a_mbstr.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/lib/libcrypto/asn1/a_mbstr.c b/lib/libcrypto/asn1/a_mbstr.c index 9945ede2acd..ebc7f2681ca 100644 --- a/lib/libcrypto/asn1/a_mbstr.c +++ b/lib/libcrypto/asn1/a_mbstr.c @@ -60,6 +60,7 @@ #include <ctype.h> #include "cryptlib.h" #include <openssl/asn1.h> +#include "asn1_locl.h" static int traverse_string(const unsigned char *p, int len, int inform, 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, case MBSTRING_UTF8: outlen = 0; - traverse_string(in, len, inform, out_utf8, &outlen); + if (traverse_string(in, len, inform, out_utf8, &outlen) < 0) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, + ASN1_R_ILLEGAL_CHARACTERS); + return -1; + } cpyfunc = cpy_utf8; break; } @@ -267,12 +272,17 @@ traverse_string(const unsigned char *p, int len, int inform, } else if (inform == MBSTRING_BMP) { value = *p++ << 8; value |= *p++; + /* BMP is explictly defined to not support surrogates */ + if (UNICODE_IS_SURROGATE(value)) + return -1; len -= 2; } else if (inform == MBSTRING_UNIV) { value = ((unsigned long)*p++) << 24; value |= ((unsigned long)*p++) << 16; value |= *p++ << 8; value |= *p++; + if (value > UNICODE_MAX || UNICODE_IS_SURROGATE(value)) + return -1; len -= 4; } else { ret = UTF8_getc(p, len, &value); @@ -310,9 +320,13 @@ static int out_utf8(unsigned long value, void *arg) { int *outlen; + int ret; outlen = arg; - *outlen += UTF8_putc(NULL, -1, value); + ret = UTF8_putc(NULL, -1, value); + if (ret < 0) + return ret; + *outlen += ret; return 1; } |