Module Name: src
Committed By: msaitoh
Date: Wed Aug 27 13:30:49 UTC 2014
Modified Files:
src/crypto/dist/openssl/crypto/asn1 [netbsd-5-2]: a_object.c asn1.h
asn1_err.c
src/crypto/dist/openssl/crypto/objects [netbsd-5-2]: obj_dat.c
src/crypto/dist/openssl/ssl [netbsd-5-2]: d1_both.c s23_srvr.c
s3_clnt.c t1_lib.c
Log Message:
Pull up following revision(s) (requested by spz in ticket #1918):
crypto/dist/openssl/crypto/asn1/a_object.c patch
crypto/dist/openssl/crypto/asn1/asn1.h patch
crypto/dist/openssl/crypto/asn1/asn1_err.c patch
crypto/dist/openssl/crypto/objects/obj_dat.c patch
crypto/dist/openssl/ssl/d1_both.c patch
crypto/dist/openssl/ssl/s23_srvr.c patch
crypto/dist/openssl/ssl/s3_clnt.c patch
crypto/dist/openssl/ssl/t1_lib.c patch
Patches for the following vulnerabilities:
Information leak in pretty printing functions (CVE-2014-3508)
Double Free when processing DTLS packets (CVE-2014-3505)
DTLS memory exhaustion (CVE-2014-3506)
DTLS memory leak from zero-length fragments (CVE-2014-3507)
OpenSSL DTLS anonymous EC(DH) denial of service (CVE-2014-3510)
Race condition in ssl_parse_serverhello_tlsext (CVE-2014-3509)
OpenSSL TLS protocol downgrade attack (CVE-2014-3511)
backported from the recent 1.0.1i OpenSSL release.
To generate a diff of this commit:
cvs rdiff -u -r1.1.1.7 -r1.1.1.7.2.1 \
src/crypto/dist/openssl/crypto/asn1/a_object.c
cvs rdiff -u -r1.9.4.1 -r1.9.4.1.10.1 \
src/crypto/dist/openssl/crypto/asn1/asn1.h
cvs rdiff -u -r1.1.1.8.4.1 -r1.1.1.8.4.1.10.1 \
src/crypto/dist/openssl/crypto/asn1/asn1_err.c
cvs rdiff -u -r1.10 -r1.10.2.1 \
src/crypto/dist/openssl/crypto/objects/obj_dat.c
cvs rdiff -u -r1.3.4.2.6.1 -r1.3.4.2.6.2 \
src/crypto/dist/openssl/ssl/d1_both.c
cvs rdiff -u -r1.6 -r1.6.2.1 src/crypto/dist/openssl/ssl/s23_srvr.c
cvs rdiff -u -r1.12.4.3.4.1 -r1.12.4.3.4.2 \
src/crypto/dist/openssl/ssl/s3_clnt.c
cvs rdiff -u -r1.2.4.3 -r1.2.4.3.2.1 src/crypto/dist/openssl/ssl/t1_lib.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/crypto/dist/openssl/crypto/asn1/a_object.c
diff -u src/crypto/dist/openssl/crypto/asn1/a_object.c:1.1.1.7 src/crypto/dist/openssl/crypto/asn1/a_object.c:1.1.1.7.2.1
--- src/crypto/dist/openssl/crypto/asn1/a_object.c:1.1.1.7 Fri May 9 21:34:16 2008
+++ src/crypto/dist/openssl/crypto/asn1/a_object.c Wed Aug 27 13:30:49 2014
@@ -95,7 +95,7 @@ int a2d_ASN1_OBJECT(unsigned char *out,
if (num == 0)
return(0);
else if (num == -1)
- num=strlen(buf);
+ num=(int)strlen(buf);
p=buf;
c= *(p++);
@@ -239,7 +239,7 @@ int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT
if ((a == NULL) || (a->data == NULL))
return(BIO_write(bp,"NULL",4));
- i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
+ i=i2t_ASN1_OBJECT(buf,(int)sizeof buf,a);
if (i > (int)(sizeof(buf) - 1))
{
p = OPENSSL_malloc(i + 1);
@@ -289,7 +289,21 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT
ASN1_OBJECT *ret=NULL;
const unsigned char *p;
unsigned char *data;
- int i;
+ int i, length;
+
+ /* Sanity check OID encoding.
+ * Need at least one content octet.
+ * MSB must be clear in the last octet.
+ * can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
+ */
+ if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
+ p[len - 1] & 0x80)
+ {
+ ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING);
+ return NULL;
+ }
+ /* Now 0 < len <= INT_MAX, so the cast is safe. */
+ length = (int)len;
/* only the ASN1_OBJECTs from the 'table' will have values
* for ->sn or ->ln */
@@ -300,28 +314,27 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT
}
else ret=(*a);
- p= *pp;
/* detach data from object */
data = (unsigned char *)ret->data;
ret->data = NULL;
/* once detached we can change it */
- if ((data == NULL) || (ret->length < len))
+ if ((data == NULL) || (ret->length < length))
{
ret->length=0;
if (data != NULL) OPENSSL_free(data);
- data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
+ data=(unsigned char *)OPENSSL_malloc(length);
if (data == NULL)
{ i=ERR_R_MALLOC_FAILURE; goto err; }
ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
}
- memcpy(data,p,(int)len);
+ memcpy(data,p,length);
/* reattach data to object, after which it remains const */
ret->data =data;
- ret->length=(int)len;
+ ret->length=length;
ret->sn=NULL;
ret->ln=NULL;
/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
- p+=len;
+ p+=length;
if (a != NULL) (*a)=ret;
*pp=p;
Index: src/crypto/dist/openssl/crypto/asn1/asn1.h
diff -u src/crypto/dist/openssl/crypto/asn1/asn1.h:1.9.4.1 src/crypto/dist/openssl/crypto/asn1/asn1.h:1.9.4.1.10.1
--- src/crypto/dist/openssl/crypto/asn1/asn1.h:1.9.4.1 Mon Mar 30 16:29:38 2009
+++ src/crypto/dist/openssl/crypto/asn1/asn1.h Wed Aug 27 13:30:49 2014
@@ -1314,6 +1314,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_INVALID_MIME_TYPE 205
#define ASN1_R_INVALID_MODIFIER 186
#define ASN1_R_INVALID_NUMBER 187
+#define ASN1_R_INVALID_OBJECT_ENCODING 216
#define ASN1_R_INVALID_SEPARATOR 131
#define ASN1_R_INVALID_TIME_FORMAT 132
#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133
Index: src/crypto/dist/openssl/crypto/asn1/asn1_err.c
diff -u src/crypto/dist/openssl/crypto/asn1/asn1_err.c:1.1.1.8.4.1 src/crypto/dist/openssl/crypto/asn1/asn1_err.c:1.1.1.8.4.1.10.1
--- src/crypto/dist/openssl/crypto/asn1/asn1_err.c:1.1.1.8.4.1 Mon Mar 30 16:29:38 2009
+++ src/crypto/dist/openssl/crypto/asn1/asn1_err.c Wed Aug 27 13:30:49 2014
@@ -245,6 +245,7 @@ static ERR_STRING_DATA ASN1_str_reasons[
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
{ERR_REASON(ASN1_R_INVALID_MODIFIER) ,"invalid modifier"},
{ERR_REASON(ASN1_R_INVALID_NUMBER) ,"invalid number"},
+{ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING),"invalid object encoding"},
{ERR_REASON(ASN1_R_INVALID_SEPARATOR) ,"invalid separator"},
{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT) ,"invalid time format"},
{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),"invalid universalstring length"},
Index: src/crypto/dist/openssl/crypto/objects/obj_dat.c
diff -u src/crypto/dist/openssl/crypto/objects/obj_dat.c:1.10 src/crypto/dist/openssl/crypto/objects/obj_dat.c:1.10.2.1
--- src/crypto/dist/openssl/crypto/objects/obj_dat.c:1.10 Fri May 9 21:49:41 2008
+++ src/crypto/dist/openssl/crypto/objects/obj_dat.c Wed Aug 27 13:30:49 2014
@@ -464,8 +464,11 @@ int OBJ_obj2txt(char *buf, int buf_len,
const unsigned char *p;
char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
- if ((a == NULL) || (a->data == NULL)) {
+ /* Ensure that, at every state, |buf| is NUL-terminated. */
+ if (buf && buf_len > 0)
buf[0]='\0';
+
+ if ((a == NULL) || (a->data == NULL)) {
return(0);
}
@@ -544,9 +547,10 @@ int OBJ_obj2txt(char *buf, int buf_len,
i=(int)(l/40);
l-=(long)(i*40);
}
- if (buf && (buf_len > 0))
+ if (buf && (buf_len > 1))
{
*buf++ = i + '0';
+ *buf = '\0';
buf_len--;
}
n++;
@@ -561,9 +565,10 @@ int OBJ_obj2txt(char *buf, int buf_len,
i = strlen(bndec);
if (buf)
{
- if (buf_len > 0)
+ if (buf_len > 1)
{
*buf++ = '.';
+ *buf = '\0';
buf_len--;
}
BUF_strlcpy(buf,bndec,buf_len);
Index: src/crypto/dist/openssl/ssl/d1_both.c
diff -u src/crypto/dist/openssl/ssl/d1_both.c:1.3.4.2.6.1 src/crypto/dist/openssl/ssl/d1_both.c:1.3.4.2.6.2
--- src/crypto/dist/openssl/ssl/d1_both.c:1.3.4.2.6.1 Fri Jun 6 06:42:08 2014
+++ src/crypto/dist/openssl/ssl/d1_both.c Wed Aug 27 13:30:49 2014
@@ -549,6 +549,17 @@ dtls1_retrieve_buffered_fragment(SSL *s,
}
+/* dtls1_max_handshake_message_len returns the maximum number of bytes
+ * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but may
+ * be greater if the maximum certificate list size requires it. */
+static unsigned long dtls1_max_handshake_message_len(const SSL *s)
+ {
+ unsigned long max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
+ if (max_len < (unsigned long)s->max_cert_list)
+ return s->max_cert_list;
+ return max_len;
+ }
+
static int
dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
{
@@ -558,7 +569,8 @@ dtls1_process_out_of_seq_message(SSL *s,
unsigned char seq64be[8];
unsigned long frag_len = msg_hdr->frag_len;
- if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
+ if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len ||
+ msg_hdr->msg_len > dtls1_max_handshake_message_len(s))
goto err;
/* Try to find item in queue, to prevent duplicate entries */
@@ -585,6 +597,8 @@ dtls1_process_out_of_seq_message(SSL *s,
i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
devnull,
frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0);
+ if ((unsigned long)i!=frag_len)
+ i = -1;
if (i<=0) goto err;
frag_len -= i;
}
@@ -592,6 +606,9 @@ dtls1_process_out_of_seq_message(SSL *s,
if (frag_len)
{
+ if (frag_len > dtls1_max_handshake_message_len(s))
+ goto err;
+
frag = dtls1_hm_fragment_new(frag_len);
if ( frag == NULL)
goto err;
@@ -604,6 +621,9 @@ dtls1_process_out_of_seq_message(SSL *s,
if (i<=0 || (unsigned long)i!=frag_len)
goto err;
+ if (frag_len == 0)
+ return DTLS1_HM_FRAGMENT_RETRY;
+
memset(seq64be,0,sizeof(seq64be));
seq64be[6] = (unsigned char)(msg_hdr->seq>>8);
seq64be[7] = (unsigned char)(msg_hdr->seq);
@@ -612,14 +632,18 @@ dtls1_process_out_of_seq_message(SSL *s,
if ( item == NULL)
goto err;
- pqueue_insert(s->d1->buffered_messages, item);
+ item = pqueue_insert(s->d1->buffered_messages, item);
+ /* pqueue_insert fails if a duplicate item is inserted.
+ * However, |item| cannot be a duplicate. If it were,
+ * |pqueue_find|, above, would have returned it and control
+ * would never have reached this branch. */
+ OPENSSL_assert(item != NULL);
}
return DTLS1_HM_FRAGMENT_RETRY;
err:
- if ( frag != NULL) dtls1_hm_fragment_free(frag);
- if ( item != NULL) OPENSSL_free(item);
+ if ( frag != NULL && item == NULL ) dtls1_hm_fragment_free(frag);
*ok = 0;
return i;
}
@@ -704,6 +728,8 @@ dtls1_get_message_fragment(SSL *s, int s
i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
&p[frag_off],frag_len,0);
/* XDTLS: fix this--message fragments cannot span multiple packets */
+ if ((unsigned long)i!=frag_len)
+ i=-1;
if (i <= 0)
{
s->rwstate=SSL_READING;
Index: src/crypto/dist/openssl/ssl/s23_srvr.c
diff -u src/crypto/dist/openssl/ssl/s23_srvr.c:1.6 src/crypto/dist/openssl/ssl/s23_srvr.c:1.6.2.1
--- src/crypto/dist/openssl/ssl/s23_srvr.c:1.6 Fri May 9 21:49:42 2008
+++ src/crypto/dist/openssl/ssl/s23_srvr.c Wed Aug 27 13:30:49 2014
@@ -332,13 +332,11 @@ int ssl23_get_client_hello(SSL *s)
* attacks. */
if (p[3] == 0 && p[4] < 6)
{
-#if 0
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL);
goto err;
-#else
- v[1] = TLS1_VERSION_MINOR;
-#endif
}
+ if (p[9] > SSL3_VERSION_MAJOR)
+ v[1]=0xff;
else
v[1]=p[10]; /* minor version according to client_version */
if (v[1] >= TLS1_VERSION_MINOR)
@@ -396,14 +394,34 @@ int ssl23_get_client_hello(SSL *s)
v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
v[1] = p[4];
+ /* An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2
+ * header is sent directly on the wire, not wrapped as a TLS
+ * record. It's format is:
+ * Byte Content
+ * 0-1 msg_length
+ * 2 msg_type
+ * 3-4 version
+ * 5-6 cipher_spec_length
+ * 7-8 session_id_length
+ * 9-10 challenge_length
+ * ... ...
+ */
n=((p[0]&0x7f)<<8)|p[1];
if (n > (1024*4))
{
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
goto err;
}
+ if (n < 9)
+ {
+ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH);
+ goto err;
+ }
j=ssl23_read_bytes(s,n+2);
+ /* We previously read 11 bytes, so if j > 0, we must have
+ * j == n+2 == s->packet_length. We have at least 11 valid
+ * packet bytes. */
if (j <= 0) return(j);
ssl3_finish_mac(s, s->packet+2, s->packet_length-2);
Index: src/crypto/dist/openssl/ssl/s3_clnt.c
diff -u src/crypto/dist/openssl/ssl/s3_clnt.c:1.12.4.3.4.1 src/crypto/dist/openssl/ssl/s3_clnt.c:1.12.4.3.4.2
--- src/crypto/dist/openssl/ssl/s3_clnt.c:1.12.4.3.4.1 Fri Jun 6 06:42:08 2014
+++ src/crypto/dist/openssl/ssl/s3_clnt.c Wed Aug 27 13:30:49 2014
@@ -1956,6 +1956,13 @@ int ssl3_send_client_key_exchange(SSL *s
RSA *rsa;
unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
+ if (s->session->sess_cert == NULL)
+ {
+ /* We should always have a server certificate with SSL_kRSA. */
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
if (s->session->sess_cert->peer_rsa_tmp != NULL)
rsa=s->session->sess_cert->peer_rsa_tmp;
else
Index: src/crypto/dist/openssl/ssl/t1_lib.c
diff -u src/crypto/dist/openssl/ssl/t1_lib.c:1.2.4.3 src/crypto/dist/openssl/ssl/t1_lib.c:1.2.4.3.2.1
--- src/crypto/dist/openssl/ssl/t1_lib.c:1.2.4.3 Wed Feb 16 21:00:23 2011
+++ src/crypto/dist/openssl/ssl/t1_lib.c Wed Aug 27 13:30:49 2014
@@ -937,6 +937,7 @@ int ssl_parse_serverhello_tlsext(SSL *s,
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
+ if (!s->hit) {
s->session->tlsext_ecpointformatlist_length = 0;
if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
@@ -946,6 +947,7 @@ int ssl_parse_serverhello_tlsext(SSL *s,
}
s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
+ }
#if 0
fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
sdata = s->session->tlsext_ecpointformatlist;