}
if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
{
+ BUF_MEM_free(buf);
ret= -1;
goto end;
}
}
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)
{
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
|| ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
#endif
- || (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
- || (alg_k & SSL_kEECDH)
+ || (alg_k & (SSL_kDHE|SSL_kDHr|SSL_kDHd))
+ || (alg_k & SSL_kECDHE)
|| ((alg_k & SSL_kRSA)
&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
|| (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
case SSL3_ST_SR_CERT_A:
case SSL3_ST_SR_CERT_B:
- /* Check for second client hello (MS SGC) */
- ret = ssl3_check_client_hello(s);
- if (ret <= 0)
- goto end;
- if (ret == 2)
+ if (s->s3->tmp.cert_request)
{
- dtls1_stop_timer(s);
- s->state = SSL3_ST_SR_CLNT_HELLO_C;
- }
- else {
- /* could be sent for a DH cert, even if we
- * have not asked for it :-) */
ret=ssl3_get_client_certificate(s);
if (ret <= 0) goto end;
- s->init_num=0;
- s->state=SSL3_ST_SR_KEY_EXCH_A;
- }
+ }
+ s->init_num=0;
+ s->state=SSL3_ST_SR_KEY_EXCH_A;
break;
case SSL3_ST_SR_KEY_EXCH_A:
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;
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;
if (ret <= 0) goto end;
#ifndef OPENSSL_NO_SCTP
- /* Change to new shared key of SCTP-Auth,
- * will be ignored if no SCTP used.
- */
- BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+ if (!s->hit)
+ {
+ /* Change to new shared key of SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+ }
#endif
s->state=SSL3_ST_SW_FINISHED_A;
if (ret <= 0) goto end;
s->state=SSL3_ST_SW_FLUSH;
if (s->hit)
+ {
s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
+
+#ifndef OPENSSL_NO_SCTP
+ /* Change to new shared key of SCTP-Auth,
+ * will be ignored if no SCTP used.
+ */
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+#endif
+ }
else
{
s->s3->tmp.next_state=SSL_ST_OK;