diff options
author | Mike DePaulo <mikedep333@gmail.com> | 2015-01-10 12:26:41 -0500 |
---|---|---|
committer | Mike DePaulo <mikedep333@gmail.com> | 2015-01-10 15:20:57 -0500 |
commit | ee914bf036b78dcbde9bf694794c15482d721028 (patch) | |
tree | 13793fdc02dbf47bd4dd5e93861bccac71d58887 /openssl/ssl/s3_srvr.c | |
parent | faa5026e540d03f858265b2796054d685f687383 (diff) | |
download | vcxsrv-ee914bf036b78dcbde9bf694794c15482d721028.tar.gz vcxsrv-ee914bf036b78dcbde9bf694794c15482d721028.tar.bz2 vcxsrv-ee914bf036b78dcbde9bf694794c15482d721028.zip |
Update openssl to version openssl-1.0.1k
Conflicts:
openssl/Makefile
Diffstat (limited to 'openssl/ssl/s3_srvr.c')
-rw-r--r-- | openssl/ssl/s3_srvr.c | 143 |
1 files changed, 102 insertions, 41 deletions
diff --git a/openssl/ssl/s3_srvr.c b/openssl/ssl/s3_srvr.c index c23d98708..fadca74ec 100644 --- a/openssl/ssl/s3_srvr.c +++ b/openssl/ssl/s3_srvr.c @@ -170,6 +170,7 @@ #endif #include <openssl/md5.h> +#ifndef OPENSSL_NO_SSL3_METHOD static const SSL_METHOD *ssl3_get_server_method(int ver); static const SSL_METHOD *ssl3_get_server_method(int ver) @@ -180,6 +181,12 @@ static const SSL_METHOD *ssl3_get_server_method(int ver) return(NULL); } +IMPLEMENT_ssl3_meth_func(SSLv3_server_method, + ssl3_accept, + ssl_undefined_function, + ssl3_get_server_method) +#endif + #ifndef OPENSSL_NO_SRP static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) { @@ -206,11 +213,6 @@ static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) } #endif -IMPLEMENT_ssl3_meth_func(SSLv3_server_method, - ssl3_accept, - ssl_undefined_function, - ssl3_get_server_method) - int ssl3_accept(SSL *s) { BUF_MEM *buf; @@ -284,6 +286,7 @@ int ssl3_accept(SSL *s) } if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) { + BUF_MEM_free(buf); ret= -1; goto end; } @@ -298,6 +301,9 @@ int ssl3_accept(SSL *s) s->init_num=0; s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE; + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + /* Should have been reset by ssl3_get_finished, too. */ + s->s3->change_cipher_spec = 0; if (s->state != SSL_ST_RENEGOTIATE) { @@ -441,20 +447,11 @@ int ssl3_accept(SSL *s) case SSL3_ST_SW_KEY_EXCH_B: alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - /* clear this, it may get reset by - * send_server_key_exchange */ - if ((s->options & SSL_OP_EPHEMERAL_RSA) -#ifndef OPENSSL_NO_KRB5 - && !(alg_k & SSL_kKRB5) -#endif /* OPENSSL_NO_KRB5 */ - ) - /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key - * even when forbidden by protocol specs - * (handshake may fail as clients are not required to - * be able to handle this) */ - s->s3->tmp.use_rsa_tmp=1; - else - s->s3->tmp.use_rsa_tmp=0; + /* + * clear this, it may get reset by + * send_server_key_exchange + */ + s->s3->tmp.use_rsa_tmp=0; /* only send if a DH key exchange, fortezza or @@ -468,7 +465,7 @@ int ssl3_accept(SSL *s) * server certificate contains the server's * public key for key exchange. */ - if (s->s3->tmp.use_rsa_tmp + if (0 /* PSK: send ServerKeyExchange if PSK identity * hint if provided */ #ifndef OPENSSL_NO_PSK @@ -674,8 +671,14 @@ int ssl3_accept(SSL *s) case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_B: - - s->s3->flags |= SSL3_FLAGS_CCS_OK; + /* + * This *should* be the first time we enable CCS, but be + * extra careful about surrounding code changes. We need + * to set this here because we don't know if we're + * expecting a CertificateVerify or not. + */ + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; /* we should decide if we expected this one */ ret=ssl3_get_cert_verify(s); if (ret <= 0) goto end; @@ -694,6 +697,19 @@ int ssl3_accept(SSL *s) #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) case SSL3_ST_SR_NEXT_PROTO_A: case SSL3_ST_SR_NEXT_PROTO_B: + /* + * Enable CCS for resumed handshakes with NPN. + * In a full handshake with NPN, we end up here through + * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was + * already set. Receiving a CCS clears the flag, so make + * sure not to re-enable it to ban duplicates. + * s->s3->change_cipher_spec is set when a CCS is + * processed in s3_pkt.c, and remains set until + * the client's Finished message is read. + */ + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret=ssl3_get_next_proto(s); if (ret <= 0) goto end; s->init_num = 0; @@ -703,7 +719,18 @@ int ssl3_accept(SSL *s) case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: - s->s3->flags |= SSL3_FLAGS_CCS_OK; + /* + * Enable CCS for resumed handshakes without NPN. + * In a full handshake, we end up here through + * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was + * already set. Receiving a CCS clears the flag, so make + * sure not to re-enable it to ban duplicates. + * s->s3->change_cipher_spec is set when a CCS is + * processed in s3_pkt.c, and remains set until + * the client's Finished message is read. + */ + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); if (ret <= 0) goto end; @@ -775,7 +802,6 @@ int ssl3_accept(SSL *s) #else if (s->s3->next_proto_neg_seen) { - s->s3->flags |= SSL3_FLAGS_CCS_OK; s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A; } else @@ -1017,7 +1043,16 @@ int ssl3_get_client_hello(SSL *s) else { i=ssl_get_prev_session(s, p, j, d + n); - if (i == 1) + /* + * Only resume if the session's version matches the negotiated + * version. + * RFC 5246 does not provide much useful advice on resumption + * with a different protocol version. It doesn't forbid it but + * the sanity of such behaviour would be questionable. + * In practice, clients do not accept a version mismatch and + * will abort the handshake with an error. + */ + if (i == 1 && s->version == s->session->ssl_version) { /* previous session */ s->hit=1; } @@ -1112,14 +1147,15 @@ int ssl3_get_client_hello(SSL *s) id=s->session->cipher->id; #ifdef CIPHER_DEBUG - printf("client sent %d ciphers\n",sk_num(ciphers)); + fprintf(stderr,"client sent %d ciphers\n",sk_SSL_CIPHER_num(ciphers)); #endif for (i=0; i<sk_SSL_CIPHER_num(ciphers); i++) { c=sk_SSL_CIPHER_value(ciphers,i); #ifdef CIPHER_DEBUG - printf("client [%2d of %2d]:%s\n", - i,sk_num(ciphers),SSL_CIPHER_get_name(c)); + fprintf(stderr,"client [%2d of %2d]:%s\n", + i,sk_SSL_CIPHER_num(ciphers), + SSL_CIPHER_get_name(c)); #endif if (c->id == id) { @@ -2171,6 +2207,7 @@ int ssl3_get_client_key_exchange(SSL *s) unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; int decrypt_len; unsigned char decrypt_good, version_good; + size_t j; /* FIX THIS UP EAY EAY EAY EAY */ if (s->s3->tmp.use_rsa_tmp) @@ -2209,8 +2246,9 @@ int ssl3_get_client_key_exchange(SSL *s) { if (!(s->options & SSL_OP_TLS_D5_BUG)) { + al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); - goto err; + goto f_err; } else p-=2; @@ -2219,6 +2257,20 @@ int ssl3_get_client_key_exchange(SSL *s) n=i; } + /* + * Reject overly short RSA ciphertext because we want to be sure + * that the buffer size makes it safe to iterate over the entire + * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The + * actual expected size is larger due to RSA padding, but the + * bound is sufficient to be safe. + */ + if (n < SSL_MAX_MASTER_KEY_LENGTH) + { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + goto f_err; + } + /* We must not leak whether a decryption failure occurs because * of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see * RFC 2246, section 7.4.7.1). The code follows that advice of @@ -2266,19 +2318,23 @@ int ssl3_get_client_key_exchange(SSL *s) * to remain non-zero (0xff). */ decrypt_good &= version_good; - /* Now copy rand_premaster_secret over p using - * decrypt_good_mask. */ - for (i = 0; i < (int) sizeof(rand_premaster_secret); i++) + /* + * Now copy rand_premaster_secret over from p using + * decrypt_good_mask. If decryption failed, then p does not + * contain valid plaintext, however, a check above guarantees + * it is still sufficiently large to read from. + */ + for (j = 0; j < sizeof(rand_premaster_secret); j++) { - p[i] = constant_time_select_8(decrypt_good, p[i], - rand_premaster_secret[i]); + p[j] = constant_time_select_8(decrypt_good, p[j], + rand_premaster_secret[j]); } s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, - p,i); - OPENSSL_cleanse(p,i); + p,sizeof(rand_premaster_secret)); + OPENSSL_cleanse(p,sizeof(rand_premaster_secret)); } else #endif @@ -2420,10 +2476,10 @@ int ssl3_get_client_key_exchange(SSL *s) &kssl_err)) != 0) { #ifdef KSSL_DEBUG - printf("kssl_sget_tkt rtn %d [%d]\n", + fprintf(stderr,"kssl_sget_tkt rtn %d [%d]\n", krb5rc, kssl_err.reason); if (kssl_err.text) - printf("kssl_err text= %s\n", kssl_err.text); + fprintf(stderr,"kssl_err text= %s\n", kssl_err.text); #endif /* KSSL_DEBUG */ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); @@ -2437,10 +2493,10 @@ int ssl3_get_client_key_exchange(SSL *s) &authtime, &kssl_err)) != 0) { #ifdef KSSL_DEBUG - printf("kssl_check_authent rtn %d [%d]\n", + fprintf(stderr,"kssl_check_authent rtn %d [%d]\n", krb5rc, kssl_err.reason); if (kssl_err.text) - printf("kssl_err text= %s\n", kssl_err.text); + fprintf(stderr,"kssl_err text= %s\n", kssl_err.text); #endif /* KSSL_DEBUG */ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); @@ -2958,7 +3014,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) { al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE); @@ -3362,6 +3418,11 @@ int ssl3_send_server_certificate(SSL *s) } l=ssl3_output_cert_chain(s,x); + if (!l) + { + SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR); + return(0); + } s->state=SSL3_ST_SW_CERT_B; s->init_num=(int)l; s->init_off=0; |