X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fd1_srvr.c;h=d3afec993db3a7a59eff53556682c1c4d962b943;hp=67baf80dc2159f9fd488b29e45c2b713663af029;hb=2927791d77ddaef687e92b1779e0bff89bdc279f;hpb=89bbe14c506b9bd2fd00e6bae22a99ef1ee7ad19 diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c index 67baf80dc2..d3afec993d 100644 --- a/ssl/d1_srvr.c +++ b/ssl/d1_srvr.c @@ -4,7 +4,7 @@ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -133,23 +133,46 @@ static const SSL_METHOD *dtls1_get_server_method(int ver) { if (ver == DTLS1_VERSION) return(DTLSv1_server_method()); + else if (ver == DTLS1_2_VERSION) + return(DTLSv1_2_server_method()); else return(NULL); } -IMPLEMENT_dtls1_meth_func(DTLSv1_server_method, +IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, + DTLSv1_server_method, dtls1_accept, ssl_undefined_function, - dtls1_get_server_method) + 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; - unsigned long l,Time=(unsigned long)time(NULL); + unsigned long Time=(unsigned long)time(NULL); void (*cb)(const SSL *ssl,int type,int val)=NULL; - long num1; + unsigned long alg_k; int ret= -1; int new_state,state,skip=0; + int listen; +#ifndef OPENSSL_NO_SCTP + unsigned char sctpauthkey[64]; + char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; +#endif RAND_add(&Time,sizeof(Time),0); ERR_clear_error(); @@ -159,17 +182,41 @@ int dtls1_accept(SSL *s) cb=s->info_callback; else if (s->ctx->info_callback != NULL) cb=s->ctx->info_callback; + + listen = s->d1->listen; /* init things to blank */ s->in_handshake++; if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); + s->d1->listen = listen; +#ifndef OPENSSL_NO_SCTP + /* Notify SCTP BIO socket to enter handshake + * mode and prevent stream identifier other + * than 0. Will be ignored if no SCTP is used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL); +#endif + if (s->cert == NULL) { SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET); return(-1); } +#ifndef OPENSSL_NO_HEARTBEATS + /* If we're awaiting a HeartbeatResponse, pretend we + * already got and don't await it anymore, because + * Heartbeats don't make sense during handshakes anyway. + */ + if (s->tlsext_hb_pending) + { + dtls1_stop_timer(s); + s->tlsext_hb_pending = 0; + s->tlsext_hb_seq++; + } +#endif + for (;;) { state=s->state; @@ -177,7 +224,7 @@ int dtls1_accept(SSL *s) switch (s->state) { case SSL_ST_RENEGOTIATE: - s->new_session=1; + s->renegotiate=1; /* s->state=SSL_ST_ACCEPT; */ case SSL_ST_BEFORE: @@ -222,8 +269,12 @@ int dtls1_accept(SSL *s) { /* Ok, we now need to push on a buffering BIO so that * the output is sent in a way that TCP likes :-) + * ...but not with SCTP :-) */ - if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; } +#ifndef OPENSSL_NO_SCTP + if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) +#endif + if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; } ssl3_init_finished_mac(s); s->state=SSL3_ST_SR_CLNT_HELLO_A; @@ -237,20 +288,17 @@ int dtls1_accept(SSL *s) s->state=SSL3_ST_SW_HELLO_REQ_A; } - if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) - s->d1->send_cookie = 1; - else - s->d1->send_cookie = 0; - break; case SSL3_ST_SW_HELLO_REQ_A: case SSL3_ST_SW_HELLO_REQ_B: s->shutdown=0; - ret=dtls1_send_hello_request(s); + dtls1_clear_record_buffer(s); + dtls1_start_timer(s); + ret=ssl3_send_hello_request(s); if (ret <= 0) goto end; - s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C; + s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; s->state=SSL3_ST_SW_FLUSH; s->init_num=0; @@ -268,14 +316,35 @@ int dtls1_accept(SSL *s) s->shutdown=0; ret=ssl3_get_client_hello(s); if (ret <= 0) goto end; - s->new_session = 2; + dtls1_stop_timer(s); - if ( s->d1->send_cookie) + if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; else s->state = SSL3_ST_SW_SRVR_HELLO_A; s->init_num=0; + + /* Reflect ClientHello sequence to remain stateless while listening */ + if (listen) + { + memcpy(s->s3->write_sequence, s->s3->read_sequence, sizeof(s->s3->write_sequence)); + } + + /* If we're just listening, stop here */ + if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) + { + ret = 2; + s->d1->listen = 0; + /* Set expected sequence numbers + * to continue the handshake. + */ + s->d1->handshake_read_seq = 2; + s->d1->handshake_write_seq = 1; + s->d1->next_handshake_write_seq = 1; + goto end; + } + break; case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: @@ -283,18 +352,83 @@ int dtls1_accept(SSL *s) ret = dtls1_send_hello_verify_request(s); if ( ret <= 0) goto end; - s->d1->send_cookie = 0; s->state=SSL3_ST_SW_FLUSH; s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; + + /* HelloVerifyRequest resets Finished MAC */ + if (s->version != DTLS1_BAD_VER) + ssl3_init_finished_mac(s); break; +#ifndef OPENSSL_NO_SCTP + case DTLS1_SCTP_ST_SR_READ_SOCK: + + if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) + { + s->s3->in_read_app_data=2; + s->rwstate=SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + ret = -1; + goto end; + } + + s->state=SSL3_ST_SR_FINISHED_A; + break; + + case DTLS1_SCTP_ST_SW_WRITE_SOCK: + ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); + if (ret < 0) goto end; + + if (ret == 0) + { + if (s->d1->next_state != SSL_ST_OK) + { + s->s3->in_read_app_data=2; + s->rwstate=SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + ret = -1; + goto end; + } + } + + s->state=s->d1->next_state; + break; +#endif + case SSL3_ST_SW_SRVR_HELLO_A: case SSL3_ST_SW_SRVR_HELLO_B: - ret=dtls1_send_server_hello(s); + s->renegotiate = 2; + dtls1_start_timer(s); + ret=ssl3_send_server_hello(s); if (ret <= 0) goto end; if (s->hit) + { +#ifndef OPENSSL_NO_SCTP + /* Add new shared key for SCTP-Auth, + * will be ignored if no SCTP used. + */ + snprintf((char*) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), + DTLS1_SCTP_AUTH_LABEL); + + SSL_export_keying_material(s, sctpauthkey, + sizeof(sctpauthkey), labelbuffer, + sizeof(labelbuffer), NULL, 0, 0); + + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + sizeof(sctpauthkey), sctpauthkey); +#endif +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_ticket_expected) + s->state=SSL3_ST_SW_SESSION_TICKET_A; + else + s->state=SSL3_ST_SW_CHANGE_A; +#else s->state=SSL3_ST_SW_CHANGE_A; +#endif + } else s->state=SSL3_ST_SW_CERT_A; s->init_num=0; @@ -302,27 +436,43 @@ int dtls1_accept(SSL *s) case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: - /* Check if it is anon DH */ - if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) + /* Check if it is anon DH or normal PSK */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - ret=dtls1_send_server_certificate(s); + dtls1_start_timer(s); + ret=ssl3_send_server_certificate(s); if (ret <= 0) goto end; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_status_expected) + s->state=SSL3_ST_SW_CERT_STATUS_A; + else + s->state=SSL3_ST_SW_KEY_EXCH_A; + } + else + { + skip = 1; + s->state=SSL3_ST_SW_KEY_EXCH_A; + } +#else } else skip=1; + s->state=SSL3_ST_SW_KEY_EXCH_A; +#endif s->init_num=0; break; case SSL3_ST_SW_KEY_EXCH_A: case SSL3_ST_SW_KEY_EXCH_B: - l=s->s3->tmp.new_cipher->algorithms; + 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 - && !(l & SSL_KRB5) + && !(alg_k & SSL_kKRB5) #endif /* OPENSSL_NO_KRB5 */ ) /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key @@ -336,8 +486,14 @@ int dtls1_accept(SSL *s) /* only send if a DH key exchange or * RSA but we have a sign only certificate */ if (s->s3->tmp.use_rsa_tmp - || (l & SSL_DH) - || ((l & SSL_kRSA) + /* 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_kRSA) && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) @@ -346,7 +502,8 @@ int dtls1_accept(SSL *s) ) ) { - ret=dtls1_send_server_key_exchange(s); + dtls1_start_timer(s); + ret=ssl3_send_server_key_exchange(s); if (ret <= 0) goto end; } else @@ -367,28 +524,53 @@ int dtls1_accept(SSL *s) /* never request cert in anonymous ciphersuites * (see section "Certificate request" in SSL 3 drafts * and in RFC 2246): */ - ((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) && + ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && /* ... except when the application insists on verification * (against the specs, but s3_clnt.c accepts this for SSL 3) */ !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || - /* never request cert in Kerberos ciphersuites */ - (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5)) + /* never request cert in Kerberos ciphersuites */ + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) + /* With normal PSK Certificates and + * Certificate Requests are omitted */ + || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { /* no cert request */ skip=1; s->s3->tmp.cert_request=0; s->state=SSL3_ST_SW_SRVR_DONE_A; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) + { + s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; + s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +#endif } else { s->s3->tmp.cert_request=1; - ret=dtls1_send_certificate_request(s); + dtls1_start_timer(s); + ret=ssl3_send_certificate_request(s); if (ret <= 0) goto end; #ifndef NETSCAPE_HANG_BUG s->state=SSL3_ST_SW_SRVR_DONE_A; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) + { + s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; + s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +#endif #else s->state=SSL3_ST_SW_FLUSH; s->s3->tmp.next_state=SSL3_ST_SR_CERT_A; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) + { + s->d1->next_state = s->s3->tmp.next_state; + s->s3->tmp.next_state=DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +#endif #endif s->init_num=0; } @@ -396,7 +578,8 @@ int dtls1_accept(SSL *s) case SSL3_ST_SW_SRVR_DONE_A: case SSL3_ST_SW_SRVR_DONE_B: - ret=dtls1_send_server_done(s); + dtls1_start_timer(s); + ret=ssl3_send_server_done(s); if (ret <= 0) goto end; s->s3->tmp.next_state=SSL3_ST_SR_CERT_A; s->state=SSL3_ST_SW_FLUSH; @@ -404,16 +587,20 @@ int dtls1_accept(SSL *s) break; case SSL3_ST_SW_FLUSH: - /* number of bytes to be flushed */ - num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL); - if (num1 > 0) + s->rwstate=SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { - s->rwstate=SSL_WRITING; - num1=BIO_flush(s->wbio); - if (num1 <= 0) { ret= -1; goto end; } - s->rwstate=SSL_NOTHING; + /* If the write error was fatal, stop trying */ + if (!BIO_should_retry(s->wbio)) + { + s->rwstate=SSL_NOTHING; + s->state=s->s3->tmp.next_state; + } + + ret= -1; + goto end; } - + s->rwstate=SSL_NOTHING; s->state=s->s3->tmp.next_state; break; @@ -424,7 +611,10 @@ int dtls1_accept(SSL *s) if (ret <= 0) goto end; if (ret == 2) + { + 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 :-) */ @@ -439,43 +629,122 @@ int dtls1_accept(SSL *s) case SSL3_ST_SR_KEY_EXCH_B: ret=ssl3_get_client_key_exchange(s); if (ret <= 0) goto end; +#ifndef OPENSSL_NO_SCTP + /* Add new shared key for SCTP-Auth, + * will be ignored if no SCTP used. + */ + snprintf((char *) labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), + DTLS1_SCTP_AUTH_LABEL); + + SSL_export_keying_material(s, sctpauthkey, + sizeof(sctpauthkey), labelbuffer, + sizeof(labelbuffer), NULL, 0, 0); + + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + sizeof(sctpauthkey), sctpauthkey); +#endif + s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; - /* We need to get hashes here so if there is - * a client cert, it can be verified */ - s->method->ssl3_enc->cert_verify_mac(s, - &(s->s3->finish_dgst1), - &(s->s3->tmp.cert_verify_md[0])); - s->method->ssl3_enc->cert_verify_mac(s, - &(s->s3->finish_dgst2), - &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH])); + if (ret == 2) + { + /* For the ECDH ciphersuites when + * the client sends its ECDH pub key in + * a certificate, the CertificateVerify + * message is not sent. + */ + 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; + s->init_num=0; + /* We need to get hashes here so if there is + * a client cert, it can be verified */ + s->method->ssl3_enc->cert_verify_mac(s, + NID_md5, + &(s->s3->tmp.cert_verify_md[0])); + s->method->ssl3_enc->cert_verify_mac(s, + NID_sha1, + &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH])); + } break; case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_B: + 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; - - s->state=SSL3_ST_SR_FINISHED_A; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && + state == SSL_ST_RENEGOTIATE) + s->state=DTLS1_SCTP_ST_SR_READ_SOCK; + else +#endif + s->state=SSL3_ST_SR_FINISHED_A; s->init_num=0; break; case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: + 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; + dtls1_stop_timer(s); if (s->hit) s->state=SSL_ST_OK; +#ifndef OPENSSL_NO_TLSEXT + else if (s->tlsext_ticket_expected) + s->state=SSL3_ST_SW_SESSION_TICKET_A; +#endif else s->state=SSL3_ST_SW_CHANGE_A; s->init_num=0; break; +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_SW_SESSION_TICKET_A: + case SSL3_ST_SW_SESSION_TICKET_B: + ret=ssl3_send_newsession_ticket(s); + if (ret <= 0) goto end; + s->state=SSL3_ST_SW_CHANGE_A; + s->init_num=0; + break; + + case SSL3_ST_SW_CERT_STATUS_A: + case SSL3_ST_SW_CERT_STATUS_B: + ret=ssl3_send_cert_status(s); + if (ret <= 0) goto end; + s->state=SSL3_ST_SW_KEY_EXCH_A; + s->init_num=0; + break; + +#endif + case SSL3_ST_SW_CHANGE_A: case SSL3_ST_SW_CHANGE_B: @@ -487,6 +756,14 @@ int dtls1_accept(SSL *s) SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B); 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); +#endif + s->state=SSL3_ST_SW_FINISHED_A; s->init_num=0; @@ -502,7 +779,7 @@ int dtls1_accept(SSL *s) case SSL3_ST_SW_FINISHED_A: case SSL3_ST_SW_FINISHED_B: - ret=dtls1_send_finished(s, + ret=ssl3_send_finished(s, SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B, s->method->ssl3_enc->server_finished_label, s->method->ssl3_enc->server_finished_label_len); @@ -511,7 +788,16 @@ int dtls1_accept(SSL *s) if (s->hit) s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; else + { s->s3->tmp.next_state=SSL_ST_OK; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) + { + s->d1->next_state = s->s3->tmp.next_state; + s->s3->tmp.next_state=DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +#endif + } s->init_num=0; break; @@ -529,11 +815,9 @@ int dtls1_accept(SSL *s) s->init_num=0; - if (s->new_session == 2) /* skipped if we just sent a HelloRequest */ + if (s->renegotiate == 2) /* skipped if we just sent a HelloRequest */ { - /* actually not necessarily a 'new' session unless - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */ - + s->renegotiate=0; s->new_session=0; ssl_update_cache(s,SSL_SESS_CACHE_SERVER); @@ -551,6 +835,7 @@ int dtls1_accept(SSL *s) s->d1->handshake_read_seq = 0; /* next message is server hello */ s->d1->handshake_write_seq = 0; + s->d1->next_handshake_write_seq = 0; goto end; /* break; */ @@ -584,33 +869,19 @@ end: /* BIO_flush(s->wbio); */ s->in_handshake--; +#ifndef OPENSSL_NO_SCTP + /* Notify SCTP BIO socket to leave handshake + * mode and prevent stream identifier other + * than 0. Will be ignored if no SCTP is used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, s->in_handshake, NULL); +#endif + if (cb != NULL) cb(s,SSL_CB_ACCEPT_EXIT,ret); return(ret); } -int dtls1_send_hello_request(SSL *s) - { - unsigned char *p; - - if (s->state == SSL3_ST_SW_HELLO_REQ_A) - { - p=(unsigned char *)s->init_buf->data; - p = dtls1_set_message_header(s, p, SSL3_MT_HELLO_REQUEST, 0, 0, 0); - - s->state=SSL3_ST_SW_HELLO_REQ_B; - /* number of bytes to write */ - s->init_num=DTLS1_HM_HEADER_LENGTH; - s->init_off=0; - - /* no need to buffer this message, since there are no retransmit - * requests for it */ - } - - /* SSL3_ST_SW_HELLO_REQ_B */ - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); - } - int dtls1_send_hello_verify_request(SSL *s) { unsigned int msg_len; @@ -621,20 +892,19 @@ int dtls1_send_hello_verify_request(SSL *s) 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; - *(p++) = (unsigned char) s->d1->cookie_len; - if ( s->ctx->app_gen_cookie_cb != NULL && - s->ctx->app_gen_cookie_cb(s, s->d1->cookie, - &(s->d1->cookie_len)) == 0) - { + if (s->ctx->app_gen_cookie_cb == NULL || + s->ctx->app_gen_cookie_cb(s, s->d1->cookie, + &(s->d1->cookie_len)) == 0) + { SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,ERR_R_INTERNAL_ERROR); - return 0; - } - /* else the cookie is assumed to have - * been initialized by the application */ + return 0; + } + *(p++) = (unsigned char) s->d1->cookie_len; memcpy(p, s->d1->cookie, s->d1->cookie_len); p += s->d1->cookie_len; msg_len = p - msg; @@ -646,486 +916,8 @@ int dtls1_send_hello_verify_request(SSL *s) /* number of bytes to write */ s->init_num=p-buf; s->init_off=0; - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); } /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */ return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); } - -int dtls1_send_server_hello(SSL *s) - { - unsigned char *buf; - unsigned char *p,*d; - int i; - unsigned int sl; - unsigned long l,Time; - - if (s->state == SSL3_ST_SW_SRVR_HELLO_A) - { - buf=(unsigned char *)s->init_buf->data; - p=s->s3->server_random; - Time=(unsigned long)time(NULL); /* Time */ - l2n(Time,p); - RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time)); - /* Do the message type and length last */ - d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); - - *(p++)=s->version>>8; - *(p++)=s->version&0xff; - - /* Random stuff */ - memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); - p+=SSL3_RANDOM_SIZE; - - /* now in theory we have 3 options to sending back the - * session id. If it is a re-use, we send back the - * old session-id, if it is a new session, we send - * back the new session-id or we send back a 0 length - * session-id if we want it to be single use. - * Currently I will not implement the '0' length session-id - * 12-Jan-98 - I'll now support the '0' length stuff. - */ - if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) - s->session->session_id_length=0; - - sl=s->session->session_id_length; - if (sl > sizeof s->session->session_id) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - return -1; - } - *(p++)=sl; - memcpy(p,s->session->session_id,sl); - p+=sl; - - /* put the cipher */ - i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p); - p+=i; - - /* put the compression method */ -#ifdef OPENSSL_NO_COMP - *(p++)=0; -#else - if (s->s3->tmp.new_compression == NULL) - *(p++)=0; - else - *(p++)=s->s3->tmp.new_compression->id; -#endif - - /* do the header */ - l=(p-d); - d=buf; - - d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l); - - s->state=SSL3_ST_CW_CLNT_HELLO_B; - /* number of bytes to write */ - s->init_num=p-buf; - s->init_off=0; - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); - } - - /* SSL3_ST_CW_CLNT_HELLO_B */ - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); - } - -int dtls1_send_server_done(SSL *s) - { - unsigned char *p; - - if (s->state == SSL3_ST_SW_SRVR_DONE_A) - { - p=(unsigned char *)s->init_buf->data; - - /* do the header */ - p = dtls1_set_message_header(s, p, SSL3_MT_SERVER_DONE, 0, 0, 0); - - s->state=SSL3_ST_SW_SRVR_DONE_B; - /* number of bytes to write */ - s->init_num=DTLS1_HM_HEADER_LENGTH; - s->init_off=0; - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); - } - - /* SSL3_ST_CW_CLNT_HELLO_B */ - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); - } - -int dtls1_send_server_key_exchange(SSL *s) - { -#ifndef OPENSSL_NO_RSA - unsigned char *q; - int j,num; - RSA *rsa; - unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; - unsigned int u; -#endif -#ifndef OPENSSL_NO_DH - DH *dh=NULL,*dhp; -#endif - EVP_PKEY *pkey; - unsigned char *p,*d; - int al,i; - unsigned long type; - int n; - CERT *cert; - BIGNUM *r[4]; - int nr[4],kn; - BUF_MEM *buf; - EVP_MD_CTX md_ctx; - - EVP_MD_CTX_init(&md_ctx); - if (s->state == SSL3_ST_SW_KEY_EXCH_A) - { - type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK; - cert=s->cert; - - buf=s->init_buf; - - r[0]=r[1]=r[2]=r[3]=NULL; - n=0; -#ifndef OPENSSL_NO_RSA - if (type & SSL_kRSA) - { - rsa=cert->rsa_tmp; - if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) - { - rsa=s->cert->rsa_tmp_cb(s, - SSL_C_IS_EXPORT(s->s3->tmp.new_cipher), - SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)); - if(rsa == NULL) - { - al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY); - goto f_err; - } - RSA_up_ref(rsa); - cert->rsa_tmp=rsa; - } - if (rsa == NULL) - { - al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY); - goto f_err; - } - r[0]=rsa->n; - r[1]=rsa->e; - s->s3->tmp.use_rsa_tmp=1; - } - else -#endif -#ifndef OPENSSL_NO_DH - if (type & SSL_kEDH) - { - dhp=cert->dh_tmp; - if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) - dhp=s->cert->dh_tmp_cb(s, - SSL_C_IS_EXPORT(s->s3->tmp.new_cipher), - SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)); - if (dhp == NULL) - { - al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY); - goto f_err; - } - - if (s->s3->tmp.dh != NULL) - { - DH_free(dh); - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - - if ((dh=DHparams_dup(dhp)) == NULL) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB); - goto err; - } - - s->s3->tmp.dh=dh; - if ((dhp->pub_key == NULL || - dhp->priv_key == NULL || - (s->options & SSL_OP_SINGLE_DH_USE))) - { - if(!DH_generate_key(dh)) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, - ERR_R_DH_LIB); - goto err; - } - } - else - { - dh->pub_key=BN_dup(dhp->pub_key); - dh->priv_key=BN_dup(dhp->priv_key); - if ((dh->pub_key == NULL) || - (dh->priv_key == NULL)) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB); - goto err; - } - } - r[0]=dh->p; - r[1]=dh->g; - r[2]=dh->pub_key; - } - else -#endif - { - al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); - goto f_err; - } - for (i=0; r[i] != NULL; i++) - { - nr[i]=BN_num_bytes(r[i]); - n+=2+nr[i]; - } - - if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) - { - if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher)) - == NULL) - { - al=SSL_AD_DECODE_ERROR; - goto f_err; - } - kn=EVP_PKEY_size(pkey); - } - else - { - pkey=NULL; - kn=0; - } - - if (!BUF_MEM_grow_clean(buf,n+DTLS1_HM_HEADER_LENGTH+kn)) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF); - goto err; - } - d=(unsigned char *)s->init_buf->data; - p= &(d[DTLS1_HM_HEADER_LENGTH]); - - for (i=0; r[i] != NULL; i++) - { - s2n(nr[i],p); - BN_bn2bin(r[i],p); - p+=nr[i]; - } - - /* not anonymous */ - if (pkey != NULL) - { - /* n is the length of the params, they start at - * &(d[DTLS1_HM_HEADER_LENGTH]) and p points to the space - * at the end. */ -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) - { - q=md_buf; - j=0; - for (num=2; num > 0; num--) - { - EVP_DigestInit_ex(&md_ctx,(num == 2) - ?s->ctx->md5:s->ctx->sha1, NULL); - 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,&(d[DTLS1_HM_HEADER_LENGTH]),n); - EVP_DigestFinal_ex(&md_ctx,q, - (unsigned int *)&i); - q+=i; - j+=i; - } - if (RSA_sign(NID_md5_sha1, md_buf, j, - &(p[2]), &u, pkey->pkey.rsa) <= 0) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA); - goto err; - } - s2n(u,p); - n+=u+2; - } - else -#endif -#if !defined(OPENSSL_NO_DSA) - if (pkey->type == EVP_PKEY_DSA) - { - /* lets do DSS */ - EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL); - EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); - EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); - EVP_SignUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n); - if (!EVP_SignFinal(&md_ctx,&(p[2]), - (unsigned int *)&i,pkey)) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA); - goto err; - } - s2n(i,p); - n+=i+2; - } - else -#endif - { - /* Is this error check actually needed? */ - al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE); - goto f_err; - } - } - - d = dtls1_set_message_header(s, d, - SSL3_MT_SERVER_KEY_EXCHANGE, n, 0, n); - - /* we should now have things packed up, so lets send - * it off */ - s->init_num=n+DTLS1_HM_HEADER_LENGTH; - s->init_off=0; - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); - } - - s->state = SSL3_ST_SW_KEY_EXCH_B; - EVP_MD_CTX_cleanup(&md_ctx); - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); -f_err: - ssl3_send_alert(s,SSL3_AL_FATAL,al); -err: - EVP_MD_CTX_cleanup(&md_ctx); - return(-1); - } - -int dtls1_send_certificate_request(SSL *s) - { - unsigned char *p,*d; - int i,j,nl,off,n; - STACK_OF(X509_NAME) *sk=NULL; - X509_NAME *name; - BUF_MEM *buf; - - if (s->state == SSL3_ST_SW_CERT_REQ_A) - { - buf=s->init_buf; - - d=p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]); - - /* get the list of acceptable cert types */ - p++; - n=ssl3_get_req_cert_type(s,p); - d[0]=n; - p+=n; - n++; - - off=n; - p+=2; - n+=2; - - sk=SSL_get_client_CA_list(s); - nl=0; - if (sk != NULL) - { - for (i=0; idata[DTLS1_HM_HEADER_LENGTH+n]); - if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) - { - s2n(j,p); - i2d_X509_NAME(name,&p); - n+=2+j; - nl+=2+j; - } - else - { - d=p; - i2d_X509_NAME(name,&p); - j-=2; s2n(j,d); j+=2; - n+=j; - nl+=j; - } - } - } - /* else no CA names */ - p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH+off]); - s2n(nl,p); - - d=(unsigned char *)buf->data; - *(d++)=SSL3_MT_CERTIFICATE_REQUEST; - l2n3(n,d); - s2n(s->d1->handshake_write_seq,d); - s->d1->handshake_write_seq++; - - /* we should now have things packed up, so lets send - * it off */ - - s->init_num=n+DTLS1_HM_HEADER_LENGTH; - s->init_off=0; -#ifdef NETSCAPE_HANG_BUG -/* XXX: what to do about this? */ - p=(unsigned char *)s->init_buf->data + s->init_num; - - /* do the header */ - *(p++)=SSL3_MT_SERVER_DONE; - *(p++)=0; - *(p++)=0; - *(p++)=0; - s->init_num += 4; -#endif - - /* XDTLS: set message header ? */ - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); - - s->state = SSL3_ST_SW_CERT_REQ_B; - } - - /* SSL3_ST_SW_CERT_REQ_B */ - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); -err: - return(-1); - } - -int dtls1_send_server_certificate(SSL *s) - { - unsigned long l; - X509 *x; - - if (s->state == SSL3_ST_SW_CERT_A) - { - x=ssl_get_server_send_cert(s); - if (x == NULL && - /* VRS: allow null cert if auth == KRB5 */ - (s->s3->tmp.new_cipher->algorithms - & (SSL_MKEY_MASK|SSL_AUTH_MASK)) - != (SSL_aKRB5|SSL_kKRB5)) - { - SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR); - return(0); - } - - l=dtls1_output_cert_chain(s,x); - s->state=SSL3_ST_SW_CERT_B; - s->init_num=(int)l; - s->init_off=0; - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); - } - - /* SSL3_ST_SW_CERT_B */ - return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); - }