#include <openssl/engine.h>
#endif
-static const SSL_METHOD *ssl3_get_client_method(int ver);
static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
+#ifndef OPENSSL_NO_SSL3_METHOD
static const SSL_METHOD *ssl3_get_client_method(int ver)
{
if (ver == SSL3_VERSION)
ssl_undefined_function,
ssl3_connect,
ssl3_get_client_method)
+#endif
int ssl3_connect(SSL *s)
{
s->state=SSL3_ST_CW_CLNT_HELLO_A;
s->ctx->stats.sess_connect++;
s->init_num=0;
+ s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+ /* Should have been reset by ssl3_get_finished, too. */
+ s->s3->change_cipher_spec = 0;
break;
case SSL3_ST_CW_CLNT_HELLO_A:
break;
case SSL3_ST_CR_CERT_A:
case SSL3_ST_CR_CERT_B:
-#ifndef OPENSSL_NO_TLSEXT
- ret=ssl3_check_finished(s);
- if (ret <= 0) goto end;
- if (ret == 2)
- {
- s->hit = 1;
- if (s->tlsext_ticket_expected)
- s->state=SSL3_ST_CR_SESSION_TICKET_A;
- else
- s->state=SSL3_ST_CR_FINISHED_A;
- s->init_num=0;
- break;
- }
-#endif
/* Check if it is anon DH/ECDH, SRP auth */
/* or PSK */
if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP)) &&
else
{
s->state=SSL3_ST_CW_CHANGE_A;
- s->s3->change_cipher_spec=0;
}
if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
{
s->state=SSL3_ST_CW_CHANGE_A;
- s->s3->change_cipher_spec=0;
}
s->init_num=0;
if (ret <= 0) goto end;
s->state=SSL3_ST_CW_CHANGE_A;
s->init_num=0;
- s->s3->change_cipher_spec=0;
break;
case SSL3_ST_CW_CHANGE_A:
s->method->ssl3_enc->client_finished_label,
s->method->ssl3_enc->client_finished_label_len);
if (ret <= 0) goto end;
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->state=SSL3_ST_CW_FLUSH;
/* clear flags */
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_CR_FINISHED_B:
-
s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
SSL3_ST_CR_FINISHED_B);
SSL_SESSION *sess = s->session;
if ((sess == NULL) ||
(sess->ssl_version != s->version) ||
-#ifdef OPENSSL_NO_TLSEXT
!sess->session_id_length ||
-#else
- (!sess->session_id_length && !sess->tlsext_tick) ||
-#endif
(sess->not_resumable))
{
if (!ssl_get_new_session(s,0))
memcpy(s->s3->server_random,p,SSL3_RANDOM_SIZE);
p+=SSL3_RANDOM_SIZE;
+ s->hit = 0;
+
/* get the session-id */
j= *(p++);
{
s->session->cipher = pref_cipher ?
pref_cipher : ssl_get_cipher_by_char(s, p+j);
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
+ s->hit = 1;
}
}
#endif /* OPENSSL_NO_TLSEXT */
- if (j != 0 && j == s->session->session_id_length
+ if (!s->hit && j != 0 && j == s->session->session_id_length
&& memcmp(p,s->session->session_id,j) == 0)
{
if(s->sid_ctx_length != s->session->sid_ctx_length
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
goto f_err;
}
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->hit=1;
}
- else /* a miss or crap from the other end */
+ /* a miss or crap from the other end */
+ if (!s->hit)
{
/* If we were trying for session-id reuse, make a new
* SSL_SESSION so we don't stuff up other people */
- s->hit=0;
if (s->session->session_id_length > 0)
{
if (!ssl_get_new_session(s,0))
if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s))
{
int num;
+ unsigned int size;
j=0;
q=md_buf;
EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_DigestUpdate(&md_ctx,param,param_len);
- EVP_DigestFinal_ex(&md_ctx,q,(unsigned int *)&i);
- q+=i;
- j+=i;
+ EVP_DigestFinal_ex(&md_ctx,q,&size);
+ q+=size;
+ j+=size;
}
i=RSA_verify(NID_md5_sha1, md_buf, j, p, n,
pkey->pkey.rsa);
s->cert->pkeys[i].digest = NULL;
s->cert->pkeys[i].valid_flags = 0;
}
- if ((llen & 1) || !tls1_process_sigalgs(s, p, llen))
+ if ((llen & 1) || !tls1_save_sigalgs(s, p, llen))
{
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_SIGNATURE_ALGORITHMS_ERROR);
goto err;
}
+ if (!tls1_process_sigalgs(s))
+ {
+ ssl3_send_alert(s,SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
p += llen;
}
n=s->method->ssl_get_message(s,
SSL3_ST_CR_SESSION_TICKET_A,
SSL3_ST_CR_SESSION_TICKET_B,
- -1,
+ SSL3_MT_NEWSESSION_TICKET,
16384,
&ok);
if (!ok)
return((int)n);
- if (s->s3->tmp.message_type == SSL3_MT_FINISHED)
- {
- s->s3->tmp.reuse_message=1;
- return(1);
- }
- if (s->s3->tmp.message_type != SSL3_MT_NEWSESSION_TICKET)
- {
- al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_BAD_MESSAGE_TYPE);
- goto f_err;
- }
if (n < 6)
{
/* need at least ticket_lifetime_hint + ticket length */
}
memcpy(s->session->tlsext_tick, p, ticklen);
s->session->tlsext_ticklen = ticklen;
- /* There are two ways to detect a resumed ticket sesion.
+ /* There are two ways to detect a resumed ticket session.
* One is to set an appropriate session ID and then the server
* must return a match in ServerHello. This allows the normal
* client session ID matching to work and we know much
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
}
# endif
-
-int ssl3_check_finished(SSL *s)
- {
- int ok;
- long n;
-
- /* If we have no ticket it cannot be a resumed session. */
- if (!s->session->tlsext_tick)
- return 1;
- /* this function is called when we really expect a Certificate
- * message, so permit appropriate message length */
- n=s->method->ssl_get_message(s,
- SSL3_ST_CR_CERT_A,
- SSL3_ST_CR_CERT_B,
- -1,
- s->max_cert_list,
- &ok);
- if (!ok) return((int)n);
- s->s3->tmp.reuse_message = 1;
-
- if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
- || (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
- return 2;
-
- return 1;
- }
#endif
int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)