*/
#include <stdio.h>
+#include <openssl/crypto.h>
#include "ssl_locl.h"
#include "kssl_lcl.h"
#include <openssl/buffer.h>
switch(s->state)
{
case SSL_ST_RENEGOTIATE:
- s->new_session=1;
+ s->renegotiate=1;
s->state=SSL_ST_CONNECT;
s->ctx->stats.sess_connect_renegotiate++;
/* break */
case SSL3_ST_CR_SRVR_HELLO_A:
case SSL3_ST_CR_SRVR_HELLO_B:
ret=ssl3_get_server_hello(s);
+#ifndef OPENSSL_NO_SRP
+ if ((ret == 0) && (s->s3->warn_alert == SSL_AD_MISSING_SRP_USERNAME))
+ {
+ if (!SRP_have_to_put_srp_username(s))
+ {
+ SSLerr(SSL_F_SSL3_CONNECT,SSL_R_MISSING_SRP_USERNAME);
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_USER_CANCELLED);
+ goto end;
+ }
+ s->state=SSL3_ST_CW_CLNT_HELLO_A;
+ if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
+ break;
+ }
+#endif
if (ret <= 0) goto end;
if (s->hit)
case SSL3_ST_CR_SRVR_DONE_B:
ret=ssl3_get_server_done(s);
if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_SRP
+ if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP)
+ {
+ if ((ret = SRP_Calc_A_param(s))<=0)
+ {
+ SSLerr(SSL_F_SSL3_CONNECT,SSL_R_SRP_A_CALC);
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
+ goto end;
+ }
+ }
+#endif
if (s->s3->tmp.cert_req)
s->state=SSL3_ST_CW_CERT_A;
else
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;
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,
/* else do it later in ssl3_write */
s->init_num=0;
+ s->renegotiate=0;
s->new_session=0;
ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
s->session->cipher_id = s->session->cipher->id;
if (s->hit && (s->session->cipher_id != c->id))
{
+/* Workaround is now obsolete */
+#if 0
if (!(s->options &
SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG))
+#endif
{
al=SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
if (!ok) return((int)n);
- if (s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE)
+ if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) ||
+ ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) &&
+ (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)))
{
s->s3->tmp.reuse_message=1;
return(1);
}
else
#endif /* !OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+ if (alg_k & SSL_kSRP)
+ {
+ n2s(p,i);
+ param_len=i+2;
+ if (param_len > n)
+ {
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_N_LENGTH);
+ goto f_err;
+ }
+ if (!(s->srp_ctx.N=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+ goto err;
+ }
+ p+=i;
+
+ n2s(p,i);
+ param_len+=i+2;
+ if (param_len > n)
+ {
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_G_LENGTH);
+ goto f_err;
+ }
+ if (!(s->srp_ctx.g=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+ goto err;
+ }
+ p+=i;
+
+ i = (unsigned int)(p[0]);
+ p++;
+ param_len+=i+1;
+ if (param_len > n)
+ {
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_S_LENGTH);
+ goto f_err;
+ }
+ if (!(s->srp_ctx.s=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+ goto err;
+ }
+ p+=i;
+
+ n2s(p,i);
+ param_len+=i+2;
+ if (param_len > n)
+ {
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_B_LENGTH);
+ goto f_err;
+ }
+ if (!(s->srp_ctx.B=BN_bin2bn(p,i,NULL)))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+ goto err;
+ }
+ p+=i;
+ n-=param_len;
+
+/* We must check if there is a certificate */
+#ifndef OPENSSL_NO_RSA
+ if (alg_a & SSL_aRSA)
+ pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+#else
+ if (0)
+ ;
+#endif
+#ifndef OPENSSL_NO_DSA
+ else if (alg_a & SSL_aDSS)
+ pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
+#endif
+ }
+ else
+#endif /* !OPENSSL_NO_SRP */
#ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA)
{
s->session->sess_cert->peer_ecdh_tmp=ecdh;
ecdh=NULL;
BN_CTX_free(bn_ctx);
+ bn_ctx = NULL;
EC_POINT_free(srvr_ecpoint);
srvr_ecpoint = NULL;
}
EVP_PKEY_free(pub_key);
}
+#ifndef OPENSSL_NO_SRP
+ else if (alg_k & SSL_kSRP)
+ {
+ if (s->srp_ctx.A != NULL)
+ {
+ /* send off the data */
+ n=BN_num_bytes(s->srp_ctx.A);
+ s2n(n,p);
+ BN_bn2bin(s->srp_ctx.A,p);
+ n+=2;
+ }
+ else
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ if (s->session->srp_username != NULL)
+ OPENSSL_free(s->session->srp_username);
+ s->session->srp_username = BUF_strdup(s->srp_ctx.login);
+ if (s->session->srp_username == NULL)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if ((s->session->master_key_length = SRP_generate_client_master_secret(s,s->session->master_key))<0)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+#endif
#ifndef OPENSSL_NO_PSK
else if (alg_k & SSL_kPSK)
{
DH *dh;
#endif
- sc=s->session->sess_cert;
- if (sc == NULL)
- {
- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
alg_a=s->s3->tmp.new_cipher->algorithm_auth;
if ((alg_a & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) || (alg_k & SSL_kPSK))
return(1);
+ sc=s->session->sess_cert;
+ if (sc == NULL)
+ {
+ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
#ifndef OPENSSL_NO_RSA
rsa=s->session->sess_cert->peer_rsa_tmp;
#endif
*/
#ifndef OPENSSL_NO_TLSEXT
+# ifndef 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
+
int ssl3_check_finished(SSL *s)
{
int ok;