From 0dcf7fd543257558bba857c8ba07cb4189847e22 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 13 Sep 2000 21:20:49 +0000 Subject: [PATCH] Merge of main trunk, conflicts resolved. --- CHANGES | 13 +++++++++ Configure | 10 +++---- STATUS | 26 ++++++++++++++--- crypto/dsa/dsa_key.c | 2 +- crypto/dsa/dsa_ossl.c | 2 +- crypto/rand/rand_win.c | 18 ++++++++++-- doc/crypto/BIO_read.pod | 20 ++++++++++--- doc/crypto/BIO_should_retry.pod | 43 ++++++++------------------- ssl/s3_pkt.c | 52 ++++++++++++++++++--------------- ssl/ssl.h | 3 ++ 10 files changed, 117 insertions(+), 72 deletions(-) diff --git a/CHANGES b/CHANGES index 7bb375d117..1eca683808 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,19 @@ Changes between 0.9.5a and 0.9.6 [xx XXX 2000] + *) Don't set the two most significant bits to one when generating a + random number < q in the DSA library. + [Ulf Möller] + + *) New SSL API mode 'SSL_MODE_AUTO_RETRY'. This disables the default + behaviour that SSL_read may result in SSL_ERROR_WANT_READ (even if + the underlying transport is blocking) if a handshake took place. + (The default behaviour is needed by applications such as s_client + and s_server that use select() to determine when to use SSL_read; + but for applications that know in advance when to expect data, it + just makes things more complicated.) + [Bodo Moeller] + *) Add RAND_egd_bytes(), which gives control over the number of bytes read from EGD. [Ben Laurie] diff --git a/Configure b/Configure index fcb9a85391..561ad93fbe 100755 --- a/Configure +++ b/Configure @@ -364,24 +364,24 @@ my %table=( # Windows NT, Microsoft Visual C++ 4.0 -"VC-NT","cl:::::BN_LLONG RC4_INDEX ${x86_gcc_opts}:::", -"VC-WIN32","cl:::::BN_LLONG RC4_INDEX ${x86_gcc_opts}:::", +"VC-NT","cl:::::BN_LLONG RC4_INDEX ${x86_gcc_opts}::::::::::win32", +"VC-WIN32","cl:::::BN_LLONG RC4_INDEX ${x86_gcc_opts}::::::::::win32", "VC-WIN16","cl:::(unknown)::MD2_CHAR DES_UNROLL DES_PTR RC4_INDEX THIRTY_TWO_BIT:::", "VC-W31-16","cl:::(unknown)::BN_LLONG MD2_CHAR DES_UNROLL DES_PTR RC4_INDEX SIXTEEN_BIT:::", "VC-W31-32","cl:::::BN_LLONG MD2_CHAR DES_UNROLL DES_PTR RC4_INDEX THIRTY_TWO_BIT:::", "VC-MSDOS","cl:::(unknown)::BN_LLONG MD2_CHAR DES_UNROLL DES_PTR RC4_INDEX SIXTEEN_BIT:::", # Borland C++ 4.5 -"BC-32","bcc32:::::BN_LLONG DES_PTR RC4_INDEX:::", +"BC-32","bcc32:::::BN_LLONG DES_PTR RC4_INDEX::::::::::win32", "BC-16","bcc:::(unknown)::BN_LLONG DES_PTR RC4_INDEX SIXTEEN_BIT:::", # Mingw32 # (Note: the real CFLAGS for Windows builds are defined by util/mk1mf.pl # and its library files in util/pl/*) -"Mingw32", "gcc:-DL_ENDIAN -fomit-frame-pointer -O3 -m486 -Wall::::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:", +"Mingw32", "gcc:-DL_ENDIAN -fomit-frame-pointer -O3 -m486 -Wall::::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}::::::::::win32", # CygWin32 -"CygWin32", "gcc:-DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O3 -m486 -Wall::::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:", +"CygWin32", "gcc:-DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O3 -m486 -Wall::::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}::::::::::win32", # Ultrix from Bernhard Simon "ultrix-cc","cc:-std1 -O -Olimit 1000 -DL_ENDIAN::(unknown)::::::", diff --git a/STATUS b/STATUS index 511fd2cf80..4424d86508 100644 --- a/STATUS +++ b/STATUS @@ -1,22 +1,40 @@ OpenSSL STATUS Last modified at - ______________ $Date: 2000/09/12 08:37:49 $ + ______________ $Date: 2000/09/13 21:20:43 $ DEVELOPMENT STATE o OpenSSL 0.9.6: Under development (in release cycle)... Proposed release date September 24, 2000 0.9.6-beta1 is available: - OpenBSD-x86 2.7 - failed (ftime/TIMEB) + OpenBSD-x86 2.7 - failed + ftime not supported [FIXED] hpux-parisc-cc 10.20 - passed hpux-parisc-gcc 10.20 - passed + hpux-parisc-gcc 11.00 - passed hpux-gcc - passed - hpux-brokengcc - failed (BN_sqr) + hpux-brokengcc - failed + BN_sqr fails in test linux-elf - passed linux-sparcv7 - passed - Solaris [engine] - failed (speed cswift) + linux-ppc - passed + Solaris [engine] - failed + speed cswift gives odd errors [FIXED] + solaris-sparcv8-gcc - passed + solaris-sparcv9-gcc - passed + solaris-sparcv9-cc - passed + solaris64-sparcv9-cc - passed sco5-gcc - passed sco5-cc - passed + FreeBSD - passed + Win32 VC++ - failed + PCURSORINFO not defined unless Win2000 [FIXED] + RAND_poll() problem on Win2000 [FIXED] + DSO method always DSO_METHOD_null [FIXED] + CygWin32 - test failed + MingW32 - failed + thelp32.h + aix-gcc (AIX 4.3.2) - passed o OpenSSL 0.9.5a: Released on April 1st, 2000 o OpenSSL 0.9.5: Released on February 28th, 2000 o OpenSSL 0.9.4: Released on August 09th, 1999 diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c index 5aef2d5fcf..af3c56d770 100644 --- a/crypto/dsa/dsa_key.c +++ b/crypto/dsa/dsa_key.c @@ -84,7 +84,7 @@ int DSA_generate_key(DSA *dsa) i=BN_num_bits(dsa->q); for (;;) { - if (!BN_rand(priv_key,i,1,0)) + if (!BN_rand(priv_key,i,0,0)) goto err; if (BN_cmp(priv_key,dsa->q) >= 0) BN_sub(priv_key,priv_key,dsa->q); diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index 533c17ece8..96295dc24f 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -182,7 +182,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) /* Get random k */ for (;;) { - if (!BN_rand(&k, BN_num_bits(dsa->q), 1, 0)) goto err; + if (!BN_rand(&k, BN_num_bits(dsa->q), 0, 0)) goto err; if (BN_cmp(&k,dsa->q) >= 0) BN_sub(&k,&k,dsa->q); if (!BN_is_zero(&k)) break; diff --git a/crypto/rand/rand_win.c b/crypto/rand/rand_win.c index cb8e17634f..82955d8d30 100644 --- a/crypto/rand/rand_win.c +++ b/crypto/rand/rand_win.c @@ -130,6 +130,15 @@ static void readtimer(void); static void readscreen(void); +/* It appears like PCURSORINFO is only defined when WINVER is 0x0500 and up, + which currently only happens on Win2000. Unfortunately, that is a typedef, + so it's a little bit difficult to detect properly. On the other hand, the + macro CURSOR_SHOWING is defined within the same conditional, so it can be + use to detect the absence of PCURSORINFO. */ +#ifndef CURSOR_SHOWING +typedef void *PCURSORINFO; +#endif + typedef BOOL (WINAPI *CRYPTACQUIRECONTEXT)(HCRYPTPROV *, LPCTSTR, LPCTSTR, DWORD, DWORD); typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV, DWORD, BYTE *); @@ -254,7 +263,8 @@ int RAND_poll(void) * * This seeding method was proposed in Peter Gutmann, Software * Generation of Practically Strong Random Numbers, - * http://www.cs.auckland.ac.nz/~pgut001/pubs/random2.pdf + * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html + * revised version at http://www.cryptoengines.com/~peter/06_random.pdf * (The assignment of entropy estimates below is arbitrary, but based * on Peter's analysis the full poll appears to be safe. Additional * interactive seeding is encouraged.) @@ -307,10 +317,14 @@ int RAND_poll(void) if (heap_first(&hentry, hlist.th32ProcessID, hlist.th32HeapID)) + { + int entrycnt = 50; do RAND_add(&hentry, hentry.dwSize, 0); - while (heap_next(&hentry)); + while (heap_next(&hentry) + && --entrycnt > 0); + } } while (heaplist_next(handle, &hlist)); diff --git a/doc/crypto/BIO_read.pod b/doc/crypto/BIO_read.pod index 6c001a3092..e7eb5ea045 100644 --- a/doc/crypto/BIO_read.pod +++ b/doc/crypto/BIO_read.pod @@ -38,16 +38,28 @@ the operation is not implemented in the specific BIO type. =head1 NOTES A 0 or -1 return is not necessarily an indication of an error. In -particular when the source/sink is non-blocking or of a certain type (for -example an SSL BIO can retry even if the underlying connection is blocking) +particular when the source/sink is non-blocking or of a certain type it may merely be an indication that no data is currently available and that -the application should retry the operation later. L -can be called to determine the precise cause. +the application should retry the operation later. + +One technique sometimes used with blocking sockets is to use a system call +(such as select(), poll() or eqivalent) to determine when data is available +and then call read() to read the data. The eqivalent with BIOs (that is call +select() on the underlying I/O structure and then call BIO_read() to +read the data) should B be used because a single call to BIO_read() +can cause several reads (and writes in the case of SSL BIOs) on the underlying +I/O structure and may block as a result. Instead select() (or equivalent) +should be combined with non blocking I/O so successive reads will request +a retry instead of blocking. + +See the L for details of how to +determine the cause of a retry and other I/O issues. If the BIO_gets() function is not supported by a BIO then it possible to work around this by adding a buffering BIO L to the chain. =head1 SEE ALSO +L TBA diff --git a/doc/crypto/BIO_should_retry.pod b/doc/crypto/BIO_should_retry.pod index ab67a46114..6d291b1888 100644 --- a/doc/crypto/BIO_should_retry.pod +++ b/doc/crypto/BIO_should_retry.pod @@ -46,7 +46,7 @@ reason other than reading or writing is the cause of the condition. BIO_get_retry_reason() returns a mask of the cause of a retry condition consisting of the values B, B, B though current BIO types will only set one of -these (Q: is this correct?). +these. BIO_get_retry_BIO() determines the precise reason for the special condition, it returns the BIO that caused this condition and if @@ -55,7 +55,7 @@ the reason code and the action that should be taken depends on the type of BIO that resulted in this condition. BIO_get_retry_reason() returns the reason for a special condition if -pass the relevant BIO, for example as returned by BIO_get_retry_BIO(). +passed the relevant BIO, for example as returned by BIO_get_retry_BIO(). =head1 NOTES @@ -68,27 +68,17 @@ has reached EOF. Some BIO types may place additional information on the error queue. For more details see the individual BIO type manual pages. -If the underlying I/O structure is in a blocking mode then most BIO -types will not signal a retry condition, because the underlying I/O +If the underlying I/O structure is in a blocking mode almost all current +BIO types will not request a retry, because the underlying I/O calls will not. If the application knows that the BIO type will never signal a retry then it need not call BIO_should_retry() after a failed BIO I/O call. This is typically done with file BIOs. -The presence of an SSL BIO is an exception to this rule: it can -request a retry because the handshake process is underway (either -initially or due to a session renegotiation) even if the underlying -I/O structure (for example a socket) is in a blocking mode. - -The action an application should take after a BIO has signalled that a -retry is required depends on the BIO that caused the retry. - -If the underlying I/O structure is in a blocking mode then the BIO -call can be retried immediately. That is something like this can be -done: - - do { - len = BIO_read(bio, buf, len); - } while((len <= 0) && BIO_should_retry(bio)); +SSL BIOs are the only current exception to this rule: they can request a +retry even if the underlying I/O structure is blocking, if a handshake +occurs during a call to BIO_read(). An application can retry the failed +call immediately or avoid this situation by setting SSL_MODE_AUTO_RETRY +on the underlying SSL structure. While an application may retry a failed non blocking call immediately this is likely to be very inefficient because the call will fail @@ -100,18 +90,9 @@ For example if the cause is ultimately a socket and BIO_should_read() is true then a call to select() may be made to wait until data is available and then retry the BIO operation. By combining the retry conditions of several non blocking BIOs in a single select() call -it is possible to service several BIOs in a single thread. - -The cause of the retry condition may not be the same as the call that -made it: for example if BIO_write() fails BIO_should_read() can be -true. One possible reason for this is that an SSL handshake is taking -place. - -Even if data is read from the underlying I/O structure this does not -imply that the next BIO I/O call will succeed. For example if an -encryption BIO reads only a fraction of a block it will not be -able to pass any data to the application until a complete block has -been read. +it is possible to service several BIOs in a single thread, though +the performance may be poor if SSL BIOs are present because long delays +can occur during the initial handshake process. It is possible for a BIO to block indefinitely if the underlying I/O structure cannot process or return any data. This depends on the behaviour of diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c index e3d02e6007..1414079853 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c @@ -899,19 +899,21 @@ start: return(-1); } - if (s->s3->rbuf.left == 0) /* no read-ahead left? */ + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - BIO *bio; - /* In the case where we try to read application data - * the first time, but we trigger an SSL handshake, we - * return -1 with the retry option set. I do this - * otherwise renegotiation can cause nasty problems - * in the blocking world */ /* ? */ - s->rwstate=SSL_READING; - bio=SSL_get_rbio(s); - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return(-1); + if (s->s3->rbuf.left == 0) /* no read-ahead left? */ + { + BIO *bio; + /* In the case where we try to read application data, + * but we trigger an SSL handshake, we return -1 with + * the retry option set. Otherwise renegotiation may + * cause nasty problems in the blocking world */ + s->rwstate=SSL_READING; + bio=SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return(-1); + } } } } @@ -1022,19 +1024,21 @@ start: return(-1); } - if (s->s3->rbuf.left == 0) /* no read-ahead left? */ + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - BIO *bio; - /* In the case where we try to read application data - * the first time, but we trigger an SSL handshake, we - * return -1 with the retry option set. I do this - * otherwise renegotiation can cause nasty problems - * in the blocking world */ /* ? */ - s->rwstate=SSL_READING; - bio=SSL_get_rbio(s); - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return(-1); + if (s->s3->rbuf.left == 0) /* no read-ahead left? */ + { + BIO *bio; + /* In the case where we try to read application data, + * but we trigger an SSL handshake, we return -1 with + * the retry option set. Otherwise renegotiation may + * cause nasty problems in the blocking world */ + s->rwstate=SSL_READING; + bio=SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return(-1); + } } goto start; } diff --git a/ssl/ssl.h b/ssl/ssl.h index f418b9921b..6ffeca4d31 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -335,6 +335,9 @@ typedef struct ssl_session_st * the misconception that non-blocking SSL_write() behaves like * non-blocking write(): */ #define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L +/* Never bother the application with retries if the transport + * is blocking: */ +#define SSL_MODE_AUTO_RETRY 0x00000004L /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, * they cannot be used to clear bits. */ -- 2.25.1