aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2018-01-04 01:21:24 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2018-01-04 01:21:24 +0000
commitf844b0f31fd8038b492db2647f9a67b3fcdf8b10 (patch)
treeb571bbc36208c57e3748d16b9375ad2e951e5e74
parent853ed450d7b87513e6066757cbbf0350ab5dc59a (diff)
downloadsrc-f844b0f31fd8038b492db2647f9a67b3fcdf8b10.tar.gz
src-f844b0f31fd8038b492db2647f9a67b3fcdf8b10.zip
MFS: r295060, r296462, r296597-296598, r299053, r306229, r306335, r308200
Sync. OpenSSL with stable/9. r295060 (delphij): Fix OpenSSL SSLv2 ciphersuite downgrade vulnerability. [SA-16:11] r296462, r296597-296598 (delphij): Fix multiple OpenSSL vulnerabilities. [SA-16:12] r299053 (delphij): Fix several OpenSSL vulnerabilities. [SA-16:17] r306229, r306335 (delphij): Fix multiple OpenSSL vulnerabilities. [SA-16:26] r308200 (delphij): Fix OpenSSL remote DoS vulnerability. [SA-16:35] Requested by: danfe
Notes
Notes: svn path=/stable/8/; revision=327537
-rw-r--r--crypto/openssl/crypto/asn1/a_type.c2
-rw-r--r--crypto/openssl/crypto/asn1/tasn_dec.c2
-rw-r--r--crypto/openssl/crypto/asn1/tasn_enc.c2
-rw-r--r--crypto/openssl/crypto/bio/b_print.c578
-rw-r--r--crypto/openssl/crypto/bn/bn.h38
-rw-r--r--crypto/openssl/crypto/bn/bn_exp.c65
-rw-r--r--crypto/openssl/crypto/bn/bn_print.c91
-rw-r--r--crypto/openssl/crypto/dsa/dsa_ossl.c7
-rw-r--r--crypto/openssl/crypto/evp/encode.c12
-rw-r--r--crypto/openssl/crypto/evp/evp_enc.c2
-rw-r--r--crypto/openssl/crypto/mdc2/mdc2dgst.c2
-rw-r--r--crypto/openssl/crypto/x509/x509_obj.c5
-rw-r--r--crypto/openssl/doc/apps/ciphers.pod22
-rw-r--r--crypto/openssl/ssl/d1_both.c32
-rw-r--r--crypto/openssl/ssl/d1_clnt.c1
-rw-r--r--crypto/openssl/ssl/d1_lib.c37
-rw-r--r--crypto/openssl/ssl/d1_pkt.c116
-rw-r--r--crypto/openssl/ssl/d1_srvr.c3
-rw-r--r--crypto/openssl/ssl/s2_lib.c84
-rw-r--r--crypto/openssl/ssl/s2_srvr.c15
-rw-r--r--crypto/openssl/ssl/s3_clnt.c11
-rw-r--r--crypto/openssl/ssl/s3_pkt.c15
-rw-r--r--crypto/openssl/ssl/s3_srvr.c22
-rw-r--r--crypto/openssl/ssl/ssl.h2
-rw-r--r--crypto/openssl/ssl/ssl3.h2
-rw-r--r--crypto/openssl/ssl/ssl_err.c4
-rw-r--r--crypto/openssl/ssl/ssl_lib.c19
-rw-r--r--crypto/openssl/ssl/ssl_locl.h7
-rw-r--r--crypto/openssl/ssl/ssl_sess.c2
-rw-r--r--crypto/openssl/ssl/t1_lib.c103
30 files changed, 804 insertions, 499 deletions
diff --git a/crypto/openssl/crypto/asn1/a_type.c b/crypto/openssl/crypto/asn1/a_type.c
index 69a5cf6f413e..be6eeedf3d94 100644
--- a/crypto/openssl/crypto/asn1/a_type.c
+++ b/crypto/openssl/crypto/asn1/a_type.c
@@ -123,9 +123,7 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
result = 0; /* They do not have content. */
break;
case V_ASN1_INTEGER:
- case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
- case V_ASN1_NEG_ENUMERATED:
case V_ASN1_BIT_STRING:
case V_ASN1_OCTET_STRING:
case V_ASN1_SEQUENCE:
diff --git a/crypto/openssl/crypto/asn1/tasn_dec.c b/crypto/openssl/crypto/asn1/tasn_dec.c
index 91e769811337..c72ed08f41d9 100644
--- a/crypto/openssl/crypto/asn1/tasn_dec.c
+++ b/crypto/openssl/crypto/asn1/tasn_dec.c
@@ -901,9 +901,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
break;
case V_ASN1_INTEGER:
- case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
- case V_ASN1_NEG_ENUMERATED:
tint = (ASN1_INTEGER **)pval;
if (!c2i_ASN1_INTEGER(tint, &cont, len))
goto err;
diff --git a/crypto/openssl/crypto/asn1/tasn_enc.c b/crypto/openssl/crypto/asn1/tasn_enc.c
index b93f3f69c7b6..928416db314e 100644
--- a/crypto/openssl/crypto/asn1/tasn_enc.c
+++ b/crypto/openssl/crypto/asn1/tasn_enc.c
@@ -610,9 +610,7 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
break;
case V_ASN1_INTEGER:
- case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
- case V_ASN1_NEG_ENUMERATED:
/*
* These are all have the same content format as ASN1_INTEGER
*/
diff --git a/crypto/openssl/crypto/bio/b_print.c b/crypto/openssl/crypto/bio/b_print.c
index 6c93f938126f..9f7f6344acb8 100644
--- a/crypto/openssl/crypto/bio/b_print.c
+++ b/crypto/openssl/crypto/bio/b_print.c
@@ -122,20 +122,20 @@
# define LLONG long long
# endif
#else
-# define LLONG long
-#endif
-
-static void fmtstr(char **, char **, size_t *, size_t *,
- const char *, int, int, int);
-static void fmtint(char **, char **, size_t *, size_t *,
- LLONG, int, int, int, int);
-static void fmtfp(char **, char **, size_t *, size_t *,
- LDOUBLE, int, int, int);
-static void doapr_outch(char **, char **, size_t *, size_t *, int);
-static void _dopr(char **sbuffer, char **buffer,
- size_t *maxlen, size_t *retlen, int *truncated,
- const char *format, va_list args);
-
+# define LLONG long
+#endif
+
+static int fmtstr(char **, char **, size_t *, size_t *,
+ const char *, int, int, int);
+static int fmtint(char **, char **, size_t *, size_t *,
+ LLONG, int, int, int, int);
+static int fmtfp(char **, char **, size_t *, size_t *,
+ LDOUBLE, int, int, int);
+static int doapr_outch(char **, char **, size_t *, size_t *, int);
+static int _dopr(char **sbuffer, char **buffer,
+ size_t *maxlen, size_t *retlen, int *truncated,
+ const char *format, va_list args);
+
/* format read states */
#define DP_S_DEFAULT 0
#define DP_S_FLAGS 1
@@ -162,13 +162,13 @@ static void _dopr(char **sbuffer, char **buffer,
#define DP_C_LLONG 4
/* some handy macros */
-#define char_to_int(p) (p - '0')
-#define OSSL_MAX(p,q) ((p >= q) ? p : q)
-
-static void
-_dopr(char **sbuffer,
- char **buffer,
- size_t *maxlen,
+#define char_to_int(p) (p - '0')
+#define OSSL_MAX(p,q) ((p >= q) ? p : q)
+
+static int
+_dopr(char **sbuffer,
+ char **buffer,
+ size_t *maxlen,
size_t *retlen, int *truncated, const char *format, va_list args)
{
char ch;
@@ -193,13 +193,14 @@ _dopr(char **sbuffer,
switch (state) {
case DP_S_DEFAULT:
- if (ch == '%')
- state = DP_S_FLAGS;
- else
- doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
- ch = *format++;
- break;
- case DP_S_FLAGS:
+ if (ch == '%')
+ state = DP_S_FLAGS;
+ else
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+ return 0;
+ ch = *format++;
+ break;
+ case DP_S_FLAGS:
switch (ch) {
case '-':
flags |= DP_F_MINUS;
@@ -299,14 +300,15 @@ _dopr(char **sbuffer,
value = va_arg(args, LLONG);
break;
default:
- value = va_arg(args, int);
- break;
- }
- fmtint(sbuffer, buffer, &currlen, maxlen,
- value, 10, min, max, flags);
- break;
- case 'X':
- flags |= DP_F_UP;
+ value = va_arg(args, int);
+ break;
+ }
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
+ max, flags))
+ return 0;
+ break;
+ case 'X':
+ flags |= DP_F_UP;
/* FALLTHROUGH */
case 'x':
case 'o':
@@ -323,23 +325,25 @@ _dopr(char **sbuffer,
value = va_arg(args, unsigned LLONG);
break;
default:
- value = (LLONG) va_arg(args, unsigned int);
- break;
- }
- fmtint(sbuffer, buffer, &currlen, maxlen, value,
- ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
- min, max, flags);
- break;
- case 'f':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg(args, LDOUBLE);
- else
- fvalue = va_arg(args, double);
- fmtfp(sbuffer, buffer, &currlen, maxlen,
- fvalue, min, max, flags);
- break;
- case 'E':
- flags |= DP_F_UP;
+ value = (LLONG) va_arg(args, unsigned int);
+ break;
+ }
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
+ ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
+ min, max, flags))
+ return 0;
+ break;
+ case 'f':
+ if (cflags == DP_C_LDOUBLE)
+ fvalue = va_arg(args, LDOUBLE);
+ else
+ fvalue = va_arg(args, double);
+ if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+ flags))
+ return 0;
+ break;
+ case 'E':
+ flags |= DP_F_UP;
case 'e':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg(args, LDOUBLE);
@@ -352,30 +356,33 @@ _dopr(char **sbuffer,
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg(args, LDOUBLE);
else
- fvalue = va_arg(args, double);
- break;
- case 'c':
- doapr_outch(sbuffer, buffer, &currlen, maxlen,
- va_arg(args, int));
- break;
- case 's':
- strvalue = va_arg(args, char *);
+ fvalue = va_arg(args, double);
+ break;
+ case 'c':
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
+ va_arg(args, int)))
+ return 0;
+ break;
+ case 's':
+ strvalue = va_arg(args, char *);
if (max < 0) {
if (buffer)
max = INT_MAX;
- else
- max = *maxlen;
- }
- fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
- flags, min, max);
- break;
- case 'p':
- value = (long)va_arg(args, void *);
- fmtint(sbuffer, buffer, &currlen, maxlen,
- value, 16, min, max, flags | DP_F_NUM);
- break;
- case 'n': /* XXX */
- if (cflags == DP_C_SHORT) {
+ else
+ max = *maxlen;
+ }
+ if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
+ flags, min, max))
+ return 0;
+ break;
+ case 'p':
+ value = (long)va_arg(args, void *);
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen,
+ value, 16, min, max, flags | DP_F_NUM))
+ return 0;
+ break;
+ case 'n': /* XXX */
+ if (cflags == DP_C_SHORT) {
short int *num;
num = va_arg(args, short int *);
*num = currlen;
@@ -391,13 +398,14 @@ _dopr(char **sbuffer,
int *num;
num = va_arg(args, int *);
*num = currlen;
- }
- break;
- case '%':
- doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
- break;
- case 'w':
- /* not supported yet, treat as next char */
+ }
+ break;
+ case '%':
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+ return 0;
+ break;
+ case 'w':
+ /* not supported yet, treat as next char */
ch = *format++;
break;
default:
@@ -415,52 +423,62 @@ _dopr(char **sbuffer,
break;
}
}
- *truncated = (currlen > *maxlen - 1);
- if (*truncated)
- currlen = *maxlen - 1;
- doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
- *retlen = currlen - 1;
- return;
-}
-
-static void
-fmtstr(char **sbuffer,
- char **buffer,
- size_t *currlen,
- size_t *maxlen, const char *value, int flags, int min, int max)
-{
- int padlen, strln;
- int cnt = 0;
-
- if (value == 0)
- value = "<NULL>";
- for (strln = 0; value[strln]; ++strln) ;
- padlen = min - strln;
- if (padlen < 0)
- padlen = 0;
- if (flags & DP_F_MINUS)
- padlen = -padlen;
-
- while ((padlen > 0) && (cnt < max)) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
- --padlen;
- ++cnt;
- }
- while (*value && (cnt < max)) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
- ++cnt;
- }
- while ((padlen < 0) && (cnt < max)) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
- ++padlen;
- ++cnt;
- }
-}
-
-static void
-fmtint(char **sbuffer,
- char **buffer,
- size_t *currlen,
+ *truncated = (currlen > *maxlen - 1);
+ if (*truncated)
+ currlen = *maxlen - 1;
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
+ return 0;
+ *retlen = currlen - 1;
+ return 1;
+}
+
+static int
+fmtstr(char **sbuffer,
+ char **buffer,
+ size_t *currlen,
+ size_t *maxlen, const char *value, int flags, int min, int max)
+{
+ int padlen;
+ size_t strln;
+ int cnt = 0;
+
+ if (value == 0)
+ value = "<NULL>";
+
+ strln = strlen(value);
+ if (strln > INT_MAX)
+ strln = INT_MAX;
+
+ padlen = min - strln;
+ if (min < 0 || padlen < 0)
+ padlen = 0;
+ if (flags & DP_F_MINUS)
+ padlen = -padlen;
+
+ while ((padlen > 0) && (cnt < max)) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ --padlen;
+ ++cnt;
+ }
+ while (*value && (cnt < max)) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
+ return 0;
+ ++cnt;
+ }
+ while ((padlen < 0) && (cnt < max)) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ ++padlen;
+ ++cnt;
+ }
+ return 1;
+}
+
+static int
+fmtint(char **sbuffer,
+ char **buffer,
+ size_t *currlen,
size_t *maxlen, LLONG value, int base, int min, int max, int flags)
{
int signvalue = 0;
@@ -514,43 +532,50 @@ fmtint(char **sbuffer,
}
if (flags & DP_F_MINUS)
spadlen = -spadlen;
-
- /* spaces */
- while (spadlen > 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
- --spadlen;
- }
-
- /* sign */
- if (signvalue)
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
-
- /* prefix */
- while (*prefix) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
- prefix++;
- }
-
- /* zeros */
- if (zpadlen > 0) {
- while (zpadlen > 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
- --zpadlen;
- }
- }
- /* digits */
- while (place > 0)
- doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
-
- /* left justified spaces */
- while (spadlen < 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
- ++spadlen;
- }
- return;
-}
-
-static LDOUBLE abs_val(LDOUBLE value)
+
+ /* spaces */
+ while (spadlen > 0) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ --spadlen;
+ }
+
+ /* sign */
+ if (signvalue)
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
+
+ /* prefix */
+ while (*prefix) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
+ return 0;
+ prefix++;
+ }
+
+ /* zeros */
+ if (zpadlen > 0) {
+ while (zpadlen > 0) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
+ --zpadlen;
+ }
+ }
+ /* digits */
+ while (place > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]))
+ return 0;
+ }
+
+ /* left justified spaces */
+ while (spadlen < 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ ++spadlen;
+ }
+ return 1;
+}
+
+static LDOUBLE abs_val(LDOUBLE value)
{
LDOUBLE result = value;
if (value < 0)
@@ -575,13 +600,13 @@ static long roundv(LDOUBLE value)
value = value - intpart;
if (value >= 0.5)
intpart++;
- return intpart;
-}
-
-static void
-fmtfp(char **sbuffer,
- char **buffer,
- size_t *currlen,
+ return intpart;
+}
+
+static int
+fmtfp(char **sbuffer,
+ char **buffer,
+ size_t *currlen,
size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags)
{
int signvalue = 0;
@@ -657,87 +682,107 @@ fmtfp(char **sbuffer,
padlen = 0;
if (flags & DP_F_MINUS)
padlen = -padlen;
-
- if ((flags & DP_F_ZERO) && (padlen > 0)) {
- if (signvalue) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
- --padlen;
- signvalue = 0;
- }
- while (padlen > 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
- --padlen;
- }
- }
- while (padlen > 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
- --padlen;
- }
- if (signvalue)
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
-
- while (iplace > 0)
- doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
-
- /*
- * Decimal point. This should probably use locale to find the correct
- * char to print out.
- */
- if (max > 0 || (flags & DP_F_NUM)) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
-
- while (fplace > 0)
- doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
- }
- while (zpadlen > 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
- --zpadlen;
- }
-
- while (padlen < 0) {
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
- ++padlen;
- }
-}
-
-static void
-doapr_outch(char **sbuffer,
- char **buffer, size_t *currlen, size_t *maxlen, int c)
-{
- /* If we haven't at least one buffer, someone has doe a big booboo */
- assert(*sbuffer != NULL || buffer != NULL);
-
- if (buffer) {
- while (*currlen >= *maxlen) {
- if (*buffer == NULL) {
- if (*maxlen == 0)
- *maxlen = 1024;
- *buffer = OPENSSL_malloc(*maxlen);
- if (*currlen > 0) {
- assert(*sbuffer != NULL);
- memcpy(*buffer, *sbuffer, *currlen);
- }
- *sbuffer = NULL;
- } else {
- *maxlen += 1024;
- *buffer = OPENSSL_realloc(*buffer, *maxlen);
- }
- }
- /* What to do if *buffer is NULL? */
- assert(*sbuffer != NULL || *buffer != NULL);
- }
-
- if (*currlen < *maxlen) {
- if (*sbuffer)
+
+ if ((flags & DP_F_ZERO) && (padlen > 0)) {
+ if (signvalue) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
+ --padlen;
+ signvalue = 0;
+ }
+ while (padlen > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
+ --padlen;
+ }
+ }
+ while (padlen > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ --padlen;
+ }
+ if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+ return 0;
+
+ while (iplace > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]))
+ return 0;
+ }
+
+ /*
+ * Decimal point. This should probably use locale to find the correct
+ * char to print out.
+ */
+ if (max > 0 || (flags & DP_F_NUM)) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.'))
+ return 0;
+
+ while (fplace > 0) {
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen,
+ fconvert[--fplace]))
+ return 0;
+ }
+ }
+ while (zpadlen > 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+ return 0;
+ --zpadlen;
+ }
+
+ while (padlen < 0) {
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+ return 0;
+ ++padlen;
+ }
+ return 1;
+}
+
+#define BUFFER_INC 1024
+
+static int
+doapr_outch(char **sbuffer,
+ char **buffer, size_t *currlen, size_t *maxlen, int c)
+{
+ /* If we haven't at least one buffer, someone has doe a big booboo */
+ assert(*sbuffer != NULL || buffer != NULL);
+
+ /* |currlen| must always be <= |*maxlen| */
+ assert(*currlen <= *maxlen);
+
+ if (buffer && *currlen == *maxlen) {
+ if (*maxlen > INT_MAX - BUFFER_INC)
+ return 0;
+
+ *maxlen += BUFFER_INC;
+ if (*buffer == NULL) {
+ *buffer = OPENSSL_malloc(*maxlen);
+ if (*buffer == NULL)
+ return 0;
+ if (*currlen > 0) {
+ assert(*sbuffer != NULL);
+ memcpy(*buffer, *sbuffer, *currlen);
+ }
+ *sbuffer = NULL;
+ } else {
+ char *tmpbuf;
+ tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
+ if (tmpbuf == NULL)
+ return 0;
+ *buffer = tmpbuf;
+ }
+ }
+
+ if (*currlen < *maxlen) {
+ if (*sbuffer)
(*sbuffer)[(*currlen)++] = (char)c;
else
- (*buffer)[(*currlen)++] = (char)c;
- }
-
- return;
-}
-
-/***************************************************************************/
+ (*buffer)[(*currlen)++] = (char)c;
+ }
+
+ return 1;
+}
+
+/***************************************************************************/
int BIO_printf(BIO *bio, const char *format, ...)
{
@@ -763,13 +808,17 @@ int BIO_vprintf(BIO *bio, const char *format, va_list args)
size_t hugebufsize = sizeof(hugebuf);
char *dynbuf = NULL;
int ignored;
-
- dynbuf = NULL;
- CRYPTO_push_info("doapr()");
- _dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format, args);
- if (dynbuf) {
- ret = BIO_write(bio, dynbuf, (int)retlen);
- OPENSSL_free(dynbuf);
+
+ dynbuf = NULL;
+ CRYPTO_push_info("doapr()");
+ if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format,
+ args)) {
+ OPENSSL_free(dynbuf);
+ return -1;
+ }
+ if (dynbuf) {
+ ret = BIO_write(bio, dynbuf, (int)retlen);
+ OPENSSL_free(dynbuf);
} else {
ret = BIO_write(bio, hugebuf, (int)retlen);
}
@@ -798,13 +847,14 @@ int BIO_snprintf(char *buf, size_t n, const char *format, ...)
int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
{
- size_t retlen;
- int truncated;
-
- _dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
-
- if (truncated)
- /*
+ size_t retlen;
+ int truncated;
+
+ if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
+ return -1;
+
+ if (truncated)
+ /*
* In case of truncation, return -1 like traditional snprintf.
* (Current drafts for ISO/IEC 9899 say snprintf should return the
* number of characters that would have been written, had the buffer
diff --git a/crypto/openssl/crypto/bn/bn.h b/crypto/openssl/crypto/bn/bn.h
index fa3520b368d7..894fed135637 100644
--- a/crypto/openssl/crypto/bn/bn.h
+++ b/crypto/openssl/crypto/bn/bn.h
@@ -69,12 +69,13 @@
*
*/
-#ifndef HEADER_BN_H
-# define HEADER_BN_H
-
-# include <openssl/e_os2.h>
-# ifndef OPENSSL_NO_FP_API
-# include <stdio.h> /* FILE */
+#ifndef HEADER_BN_H
+# define HEADER_BN_H
+
+# include <limits.h>
+# include <openssl/e_os2.h>
+# ifndef OPENSSL_NO_FP_API
+# include <stdio.h> /* FILE */
# endif
# include <openssl/ossl_typ.h>
@@ -701,14 +702,23 @@ const BIGNUM *BN_get0_nist_prime_224(void);
const BIGNUM *BN_get0_nist_prime_256(void);
const BIGNUM *BN_get0_nist_prime_384(void);
const BIGNUM *BN_get0_nist_prime_521(void);
-
-/* library internal functions */
-
-# define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
- (a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
-# define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
-BIGNUM *bn_expand2(BIGNUM *a, int words);
-# ifndef OPENSSL_NO_DEPRECATED
+
+/* library internal functions */
+
+# define bn_expand(a,bits) \
+ ( \
+ bits > (INT_MAX - BN_BITS2 + 1) ? \
+ NULL \
+ : \
+ (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax) ? \
+ (a) \
+ : \
+ bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2) \
+ )
+
+# define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+# ifndef OPENSSL_NO_DEPRECATED
BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
# endif
diff --git a/crypto/openssl/crypto/bn/bn_exp.c b/crypto/openssl/crypto/bn/bn_exp.c
index ef67843fc230..2ce056d13089 100644
--- a/crypto/openssl/crypto/bn/bn_exp.c
+++ b/crypto/openssl/crypto/bn/bn_exp.c
@@ -110,6 +110,7 @@
*/
#include "cryptlib.h"
+#include "constant_time_locl.h"
#include "bn_lcl.h"
/* maximum precomputation table size for *variable* sliding windows */
@@ -523,9 +524,11 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
static int MOD_EXP_CTIME_COPY_TO_PREBUF(BIGNUM *b, int top,
unsigned char *buf, int idx,
- int width)
+ int window)
{
- size_t i, j;
+ int i, j;
+ int width = 1 << window;
+ BN_ULONG *table = (BN_ULONG *)buf;
if (bn_wexpand(b, top) == NULL)
return 0;
@@ -533,8 +536,8 @@ static int MOD_EXP_CTIME_COPY_TO_PREBUF(BIGNUM *b, int top,
b->d[b->top++] = 0;
}
- for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
- buf[j] = ((unsigned char *)b->d)[i];
+ for (i = 0, j = idx; i < top; i++, j += width) {
+ table[j] = b->d[i];
}
bn_correct_top(b);
@@ -543,15 +546,51 @@ static int MOD_EXP_CTIME_COPY_TO_PREBUF(BIGNUM *b, int top,
static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
unsigned char *buf, int idx,
- int width)
+ int window)
{
- size_t i, j;
+ int i, j;
+ int width = 1 << window;
+ volatile BN_ULONG *table = (volatile BN_ULONG *)buf;
if (bn_wexpand(b, top) == NULL)
return 0;
- for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
- ((unsigned char *)b->d)[i] = buf[j];
+ if (window <= 3) {
+ for (i = 0; i < top; i++, table += width) {
+ BN_ULONG acc = 0;
+
+ for (j = 0; j < width; j++) {
+ acc |= table[j] &
+ ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
+ }
+
+ b->d[i] = acc;
+ }
+ } else {
+ int xstride = 1 << (window - 2);
+ BN_ULONG y0, y1, y2, y3;
+
+ i = idx >> (window - 2); /* equivalent of idx / xstride */
+ idx &= xstride - 1; /* equivalent of idx % xstride */
+
+ y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1);
+ y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1);
+ y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1);
+ y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1);
+
+ for (i = 0; i < top; i++, table += width) {
+ BN_ULONG acc = 0;
+
+ for (j = 0; j < xstride; j++) {
+ acc |= ( (table[j + 0 * xstride] & y0) |
+ (table[j + 1 * xstride] & y1) |
+ (table[j + 2 * xstride] & y2) |
+ (table[j + 3 * xstride] & y3) )
+ & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
+ }
+
+ b->d[i] = acc;
+ }
}
b->top = top;
@@ -648,7 +687,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
*/
if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
goto err;
- if (!MOD_EXP_CTIME_COPY_TO_PREBUF(r, top, powerbuf, 0, numPowers))
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(r, top, powerbuf, 0, window))
goto err;
/* Initialize computeTemp as a^1 with montgomery precalcs */
@@ -667,7 +706,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
goto err;
if (!BN_copy(computeTemp, am))
goto err;
- if (!MOD_EXP_CTIME_COPY_TO_PREBUF(am, top, powerbuf, 1, numPowers))
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(am, top, powerbuf, 1, window))
goto err;
/*
@@ -682,8 +721,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
if (!BN_mod_mul_montgomery
(computeTemp, am, computeTemp, mont, ctx))
goto err;
- if (!MOD_EXP_CTIME_COPY_TO_PREBUF
- (computeTemp, top, powerbuf, i, numPowers))
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(computeTemp, top, powerbuf, i,
+ window))
goto err;
}
}
@@ -719,7 +758,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
* Fetch the appropriate pre-computed value from the pre-buf
*/
if (!MOD_EXP_CTIME_COPY_FROM_PREBUF
- (computeTemp, top, powerbuf, wvalue, numPowers))
+ (computeTemp, top, powerbuf, wvalue, window))
goto err;
/* Multiply the result into the intermediate result */
diff --git a/crypto/openssl/crypto/bn/bn_print.c b/crypto/openssl/crypto/bn/bn_print.c
index 611765341d1d..ad652e7f1290 100644
--- a/crypto/openssl/crypto/bn/bn_print.c
+++ b/crypto/openssl/crypto/bn/bn_print.c
@@ -55,12 +55,13 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
-
-#include <stdio.h>
-#include <ctype.h>
-#include "cryptlib.h"
-#include <openssl/buffer.h>
-#include "bn_lcl.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include "bn_lcl.h"
static const char Hex[] = "0123456789ABCDEF";
@@ -110,6 +111,7 @@ char *BN_bn2dec(const BIGNUM *a)
char *p;
BIGNUM *t = NULL;
BN_ULONG *bn_data = NULL, *lp;
+ int bn_data_num;
/*-
* get an upper bound for the length of the decimal integer
@@ -119,8 +121,8 @@ char *BN_bn2dec(const BIGNUM *a)
*/
i = BN_num_bits(a) * 3;
num = (i / 10 + i / 1000 + 1) + 1;
- bn_data =
- (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
+ bn_data_num = num / BN_DEC_NUM + 1;
+ bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG));
buf = (char *)OPENSSL_malloc(num + 3);
if ((buf == NULL) || (bn_data == NULL)) {
BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE);
@@ -139,9 +141,12 @@ char *BN_bn2dec(const BIGNUM *a)
if (BN_is_negative(t))
*p++ = '-';
- i = 0;
while (!BN_is_zero(t)) {
+ if (lp - bn_data >= bn_data_num)
+ goto err;
*lp = BN_div_word(t, BN_DEC_CONV);
+ if (*lp == (BN_ULONG)-1)
+ goto err;
lp++;
}
lp--;
@@ -186,14 +191,18 @@ int BN_hex2bn(BIGNUM **bn, const char *a)
if (*a == '-') {
neg = 1;
- a++;
- }
-
- for (i = 0; isxdigit((unsigned char)a[i]); i++) ;
-
- num = i + neg;
- if (bn == NULL)
- return (num);
+ a++;
+ }
+
+ for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++)
+ continue;
+
+ if (i > INT_MAX/4)
+ goto err;
+
+ num = i + neg;
+ if (bn == NULL)
+ return (num);
/* a is the start of the hex digits, and it is 'i' long */
if (*bn == NULL) {
@@ -201,13 +210,13 @@ int BN_hex2bn(BIGNUM **bn, const char *a)
return (0);
} else {
ret = *bn;
- BN_zero(ret);
- }
-
- /* i is the number of hex digests; */
- if (bn_expand(ret, i * 4) == NULL)
- goto err;
-
+ BN_zero(ret);
+ }
+
+ /* i is the number of hex digits */
+ if (bn_expand(ret, i * 4) == NULL)
+ goto err;
+
j = i; /* least significant 'hex' */
m = 0;
h = 0;
@@ -257,14 +266,18 @@ int BN_dec2bn(BIGNUM **bn, const char *a)
return (0);
if (*a == '-') {
neg = 1;
- a++;
- }
-
- for (i = 0; isdigit((unsigned char)a[i]); i++) ;
-
- num = i + neg;
- if (bn == NULL)
- return (num);
+ a++;
+ }
+
+ for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++)
+ continue;
+
+ if (i > INT_MAX/4)
+ goto err;
+
+ num = i + neg;
+ if (bn == NULL)
+ return (num);
/*
* a is the start of the digits, and it is 'i' long. We chop it into
@@ -275,13 +288,13 @@ int BN_dec2bn(BIGNUM **bn, const char *a)
return (0);
} else {
ret = *bn;
- BN_zero(ret);
- }
-
- /* i is the number of digests, a bit of an over expand; */
- if (bn_expand(ret, i * 4) == NULL)
- goto err;
-
+ BN_zero(ret);
+ }
+
+ /* i is the number of digits, a bit of an over expand */
+ if (bn_expand(ret, i * 4) == NULL)
+ goto err;
+
j = BN_DEC_NUM - (i % BN_DEC_NUM);
if (j == BN_DEC_NUM)
j = 0;
diff --git a/crypto/openssl/crypto/dsa/dsa_ossl.c b/crypto/openssl/crypto/dsa/dsa_ossl.c
index c44a4e36a19c..e26a62d62a0c 100644
--- a/crypto/openssl/crypto/dsa/dsa_ossl.c
+++ b/crypto/openssl/crypto/dsa/dsa_ossl.c
@@ -235,11 +235,13 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
do
if (!BN_rand_range(&k, dsa->q))
goto err;
- while (BN_is_zero(&k)) ;
+ while (BN_is_zero(&k));
+
if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) {
BN_set_flags(&k, BN_FLG_CONSTTIME);
}
+
if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
CRYPTO_LOCK_DSA, dsa->p, ctx))
@@ -252,6 +254,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
if (!BN_copy(&kq, &k))
goto err;
+ BN_set_flags(&kq, BN_FLG_CONSTTIME);
+
/*
* We do not want timing information to leak the length of k, so we
* compute g^k using an equivalent exponent of fixed length. (This
@@ -270,6 +274,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
} else {
K = &k;
}
+
DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx,
dsa->method_mont_p);
if (!BN_mod(r, r, dsa->q, ctx))
diff --git a/crypto/openssl/crypto/evp/encode.c b/crypto/openssl/crypto/evp/encode.c
index 9bdcd5724109..eb42a18a31c3 100644
--- a/crypto/openssl/crypto/evp/encode.c
+++ b/crypto/openssl/crypto/evp/encode.c
@@ -57,6 +57,7 @@
*/
#include <stdio.h>
+#include <limits.h>
#include "cryptlib.h"
#include <openssl/evp.h>
@@ -134,13 +135,13 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
const unsigned char *in, int inl)
{
int i, j;
- unsigned int total = 0;
+ size_t total = 0;
*outl = 0;
if (inl == 0)
return;
OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
- if ((ctx->num + inl) < ctx->length) {
+ if (ctx->length - ctx->num > inl) {
memcpy(&(ctx->enc_data[ctx->num]), in, inl);
ctx->num += inl;
return;
@@ -157,7 +158,7 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
*out = '\0';
total = j + 1;
}
- while (inl >= ctx->length) {
+ while (inl >= ctx->length && total <= INT_MAX) {
j = EVP_EncodeBlock(out, in, ctx->length);
in += ctx->length;
inl -= ctx->length;
@@ -166,6 +167,11 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
*out = '\0';
total += j + 1;
}
+ if (total > INT_MAX) {
+ /* Too much output data! */
+ *outl = 0;
+ return;
+ }
if (inl != 0)
memcpy(&(ctx->enc_data[0]), in, inl);
ctx->num = inl;
diff --git a/crypto/openssl/crypto/evp/evp_enc.c b/crypto/openssl/crypto/evp/evp_enc.c
index 8a91a679bba7..5205047e49b2 100644
--- a/crypto/openssl/crypto/evp/evp_enc.c
+++ b/crypto/openssl/crypto/evp/evp_enc.c
@@ -166,7 +166,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
bl = ctx->cipher->block_size;
OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
if (i != 0) {
- if (i + inl < bl) {
+ if (bl - i > inl) {
memcpy(&(ctx->buf[i]), in, inl);
ctx->buf_len += inl;
*outl = 0;
diff --git a/crypto/openssl/crypto/mdc2/mdc2dgst.c b/crypto/openssl/crypto/mdc2/mdc2dgst.c
index 82cd6b4520ec..2868ae033f13 100644
--- a/crypto/openssl/crypto/mdc2/mdc2dgst.c
+++ b/crypto/openssl/crypto/mdc2/mdc2dgst.c
@@ -94,7 +94,7 @@ int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len)
i = c->num;
if (i != 0) {
- if (i + len < MDC2_BLOCK) {
+ if (len < MDC2_BLOCK - i) {
/* partial block */
memcpy(&(c->data[i]), in, len);
c->num += (int)len;
diff --git a/crypto/openssl/crypto/x509/x509_obj.c b/crypto/openssl/crypto/x509/x509_obj.c
index c334d3b05ce8..e9822b0e9875 100644
--- a/crypto/openssl/crypto/x509/x509_obj.c
+++ b/crypto/openssl/crypto/x509/x509_obj.c
@@ -117,8 +117,9 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
type == V_ASN1_PRINTABLESTRING ||
type == V_ASN1_TELETEXSTRING ||
type == V_ASN1_VISIBLESTRING || type == V_ASN1_IA5STRING) {
- ascii2ebcdic(ebcdic_buf, q, (num > sizeof ebcdic_buf)
- ? sizeof ebcdic_buf : num);
+ if (num > (int)sizeof(ebcdic_buf))
+ num = sizeof(ebcdic_buf);
+ ascii2ebcdic(ebcdic_buf, q, num);
q = ebcdic_buf;
}
#endif
diff --git a/crypto/openssl/doc/apps/ciphers.pod b/crypto/openssl/doc/apps/ciphers.pod
index 01d31ddfcae6..f763cdc95107 100644
--- a/crypto/openssl/doc/apps/ciphers.pod
+++ b/crypto/openssl/doc/apps/ciphers.pod
@@ -380,17 +380,17 @@ Note: these ciphers can also be used in SSL v3.
TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA EXP1024-DHE-DSS-RC4-SHA
TLS_DHE_DSS_WITH_RC4_128_SHA DHE-DSS-RC4-SHA
-=head2 SSL v2.0 cipher suites.
-
- SSL_CK_RC4_128_WITH_MD5 RC4-MD5
- SSL_CK_RC4_128_EXPORT40_WITH_MD5 EXP-RC4-MD5
- SSL_CK_RC2_128_CBC_WITH_MD5 RC2-MD5
- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 EXP-RC2-MD5
- SSL_CK_IDEA_128_CBC_WITH_MD5 IDEA-CBC-MD5
- SSL_CK_DES_64_CBC_WITH_MD5 DES-CBC-MD5
- SSL_CK_DES_192_EDE3_CBC_WITH_MD5 DES-CBC3-MD5
-
-=head1 NOTES
+=head2 SSL v2.0 cipher suites.
+
+ SSL_CK_RC4_128_WITH_MD5 RC4-MD5
+ SSL_CK_RC4_128_EXPORT40_WITH_MD5 Not implemented.
+ SSL_CK_RC2_128_CBC_WITH_MD5 RC2-CBC-MD5
+ SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 Not implemented.
+ SSL_CK_IDEA_128_CBC_WITH_MD5 IDEA-CBC-MD5
+ SSL_CK_DES_64_CBC_WITH_MD5 Not implemented.
+ SSL_CK_DES_192_EDE3_CBC_WITH_MD5 DES-CBC3-MD5
+
+=head1 NOTES
The non-ephemeral DH modes are currently unimplemented in OpenSSL
because there is no support for DH certificates.
diff --git a/crypto/openssl/ssl/d1_both.c b/crypto/openssl/ssl/d1_both.c
index 4642d7729435..9856cfc2e235 100644
--- a/crypto/openssl/ssl/d1_both.c
+++ b/crypto/openssl/ssl/d1_both.c
@@ -543,11 +543,23 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
int al;
*ok = 0;
- item = pqueue_peek(s->d1->buffered_messages);
- if (item == NULL)
- return 0;
+ do {
+ item = pqueue_peek(s->d1->buffered_messages);
+ if (item == NULL)
+ return 0;
+
+ frag = (hm_fragment *)item->data;
+
+ if (frag->msg_header.seq < s->d1->handshake_read_seq) {
+ /* This is a stale message that has been buffered so clear it */
+ pqueue_pop(s->d1->buffered_messages);
+ dtls1_hm_fragment_free(frag);
+ pitem_free(item);
+ item = NULL;
+ frag = NULL;
+ }
+ } while (item == NULL);
- frag = (hm_fragment *)item->data;
/* Don't return if reassembly still in progress */
if (frag->reassembly != NULL)
@@ -1335,18 +1347,6 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
return ret;
}
-/* call this function when the buffered messages are no longer needed */
-void dtls1_clear_record_buffer(SSL *s)
-{
- pitem *item;
-
- for (item = pqueue_pop(s->d1->sent_messages);
- item != NULL; item = pqueue_pop(s->d1->sent_messages)) {
- dtls1_hm_fragment_free((hm_fragment *)item->data);
- pitem_free(item);
- }
-}
-
unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p,
unsigned char mt, unsigned long len,
unsigned long frag_off,
diff --git a/crypto/openssl/ssl/d1_clnt.c b/crypto/openssl/ssl/d1_clnt.c
index 335111a4f645..afe1aa60eb61 100644
--- a/crypto/openssl/ssl/d1_clnt.c
+++ b/crypto/openssl/ssl/d1_clnt.c
@@ -564,6 +564,7 @@ int dtls1_connect(SSL *s)
/* done with handshaking */
s->d1->handshake_read_seq = 0;
s->d1->next_handshake_write_seq = 0;
+ dtls1_clear_received_buffer(s);
goto end;
/* break; */
diff --git a/crypto/openssl/ssl/d1_lib.c b/crypto/openssl/ssl/d1_lib.c
index b4f5fcd7e32c..b166c1fe969b 100644
--- a/crypto/openssl/ssl/d1_lib.c
+++ b/crypto/openssl/ssl/d1_lib.c
@@ -155,7 +155,6 @@ int dtls1_new(SSL *s)
static void dtls1_clear_queues(SSL *s)
{
pitem *item = NULL;
- hm_fragment *frag = NULL;
DTLS1_RECORD_DATA *rdata;
while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) {
@@ -176,12 +175,36 @@ static void dtls1_clear_queues(SSL *s)
pitem_free(item);
}
+ while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) {
+ rdata = (DTLS1_RECORD_DATA *)item->data;
+ if (rdata->rbuf.buf) {
+ OPENSSL_free(rdata->rbuf.buf);
+ }
+ OPENSSL_free(item->data);
+ pitem_free(item);
+ }
+
+ dtls1_clear_received_buffer(s);
+ dtls1_clear_sent_buffer(s);
+}
+
+void dtls1_clear_received_buffer(SSL *s)
+{
+ pitem *item = NULL;
+ hm_fragment *frag = NULL;
+
while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) {
frag = (hm_fragment *)item->data;
OPENSSL_free(frag->fragment);
OPENSSL_free(frag);
pitem_free(item);
}
+}
+
+void dtls1_clear_sent_buffer(SSL *s)
+{
+ pitem *item = NULL;
+ hm_fragment *frag = NULL;
while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) {
frag = (hm_fragment *)item->data;
@@ -189,17 +212,9 @@ static void dtls1_clear_queues(SSL *s)
OPENSSL_free(frag);
pitem_free(item);
}
-
- while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) {
- rdata = (DTLS1_RECORD_DATA *)item->data;
- if (rdata->rbuf.buf) {
- OPENSSL_free(rdata->rbuf.buf);
- }
- OPENSSL_free(item->data);
- pitem_free(item);
- }
}
+
void dtls1_free(SSL *s)
{
ssl3_free(s);
@@ -431,7 +446,7 @@ void dtls1_stop_timer(SSL *s)
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
&(s->d1->next_timeout));
/* Clear retransmission buffer */
- dtls1_clear_record_buffer(s);
+ dtls1_clear_sent_buffer(s);
}
int dtls1_check_timeout_num(SSL *s)
diff --git a/crypto/openssl/ssl/d1_pkt.c b/crypto/openssl/ssl/d1_pkt.c
index b5c3653d8b07..9a5b14582e41 100644
--- a/crypto/openssl/ssl/d1_pkt.c
+++ b/crypto/openssl/ssl/d1_pkt.c
@@ -124,8 +124,7 @@
static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
int len, int peek);
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
- PQ_64BIT * seq_num);
+static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
unsigned int *is_next_epoch);
@@ -135,7 +134,7 @@ static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
unsigned long *offset);
#endif
static int dtls1_buffer_record(SSL *s, record_pqueue *q, PQ_64BIT * priority);
-static int dtls1_process_record(SSL *s);
+static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap);
#if PQ_64BIT_IS_INTEGER
static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT * num);
#endif
@@ -248,20 +247,66 @@ static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
static int dtls1_process_buffered_records(SSL *s)
{
pitem *item;
+ SSL3_BUFFER *rb;
+ SSL3_RECORD *rr;
+ DTLS1_BITMAP *bitmap;
+ unsigned int is_next_epoch;
+ int replayok = 1;
item = pqueue_peek(s->d1->unprocessed_rcds.q);
if (item) {
/* Check if epoch is current. */
if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch)
- return (1); /* Nothing to do. */
+ return 1; /* Nothing to do. */
+
+ rr = &s->s3->rrec;
+ rb = &s->s3->rbuf;
+
+ if (rb->left > 0) {
+ /*
+ * We've still got data from the current packet to read. There could
+ * be a record from the new epoch in it - so don't overwrite it
+ * with the unprocessed records yet (we'll do it when we've
+ * finished reading the current packet).
+ */
+ return 1;
+ }
+
/* Process all the records. */
while (pqueue_peek(s->d1->unprocessed_rcds.q)) {
dtls1_get_unprocessed_record(s);
- if (!dtls1_process_record(s))
- return (0);
- dtls1_buffer_record(s, &(s->d1->processed_rcds),
- &s->s3->rrec.seq_num);
+ bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
+ if (bitmap == NULL) {
+ /*
+ * Should not happen. This will only ever be NULL when the
+ * current record is from a different epoch. But that cannot
+ * be the case because we already checked the epoch above
+ */
+ SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ {
+ /*
+ * Check whether this is a repeat, or aged record. We did this
+ * check once already when we first received the record - but
+ * we might have updated the window since then due to
+ * records we subsequently processed.
+ */
+ replayok = dtls1_record_replay_check(s, bitmap);
+ }
+
+ if (!replayok || !dtls1_process_record(s, bitmap)) {
+ /* dump this record */
+ rr->length = 0;
+ s->packet_length = 0;
+ continue;
+ }
+
+ if (dtls1_buffer_record(s, &(s->d1->processed_rcds),
+ &s->s3->rrec.seq_num) < 0)
+ return 0;
}
}
@@ -272,7 +317,7 @@ static int dtls1_process_buffered_records(SSL *s)
s->d1->processed_rcds.epoch = s->d1->r_epoch;
s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1;
- return (1);
+ return 1;
}
#if 0
@@ -319,7 +364,7 @@ static int dtls1_get_buffered_record(SSL *s)
#endif
-static int dtls1_process_record(SSL *s)
+static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap)
{
int i, al;
int enc_err;
@@ -478,8 +523,10 @@ static int dtls1_process_record(SSL *s)
/* we have pulled in a full packet so zero things */
s->packet_length = 0;
- dtls1_record_bitmap_update(s, &(s->d1->bitmap)); /* Mark receipt of
- * record. */
+
+ /* Mark receipt of record. */
+ dtls1_record_bitmap_update(s, bitmap);
+
return (1);
f_err:
@@ -510,6 +557,7 @@ int dtls1_get_record(SSL *s)
rr = &(s->s3->rrec);
+ again:
/*
* The epoch may have changed. If so, process all the pending records.
* This is a non-blocking operation.
@@ -521,7 +569,6 @@ int dtls1_get_record(SSL *s)
return 1;
/* get something from the wire */
- again:
/* check if we have the header */
if ((s->rstate != SSL_ST_READ_BODY) ||
(s->packet_length < DTLS1_RT_HEADER_LENGTH)) {
@@ -620,7 +667,7 @@ int dtls1_get_record(SSL *s)
if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
s->packet_length > DTLS1_RT_HEADER_LENGTH &&
s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) &&
- !dtls1_record_replay_check(s, bitmap, &(rr->seq_num))) {
+ !dtls1_record_replay_check(s, bitmap)) {
rr->length = 0;
s->packet_length = 0; /* dump this record */
goto again; /* get another record */
@@ -638,14 +685,16 @@ int dtls1_get_record(SSL *s)
*/
if (is_next_epoch) {
if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) {
- dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num);
+ if (dtls1_buffer_record
+ (s, &(s->d1->unprocessed_rcds), &rr->seq_num) < 0)
+ return -1;
}
rr->length = 0;
s->packet_length = 0;
goto again;
}
- if (!dtls1_process_record(s)) {
+ if (!dtls1_process_record(s, bitmap)) {
rr->length = 0;
s->packet_length = 0; /* dump this record */
goto again; /* get another record */
@@ -771,6 +820,13 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
goto start;
}
+ /*
+ * Reset the count of consecutive warning alerts if we've got a non-empty
+ * record that isn't an alert.
+ */
+ if (rr->type != SSL3_RT_ALERT && rr->length != 0)
+ s->s3->alert_count = 0;
+
/* we now have a packet which can be read and processed */
if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
@@ -994,6 +1050,14 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
if (alert_level == 1) { /* warning */
s->s3->warn_alert = alert_descr;
+
+ s->s3->alert_count++;
+ if (s->s3->alert_count == MAX_WARN_ALERT_COUNT) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS);
+ goto f_err;
+ }
+
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
return (0);
@@ -1514,8 +1578,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
return -1;
}
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
- PQ_64BIT * seq_num)
+static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
{
#if PQ_64BIT_IS_INTEGER
PQ_64BIT mask = 0x0000000000000001L;
@@ -1530,7 +1593,7 @@ static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
if (pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) ||
pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num))) {
- pq_64bit_assign(seq_num, &rcd_num);
+ pq_64bit_assign(&s->s3->rrec.seq_num, &rcd_num);
pq_64bit_free(&rcd_num);
pq_64bit_free(&tmp);
return 1; /* this record is new */
@@ -1561,7 +1624,7 @@ static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
return 0; /* record previously received */
#endif
- pq_64bit_assign(seq_num, &rcd_num);
+ pq_64bit_assign(&s->s3->rrec.seq_num, &rcd_num);
pq_64bit_free(&rcd_num);
pq_64bit_free(&tmp);
return 1;
@@ -1687,8 +1750,13 @@ static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
if (rr->epoch == s->d1->r_epoch)
return &s->d1->bitmap;
- /* Only HM and ALERT messages can be from the next epoch */
+ /*
+ * Only HM and ALERT messages can be from the next epoch and only if we
+ * have already processed all of the unprocessed records from the last
+ * epoch
+ */
else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
+ s->d1->unprocessed_rcds.epoch != s->d1->r_epoch &&
(rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) {
*is_next_epoch = 1;
return &s->d1->next_bitmap;
@@ -1776,6 +1844,12 @@ void dtls1_reset_seq_numbers(SSL *s, int rw)
memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
pq_64bit_init(&(s->d1->next_bitmap.map));
pq_64bit_init(&(s->d1->next_bitmap.max_seq_num));
+
+ /*
+ * We must not use any buffered messages received from the previous
+ * epoch
+ */
+ dtls1_clear_received_buffer(s);
} else {
seq = s->s3->write_sequence;
memcpy(s->d1->last_write_sequence, seq,
diff --git a/crypto/openssl/ssl/d1_srvr.c b/crypto/openssl/ssl/d1_srvr.c
index c5dac9fa2caa..7a8f8bbaa47e 100644
--- a/crypto/openssl/ssl/d1_srvr.c
+++ b/crypto/openssl/ssl/d1_srvr.c
@@ -242,7 +242,7 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SW_HELLO_REQ_B:
s->shutdown = 0;
- dtls1_clear_record_buffer(s);
+ dtls1_clear_sent_buffer(s);
dtls1_start_timer(s);
ret = dtls1_send_hello_request(s);
if (ret <= 0)
@@ -648,6 +648,7 @@ int dtls1_accept(SSL *s)
/* next message is server hello */
s->d1->handshake_write_seq = 0;
s->d1->next_handshake_write_seq = 0;
+ dtls1_clear_received_buffer(s);
goto end;
/* break; */
diff --git a/crypto/openssl/ssl/s2_lib.c b/crypto/openssl/ssl/s2_lib.c
index 4386ac53b925..6739afc9d2ee 100644
--- a/crypto/openssl/ssl/s2_lib.c
+++ b/crypto/openssl/ssl/s2_lib.c
@@ -94,12 +94,14 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] = {
0,
128,
128,
- SSL_ALL_CIPHERS,
- SSL_ALL_STRENGTHS,
- },
-/* RC4_128_EXPORT40_WITH_MD5 */
- {
- 1,
+ SSL_ALL_CIPHERS,
+ SSL_ALL_STRENGTHS,
+ },
+
+# if 0
+/* RC4_128_EXPORT40_WITH_MD5 */
+ {
+ 1,
SSL2_TXT_RC4_128_EXPORT40_WITH_MD5,
SSL2_CK_RC4_128_EXPORT40_WITH_MD5,
SSL_kRSA | SSL_aRSA | SSL_RC4 | SSL_MD5 | SSL_SSLV2,
@@ -107,12 +109,14 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] = {
SSL2_CF_5_BYTE_ENC,
40,
128,
- SSL_ALL_CIPHERS,
- SSL_ALL_STRENGTHS,
- },
-/* RC2_128_CBC_WITH_MD5 */
- {
- 1,
+ SSL_ALL_CIPHERS,
+ SSL_ALL_STRENGTHS,
+ },
+# endif
+
+/* RC2_128_CBC_WITH_MD5 */
+ {
+ 1,
SSL2_TXT_RC2_128_CBC_WITH_MD5,
SSL2_CK_RC2_128_CBC_WITH_MD5,
SSL_kRSA | SSL_aRSA | SSL_RC2 | SSL_MD5 | SSL_SSLV2,
@@ -120,12 +124,14 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] = {
0,
128,
128,
- SSL_ALL_CIPHERS,
- SSL_ALL_STRENGTHS,
- },
-/* RC2_128_CBC_EXPORT40_WITH_MD5 */
- {
- 1,
+ SSL_ALL_CIPHERS,
+ SSL_ALL_STRENGTHS,
+ },
+
+# if 0
+/* RC2_128_CBC_EXPORT40_WITH_MD5 */
+ {
+ 1,
SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5,
SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5,
SSL_kRSA | SSL_aRSA | SSL_RC2 | SSL_MD5 | SSL_SSLV2,
@@ -133,12 +139,14 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] = {
SSL2_CF_5_BYTE_ENC,
40,
128,
- SSL_ALL_CIPHERS,
- SSL_ALL_STRENGTHS,
- },
-/* IDEA_128_CBC_WITH_MD5 */
-# ifndef OPENSSL_NO_IDEA
- {
+ SSL_ALL_CIPHERS,
+ SSL_ALL_STRENGTHS,
+ },
+# endif
+
+/* IDEA_128_CBC_WITH_MD5 */
+# ifndef OPENSSL_NO_IDEA
+ {
1,
SSL2_TXT_IDEA_128_CBC_WITH_MD5,
SSL2_CK_IDEA_128_CBC_WITH_MD5,
@@ -148,12 +156,14 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] = {
128,
128,
SSL_ALL_CIPHERS,
- SSL_ALL_STRENGTHS,
- },
-# endif
-/* DES_64_CBC_WITH_MD5 */
- {
- 1,
+ SSL_ALL_STRENGTHS,
+ },
+# endif
+
+# if 0
+/* DES_64_CBC_WITH_MD5 */
+ {
+ 1,
SSL2_TXT_DES_64_CBC_WITH_MD5,
SSL2_CK_DES_64_CBC_WITH_MD5,
SSL_kRSA | SSL_aRSA | SSL_DES | SSL_MD5 | SSL_SSLV2,
@@ -161,12 +171,14 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] = {
0,
56,
56,
- SSL_ALL_CIPHERS,
- SSL_ALL_STRENGTHS,
- },
-/* DES_192_EDE3_CBC_WITH_MD5 */
- {
- 1,
+ SSL_ALL_CIPHERS,
+ SSL_ALL_STRENGTHS,
+ },
+# endif
+
+/* DES_192_EDE3_CBC_WITH_MD5 */
+ {
+ 1,
SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5,
SSL2_CK_DES_192_EDE3_CBC_WITH_MD5,
SSL_kRSA | SSL_aRSA | SSL_3DES | SSL_MD5 | SSL_SSLV2,
diff --git a/crypto/openssl/ssl/s2_srvr.c b/crypto/openssl/ssl/s2_srvr.c
index ba8c8e8858dd..48cc764fcf12 100644
--- a/crypto/openssl/ssl/s2_srvr.c
+++ b/crypto/openssl/ssl/s2_srvr.c
@@ -396,7 +396,7 @@ static int get_client_master_key(SSL *s)
}
cp = ssl2_get_cipher_by_char(p);
- if (cp == NULL) {
+ if (cp == NULL || sk_SSL_CIPHER_find(s->session->ciphers, cp) < 0) {
ssl2_return_error(s, SSL2_PE_NO_CIPHER);
SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH);
return (-1);
@@ -687,8 +687,12 @@ static int get_client_hello(SSL *s)
prio = cs;
allow = cl;
}
+
+ /* Generate list of SSLv2 ciphers shared between client and server */
for (z = 0; z < sk_SSL_CIPHER_num(prio); z++) {
- if (sk_SSL_CIPHER_find(allow, sk_SSL_CIPHER_value(prio, z)) < 0) {
+ const SSL_CIPHER *cp = sk_SSL_CIPHER_value(prio, z);
+ if ((cp->algorithms & SSL_SSLV2) == 0 ||
+ sk_SSL_CIPHER_find(allow, cp) < 0) {
(void)sk_SSL_CIPHER_delete(prio, z);
z--;
}
@@ -697,6 +701,13 @@ static int get_client_hello(SSL *s)
sk_SSL_CIPHER_free(s->session->ciphers);
s->session->ciphers = prio;
}
+
+ /* Make sure we have at least one cipher in common */
+ if (sk_SSL_CIPHER_num(s->session->ciphers) == 0) {
+ ssl2_return_error(s, SSL2_PE_NO_CIPHER);
+ SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CIPHER_MATCH);
+ return -1;
+ }
/*
* s->session->ciphers should now have a list of ciphers that are on
* both the client and server. This list is ordered by the order the
diff --git a/crypto/openssl/ssl/s3_clnt.c b/crypto/openssl/ssl/s3_clnt.c
index 8d035f7cfa62..62a48431da86 100644
--- a/crypto/openssl/ssl/s3_clnt.c
+++ b/crypto/openssl/ssl/s3_clnt.c
@@ -931,6 +931,12 @@ int ssl3_get_server_certificate(SSL *s)
goto f_err;
}
for (nc = 0; nc < llen;) {
+ if (nc + 3 > llen) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
+ SSL_R_CERT_LENGTH_MISMATCH);
+ goto f_err;
+ }
n2l3(p, l);
if ((l + nc + 3) > llen) {
al = SSL_AD_DECODE_ERROR;
@@ -1627,6 +1633,11 @@ int ssl3_get_certificate_request(SSL *s)
}
for (nc = 0; nc < llen;) {
+ if (nc + 2 > llen) {
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG);
+ goto err;
+ }
n2s(p, l);
if ((l + nc + 2) > llen) {
if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
diff --git a/crypto/openssl/ssl/s3_pkt.c b/crypto/openssl/ssl/s3_pkt.c
index ca0ef70648e4..8a9c92e6f05b 100644
--- a/crypto/openssl/ssl/s3_pkt.c
+++ b/crypto/openssl/ssl/s3_pkt.c
@@ -922,6 +922,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
return (ret);
}
+ /*
+ * Reset the count of consecutive warning alerts if we've got a non-empty
+ * record that isn't an alert.
+ */
+ if (rr->type != SSL3_RT_ALERT && rr->length != 0)
+ s->s3->alert_count = 0;
+
/* we now have a packet which can be read and processed */
if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
@@ -1121,6 +1128,14 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
if (alert_level == 1) { /* warning */
s->s3->warn_alert = alert_descr;
+
+ s->s3->alert_count++;
+ if (s->s3->alert_count == MAX_WARN_ALERT_COUNT) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS);
+ goto f_err;
+ }
+
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
return (0);
diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c
index 8749ea2434a8..0badd1d08089 100644
--- a/crypto/openssl/ssl/s3_srvr.c
+++ b/crypto/openssl/ssl/s3_srvr.c
@@ -819,7 +819,7 @@ int ssl3_get_client_hello(SSL *s)
session_length = *(p + SSL3_RANDOM_SIZE);
- if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) {
+ if (SSL3_RANDOM_SIZE + session_length + 1 >= (d + n) - p) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -837,7 +837,7 @@ int ssl3_get_client_hello(SSL *s)
/* get the session-id */
j = *(p++);
- if (p + j > d + n) {
+ if ((d + n) - p < j) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -874,14 +874,14 @@ int ssl3_get_client_hello(SSL *s)
if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) {
/* cookie stuff */
- if (p + 1 > d + n) {
+ if ((d + n) - p < 1) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
cookie_len = *(p++);
- if (p + cookie_len > d + n) {
+ if ((d + n ) - p < cookie_len) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -927,7 +927,7 @@ int ssl3_get_client_hello(SSL *s)
p += cookie_len;
}
- if (p + 2 > d + n) {
+ if ((d + n ) - p < 2) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -941,7 +941,7 @@ int ssl3_get_client_hello(SSL *s)
}
/* i bytes of cipher data + 1 byte for compression length later */
- if ((p + i + 1) > (d + n)) {
+ if ((d + n) - p < i + 1) {
/* not enough data */
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
@@ -1007,7 +1007,7 @@ int ssl3_get_client_hello(SSL *s)
/* compression */
i = *(p++);
- if ((p + i) > (d + n)) {
+ if ((d + n) - p < i) {
/* not enough data */
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
@@ -1029,7 +1029,7 @@ int ssl3_get_client_hello(SSL *s)
#ifndef OPENSSL_NO_TLSEXT
/* TLS extensions */
if (s->version >= SSL3_VERSION) {
- if (!ssl_parse_clienthello_tlsext(s, &p, d, n, &al)) {
+ if (!ssl_parse_clienthello_tlsext(s, &p, d + n, &al)) {
/* 'al' set by ssl_parse_clienthello_tlsext */
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT);
goto f_err;
@@ -2526,6 +2526,12 @@ int ssl3_get_client_certificate(SSL *s)
goto f_err;
}
for (nc = 0; nc < llen;) {
+ if (nc + 3 > llen) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
+ SSL_R_CERT_LENGTH_MISMATCH);
+ goto f_err;
+ }
n2l3(p, l);
if ((l + nc + 3) > llen) {
al = SSL_AD_DECODE_ERROR;
diff --git a/crypto/openssl/ssl/ssl.h b/crypto/openssl/ssl/ssl.h
index 2dcc3b8e9523..b6aa2cdabe97 100644
--- a/crypto/openssl/ssl/ssl.h
+++ b/crypto/openssl/ssl/ssl.h
@@ -1803,6 +1803,7 @@ void ERR_load_SSL_strings(void);
# define SSL_F_DTLS1_HANDLE_TIMEOUT 282
# define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255
# define SSL_F_DTLS1_PREPROCESS_FRAGMENT 277
+# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424
# define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256
# define SSL_F_DTLS1_PROCESS_RECORD 257
# define SSL_F_DTLS1_READ_BYTES 258
@@ -2194,6 +2195,7 @@ void ERR_load_SSL_strings(void);
# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110
# define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232
# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 227
+# define SSL_R_TOO_MANY_WARN_ALERTS 409
# define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
# define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234
# define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235
diff --git a/crypto/openssl/ssl/ssl3.h b/crypto/openssl/ssl/ssl3.h
index 761a0e20bed9..eda992fcec4f 100644
--- a/crypto/openssl/ssl/ssl3.h
+++ b/crypto/openssl/ssl/ssl3.h
@@ -491,6 +491,8 @@ typedef struct ssl3_state_st {
char is_probably_safari;
# endif /* !OPENSSL_NO_EC */
# endif /* !OPENSSL_NO_TLSEXT */
+ /* Count of the number of consecutive warning alerts received */
+ unsigned int alert_count;
} SSL3_STATE;
/* SSLv3 */
diff --git a/crypto/openssl/ssl/ssl_err.c b/crypto/openssl/ssl/ssl_err.c
index 65c8f61e78b3..42b50cba5294 100644
--- a/crypto/openssl/ssl/ssl_err.c
+++ b/crypto/openssl/ssl/ssl_err.c
@@ -1,6 +1,6 @@
/* ssl/ssl_err.c */
/* ====================================================================
- * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2016 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
@@ -92,6 +92,8 @@ static ERR_STRING_DATA SSL_str_functs[] = {
{ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT), "DTLS1_HANDLE_TIMEOUT"},
{ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"},
{ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"},
+ {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS),
+ "DTLS1_PROCESS_BUFFERED_RECORDS"},
{ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE),
"DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"},
{ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"},
diff --git a/crypto/openssl/ssl/ssl_lib.c b/crypto/openssl/ssl/ssl_lib.c
index 7182bd22579f..e70cfb5fcca7 100644
--- a/crypto/openssl/ssl/ssl_lib.c
+++ b/crypto/openssl/ssl/ssl_lib.c
@@ -1632,12 +1632,19 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
/*
* Default is to connect to non-RI servers. When RI is more widely
* deployed might change this.
- */
- ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
-
- return (ret);
- err:
- SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ */
+ ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
+
+ /*
+ * Disable SSLv2 by default, callers that want to enable SSLv2 will have to
+ * explicitly clear this option via either of SSL_CTX_clear_options() or
+ * SSL_clear_options().
+ */
+ ret->options |= SSL_OP_NO_SSLv2;
+
+ return (ret);
+ err:
+ SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE);
err2:
if (ret != NULL)
SSL_CTX_free(ret);
diff --git a/crypto/openssl/ssl/ssl_locl.h b/crypto/openssl/ssl/ssl_locl.h
index 038554f0d69b..ecb0814f3fa6 100644
--- a/crypto/openssl/ssl/ssl_locl.h
+++ b/crypto/openssl/ssl/ssl_locl.h
@@ -247,6 +247,8 @@
# define DEC32(a) ((a)=((a)-1)&0xffffffffL)
# define MAX_MAC_SIZE 20 /* up from 16 for SSLv3 */
+# define MAX_WARN_ALERT_COUNT 5
+
/*
* Define the Bitmasks for SSL_CIPHER.algorithms.
* This bits are used packed as dense as possible. If new methods/ciphers
@@ -910,7 +912,8 @@ int dtls1_retransmit_message(SSL *s, unsigned short seq,
unsigned long frag_off, int *found);
int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
int dtls1_retransmit_buffered_messages(SSL *s);
-void dtls1_clear_record_buffer(SSL *s);
+void dtls1_clear_received_buffer(SSL *s);
+void dtls1_clear_sent_buffer(SSL *s);
void dtls1_get_message_header(unsigned char *data,
struct hm_header_st *msg_hdr);
void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
@@ -1022,7 +1025,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p,
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p,
unsigned char *limit);
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data,
- unsigned char *d, int n, int *al);
+ unsigned char *limit, int *al);
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data,
unsigned char *d, int n, int *al);
int ssl_prepare_clienthello_tlsext(SSL *s);
diff --git a/crypto/openssl/ssl/ssl_sess.c b/crypto/openssl/ssl/ssl_sess.c
index 51c02dc9edd6..19e284a43fce 100644
--- a/crypto/openssl/ssl/ssl_sess.c
+++ b/crypto/openssl/ssl/ssl_sess.c
@@ -384,7 +384,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
goto err;
- if (session_id + len > limit) {
+ if (limit - session_id < len) {
fatal = 1;
goto err;
}
diff --git a/crypto/openssl/ssl/t1_lib.c b/crypto/openssl/ssl/t1_lib.c
index dd02c933c307..d4ee92cc9f78 100644
--- a/crypto/openssl/ssl/t1_lib.c
+++ b/crypto/openssl/ssl/t1_lib.c
@@ -357,7 +357,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p,
* 10.8..10.8.3 (which don't work).
*/
static void ssl_check_for_safari(SSL *s, const unsigned char *data,
- const unsigned char *d, int n)
+ const unsigned char *limit)
{
unsigned short type, size;
static const unsigned char kSafariExtensionsBlock[] = {
@@ -386,11 +386,11 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
0x02, 0x03, /* SHA-1/ECDSA */
};
- if (data >= (d + n - 2))
+ if (limit - data <= 2)
return;
data += 2;
- if (data > (d + n - 4))
+ if (limit - data < 4)
return;
n2s(data, type);
n2s(data, size);
@@ -398,7 +398,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
if (type != TLSEXT_TYPE_server_name)
return;
- if (data + size > d + n)
+ if (limit - data < size)
return;
data += size;
@@ -406,7 +406,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
const size_t len1 = sizeof(kSafariExtensionsBlock);
const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
- if (data + len1 + len2 != d + n)
+ if (limit - data != (int)(len1 + len2))
return;
if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
return;
@@ -415,7 +415,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
} else {
const size_t len = sizeof(kSafariExtensionsBlock);
- if (data + len != d + n)
+ if (limit - data != (int)(len))
return;
if (memcmp(data, kSafariExtensionsBlock, len) != 0)
return;
@@ -425,8 +425,8 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
}
# endif /* !OPENSSL_NO_EC */
-int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
- int n, int *al)
+int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p,
+ unsigned char *limit, int *al)
{
unsigned short type;
unsigned short size;
@@ -439,24 +439,26 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
# ifndef OPENSSL_NO_EC
if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
- ssl_check_for_safari(s, data, d, n);
+ ssl_check_for_safari(s, data, limit);
# endif /* !OPENSSL_NO_EC */
- if (data >= (d + n - 2))
+ if (data == limit)
goto ri_check;
+ if (limit - data < 2)
+ goto err;
+
n2s(data, len);
- if (data > (d + n - len))
- goto ri_check;
+ if (limit - data != len)
+ goto err;
- while (data <= (d + n - 4)) {
+ while (limit - data >= 4) {
n2s(data, type);
n2s(data, size);
- if (data + size > (d + n))
- goto ri_check;
-
+ if (limit - data < size)
+ goto err;
if (s->tlsext_debug_cb)
s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg);
/*-
@@ -580,6 +582,23 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
*al = SSL_AD_DECODE_ERROR;
return 0;
}
+
+ /*
+ * We remove any OCSP_RESPIDs from a previous handshake
+ * to prevent unbounded memory growth - CVE-2016-6304
+ */
+ sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids,
+ OCSP_RESPID_free);
+ if (dsize > 0) {
+ s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
+ if (s->tlsext_ocsp_ids == NULL) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ } else {
+ s->tlsext_ocsp_ids = NULL;
+ }
+
while (dsize > 0) {
OCSP_RESPID *id;
int idsize;
@@ -606,13 +625,6 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
*al = SSL_AD_DECODE_ERROR;
return 0;
}
- if (!s->tlsext_ocsp_ids
- && !(s->tlsext_ocsp_ids =
- sk_OCSP_RESPID_new_null())) {
- OCSP_RESPID_free(id);
- *al = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) {
OCSP_RESPID_free(id);
*al = SSL_AD_INTERNAL_ERROR;
@@ -672,6 +684,10 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
}
return 1;
+
+err:
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
}
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
@@ -684,20 +700,20 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
int tlsext_servername = 0;
int renegotiate_seen = 0;
- if (data >= (d + n - 2))
+ if ((d + n) - data <= 2)
goto ri_check;
n2s(data, length);
- if (data + length != d + n) {
+ if ((d + n) - data != length) {
*al = SSL_AD_DECODE_ERROR;
return 0;
}
- while (data <= (d + n - 4)) {
+ while ((d + n) - data >= 4) {
n2s(data, type);
n2s(data, size);
- if (data + size > (d + n))
+ if ((d + n) - data < size)
goto ri_check;
if (s->tlsext_debug_cb)
@@ -960,29 +976,33 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
/* Skip past DTLS cookie */
if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) {
i = *(p++);
- p += i;
- if (p >= limit)
+
+ if (limit - p <= i)
return -1;
+
+ p += i;
}
/* Skip past cipher list */
n2s(p, i);
- p += i;
- if (p >= limit)
+ if (limit - p <= i)
return -1;
+ p += i;
+
/* Skip past compression algorithm list */
i = *(p++);
- p += i;
- if (p > limit)
+ if (limit - p < i)
return -1;
+ p += i;
+
/* Now at start of extensions */
- if ((p + 2) >= limit)
+ if (limit - p <= 2)
return 1;
n2s(p, i);
- while ((p + 4) <= limit) {
+ while (limit - p >= 4) {
unsigned short type, size;
n2s(p, type);
n2s(p, size);
- if (p + size > limit)
+ if (limit - p < size)
return 1;
if (type == TLSEXT_TYPE_session_ticket) {
/*
@@ -1012,9 +1032,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
HMAC_CTX hctx;
EVP_CIPHER_CTX ctx;
SSL_CTX *tctx = s->initial_ctx;
- /* Need at least keyname + iv + some encrypted data */
- if (eticklen < 48)
- goto tickerr;
+
/* Initialize session ticket encryption and HMAC contexts */
HMAC_CTX_init(&hctx);
EVP_CIPHER_CTX_init(&ctx);
@@ -1042,6 +1060,13 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
* checks on ticket.
*/
mlen = HMAC_size(&hctx);
+ /* Sanity check ticket length: must exceed keyname + IV + HMAC */
+ if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) {
+ HMAC_CTX_cleanup(&hctx);
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return 2;
+ }
+
eticklen -= mlen;
/* Check HMAC of encrypted ticket */
HMAC_Update(&hctx, etick, eticklen);