summaryrefslogtreecommitdiff
path: root/openssl/ssl
diff options
context:
space:
mode:
authordigit@chromium.org <digit@chromium.org@4ff67af0-8c30-449e-8e8b-ad334ec8d88c>2013-01-24 10:15:07 +0000
committerdigit@chromium.org <digit@chromium.org@4ff67af0-8c30-449e-8e8b-ad334ec8d88c>2013-01-24 10:15:07 +0000
commite4dea707fa21299f1e0abf4c12827adfccb2eb85 (patch)
treea28ac4a84eb9469037bd7728b96c7c84b99697cd /openssl/ssl
parentecd56d84116e2acded8a6c4e0ea6ffdde09c2a78 (diff)
downloadopenssl-e4dea707fa21299f1e0abf4c12827adfccb2eb85.tar.gz
Update the openssl sources to the latest Android version.
Compared to the previous version, this includes the following fixes: - Remove "small_records.patch". https://android-review.googlesource.com/#/c/49977/ - Add support for TLS channel ID. https://android-review.googlesource.com/#/c/49984/ - Remove recursive lock in X509_PUBKEY_get. https://android-review.googlesource.com/#/c/50413/ - Add x86_64 assembly files and use them. https://android-review.googlesource.com/#/c/47913/ https://android-review.googlesource.com/#/c/50401/ https://android-review.googlesource.com/#/c/50402/ This should only matter for the "linux_redux" build, and the net/tools/flip_server binary (flip_in_mem_edsm_server) which implements a host SPDY proxy. - Remove obsolete patch file fix-clang-build.patch. Review URL: https://codereview.chromium.org/12033053 git-svn-id: http://src.chromium.org/svn/trunk/deps/third_party/openssl@178558 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
Diffstat (limited to 'openssl/ssl')
-rw-r--r--openssl/ssl/d1_pkt.c29
-rw-r--r--openssl/ssl/s23_srvr.c7
-rw-r--r--openssl/ssl/s3_both.c34
-rw-r--r--openssl/ssl/s3_clnt.c166
-rw-r--r--openssl/ssl/s3_lib.c56
-rw-r--r--openssl/ssl/s3_pkt.c45
-rw-r--r--openssl/ssl/s3_srvr.c196
-rw-r--r--openssl/ssl/ssl.h57
-rw-r--r--openssl/ssl/ssl3.h28
-rw-r--r--openssl/ssl/ssl_err.c11
-rw-r--r--openssl/ssl/ssl_lib.c10
-rw-r--r--openssl/ssl/ssl_locl.h5
-rw-r--r--openssl/ssl/ssltest.c35
-rw-r--r--openssl/ssl/t1_lib.c60
-rw-r--r--openssl/ssl/tls1.h3
15 files changed, 549 insertions, 193 deletions
diff --git a/openssl/ssl/d1_pkt.c b/openssl/ssl/d1_pkt.c
index e3e9864..987af60 100644
--- a/openssl/ssl/d1_pkt.c
+++ b/openssl/ssl/d1_pkt.c
@@ -614,24 +614,6 @@ again:
goto again;
}
- /* If we receive a valid record larger than the current buffer size,
- * allocate some memory for it.
- */
- if (rr->length > s->s3->rbuf.len - DTLS1_RT_HEADER_LENGTH)
- {
- unsigned char *pp;
- unsigned int newlen = rr->length + DTLS1_RT_HEADER_LENGTH;
- if ((pp=OPENSSL_realloc(s->s3->rbuf.buf, newlen))==NULL)
- {
- SSLerr(SSL_F_DTLS1_GET_RECORD,ERR_R_MALLOC_FAILURE);
- return(-1);
- }
- p = pp + (p - s->s3->rbuf.buf);
- s->s3->rbuf.buf=pp;
- s->s3->rbuf.len=newlen;
- s->packet= &(s->s3->rbuf.buf[0]);
- }
-
/* now s->rstate == SSL_ST_READ_BODY */
}
@@ -1470,7 +1452,6 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
SSL3_BUFFER *wb;
SSL_SESSION *sess;
int bs;
- unsigned int len_with_overhead = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;
/* first check if there is a SSL3_BUFFER still being written
* out. This will happen with non blocking IO */
@@ -1480,16 +1461,6 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
return(ssl3_write_pending(s,type,buf,len));
}
- if (s->s3->wbuf.len < len_with_overhead)
- {
- if ((p=OPENSSL_realloc(s->s3->wbuf.buf, len_with_overhead)) == NULL) {
- SSLerr(SSL_F_DO_DTLS1_WRITE,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s->s3->wbuf.buf = p;
- s->s3->wbuf.len = len_with_overhead;
- }
-
/* If we have an alert to send, lets send it */
if (s->s3->alert_dispatch)
{
diff --git a/openssl/ssl/s23_srvr.c b/openssl/ssl/s23_srvr.c
index 4c4721f..4877849 100644
--- a/openssl/ssl/s23_srvr.c
+++ b/openssl/ssl/s23_srvr.c
@@ -444,13 +444,8 @@ int ssl23_get_client_hello(SSL *s)
v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
v[1] = p[4];
-/* The SSL2 protocol allows n to be larger, just pick
- * a reasonable buffer size. */
-#if SSL3_RT_DEFAULT_PACKET_SIZE < 1024*4 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
-#error "SSL3_RT_DEFAULT_PACKET_SIZE is too small."
-#endif
n=((p[0]&0x7f)<<8)|p[1];
- if (n > SSL3_RT_DEFAULT_PACKET_SIZE - 2)
+ if (n > (1024*4))
{
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
goto err;
diff --git a/openssl/ssl/s3_both.c b/openssl/ssl/s3_both.c
index af271d6..c8a7d18 100644
--- a/openssl/ssl/s3_both.c
+++ b/openssl/ssl/s3_both.c
@@ -551,7 +551,8 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
ssl3_take_mac(s);
#endif
/* Feed this message into MAC computation. */
- ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
+ if (*s->init_buf->data != SSL3_MT_ENCRYPTED_EXTENSIONS)
+ ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
if (s->msg_callback)
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);
*ok=1;
@@ -752,20 +753,13 @@ int ssl3_setup_read_buffer(SSL *s)
if (s->s3->rbuf.buf == NULL)
{
- if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
- {
- len = SSL3_RT_DEFAULT_PACKET_SIZE;
- }
- else
+ len = SSL3_RT_MAX_PLAIN_LENGTH
+ + SSL3_RT_MAX_ENCRYPTED_OVERHEAD
+ + headerlen + align;
+ if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
{
- len = SSL3_RT_MAX_PLAIN_LENGTH
- + SSL3_RT_MAX_ENCRYPTED_OVERHEAD
- + headerlen + align;
- if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
- {
- s->s3->init_extra = 1;
- len += SSL3_RT_MAX_EXTRA;
- }
+ s->s3->init_extra = 1;
+ len += SSL3_RT_MAX_EXTRA;
}
#ifndef OPENSSL_NO_COMP
if (!(s->options & SSL_OP_NO_COMPRESSION))
@@ -801,15 +795,7 @@ int ssl3_setup_write_buffer(SSL *s)
if (s->s3->wbuf.buf == NULL)
{
- if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
- {
- len = SSL3_RT_DEFAULT_PACKET_SIZE;
- }
- else
- {
- len = s->max_send_fragment;
- }
- len += 0
+ len = s->max_send_fragment
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
+ headerlen + align;
#ifndef OPENSSL_NO_COMP
@@ -819,6 +805,7 @@ int ssl3_setup_write_buffer(SSL *s)
if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
len += headerlen + align
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+
if ((p=freelist_extract(s->ctx, 0, len)) == NULL)
goto err;
s->s3->wbuf.buf = p;
@@ -861,3 +848,4 @@ int ssl3_release_read_buffer(SSL *s)
}
return 1;
}
+
diff --git a/openssl/ssl/s3_clnt.c b/openssl/ssl/s3_clnt.c
index d24bf52..a5d646a 100644
--- a/openssl/ssl/s3_clnt.c
+++ b/openssl/ssl/s3_clnt.c
@@ -202,18 +202,6 @@ int ssl3_connect(SSL *s)
s->in_handshake++;
if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
-#if 0 /* Send app data in separate packet, otherwise, some particular site
- * (only one site so far) closes the socket.
- * Note: there is a very small chance that two TCP packets
- * could be arriving at server combined into a single TCP packet,
- * then trigger that site to break. We haven't encounter that though.
- */
- if (SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
- {
- /* Send app data along with CCS/Finished */
- s->s3->flags |= SSL3_FLAGS_DELAY_CLIENT_FINISHED;
- }
-#endif
#ifndef OPENSSL_NO_HEARTBEATS
/* If we're awaiting a HeartbeatResponse, pretend we
@@ -227,6 +215,24 @@ int ssl3_connect(SSL *s)
}
#endif
+// BEGIN android-added
+#if 0
+/* Send app data in separate packet, otherwise, some particular site
+ * (only one site so far) closes the socket. http://b/2511073
+ * Note: there is a very small chance that two TCP packets
+ * could be arriving at server combined into a single TCP packet,
+ * then trigger that site to break. We haven't encounter that though.
+ */
+// END android-added
+ if (SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
+ {
+ /* Send app data along with CCS/Finished */
+ s->s3->flags |= SSL3_FLAGS_DELAY_CLIENT_FINISHED;
+ }
+
+// BEGIN android-added
+#endif
+// END android-added
for (;;)
{
state=s->state;
@@ -471,14 +477,14 @@ int ssl3_connect(SSL *s)
SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
if (ret <= 0) goto end;
-
-#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
s->state=SSL3_ST_CW_FINISHED_A;
-#else
+#if !defined(OPENSSL_NO_TLSEXT)
+ if (s->s3->tlsext_channel_id_valid)
+ s->state=SSL3_ST_CW_CHANNEL_ID_A;
+# if !defined(OPENSSL_NO_NEXTPROTONEG)
if (s->s3->next_proto_neg_seen)
s->state=SSL3_ST_CW_NEXT_PROTO_A;
- else
- s->state=SSL3_ST_CW_FINISHED_A;
+# endif
#endif
s->init_num=0;
@@ -512,6 +518,18 @@ int ssl3_connect(SSL *s)
case SSL3_ST_CW_NEXT_PROTO_B:
ret=ssl3_send_next_proto(s);
if (ret <= 0) goto end;
+ if (s->s3->tlsext_channel_id_valid)
+ s->state=SSL3_ST_CW_CHANNEL_ID_A;
+ else
+ s->state=SSL3_ST_CW_FINISHED_A;
+ break;
+#endif
+
+#if !defined(OPENSSL_NO_TLSEXT)
+ case SSL3_ST_CW_CHANNEL_ID_A:
+ case SSL3_ST_CW_CHANNEL_ID_B:
+ ret=ssl3_send_channel_id(s);
+ if (ret <= 0) goto end;
s->state=SSL3_ST_CW_FINISHED_A;
break;
#endif
@@ -3354,7 +3372,8 @@ err:
return(0);
}
-#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+#if !defined(OPENSSL_NO_TLSEXT)
+# if !defined(OPENSSL_NO_NEXTPROTONEG)
int ssl3_send_next_proto(SSL *s)
{
unsigned int len, padding_len;
@@ -3378,7 +3397,116 @@ int ssl3_send_next_proto(SSL *s)
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
}
-#endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
+# endif /* !OPENSSL_NO_NEXTPROTONEG */
+
+int ssl3_send_channel_id(SSL *s)
+ {
+ unsigned char *d;
+ int ret = -1, public_key_len;
+ EVP_MD_CTX md_ctx;
+ size_t sig_len;
+ ECDSA_SIG *sig = NULL;
+ unsigned char *public_key = NULL, *derp, *der_sig = NULL;
+
+ if (s->state != SSL3_ST_CW_CHANNEL_ID_A)
+ return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+
+ d = (unsigned char *)s->init_buf->data;
+ *(d++)=SSL3_MT_ENCRYPTED_EXTENSIONS;
+ l2n3(2 + 2 + TLSEXT_CHANNEL_ID_SIZE, d);
+ s2n(TLSEXT_TYPE_channel_id, d);
+ s2n(TLSEXT_CHANNEL_ID_SIZE, d);
+
+ EVP_MD_CTX_init(&md_ctx);
+
+ public_key_len = i2d_PublicKey(s->tlsext_channel_id_private, NULL);
+ if (public_key_len <= 0)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
+ goto err;
+ }
+ // i2d_PublicKey will produce an ANSI X9.62 public key which, for a
+ // P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
+ // field elements as 32-byte, big-endian numbers.
+ if (public_key_len != 65)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_CHANNEL_ID_NOT_P256);
+ goto err;
+ }
+ public_key = OPENSSL_malloc(public_key_len);
+ if (!public_key)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ derp = public_key;
+ i2d_PublicKey(s->tlsext_channel_id_private, &derp);
+
+ if (EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL,
+ s->tlsext_channel_id_private) != 1)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_EVP_DIGESTSIGNINIT_FAILED);
+ goto err;
+ }
+
+ if (!tls1_channel_id_hash(&md_ctx, s))
+ goto err;
+
+ if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len))
+ {
+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
+ goto err;
+ }
+
+ der_sig = OPENSSL_malloc(sig_len);
+ if (!der_sig)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!EVP_DigestSignFinal(&md_ctx, der_sig, &sig_len))
+ {
+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
+ goto err;
+ }
+
+ derp = der_sig;
+ sig = d2i_ECDSA_SIG(NULL, &derp, sig_len);
+ if (sig == NULL)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_D2I_ECDSA_SIG);
+ goto err;
+ }
+
+ // The first byte of public_key will be 0x4, denoting an uncompressed key.
+ memcpy(d, public_key + 1, 64);
+ d += 64;
+ memset(d, 0, 2 * 32);
+ BN_bn2bin(sig->r, d + 32 - BN_num_bytes(sig->r));
+ d += 32;
+ BN_bn2bin(sig->s, d + 32 - BN_num_bytes(sig->s));
+ d += 32;
+
+ s->state = SSL3_ST_CW_CHANNEL_ID_B;
+ s->init_num = 4 + 2 + 2 + TLSEXT_CHANNEL_ID_SIZE;
+ s->init_off = 0;
+
+ ret = ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+
+err:
+ EVP_MD_CTX_cleanup(&md_ctx);
+ if (public_key)
+ OPENSSL_free(public_key);
+ if (der_sig)
+ OPENSSL_free(der_sig);
+ if (sig)
+ ECDSA_SIG_free(sig);
+
+ return ret;
+ }
+#endif /* !OPENSSL_NO_TLSEXT */
/* Check to see if handshake is full or resumed. Usually this is just a
* case of checking to see if a cache hit has occurred. In the case of
diff --git a/openssl/ssl/s3_lib.c b/openssl/ssl/s3_lib.c
index 8b8350c..50aa465 100644
--- a/openssl/ssl/s3_lib.c
+++ b/openssl/ssl/s3_lib.c
@@ -2951,6 +2951,11 @@ int ssl3_new(SSL *s)
#ifndef OPENSSL_NO_SRP
SSL_SRP_CTX_init(s);
#endif
+#if !defined(OPENSSL_NO_TLSEXT)
+ s->tlsext_channel_id_enabled = s->ctx->tlsext_channel_id_enabled;
+ if (s->ctx->tlsext_channel_id_private)
+ s->tlsext_channel_id_private = EVP_PKEY_dup(s->ctx->tlsext_channel_id_private);
+#endif
s->method->ssl_clear(s);
return(1);
err:
@@ -3074,6 +3079,10 @@ void ssl3_clear(SSL *s)
s->next_proto_negotiated_len = 0;
}
#endif
+
+#if !defined(OPENSSL_NO_TLSEXT)
+ s->s3->tlsext_channel_id_valid = 0;
+#endif
}
#ifndef OPENSSL_NO_SRP
@@ -3348,6 +3357,35 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
ret = 1;
break;
#endif
+ case SSL_CTRL_CHANNEL_ID:
+ if (!s->server)
+ break;
+ s->tlsext_channel_id_enabled = 1;
+ ret = 1;
+ break;
+
+ case SSL_CTRL_SET_CHANNEL_ID:
+ if (s->server)
+ break;
+ s->tlsext_channel_id_enabled = 1;
+ if (EVP_PKEY_bits(parg) != 256)
+ {
+ SSLerr(SSL_F_SSL3_CTRL,SSL_R_CHANNEL_ID_NOT_P256);
+ break;
+ }
+ if (s->tlsext_channel_id_private)
+ EVP_PKEY_free(s->tlsext_channel_id_private);
+ s->tlsext_channel_id_private = (EVP_PKEY*) parg;
+ ret = 1;
+ break;
+
+ case SSL_CTRL_GET_CHANNEL_ID:
+ if (!s->server)
+ break;
+ if (!s->s3->tlsext_channel_id_valid)
+ break;
+ memcpy(parg, s->s3->tlsext_channel_id, larg < 64 ? larg : 64);
+ return 64;
#endif /* !OPENSSL_NO_TLSEXT */
default:
@@ -3569,6 +3607,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
}
return 1;
}
+ case SSL_CTRL_CHANNEL_ID:
+ /* must be called on a server */
+ if (ctx->method->ssl_accept == ssl_undefined_function)
+ return 0;
+ ctx->tlsext_channel_id_enabled=1;
+ return 1;
#ifdef TLSEXT_TYPE_opaque_prf_input
case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG:
@@ -3637,6 +3681,18 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
}
break;
+ case SSL_CTRL_SET_CHANNEL_ID:
+ ctx->tlsext_channel_id_enabled = 1;
+ if (EVP_PKEY_bits(parg) != 256)
+ {
+ SSLerr(SSL_F_SSL3_CTX_CTRL,SSL_R_CHANNEL_ID_NOT_P256);
+ break;
+ }
+ if (ctx->tlsext_channel_id_private)
+ EVP_PKEY_free(ctx->tlsext_channel_id_private);
+ ctx->tlsext_channel_id_private = (EVP_PKEY*) parg;
+ break;
+
default:
return(0);
}
diff --git a/openssl/ssl/s3_pkt.c b/openssl/ssl/s3_pkt.c
index 1cc3442..adf8c38 100644
--- a/openssl/ssl/s3_pkt.c
+++ b/openssl/ssl/s3_pkt.c
@@ -295,11 +295,6 @@ static int ssl3_get_record(SSL *s)
size_t extra;
int decryption_failed_or_bad_record_mac = 0;
unsigned char *mac = NULL;
-#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
- long align=SSL3_ALIGN_PAYLOAD;
-#else
- long align=0;
-#endif
rr= &(s->s3->rrec);
sess=s->session;
@@ -308,8 +303,7 @@ static int ssl3_get_record(SSL *s)
extra=SSL3_RT_MAX_EXTRA;
else
extra=0;
- if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) &&
- extra && !s->s3->init_extra)
+ if (extra && !s->s3->init_extra)
{
/* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
* set after ssl3_setup_buffers() was done */
@@ -358,21 +352,6 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
goto err;
}
- /* If we receive a valid record larger than the current buffer size,
- * allocate some memory for it.
- */
- if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH - align)
- {
- if ((p=OPENSSL_realloc(s->s3->rbuf.buf, rr->length + SSL3_RT_HEADER_LENGTH + align))==NULL)
- {
- SSLerr(SSL_F_SSL3_GET_RECORD,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s->s3->rbuf.buf=p;
- s->s3->rbuf.len=rr->length + SSL3_RT_HEADER_LENGTH + align;
- s->packet= &(s->s3->rbuf.buf[0]);
- }
-
if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH)
{
al=SSL_AD_RECORD_OVERFLOW;
@@ -599,7 +578,6 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
const unsigned char *buf=buf_;
unsigned int tot,n,nw;
int i;
- unsigned int max_plain_length;
s->rwstate=SSL_NOTHING;
tot=s->s3->wnum;
@@ -619,13 +597,8 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
n=(len-tot);
for (;;)
{
- if (type == SSL3_RT_APPLICATION_DATA && (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS))
- max_plain_length = SSL3_RT_DEFAULT_PLAIN_LENGTH;
- else
- max_plain_length = s->max_send_fragment;
-
- if (n > max_plain_length)
- nw = max_plain_length;
+ if (n > s->max_send_fragment)
+ nw=s->max_send_fragment;
else
nw=n;
@@ -734,18 +707,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
s->s3->empty_fragment_done = 1;
}
- /* resize if necessary to hold the data. */
- if (len + SSL3_RT_DEFAULT_WRITE_OVERHEAD > wb->len)
- {
- if ((p=OPENSSL_realloc(wb->buf, len + SSL3_RT_DEFAULT_WRITE_OVERHEAD))==NULL)
- {
- SSLerr(SSL_F_DO_SSL3_WRITE,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- wb->buf = p;
- wb->len = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;
- }
-
if (create_empty_fragment)
{
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
diff --git a/openssl/ssl/s3_srvr.c b/openssl/ssl/s3_srvr.c
index ee42fa5..c5c53dc 100644
--- a/openssl/ssl/s3_srvr.c
+++ b/openssl/ssl/s3_srvr.c
@@ -157,8 +157,11 @@
#include <openssl/buffer.h>
#include <openssl/rand.h>
#include <openssl/objects.h>
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
+#include <openssl/sha.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_DH
#include <openssl/dh.h>
@@ -607,15 +610,8 @@ int ssl3_accept(SSL *s)
* the client uses its key from the certificate
* for key exchange.
*/
-#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
- s->state=SSL3_ST_SR_FINISHED_A;
-#else
- if (s->s3->next_proto_neg_seen)
- s->state=SSL3_ST_SR_NEXT_PROTO_A;
- else
- s->state=SSL3_ST_SR_FINISHED_A;
-#endif
s->init_num = 0;
+ s->state=SSL3_ST_SR_POST_CLIENT_CERT;
}
else if (TLS1_get_version(s) >= TLS1_2_VERSION)
{
@@ -675,16 +671,28 @@ int ssl3_accept(SSL *s)
ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end;
-#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
- s->state=SSL3_ST_SR_FINISHED_A;
-#else
- if (s->s3->next_proto_neg_seen)
+ s->state=SSL3_ST_SR_POST_CLIENT_CERT;
+ s->init_num=0;
+ break;
+
+ case SSL3_ST_SR_POST_CLIENT_CERT: {
+ char next_proto_neg = 0;
+ char channel_id = 0;
+#if !defined(OPENSSL_NO_TLSEXT)
+# if !defined(OPENSSL_NO_NEXTPROTONEG)
+ next_proto_neg = s->s3->next_proto_neg_seen;
+# endif
+ channel_id = s->s3->tlsext_channel_id_valid;
+#endif
+
+ if (next_proto_neg)
s->state=SSL3_ST_SR_NEXT_PROTO_A;
+ else if (channel_id)
+ s->state=SSL3_ST_SR_CHANNEL_ID_A;
else
s->state=SSL3_ST_SR_FINISHED_A;
-#endif
- s->init_num=0;
break;
+ }
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
case SSL3_ST_SR_NEXT_PROTO_A:
@@ -692,6 +700,19 @@ int ssl3_accept(SSL *s)
ret=ssl3_get_next_proto(s);
if (ret <= 0) goto end;
s->init_num = 0;
+ if (s->s3->tlsext_channel_id_valid)
+ s->state=SSL3_ST_SR_CHANNEL_ID_A;
+ else
+ s->state=SSL3_ST_SR_FINISHED_A;
+ break;
+#endif
+
+#if !defined(OPENSSL_NO_TLSEXT)
+ case SSL3_ST_SR_CHANNEL_ID_A:
+ case SSL3_ST_SR_CHANNEL_ID_B:
+ ret=ssl3_get_channel_id(s);
+ if (ret <= 0) goto end;
+ s->init_num = 0;
s->state=SSL3_ST_SR_FINISHED_A;
break;
#endif
@@ -763,16 +784,7 @@ int ssl3_accept(SSL *s)
if (ret <= 0) goto end;
s->state=SSL3_ST_SW_FLUSH;
if (s->hit)
- {
-#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
- s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
-#else
- if (s->s3->next_proto_neg_seen)
- s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
- else
- s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
-#endif
- }
+ s->s3->tmp.next_state=SSL3_ST_SR_POST_CLIENT_CERT;
else
s->s3->tmp.next_state=SSL_ST_OK;
s->init_num=0;
@@ -3595,4 +3607,140 @@ int ssl3_get_next_proto(SSL *s)
return 1;
}
# endif
+
+/* ssl3_get_channel_id reads and verifies a ClientID handshake message. */
+int ssl3_get_channel_id(SSL *s)
+ {
+ int ret = -1, ok;
+ long n;
+ const unsigned char *p;
+ unsigned short extension_type, extension_len;
+ EC_GROUP* p256 = NULL;
+ EC_KEY* key = NULL;
+ EC_POINT* point = NULL;
+ ECDSA_SIG sig;
+ BIGNUM x, y;
+
+ if (s->state == SSL3_ST_SR_CHANNEL_ID_A && s->init_num == 0)
+ {
+ /* The first time that we're called we take the current
+ * handshake hash and store it. */
+ EVP_MD_CTX md_ctx;
+ unsigned int len;
+
+ EVP_MD_CTX_init(&md_ctx);
+ EVP_DigestInit_ex(&md_ctx, EVP_sha256(), NULL);
+ if (!tls1_channel_id_hash(&md_ctx, s))
+ return -1;
+ len = sizeof(s->s3->tlsext_channel_id);
+ EVP_DigestFinal(&md_ctx, s->s3->tlsext_channel_id, &len);
+ EVP_MD_CTX_cleanup(&md_ctx);
+ }
+
+ n = s->method->ssl_get_message(s,
+ SSL3_ST_SR_CHANNEL_ID_A,
+ SSL3_ST_SR_CHANNEL_ID_B,
+ SSL3_MT_ENCRYPTED_EXTENSIONS,
+ 2 + 2 + TLSEXT_CHANNEL_ID_SIZE,
+ &ok);
+
+ if (!ok)
+ return((int)n);
+
+ ssl3_finish_mac(s, (unsigned char*)s->init_buf->data, s->init_num + 4);
+
+ /* s->state doesn't reflect whether ChangeCipherSpec has been received
+ * in this handshake, but s->s3->change_cipher_spec does (will be reset
+ * by ssl3_get_finished). */
+ if (!s->s3->change_cipher_spec)
+ {
+ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS);
+ return -1;
+ }
+
+ if (n != 2 + 2 + TLSEXT_CHANNEL_ID_SIZE)
+ {
+ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_INVALID_MESSAGE);
+ return -1;
+ }
+
+ p = (unsigned char *)s->init_msg;
+
+ /* The payload looks like:
+ * uint16 extension_type
+ * uint16 extension_len;
+ * uint8 x[32];
+ * uint8 y[32];
+ * uint8 r[32];
+ * uint8 s[32];
+ */
+ n2s(p, extension_type);
+ n2s(p, extension_len);
+
+ if (extension_type != TLSEXT_TYPE_channel_id ||
+ extension_len != TLSEXT_CHANNEL_ID_SIZE)
+ {
+ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_INVALID_MESSAGE);
+ return -1;
+ }
+
+ p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+ if (!p256)
+ {
+ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_NO_P256_SUPPORT);
+ return -1;
+ }
+
+ BN_init(&x);
+ BN_init(&y);
+ sig.r = BN_new();
+ sig.s = BN_new();
+
+ if (BN_bin2bn(p + 0, 32, &x) == NULL ||
+ BN_bin2bn(p + 32, 32, &y) == NULL ||
+ BN_bin2bn(p + 64, 32, sig.r) == NULL ||
+ BN_bin2bn(p + 96, 32, sig.s) == NULL)
+ goto err;
+
+ point = EC_POINT_new(p256);
+ if (!point ||
+ !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL))
+ goto err;
+
+ key = EC_KEY_new();
+ if (!key ||
+ !EC_KEY_set_group(key, p256) ||
+ !EC_KEY_set_public_key(key, point))
+ goto err;
+
+ /* We stored the handshake hash in |tlsext_channel_id| the first time
+ * that we were called. */
+ switch (ECDSA_do_verify(s->s3->tlsext_channel_id, SHA256_DIGEST_LENGTH, &sig, key)) {
+ case 1:
+ break;
+ case 0:
+ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
+ s->s3->tlsext_channel_id_valid = 0;
+ goto err;
+ default:
+ s->s3->tlsext_channel_id_valid = 0;
+ goto err;
+ }
+
+ memcpy(s->s3->tlsext_channel_id, p, 64);
+ ret = 1;
+
+err:
+ BN_free(&x);
+ BN_free(&y);
+ BN_free(sig.r);
+ BN_free(sig.s);
+ if (key)
+ EC_KEY_free(key);
+ if (point)
+ EC_POINT_free(point);
+ if (p256)
+ EC_GROUP_free(p256);
+ return ret;
+ }
#endif
diff --git a/openssl/ssl/ssl.h b/openssl/ssl/ssl.h
index d5bcead..1aaadf3 100644
--- a/openssl/ssl/ssl.h
+++ b/openssl/ssl/ssl.h
@@ -638,13 +638,10 @@ struct ssl_session_st
* TLS only.) "Released" buffers are put onto a free-list in the context
* or just freed (depending on the context's setting for freelist_max_len). */
#define SSL_MODE_RELEASE_BUFFERS 0x00000010L
-/* Use small read and write buffers: (a) lazy allocate read buffers for
- * large incoming records, and (b) limit the size of outgoing records. */
-#define SSL_MODE_SMALL_BUFFERS 0x00000020L
/* When set, clients may send application data before receipt of CCS
* and Finished. This mode enables full-handshakes to 'complete' in
* one RTT. */
-#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000040L
+#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000020L
/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
* they cannot be used to clear bits. */
@@ -979,6 +976,12 @@ struct ssl_ctx_st
# endif
/* SRTP profiles we are willing to do from RFC 5764 */
STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
+
+ /* If true, a client will advertise the Channel ID extension and a
+ * server will echo it. */
+ char tlsext_channel_id_enabled;
+ /* The client's Channel ID private key. */
+ EVP_PKEY *tlsext_channel_id_private;
#endif
};
@@ -1020,6 +1023,10 @@ LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL)
#define SSL_CTX_sess_cache_full(ctx) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL)
+/* SSL_CTX_enable_tls_channel_id configures a TLS server to accept TLS client
+ * IDs from clients. Returns 1 on success. */
+#define SSL_CTX_enable_tls_channel_id(ctx) \
+ SSL_CTX_ctrl(ctx,SSL_CTRL_CHANNEL_ID,0,NULL)
void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess));
int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess);
@@ -1346,6 +1353,13 @@ struct ssl_st
*/
unsigned int tlsext_hb_pending; /* Indicates if a HeartbeatRequest is in flight */
unsigned int tlsext_hb_seq; /* HeartbeatRequest sequence number */
+
+ /* Copied from the SSL_CTX. For a server, means that we'll accept
+ * Channel IDs from clients. For a client, means that we'll advertise
+ * support. */
+ char tlsext_channel_id_enabled;
+ /* The client's Channel ID private key. */
+ EVP_PKEY *tlsext_channel_id_private;
#else
#define session_ctx ctx
#endif /* OPENSSL_NO_TLSEXT */
@@ -1417,7 +1431,7 @@ extern "C" {
#define SSL_get_state(a) SSL_state(a)
#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK)
#define SSL_in_init(a) ((SSL_state(a)&SSL_ST_INIT) && \
- !SSL_cutthrough_complete(a))
+ !SSL_cutthrough_complete(a))
#define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE)
#define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT)
#define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT)
@@ -1603,6 +1617,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86
#define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87
#endif
+#define SSL_CTRL_CHANNEL_ID 88
+#define SSL_CTRL_GET_CHANNEL_ID 89
+#define SSL_CTRL_SET_CHANNEL_ID 90
#endif
#define DTLS_CTRL_GET_TIMEOUT 73
@@ -1650,6 +1667,25 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_set_tmp_ecdh(ssl,ecdh) \
SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+/* SSL_enable_tls_channel_id configures a TLS server to accept TLS client
+ * IDs from clients. Returns 1 on success. */
+#define SSL_enable_tls_channel_id(ctx) \
+ SSL_ctrl(ctx,SSL_CTRL_CHANNEL_ID,0,NULL)
+/* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to
+ * compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on
+ * success. */
+#define SSL_set1_tls_channel_id(s, private_key) \
+ SSL_ctrl(s,SSL_CTRL_SET_CHANNEL_ID,0,(void*)private_key)
+#define SSL_CTX_set1_tls_channel_id(ctx, private_key) \
+ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHANNEL_ID,0,(void*)private_key)
+/* SSL_get_tls_channel_id gets the client's TLS Channel ID from a server SSL*
+ * and copies up to the first |channel_id_len| bytes into |channel_id|. The
+ * Channel ID consists of the client's P-256 public key as an (x,y) pair where
+ * each is a 32-byte, big-endian field element. Returns 0 if the client didn't
+ * offer a Channel ID and the length of the complete Channel ID otherwise. */
+#define SSL_get_tls_channel_id(ctx, channel_id, channel_id_len) \
+ SSL_ctrl(ctx,SSL_CTRL_GET_CHANNEL_ID,channel_id_len,(void*)channel_id)
+
#define SSL_CTX_add_extra_chain_cert(ctx,x509) \
SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
#define SSL_CTX_get_extra_chain_certs(ctx,px509) \
@@ -2147,6 +2183,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135
#define SSL_F_SSL3_GET_CERT_STATUS 289
#define SSL_F_SSL3_GET_CERT_VERIFY 136
+#define SSL_F_SSL3_GET_CHANNEL_ID 317
#define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137
#define SSL_F_SSL3_GET_CLIENT_HELLO 138
#define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE 139
@@ -2166,6 +2203,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL3_READ_BYTES 148
#define SSL_F_SSL3_READ_N 149
#define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST 150
+#define SSL_F_SSL3_SEND_CHANNEL_ID 318
#define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE 151
#define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE 152
#define SSL_F_SSL3_SEND_CLIENT_VERIFY 153
@@ -2332,12 +2370,15 @@ void ERR_load_SSL_strings(void);
#define SSL_R_BIO_NOT_SET 128
#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129
#define SSL_R_BN_LIB 130
+#define SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY 376
#define SSL_R_CA_DN_LENGTH_MISMATCH 131
#define SSL_R_CA_DN_TOO_LONG 132
#define SSL_R_CCS_RECEIVED_EARLY 133
#define SSL_R_CERTIFICATE_VERIFY_FAILED 134
#define SSL_R_CERT_LENGTH_MISMATCH 135
#define SSL_R_CHALLENGE_IS_DIFFERENT 136
+#define SSL_R_CHANNEL_ID_NOT_P256 375
+#define SSL_R_CHANNEL_ID_SIGNATURE_INVALID 371
#define SSL_R_CIPHER_CODE_WRONG_LENGTH 137
#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138
#define SSL_R_CIPHER_TABLE_SRC_ERROR 139
@@ -2350,6 +2391,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_CONNECTION_ID_IS_DIFFERENT 143
#define SSL_R_CONNECTION_TYPE_NOT_SET 144
#define SSL_R_COOKIE_MISMATCH 308
+#define SSL_R_D2I_ECDSA_SIG 379
#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145
#define SSL_R_DATA_LENGTH_TOO_LONG 146
#define SSL_R_DECRYPTION_FAILED 147
@@ -2367,9 +2409,12 @@ void ERR_load_SSL_strings(void);
#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150
#define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282
#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151
+#define SSL_R_EVP_DIGESTSIGNFINAL_FAILED 377
+#define SSL_R_EVP_DIGESTSIGNINIT_FAILED 378
#define SSL_R_EXCESSIVE_MESSAGE_SIZE 152
#define SSL_R_EXTRA_DATA_IN_MESSAGE 153
#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154
+#define SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS 372
#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 355
#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 356
#define SSL_R_HTTPS_PROXY_REQUEST 155
@@ -2379,6 +2424,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_INVALID_CHALLENGE_LENGTH 158
#define SSL_R_INVALID_COMMAND 280
#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341
+#define SSL_R_INVALID_MESSAGE 374
#define SSL_R_INVALID_PURPOSE 278
#define SSL_R_INVALID_SRP_USERNAME 357
#define SSL_R_INVALID_STATUS_RESPONSE 328
@@ -2433,6 +2479,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_NO_COMPRESSION_SPECIFIED 187
#define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330
#define SSL_R_NO_METHOD_SPECIFIED 188
+#define SSL_R_NO_P256_SUPPORT 373
#define SSL_R_NO_PRIVATEKEY 189
#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190
#define SSL_R_NO_PROTOCOLS_AVAILABLE 191
diff --git a/openssl/ssl/ssl3.h b/openssl/ssl/ssl3.h
index fb08e72..f4578aa 100644
--- a/openssl/ssl/ssl3.h
+++ b/openssl/ssl/ssl3.h
@@ -280,9 +280,6 @@ extern "C" {
#define SSL3_RT_MAX_EXTRA (16384)
-/* Default buffer length used for writen records. Thus a generated record
- * will contain plaintext no larger than this value. */
-#define SSL3_RT_DEFAULT_PLAIN_LENGTH 2048
/* Maximum plaintext length: defined by SSL/TLS standards */
#define SSL3_RT_MAX_PLAIN_LENGTH 16384
/* Maximum compression overhead: defined by SSL/TLS standards */
@@ -314,13 +311,6 @@ extern "C" {
#define SSL3_RT_MAX_PACKET_SIZE \
(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
-/* Extra space for empty fragment, headers, MAC, and padding. */
-#define SSL3_RT_DEFAULT_WRITE_OVERHEAD 256
-#define SSL3_RT_DEFAULT_PACKET_SIZE 4096 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
-#if SSL3_RT_DEFAULT_PLAIN_LENGTH + SSL3_RT_DEFAULT_WRITE_OVERHEAD > SSL3_RT_DEFAULT_PACKET_SIZE
-#error "Insufficient space allocated for write buffers."
-#endif
-
#define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54"
#define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52"
@@ -549,6 +539,17 @@ typedef struct ssl3_state_st
/* Set if we saw the Next Protocol Negotiation extension from our peer. */
int next_proto_neg_seen;
#endif
+
+ /* In a client, this means that the server supported Channel ID and that
+ * a Channel ID was sent. In a server it means that we echoed support
+ * for Channel IDs and that tlsext_channel_id will be valid after the
+ * handshake. */
+ char tlsext_channel_id_valid;
+ /* For a server:
+ * If |tlsext_channel_id_valid| is true, then this contains the
+ * verified Channel ID from the client: a P256 point, (x,y), where
+ * each are big-endian values. */
+ unsigned char tlsext_channel_id[64];
} SSL3_STATE;
#endif
@@ -591,6 +592,8 @@ typedef struct ssl3_state_st
#define SSL3_ST_CW_CHANGE_B (0x1A1|SSL_ST_CONNECT)
#define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT)
#define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CHANNEL_ID_A (0x210|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CHANNEL_ID_B (0x211|SSL_ST_CONNECT)
#define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT)
#define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT)
/* read from server */
@@ -640,8 +643,11 @@ typedef struct ssl3_state_st
#define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_POST_CLIENT_CERT (0x1BF|SSL_ST_ACCEPT)
#define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT)
#define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CHANNEL_ID_A (0x220|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CHANNEL_ID_B (0x221|SSL_ST_ACCEPT)
#define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT)
#define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT)
/* write to client */
@@ -667,6 +673,7 @@ typedef struct ssl3_state_st
#define SSL3_MT_FINISHED 20
#define SSL3_MT_CERTIFICATE_STATUS 22
#define SSL3_MT_NEXT_PROTO 67
+#define SSL3_MT_ENCRYPTED_EXTENSIONS 203
#define DTLS1_MT_HELLO_VERIFY_REQUEST 3
@@ -686,3 +693,4 @@ typedef struct ssl3_state_st
}
#endif
#endif
+
diff --git a/openssl/ssl/ssl_err.c b/openssl/ssl/ssl_err.c
index 3f9480c..fbefce3 100644
--- a/openssl/ssl/ssl_err.c
+++ b/openssl/ssl/ssl_err.c
@@ -151,6 +151,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST), "SSL3_GET_CERTIFICATE_REQUEST"},
{ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "SSL3_GET_CERT_STATUS"},
{ERR_FUNC(SSL_F_SSL3_GET_CERT_VERIFY), "SSL3_GET_CERT_VERIFY"},
+{ERR_FUNC(SSL_F_SSL3_GET_CHANNEL_ID), "SSL3_GET_CHANNEL_ID"},
{ERR_FUNC(SSL_F_SSL3_GET_CLIENT_CERTIFICATE), "SSL3_GET_CLIENT_CERTIFICATE"},
{ERR_FUNC(SSL_F_SSL3_GET_CLIENT_HELLO), "SSL3_GET_CLIENT_HELLO"},
{ERR_FUNC(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE), "SSL3_GET_CLIENT_KEY_EXCHANGE"},
@@ -170,6 +171,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL3_READ_BYTES), "SSL3_READ_BYTES"},
{ERR_FUNC(SSL_F_SSL3_READ_N), "SSL3_READ_N"},
{ERR_FUNC(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST), "SSL3_SEND_CERTIFICATE_REQUEST"},
+{ERR_FUNC(SSL_F_SSL3_SEND_CHANNEL_ID), "SSL3_SEND_CHANNEL_ID"},
{ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE), "SSL3_SEND_CLIENT_CERTIFICATE"},
{ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE), "SSL3_SEND_CLIENT_KEY_EXCHANGE"},
{ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_VERIFY), "SSL3_SEND_CLIENT_VERIFY"},
@@ -338,12 +340,15 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_BIO_NOT_SET) ,"bio not set"},
{ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG),"block cipher pad is wrong"},
{ERR_REASON(SSL_R_BN_LIB) ,"bn lib"},
+{ERR_REASON(SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY),"cannot serialize public key"},
{ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH) ,"ca dn length mismatch"},
{ERR_REASON(SSL_R_CA_DN_TOO_LONG) ,"ca dn too long"},
{ERR_REASON(SSL_R_CCS_RECEIVED_EARLY) ,"ccs received early"},
{ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED),"certificate verify failed"},
{ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH) ,"cert length mismatch"},
{ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT),"challenge is different"},
+{ERR_REASON(SSL_R_CHANNEL_ID_NOT_P256) ,"channel id not p256"},
+{ERR_REASON(SSL_R_CHANNEL_ID_SIGNATURE_INVALID),"Channel ID signature invalid"},
{ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"},
{ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher or hash unavailable"},
{ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"},
@@ -356,6 +361,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT),"connection id is different"},
{ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET),"connection type not set"},
{ERR_REASON(SSL_R_COOKIE_MISMATCH) ,"cookie mismatch"},
+{ERR_REASON(SSL_R_D2I_ECDSA_SIG) ,"d2i ecdsa sig"},
{ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED),"data between ccs and finished"},
{ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) ,"data length too long"},
{ERR_REASON(SSL_R_DECRYPTION_FAILED) ,"decryption failed"},
@@ -373,9 +379,12 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),"encrypted length too long"},
{ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY),"error generating tmp rsa key"},
{ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST),"error in received cipher list"},
+{ERR_REASON(SSL_R_EVP_DIGESTSIGNFINAL_FAILED),"evp digestsignfinal failed"},
+{ERR_REASON(SSL_R_EVP_DIGESTSIGNINIT_FAILED),"evp digestsigninit failed"},
{ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE),"excessive message size"},
{ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE) ,"extra data in message"},
{ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS),"got a fin before a ccs"},
+{ERR_REASON(SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS),"got Channel ID before a ccs"},
{ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS),"got next proto before a ccs"},
{ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION),"got next proto without seeing extension"},
{ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) ,"https proxy request"},
@@ -385,6 +394,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
{ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
+{ERR_REASON(SSL_R_INVALID_MESSAGE) ,"invalid message"},
{ERR_REASON(SSL_R_INVALID_PURPOSE) ,"invalid purpose"},
{ERR_REASON(SSL_R_INVALID_SRP_USERNAME) ,"invalid srp username"},
{ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"},
@@ -439,6 +449,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED),"no compression specified"},
{ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),"Peer haven't sent GOST certificate, required for selected ciphersuite"},
{ERR_REASON(SSL_R_NO_METHOD_SPECIFIED) ,"no method specified"},
+{ERR_REASON(SSL_R_NO_P256_SUPPORT) ,"no p256 support"},
{ERR_REASON(SSL_R_NO_PRIVATEKEY) ,"no privatekey"},
{ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED),"no private key assigned"},
{ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE),"no protocols available"},
diff --git a/openssl/ssl/ssl_lib.c b/openssl/ssl/ssl_lib.c
index d6b8ca8..4db0fef 100644
--- a/openssl/ssl/ssl_lib.c
+++ b/openssl/ssl/ssl_lib.c
@@ -160,9 +160,6 @@
#include <openssl/engine.h>
#endif
-/* defined in ssl_ciph.c - not exported by any header. */
-extern const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher);
-
const char *SSL_version_str=OPENSSL_VERSION_TEXT;
SSL3_ENC_METHOD ssl3_undef_enc_method={
@@ -582,6 +579,8 @@ void SSL_free(SSL *s)
sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
if (s->tlsext_ocsp_resp)
OPENSSL_free(s->tlsext_ocsp_resp);
+ if (s->tlsext_channel_id_private)
+ EVP_PKEY_free(s->tlsext_channel_id_private);
#endif
if (s->client_CA != NULL)
@@ -2004,6 +2003,11 @@ void SSL_CTX_free(SSL_CTX *a)
ssl_buf_freelist_free(a->rbuf_freelist);
#endif
+#ifndef OPENSSL_NO_TLSEXT
+ if (a->tlsext_channel_id_private)
+ EVP_PKEY_free(a->tlsext_channel_id_private);
+#endif
+
OPENSSL_free(a);
}
diff --git a/openssl/ssl/ssl_locl.h b/openssl/ssl/ssl_locl.h
index 9e8172a..2116913 100644
--- a/openssl/ssl/ssl_locl.h
+++ b/openssl/ssl/ssl_locl.h
@@ -369,6 +369,7 @@
* (currently this also goes into algorithm2) */
#define TLS1_STREAM_MAC 0x04
+#define TLSEXT_CHANNEL_ID_SIZE 128
/*
@@ -994,6 +995,7 @@ int ssl3_check_cert_and_algorithm(SSL *s);
int ssl3_check_finished(SSL *s);
# ifndef OPENSSL_NO_NEXTPROTONEG
int ssl3_send_next_proto(SSL *s);
+int ssl3_send_channel_id(SSL *s);
# endif
#endif
@@ -1016,6 +1018,7 @@ int ssl3_get_cert_verify(SSL *s);
#ifndef OPENSSL_NO_NEXTPROTONEG
int ssl3_get_next_proto(SSL *s);
#endif
+int ssl3_get_channel_id(SSL *s);
int dtls1_send_hello_request(SSL *s);
int dtls1_send_server_hello(SSL *s);
@@ -1112,7 +1115,9 @@ int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
int tls12_get_sigid(const EVP_PKEY *pk);
const EVP_MD *tls12_get_hash(unsigned char hash_alg);
+int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s);
#endif
+
EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
diff --git a/openssl/ssl/ssltest.c b/openssl/ssl/ssltest.c
index a950b6e..02ce4ec 100644
--- a/openssl/ssl/ssltest.c
+++ b/openssl/ssl/ssltest.c
@@ -369,8 +369,6 @@ static void sv_usage(void)
" (default is sect163r2).\n");
#endif
fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
- fprintf(stderr," -c_small_records - enable client side use of small SSL record buffers\n");
- fprintf(stderr," -s_small_records - enable server side use of small SSL record buffers\n");
fprintf(stderr," -cutthrough - enable 1-RTT full-handshake for strong ciphers\n");
}
@@ -500,10 +498,6 @@ int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_)
return arg->ret;
}
#endif
- int ssl_mode = 0;
- int c_small_records=0;
- int s_small_records=0;
- int cutthrough = 0;
int main(int argc, char *argv[])
{
@@ -556,6 +550,7 @@ int main(int argc, char *argv[])
#ifdef OPENSSL_FIPS
int fips_mode=0;
#endif
+ int cutthrough = 0;
verbose = 0;
debug = 0;
@@ -772,14 +767,6 @@ int main(int argc, char *argv[])
{
test_cipherlist = 1;
}
- else if (strcmp(*argv, "-c_small_records") == 0)
- {
- c_small_records = 1;
- }
- else if (strcmp(*argv, "-s_small_records") == 0)
- {
- s_small_records = 1;
- }
else if (strcmp(*argv, "-cutthrough") == 0)
{
cutthrough = 1;
@@ -919,26 +906,10 @@ bad:
SSL_CTX_set_cipher_list(c_ctx,cipher);
SSL_CTX_set_cipher_list(s_ctx,cipher);
}
-
- ssl_mode = 0;
- if (c_small_records)
- {
- ssl_mode = SSL_CTX_get_mode(c_ctx);
- ssl_mode |= SSL_MODE_SMALL_BUFFERS;
- SSL_CTX_set_mode(c_ctx, ssl_mode);
- }
- ssl_mode = 0;
- if (s_small_records)
- {
- ssl_mode = SSL_CTX_get_mode(s_ctx);
- ssl_mode |= SSL_MODE_SMALL_BUFFERS;
- SSL_CTX_set_mode(s_ctx, ssl_mode);
- }
- ssl_mode = 0;
if (cutthrough)
{
- ssl_mode = SSL_CTX_get_mode(c_ctx);
- ssl_mode = SSL_MODE_HANDSHAKE_CUTTHROUGH;
+ int ssl_mode = SSL_CTX_get_mode(c_ctx);
+ ssl_mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH;
SSL_CTX_set_mode(c_ctx, ssl_mode);
}
diff --git a/openssl/ssl/t1_lib.c b/openssl/ssl/t1_lib.c
index 27c8e34..26d19e9 100644
--- a/openssl/ssl/t1_lib.c
+++ b/openssl/ssl/t1_lib.c
@@ -649,6 +649,16 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
#endif
+ if (s->tlsext_channel_id_enabled)
+ {
+ /* The client advertises an emtpy extension to indicate its
+ * support for Channel ID. */
+ if (limit - ret - 4 < 0)
+ return NULL;
+ s2n(TLSEXT_TYPE_channel_id,ret);
+ s2n(0,ret);
+ }
+
if(SSL_get_srtp_profiles(s))
{
int el;
@@ -855,6 +865,16 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
#endif
+ /* If the client advertised support for Channel ID, and we have it
+ * enabled, then we want to echo it back. */
+ if (s->s3->tlsext_channel_id_valid)
+ {
+ if (limit - ret - 4 < 0)
+ return NULL;
+ s2n(TLSEXT_TYPE_channel_id,ret);
+ s2n(0,ret);
+ }
+
if ((extdatalen = ret-p-2)== 0)
return p;
@@ -1327,6 +1347,9 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
}
#endif
+ else if (type == TLSEXT_TYPE_channel_id && s->tlsext_channel_id_enabled)
+ s->s3->tlsext_channel_id_valid = 1;
+
/* session ticket processed earlier */
else if (type == TLSEXT_TYPE_use_srtp)
{
@@ -1554,6 +1577,9 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
s->s3->next_proto_neg_seen = 1;
}
#endif
+ else if (type == TLSEXT_TYPE_channel_id)
+ s->s3->tlsext_channel_id_valid = 1;
+
else if (type == TLSEXT_TYPE_renegotiate)
{
if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
@@ -2576,3 +2602,37 @@ tls1_heartbeat(SSL *s)
return ret;
}
#endif
+
+#if !defined(OPENSSL_NO_TLSEXT)
+/* tls1_channel_id_hash calculates the signed data for a Channel ID on the given
+ * SSL connection and writes it to |md|.
+ */
+int
+tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
+ {
+ EVP_MD_CTX ctx;
+ unsigned char temp_digest[EVP_MAX_MD_SIZE];
+ unsigned temp_digest_len;
+ int i;
+ static const char kClientIDMagic[] = "TLS Channel ID signature";
+
+ if (s->s3->handshake_buffer)
+ if (!ssl3_digest_cached_records(s))
+ return 0;
+
+ EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
+
+ EVP_MD_CTX_init(&ctx);
+ for (i = 0; i < SSL_MAX_DIGEST; i++)
+ {
+ if (s->s3->handshake_dgst[i] == NULL)
+ continue;
+ EVP_MD_CTX_copy_ex(&ctx, s->s3->handshake_dgst[i]);
+ EVP_DigestFinal_ex(&ctx, temp_digest, &temp_digest_len);
+ EVP_DigestUpdate(md, temp_digest, temp_digest_len);
+ }
+ EVP_MD_CTX_cleanup(&ctx);
+
+ return 1;
+ }
+#endif
diff --git a/openssl/ssl/tls1.h b/openssl/ssl/tls1.h
index c39c267..8fc1ff4 100644
--- a/openssl/ssl/tls1.h
+++ b/openssl/ssl/tls1.h
@@ -248,6 +248,9 @@ extern "C" {
#define TLSEXT_TYPE_next_proto_neg 13172
#endif
+/* This is not an IANA defined extension number */
+#define TLSEXT_TYPE_channel_id 30031
+
/* NameType value from RFC 3546 */
#define TLSEXT_NAMETYPE_host_name 0
/* status request value from RFC 3546 */