diff options
author | Ben Laurie <ben@openssl.org> | 2011-11-13 21:55:42 +0000 |
---|---|---|
committer | Ben Laurie <ben@openssl.org> | 2011-11-13 21:55:42 +0000 |
commit | 68b33cc5c7aa1bb98e95bfb4b61c34192a7a50e3 (patch) | |
tree | 8c4298a1cc0487b3223a06764fe5f338f9691ad8 /ssl/s3_clnt.c | |
parent | 4c02cf8ecc4b4cedeb6b6c11185f5d3e49c3cd4a (diff) |
Add Next Protocol Negotiation.
Diffstat (limited to 'ssl/s3_clnt.c')
-rw-r--r-- | ssl/s3_clnt.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 6cf6e6f378..1578f17e97 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -460,7 +460,16 @@ int ssl3_connect(SSL *s) ret=ssl3_send_change_cipher_spec(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 (s->next_proto_negotiated) + s->state=SSL3_ST_CW_NEXT_PROTO_A; + else + s->state=SSL3_ST_CW_FINISHED_A; +#endif s->init_num=0; s->session->cipher=s->s3->tmp.new_cipher; @@ -488,6 +497,15 @@ int ssl3_connect(SSL *s) break; +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + case SSL3_ST_CW_NEXT_PROTO_A: + case SSL3_ST_CW_NEXT_PROTO_B: + ret=ssl3_send_next_proto(s); + if (ret <= 0) goto end; + s->state=SSL3_ST_CW_FINISHED_A; + break; +#endif + case SSL3_ST_CW_FINISHED_A: case SSL3_ST_CW_FINISHED_B: ret=ssl3_send_finished(s, @@ -3236,6 +3254,32 @@ err: return(0); } +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) +int ssl3_send_next_proto(SSL *s) + { + unsigned int len, padding_len; + unsigned char *d; + + if (s->state == SSL3_ST_CW_NEXT_PROTO_A) + { + len = s->next_proto_negotiated_len; + padding_len = 32 - ((len + 2) % 32); + d = (unsigned char *)s->init_buf->data; + d[4] = len; + memcpy(d + 5, s->next_proto_negotiated, len); + d[5 + len] = padding_len; + memset(d + 6 + len, 0, padding_len); + *(d++)=SSL3_MT_NEXT_PROTO; + l2n3(2 + len + padding_len, d); + s->state = SSL3_ST_CW_NEXT_PROTO_B; + s->init_num = 4 + 2 + len + padding_len; + s->init_off = 0; + } + + return ssl3_do_write(s, SSL3_RT_HANDSHAKE); +} +#endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */ + /* 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 * session tickets we have to check the next message to be sure. |