Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(440)

Unified Diff: patches/snap_start.patch

Issue 9254031: Upgrade chrome's OpenSSL to same version Android ships with. (Closed) Base URL: http://src.chromium.org/svn/trunk/deps/third_party/openssl/
Patch Set: '' Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « patches/small_records.patch ('k') | patches/x509_hash_name_algorithm_change.patch » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: patches/snap_start.patch
===================================================================
--- patches/snap_start.patch (revision 105093)
+++ patches/snap_start.patch (working copy)
@@ -1,780 +0,0 @@
-commit ca77729f0395a16f08ff5d54968e05dbd84b331f
-Author: Adam Langley <agl@chromium.org>
-Date: Thu Nov 4 16:09:48 2010 -0400
-
- snap_start.patch
-
-diff --git a/apps/s_server.c b/apps/s_server.c
-index c4e19c9..37db8f9 100644
---- a/apps/s_server.c
-+++ b/apps/s_server.c
-@@ -802,6 +802,7 @@ int MAIN(int argc, char *argv[])
- tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
- const char *next_proto_neg_in = NULL;
- tlsextnextprotoctx next_proto;
-+ char snapstart = 0;
- #endif
-
- #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
-@@ -1105,6 +1106,10 @@ int MAIN(int argc, char *argv[])
- if (--argc < 1) goto bad;
- next_proto_neg_in = *(++argv);
- }
-+ else if (strcmp(*argv,"-snapstart") == 0)
-+ {
-+ snapstart = 1;
-+ }
- #endif
- #ifndef OPENSSL_NO_JPAKE
- else if (strcmp(*argv,"-jpake") == 0)
-@@ -1389,6 +1394,11 @@ bad:
- }
- #endif
-
-+ if (snapstart)
-+ {
-+ static const unsigned char orbit[8] = {1, 2, 3, 4, 5, 6, 7, 8};
-+ SSL_CTX_set_snap_start_orbit(ctx, orbit);
-+ }
-
- #ifndef OPENSSL_NO_DH
- if (!no_dhe)
-@@ -2031,6 +2041,7 @@ static int init_ssl_connection(SSL *con)
- unsigned next_proto_neg_len;
- #endif
-
-+again:
- if ((i=SSL_accept(con)) <= 0)
- {
- if (BIO_sock_should_retry(i))
-@@ -2039,6 +2050,12 @@ static int init_ssl_connection(SSL *con)
- return(1);
- }
-
-+ if (SSL_get_error(con, i) == SSL_ERROR_SERVER_RANDOM_VALIDATION_PENDING)
-+ {
-+ SSL_set_suggested_server_random_validity(con, 1);
-+ goto again;
-+ }
-+
- BIO_printf(bio_err,"ERROR\n");
- verify_error=SSL_get_verify_result(con);
- if (verify_error != X509_V_OK)
-@@ -2224,6 +2241,9 @@ static int www_body(char *hostname, int s, unsigned char *context)
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_X509_LOOKUP:
- continue;
-+ case SSL_ERROR_SERVER_RANDOM_VALIDATION_PENDING:
-+ SSL_set_suggested_server_random_validity(con, 1);
-+ continue;
- case SSL_ERROR_SYSCALL:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
-diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
-index 06e5466..e32f97d 100644
---- a/ssl/s3_enc.c
-+++ b/ssl/s3_enc.c
-@@ -111,6 +111,7 @@
-
- #include <stdio.h>
- #include "ssl_locl.h"
-+#include "fnv1a64.h"
- #include <openssl/evp.h>
- #include <openssl/md5.h>
-
-@@ -529,6 +530,11 @@ void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
- {
- EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len);
- EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len);
-+ if (s->s3->snap_start_requested)
-+ {
-+ /* Compute Fowler-Noll-Vo (FNV) hash for Snap Start handshake */
-+ fnv1a64_update((FNV1A64*) s->s3->response_hash, buf, len);
-+ }
- }
-
- int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *ctx, unsigned char *p)
-diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
-index 84bff8d..1058b4e 100644
---- a/ssl/s3_lib.c
-+++ b/ssl/s3_lib.c
-@@ -1701,6 +1701,12 @@ void ssl3_free(SSL *s)
- pq_64bit_free(&(s->s3->rrec.seq_num));
- pq_64bit_free(&(s->s3->wrec.seq_num));
-
-+ if (s->s3->snap_start_client_hello.buf)
-+ {
-+ /* s->s3->snap_start_records, if set, uses the same buffer */
-+ OPENSSL_free(s->s3->snap_start_client_hello.buf);
-+ }
-+
- OPENSSL_cleanse(s->s3,sizeof *s->s3);
- OPENSSL_free(s->s3);
- s->s3=NULL;
-diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
-index 6853058..61774b2 100644
---- a/ssl/s3_pkt.c
-+++ b/ssl/s3_pkt.c
-@@ -120,8 +120,51 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
- unsigned int len, int create_empty_fragment);
- static int ssl3_get_record(SSL *s);
-
-+/* ssl3_read_snap_start_n reads from the opportunistic records contained within
-+ * a Snap Start extension. |s->packet| and |s->packet_length| are set to frame
-+ * a record within this area. Partial records are not allowed. The Snap Start
-+ * records are held in |s->s3->snap_start_records| and the |left| member must
-+ * be non-zero on entry.
-+ *
-+ * If |extend| is true then we'll expand the currently framed record by |n|
-+ * bytes, otherwise we frame a new record. */
-+static int ssl3_read_snap_start_n(SSL *s, int n, int extend)
-+ {
-+ if (!extend)
-+ {
-+ s->packet = s->s3->snap_start_records.buf + s->s3->snap_start_records.offset;
-+ s->packet_length = 0;
-+ }
-+
-+ if (s->s3->snap_start_records.left < n)
-+ {
-+ /* We aren't called unless .left is non-zero, therefore this
-+ * means that we wanted to read more than we have. Since
-+ * partial records aren't allowed, this is fatal. */
-+ SSLerr(SSL_F_SSL3_READ_SNAP_START_N,SSL_R_BAD_PACKET_LENGTH);
-+ return -1;
-+ }
-+
-+ s->packet_length += n;
-+ s->s3->snap_start_records.left -= n;
-+ s->s3->snap_start_records.offset += n;
-+
-+ return n;
-+ }
-+
- int ssl3_read_n(SSL *s, int n, int max, int extend)
- {
-+ if (s->s3->snap_start_records.left)
-+ return ssl3_read_snap_start_n(s, n, extend);
-+ else if (s->s3->snap_start_client_hello.buf && !extend)
-+ {
-+ /* If we started reading the opportunistic records then we know
-+ * that we didn't enter recovery. Thus it's safe to free the
-+ * copy of the ClientHello now because we'll not need it again. */
-+ OPENSSL_free(s->s3->snap_start_client_hello.buf);
-+ s->s3->snap_start_client_hello.buf = NULL;
-+ }
-+
- /* If extend == 0, obtain new n-byte packet; if extend == 1, increase
- * packet by another n bytes.
- * The packet will be in the sub-array of s->s3->rbuf.buf specified
-diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
-index 8e0a504..315b8f3 100644
---- a/ssl/s3_srvr.c
-+++ b/ssl/s3_srvr.c
-@@ -144,6 +144,7 @@
- #include <openssl/md5.h>
-
- static SSL_METHOD *ssl3_get_server_method(int ver);
-+static int ssl3_snap_start_evaluate_handshake(SSL* s);
- #ifndef OPENSSL_NO_ECDH
- static int nid2curve_id(int nid);
- #endif
-@@ -300,10 +301,36 @@ int ssl3_accept(SSL *s)
- case SSL3_ST_SW_SRVR_HELLO_A:
- case SSL3_ST_SW_SRVR_HELLO_B:
- ret=ssl3_send_server_hello(s);
-+ if (ret == SERVER_RANDOM_VALIDATION_PENDING)
-+ {
-+ s->rwstate = SSL_SERVER_RANDOM_VALIDATE;
-+ s->state = SSL3_ST_SW_SRVR_HELLO_A;
-+ s->init_num = 0;
-+ goto end;
-+ }
- if (ret <= 0) goto end;
- #ifndef OPENSSL_NO_TLSEXT
-+ if ((s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK) != SSL_kRSA &&
-+ (s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK) != SSL_kKRB5 &&
-+ (s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK) != SSL_kDHr &&
-+ (s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK) != SSL_kDHd &&
-+ (s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK) != SSL_kECDH &&
-+ s->s3->snap_start_requested)
-+ {
-+ /* There's no point in carrying on with a Snap
-+ * Start handshake if we're using a cipher
-+ * suite which is going to send a
-+ * ServerKeyExchange message. */
-+ ssl3_snap_start_reset_for_recovery(s);
-+ s->state = SSL3_ST_SW_SRVR_HELLO_A;
-+ break;
-+ }
-+
- if (s->hit)
- {
-+ if (ssl3_snap_start_evaluate_handshake(s))
-+ break;
-+
- if (s->tlsext_ticket_expected)
- s->state=SSL3_ST_SW_SESSION_TICKET_A;
- else
-@@ -440,8 +467,19 @@ int ssl3_accept(SSL *s)
- case SSL3_ST_SW_SRVR_DONE_B:
- ret=ssl3_send_server_done(s);
- if (ret <= 0) goto end;
-- s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
-- s->state=SSL3_ST_SW_FLUSH;
-+
-+ if (s->s3->snap_start_requested)
-+ {
-+ if (ssl3_snap_start_evaluate_handshake(s))
-+ break;
-+ s->state = SSL3_ST_SR_CERT_A;
-+ }
-+ else
-+ {
-+ s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
-+ s->state=SSL3_ST_SW_FLUSH;
-+ }
-+
- s->init_num=0;
- break;
-
-@@ -1152,11 +1190,19 @@ int ssl3_send_server_hello(SSL *s)
- if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
- {
- buf=(unsigned char *)s->init_buf->data;
-- p=s->s3->server_random;
-- Time=(unsigned long)time(NULL); /* Time */
-- l2n(Time,p);
-- if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
-- return -1;
-+ if (!s->s3->snap_start_requested)
-+ {
-+ p=s->s3->server_random;
-+ Time=(unsigned long)time(NULL); /* Time */
-+ l2n(Time,p);
-+ if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
-+ return -1;
-+ }
-+ else if (s->s3->server_random_suggestion_valid == 0)
-+ {
-+ return SERVER_RANDOM_VALIDATION_PENDING;
-+ }
-+
- /* Do the message type and length last */
- d=p= &(buf[4]);
-
-@@ -2952,3 +2998,55 @@ int ssl3_send_cert_status(SSL *s)
- return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
- }
- #endif
-+
-+/* ssl3_snap_start_evaluate_handshake verifies the Snap Start prediction (if
-+ * this is a Snap Start handshake). If it returns non-zero, then we are
-+ * entering recovery and |s->state| has been set accordingly. */
-+static int ssl3_snap_start_evaluate_handshake(SSL* s)
-+ {
-+ unsigned char digest[8];
-+
-+ if (!s->s3->snap_start_requested)
-+ return 0;
-+
-+ /* Drop the currently queued messages. Either we're entering recovery,
-+ * in which case they're wrong, or we're doing snap start, in which
-+ * case we don't want to send them. */
-+ if (!ssl_init_wbio_buffer(s, 1 /* push new BIO */))
-+ return -1;
-+
-+ fnv1a64_final(digest, (FNV1A64*) s->s3->response_hash);
-+
-+ /* Turn off FNV hashing of handshake messages. */
-+ s->s3->snap_start_requested = 0;
-+
-+ if (memcmp(digest, s->s3->predicted_response_hash, sizeof(digest)) != 0)
-+ {
-+ /* The predicted handshake didn't match. */
-+ ssl3_snap_start_reset_for_recovery(s);
-+ s->state = SSL3_ST_SW_SRVR_HELLO_A;
-+ return 1;
-+ }
-+
-+ return 0;
-+ }
-+
-+/* ssl3_snap_start_reset_for_recovery is called is called when a Snap Start
-+ * handshake is impossible because either the application layer has rejected
-+ * the client's suggested server random, or predicated_response_hash failed to
-+ * match response_hash */
-+int ssl3_snap_start_reset_for_recovery(SSL* s)
-+ {
-+ s->s3->snap_start_requested = 0;
-+ s->s3->snap_start_records.left = 0;
-+ s->init_num = 0;
-+
-+ /* Reset the handshake hash and hash in the original ClientHello. */
-+ ssl3_init_finished_mac(s);
-+ ssl3_finish_mac(s, s->s3->snap_start_client_hello.buf, s->s3->snap_start_client_hello.left);
-+
-+ OPENSSL_free(s->s3->snap_start_client_hello.buf);
-+ s->s3->snap_start_client_hello.buf = NULL;
-+
-+ return 0;
-+ }
-diff --git a/ssl/ssl.h b/ssl/ssl.h
-index dc8dff8..bbe2543 100644
---- a/ssl/ssl.h
-+++ b/ssl/ssl.h
-@@ -770,6 +770,11 @@ struct ssl_ctx_st
-
- X509_VERIFY_PARAM *param;
-
-+ /* The configured Snap Start orbit value, if set. */
-+ char snap_start_orbit_valid;
-+ unsigned char snap_start_orbit[8];
-+
-+
- #if 0
- int purpose; /* Purpose setting */
- int trust; /* Trust setting */
-@@ -876,10 +881,14 @@ void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *
- void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
- void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, int (*cb) (SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg), void *arg);
- void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s, int (*cb) (SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg), void *arg);
-+void SSL_CTX_set_snap_start_orbit(SSL_CTX *s, const unsigned char orbit[8]);
-
- int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, const unsigned char *client, unsigned int client_len);
- void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, unsigned *len);
-
-+void SSL_get0_suggested_server_random(const SSL *s, const unsigned char **data, unsigned *len);
-+void SSL_set_suggested_server_random_validity(SSL *s, char is_valid);
-+
- #define OPENSSL_NPN_UNSUPPORTED 0
- #define OPENSSL_NPN_NEGOTIATED 1
- #define OPENSSL_NPN_NO_OVERLAP 2
-@@ -888,12 +897,14 @@ void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, un
- #define SSL_WRITING 2
- #define SSL_READING 3
- #define SSL_X509_LOOKUP 4
-+#define SSL_SERVER_RANDOM_VALIDATE 6
-
- /* These will only be used when doing non-blocking IO */
- #define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING)
- #define SSL_want_read(s) (SSL_want(s) == SSL_READING)
- #define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
- #define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
-+#define SSL_want_server_random_validation(s) (SSL_want(s) == SSL_SERVER_RANDOM_VALIDATE)
-
- struct ssl_st
- {
-@@ -1255,6 +1266,7 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
- #define SSL_ERROR_ZERO_RETURN 6
- #define SSL_ERROR_WANT_CONNECT 7
- #define SSL_ERROR_WANT_ACCEPT 8
-+#define SSL_ERROR_SERVER_RANDOM_VALIDATION_PENDING 10
-
- #define SSL_CTRL_NEED_TMP_RSA 1
- #define SSL_CTRL_SET_TMP_RSA 2
-@@ -1754,6 +1766,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_F_GET_SERVER_VERIFY 110
- #define SSL_F_I2D_SSL_SESSION 111
- #define SSL_F_READ_N 112
-+#define SSL_F_SSL3_READ_SNAP_START_N 300
- #define SSL_F_REQUEST_CERTIFICATE 113
- #define SSL_F_SERVER_FINISH 239
- #define SSL_F_SERVER_HELLO 114
-@@ -1907,7 +1920,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_F_TLS1_ENC 210
- #define SSL_F_TLS1_SETUP_KEY_BLOCK 211
- #define SSL_F_WRITE_PENDING 212
--/* Next entry: 299 */
-+/* Next entry: 300 */
-
- /* Reason codes. */
- #define SSL_R_APP_DATA_IN_HANDSHAKE 100
-diff --git a/ssl/ssl3.h b/ssl/ssl3.h
-index 54b73b7..4a6e8cf 100644
---- a/ssl/ssl3.h
-+++ b/ssl/ssl3.h
-@@ -452,6 +452,48 @@ typedef struct ssl3_state_st
- unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
- unsigned char previous_server_finished_len;
- int send_connection_binding; /* TODOEKR */
-+
-+ /* Snap Start support (server-side only):
-+ *
-+ * Snap Start allows the client to 'suggest' the value of our random
-+ * nonce. Assuming that we accept this suggestion, then the client can
-+ * predict our exact reply and calculate a complete handshake based on
-+ * that. These opportunistic handshake messages are embedded in the
-+ * Snap Start extension, possibly including application data.
-+ *
-+ * (Note that if the handshake doesn't resume a session, the client
-+ * couldn't hope to predict the exact server reply unless it uses the
-+ * session ticket extension to suppress session ID generation.)
-+ *
-+ * All this allows for a TLS handshake that doesn't incur additional
-+ * latency if the client side sends application data first. */
-+
-+ /* Set if the client presented a Snap Start extension (empty or
-+ * otherwise and the SSL_CTX has a cell configured. Server side only. */
-+ int snap_start_ext_seen;
-+ /* Set if the client-suggested a server random value (which is stored
-+ * in |server_random|) */
-+ char snap_start_requested;
-+ /* Set if the appplication has indicated that the client's
-+ * server_random suggestion is acceptable (see
-+ * SSL_set_suggested_server_random_validity). If so, a Snap Start
-+ * handshake will be attempted. */
-+ char server_random_suggestion_valid;
-+ /* Client's predicted response_hash from client snap start extension.
-+ * Valid if |snap_start_requested| is set. */
-+ unsigned char predicted_response_hash[8];
-+ /* Actual server handshake message hash. A Snap Start handshake is
-+ * possible only if predicated_response_hash matches this. */
-+ unsigned char response_hash[8];
-+ /* If we need to enter snap start recovery then we need to reset the
-+ * Finished hash with a different value for the ClientHello. Thus, we
-+ * need a copy of the whole ClientHello: */
-+ SSL3_BUFFER snap_start_client_hello;
-+ /* A snap start ClientHello can contain records embedded in an
-+ * extension. If we wish to read them then this points to the records
-+ * within |snap_start_client_hello|. */
-+ SSL3_BUFFER snap_start_records;
-+
- } SSL3_STATE;
-
-
-diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
-index cfa70ec..88358fb 100644
---- a/ssl/ssl_lib.c
-+++ b/ssl/ssl_lib.c
-@@ -2119,6 +2119,9 @@ int SSL_get_error(const SSL *s,int i)
- return(SSL_ERROR_SSL);
- }
-
-+ if ((i < 0) && SSL_want_server_random_validation(s))
-+ return(SSL_ERROR_SERVER_RANDOM_VALIDATION_PENDING);
-+
- if ((i < 0) && SSL_want_read(s))
- {
- bio=SSL_get_rbio(s);
-@@ -2876,6 +2879,61 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned
- ctx->next_proto_select_cb = cb;
- ctx->next_proto_select_cb_arg = arg;
- }
-+
-+/* SSL_CTX_set_snap_start_orbit sets the orbit value which will be echoed back
-+ * to the client and enables Snap Start for this context.
-+ *
-+ * An orbit value can be used to spatially partition the state needed to support
-+ * Snap Start. See the comments above SSL_set_suggested_server_random_validity
-+ * (below). */
-+void SSL_CTX_set_snap_start_orbit(SSL_CTX *ctx, const unsigned char orbit[8])
-+ {
-+ memcpy(ctx->snap_start_orbit, orbit, sizeof(ctx->snap_start_orbit));
-+ ctx->snap_start_orbit_valid = 1;
-+ }
-+
-+/* Once SSL_accept has returned with SSL_SERVER_RANDOM_VALIDATE, then one can
-+ * call this function in order to get the client's suggested server random
-+ * value. */
-+void SSL_get0_suggested_server_random(const SSL* s, const unsigned char **data, unsigned *length)
-+ {
-+ if (!s->s3->snap_start_requested)
-+ {
-+ *data = NULL;
-+ *length = 0;
-+ return;
-+ }
-+ *length = 32;
-+ *data = s->s3->server_random;
-+ }
-+
-+/* SSL_set_suggested_server_random_validity passes judgement on a
-+ * client-suggested random value (obtained from
-+ * SSL_get0_suggested_server_random). Rejecting the value triggers a recovery,
-+ * while accepting the value /may/ result in a successful Snap Start, as long
-+ * as the client predicted the handshake correctly.
-+ *
-+ * In order to accept a random value the user must ensure that it has NEVER
-+ * been used before by this server, or any server configured with any of the
-+ * same certificates. It may reject more if necessary.
-+ *
-+ * The first four bytes of the random value contain a timestamp (UNIX seconds
-+ * since the epoch) which can be used to manage a time window. Additionally,
-+ * the following eight bytes contain the orbit which which can also bound the
-+ * state required if geographically separate servers share certificates.
-+ *
-+ * It's recommended that the time window have a maximum size, independent of
-+ * the resources available, in order to prevent an attacker from arbitrarily
-+ * delaying a Snap Start handshake.
-+ */
-+void SSL_set_suggested_server_random_validity(SSL *s, char is_valid)
-+ {
-+ if (is_valid)
-+ s->s3->server_random_suggestion_valid = 1;
-+ else
-+ ssl3_snap_start_reset_for_recovery(s);
-+ }
-+
- #endif
-
- int SSL_cutthrough_complete(const SSL *s)
-diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
-index a9183ff..639a185 100644
---- a/ssl/ssl_locl.h
-+++ b/ssl/ssl_locl.h
-@@ -392,6 +392,11 @@
- #define CERT_PRIVATE_KEY 2
- */
-
-+/* This can be returned from ssl3_send_server_hello to indicate that an
-+ * offline validation of a client-suggested server_random needs to be
-+ * performed. */
-+#define SERVER_RANDOM_VALIDATION_PENDING -(TLSEXT_TYPE_snap_start)
-+
- #ifndef OPENSSL_NO_EC
- /* From ECC-TLS draft, used in encoding the curve type in
- * ECParameters
-@@ -915,6 +920,7 @@ int ssl3_get_client_certificate(SSL *s);
- int ssl3_get_client_key_exchange(SSL *s);
- int ssl3_get_cert_verify(SSL *s);
- int ssl3_get_next_proto(SSL *s);
-+int ssl3_snap_start_reset_for_recovery(SSL* s);
-
- int dtls1_send_hello_request(SSL *s);
- int dtls1_send_server_hello(SSL *s);
-diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
-index fd35b18..ce33f16 100644
---- a/ssl/t1_lib.c
-+++ b/ssl/t1_lib.c
-@@ -62,6 +62,7 @@
- #include <openssl/hmac.h>
- #include <openssl/ocsp.h>
- #include "ssl_locl.h"
-+#include "fnv1a64.h"
-
- const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
-
-@@ -368,6 +369,21 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
- }
- }
-
-+ if (s->s3->snap_start_ext_seen)
-+ {
-+ if ((long)(limit - ret - 14) < 0) return NULL;
-+ s2n(TLSEXT_TYPE_snap_start,ret);
-+ s2n(10,ret); /* extension length */
-+ memcpy(ret, s->ctx->snap_start_orbit, 8);
-+ ret += 8;
-+ /* This is the ciphersuite that we would pick in the event of a
-+ * Snap Start handshake. (Maybe the server wants to do EDH
-+ * unless the client is Snap Start capable). At the moment we
-+ * don't have any logic to pick a different cipher suite so we
-+ * repeat the choice from the ServerHello. */
-+ s2n(s->s3->tmp.new_cipher->id & 0xffff,ret);
-+ }
-+
- if ((extdatalen = ret-p-2)== 0)
- return p;
-
-@@ -375,6 +391,174 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
- return ret;
- }
-
-+
-+static int ssl_hash_snap_start_client_hello(SSL* s,
-+ const char* data,
-+ unsigned len,
-+ unsigned ext_len)
-+ {
-+ /* We walk the ClientHello from the beginning, writing
-+ * adjusted lengths into |b| and hashing as we go.
-+ *
-+ * The resulting ClientHello is going to be shorter by the length of
-+ * this extension, which is |ext_len + 4| (two bytes for the type and two for
-+ * the length). */
-+
-+ const unsigned char *p;
-+ unsigned remaining;
-+ unsigned char b[3], *c;
-+ unsigned long l;
-+
-+ p = (unsigned char*) data;
-+ remaining = len;
-+ /* Handshake header: type */
-+ if (!remaining)
-+ return 0;
-+ ssl3_finish_mac(s, p, 1);
-+ p++;
-+ remaining--;
-+ /* Handshake header: length */
-+ if (remaining < 3)
-+ return 0;
-+ n2l3(p, l);
-+ l -= ext_len + 4;
-+ c = b;
-+ l2n3(l, c);
-+ ssl3_finish_mac(s, b, 3);
-+ remaining -= 3;
-+ /* ClientHello: version and random */
-+ if (remaining < 34)
-+ return 0;
-+ ssl3_finish_mac(s, p, 34);
-+ p += 34;
-+ remaining -= 34;
-+ /* ClientHello: session id length */
-+ if (!remaining)
-+ return 0;
-+ l = *p;
-+ ssl3_finish_mac(s, p, 1);
-+ p++;
-+ remaining--;
-+ /* ClientHello: session id */
-+ if (remaining < l)
-+ return 0;
-+ ssl3_finish_mac(s, p, l);
-+ p += l;
-+ remaining -= l;
-+ /* ClientHello: cipher suites length */
-+ if (remaining < 2)
-+ return 0;
-+ ssl3_finish_mac(s, p, 2);
-+ n2s(p, l);
-+ remaining -= 2;
-+ /* ClientHello: cipher suites */
-+ if (remaining < l)
-+ return 0;
-+ ssl3_finish_mac(s, p, l);
-+ p += l;
-+ remaining -= l;
-+ /* ClientHello: compression methods length */
-+ if (!remaining)
-+ return 0;
-+ l = *p;
-+ ssl3_finish_mac(s, p, 1);
-+ p++;
-+ remaining--;
-+ /* ClientHello: compression methods */
-+ if (remaining < l)
-+ return 0;
-+ ssl3_finish_mac(s, p, l);
-+ p += l;
-+ remaining -= l;
-+ /* ClientHello: extensions length (must exist given that we're already
-+ * parsing the extensions from it */
-+ if (remaining < 2)
-+ return 0;
-+ n2s(p, l);
-+ remaining -= 2;
-+ if (l != remaining || l < ext_len + 4)
-+ return 0;
-+ l -= ext_len + 4;
-+ c = b;
-+ s2n(l, c);
-+ ssl3_finish_mac(s, b, 2);
-+
-+ while (remaining)
-+ {
-+ unsigned long extension_type, extension_len;
-+ if (remaining < 4)
-+ return 0;
-+ n2s(p, extension_type);
-+ n2s(p, extension_len);
-+ remaining -= 4;
-+ if (remaining < extension_len)
-+ return 0;
-+ if (extension_type != TLSEXT_TYPE_snap_start)
-+ ssl3_finish_mac(s, p - 4, extension_len + 4);
-+ p += extension_len;
-+ remaining -= extension_len;
-+ }
-+
-+ return 1;
-+ }
-+
-+static char ssl_parse_snap_start_tlsext(SSL *s, const unsigned char *data, unsigned short len)
-+ {
-+ ptrdiff_t extension_offset = data - (unsigned char *) s->init_buf->data;
-+
-+ if (len > 0 && len < 36)
-+ return 0;
-+ s->s3->snap_start_ext_seen = 1;
-+ if (len == 0)
-+ return 1;
-+
-+ fnv1a64_init((FNV1A64*) s->s3->response_hash);
-+
-+ /* We need to make a copy of the ClientHello because we'll be hashing a
-+ * modified version. However, if we enter recovery then we need to hash
-+ * the unchanged message.
-+ *
-+ * We are adding 4 bytes to the length here because we're including the
-+ * handshake header. */
-+ s->s3->snap_start_client_hello.left = s->init_num + 4;
-+ s->s3->snap_start_client_hello.offset = 0;
-+ s->s3->snap_start_client_hello.buf = OPENSSL_malloc(s->init_num + 4);
-+ if (!s->s3->snap_start_client_hello.buf)
-+ {
-+ /* If we're out of memory then we pretend that we
-+ * didn't see the extension. */
-+ s->s3->snap_start_ext_seen = 0;
-+ return 1;
-+ }
-+
-+ memcpy(s->s3->snap_start_client_hello.buf, s->init_buf->data, s->init_num + 4);
-+ memcpy(s->s3->server_random, s->s3->client_random, 4); /* time */
-+ memcpy(s->s3->server_random + 4, data, 28); /* orbit and random bytes */
-+ memcpy(s->s3->predicted_response_hash, data + 28, 8);
-+
-+ /* Point snap_start_records to within the copy of the ClientHello */
-+ s->s3->snap_start_records.offset = 0;
-+ s->s3->snap_start_records.left = len - 36;
-+ s->s3->snap_start_records.buf = s->s3->snap_start_client_hello.buf + extension_offset + 36;
-+
-+ /* Reset the handshake hash */
-+ ssl3_init_finished_mac(s);
-+
-+ /* Need to hash the ClientHello as if the snap start extension wasn't
-+ * included. */
-+ if (!ssl_hash_snap_start_client_hello(
-+ s,
-+ s->init_buf->data,
-+ s->init_num + 4 /* four bytes of handshake header */,
-+ len))
-+ {
-+ return 0;
-+ }
-+
-+ s->s3->snap_start_requested = 1;
-+ return 1;
-+ }
-+
- int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
- {
- unsigned short type;
-@@ -627,6 +811,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
- s->s3->next_proto_neg_seen = 1;
- }
-
-+ else if (type == TLSEXT_TYPE_snap_start && s->ctx->snap_start_orbit_valid)
-+ {
-+ if (ssl_parse_snap_start_tlsext(s, data, size) == 0)
-+ return 0;
-+ }
-+
- /* session ticket processed earlier */
-
- data+=size;
-diff --git a/ssl/tls1.h b/ssl/tls1.h
-index 71d76de..52ff325 100644
---- a/ssl/tls1.h
-+++ b/ssl/tls1.h
-@@ -120,6 +120,8 @@ extern "C" {
-
- /* This is not an IANA defined extension number */
- #define TLSEXT_TYPE_next_proto_neg 13172
-+ /* http://tools.ietf.org/html/draft-agl-tls-snapstart-00 */
-+#define TLSEXT_TYPE_snap_start 13174
-
- /* NameType value from RFC 3546 */
- #define TLSEXT_NAMETYPE_host_name 0
« no previous file with comments | « patches/small_records.patch ('k') | patches/x509_hash_name_algorithm_change.patch » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698