Add Next Protocol Negotiation.
This commit is contained in:
101
ssl/s3_srvr.c
101
ssl/s3_srvr.c
@@ -538,7 +538,14 @@ int ssl3_accept(SSL *s)
|
||||
* the client uses its key from the certificate
|
||||
* for key exchange.
|
||||
*/
|
||||
#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NPN)
|
||||
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;
|
||||
}
|
||||
else
|
||||
@@ -581,10 +588,27 @@ int ssl3_accept(SSL *s)
|
||||
ret=ssl3_get_cert_verify(s);
|
||||
if (ret <= 0) goto end;
|
||||
|
||||
#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NPN)
|
||||
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;
|
||||
break;
|
||||
|
||||
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NPN)
|
||||
case SSL3_ST_SR_NEXT_PROTO_A:
|
||||
case SSL3_ST_SR_NEXT_PROTO_B:
|
||||
ret=ssl3_get_next_proto(s);
|
||||
if (ret <= 0) goto end;
|
||||
s->init_num = 0;
|
||||
s->state=SSL3_ST_SR_FINISHED_A;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SSL3_ST_SR_FINISHED_A:
|
||||
case SSL3_ST_SR_FINISHED_B:
|
||||
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
|
||||
@@ -655,7 +679,16 @@ 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_NPN)
|
||||
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
|
||||
}
|
||||
else
|
||||
s->s3->tmp.next_state=SSL_ST_OK;
|
||||
s->init_num=0;
|
||||
@@ -3177,4 +3210,72 @@ int ssl3_send_cert_status(SSL *s)
|
||||
/* SSL3_ST_SW_CERT_STATUS_B */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_NPN
|
||||
/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It
|
||||
* sets the next_proto member in s if found */
|
||||
int ssl3_get_next_proto(SSL *s)
|
||||
{
|
||||
int ok;
|
||||
unsigned proto_len, padding_len;
|
||||
long n;
|
||||
const unsigned char *p;
|
||||
|
||||
/* Clients cannot send a NextProtocol message if we didn't see the
|
||||
* extension in their ClientHello */
|
||||
if (!s->s3->next_proto_neg_seen)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
|
||||
return -1;
|
||||
}
|
||||
|
||||
n=s->method->ssl_get_message(s,
|
||||
SSL3_ST_SR_NEXT_PROTO_A,
|
||||
SSL3_ST_SR_NEXT_PROTO_B,
|
||||
SSL3_MT_NEXT_PROTO,
|
||||
129,
|
||||
&ok);
|
||||
|
||||
if (!ok)
|
||||
return((int)n);
|
||||
|
||||
/* 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_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n < 2)
|
||||
return 0; /* The body must be > 1 bytes long */
|
||||
|
||||
p=(unsigned char *)s->init_msg;
|
||||
|
||||
/* The payload looks like:
|
||||
* uint8 proto_len;
|
||||
* uint8 proto[proto_len];
|
||||
* uint8 padding_len;
|
||||
* uint8 padding[padding_len];
|
||||
*/
|
||||
proto_len = p[0];
|
||||
if (proto_len + 2 > s->init_num)
|
||||
return 0;
|
||||
padding_len = p[proto_len + 1];
|
||||
if (proto_len + padding_len + 2 != s->init_num)
|
||||
return 0;
|
||||
|
||||
s->next_proto_negotiated = OPENSSL_malloc(proto_len);
|
||||
if (!s->next_proto_negotiated)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
memcpy(s->next_proto_negotiated, p + 1, proto_len);
|
||||
s->next_proto_negotiated_len = proto_len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user