summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/asn1/a_mbstr.c
diff options
context:
space:
mode:
authorguenther <>2014-05-20 01:21:52 +0000
committerguenther <>2014-05-20 01:21:52 +0000
commitb19e47792ae015b7179921c106605e9b7861cb0c (patch)
treed009a3ee2d810a28ee368be1fe06aaab046f09b1 /src/lib/libcrypto/asn1/a_mbstr.c
parent4dc1407574fb45b0e8985f2b8149b94dd4704437 (diff)
downloadopenbsd-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.c18
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
64static int traverse_string(const unsigned char *p, int len, int inform, 65static 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
310out_utf8(unsigned long value, void *arg) 320out_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