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_NPN)
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;
break;
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NPN)
+ 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,
*/
#ifndef OPENSSL_NO_TLSEXT
+# ifndef OPENSSL_NO_NPN
+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
+
int ssl3_check_finished(SSL *s)
{
int ok;