summaryrefslogtreecommitdiffstats
path: root/freebsd/crypto/openssl/crypto/asn1/a_strex.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/crypto/openssl/crypto/asn1/a_strex.c')
-rw-r--r--freebsd/crypto/openssl/crypto/asn1/a_strex.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/freebsd/crypto/openssl/crypto/asn1/a_strex.c b/freebsd/crypto/openssl/crypto/asn1/a_strex.c
index 8521cb39..031303c3 100644
--- a/freebsd/crypto/openssl/crypto/asn1/a_strex.c
+++ b/freebsd/crypto/openssl/crypto/asn1/a_strex.c
@@ -6,7 +6,7 @@
* 2000.
*/
/* ====================================================================
- * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2000-2018 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -196,18 +196,38 @@ static int do_buf(unsigned char *buf, int buflen,
int type, unsigned char flags, char *quotes, char_io *io_ch,
void *arg)
{
- int i, outlen, len;
+ int i, outlen, len, charwidth;
unsigned char orflags, *p, *q;
unsigned long c;
p = buf;
q = buf + buflen;
outlen = 0;
+ charwidth = type & BUF_TYPE_WIDTH_MASK;
+
+ switch (charwidth) {
+ case 4:
+ if (buflen & 3) {
+ ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+ return -1;
+ }
+ break;
+ case 2:
+ if (buflen & 1) {
+ ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_BMPSTRING_LENGTH);
+ return -1;
+ }
+ break;
+ default:
+ break;
+ }
+
while (p != q) {
if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
orflags = CHARTYPE_FIRST_ESC_2253;
else
orflags = 0;
- switch (type & BUF_TYPE_WIDTH_MASK) {
+
+ switch (charwidth) {
case 4:
c = ((unsigned long)*p++) << 24;
c |= ((unsigned long)*p++) << 16;
@@ -228,6 +248,7 @@ static int do_buf(unsigned char *buf, int buflen,
i = UTF8_getc(p, buflen, &c);
if (i < 0)
return -1; /* Invalid UTF8String */
+ buflen -= i;
p += i;
break;
default: