aboutsummaryrefslogtreecommitdiffstats
path: root/ssl/d1_srvr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssl/d1_srvr.c')
-rw-r--r--ssl/d1_srvr.c53
1 files changed, 35 insertions, 18 deletions
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 4b8ba3e452f3..da4c21e06a1c 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -233,6 +233,7 @@ int dtls1_accept(SSL *s)
}
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
{
+ BUF_MEM_free(buf);
ret= -1;
goto end;
}
@@ -246,6 +247,9 @@ int dtls1_accept(SSL *s)
}
s->init_num=0;
+ s->d1->change_cipher_spec_ok = 0;
+ /* Should have been reset by ssl3_get_finished, too. */
+ s->s3->change_cipher_spec = 0;
if (s->state != SSL_ST_RENEGOTIATE)
{
@@ -450,24 +454,15 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SW_KEY_EXCH_B:
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- /* clear this, it may get reset by
- * send_server_key_exchange */
- if ((s->options & SSL_OP_EPHEMERAL_RSA)
-#ifndef OPENSSL_NO_KRB5
- && !(alg_k & SSL_kKRB5)
-#endif /* OPENSSL_NO_KRB5 */
- )
- /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
- * even when forbidden by protocol specs
- * (handshake may fail as clients are not required to
- * be able to handle this) */
- s->s3->tmp.use_rsa_tmp=1;
- else
- s->s3->tmp.use_rsa_tmp=0;
+ /*
+ * clear this, it may get reset by
+ * send_server_key_exchange
+ */
+ s->s3->tmp.use_rsa_tmp=0;
/* only send if a DH key exchange or
* RSA but we have a sign only certificate */
- if (s->s3->tmp.use_rsa_tmp
+ if (0
/* PSK: send ServerKeyExchange if PSK identity
* hint if provided */
#ifndef OPENSSL_NO_PSK
@@ -658,8 +653,14 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B:
-
- s->d1->change_cipher_spec_ok = 1;
+ /*
+ * This *should* be the first time we enable CCS, but be
+ * extra careful about surrounding code changes. We need
+ * to set this here because we don't know if we're
+ * expecting a CertificateVerify or not.
+ */
+ if (!s->s3->change_cipher_spec)
+ s->d1->change_cipher_spec_ok = 1;
/* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end;
@@ -675,7 +676,18 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B:
- s->d1->change_cipher_spec_ok = 1;
+ /*
+ * Enable CCS for resumed handshakes.
+ * In a full handshake, we end up here through
+ * SSL3_ST_SR_CERT_VRFY_B, so change_cipher_spec_ok was
+ * already set. Receiving a CCS clears the flag, so make
+ * sure not to re-enable it to ban duplicates.
+ * s->s3->change_cipher_spec is set when a CCS is
+ * processed in d1_pkt.c, and remains set until
+ * the client's Finished message is read.
+ */
+ if (!s->s3->change_cipher_spec)
+ s->d1->change_cipher_spec_ok = 1;
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B);
if (ret <= 0) goto end;
@@ -1604,6 +1616,11 @@ int dtls1_send_server_certificate(SSL *s)
}
l=dtls1_output_cert_chain(s,x);
+ if (!l)
+ {
+ SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+ return(0);
+ }
s->state=SSL3_ST_SW_CERT_B;
s->init_num=(int)l;
s->init_off=0;