}
#ifndef OPENSSL_NO_SRP
-static int SSL_check_srp_ext_ClientHello(SSL *s, int *ad)
+static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
{
int ret = SSL_ERROR_NONE;
- *ad = SSL_AD_UNRECOGNIZED_NAME;
+ *al = SSL_AD_UNRECOGNIZED_NAME;
if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) &&
(s->srp_ctx.TLS_ext_srp_username_callback != NULL))
{
if(s->srp_ctx.login == NULL)
{
- /* There isn't any srp login extension !!! */
- ret = SSL3_AL_WARNING;
- *ad = SSL_AD_MISSING_SRP_USERNAME;
+ /* RFC 5054 says SHOULD reject,
+ we do so if There is no srp login name */
+ ret = SSL3_AL_FATAL;
+ *al = SSL_AD_UNKNOWN_PSK_IDENTITY;
}
else
{
- ret = SSL_srp_server_param_with_username(s,ad);
+ ret = SSL_srp_server_param_with_username(s,al);
}
}
return ret;
void (*cb)(const SSL *ssl,int type,int val)=NULL;
int ret= -1;
int new_state,state,skip=0;
-#ifndef OPENSSL_NO_SRP
- int srp_no_username=0;
- int extension_error,al;
-#endif
RAND_add(&Time,sizeof(Time),0);
ERR_clear_error();
return(-1);
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ /* If we're awaiting a HeartbeatResponse, pretend we
+ * already got and don't await it anymore, because
+ * Heartbeats don't make sense during handshakes anyway.
+ */
+ if (s->tlsext_hb_pending)
+ {
+ s->tlsext_hb_pending = 0;
+ s->tlsext_hb_seq++;
+ }
+#endif
+
for (;;)
{
state=s->state;
}
s->init_num=0;
+ s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
if (s->state != SSL_ST_RENEGOTIATE)
{
case SSL3_ST_SR_CLNT_HELLO_A:
case SSL3_ST_SR_CLNT_HELLO_B:
case SSL3_ST_SR_CLNT_HELLO_C:
-#ifndef OPENSSL_NO_SRP
- case SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME:
-#endif
s->shutdown=0;
- ret=ssl3_get_client_hello(s);
- if (ret <= 0) goto end;
+ if (s->rwstate != SSL_X509_LOOKUP)
+ {
+ ret=ssl3_get_client_hello(s);
+ if (ret <= 0) goto end;
+ }
#ifndef OPENSSL_NO_SRP
- extension_error = 0;
- if ((al = SSL_check_srp_ext_ClientHello(s,&extension_error)) != SSL_ERROR_NONE)
- {
- ssl3_send_alert(s,al,extension_error);
- if (extension_error == SSL_AD_MISSING_SRP_USERNAME)
+ {
+ int al;
+ if ((ret = ssl_check_srp_ext_ClientHello(s,&al)) < 0)
{
- if (srp_no_username) goto end;
- ERR_clear_error();
- srp_no_username = 1;
- s->state=SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME;
- if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
- if ((ret=BIO_flush(s->wbio)) <= 0) goto end;
- s->init_num=0;
- break;
+ /* callback indicates firther work to be done */
+ s->rwstate=SSL_X509_LOOKUP;
+ goto end;
}
- ret = -1;
- SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT);
- goto end;
+ if (ret != SSL_ERROR_NONE)
+ {
+ ssl3_send_alert(s,SSL3_AL_FATAL,al);
+ /* This is not really an error but the only means to
+ for a client to detect whether srp is supported. */
+ if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY)
+ SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT);
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ ret= -1;
+ goto end;
}
-#endif
+ }
+#endif
s->renegotiate = 2;
s->state=SSL3_ST_SW_SRVR_HELLO_A;
s->s3->tmp.reuse_message = 1;
if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
{
+ /* We only allow the client to restart the handshake once per
+ * negotiation. */
+ if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
+ {
+ SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
+ return -1;
+ }
/* Throw away what we have done so far in the current handshake,
* which will now be aborted. (A full SSL_clear would be too much.) */
#ifndef OPENSSL_NO_DH
s->s3->tmp.ecdh = NULL;
}
#endif
+ s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
return 2;
}
return 1;
* TLSv1.
*/
if (s->state == SSL3_ST_SR_CLNT_HELLO_A
-#ifndef OPENSSL_NO_SRP
- || (s->state == SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME)
-#endif
)
{
s->state=SSL3_ST_SR_CLNT_HELLO_B;
goto f_err;
}
}
- if (ssl_check_clienthello_tlsext(s) <= 0) {
+ if (ssl_check_clienthello_tlsext_early(s) <= 0) {
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
goto err;
}
* server_random before calling tls_session_secret_cb in order to allow
* SessionTicket processing to use it in key derivation. */
{
- unsigned long Time;
unsigned char *pos;
- Time=(unsigned long)time(NULL); /* Time */
pos=s->s3->server_random;
- l2n(Time,pos);
- if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
+ if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0)
{
al=SSL_AD_INTERNAL_ERROR;
goto f_err;
if (TLS1_get_version(s) < TLS1_2_VERSION || !(s->verify_mode & SSL_VERIFY_PEER))
{
if (!ssl3_digest_cached_records(s))
+ {
+ al = SSL_AD_INTERNAL_ERROR;
goto f_err;
+ }
}
/* we now have the following setup.
* s->tmp.new_cipher - the new cipher to use.
*/
+ /* Handles TLS extensions that we couldn't check earlier */
+ if (s->version >= SSL3_VERSION)
+ {
+ if (ssl_check_clienthello_tlsext_late(s) <= 0)
+ {
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
+ goto err;
+ }
+ }
+
if (ret < 0) ret=1;
if (0)
{
unsigned char *p,*d;
int i,sl;
unsigned long l;
-#ifdef OPENSSL_NO_TLSEXT
- unsigned long Time;
-#endif
if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
{
buf=(unsigned char *)s->init_buf->data;
#ifdef OPENSSL_NO_TLSEXT
p=s->s3->server_random;
- /* Generate server_random if it was not needed previously */
- Time=(unsigned long)time(NULL); /* Time */
- l2n(Time,p);
- if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+ if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0)
return -1;
#endif
/* Do the message type and length last */
if (i <= 0)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
+ BN_clear_free(pub);
goto err;
}
SSL3_ST_SR_CERT_VRFY_A,
SSL3_ST_SR_CERT_VRFY_B,
-1,
- 514, /* 514? */
+ 516, /* Enough for 4096 bit RSA key with TLS v1.2 */
&ok);
if (!ok) return((int)n);
if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
{
s->s3->tmp.reuse_message=1;
- if ((peer != NULL) && (type | EVP_PKT_SIGN))
+ if ((peer != NULL) && (type & EVP_PKT_SIGN))
{
al=SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);