X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_srvr.c;h=200f4951fb193825d3bbe5a58d5302d0e7ca49ff;hp=44065d7e894103239ad72148e45955acbef58da4;hb=c6913eeb762edffddecaaba5c84909d7a7962927;hpb=21b25ed4b83334b0296aa5b33a250f1f7488de4c diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 44065d7e89..200f4951fb 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -179,6 +179,32 @@ static const SSL_METHOD *ssl3_get_server_method(int ver) return(NULL); } +#ifndef OPENSSL_NO_SRP +static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) + { + int ret = SSL_ERROR_NONE; + + *al = SSL_AD_UNRECOGNIZED_NAME; + + if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) && + (s->srp_ctx.TLS_ext_srp_username_callback != NULL)) + { + if(s->srp_ctx.login == NULL) + { + /* RFC 5054 says SHOULD reject, + we do so if There is no srp login name */ + ret = SSL3_AL_FATAL; + *al = SSL_AD_UNKNOWN_PSK_IDENTITY; + } + else + { + ret = SSL_srp_server_param_with_username(s,al); + } + } + return ret; + } +#endif + IMPLEMENT_ssl3_meth_func(SSLv3_server_method, ssl3_accept, ssl_undefined_function, @@ -189,7 +215,6 @@ int ssl3_accept(SSL *s) BUF_MEM *buf; unsigned long alg_k,Time=(unsigned long)time(NULL); void (*cb)(const SSL *ssl,int type,int val)=NULL; - long num1; int ret= -1; int new_state,state,skip=0; @@ -212,6 +237,18 @@ int ssl3_accept(SSL *s) 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) + { + s->tlsext_hb_pending = 0; + s->tlsext_hb_seq++; + } +#endif + for (;;) { state=s->state; @@ -219,7 +256,7 @@ int ssl3_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: @@ -259,6 +296,8 @@ int ssl3_accept(SSL *s) } s->init_num=0; + s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE; + s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY; if (s->state != SSL_ST_RENEGOTIATE) { @@ -271,6 +310,18 @@ int ssl3_accept(SSL *s) s->state=SSL3_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; } + else if (!s->s3->send_connection_binding && + !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) + { + /* Server attempting to renegotiate with + * client that doesn't support secure + * renegotiation. + */ + SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + ret = -1; + goto end; + } else { /* s->state == SSL_ST_RENEGOTIATE, @@ -301,11 +352,35 @@ int ssl3_accept(SSL *s) case SSL3_ST_SR_CLNT_HELLO_B: case SSL3_ST_SR_CLNT_HELLO_C: - s->shutdown=0; - ret=ssl3_get_client_hello(s); - if (ret <= 0) goto end; + if (s->rwstate != SSL_X509_LOOKUP) + { + ret=ssl3_get_client_hello(s); + if (ret <= 0) goto end; + } +#ifndef OPENSSL_NO_SRP + { + int al; + if ((ret = ssl_check_srp_ext_ClientHello(s,&al)) < 0) + { + /* callback indicates firther work to be done */ + s->rwstate=SSL_X509_LOOKUP; + goto end; + } + if (ret != SSL_ERROR_NONE) + { + ssl3_send_alert(s,SSL3_AL_FATAL,al); + /* This is not really an error but the only means to + for a client to detect whether srp is supported. */ + if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY) + SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT); + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + ret= -1; + goto end; + } + } +#endif - s->new_session = 2; + s->renegotiate = 2; s->state=SSL3_ST_SW_SRVR_HELLO_A; s->init_num=0; break; @@ -327,14 +402,35 @@ int ssl3_accept(SSL *s) s->state=SSL3_ST_SW_CHANGE_A; #endif else - s->state=SSL3_ST_SW_CERT_A; - s->init_num=0; +#ifndef OPENSSL_NO_TLSEXT + s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_A; +#else + s->state = SSL3_ST_SW_CERT_A; +#endif + s->init_num = 0; + break; + +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_SW_SUPPLEMENTAL_DATA_A: + case SSL3_ST_SW_SUPPLEMENTAL_DATA_B: + /* We promised to send an audit proof in the hello. */ + if (s->s3->tlsext_authz_promised_to_client) + { + ret = tls1_send_server_supplemental_data(s); + if (ret <= 0) goto end; + } + else + skip = 1; + + s->state = SSL3_ST_SW_CERT_A; + s->init_num = 0; break; +#endif case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: /* Check if it is anon DH or anon ECDH, */ - /* normal PSK or KRB5 */ + /* normal PSK or KRB5 or SRP */ if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) @@ -399,7 +495,11 @@ int ssl3_accept(SSL *s) #ifndef OPENSSL_NO_PSK || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) #endif - || (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH)) +#ifndef OPENSSL_NO_SRP + /* SRP: send ServerKeyExchange */ + || (alg_k & SSL_kSRP) +#endif + || (alg_k & SSL_kEDH) || (alg_k & SSL_kEECDH) || ((alg_k & SSL_kRSA) && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL @@ -445,6 +545,9 @@ int ssl3_accept(SSL *s) skip=1; s->s3->tmp.cert_request=0; s->state=SSL3_ST_SW_SRVR_DONE_A; + if (s->s3->handshake_buffer) + if (!ssl3_digest_cached_records(s)) + return -1; } else { @@ -471,15 +574,24 @@ int ssl3_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) + + /* This code originally checked to see if + * any data was pending using BIO_CTRL_INFO + * and then flushed. This caused problems + * as documented in PR#1939. The proposed + * fix doesn't completely resolve this issue + * as buggy implementations of BIO_CTRL_PENDING + * still exist. So instead we just flush + * unconditionally. + */ + + 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; + ret= -1; + goto end; } + s->rwstate=SSL_NOTHING; s->state=s->s3->tmp.next_state; break; @@ -514,10 +626,38 @@ int ssl3_accept(SSL *s) * the client sends its ECDH pub key in * a certificate, the CertificateVerify * message is not sent. + * Also for GOST ciphersuites when + * the client uses its key from the certificate + * for key exchange. */ +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) s->state=SSL3_ST_SR_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) + s->state=SSL3_ST_SR_NEXT_PROTO_A; + else + s->state=SSL3_ST_SR_FINISHED_A; +#endif 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_SSL3_ACCEPT,ERR_R_INTERNAL_ERROR); + return -1; + } + s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; + if (!ssl3_digest_cached_records(s)) + return -1; + } else { int offset=0; @@ -558,23 +698,37 @@ int ssl3_accept(SSL *s) ret=ssl3_get_cert_verify(s); if (ret <= 0) goto end; +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) s->state=SSL3_ST_SR_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) + s->state=SSL3_ST_SR_NEXT_PROTO_A; + else + s->state=SSL3_ST_SR_FINISHED_A; +#endif s->init_num=0; break; +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + case SSL3_ST_SR_NEXT_PROTO_A: + case SSL3_ST_SR_NEXT_PROTO_B: + ret=ssl3_get_next_proto(s); + if (ret <= 0) goto end; + s->init_num = 0; + s->state=SSL3_ST_SR_FINISHED_A; + break; +#endif + case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); if (ret <= 0) goto end; -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_ticket_expected) - s->state=SSL3_ST_SW_SESSION_TICKET_A; - else if (s->hit) - s->state=SSL_ST_OK; -#else 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; @@ -632,7 +786,16 @@ int ssl3_accept(SSL *s) if (ret <= 0) goto end; s->state=SSL3_ST_SW_FLUSH; if (s->hit) + { +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) + s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A; + else + s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; +#endif + } else s->s3->tmp.next_state=SSL_ST_OK; s->init_num=0; @@ -650,11 +813,9 @@ int ssl3_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); @@ -707,24 +868,15 @@ end: int ssl3_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++)=SSL3_MT_HELLO_REQUEST; - *(p++)=0; - *(p++)=0; - *(p++)=0; - + ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0); s->state=SSL3_ST_SW_HELLO_REQ_B; - /* number of bytes to write */ - s->init_num=4; - s->init_off=0; } /* SSL3_ST_SW_HELLO_REQ_B */ - return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); + return ssl_do_write(s); } int ssl3_check_client_hello(SSL *s) @@ -744,10 +896,15 @@ int ssl3_check_client_hello(SSL *s) s->s3->tmp.reuse_message = 1; if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) { + /* We only allow the client to restart the handshake once per + * negotiation. */ + if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) + { + SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); + return -1; + } /* Throw away what we have done so far in the current handshake, - * which will now be aborted. (A full SSL_clear would be too much.) - * I hope that tmp.dh is the only thing that may need to be cleared - * when a handshake is not completed ... */ + * which will now be aborted. (A full SSL_clear would be too much.) */ #ifndef OPENSSL_NO_DH if (s->s3->tmp.dh != NULL) { @@ -755,6 +912,14 @@ int ssl3_check_client_hello(SSL *s) s->s3->tmp.dh = NULL; } #endif +#ifndef OPENSSL_NO_ECDH + if (s->s3->tmp.ecdh != NULL) + { + EC_KEY_free(s->s3->tmp.ecdh); + s->s3->tmp.ecdh = NULL; + } +#endif + s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE; return 2; } return 1; @@ -762,13 +927,14 @@ int ssl3_check_client_hello(SSL *s) int ssl3_get_client_hello(SSL *s) { - int i,j,ok,al,ret= -1; + int i,j,ok,al=SSL_AD_INTERNAL_ERROR,ret= -1; unsigned int cookie_len; long n; unsigned long id; - unsigned char *p,*d,*q; + unsigned char *p,*d; SSL_CIPHER *c; #ifndef OPENSSL_NO_COMP + unsigned char *q; SSL_COMP *comp=NULL; #endif STACK_OF(SSL_CIPHER) *ciphers=NULL; @@ -779,7 +945,8 @@ int ssl3_get_client_hello(SSL *s) * If we are SSLv3, we will respond with SSLv3, even if prompted with * TLSv1. */ - if (s->state == SSL3_ST_SR_CLNT_HELLO_A) + if (s->state == SSL3_ST_SR_CLNT_HELLO_A + ) { s->state=SSL3_ST_SR_CLNT_HELLO_B; } @@ -800,8 +967,9 @@ int ssl3_get_client_hello(SSL *s) s->client_version=(((int)p[0])<<8)|(int)p[1]; p+=2; - if ((s->version == DTLS1_VERSION && s->client_version > s->version) || - (s->version != DTLS1_VERSION && s->client_version < s->version)) + if ((SSL_IS_DTLS(s) && s->client_version > s->version + && s->method->version != DTLS_ANY_VERSION) || + (!SSL_IS_DTLS(s) && s->client_version < s->version)) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); if ((s->client_version>>8) == SSL3_VERSION_MAJOR) @@ -813,6 +981,21 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } + /* If we require cookies and this ClientHello doesn't + * contain one, just return since we do not want to + * allocate any memory yet. So check cookie length... + */ + if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) + { + unsigned int session_length, cookie_length; + + session_length = *(p + SSL3_RANDOM_SIZE); + cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1); + + if (cookie_length == 0) + return 1; + } + /* load the client random */ memcpy(s->s3->client_random,p,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; @@ -821,13 +1004,16 @@ int ssl3_get_client_hello(SSL *s) j= *(p++); s->hit=0; - /* Versions before 0.9.7 always allow session reuse during renegotiation - * (i.e. when s->new_session is true), option - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is new with 0.9.7. - * Maybe this optional behaviour should always have been the default, - * but we cannot safely change the default behaviour (or new applications - * might be written that become totally unsecure when compiled with - * an earlier library version) + /* Versions before 0.9.7 always allow clients to resume sessions in renegotiation. + * 0.9.7 and later allow this by default, but optionally ignore resumption requests + * with flag SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather + * than a change to default behavior so that applications relying on this for security + * won't even compile against older library versions). + * + * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to request + * renegotiation but not a new session (s->new_session remains unset): for servers, + * this essentially just means that the SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + * setting will be ignored. */ if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { @@ -852,23 +1038,11 @@ int ssl3_get_client_hello(SSL *s) p+=j; - if (s->version == DTLS1_VERSION) + if (SSL_IS_DTLS(s)) { /* cookie stuff */ cookie_len = *(p++); - if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && - s->d1->send_cookie == 0) - { - /* HelloVerifyMessage has already been sent */ - if ( cookie_len != s->d1->cookie_len) - { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); - goto f_err; - } - } - /* * The ClientHello may contain a cookie even if the * HelloVerify message has not been sent--make sure that it @@ -883,7 +1057,7 @@ int ssl3_get_client_hello(SSL *s) } /* verify the cookie if appropriate option is set. */ - if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && + if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && cookie_len > 0) { memcpy(s->d1->rcvd_cookie, p, cookie_len); @@ -908,9 +1082,35 @@ int ssl3_get_client_hello(SSL *s) SSL_R_COOKIE_MISMATCH); goto f_err; } + + ret = 2; } p += cookie_len; + if (s->method->version == DTLS_ANY_VERSION) + { + /* Select version to use */ + if (s->client_version <= DTLS1_2_VERSION && + !(s->options & SSL_OP_NO_DTLSv1_2)) + { + s->version = DTLS1_2_VERSION; + s->method = DTLSv1_2_server_method(); + } + else if (s->client_version <= DTLS1_VERSION && + !(s->options & SSL_OP_NO_DTLSv1)) + { + s->version = DTLS1_VERSION; + s->method = DTLSv1_server_method(); + } + else + { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); + s->version = s->client_version; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + s->session->ssl_version = s->version; + } } n2s(p,i); @@ -957,6 +1157,10 @@ int ssl3_get_client_hello(SSL *s) break; } } +/* Disabled because it can be used in a ciphersuite downgrade + * attack: CVE-2010-4180. + */ +#if 0 if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1)) { /* Special case as client bug workaround: the previously used cipher may @@ -971,6 +1175,7 @@ int ssl3_get_client_hello(SSL *s) j = 1; } } +#endif if (j == 0) { /* we need to have the cipher in the cipher @@ -990,7 +1195,9 @@ int ssl3_get_client_hello(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH); goto f_err; } +#ifndef OPENSSL_NO_COMP q=p; +#endif for (j=0; jversion > SSL3_VERSION) + if (s->version >= SSL3_VERSION) { - if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al)) + if (!ssl_parse_clienthello_tlsext(s,&p,d,n)) { - /* 'al' set by ssl_parse_clienthello_tlsext */ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT); - goto f_err; - } - } - if (ssl_check_clienthello_tlsext(s) <= 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); goto err; + } } /* Check if we want to use external pre-shared secret for this @@ -1033,7 +1235,6 @@ int ssl3_get_client_hello(SSL *s) l2n(Time,pos); if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0) { - al=SSL_AD_INTERNAL_ERROR; goto f_err; } } @@ -1080,7 +1281,48 @@ int ssl3_get_client_hello(SSL *s) * algorithms from the client, starting at q. */ s->s3->tmp.new_compression=NULL; #ifndef OPENSSL_NO_COMP - if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods) + /* This only happens if we have a cache hit */ + if (s->session->compress_meth != 0) + { + int m, comp_id = s->session->compress_meth; + /* Perform sanity checks on resumed compression algorithm */ + /* Can't disable compression */ + if (s->options & SSL_OP_NO_COMPRESSION) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION); + goto f_err; + } + /* Look for resumed compression method */ + for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++) + { + comp=sk_SSL_COMP_value(s->ctx->comp_methods,m); + if (comp_id == comp->id) + { + s->s3->tmp.new_compression=comp; + break; + } + } + if (s->s3->tmp.new_compression == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INVALID_COMPRESSION_ALGORITHM); + goto f_err; + } + /* Look for resumed method in compression list */ + for (m = 0; m < i; m++) + { + if (q[m] == comp_id) + break; + } + if (m >= i) + { + al=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING); + goto f_err; + } + } + else if (s->hit) + comp = NULL; + else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods) { /* See if we have a match */ int m,nn,o,v,done=0; @@ -1104,6 +1346,15 @@ int ssl3_get_client_hello(SSL *s) else comp=NULL; } +#else + /* If compression is disabled we'd better not try to resume a session + * using compression. + */ + if (s->session->compress_meth != 0) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION); + goto f_err; + } #endif /* Given s->session->ciphers and SSL_get_ciphers, we must @@ -1126,6 +1377,14 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } ciphers=NULL; + /* Let cert callback update server certificates if required */ + if (s->cert->cert_cb + && s->cert->cert_cb(s, s->cert->cert_cb_arg) <= 0) + { + al=SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CERT_CB_ERROR); + goto f_err; + } c=ssl3_choose_cipher(s,s->session->ciphers, SSL_get_ciphers(s)); @@ -1136,6 +1395,13 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } s->s3->tmp.new_cipher=c; + /* check whether we should disable session resumption */ + if (s->not_resumable_session_cb != NULL) + s->session->not_resumable=s->not_resumable_session_cb(s, + ((c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH)) != 0)); + if (s->session->not_resumable) + /* do not send a session ticket */ + s->tlsext_ticket_expected = 0; } else { @@ -1168,8 +1434,11 @@ int ssl3_get_client_hello(SSL *s) s->s3->tmp.new_cipher=s->session->cipher; } - if (!ssl3_digest_cached_records(s)) - goto f_err; + if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) + { + if (!ssl3_digest_cached_records(s)) + goto f_err; + } /* we now have the following setup. * client_random @@ -1182,7 +1451,17 @@ int ssl3_get_client_hello(SSL *s) * s->tmp.new_cipher - the new cipher to use. */ - ret=1; + /* Handles TLS extensions that we couldn't check earlier */ + if (s->version >= SSL3_VERSION) + { + if (ssl_check_clienthello_tlsext_late(s) <= 0) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + } + + if (ret < 0) ret=1; if (0) { f_err: @@ -1215,7 +1494,7 @@ int ssl3_send_server_hello(SSL *s) return -1; #endif /* Do the message type and length last */ - d=p= &(buf[4]); + d=p= ssl_handshake_start(s); *(p++)=s->version>>8; *(p++)=s->version&0xff; @@ -1224,23 +1503,24 @@ int ssl3_send_server_hello(SSL *s) 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. - * - * We also have an additional case where stateless session - * resumption is successful: we always send back the old - * session id. In this case s->hit is non zero: this can - * only happen if stateless session resumption is succesful - * if session caching is disabled so existing functionality - * is unaffected. + /* There are several cases for the session ID to send + * back in the server hello: + * - For session reuse from the session cache, + * we send back the old session ID. + * - If stateless session reuse (using a session ticket) + * is successful, we send back the client's "session ID" + * (which doesn't actually identify the session). + * - If it is a new session, we send back the new + * session ID. + * - However, if we want the new session to be single-use, + * we send back a 0-length session ID. + * s->hit is non-zero in either case of session reuse, + * so the following won't overwrite an ID that we're supposed + * to send back. */ - if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) - && !s->hit) + if (s->session->not_resumable || + (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) + && !s->hit)) s->session->session_id_length=0; sl=s->session->session_id_length; @@ -1280,42 +1560,25 @@ int ssl3_send_server_hello(SSL *s) #endif /* do the header */ l=(p-d); - d=buf; - *(d++)=SSL3_MT_SERVER_HELLO; - l2n3(l,d); - + ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l); s->state=SSL3_ST_SW_SRVR_HELLO_B; - /* number of bytes to write */ - s->init_num=p-buf; - s->init_off=0; } /* SSL3_ST_SW_SRVR_HELLO_B */ - return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); + return ssl_do_write(s); } int ssl3_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++)=SSL3_MT_SERVER_DONE; - *(p++)=0; - *(p++)=0; - *(p++)=0; - - s->state=SSL3_ST_SW_SRVR_DONE_B; - /* number of bytes to write */ - s->init_num=4; - s->init_off=0; + ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0); + s->state = SSL3_ST_SW_SRVR_DONE_B; } /* SSL3_ST_SW_SRVR_DONE_B */ - return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); + return ssl_do_write(s); } int ssl3_send_server_key_exchange(SSL *s) @@ -1338,6 +1601,7 @@ int ssl3_send_server_key_exchange(SSL *s) BN_CTX *bn_ctx = NULL; #endif EVP_PKEY *pkey; + const EVP_MD *md = NULL; unsigned char *p,*d; int al,i; unsigned long type; @@ -1405,7 +1669,6 @@ int ssl3_send_server_key_exchange(SSL *s) if (s->s3->tmp.dh != NULL) { - DH_free(dh); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } @@ -1451,7 +1714,14 @@ int ssl3_send_server_key_exchange(SSL *s) const EC_GROUP *group; ecdhp=cert->ecdh_tmp; - if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL)) + if (s->cert->ecdh_tmp_auto) + { + /* Get NID of appropriate shared curve */ + int nid = tls1_shared_curve(s, -2); + if (nid != NID_undef) + ecdhp = EC_KEY_new_by_curve_name(nid); + } + else if ((ecdhp == NULL) && s->cert->ecdh_tmp_cb) { ecdhp=s->cert->ecdh_tmp_cb(s, SSL_C_IS_EXPORT(s->s3->tmp.new_cipher), @@ -1466,7 +1736,6 @@ int ssl3_send_server_key_exchange(SSL *s) if (s->s3->tmp.ecdh != NULL) { - EC_KEY_free(s->s3->tmp.ecdh); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } @@ -1477,12 +1746,13 @@ int ssl3_send_server_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); goto err; } - if (!EC_KEY_up_ref(ecdhp)) + if (s->cert->ecdh_tmp_auto) + ecdh = ecdhp; + else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); goto err; } - ecdh = ecdhp; s->s3->tmp.ecdh=ecdh; if ((EC_KEY_get0_public_key(ecdh) == NULL) || @@ -1581,21 +1851,44 @@ int ssl3_send_server_key_exchange(SSL *s) } else #endif /* !OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (type & SSL_kSRP) + { + if ((s->srp_ctx.N == NULL) || + (s->srp_ctx.g == NULL) || + (s->srp_ctx.s == NULL) || + (s->srp_ctx.B == NULL)) + { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_SRP_PARAM); + goto err; + } + r[0]=s->srp_ctx.N; + r[1]=s->srp_ctx.g; + r[2]=s->srp_ctx.s; + r[3]=s->srp_ctx.B; + } + else +#endif { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); goto f_err; } - for (i=0; r[i] != NULL; i++) + for (i=0; r[i] != NULL && i<4; i++) { nr[i]=BN_num_bytes(r[i]); +#ifndef OPENSSL_NO_SRP + if ((i == 2) && (type & SSL_kSRP)) + n+=1+nr[i]; + else +#endif n+=2+nr[i]; } if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher)) + if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md)) == NULL) { al=SSL_AD_DECODE_ERROR; @@ -1609,16 +1902,23 @@ int ssl3_send_server_key_exchange(SSL *s) kn=0; } - if (!BUF_MEM_grow_clean(buf,n+4+kn)) + if (!BUF_MEM_grow_clean(buf,n+SSL_HM_HEADER_LENGTH(s)+kn)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF); goto err; } - d=(unsigned char *)s->init_buf->data; - p= &(d[4]); + d = p = ssl_handshake_start(s); - for (i=0; r[i] != NULL; i++) + for (i=0; r[i] != NULL && i<4; i++) { +#ifndef OPENSSL_NO_SRP + if ((i == 2) && (type & SSL_kSRP)) + { + *p = nr[i]; + p++; + } + else +#endif s2n(nr[i],p); BN_bn2bin(r[i],p); p+=nr[i]; @@ -1645,6 +1945,7 @@ int ssl3_send_server_key_exchange(SSL *s) (unsigned char *)encodedPoint, encodedlen); OPENSSL_free(encodedPoint); + encodedPoint = NULL; p += encodedlen; } #endif @@ -1665,17 +1966,19 @@ int ssl3_send_server_key_exchange(SSL *s) /* n is the length of the params, they start at &(d[4]) * and p points to the space at the end. */ #ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) + if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { q=md_buf; j=0; for (num=2; num > 0; num--) { + EVP_MD_CTX_set_flags(&md_ctx, + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); 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[4]),n); + EVP_DigestUpdate(&md_ctx,d,n); EVP_DigestFinal_ex(&md_ctx,q, (unsigned int *)&i); q+=i; @@ -1692,44 +1995,40 @@ int ssl3_send_server_key_exchange(SSL *s) } else #endif -#if !defined(OPENSSL_NO_DSA) - if (pkey->type == EVP_PKEY_DSA) + if (md) { - /* 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[4]),n); - if (!EVP_SignFinal(&md_ctx,&(p[2]), - (unsigned int *)&i,pkey)) + /* send signature algorithm */ + if (SSL_USE_SIGALGS(s)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA); - goto err; + if (!tls12_get_sigandhash(p, pkey, md)) + { + /* Should never happen */ + al=SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); + goto f_err; + } + p+=2; } - s2n(i,p); - n+=i+2; - } - else +#ifdef SSL_DEBUG + fprintf(stderr, "Using hash %s\n", + EVP_MD_name(md)); #endif -#if !defined(OPENSSL_NO_ECDSA) - if (pkey->type == EVP_PKEY_EC) - { - /* let's do ECDSA */ - EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL); + EVP_SignInit_ex(&md_ctx, md, 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[4]),n); + EVP_SignUpdate(&md_ctx,d,n); if (!EVP_SignFinal(&md_ctx,&(p[2]), (unsigned int *)&i,pkey)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_ECDSA); + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_EVP); goto err; } s2n(i,p); n+=i+2; + if (SSL_USE_SIGALGS(s)) + n+= 2; } else -#endif { /* Is this error check actually needed? */ al=SSL_AD_HANDSHAKE_FAILURE; @@ -1738,18 +2037,12 @@ int ssl3_send_server_key_exchange(SSL *s) } } - *(d++)=SSL3_MT_SERVER_KEY_EXCHANGE; - l2n3(n,d); - - /* we should now have things packed up, so lets send - * it off */ - s->init_num=n+4; - s->init_off=0; + ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n); } s->state = SSL3_ST_SW_KEY_EXCH_B; EVP_MD_CTX_cleanup(&md_ctx); - return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); + return ssl_do_write(s); f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); err: @@ -1773,7 +2066,7 @@ int ssl3_send_certificate_request(SSL *s) { buf=s->init_buf; - d=p=(unsigned char *)&(buf->data[4]); + d=p=ssl_handshake_start(s); /* get the list of acceptable cert types */ p++; @@ -1782,6 +2075,16 @@ int ssl3_send_certificate_request(SSL *s) p+=n; n++; + if (SSL_USE_SIGALGS(s)) + { + const unsigned char *psigs; + nl = tls12_get_psigalgs(s, &psigs); + s2n(nl, p); + memcpy(p, psigs, nl); + p += nl; + n += nl + 2; + } + off=n; p+=2; n+=2; @@ -1818,34 +2121,29 @@ int ssl3_send_certificate_request(SSL *s) } } /* else no CA names */ - p=(unsigned char *)&(buf->data[4+off]); + p = ssl_handshake_start(s) + off; s2n(nl,p); - d=(unsigned char *)buf->data; - *(d++)=SSL3_MT_CERTIFICATE_REQUEST; - l2n3(n,d); - - /* we should now have things packed up, so lets send - * it off */ + ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n); - s->init_num=n+4; - s->init_off=0; #ifdef NETSCAPE_HANG_BUG - 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; + if (!SSL_IS_DTLS(s)) + { + 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 s->state = SSL3_ST_SW_CERT_REQ_B; } /* SSL3_ST_SW_CERT_REQ_B */ - return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); + return ssl_do_write(s); err: return(-1); } @@ -1862,7 +2160,7 @@ int ssl3_get_client_key_exchange(SSL *s) #endif #ifndef OPENSSL_NO_DH BIGNUM *pub=NULL; - DH *dh_srvr; + DH *dh_srvr, *dh_clnt = NULL; #endif #ifndef OPENSSL_NO_KRB5 KSSL_ERR kssl_err; @@ -1996,8 +2294,13 @@ int ssl3_get_client_key_exchange(SSL *s) #ifndef OPENSSL_NO_DH if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { - n2s(p,i); - if (n != i+2) + int idx = -1; + EVP_PKEY *skey = NULL; + if (n) + n2s(p,i); + else + i = 0; + if (n && n != i+2) { if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { @@ -2010,26 +2313,52 @@ int ssl3_get_client_key_exchange(SSL *s) i=(int)n; } } - - if (n == 0L) /* the parameters are in the cert */ + if (alg_k & SSL_kDHr) + idx = SSL_PKEY_DH_RSA; + else if (alg_k & SSL_kDHd) + idx = SSL_PKEY_DH_DSA; + if (idx >= 0) + { + skey = s->cert->pkeys[idx].privatekey; + if ((skey == NULL) || + (skey->type != EVP_PKEY_DH) || + (skey->pkey.dh == NULL)) + { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_RSA_CERTIFICATE); + goto f_err; + } + dh_srvr = skey->pkey.dh; + } + else if (s->s3->tmp.dh == NULL) { al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_DECODE_DH_CERTS); + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY); goto f_err; } else + dh_srvr=s->s3->tmp.dh; + + if (n == 0L) { - if (s->s3->tmp.dh == NULL) + /* Get pubkey from cert */ + EVP_PKEY *clkey=X509_get_pubkey(s->session->peer); + if (clkey) + { + if (EVP_PKEY_cmp_parameters(clkey, skey) == 1) + dh_clnt = EVP_PKEY_get1_DH(clkey); + } + if (dh_clnt == NULL) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY); goto f_err; } - else - dh_srvr=s->s3->tmp.dh; + EVP_PKEY_free(clkey); + pub = dh_clnt->pub_key; } - - pub=BN_bin2bn(p,i,NULL); + else + pub=BN_bin2bn(p,i,NULL); if (pub == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BN_LIB); @@ -2041,18 +2370,23 @@ int ssl3_get_client_key_exchange(SSL *s) if (i <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); + BN_clear_free(pub); goto err; } DH_free(s->s3->tmp.dh); s->s3->tmp.dh=NULL; - - BN_clear_free(pub); + if (dh_clnt) + DH_free(dh_clnt); + else + BN_clear_free(pub); pub=NULL; s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key,p,i); OPENSSL_cleanse(p,i); + if (dh_clnt) + return 2; } else #endif @@ -2205,7 +2539,7 @@ int ssl3_get_client_key_exchange(SSL *s) SSL_R_DATA_LENGTH_TOO_LONG); goto err; } - if (!((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff)))) + if (!((pms[0] == (s->client_version>>8)) && (pms[1] == (s->client_version & 0xff)))) { /* The premaster secret must contain the same version number as the * ClientHello to detect version rollback attacks (strangely, the @@ -2215,8 +2549,7 @@ int ssl3_get_client_key_exchange(SSL *s) * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. * (Perhaps we should have a separate BUG value for the Kerberos cipher) */ - if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) && - (p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff)))) + if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_AD_DECODE_ERROR); @@ -2355,6 +2688,12 @@ int ssl3_get_client_key_exchange(SSL *s) /* Get encoded point length */ i = *p; p += 1; + if (n != 1 + i) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_EC_LIB); + goto err; + } if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { @@ -2495,34 +2834,116 @@ int ssl3_get_client_key_exchange(SSL *s) } else #endif +#ifndef OPENSSL_NO_SRP + if (alg_k & SSL_kSRP) + { + int param_len; + + n2s(p,i); + param_len=i+2; + if (param_len > n) + { + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_SRP_A_LENGTH); + goto f_err; + } + if (!(s->srp_ctx.A=BN_bin2bn(p,i,NULL))) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB); + 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_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); + goto err; + } + + p+=i; + } + else +#endif /* OPENSSL_NO_SRP */ if (alg_k & SSL_kGOST) - { + { + int ret = 0; EVP_PKEY_CTX *pkey_ctx; - unsigned char premaster_secret[32]; - size_t outlen; - - /* Get our certificate privatec key*/ - pkey_ctx = EVP_PKEY_CTX_new(s->cert->key->privatekey,NULL); + EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; + unsigned char premaster_secret[32], *start; + size_t outlen=32, inlen; + unsigned long alg_a; + + /* Get our certificate private key*/ + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + if (alg_a & SSL_aGOST94) + pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey; + else if (alg_a & SSL_aGOST01) + pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; + + pkey_ctx = EVP_PKEY_CTX_new(pk,NULL); EVP_PKEY_decrypt_init(pkey_ctx); + /* If client certificate is present and is of the same type, maybe + * use it for key exchange. Don't mind errors from + * EVP_PKEY_derive_set_peer, because it is completely valid to use + * a client certificate for authorization only. */ + client_pub_pkey = X509_get_pubkey(s->session->peer); + if (client_pub_pkey) + { + if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) + ERR_clear_error(); + } /* Decrypt session key */ - if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED)) || p[1]!=0x81 ) + if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); - goto err; - } - if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,p+3,p[2]) <0) + goto gerr; + } + if (p[1] == 0x81) + { + start = p+3; + inlen = p[2]; + } + else if (p[1] < 0x80) + { + start = p+2; + inlen = p[1]; + } + else + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); + goto gerr; + } + if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); - goto err; + goto gerr; } /* Generate master secret */ - EVP_PKEY_CTX_free(pkey_ctx); s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key,premaster_secret,32); - - } + /* Check if pubkey from client certificate was used */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) + ret = 2; + else + ret = 1; + gerr: + EVP_PKEY_free(client_pub_pkey); + EVP_PKEY_CTX_free(pkey_ctx); + if (ret) + return ret; + else + goto err; + } else { al=SSL_AD_HANDSHAKE_FAILURE; @@ -2534,7 +2955,7 @@ int ssl3_get_client_key_exchange(SSL *s) return(1); f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP) err: #endif #ifndef OPENSSL_NO_ECDH @@ -2555,12 +2976,15 @@ int ssl3_get_cert_verify(SSL *s) long n; int type=0,i,j; X509 *peer; + const EVP_MD *md = NULL; + EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); n=s->method->ssl_get_message(s, SSL3_ST_SR_CERT_VRFY_A, SSL3_ST_SR_CERT_VRFY_B, -1, - 514, /* 514? */ + 516, /* Enough for 4096 bit RSA key with TLS v1.2 */ &ok); if (!ok) return((int)n); @@ -2580,7 +3004,7 @@ int ssl3_get_cert_verify(SSL *s) if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY) { s->s3->tmp.reuse_message=1; - if ((peer != NULL) && (type | EVP_PKT_SIGN)) + if ((peer != NULL) && (type & EVP_PKT_SIGN)) { al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE); @@ -2623,6 +3047,25 @@ int ssl3_get_cert_verify(SSL *s) } else { + if (SSL_USE_SIGALGS(s)) + { + int rv = tls12_check_peer_sigalg(&md, s, p, pkey); + if (rv == -1) + { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + else if (rv == 0) + { + al = SSL_AD_DECODE_ERROR; + goto f_err; + } +#ifdef SSL_DEBUG +fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); +#endif + p += 2; + n -= 2; + } n2s(p,i); n-=2; if (i > n) @@ -2640,6 +3083,37 @@ int ssl3_get_cert_verify(SSL *s) goto f_err; } + if (SSL_USE_SIGALGS(s)) + { + long hdatalen = 0; + void *hdata; + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) + { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); + al=SSL_AD_INTERNAL_ERROR; + goto f_err; + } +#ifdef SSL_DEBUG + fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n", + EVP_MD_name(md)); +#endif + if (!EVP_VerifyInit_ex(&mctx, md, NULL) + || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) + { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_EVP_LIB); + al=SSL_AD_INTERNAL_ERROR; + goto f_err; + } + + if (EVP_VerifyFinal(&mctx, p , i, pkey) <= 0) + { + al=SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_SIGNATURE); + goto f_err; + } + } + else #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) { @@ -2730,6 +3204,13 @@ f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); } end: + if (s->s3->handshake_buffer) + { + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE; + } + EVP_MD_CTX_cleanup(&mctx); EVP_PKEY_free(pkey); return(ret); } @@ -2842,6 +3323,12 @@ int ssl3_get_client_certificate(SSL *s) al=SSL_AD_HANDSHAKE_FAILURE; goto f_err; } + /* No client certificate so digest cached records */ + if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s)) + { + al=SSL_AD_INTERNAL_ERROR; + goto f_err; + } } else { @@ -2849,7 +3336,7 @@ int ssl3_get_client_certificate(SSL *s) if (i <= 0) { al=ssl_verify_alarm_type(s->verify_result); - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED); + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED); goto f_err; } } @@ -2892,13 +3379,12 @@ err: int ssl3_send_server_certificate(SSL *s) { - unsigned long l; - X509 *x; + CERT_PKEY *cpk; if (s->state == SSL3_ST_SW_CERT_A) { - x=ssl_get_server_send_cert(s); - if (x == NULL) + cpk=ssl_get_server_send_pkey(s); + if (cpk == NULL) { /* VRS: allow null cert if auth == KRB5 */ if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) || @@ -2909,66 +3395,85 @@ int ssl3_send_server_certificate(SSL *s) } } - l=ssl3_output_cert_chain(s,x); + ssl3_output_cert_chain(s,cpk); s->state=SSL3_ST_SW_CERT_B; - s->init_num=(int)l; - s->init_off=0; } /* SSL3_ST_SW_CERT_B */ - return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); + return ssl_do_write(s); } + #ifndef OPENSSL_NO_TLSEXT +/* send a new session ticket (not necessarily for a new session) */ int ssl3_send_newsession_ticket(SSL *s) { if (s->state == SSL3_ST_SW_SESSION_TICKET_A) { unsigned char *p, *senc, *macstart; - int len, slen; + const unsigned char *const_p; + int len, slen_full, slen; + SSL_SESSION *sess; unsigned int hlen; EVP_CIPHER_CTX ctx; HMAC_CTX hctx; + SSL_CTX *tctx = s->initial_ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char key_name[16]; /* get session encoding length */ - slen = i2d_SSL_SESSION(s->session, NULL); + slen_full = i2d_SSL_SESSION(s->session, NULL); /* Some length values are 16 bits, so forget it if session is * too long */ - if (slen > 0xFF00) + if (slen_full > 0xFF00) + return -1; + senc = OPENSSL_malloc(slen_full); + if (!senc) return -1; + p = senc; + i2d_SSL_SESSION(s->session, &p); + + /* create a fresh copy (not shared with other threads) to clean up */ + const_p = senc; + sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); + if (sess == NULL) + { + OPENSSL_free(senc); + return -1; + } + sess->session_id_length = 0; /* ID is irrelevant for the ticket */ + + slen = i2d_SSL_SESSION(sess, NULL); + if (slen > slen_full) /* shouldn't ever happen */ + { + OPENSSL_free(senc); + return -1; + } + p = senc; + i2d_SSL_SESSION(sess, &p); + SSL_SESSION_free(sess); + /* Grow buffer if need be: the length calculation is as - * follows 1 (size of message name) + 3 (message length - * bytes) + 4 (ticket lifetime hint) + 2 (ticket length) + + * follows handshake_header_length + + * 4 (ticket lifetime hint) + 2 (ticket length) + * 16 (key name) + max_iv_len (iv length) + * session_length + max_enc_block_size (max encrypted session * length) + max_md_size (HMAC). */ if (!BUF_MEM_grow(s->init_buf, - 26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + - EVP_MAX_MD_SIZE + slen)) + SSL_HM_HEADER_LENGTH(s) + 22 + EVP_MAX_IV_LENGTH + + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen)) return -1; - senc = OPENSSL_malloc(slen); - if (!senc) - return -1; - p = senc; - i2d_SSL_SESSION(s->session, &p); - - p=(unsigned char *)s->init_buf->data; - /* do the header */ - *(p++)=SSL3_MT_NEWSESSION_TICKET; - /* Skip message length for now */ - p += 3; + p = ssl_handshake_start(s); EVP_CIPHER_CTX_init(&ctx); HMAC_CTX_init(&hctx); /* Initialize HMAC and cipher contexts. If callback present * it does all the work otherwise use generated values * from parent ctx. */ - if (s->ctx->tlsext_ticket_key_cb) + if (tctx->tlsext_ticket_key_cb) { - if (s->ctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, + if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, &hctx, 1) < 0) { OPENSSL_free(senc); @@ -2979,12 +3484,18 @@ int ssl3_send_newsession_ticket(SSL *s) { RAND_pseudo_bytes(iv, 16); EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, - s->ctx->tlsext_tick_aes_key, iv); - HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16, + tctx->tlsext_tick_aes_key, iv); + HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(), NULL); - memcpy(key_name, s->ctx->tlsext_tick_key_name, 16); + memcpy(key_name, tctx->tlsext_tick_key_name, 16); } - l2n(s->session->tlsext_tick_lifetime_hint, p); + + /* Ticket lifetime hint (advisory only): + * We leave this unspecified for resumed session (for simplicity), + * and guess that tickets for new sessions will live as long + * as their sessions. */ + l2n(s->hit ? 0 : s->session->timeout, p); + /* Skip ticket length for now */ p += 2; /* Output key name */ @@ -3008,21 +3519,17 @@ int ssl3_send_newsession_ticket(SSL *s) p += hlen; /* Now write out lengths: p points to end of data written */ /* Total length */ - len = p - (unsigned char *)s->init_buf->data; - p=(unsigned char *)s->init_buf->data + 1; - l2n3(len - 4, p); /* Message length */ - p += 4; - s2n(len - 10, p); /* Ticket length */ - - /* number of bytes to write */ - s->init_num= len; + len = p - ssl_handshake_start(s); + ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len); + /* Skip ticket lifetime hint */ + p = ssl_handshake_start(s) + 4; + s2n(len - 6, p); s->state=SSL3_ST_SW_SESSION_TICKET_B; - s->init_off=0; OPENSSL_free(senc); } /* SSL3_ST_SW_SESSION_TICKET_B */ - return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); + return ssl_do_write(s); } int ssl3_send_cert_status(SSL *s) @@ -3059,4 +3566,167 @@ int ssl3_send_cert_status(SSL *s) /* SSL3_ST_SW_CERT_STATUS_B */ return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It + * sets the next_proto member in s if found */ +int ssl3_get_next_proto(SSL *s) + { + int ok; + int proto_len, padding_len; + long n; + const unsigned char *p; + + /* Clients cannot send a NextProtocol message if we didn't see the + * extension in their ClientHello */ + if (!s->s3->next_proto_neg_seen) + { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); + return -1; + } + + n=s->method->ssl_get_message(s, + SSL3_ST_SR_NEXT_PROTO_A, + SSL3_ST_SR_NEXT_PROTO_B, + SSL3_MT_NEXT_PROTO, + 514, /* See the payload format below */ + &ok); + + if (!ok) + return((int)n); + + /* s->state doesn't reflect whether ChangeCipherSpec has been received + * in this handshake, but s->s3->change_cipher_spec does (will be reset + * by ssl3_get_finished). */ + if (!s->s3->change_cipher_spec) + { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); + return -1; + } + + if (n < 2) + return 0; /* The body must be > 1 bytes long */ + + p=(unsigned char *)s->init_msg; + + /* The payload looks like: + * uint8 proto_len; + * uint8 proto[proto_len]; + * uint8 padding_len; + * uint8 padding[padding_len]; + */ + proto_len = p[0]; + if (proto_len + 2 > s->init_num) + return 0; + padding_len = p[proto_len + 1]; + if (proto_len + padding_len + 2 != s->init_num) + return 0; + + s->next_proto_negotiated = OPENSSL_malloc(proto_len); + if (!s->next_proto_negotiated) + { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(s->next_proto_negotiated, p + 1, proto_len); + s->next_proto_negotiated_len = proto_len; + + return 1; + } +# endif + +int tls1_send_server_supplemental_data(SSL *s) + { + size_t length = 0; + const unsigned char *authz, *orig_authz; + unsigned char *p; + size_t authz_length, i; + + if (s->state != SSL3_ST_SW_SUPPLEMENTAL_DATA_A) + return ssl3_do_write(s, SSL3_RT_HANDSHAKE); + + orig_authz = authz = ssl_get_authz_data(s, &authz_length); + if (authz == NULL) + { + /* This should never occur. */ + return 0; + } + + /* First we walk over the authz data to see how long the handshake + * message will be. */ + for (i = 0; i < authz_length; i++) + { + unsigned short len; + unsigned char type; + + type = *(authz++); + n2s(authz, len); + /* n2s increments authz by 2*/ + i += 2; + + if (memchr(s->s3->tlsext_authz_client_types, + type, + s->s3->tlsext_authz_client_types_len) != NULL) + length += 1 /* authz type */ + 2 /* length */ + len; + + authz += len; + i += len; + } + + length += 1 /* handshake type */ + + 3 /* handshake length */ + + 3 /* supplemental data length */ + + 2 /* supplemental entry type */ + + 2 /* supplemental entry length */; + + if (!BUF_MEM_grow_clean(s->init_buf, length)) + { + SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); + return 0; + } + + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL3_MT_SUPPLEMENTAL_DATA; + /* Handshake length */ + l2n3(length - 4, p); + /* Length of supplemental data */ + l2n3(length - 7, p); + /* Supplemental data type */ + s2n(TLSEXT_SUPPLEMENTALDATATYPE_authz_data, p); + /* Its length */ + s2n(length - 11, p); + + authz = orig_authz; + + /* Walk over the authz again and append the selected elements. */ + for (i = 0; i < authz_length; i++) + { + unsigned short len; + unsigned char type; + + type = *(authz++); + n2s(authz, len); + /* n2s increments authz by 2 */ + i += 2; + + if (memchr(s->s3->tlsext_authz_client_types, + type, + s->s3->tlsext_authz_client_types_len) != NULL) + { + *(p++) = type; + s2n(len, p); + memcpy(p, authz, len); + p += len; + } + + authz += len; + i += len; + } + + s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B; + s->init_num = length; + s->init_off = 0; + + return ssl3_do_write(s, SSL3_RT_HANDSHAKE); + } #endif