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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « patches/small_records.patch ('k') | patches/x509_hash_name_algorithm_change.patch » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 commit ca77729f0395a16f08ff5d54968e05dbd84b331f
2 Author: Adam Langley <agl@chromium.org>
3 Date: Thu Nov 4 16:09:48 2010 -0400
4
5 snap_start.patch
6
7 diff --git a/apps/s_server.c b/apps/s_server.c
8 index c4e19c9..37db8f9 100644
9 --- a/apps/s_server.c
10 +++ b/apps/s_server.c
11 @@ -802,6 +802,7 @@ int MAIN(int argc, char *argv[])
12 tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
13 const char *next_proto_neg_in = NULL;
14 tlsextnextprotoctx next_proto;
15 + char snapstart = 0;
16 #endif
17
18 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
19 @@ -1105,6 +1106,10 @@ int MAIN(int argc, char *argv[])
20 if (--argc < 1) goto bad;
21 next_proto_neg_in = *(++argv);
22 }
23 + else if (strcmp(*argv,"-snapstart") == 0)
24 + {
25 + snapstart = 1;
26 + }
27 #endif
28 #ifndef OPENSSL_NO_JPAKE
29 else if (strcmp(*argv,"-jpake") == 0)
30 @@ -1389,6 +1394,11 @@ bad:
31 }
32 #endif
33
34 + if (snapstart)
35 + {
36 + static const unsigned char orbit[8] = {1, 2, 3, 4, 5, 6, 7, 8};
37 + SSL_CTX_set_snap_start_orbit(ctx, orbit);
38 + }
39
40 #ifndef OPENSSL_NO_DH
41 if (!no_dhe)
42 @@ -2031,6 +2041,7 @@ static int init_ssl_connection(SSL *con)
43 unsigned next_proto_neg_len;
44 #endif
45
46 +again:
47 if ((i=SSL_accept(con)) <= 0)
48 {
49 if (BIO_sock_should_retry(i))
50 @@ -2039,6 +2050,12 @@ static int init_ssl_connection(SSL *con)
51 return(1);
52 }
53
54 + if (SSL_get_error(con, i) == SSL_ERROR_SERVER_RANDOM_VALIDATION_ PENDING)
55 + {
56 + SSL_set_suggested_server_random_validity(con, 1);
57 + goto again;
58 + }
59 +
60 BIO_printf(bio_err,"ERROR\n");
61 verify_error=SSL_get_verify_result(con);
62 if (verify_error != X509_V_OK)
63 @@ -2224,6 +2241,9 @@ static int www_body(char *hostname, int s, unsigned char * context)
64 case SSL_ERROR_WANT_READ:
65 case SSL_ERROR_WANT_X509_LOOKUP:
66 continue;
67 + case SSL_ERROR_SERVER_RANDOM_VALIDATION_PENDING:
68 + SSL_set_suggested_server_random_validity(con, 1) ;
69 + continue;
70 case SSL_ERROR_SYSCALL:
71 case SSL_ERROR_SSL:
72 case SSL_ERROR_ZERO_RETURN:
73 diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
74 index 06e5466..e32f97d 100644
75 --- a/ssl/s3_enc.c
76 +++ b/ssl/s3_enc.c
77 @@ -111,6 +111,7 @@
78
79 #include <stdio.h>
80 #include "ssl_locl.h"
81 +#include "fnv1a64.h"
82 #include <openssl/evp.h>
83 #include <openssl/md5.h>
84
85 @@ -529,6 +530,11 @@ void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
86 {
87 EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len);
88 EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len);
89 + if (s->s3->snap_start_requested)
90 + {
91 + /* Compute Fowler-Noll-Vo (FNV) hash for Snap Start handshake */
92 + fnv1a64_update((FNV1A64*) s->s3->response_hash, buf, len);
93 + }
94 }
95
96 int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *ctx, unsigned char *p)
97 diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
98 index 84bff8d..1058b4e 100644
99 --- a/ssl/s3_lib.c
100 +++ b/ssl/s3_lib.c
101 @@ -1701,6 +1701,12 @@ void ssl3_free(SSL *s)
102 pq_64bit_free(&(s->s3->rrec.seq_num));
103 pq_64bit_free(&(s->s3->wrec.seq_num));
104
105 + if (s->s3->snap_start_client_hello.buf)
106 + {
107 + /* s->s3->snap_start_records, if set, uses the same buffer */
108 + OPENSSL_free(s->s3->snap_start_client_hello.buf);
109 + }
110 +
111 OPENSSL_cleanse(s->s3,sizeof *s->s3);
112 OPENSSL_free(s->s3);
113 s->s3=NULL;
114 diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
115 index 6853058..61774b2 100644
116 --- a/ssl/s3_pkt.c
117 +++ b/ssl/s3_pkt.c
118 @@ -120,8 +120,51 @@ static int do_ssl3_write(SSL *s, int type, const unsigned c har *buf,
119 unsigned int len, int create_empty_fragment);
120 static int ssl3_get_record(SSL *s);
121
122 +/* ssl3_read_snap_start_n reads from the opportunistic records contained within
123 + * a Snap Start extension. |s->packet| and |s->packet_length| are set to frame
124 + * a record within this area. Partial records are not allowed. The Snap Start
125 + * records are held in |s->s3->snap_start_records| and the |left| member must
126 + * be non-zero on entry.
127 + *
128 + * If |extend| is true then we'll expand the currently framed record by |n|
129 + * bytes, otherwise we frame a new record. */
130 +static int ssl3_read_snap_start_n(SSL *s, int n, int extend)
131 + {
132 + if (!extend)
133 + {
134 + s->packet = s->s3->snap_start_records.buf + s->s3->snap_start_re cords.offset;
135 + s->packet_length = 0;
136 + }
137 +
138 + if (s->s3->snap_start_records.left < n)
139 + {
140 + /* We aren't called unless .left is non-zero, therefore this
141 + * means that we wanted to read more than we have. Since
142 + * partial records aren't allowed, this is fatal. */
143 + SSLerr(SSL_F_SSL3_READ_SNAP_START_N,SSL_R_BAD_PACKET_LENGTH);
144 + return -1;
145 + }
146 +
147 + s->packet_length += n;
148 + s->s3->snap_start_records.left -= n;
149 + s->s3->snap_start_records.offset += n;
150 +
151 + return n;
152 + }
153 +
154 int ssl3_read_n(SSL *s, int n, int max, int extend)
155 {
156 + if (s->s3->snap_start_records.left)
157 + return ssl3_read_snap_start_n(s, n, extend);
158 + else if (s->s3->snap_start_client_hello.buf && !extend)
159 + {
160 + /* If we started reading the opportunistic records then we know
161 + * that we didn't enter recovery. Thus it's safe to free the
162 + * copy of the ClientHello now because we'll not need it again. */
163 + OPENSSL_free(s->s3->snap_start_client_hello.buf);
164 + s->s3->snap_start_client_hello.buf = NULL;
165 + }
166 +
167 /* If extend == 0, obtain new n-byte packet; if extend == 1, increase
168 * packet by another n bytes.
169 * The packet will be in the sub-array of s->s3->rbuf.buf specified
170 diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
171 index 8e0a504..315b8f3 100644
172 --- a/ssl/s3_srvr.c
173 +++ b/ssl/s3_srvr.c
174 @@ -144,6 +144,7 @@
175 #include <openssl/md5.h>
176
177 static SSL_METHOD *ssl3_get_server_method(int ver);
178 +static int ssl3_snap_start_evaluate_handshake(SSL* s);
179 #ifndef OPENSSL_NO_ECDH
180 static int nid2curve_id(int nid);
181 #endif
182 @@ -300,10 +301,36 @@ int ssl3_accept(SSL *s)
183 case SSL3_ST_SW_SRVR_HELLO_A:
184 case SSL3_ST_SW_SRVR_HELLO_B:
185 ret=ssl3_send_server_hello(s);
186 + if (ret == SERVER_RANDOM_VALIDATION_PENDING)
187 + {
188 + s->rwstate = SSL_SERVER_RANDOM_VALIDATE;
189 + s->state = SSL3_ST_SW_SRVR_HELLO_A;
190 + s->init_num = 0;
191 + goto end;
192 + }
193 if (ret <= 0) goto end;
194 #ifndef OPENSSL_NO_TLSEXT
195 + if ((s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK) != SSL_kRSA &&
196 + (s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK) != SSL_kKRB5 &&
197 + (s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK) != SSL_kDHr &&
198 + (s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK) != SSL_kDHd &&
199 + (s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK) != SSL_kECDH &&
200 + s->s3->snap_start_requested)
201 + {
202 + /* There's no point in carrying on with a Snap
203 + * Start handshake if we're using a cipher
204 + * suite which is going to send a
205 + * ServerKeyExchange message. */
206 + ssl3_snap_start_reset_for_recovery(s);
207 + s->state = SSL3_ST_SW_SRVR_HELLO_A;
208 + break;
209 + }
210 +
211 if (s->hit)
212 {
213 + if (ssl3_snap_start_evaluate_handshake(s))
214 + break;
215 +
216 if (s->tlsext_ticket_expected)
217 s->state=SSL3_ST_SW_SESSION_TICKET_A;
218 else
219 @@ -440,8 +467,19 @@ int ssl3_accept(SSL *s)
220 case SSL3_ST_SW_SRVR_DONE_B:
221 ret=ssl3_send_server_done(s);
222 if (ret <= 0) goto end;
223 - s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
224 - s->state=SSL3_ST_SW_FLUSH;
225 +
226 + if (s->s3->snap_start_requested)
227 + {
228 + if (ssl3_snap_start_evaluate_handshake(s))
229 + break;
230 + s->state = SSL3_ST_SR_CERT_A;
231 + }
232 + else
233 + {
234 + s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
235 + s->state=SSL3_ST_SW_FLUSH;
236 + }
237 +
238 s->init_num=0;
239 break;
240
241 @@ -1152,11 +1190,19 @@ int ssl3_send_server_hello(SSL *s)
242 if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
243 {
244 buf=(unsigned char *)s->init_buf->data;
245 - p=s->s3->server_random;
246 - Time=(unsigned long)time(NULL); /* Time */
247 - l2n(Time,p);
248 - if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
249 - return -1;
250 + if (!s->s3->snap_start_requested)
251 + {
252 + p=s->s3->server_random;
253 + Time=(unsigned long)time(NULL); /* Time */
254 + l2n(Time,p);
255 + if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
256 + return -1;
257 + }
258 + else if (s->s3->server_random_suggestion_valid == 0)
259 + {
260 + return SERVER_RANDOM_VALIDATION_PENDING;
261 + }
262 +
263 /* Do the message type and length last */
264 d=p= &(buf[4]);
265
266 @@ -2952,3 +2998,55 @@ int ssl3_send_cert_status(SSL *s)
267 return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
268 }
269 #endif
270 +
271 +/* ssl3_snap_start_evaluate_handshake verifies the Snap Start prediction (if
272 + * this is a Snap Start handshake). If it returns non-zero, then we are
273 + * entering recovery and |s->state| has been set accordingly. */
274 +static int ssl3_snap_start_evaluate_handshake(SSL* s)
275 + {
276 + unsigned char digest[8];
277 +
278 + if (!s->s3->snap_start_requested)
279 + return 0;
280 +
281 + /* Drop the currently queued messages. Either we're entering recovery,
282 + * in which case they're wrong, or we're doing snap start, in which
283 + * case we don't want to send them. */
284 + if (!ssl_init_wbio_buffer(s, 1 /* push new BIO */))
285 + return -1;
286 +
287 + fnv1a64_final(digest, (FNV1A64*) s->s3->response_hash);
288 +
289 + /* Turn off FNV hashing of handshake messages. */
290 + s->s3->snap_start_requested = 0;
291 +
292 + if (memcmp(digest, s->s3->predicted_response_hash, sizeof(digest)) != 0)
293 + {
294 + /* The predicted handshake didn't match. */
295 + ssl3_snap_start_reset_for_recovery(s);
296 + s->state = SSL3_ST_SW_SRVR_HELLO_A;
297 + return 1;
298 + }
299 +
300 + return 0;
301 + }
302 +
303 +/* ssl3_snap_start_reset_for_recovery is called is called when a Snap Start
304 + * handshake is impossible because either the application layer has rejected
305 + * the client's suggested server random, or predicated_response_hash failed to
306 + * match response_hash */
307 +int ssl3_snap_start_reset_for_recovery(SSL* s)
308 + {
309 + s->s3->snap_start_requested = 0;
310 + s->s3->snap_start_records.left = 0;
311 + s->init_num = 0;
312 +
313 + /* Reset the handshake hash and hash in the original ClientHello. */
314 + ssl3_init_finished_mac(s);
315 + ssl3_finish_mac(s, s->s3->snap_start_client_hello.buf, s->s3->snap_start _client_hello.left);
316 +
317 + OPENSSL_free(s->s3->snap_start_client_hello.buf);
318 + s->s3->snap_start_client_hello.buf = NULL;
319 +
320 + return 0;
321 + }
322 diff --git a/ssl/ssl.h b/ssl/ssl.h
323 index dc8dff8..bbe2543 100644
324 --- a/ssl/ssl.h
325 +++ b/ssl/ssl.h
326 @@ -770,6 +770,11 @@ struct ssl_ctx_st
327
328 X509_VERIFY_PARAM *param;
329
330 + /* The configured Snap Start orbit value, if set. */
331 + char snap_start_orbit_valid;
332 + unsigned char snap_start_orbit[8];
333 +
334 +
335 #if 0
336 int purpose; /* Purpose setting */
337 int trust; /* Trust setting */
338 @@ -876,10 +881,14 @@ void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*ap p_gen_cookie_cb)(SSL *
339 void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
340 void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, int (*cb) (SSL *ssl, con st unsigned char **out, unsigned int *outlen, void *arg), void *arg);
341 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);
342 +void SSL_CTX_set_snap_start_orbit(SSL_CTX *s, const unsigned char orbit[8]);
343
344 int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, const uns igned char *in, unsigned int inlen, const unsigned char *client, unsigned int cl ient_len);
345 void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, u nsigned *len);
346
347 +void SSL_get0_suggested_server_random(const SSL *s, const unsigned char **data, unsigned *len);
348 +void SSL_set_suggested_server_random_validity(SSL *s, char is_valid);
349 +
350 #define OPENSSL_NPN_UNSUPPORTED 0
351 #define OPENSSL_NPN_NEGOTIATED 1
352 #define OPENSSL_NPN_NO_OVERLAP 2
353 @@ -888,12 +897,14 @@ void SSL_get0_next_proto_negotiated(const SSL *s, const un signed char **data, un
354 #define SSL_WRITING 2
355 #define SSL_READING 3
356 #define SSL_X509_LOOKUP 4
357 +#define SSL_SERVER_RANDOM_VALIDATE 6
358
359 /* These will only be used when doing non-blocking IO */
360 #define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING)
361 #define SSL_want_read(s) (SSL_want(s) == SSL_READING)
362 #define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
363 #define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
364 +#define SSL_want_server_random_validation(s) (SSL_want(s) == SSL_SERVER_RANDO M_VALIDATE)
365
366 struct ssl_st
367 {
368 @@ -1255,6 +1266,7 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size _t count);
369 #define SSL_ERROR_ZERO_RETURN 6
370 #define SSL_ERROR_WANT_CONNECT 7
371 #define SSL_ERROR_WANT_ACCEPT 8
372 +#define SSL_ERROR_SERVER_RANDOM_VALIDATION_PENDING 10
373
374 #define SSL_CTRL_NEED_TMP_RSA 1
375 #define SSL_CTRL_SET_TMP_RSA 2
376 @@ -1754,6 +1766,7 @@ void ERR_load_SSL_strings(void);
377 #define SSL_F_GET_SERVER_VERIFY 110
378 #define SSL_F_I2D_SSL_SESSION 111
379 #define SSL_F_READ_N 112
380 +#define SSL_F_SSL3_READ_SNAP_START_N 300
381 #define SSL_F_REQUEST_CERTIFICATE 113
382 #define SSL_F_SERVER_FINISH 239
383 #define SSL_F_SERVER_HELLO 114
384 @@ -1907,7 +1920,7 @@ void ERR_load_SSL_strings(void);
385 #define SSL_F_TLS1_ENC 210
386 #define SSL_F_TLS1_SETUP_KEY_BLOCK 211
387 #define SSL_F_WRITE_PENDING 212
388 -/* Next entry: 299 */
389 +/* Next entry: 300 */
390
391 /* Reason codes. */
392 #define SSL_R_APP_DATA_IN_HANDSHAKE 100
393 diff --git a/ssl/ssl3.h b/ssl/ssl3.h
394 index 54b73b7..4a6e8cf 100644
395 --- a/ssl/ssl3.h
396 +++ b/ssl/ssl3.h
397 @@ -452,6 +452,48 @@ typedef struct ssl3_state_st
398 unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
399 unsigned char previous_server_finished_len;
400 int send_connection_binding; /* TODOEKR */
401 +
402 + /* Snap Start support (server-side only):
403 + *
404 + * Snap Start allows the client to 'suggest' the value of our random
405 + * nonce. Assuming that we accept this suggestion, then the client can
406 + * predict our exact reply and calculate a complete handshake based on
407 + * that. These opportunistic handshake messages are embedded in the
408 + * Snap Start extension, possibly including application data.
409 + *
410 + * (Note that if the handshake doesn't resume a session, the client
411 + * couldn't hope to predict the exact server reply unless it uses the
412 + * session ticket extension to suppress session ID generation.)
413 + *
414 + * All this allows for a TLS handshake that doesn't incur additional
415 + * latency if the client side sends application data first. */
416 +
417 + /* Set if the client presented a Snap Start extension (empty or
418 + * otherwise and the SSL_CTX has a cell configured. Server side only. */
419 + int snap_start_ext_seen;
420 + /* Set if the client-suggested a server random value (which is stored
421 + * in |server_random|) */
422 + char snap_start_requested;
423 + /* Set if the appplication has indicated that the client's
424 + * server_random suggestion is acceptable (see
425 + * SSL_set_suggested_server_random_validity). If so, a Snap Start
426 + * handshake will be attempted. */
427 + char server_random_suggestion_valid;
428 + /* Client's predicted response_hash from client snap start extension.
429 + * Valid if |snap_start_requested| is set. */
430 + unsigned char predicted_response_hash[8];
431 + /* Actual server handshake message hash. A Snap Start handshake is
432 + * possible only if predicated_response_hash matches this. */
433 + unsigned char response_hash[8];
434 + /* If we need to enter snap start recovery then we need to reset the
435 + * Finished hash with a different value for the ClientHello. Thus, we
436 + * need a copy of the whole ClientHello: */
437 + SSL3_BUFFER snap_start_client_hello;
438 + /* A snap start ClientHello can contain records embedded in an
439 + * extension. If we wish to read them then this points to the records
440 + * within |snap_start_client_hello|. */
441 + SSL3_BUFFER snap_start_records;
442 +
443 } SSL3_STATE;
444
445
446 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
447 index cfa70ec..88358fb 100644
448 --- a/ssl/ssl_lib.c
449 +++ b/ssl/ssl_lib.c
450 @@ -2119,6 +2119,9 @@ int SSL_get_error(const SSL *s,int i)
451 return(SSL_ERROR_SSL);
452 }
453
454 + if ((i < 0) && SSL_want_server_random_validation(s))
455 + return(SSL_ERROR_SERVER_RANDOM_VALIDATION_PENDING);
456 +
457 if ((i < 0) && SSL_want_read(s))
458 {
459 bio=SSL_get_rbio(s);
460 @@ -2876,6 +2879,61 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int ( *cb) (SSL *s, unsigned
461 ctx->next_proto_select_cb = cb;
462 ctx->next_proto_select_cb_arg = arg;
463 }
464 +
465 +/* SSL_CTX_set_snap_start_orbit sets the orbit value which will be echoed back
466 + * to the client and enables Snap Start for this context.
467 + *
468 + * An orbit value can be used to spatially partition the state needed to suppor t
469 + * Snap Start. See the comments above SSL_set_suggested_server_random_validity
470 + * (below). */
471 +void SSL_CTX_set_snap_start_orbit(SSL_CTX *ctx, const unsigned char orbit[8])
472 + {
473 + memcpy(ctx->snap_start_orbit, orbit, sizeof(ctx->snap_start_orbit));
474 + ctx->snap_start_orbit_valid = 1;
475 + }
476 +
477 +/* Once SSL_accept has returned with SSL_SERVER_RANDOM_VALIDATE, then one can
478 + * call this function in order to get the client's suggested server random
479 + * value. */
480 +void SSL_get0_suggested_server_random(const SSL* s, const unsigned char **data, unsigned *length)
481 + {
482 + if (!s->s3->snap_start_requested)
483 + {
484 + *data = NULL;
485 + *length = 0;
486 + return;
487 + }
488 + *length = 32;
489 + *data = s->s3->server_random;
490 + }
491 +
492 +/* SSL_set_suggested_server_random_validity passes judgement on a
493 + * client-suggested random value (obtained from
494 + * SSL_get0_suggested_server_random). Rejecting the value triggers a recovery,
495 + * while accepting the value /may/ result in a successful Snap Start, as long
496 + * as the client predicted the handshake correctly.
497 + *
498 + * In order to accept a random value the user must ensure that it has NEVER
499 + * been used before by this server, or any server configured with any of the
500 + * same certificates. It may reject more if necessary.
501 + *
502 + * The first four bytes of the random value contain a timestamp (UNIX seconds
503 + * since the epoch) which can be used to manage a time window. Additionally,
504 + * the following eight bytes contain the orbit which which can also bound the
505 + * state required if geographically separate servers share certificates.
506 + *
507 + * It's recommended that the time window have a maximum size, independent of
508 + * the resources available, in order to prevent an attacker from arbitrarily
509 + * delaying a Snap Start handshake.
510 + */
511 +void SSL_set_suggested_server_random_validity(SSL *s, char is_valid)
512 + {
513 + if (is_valid)
514 + s->s3->server_random_suggestion_valid = 1;
515 + else
516 + ssl3_snap_start_reset_for_recovery(s);
517 + }
518 +
519 #endif
520
521 int SSL_cutthrough_complete(const SSL *s)
522 diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
523 index a9183ff..639a185 100644
524 --- a/ssl/ssl_locl.h
525 +++ b/ssl/ssl_locl.h
526 @@ -392,6 +392,11 @@
527 #define CERT_PRIVATE_KEY 2
528 */
529
530 +/* This can be returned from ssl3_send_server_hello to indicate that an
531 + * offline validation of a client-suggested server_random needs to be
532 + * performed. */
533 +#define SERVER_RANDOM_VALIDATION_PENDING -(TLSEXT_TYPE_snap_start)
534 +
535 #ifndef OPENSSL_NO_EC
536 /* From ECC-TLS draft, used in encoding the curve type in
537 * ECParameters
538 @@ -915,6 +920,7 @@ int ssl3_get_client_certificate(SSL *s);
539 int ssl3_get_client_key_exchange(SSL *s);
540 int ssl3_get_cert_verify(SSL *s);
541 int ssl3_get_next_proto(SSL *s);
542 +int ssl3_snap_start_reset_for_recovery(SSL* s);
543
544 int dtls1_send_hello_request(SSL *s);
545 int dtls1_send_server_hello(SSL *s);
546 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
547 index fd35b18..ce33f16 100644
548 --- a/ssl/t1_lib.c
549 +++ b/ssl/t1_lib.c
550 @@ -62,6 +62,7 @@
551 #include <openssl/hmac.h>
552 #include <openssl/ocsp.h>
553 #include "ssl_locl.h"
554 +#include "fnv1a64.h"
555
556 const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
557
558 @@ -368,6 +369,21 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
559 }
560 }
561
562 + if (s->s3->snap_start_ext_seen)
563 + {
564 + if ((long)(limit - ret - 14) < 0) return NULL;
565 + s2n(TLSEXT_TYPE_snap_start,ret);
566 + s2n(10,ret); /* extension length */
567 + memcpy(ret, s->ctx->snap_start_orbit, 8);
568 + ret += 8;
569 + /* This is the ciphersuite that we would pick in the event of a
570 + * Snap Start handshake. (Maybe the server wants to do EDH
571 + * unless the client is Snap Start capable). At the moment we
572 + * don't have any logic to pick a different cipher suite so we
573 + * repeat the choice from the ServerHello. */
574 + s2n(s->s3->tmp.new_cipher->id & 0xffff,ret);
575 + }
576 +
577 if ((extdatalen = ret-p-2)== 0)
578 return p;
579
580 @@ -375,6 +391,174 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
581 return ret;
582 }
583
584 +
585 +static int ssl_hash_snap_start_client_hello(SSL* s,
586 + const char* data,
587 + unsigned len,
588 + unsigned ext_len)
589 + {
590 + /* We walk the ClientHello from the beginning, writing
591 + * adjusted lengths into |b| and hashing as we go.
592 + *
593 + * The resulting ClientHello is going to be shorter by the length of
594 + * this extension, which is |ext_len + 4| (two bytes for the type and tw o for
595 + * the length). */
596 +
597 + const unsigned char *p;
598 + unsigned remaining;
599 + unsigned char b[3], *c;
600 + unsigned long l;
601 +
602 + p = (unsigned char*) data;
603 + remaining = len;
604 + /* Handshake header: type */
605 + if (!remaining)
606 + return 0;
607 + ssl3_finish_mac(s, p, 1);
608 + p++;
609 + remaining--;
610 + /* Handshake header: length */
611 + if (remaining < 3)
612 + return 0;
613 + n2l3(p, l);
614 + l -= ext_len + 4;
615 + c = b;
616 + l2n3(l, c);
617 + ssl3_finish_mac(s, b, 3);
618 + remaining -= 3;
619 + /* ClientHello: version and random */
620 + if (remaining < 34)
621 + return 0;
622 + ssl3_finish_mac(s, p, 34);
623 + p += 34;
624 + remaining -= 34;
625 + /* ClientHello: session id length */
626 + if (!remaining)
627 + return 0;
628 + l = *p;
629 + ssl3_finish_mac(s, p, 1);
630 + p++;
631 + remaining--;
632 + /* ClientHello: session id */
633 + if (remaining < l)
634 + return 0;
635 + ssl3_finish_mac(s, p, l);
636 + p += l;
637 + remaining -= l;
638 + /* ClientHello: cipher suites length */
639 + if (remaining < 2)
640 + return 0;
641 + ssl3_finish_mac(s, p, 2);
642 + n2s(p, l);
643 + remaining -= 2;
644 + /* ClientHello: cipher suites */
645 + if (remaining < l)
646 + return 0;
647 + ssl3_finish_mac(s, p, l);
648 + p += l;
649 + remaining -= l;
650 + /* ClientHello: compression methods length */
651 + if (!remaining)
652 + return 0;
653 + l = *p;
654 + ssl3_finish_mac(s, p, 1);
655 + p++;
656 + remaining--;
657 + /* ClientHello: compression methods */
658 + if (remaining < l)
659 + return 0;
660 + ssl3_finish_mac(s, p, l);
661 + p += l;
662 + remaining -= l;
663 + /* ClientHello: extensions length (must exist given that we're already
664 + * parsing the extensions from it */
665 + if (remaining < 2)
666 + return 0;
667 + n2s(p, l);
668 + remaining -= 2;
669 + if (l != remaining || l < ext_len + 4)
670 + return 0;
671 + l -= ext_len + 4;
672 + c = b;
673 + s2n(l, c);
674 + ssl3_finish_mac(s, b, 2);
675 +
676 + while (remaining)
677 + {
678 + unsigned long extension_type, extension_len;
679 + if (remaining < 4)
680 + return 0;
681 + n2s(p, extension_type);
682 + n2s(p, extension_len);
683 + remaining -= 4;
684 + if (remaining < extension_len)
685 + return 0;
686 + if (extension_type != TLSEXT_TYPE_snap_start)
687 + ssl3_finish_mac(s, p - 4, extension_len + 4);
688 + p += extension_len;
689 + remaining -= extension_len;
690 + }
691 +
692 + return 1;
693 + }
694 +
695 +static char ssl_parse_snap_start_tlsext(SSL *s, const unsigned char *data, unsi gned short len)
696 + {
697 + ptrdiff_t extension_offset = data - (unsigned char *) s->init_buf->data;
698 +
699 + if (len > 0 && len < 36)
700 + return 0;
701 + s->s3->snap_start_ext_seen = 1;
702 + if (len == 0)
703 + return 1;
704 +
705 + fnv1a64_init((FNV1A64*) s->s3->response_hash);
706 +
707 + /* We need to make a copy of the ClientHello because we'll be hashing a
708 + * modified version. However, if we enter recovery then we need to hash
709 + * the unchanged message.
710 + *
711 + * We are adding 4 bytes to the length here because we're including the
712 + * handshake header. */
713 + s->s3->snap_start_client_hello.left = s->init_num + 4;
714 + s->s3->snap_start_client_hello.offset = 0;
715 + s->s3->snap_start_client_hello.buf = OPENSSL_malloc(s->init_num + 4);
716 + if (!s->s3->snap_start_client_hello.buf)
717 + {
718 + /* If we're out of memory then we pretend that we
719 + * didn't see the extension. */
720 + s->s3->snap_start_ext_seen = 0;
721 + return 1;
722 + }
723 +
724 + memcpy(s->s3->snap_start_client_hello.buf, s->init_buf->data, s->init_nu m + 4);
725 + memcpy(s->s3->server_random, s->s3->client_random, 4); /* time */
726 + memcpy(s->s3->server_random + 4, data, 28); /* orbit and random bytes */
727 + memcpy(s->s3->predicted_response_hash, data + 28, 8);
728 +
729 + /* Point snap_start_records to within the copy of the ClientHello */
730 + s->s3->snap_start_records.offset = 0;
731 + s->s3->snap_start_records.left = len - 36;
732 + s->s3->snap_start_records.buf = s->s3->snap_start_client_hello.buf + ext ension_offset + 36;
733 +
734 + /* Reset the handshake hash */
735 + ssl3_init_finished_mac(s);
736 +
737 + /* Need to hash the ClientHello as if the snap start extension wasn't
738 + * included. */
739 + if (!ssl_hash_snap_start_client_hello(
740 + s,
741 + s->init_buf->data,
742 + s->init_num + 4 /* four bytes of handshake header */,
743 + len))
744 + {
745 + return 0;
746 + }
747 +
748 + s->s3->snap_start_requested = 1;
749 + return 1;
750 + }
751 +
752 int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, i nt n, int *al)
753 {
754 unsigned short type;
755 @@ -627,6 +811,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
756 s->s3->next_proto_neg_seen = 1;
757 }
758
759 + else if (type == TLSEXT_TYPE_snap_start && s->ctx->snap_start_or bit_valid)
760 + {
761 + if (ssl_parse_snap_start_tlsext(s, data, size) == 0)
762 + return 0;
763 + }
764 +
765 /* session ticket processed earlier */
766
767 data+=size;
768 diff --git a/ssl/tls1.h b/ssl/tls1.h
769 index 71d76de..52ff325 100644
770 --- a/ssl/tls1.h
771 +++ b/ssl/tls1.h
772 @@ -120,6 +120,8 @@ extern "C" {
773
774 /* This is not an IANA defined extension number */
775 #define TLSEXT_TYPE_next_proto_neg 13172
776 + /* http://tools.ietf.org/html/draft-agl-tls-snapstart-00 */
777 +#define TLSEXT_TYPE_snap_start 13174
778
779 /* NameType value from RFC 3546 */
780 #define TLSEXT_NAMETYPE_host_name 0
OLDNEW
« 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