From: Richard Levitte Date: Tue, 5 Jun 2001 05:08:26 +0000 (+0000) Subject: Add changes from the 0.9.6-stable branch. X-Git-Tag: OpenSSL-engine-0_9_6b~2 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=4ae5099856741dd7cf365dbd2c1df45751dfbf4f;p=oweals%2Fopenssl.git Add changes from the 0.9.6-stable branch. --- diff --git a/CHANGES b/CHANGES index d59baf9a57..db225ce569 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,48 @@ Changes between 0.9.6a and 0.9.6b [XX xxx XXXX] + *) The countermeasure against Bleichbacher's attack on PKCS #1 v1.5 + RSA encryption was accidentily removed in s3_srvr.c in OpenSSL 0.9.5 + when fixing the server behaviour for backwards-compatible 'client + hello' messages. (Note that the attack is impractical against + SSL 3.0 and TLS 1.0 anyway because length and version checking + means that the probability of guessing a valid ciphertext is + around 2^-40; see section 5 in Bleichenbacher's CRYPTO '98 + paper.) + + Before 0.9.5, the countermeasure (hide the error by generating a + random 'decryption result') did not work properly because + ERR_clear_error() was missing, meaning that SSL_get_error() would + detect the supposedly ignored error. + + Both problems are now fixed. + [Bodo Moeller] + + *) In crypto/bio/bf_buff.c, increase DEFAULT_BUFFER_SIZE to 4096 + (previously it was 1024). + [Bodo Moeller] + + *) Fix for compatibility mode trust settings: ignore trust settings + unless some valid trust or reject settings are present. + [Steve Henson] + + *) Fix for blowfish EVP: its a variable length cipher. + [Steve Henson] + + *) Fix various bugs related to DSA S/MIME verification. Handle missing + parameters in DSA public key structures and return an error in the + DSA routines if parameters are absent. + [Steve Henson] + + *) In versions up to 0.9.6, RAND_file_name() resorted to file ".rnd" + in the current directory if neither $RANDFILE nor $HOME was set. + RAND_file_name() in 0.9.6a returned NULL in this case. This has + caused some confusion to Windows users who haven't defined $HOME. + Thus RAND_file_name() is changed again: e_os.h can define a + DEFAULT_HOME, which will be used if $HOME is not set. + For Windows, we use "C:"; on other platforms, we still require + environment variables. + *) Move 'if (!initialized) RAND_poll()' into regions protected by CRYPTO_LOCK_RAND. This is not strictly necessary, but avoids having multiple threads call RAND_poll() concurrently. @@ -2382,7 +2424,7 @@ copied!) [Bodo Moeller] - *) Bugfix: SSL_set_mode ignored its parameter, only SSL_CTX_set_mode + *) Bugfix: SSL_set_options ignored its parameter, only SSL_CTX_set_options worked. *) Fix problems with no-hmac etc. diff --git a/Configure b/Configure index acd05f3868..c60c757152 100755 --- a/Configure +++ b/Configure @@ -143,6 +143,9 @@ my %table=( # error message. "solaris-x86-gcc","gcc:-O3 -fomit-frame-pointer -m486 -Wall -DL_ENDIAN -DNO_INLINE_ASM::-D_REENTRANT:-lsocket -lnsl -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_sol_asm}:dlfcn:gnu-shared:-fPIC:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +#### Solaris x86 with Sun C setups +"solaris-x86-cc","cc:-fast -O -Xa::-D_REENTRANT:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL BF_PTR::::::::::dlfcn:solaris-shared:-KPIC:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", + #### SPARC Solaris with GNU C setups "solaris-sparcv7-gcc","gcc:-O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR::::::::::dlfcn:gnu-shared:-fPIC:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", "solaris-sparcv8-gcc","gcc:-mv8 -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8.o:::::::::dlfcn:gnu-shared:-fPIC:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", diff --git a/FAQ b/FAQ index 878a779670..8b3d540335 100644 --- a/FAQ +++ b/FAQ @@ -17,6 +17,7 @@ OpenSSL - Frequently Asked Questions [USER] Questions on using the OpenSSL applications * Why do I get a "PRNG not seeded" error message? +* Why do I get an "unable to write 'random state'" error message? * How do I create certificates or certificate requests? * Why can't I create certificate requests? * Why does fail with a certificate verify error? @@ -161,6 +162,7 @@ correctly. Many open source operating systems provide a "randomness device" that serves this purpose. On other systems, applications have to call the RAND_add() or RAND_seed() function with appropriate data before generating keys or performing public key encryption. +(These functions initialize the pseudo-random number generator, PRNG.) Some broken applications do not do this. As of version 0.9.5, the OpenSSL functions that need randomness report an error if the random @@ -170,18 +172,36 @@ application you are using. It is likely that it never worked correctly. OpenSSL 0.9.5 and later make the error visible by refusing to perform potentially insecure encryption. -On systems without /dev/urandom, it is a good idea to use the Entropy -Gathering Demon; see the RAND_egd() manpage for details. - -Most components of the openssl command line tool try to use the -file $HOME/.rnd (or $RANDFILE, if this environment variable is set) -for seeding the PRNG. If this file does not exist or is too short, -the "PRNG not seeded" error message may occur. - -[Note to OpenSSL 0.9.5 users: The command "openssl rsa" in version -0.9.5 does not do this and will fail on systems without /dev/urandom -when trying to password-encrypt an RSA key! This is a bug in the -library; try a later version instead.] +On systems without /dev/urandom and /dev/random, it is a good idea to +use the Entropy Gathering Demon (EGD); see the RAND_egd() manpage for +details. Starting with version 0.9.7, OpenSSL will automatically look +for an EGD socket at /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool and +/etc/entropy. + +Most components of the openssl command line utility automatically try +to seed the random number generator from a file. The name of the +default seeding file is determined as follows: If environment variable +RANDFILE is set, then it names the seeding file. Otherwise if +environment variable HOME is set, then the seeding file is $HOME/.rnd. +If neither RANDFILE nor HOME is set, versions up to OpenSSL 0.9.6 will +use file .rnd in the current directory while OpenSSL 0.9.6a uses no +default seeding file at all. OpenSSL 0.9.6b and later will behave +similarly to 0.9.6a, but will use a default of "C:" for HOME on +Windows systems if the environment variable has not been set. + +If the default seeding file does not exist or is too short, the "PRNG +not seeded" error message may occur. + +The openssl command line utility will write back a new state to the +default seeding file (and create this file if necessary) unless +there was no sufficient seeding. + +Pointing $RANDFILE to an Entropy Gathering Daemon socket does not work. +Use the "-rand" option of the OpenSSL command line tools instead. +The $RANDFILE environment variable and $HOME/.rnd are only used by the +OpenSSL command line tools. Applications using the OpenSSL library +provide their own configuration options to specify the entropy source, +please check out the documentation coming the with application. For Solaris 2.6, Tim Nibbe and others have suggested installing the SUNski package from Sun patch 105710-01 (Sparc) which @@ -191,6 +211,18 @@ versions. However, be warned that /dev/random is usually a blocking device, which may have some effects on OpenSSL. +* Why do I get an "unable to write 'random state'" error message? + + +Sometimes the openssl command line utility does not abort with +a "PRNG not seeded" error message, but complains that it is +"unable to write 'random state'". This message refers to the +default seeding file (see previous answer). A possible reason +is that no default filename is known because neither RANDFILE +nor HOME is set. (Versions up to 0.9.6 used file ".rnd" in the +current directory in this case, but this has changed with 0.9.6a.) + + * How do I create certificates or certificate requests? Check out the CA.pl(1) manual page. This provides a simple wrapper round diff --git a/INSTALL b/INSTALL index f658a0ad51..e9cb572edb 100644 --- a/INSTALL +++ b/INSTALL @@ -7,8 +7,11 @@ To install OpenSSL, you will need: + * make * Perl 5 * an ANSI C compiler + * a development environment in form of development libraries and C + header files * a supported Unix operating system Quick Start @@ -43,9 +46,6 @@ --openssldir=DIR Directory for OpenSSL files. If no prefix is specified, the library files and binaries are also installed there. - rsaref Build with RSADSI's RSAREF toolkit (this assumes that - librsaref.a is in the library search path). - no-threads Don't try to build with support for multi-threaded applications. @@ -128,7 +128,7 @@ directory, and the binary will be in the "apps" directory. If "make" fails, look at the output. There may be reasons for - the failure that isn't a problem in OpenSSL itself (like missing + the failure that aren't problems in OpenSSL itself (like missing standard headers). If it is a problem with OpenSSL itself, please report the problem to (note that your message will be forwarded to a public mailing list). Include the diff --git a/INSTALL.VMS b/INSTALL.VMS index 1fe78a41bb..b8ea2d0a4d 100644 --- a/INSTALL.VMS +++ b/INSTALL.VMS @@ -8,6 +8,7 @@ Intro: This file is divided in the following parts: + Requirements - Mandatory reading. Checking the distribution - Mandatory reading. Compilation - Mandatory reading. Logical names - Mandatory reading. @@ -19,6 +20,15 @@ This file is divided in the following parts: TODO - Things that are to come. +Requirements: +============= + +To build and install OpenSSL, you will need: + + * DEC C or some other ANSI C compiler. VAX C is *not* supported. + [Note: OpenSSL has only been tested with DEC C. Compiling with + a different ANSI C compiler may require some work] + Checking the distribution: ========================== diff --git a/apps/ca.c b/apps/ca.c index 2ab0c4db51..f3fb45b7b4 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -1247,7 +1247,11 @@ bad: X509_free(revcert); strncpy(buf[0],dbfile,BSIZE-4); +#ifndef VMS strcat(buf[0],".new"); +#else + strcat(buf[0],"-new"); +#endif if (BIO_write_filename(out,buf[0]) <= 0) { perror(dbfile); @@ -1257,7 +1261,11 @@ bad: j=TXT_DB_write(out,db); if (j <= 0) goto err; strncpy(buf[1],dbfile,BSIZE-4); +#ifndef VMS strcat(buf[1],".old"); +#else + strcat(buf[1],"-old"); +#endif if (rename(dbfile,buf[1]) < 0) { BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]); diff --git a/crypto/asn1/x_pubkey.c b/crypto/asn1/x_pubkey.c index b2e2a51477..4397a404b5 100644 --- a/crypto/asn1/x_pubkey.c +++ b/crypto/asn1/x_pubkey.c @@ -234,7 +234,7 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) a=key->algor; if (ret->type == EVP_PKEY_DSA) { - if (a->parameter->type == V_ASN1_SEQUENCE) + if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) { ret->pkey.dsa->write_params=0; p=a->parameter->value.sequence->data; diff --git a/crypto/bio/bf_buff.c b/crypto/bio/bf_buff.c index f50e8f98a3..c90238bae1 100644 --- a/crypto/bio/bf_buff.c +++ b/crypto/bio/bf_buff.c @@ -70,7 +70,7 @@ static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int buffer_new(BIO *h); static int buffer_free(BIO *data); static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); -#define DEFAULT_BUFFER_SIZE 1024 +#define DEFAULT_BUFFER_SIZE 4096 static BIO_METHOD methods_buffer= { diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h index 65689a3426..12b60a8faa 100644 --- a/crypto/dsa/dsa.h +++ b/crypto/dsa/dsa.h @@ -248,6 +248,7 @@ DH *DSA_dup_DH(DSA *r); /* Reason codes. */ #define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 +#define DSA_R_MISSING_PARAMETERS 101 #ifdef __cplusplus } diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c index 2b3ab3a9ad..736aeef7c4 100644 --- a/crypto/dsa/dsa_err.c +++ b/crypto/dsa/dsa_err.c @@ -85,6 +85,7 @@ static ERR_STRING_DATA DSA_str_functs[]= static ERR_STRING_DATA DSA_str_reasons[]= { {DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE ,"data too large for key size"}, +{DSA_R_MISSING_PARAMETERS ,"missing parameters"}, {0,NULL} }; diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index 72878e193f..0ee172dd07 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -106,6 +106,11 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) int i,reason=ERR_R_BN_LIB; DSA_SIG *ret=NULL; + if (!dsa->p || !dsa->q || !dsa->g) + { + reason=DSA_R_MISSING_PARAMETERS; + goto err; + } BN_init(&m); BN_init(&xr); s=BN_new(); @@ -168,6 +173,11 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) BIGNUM k,*kinv=NULL,*r=NULL; int ret=0; + if (!dsa->p || !dsa->q || !dsa->g) + { + DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS); + return 0; + } if (ctx_in == NULL) { if ((ctx=BN_CTX_new()) == NULL) goto err; diff --git a/crypto/evp/e_bf.c b/crypto/evp/e_bf.c index 72047f64da..53559b0b65 100644 --- a/crypto/evp/e_bf.c +++ b/crypto/evp/e_bf.c @@ -67,7 +67,7 @@ static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); IMPLEMENT_BLOCK_CIPHER(bf, bf_ks, BF, bf_ks, NID_bf, 8, 16, 8, - 0, bf_init_key, NULL, + EVP_CIPH_VARIABLE_LENGTH, bf_init_key, NULL, EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, diff --git a/crypto/perlasm/x86unix.pl b/crypto/perlasm/x86unix.pl index 309060ea00..10a7af8bff 100644 --- a/crypto/perlasm/x86unix.pl +++ b/crypto/perlasm/x86unix.pl @@ -79,7 +79,7 @@ sub main'DWP local($addr,$reg1,$reg2,$idx)=@_; $ret=""; - $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/; + $addr =~ s/(^|[+ \t])([A-Za-z_]+[A-Za-z0-9_]+)($|[+ \t])/$1$under$2$3/; $reg1="$regs{$reg1}" if defined($regs{$reg1}); $reg2="$regs{$reg2}" if defined($regs{$reg2}); $ret.=$addr if ($addr ne "") && ($addr ne 0); diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c index 7548ac324c..c2ae28c3a2 100644 --- a/crypto/rand/randfile.c +++ b/crypto/rand/randfile.c @@ -211,6 +211,12 @@ const char *RAND_file_name(char *buf, size_t size) { if (OPENSSL_issetugid() == 0) s=getenv("HOME"); +#ifdef DEFAULT_HOME + if (s == NULL) + { + s = DEFAULT_HOME; + } +#endif if (s != NULL && (strlen(s)+strlen(RFILE)+2 < size)) { strcpy(buf,s); @@ -220,7 +226,7 @@ const char *RAND_file_name(char *buf, size_t size) strcat(buf,RFILE); ret=buf; } - else + else buf[0] = '\0'; /* no file name */ } return(ret); diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c index a7b1543461..86b3b79dcc 100644 --- a/crypto/x509/x509_trs.c +++ b/crypto/x509/x509_trs.c @@ -228,7 +228,8 @@ int X509_TRUST_get_trust(X509_TRUST *xp) static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) { - if(x->aux) return obj_trust(trust->arg1, x, flags); + if(x->aux && (x->aux->trust || x->aux->reject)) + return obj_trust(trust->arg1, x, flags); /* we don't have any trust settings: for compatibility * we return trusted if it is self signed */ diff --git a/doc/ssl/SSL_CTX_get_ex_new_index.pod b/doc/ssl/SSL_CTX_get_ex_new_index.pod index 15067438c8..5686faf299 100644 --- a/doc/ssl/SSL_CTX_get_ex_new_index.pod +++ b/doc/ssl/SSL_CTX_get_ex_new_index.pod @@ -40,7 +40,7 @@ SSL_CTX_get_ex_data() is used to retrieve the information for B from B. A detailed description for the B<*_get_ex_new_index()> functionality -can be found in L. +can be found in L. The B<*_get_ex_data()> and B<*_set_ex_data()> functionality is described in L. diff --git a/doc/ssl/SSL_CTX_set_session_cache_mode.pod b/doc/ssl/SSL_CTX_set_session_cache_mode.pod index 083766f8d0..8bbfc78720 100644 --- a/doc/ssl/SSL_CTX_set_session_cache_mode.pod +++ b/doc/ssl/SSL_CTX_set_session_cache_mode.pod @@ -101,7 +101,7 @@ L, L, L, L, -L, +L, L =cut diff --git a/doc/ssl/SSL_SESSION_get_ex_new_index.pod b/doc/ssl/SSL_SESSION_get_ex_new_index.pod index dd5cb4f04b..da0bcf1590 100644 --- a/doc/ssl/SSL_SESSION_get_ex_new_index.pod +++ b/doc/ssl/SSL_SESSION_get_ex_new_index.pod @@ -40,7 +40,7 @@ SSL_SESSION_get_ex_data() is used to retrieve the information for B from B. A detailed description for the B<*_get_ex_new_index()> functionality -can be found in L. +can be found in L. The B<*_get_ex_data()> and B<*_set_ex_data()> functionality is described in L. diff --git a/doc/ssl/SSL_get_error.pod b/doc/ssl/SSL_get_error.pod index fefaf61936..d95eec78aa 100644 --- a/doc/ssl/SSL_get_error.pod +++ b/doc/ssl/SSL_get_error.pod @@ -69,6 +69,17 @@ to read data. This is mainly because TLS/SSL handshakes may occur at any time during the protocol (initiated by either the client or the server); SSL_read(), SSL_peek(), and SSL_write() will handle any pending handshakes. +=item SSL_ERROR_WANT_CONNECT + +The operation did not complete; the same TLS/SSL I/O function should be +called again later. The underlying BIO was not connected yet to the peer +and the call would block in connect(). The SSL function should be +called again when the connection is established. This messages can only +appear with a BIO_s_connect() BIO. +In order to find out, when the connection has been successfully established, +on many platforms select() or poll() for writing on the socket file descriptor +can be used. + =item SSL_ERROR_WANT_X509_LOOKUP The operation did not complete because an application callback set by diff --git a/doc/ssl/SSL_get_ex_new_index.pod b/doc/ssl/SSL_get_ex_new_index.pod index 2b69bb1050..6644ef8fbc 100644 --- a/doc/ssl/SSL_get_ex_new_index.pod +++ b/doc/ssl/SSL_get_ex_new_index.pod @@ -40,7 +40,7 @@ SSL_get_ex_data() is used to retrieve the information for B from B. A detailed description for the B<*_get_ex_new_index()> functionality -can be found in L. +can be found in L. The B<*_get_ex_data()> and B<*_set_ex_data()> functionality is described in L. diff --git a/doc/ssl/SSL_read.pod b/doc/ssl/SSL_read.pod index 7db5ee0a22..cc7aa1a547 100644 --- a/doc/ssl/SSL_read.pod +++ b/doc/ssl/SSL_read.pod @@ -29,7 +29,22 @@ initialized to client or server mode. This is not the case if a generic method is being used (see L, so that L or SSL_set_accept_state() must be used before the first call to an SSL_read() or -L function. +L function). + +SSL_read() works based on the SSL/TLS records. The data are received in +records (with a maximum record size of 16kB for SSLv3/TLSv1). Only when a +record has been completely received, it can be processed (decryption and +check of integrity). Therefore data that was not retrieved at the last +call of SSL_read() can still be buffered inside the SSL layer and will be +retrieved on the next call to SSL_read(). If B is higher than the +number of bytes buffered, SSL_read() will return with the bytes buffered. +If no more bytes are in the buffer, SSL_read() will trigger the processing +of the next record. Only when the record has been received and processed +completely, SSL_read() will return reporting success. At most the contents +of the record will be returned. As the size of an SSL/TLS record may exceed +the maximum packet size of the underlying transport (e.g. TCP), it may +be necessary to read several packets from the transport layer before the +record is complete and SSL_read() can succeed. If the underlying BIO is B, SSL_read() will only return, once the read operation has been finished or an error occurred, except when a diff --git a/doc/ssl/SSL_write.pod b/doc/ssl/SSL_write.pod index be1ad76d3b..b0dfefae20 100644 --- a/doc/ssl/SSL_write.pod +++ b/doc/ssl/SSL_write.pod @@ -50,6 +50,17 @@ non-blocking socket, nothing is to be done, but select() can be used to check for the required condition. When using a buffering BIO, like a BIO pair, data must be written into or retrieved out of the BIO before being able to continue. +SSL_write() will only return with success, when the complete contents +of B of length B has been written. This default behaviour +can be changed with the SSL_MODE_ENABLE_PARTIAL_WRITE option of +L. When this flag is set, +SSL_write() will also return with success, when a partial write has been +successfully completed. In this case the SSL_write() operation is considered +completed. The bytes are sent and a new SSL_write() operation with a new +buffer (with the already sent bytes removed) must be started. +A partial write is performed with the size of a message block, which is +16kB for SSLv3/TLSv1. + =head1 WARNING When an SSL_write() operation has to be repeated because of diff --git a/e_os.h b/e_os.h index 4f9c983ef1..8a996096be 100644 --- a/e_os.h +++ b/e_os.h @@ -224,6 +224,7 @@ extern "C" { # define SSLEAY_CONF OPENSSL_CONF # define NUL_DEV "nul" # define RFILE ".rnd" +# define DEFAULT_HOME "C:" #else /* The non-microsoft world world */ diff --git a/ssl/s2_srvr.c b/ssl/s2_srvr.c index 1ed02540ae..2fa2f310a8 100644 --- a/ssl/s2_srvr.c +++ b/ssl/s2_srvr.c @@ -405,12 +405,13 @@ static int get_client_master_key(SSL *s) /* bad decrypt */ #if 1 /* If a bad decrypt, continue with protocol but with a - * dud master secret */ + * random master secret (Bleichenbacher attack) */ if ((i < 0) || ((!is_export && (i != EVP_CIPHER_key_length(c))) || (is_export && ((i != ek) || (s->s2->tmp.clear+i != EVP_CIPHER_key_length(c)))))) { + ERR_clear_error(); if (is_export) i=ek; else diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index d04232960e..258af84867 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -1322,14 +1322,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 @@ -1347,6 +1348,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, diff --git a/test/Makefile.ssl b/test/Makefile.ssl index 1e975c5338..309e2a882e 100644 --- a/test/Makefile.ssl +++ b/test/Makefile.ssl @@ -192,7 +192,7 @@ test_bn: @./$(BNTEST) >tmp.bntest @echo quit >>tmp.bntest @echo "running bc" - @) {if (/^test (.*)/) {print STDERR "\nverify $$1";} elsif (!/^0$$/) {die "\nFailed! bc: $$_";} else {print STDERR "."; $$i++;}} print STDERR "\n$$i tests passed\n"' + @) {if (/^test (.*)/) {print STDERR "\nverify $$1";} elsif (!/^0$$/) {die "\nFailed! bc: $$_";} else {print STDERR "."; $$i++;}} print STDERR "\n$$i tests passed\n"' @echo 'test a^b%c implementations' ./$(EXPTEST) diff --git a/test/bctest b/test/bctest index fbe74ed90b..bdb3218f7a 100755 --- a/test/bctest +++ b/test/bctest @@ -104,5 +104,8 @@ EOF done echo "No working bc found. Consider installing GNU bc." >&2 -echo "cat >/dev/null" +if [ "$1" = ignore ]; then + echo "cat >/dev/null" + exit 0 +fi exit 1