X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_srvr.c;h=8c5b6e8c9cb658343bb6c90b6dbc7bfbd332d441;hp=0a46e4ab74e4316e7afa6f513ae7f88220d63211;hb=979689aa5cfa100ccbc1f25064e9398be4b7b05c;hpb=bc36ee6227517edae802bcb0da68d4f04fe1fb5e diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 0a46e4ab74..8c5b6e8c9c 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -55,6 +55,59 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ #define REUSE_CIPHER_BUG #define NETSCAPE_HANG_BUG @@ -64,15 +117,12 @@ #include #include #include -#include -#include #include #include +#include #include "ssl_locl.h" - -#ifndef OPENSSL_NO_KRB5 -#include "kssl.h" -#endif /* OPENSSL_NO_KRB5 */ +#include "kssl_lcl.h" +#include static SSL_METHOD *ssl3_get_server_method(int ver); static int ssl3_get_client_hello(SSL *s); @@ -118,6 +168,7 @@ int ssl3_accept(SSL *s) long num1; int ret= -1; int new_state,state,skip=0; + int got_new_session=0; RAND_add(&Time,sizeof(Time),0); ERR_clear_error(); @@ -129,8 +180,8 @@ int ssl3_accept(SSL *s) cb=s->ctx->info_callback; /* init things to blank */ - if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); if (s->cert == NULL) { @@ -158,7 +209,7 @@ int ssl3_accept(SSL *s) if ((s->version>>8) != 3) { - SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_INTERNAL_ERROR); + SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); return -1; } s->type=SSL_ST_ACCEPT; @@ -184,21 +235,23 @@ int ssl3_accept(SSL *s) goto end; } - /* Ok, we now need to push on a buffering BIO so that - * the output is sent in a way that TCP likes :-) - */ - if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; } - s->init_num=0; if (s->state != SSL_ST_RENEGOTIATE) { + /* Ok, we now need to push on a buffering BIO so that + * the output is sent in a way that TCP likes :-) + */ + if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; } + ssl3_init_finished_mac(s); s->state=SSL3_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; } else { + /* s->state == SSL_ST_RENEGOTIATE, + * we will just send a HelloRequest */ s->ctx->stats.sess_accept_renegotiate++; s->state=SSL3_ST_SW_HELLO_REQ_A; } @@ -219,9 +272,7 @@ int ssl3_accept(SSL *s) case SSL3_ST_SW_HELLO_REQ_C: s->state=SSL_ST_OK; - ret=1; - goto end; - /* break; */ + break; case SSL3_ST_SR_CLNT_HELLO_A: case SSL3_ST_SR_CLNT_HELLO_B: @@ -230,6 +281,7 @@ int ssl3_accept(SSL *s) s->shutdown=0; ret=ssl3_get_client_hello(s); if (ret <= 0) goto end; + got_new_session=1; s->state=SSL3_ST_SW_SRVR_HELLO_A; s->init_num=0; break; @@ -271,6 +323,10 @@ int ssl3_accept(SSL *s) && !(l & SSL_KRB5) #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; @@ -312,7 +368,9 @@ int ssl3_accept(SSL *s) ((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) && /* ... except when the application insists on verification * (against the specs, but s3_clnt.c accepts this for SSL 3) */ - !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) + !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || + /* never request cert in Kerberos ciphersuites */ + (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5)) { /* no cert request */ skip=1; @@ -464,18 +522,25 @@ int ssl3_accept(SSL *s) /* remove buffering on output */ ssl_free_wbio_buffer(s); - s->new_session=0; s->init_num=0; - ssl_update_cache(s,SSL_SESS_CACHE_SERVER); - - s->ctx->stats.sess_accept_good++; - /* s->server=1; */ - s->handshake_func=ssl3_accept; - ret=1; - - if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); - + if (got_new_session) /* skipped if we just sent a HelloRequest */ + { + /* actually not necessarily a 'new' session unless + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */ + + s->new_session=0; + + ssl_update_cache(s,SSL_SESS_CACHE_SERVER); + + s->ctx->stats.sess_accept_good++; + /* s->server=1; */ + s->handshake_func=ssl3_accept; + + if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); + } + + ret = 1; goto end; /* break; */ @@ -541,11 +606,13 @@ static int ssl3_check_client_hello(SSL *s) int ok; long n; + /* this function is called when we really expect a Certificate message, + * so permit appropriate message length */ n=ssl3_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, -1, - SSL3_RT_MAX_PLAIN_LENGTH, + s->max_cert_list, &ok); if (!ok) return((int)n); s->s3->tmp.reuse_message = 1; @@ -596,13 +663,25 @@ static int ssl3_get_client_hello(SSL *s) &ok); if (!ok) return((int)n); - d=p=(unsigned char *)s->init_buf->data; + d=p=(unsigned char *)s->init_msg; /* use version from inside client hello, not from record header * (may differ: see RFC 2246, Appendix E, second paragraph) */ s->client_version=(((int)p[0])<<8)|(int)p[1]; p+=2; + if (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) + { + /* similar to ssl3_get_record, send alert using remote version number */ + s->version = s->client_version; + } + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + /* load the client random */ memcpy(s->s3->client_random,p,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; @@ -611,7 +690,15 @@ static int ssl3_get_client_hello(SSL *s) j= *(p++); s->hit=0; - if (j == 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) + */ + if (j == 0 || (s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { if (!ssl_get_new_session(s,1)) goto err; @@ -948,6 +1035,7 @@ static int ssl3_send_server_key_exchange(SSL *s) BUF_MEM *buf; EVP_MD_CTX md_ctx; + EVP_MD_CTX_init(&md_ctx); if (s->state == SSL3_ST_SW_KEY_EXCH_A) { type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK; @@ -972,7 +1060,7 @@ static int ssl3_send_server_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY); goto f_err; } - CRYPTO_add(&rsa->references,1,CRYPTO_LOCK_RSA); + RSA_up_ref(rsa); cert->rsa_tmp=rsa; } if (rsa == NULL) @@ -1005,7 +1093,7 @@ static 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, SSL_R_INTERNAL_ERROR); + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } @@ -1098,12 +1186,12 @@ static int ssl3_send_server_key_exchange(SSL *s) j=0; for (num=2; num > 0; num--) { - EVP_DigestInit(&md_ctx,(num == 2) - ?s->ctx->md5:s->ctx->sha1); + 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_DigestFinal(&md_ctx,q, + EVP_DigestFinal_ex(&md_ctx,q, (unsigned int *)&i); q+=i; j+=i; @@ -1123,7 +1211,7 @@ static int ssl3_send_server_key_exchange(SSL *s) if (pkey->type == EVP_PKEY_DSA) { /* lets do DSS */ - EVP_SignInit(&md_ctx,EVP_dss1()); + 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); @@ -1156,10 +1244,12 @@ static int ssl3_send_server_key_exchange(SSL *s) } s->state = SSL3_ST_SW_KEY_EXCH_B; + EVP_MD_CTX_cleanup(&md_ctx); return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); err: + EVP_MD_CTX_cleanup(&md_ctx); return(-1); } @@ -1277,7 +1367,7 @@ static int ssl3_get_client_key_exchange(SSL *s) &ok); if (!ok) return((int)n); - p=(unsigned char *)s->init_buf->data; + p=(unsigned char *)s->init_msg; l=s->s3->tmp.new_cipher->algorithms; @@ -1333,14 +1423,15 @@ static int ssl3_get_client_key_exchange(SSL *s) i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING); + al = -1; + if (i != SSL_MAX_MASTER_KEY_LENGTH) { al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); - goto f_err; } - if (!((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff)))) + if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff)))) { /* The premaster secret must contain the same version number as the * ClientHello to detect version rollback attacks (strangely, the @@ -1358,6 +1449,27 @@ static int ssl3_get_client_key_exchange(SSL *s) } } + if (al != -1) + { +#if 0 + goto f_err; +#else + /* Some decryption failure -- use random value instead as countermeasure + * against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding + * (see RFC 2246, section 7.4.7.1). + * But note that due to length and protocol version checking, the + * attack is impractical anyway (see section 5 in D. Bleichenbacher: + * "Chosen Ciphertext Attacks Against Protocols Based on the RSA + * Encryption Standard PKCS #1", CRYPTO '98, LNCS 1462, pp. 1-12). + */ + ERR_clear_error(); + i = SSL_MAX_MASTER_KEY_LENGTH; + p[0] = s->client_version >> 8; + p[1] = s->client_version & 0xff; + RAND_pseudo_bytes(p+2, i-2); /* should be RAND_bytes, but we cannot work around a failure */ +#endif + } + s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, @@ -1432,13 +1544,47 @@ static int ssl3_get_client_key_exchange(SSL *s) #ifndef OPENSSL_NO_KRB5 if (l & SSL_kKRB5) { - krb5_error_code krb5rc; - KSSL_CTX *kssl_ctx = s->kssl_ctx; + krb5_error_code krb5rc; + krb5_data enc_ticket; + krb5_data authenticator; + krb5_data enc_pms; + KSSL_CTX *kssl_ctx = s->kssl_ctx; + EVP_CIPHER_CTX ciph_ctx; + EVP_CIPHER *enc = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH + + EVP_MAX_IV_LENGTH + 1]; + int padl, outl = sizeof(pms); + krb5_timestamp authtime = 0; + krb5_ticket_times ttimes; if (!kssl_ctx) kssl_ctx = kssl_ctx_new(); - if ((krb5rc = kssl_sget_tkt(kssl_ctx, - s->init_buf->data, s->init_buf->length, - &kssl_err)) != 0) + + n2s(p,i); + enc_ticket.length = i; + enc_ticket.data = p; + p+=enc_ticket.length; + + n2s(p,i); + authenticator.length = i; + authenticator.data = p; + p+=authenticator.length; + + n2s(p,i); + enc_pms.length = i; + enc_pms.data = p; + p+=enc_pms.length; + + if ((unsigned long)n != enc_ticket.length + authenticator.length + + enc_pms.length + 6) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes, + &kssl_err)) != 0) { #ifdef KSSL_DEBUG printf("kssl_sget_tkt rtn %d [%d]\n", @@ -1451,34 +1597,100 @@ static int ssl3_get_client_key_exchange(SSL *s) goto err; } + /* Note: no authenticator is not considered an error, + ** but will return authtime == 0. + */ + if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator, + &authtime, &kssl_err)) != 0) + { +#ifdef KSSL_DEBUG + printf("kssl_check_authent rtn %d [%d]\n", + krb5rc, kssl_err.reason); + if (kssl_err.text) + printf("kssl_err text= %s\n", kssl_err.text); +#endif /* KSSL_DEBUG */ + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + kssl_err.reason); + goto err; + } + + if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, krb5rc); + goto err; + } + #ifdef KSSL_DEBUG kssl_ctx_show(kssl_ctx); #endif /* KSSL_DEBUG */ - /* 19991013 VRS - 3DES is kind of bogus here, - ** at least until Kerberos supports 3DES. The only - ** real secret is the 8-byte Kerberos session key; - ** the other key material (client_random, server_random) - ** could be sniffed. Nonces may help against replays though. - ** - ** Alternate code for Kerberos Purists: - ** - ** memcpy(s->session->master_key, kssl_ctx->key, kssl_ctx->length); - ** s->session->master_key_length = kssl_ctx->length; - */ + enc = kssl_map_enc(kssl_ctx->enctype); + if (enc == NULL) + goto err; + + memset(iv, 0, EVP_MAX_IV_LENGTH); /* per RFC 1510 */ + + if (!EVP_DecryptInit_ex(&ciph_ctx,enc,NULL,kssl_ctx->key,iv)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto err; + } + if (!EVP_DecryptUpdate(&ciph_ctx, pms,&outl, + enc_pms.data, enc_pms.length)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto err; + } + if (outl > SSL_MAX_MASTER_KEY_LENGTH) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + if (!EVP_DecryptFinal_ex(&ciph_ctx,&(pms[outl]),&padl)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto err; + } + outl += padl; + if (outl > SSL_MAX_MASTER_KEY_LENGTH) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, - s->session->master_key, kssl_ctx->key, kssl_ctx->length); - /* Was doing kssl_ctx_free() here, but it caused problems for apache. - ** kssl_ctx = kssl_ctx_free(kssl_ctx); - ** if (s->kssl_ctx) s->kssl_ctx = NULL; + s->session->master_key, pms, outl); + + if (kssl_ctx->client_princ) + { + int len = strlen(kssl_ctx->client_princ); + if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH ) + { + s->session->krb5_client_princ_len = len; + memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len); + } + } + + + /* Was doing kssl_ctx_free() here, + ** but it caused problems for apache. + ** kssl_ctx = kssl_ctx_free(kssl_ctx); + ** if (s->kssl_ctx) s->kssl_ctx = NULL; */ } else #endif /* OPENSSL_NO_KRB5 */ { al=SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNKNOWN_CIPHER_TYPE); + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_UNKNOWN_CIPHER_TYPE); goto f_err; } @@ -1556,7 +1768,7 @@ static int ssl3_get_cert_verify(SSL *s) } /* we now have a signature that we need to verify */ - p=(unsigned char *)s->init_buf->data; + p=(unsigned char *)s->init_msg; n2s(p,i); n-=2; if (i > n) @@ -1612,7 +1824,7 @@ static int ssl3_get_cert_verify(SSL *s) else #endif { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_INTERNAL_ERROR); + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR); al=SSL_AD_UNSUPPORTED_CERTIFICATE; goto f_err; } @@ -1641,11 +1853,7 @@ static int ssl3_get_client_certificate(SSL *s) SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, -1, -#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32) - 1024*30, /* 30k max cert list :-) */ -#else - 1024*100, /* 100k max cert list :-) */ -#endif + s->max_cert_list, &ok); if (!ok) return((int)n); @@ -1676,7 +1884,7 @@ static int ssl3_get_client_certificate(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_WRONG_MESSAGE_TYPE); goto f_err; } - d=p=(unsigned char *)s->init_buf->data; + d=p=(unsigned char *)s->init_msg; if ((sk=sk_X509_new_null()) == NULL) { @@ -1802,7 +2010,7 @@ int ssl3_send_server_certificate(SSL *s) & (SSL_MKEY_MASK|SSL_AUTH_MASK)) != (SSL_aKRB5|SSL_kKRB5)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,SSL_R_INTERNAL_ERROR); + SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR); return(0); }