{
if (ver == DTLS1_VERSION)
return(DTLSv1_server_method());
+ else if (ver == DTLS1_2_VERSION)
+ return(DTLSv1_2_server_method());
else
return(NULL);
}
dtls1_get_server_method,
DTLSv1_enc_data)
+IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION,
+ DTLSv1_2_server_method,
+ dtls1_accept,
+ ssl_undefined_function,
+ dtls1_get_server_method,
+ DTLSv1_2_enc_data)
+
+IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION,
+ DTLS_server_method,
+ dtls1_accept,
+ ssl_undefined_function,
+ dtls1_get_server_method,
+ DTLSv1_2_enc_data)
+
int dtls1_accept(SSL *s)
{
BUF_MEM *buf;
}
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)
{
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;
+ if (s->s3->tmp.cert_request)
+ {
+ ret=ssl3_get_client_certificate(s);
+ if (ret <= 0) goto end;
+ }
s->init_num=0;
s->state=SSL3_ST_SR_KEY_EXCH_A;
}
s->state=SSL3_ST_SR_FINISHED_A;
s->init_num = 0;
}
+ else if (SSL_USE_SIGALGS(s))
+ {
+ s->state=SSL3_ST_SR_CERT_VRFY_A;
+ s->init_num=0;
+ if (!s->session->peer)
+ break;
+ /* For sigalgs freeze the handshake buffer
+ * at this point and digest cached records.
+ */
+ if (!s->s3->handshake_buffer)
+ {
+ SSLerr(SSL_F_DTLS1_ACCEPT,ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
+ if (!ssl3_digest_cached_records(s))
+ return -1;
+ }
else
{
s->state=SSL3_ST_SR_CERT_VRFY_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;
buf = (unsigned char *)s->init_buf->data;
msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
- *(p++) = s->version >> 8;
- *(p++) = s->version & 0xFF;
+ /* Always use DTLS 1.0 version: see RFC 6347 */
+ *(p++) = DTLS1_VERSION >> 8;
+ *(p++) = DTLS1_VERSION & 0xFF;
if (s->ctx->app_gen_cookie_cb == NULL ||
s->ctx->app_gen_cookie_cb(s, s->d1->cookie,