diff options
author | Parménides GV <parmegv@sdf.org> | 2014-06-13 13:24:13 +0200 |
---|---|---|
committer | Parménides GV <parmegv@sdf.org> | 2014-06-13 13:24:13 +0200 |
commit | 69b10487fcd63dfe1e94fa97c9f3fd9b035646b4 (patch) | |
tree | d4960893a4444634d404c7fbe4fa3e8778d30179 /app/openssl/ssl/s3_srvr.c | |
parent | 9f6cfff38ae87922adc022300e1e2fd1c0d4c3e4 (diff) | |
parent | e45929e220fe49e30235a1d4d36c1a413547f8bf (diff) |
Merge branch 'develop'
Diffstat (limited to 'app/openssl/ssl/s3_srvr.c')
-rw-r--r-- | app/openssl/ssl/s3_srvr.c | 1127 |
1 files changed, 807 insertions, 320 deletions
diff --git a/app/openssl/ssl/s3_srvr.c b/app/openssl/ssl/s3_srvr.c index 60591622..1976efa7 100644 --- a/app/openssl/ssl/s3_srvr.c +++ b/app/openssl/ssl/s3_srvr.c @@ -157,8 +157,11 @@ #include <openssl/buffer.h> #include <openssl/rand.h> #include <openssl/objects.h> +#include <openssl/ec.h> +#include <openssl/ecdsa.h> #include <openssl/evp.h> #include <openssl/hmac.h> +#include <openssl/sha.h> #include <openssl/x509.h> #ifndef OPENSSL_NO_DH #include <openssl/dh.h> @@ -179,6 +182,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, @@ -188,6 +217,7 @@ int ssl3_accept(SSL *s) { BUF_MEM *buf; unsigned long alg_k,Time=(unsigned long)time(NULL); + unsigned long alg_a; void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; int new_state,state,skip=0; @@ -211,6 +241,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; @@ -218,7 +260,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: @@ -258,6 +300,7 @@ int ssl3_accept(SSL *s) } s->init_num=0; + s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE; if (s->state != SSL_ST_RENEGOTIATE) { @@ -313,10 +356,35 @@ int ssl3_accept(SSL *s) 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; @@ -345,9 +413,11 @@ int ssl3_accept(SSL *s) 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 */ + /* non-RSA PSK or KRB5 or SRP */ if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) + /* Among PSK ciphersuites only RSA_PSK uses server certificate */ + && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK && + !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kRSA)) && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) { ret=ssl3_send_server_certificate(s); @@ -376,6 +446,7 @@ int ssl3_accept(SSL *s) case SSL3_ST_SW_KEY_EXCH_A: case SSL3_ST_SW_KEY_EXCH_B: alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_a = s->s3->tmp.new_cipher->algorithm_auth; /* clear this, it may get reset by * send_server_key_exchange */ @@ -405,10 +476,16 @@ int ssl3_accept(SSL *s) * public key for key exchange. */ if (s->s3->tmp.use_rsa_tmp - /* PSK: send ServerKeyExchange if PSK identity - * hint if provided */ + /* PSK: send ServerKeyExchange if either: + * - PSK identity hint is provided, or + * - the key exchange is kEECDH. + */ #ifndef OPENSSL_NO_PSK - || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) + || ((alg_a & SSL_aPSK) && ((alg_k & SSL_kEECDH) || s->session->psk_identity_hint)) +#endif +#ifndef OPENSSL_NO_SRP + /* SRP: send ServerKeyExchange */ + || (alg_k & SSL_kSRP) #endif || (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH)) || (alg_k & SSL_kEECDH) @@ -456,6 +533,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 { @@ -538,15 +618,26 @@ int ssl3_accept(SSL *s) * 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; + s->state=SSL3_ST_SR_POST_CLIENT_CERT; + } + else if (TLS1_get_version(s) >= TLS1_2_VERSION) + { + s->state=SSL3_ST_SR_CERT_VRFY_A; + s->init_num=0; + if (!s->session->peer) + break; + /* For TLS v1.2 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 { @@ -585,19 +676,33 @@ int ssl3_accept(SSL *s) case SSL3_ST_SR_CERT_VRFY_B: /* we should decide if we expected this one */ + s->s3->flags |= SSL3_FLAGS_CCS_OK; 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_POST_CLIENT_CERT; + s->init_num=0; + break; + + case SSL3_ST_SR_POST_CLIENT_CERT: { + char next_proto_neg = 0; + char channel_id = 0; +#if !defined(OPENSSL_NO_TLSEXT) +# if !defined(OPENSSL_NO_NEXTPROTONEG) + next_proto_neg = s->s3->next_proto_neg_seen; +# endif + channel_id = s->s3->tlsext_channel_id_valid; +#endif + + s->s3->flags |= SSL3_FLAGS_CCS_OK; + if (next_proto_neg) s->state=SSL3_ST_SR_NEXT_PROTO_A; + else if (channel_id) + s->state=SSL3_ST_SR_CHANNEL_ID_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: @@ -605,6 +710,19 @@ int ssl3_accept(SSL *s) ret=ssl3_get_next_proto(s); if (ret <= 0) goto end; s->init_num = 0; + if (s->s3->tlsext_channel_id_valid) + s->state=SSL3_ST_SR_CHANNEL_ID_A; + else + s->state=SSL3_ST_SR_FINISHED_A; + break; +#endif + +#if !defined(OPENSSL_NO_TLSEXT) + case SSL3_ST_SR_CHANNEL_ID_A: + case SSL3_ST_SR_CHANNEL_ID_B: + ret=ssl3_get_channel_id(s); + if (ret <= 0) goto end; + s->init_num = 0; s->state=SSL3_ST_SR_FINISHED_A; break; #endif @@ -614,14 +732,11 @@ int ssl3_accept(SSL *s) 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; @@ -679,16 +794,7 @@ 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 - } + s->s3->tmp.next_state=SSL3_ST_SR_POST_CLIENT_CERT; else s->s3->tmp.next_state=SSL_ST_OK; s->init_num=0; @@ -706,11 +812,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); @@ -800,6 +904,13 @@ 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.) */ #ifndef OPENSSL_NO_DH @@ -816,6 +927,7 @@ int ssl3_check_client_hello(SSL *s) s->s3->tmp.ecdh = NULL; } #endif + s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE; return 2; } return 1; @@ -840,7 +952,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; } @@ -865,7 +978,8 @@ int ssl3_get_client_hello(SSL *s) (s->version != DTLS1_VERSION && 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) + if ((s->client_version>>8) == SSL3_VERSION_MAJOR && + !s->enc_write_ctx && !s->write_hash) { /* similar to ssl3_get_record, send alert using remote version number */ s->version = s->client_version; @@ -897,13 +1011,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))) { @@ -1099,7 +1216,7 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } } - if (ssl_check_clienthello_tlsext(s) <= 0) { + if (ssl_check_clienthello_tlsext_early(s) <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); goto err; } @@ -1109,12 +1226,9 @@ int ssl3_get_client_hello(SSL *s) * server_random before calling tls_session_secret_cb in order to allow * SessionTicket processing to use it in key derivation. */ { - unsigned long Time; unsigned char *pos; - Time=(unsigned long)time(NULL); /* Time */ pos=s->s3->server_random; - l2n(Time,pos); - if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0) + if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0) { al=SSL_AD_INTERNAL_ERROR; goto f_err; @@ -1304,8 +1418,14 @@ 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 (TLS1_get_version(s) < TLS1_2_VERSION || !(s->verify_mode & SSL_VERIFY_PEER)) + { + if (!ssl3_digest_cached_records(s)) + { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } /* we now have the following setup. * client_random @@ -1318,6 +1438,16 @@ int ssl3_get_client_hello(SSL *s) * s->tmp.new_cipher - the new cipher to use. */ + /* 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) { @@ -1335,19 +1465,13 @@ int ssl3_send_server_hello(SSL *s) unsigned char *p,*d; int i,sl; unsigned long l; -#ifdef OPENSSL_NO_TLSEXT - unsigned long Time; -#endif if (s->state == SSL3_ST_SW_SRVR_HELLO_A) { buf=(unsigned char *)s->init_buf->data; #ifdef OPENSSL_NO_TLSEXT p=s->s3->server_random; - /* Generate server_random if it was not needed previously */ - Time=(unsigned long)time(NULL); /* Time */ - l2n(Time,p); - if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) + if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0) return -1; #endif /* Do the message type and length last */ @@ -1360,20 +1484,20 @@ 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) @@ -1473,10 +1597,16 @@ int ssl3_send_server_key_exchange(SSL *s) int curve_id = 0; BN_CTX *bn_ctx = NULL; #endif +#ifndef OPENSSL_NO_PSK + const char* psk_identity_hint; + size_t psk_identity_hint_len; +#endif EVP_PKEY *pkey; + const EVP_MD *md = NULL; unsigned char *p,*d; int al,i; - unsigned long type; + unsigned long alg_k; + unsigned long alg_a; int n; CERT *cert; BIGNUM *r[4]; @@ -1487,15 +1617,28 @@ int ssl3_send_server_key_exchange(SSL *s) EVP_MD_CTX_init(&md_ctx); if (s->state == SSL3_ST_SW_KEY_EXCH_A) { - type=s->s3->tmp.new_cipher->algorithm_mkey; + alg_k=s->s3->tmp.new_cipher->algorithm_mkey; + alg_a=s->s3->tmp.new_cipher->algorithm_auth; cert=s->cert; buf=s->init_buf; r[0]=r[1]=r[2]=r[3]=NULL; n=0; +#ifndef OPENSSL_NO_PSK + if (alg_a & SSL_aPSK) + { + /* size for PSK identity hint */ + psk_identity_hint = s->session->psk_identity_hint; + if (psk_identity_hint) + psk_identity_hint_len = strlen(psk_identity_hint); + else + psk_identity_hint_len = 0; + n+=2+psk_identity_hint_len; + } +#endif /* !OPENSSL_NO_PSK */ #ifndef OPENSSL_NO_RSA - if (type & SSL_kRSA) + if (alg_k & SSL_kRSA) { rsa=cert->rsa_tmp; if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) @@ -1522,10 +1665,9 @@ int ssl3_send_server_key_exchange(SSL *s) r[1]=rsa->e; s->s3->tmp.use_rsa_tmp=1; } - else #endif #ifndef OPENSSL_NO_DH - if (type & SSL_kEDH) + else if (alg_k & SSL_kEDH) { dhp=cert->dh_tmp; if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) @@ -1578,10 +1720,9 @@ int ssl3_send_server_key_exchange(SSL *s) r[1]=dh->g; r[2]=dh->pub_key; } - else #endif #ifndef OPENSSL_NO_ECDH - if (type & SSL_kEECDH) + else if (alg_k & SSL_kEECDH) { const EC_GROUP *group; @@ -1694,7 +1835,7 @@ int ssl3_send_server_key_exchange(SSL *s) * to encode the entire ServerECDHParams * structure. */ - n = 4 + encodedlen; + n += 4 + encodedlen; /* We'll generate the serverKeyExchange message * explicitly so we can set these to NULLs @@ -1704,31 +1845,46 @@ int ssl3_send_server_key_exchange(SSL *s) r[2]=NULL; r[3]=NULL; } - else #endif /* !OPENSSL_NO_ECDH */ -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) +#ifndef OPENSSL_NO_SRP + else if (alg_k & SSL_kSRP) + { + if ((s->srp_ctx.N == NULL) || + (s->srp_ctx.g == NULL) || + (s->srp_ctx.s == NULL) || + (s->srp_ctx.B == NULL)) { - /* reserve size for record length and PSK identity hint*/ - n+=2+strlen(s->ctx->psk_identity_hint); + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_SRP_PARAM); + goto err; } - else -#endif /* !OPENSSL_NO_PSK */ + r[0]=s->srp_ctx.N; + r[1]=s->srp_ctx.g; + r[2]=s->srp_ctx.s; + r[3]=s->srp_ctx.B; + } +#endif + else if (!(alg_k & SSL_kPSK)) { 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; i < 4 && r[i] != NULL; i++) { nr[i]=BN_num_bytes(r[i]); +#ifndef OPENSSL_NO_SRP + if ((i == 2) && (alg_k & 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 (!(alg_a & SSL_aNULL) + /* Among PSK ciphersuites only RSA uses a certificate */ + && !((alg_a & SSL_aPSK) && !(alg_k & SSL_kRSA))) { - 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; @@ -1750,15 +1906,39 @@ int ssl3_send_server_key_exchange(SSL *s) d=(unsigned char *)s->init_buf->data; p= &(d[4]); - for (i=0; r[i] != NULL; i++) + for (i=0; i < 4 && r[i] != NULL; i++) { +#ifndef OPENSSL_NO_SRP + if ((i == 2) && (alg_k & SSL_kSRP)) + { + *p = nr[i]; + p++; + } + else +#endif s2n(nr[i],p); BN_bn2bin(r[i],p); p+=nr[i]; } +/* Note: ECDHE PSK ciphersuites use SSL_kEECDH and SSL_aPSK. + * When one of them is used, the server key exchange record needs to have both + * the psk_identity_hint and the ServerECDHParams. */ +#ifndef OPENSSL_NO_PSK + if (alg_a & SSL_aPSK) + { + /* copy PSK identity hint (if provided) */ + s2n(psk_identity_hint_len, p); + if (psk_identity_hint_len > 0) + { + memcpy(p, psk_identity_hint, psk_identity_hint_len); + p+=psk_identity_hint_len; + } + } +#endif /* OPENSSL_NO_PSK */ + #ifndef OPENSSL_NO_ECDH - if (type & SSL_kEECDH) + if (alg_k & SSL_kEECDH) { /* XXX: For now, we only support named (not generic) curves. * In this situation, the serverKeyExchange message has: @@ -1781,17 +1961,7 @@ int ssl3_send_server_key_exchange(SSL *s) encodedPoint = NULL; p += encodedlen; } -#endif - -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) - { - /* copy PSK identity hint */ - s2n(strlen(s->ctx->psk_identity_hint), p); - strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint)); - p+=strlen(s->ctx->psk_identity_hint); - } -#endif +#endif /* OPENSSL_NO_ECDH */ /* not anonymous */ if (pkey != NULL) @@ -1799,12 +1969,15 @@ 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 + && TLS1_get_version(s) < TLS1_2_VERSION) { 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); @@ -1825,45 +1998,42 @@ int ssl3_send_server_key_exchange(SSL *s) n+=u+2; } else -#endif -#if !defined(OPENSSL_NO_DSA) - if (pkey->type == EVP_PKEY_DSA) +#endif /* OPENSSL_NO_RSA */ + 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)) + /* For TLS1.2 and later send signature + * algorithm */ + if (TLS1_get_version(s) >= TLS1_2_VERSION) { - 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); 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 (TLS1_get_version(s) >= TLS1_2_VERSION) + n+= 2; } else -#endif { /* Is this error check actually needed? */ al=SSL_AD_HANDSHAKE_FAILURE; @@ -1916,6 +2086,14 @@ int ssl3_send_certificate_request(SSL *s) p+=n; n++; + if (TLS1_get_version(s) >= TLS1_2_VERSION) + { + nl = tls12_get_req_sig_algs(s, p + 2); + s2n(nl, p); + p += nl + 2; + n += nl + 2; + } + off=n; p+=2; n+=2; @@ -1989,6 +2167,7 @@ int ssl3_get_client_key_exchange(SSL *s) int i,al,ok; long n; unsigned long alg_k; + unsigned long alg_a; unsigned char *p; #ifndef OPENSSL_NO_RSA RSA *rsa=NULL; @@ -2006,7 +2185,11 @@ int ssl3_get_client_key_exchange(SSL *s) EC_KEY *srvr_ecdh = NULL; EVP_PKEY *clnt_pub_pkey = NULL; EC_POINT *clnt_ecpoint = NULL; - BN_CTX *bn_ctx = NULL; + BN_CTX *bn_ctx = NULL; +#ifndef OPENSSL_NO_PSK + unsigned int psk_len = 0; + unsigned char psk[PSK_MAX_PSK_LEN]; +#endif /* OPENSSL_NO_PSK */ #endif n=s->method->ssl_get_message(s, @@ -2020,7 +2203,95 @@ int ssl3_get_client_key_exchange(SSL *s) p=(unsigned char *)s->init_msg; alg_k=s->s3->tmp.new_cipher->algorithm_mkey; + alg_a=s->s3->tmp.new_cipher->algorithm_auth; + +#ifndef OPENSSL_NO_PSK + if (alg_a & SSL_aPSK) + { + unsigned char *t = NULL; + unsigned char pre_ms[PSK_MAX_PSK_LEN*2+4]; + unsigned int pre_ms_len = 0; + int psk_err = 1; + char tmp_id[PSK_MAX_IDENTITY_LEN+1]; + + al=SSL_AD_HANDSHAKE_FAILURE; + n2s(p, i); + if (n != i+2 && !(alg_k & SSL_kEECDH)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_LENGTH_MISMATCH); + goto psk_err; + } + if (i > PSK_MAX_IDENTITY_LEN) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto psk_err; + } + if (s->psk_server_callback == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_NO_SERVER_CB); + goto psk_err; + } + + /* Create guaranteed NUL-terminated identity + * string for the callback */ + memcpy(tmp_id, p, i); + memset(tmp_id+i, 0, PSK_MAX_IDENTITY_LEN+1-i); + psk_len = s->psk_server_callback(s, tmp_id, psk, sizeof(psk)); + + if (psk_len > PSK_MAX_PSK_LEN) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto psk_err; + } + else if (psk_len == 0) + { + /* PSK related to the given identity not found */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + al=SSL_AD_UNKNOWN_PSK_IDENTITY; + goto psk_err; + } + if (!(alg_k & SSL_kEECDH)) + { + /* Create the shared secret now if we're not using ECDHE-PSK.*/ + pre_ms_len=2+psk_len+2+psk_len; + t = pre_ms; + s2n(psk_len, t); + memset(t, 0, psk_len); + t+=psk_len; + s2n(psk_len, t); + memcpy(t, psk, psk_len); + + s->session->master_key_length= + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, pre_ms, pre_ms_len); + } + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); + s->session->psk_identity = BUF_strdup(tmp_id); + OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN+1); + if (s->session->psk_identity == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + p += i; + n -= (i + 2); + psk_err = 0; + psk_err: + OPENSSL_cleanse(pre_ms, sizeof(pre_ms)); + if (psk_err != 0) + goto f_err; + } +#endif /* OPENSSL_NO_PSK */ + if (0) {} #ifndef OPENSSL_NO_RSA if (alg_k & SSL_kRSA) { @@ -2125,10 +2396,9 @@ int ssl3_get_client_key_exchange(SSL *s) p,i); OPENSSL_cleanse(p,i); } - else #endif #ifndef OPENSSL_NO_DH - if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) + else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { n2s(p,i); if (n != i+2) @@ -2175,6 +2445,7 @@ 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; } @@ -2188,10 +2459,9 @@ int ssl3_get_client_key_exchange(SSL *s) s->session->master_key,p,i); OPENSSL_cleanse(p,i); } - else #endif #ifndef OPENSSL_NO_KRB5 - if (alg_k & SSL_kKRB5) + else if (alg_k & SSL_kKRB5) { krb5_error_code krb5rc; krb5_data enc_ticket; @@ -2380,17 +2650,20 @@ int ssl3_get_client_key_exchange(SSL *s) ** if (s->kssl_ctx) s->kssl_ctx = NULL; */ } - else #endif /* OPENSSL_NO_KRB5 */ - #ifndef OPENSSL_NO_ECDH - if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) + else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) { int ret = 1; int field_size = 0; const EC_KEY *tkey; const EC_GROUP *group; const BIGNUM *priv_key; +#ifndef OPENSSL_NO_PSK + unsigned char *pre_ms; + unsigned int pre_ms_len; + unsigned char *t; +#endif /* OPENSSL_NO_PSK */ /* initialize structures for server's ECDH key pair */ if ((srvr_ecdh = EC_KEY_new()) == NULL) @@ -2486,7 +2759,7 @@ int ssl3_get_client_key_exchange(SSL *s) } /* Get encoded point length */ - i = *p; + i = *p; p += 1; if (n != 1 + i) { @@ -2528,185 +2801,155 @@ int ssl3_get_client_key_exchange(SSL *s) EC_KEY_free(srvr_ecdh); BN_CTX_free(bn_ctx); EC_KEY_free(s->s3->tmp.ecdh); - s->s3->tmp.ecdh = NULL; + s->s3->tmp.ecdh = NULL; - /* Compute the master secret */ - s->session->master_key_length = s->method->ssl3_enc-> \ - generate_master_secret(s, s->session->master_key, p, i); - - OPENSSL_cleanse(p, i); - return (ret); - } - else -#endif #ifndef OPENSSL_NO_PSK - if (alg_k & SSL_kPSK) + /* ECDHE PSK ciphersuites from RFC 5489 */ + if ((alg_a & SSL_aPSK) && psk_len != 0) { - unsigned char *t = NULL; - unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4]; - unsigned int pre_ms_len = 0, psk_len = 0; - int psk_err = 1; - char tmp_id[PSK_MAX_IDENTITY_LEN+1]; - - al=SSL_AD_HANDSHAKE_FAILURE; - - n2s(p,i); - if (n != i+2) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_LENGTH_MISMATCH); - goto psk_err; - } - if (i > PSK_MAX_IDENTITY_LEN) + pre_ms_len = 2+psk_len+2+i; + pre_ms = OPENSSL_malloc(pre_ms_len); + if (pre_ms == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto psk_err; - } - if (s->psk_server_callback == NULL) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_NO_SERVER_CB); - goto psk_err; + ERR_R_MALLOC_FAILURE); + goto err; } + memset(pre_ms, 0, pre_ms_len); + t = pre_ms; + s2n(psk_len, t); + memcpy(t, psk, psk_len); + t += psk_len; + s2n(i, t); + memcpy(t, p, i); + s->session->master_key_length = s->method->ssl3_enc \ + -> generate_master_secret(s, + s->session->master_key, pre_ms, pre_ms_len); + OPENSSL_cleanse(pre_ms, pre_ms_len); + OPENSSL_free(pre_ms); + } +#endif /* OPENSSL_NO_PSK */ + if (!(alg_a & SSL_aPSK)) + { + /* Compute the master secret */ + s->session->master_key_length = s->method->ssl3_enc \ + -> generate_master_secret(s, + s->session->master_key, p, i); + } - /* Create guaranteed NULL-terminated identity - * string for the callback */ - memcpy(tmp_id, p, i); - memset(tmp_id+i, 0, PSK_MAX_IDENTITY_LEN+1-i); - psk_len = s->psk_server_callback(s, tmp_id, - psk_or_pre_ms, sizeof(psk_or_pre_ms)); - OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN+1); + OPENSSL_cleanse(p, i); + } +#endif +#ifndef OPENSSL_NO_SRP + else if (alg_k & SSL_kSRP) + { + int param_len; - if (psk_len > PSK_MAX_PSK_LEN) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto psk_err; - } - else if (psk_len == 0) - { - /* PSK related to the given identity not found */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_IDENTITY_NOT_FOUND); - al=SSL_AD_UNKNOWN_PSK_IDENTITY; - goto psk_err; - } + 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; + } - /* create PSK pre_master_secret */ - pre_ms_len=2+psk_len+2+psk_len; - t = psk_or_pre_ms; - memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len); - s2n(psk_len, t); - memset(t, 0, psk_len); - t+=psk_len; - s2n(psk_len, t); + 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; + } - if (s->session->psk_identity != NULL) - OPENSSL_free(s->session->psk_identity); - s->session->psk_identity = BUF_strdup((char *)p); - if (s->session->psk_identity == NULL) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto psk_err; - } + p+=i; + } +#endif /* OPENSSL_NO_SRP */ + else if (alg_k & SSL_kGOST) + { + int ret = 0; + EVP_PKEY_CTX *pkey_ctx; + EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; + unsigned char premaster_secret[32], *start; + size_t outlen=32, inlen; + unsigned long alg_a; - if (s->session->psk_identity_hint != NULL) - OPENSSL_free(s->session->psk_identity_hint); - s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); - if (s->ctx->psk_identity_hint != NULL && - s->session->psk_identity_hint == NULL) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto psk_err; - } + /* 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; - s->session->master_key_length= - s->method->ssl3_enc->generate_master_secret(s, - s->session->master_key, psk_or_pre_ms, pre_ms_len); - psk_err = 0; - psk_err: - OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); - if (psk_err != 0) - goto f_err; + 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))) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); + goto gerr; + } + if (p[1] == 0x81) + { + start = p+3; + inlen = p[2]; + } + else if (p[1] < 0x80) + { + start = p+2; + inlen = p[1]; } else -#endif - if (alg_k & SSL_kGOST) { - int ret = 0; - EVP_PKEY_CTX *pkey_ctx; - 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))) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); - 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 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 gerr; - } - /* Generate master secret */ - 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; + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); + goto gerr; } + /* Generate master secret */ + 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 if (!(alg_k & SSL_kPSK)) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, @@ -2717,7 +2960,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 @@ -2738,12 +2981,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); @@ -2763,7 +3009,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); @@ -2806,6 +3052,36 @@ int ssl3_get_cert_verify(SSL *s) } else { + if (TLS1_get_version(s) >= TLS1_2_VERSION) + { + int sigalg = tls12_get_sigid(pkey); + /* Should never happen */ + if (sigalg == -1) + { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR); + al=SSL_AD_INTERNAL_ERROR; + goto f_err; + } + /* Check key type is consistent with signature */ + if (sigalg != (int)p[1]) + { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_WRONG_SIGNATURE_TYPE); + al=SSL_AD_DECODE_ERROR; + goto f_err; + } + md = tls12_get_hash(p[0]); + if (md == NULL) + { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_UNKNOWN_DIGEST); + 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) @@ -2823,6 +3099,37 @@ int ssl3_get_cert_verify(SSL *s) goto f_err; } + if (TLS1_get_version(s) >= TLS1_2_VERSION) + { + 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) { @@ -2913,6 +3220,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); } @@ -3025,6 +3339,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 { @@ -3101,13 +3421,17 @@ int ssl3_send_server_certificate(SSL *s) /* SSL3_ST_SW_CERT_B */ return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } + #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; @@ -3116,12 +3440,38 @@ int ssl3_send_newsession_ticket(SSL *s) 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) + @@ -3133,11 +3483,6 @@ int ssl3_send_newsession_ticket(SSL *s) 26 + 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 */ @@ -3168,7 +3513,13 @@ int ssl3_send_newsession_ticket(SSL *s) tlsext_tick_md(), NULL); 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 */ @@ -3244,13 +3595,13 @@ int ssl3_send_cert_status(SSL *s) return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } -# ifndef OPENSSL_NO_NPN +# 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; - unsigned proto_len, padding_len; + int proto_len, padding_len; long n; const unsigned char *p; @@ -3311,4 +3662,140 @@ int ssl3_get_next_proto(SSL *s) return 1; } # endif + +/* ssl3_get_channel_id reads and verifies a ClientID handshake message. */ +int ssl3_get_channel_id(SSL *s) + { + int ret = -1, ok; + long n; + const unsigned char *p; + unsigned short extension_type, extension_len; + EC_GROUP* p256 = NULL; + EC_KEY* key = NULL; + EC_POINT* point = NULL; + ECDSA_SIG sig; + BIGNUM x, y; + + if (s->state == SSL3_ST_SR_CHANNEL_ID_A && s->init_num == 0) + { + /* The first time that we're called we take the current + * handshake hash and store it. */ + EVP_MD_CTX md_ctx; + unsigned int len; + + EVP_MD_CTX_init(&md_ctx); + EVP_DigestInit_ex(&md_ctx, EVP_sha256(), NULL); + if (!tls1_channel_id_hash(&md_ctx, s)) + return -1; + len = sizeof(s->s3->tlsext_channel_id); + EVP_DigestFinal(&md_ctx, s->s3->tlsext_channel_id, &len); + EVP_MD_CTX_cleanup(&md_ctx); + } + + n = s->method->ssl_get_message(s, + SSL3_ST_SR_CHANNEL_ID_A, + SSL3_ST_SR_CHANNEL_ID_B, + SSL3_MT_ENCRYPTED_EXTENSIONS, + 2 + 2 + TLSEXT_CHANNEL_ID_SIZE, + &ok); + + if (!ok) + return((int)n); + + ssl3_finish_mac(s, (unsigned char*)s->init_buf->data, s->init_num + 4); + + /* 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_CHANNEL_ID,SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS); + return -1; + } + + if (n != 2 + 2 + TLSEXT_CHANNEL_ID_SIZE) + { + SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_INVALID_MESSAGE); + return -1; + } + + p = (unsigned char *)s->init_msg; + + /* The payload looks like: + * uint16 extension_type + * uint16 extension_len; + * uint8 x[32]; + * uint8 y[32]; + * uint8 r[32]; + * uint8 s[32]; + */ + n2s(p, extension_type); + n2s(p, extension_len); + + if (extension_type != TLSEXT_TYPE_channel_id || + extension_len != TLSEXT_CHANNEL_ID_SIZE) + { + SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_INVALID_MESSAGE); + return -1; + } + + p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); + if (!p256) + { + SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_NO_P256_SUPPORT); + return -1; + } + + BN_init(&x); + BN_init(&y); + sig.r = BN_new(); + sig.s = BN_new(); + + if (BN_bin2bn(p + 0, 32, &x) == NULL || + BN_bin2bn(p + 32, 32, &y) == NULL || + BN_bin2bn(p + 64, 32, sig.r) == NULL || + BN_bin2bn(p + 96, 32, sig.s) == NULL) + goto err; + + point = EC_POINT_new(p256); + if (!point || + !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL)) + goto err; + + key = EC_KEY_new(); + if (!key || + !EC_KEY_set_group(key, p256) || + !EC_KEY_set_public_key(key, point)) + goto err; + + /* We stored the handshake hash in |tlsext_channel_id| the first time + * that we were called. */ + switch (ECDSA_do_verify(s->s3->tlsext_channel_id, SHA256_DIGEST_LENGTH, &sig, key)) { + case 1: + break; + case 0: + SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_CHANNEL_ID_SIGNATURE_INVALID); + s->s3->tlsext_channel_id_valid = 0; + goto err; + default: + s->s3->tlsext_channel_id_valid = 0; + goto err; + } + + memcpy(s->s3->tlsext_channel_id, p, 64); + ret = 1; + +err: + BN_free(&x); + BN_free(&y); + BN_free(sig.r); + BN_free(sig.s); + if (key) + EC_KEY_free(key); + if (point) + EC_POINT_free(point); + if (p256) + EC_GROUP_free(p256); + return ret; + } #endif |