Clean up some of the SSL server code.

This commit is contained in:
Bodo Möller 2000-01-11 01:07:26 +00:00
parent 7e3d8df1bb
commit c51ae173a6
7 changed files with 142 additions and 105 deletions

View File

@ -4,6 +4,11 @@
Changes between 0.9.4 and 0.9.5 [xx XXX 1999] Changes between 0.9.4 and 0.9.5 [xx XXX 1999]
*) Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs,
including a possible buffer overflow when the 'read_ahead'
flag is set.
[Bodo Moeller]
*) New function X509_CTX_rget_chain(), this returns the chain *) New function X509_CTX_rget_chain(), this returns the chain
from an X509_CTX structure with a dup of the stack and all from an X509_CTX structure with a dup of the stack and all
the X509 reference counts upped: so the stack will exist the X509 reference counts upped: so the stack will exist

View File

@ -186,7 +186,18 @@ end:
int ssl23_get_client_hello(SSL *s) int ssl23_get_client_hello(SSL *s)
{ {
char buf_space[11]; /* request this many bytes in initial read */ char buf_space[11]; /* Request this many bytes in initial read.
* We can detect SSL 3.0/TLS 1.0 Client Hellos only
* when the following is in a single record
* (not guaranteed by protocol specs):
* Byte Content
* 0 type \
* 1/2 version > record header
* 3/4 length /
* 5 msg_type \
* 6-8 length > Client Hello message
* 9/10 client_version /
*/
char *buf= &(buf_space[0]); char *buf= &(buf_space[0]);
unsigned char *p,*d,*dd; unsigned char *p,*d,*dd;
unsigned int i; unsigned int i;

View File

@ -55,6 +55,59 @@
* copied and put under another distribution licence * copied and put under another distribution licence
* [including the GNU Public Licence.] * [including the GNU Public Licence.]
*/ */
/* ====================================================================
* Copyright (c) 1998-1999 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).
*
*/
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
@ -71,104 +124,91 @@ static int ssl3_get_record(SSL *s);
static int do_compress(SSL *ssl); static int do_compress(SSL *ssl);
static int do_uncompress(SSL *ssl); static int do_uncompress(SSL *ssl);
static int do_change_cipher_spec(SSL *ssl); static int do_change_cipher_spec(SSL *ssl);
static int ssl3_read_n(SSL *s, int n, int max, int extend) static int ssl3_read_n(SSL *s, int n, int max, int extend)
{ {
/* If extend == 0, obtain new n-byte packet; if extend == 1, increase
* packet by another n bytes.
* The packet will be in the sub-array of s->s3->rbuf.buf specified
* by s->packet and s->packet_length.
* (If s->read_ahead is set, 'max' bytes may be stored in rbuf
* [plus s->packet_length bytes if extend == 1].)
*/
int i,off,newb; int i,off,newb;
/* if there is stuff still in the buffer from a previous read, if (!extend)
* and there is more than we want, take some. */ {
/* start with empty packet ... */
if (s->s3->rbuf.left == 0)
s->s3->rbuf.offset = 0;
s->packet = s->s3->rbuf.buf + s->s3->rbuf.offset;
s->packet_length = 0;
/* ... now we can act as if 'extend' was set */
}
/* if there is enough in the buffer from a previous read, take some */
if (s->s3->rbuf.left >= (int)n) if (s->s3->rbuf.left >= (int)n)
{ {
if (extend) s->packet_length+=n;
s->packet_length+=n;
else
{
s->packet= &(s->s3->rbuf.buf[s->s3->rbuf.offset]);
s->packet_length=n;
}
s->s3->rbuf.left-=n; s->s3->rbuf.left-=n;
s->s3->rbuf.offset+=n; s->s3->rbuf.offset+=n;
return(n); return(n);
} }
/* else we need to read more data */ /* else we need to read more data */
if (!s->read_ahead) max=n; if (!s->read_ahead)
if (max > SSL3_RT_MAX_PACKET_SIZE) max=n;
max=SSL3_RT_MAX_PACKET_SIZE;
/* First check if there is some left or we want to extend */ {
off=0; /* avoid buffer overflow */
if ( (s->s3->rbuf.left != 0) || int max_max = SSL3_RT_MAX_PACKET_SIZE - s->packet_length;
((s->packet_length != 0) && extend)) if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
max_max += SSL3_RT_MAX_EXTRA;
if (max > max_max)
max = max_max;
}
off = s->packet_length;
newb = s->s3->rbuf.left;
/* Move any available bytes to front of buffer:
* 'off' bytes already pointed to by 'packet',
* 'newb' extra ones at the end */
if (s->packet != s->s3->rbuf.buf)
{ {
newb=s->s3->rbuf.left; /* off > 0 */
if (extend) memmove(s->s3->rbuf.buf, s->packet, off+newb);
{ s->packet = s->s3->rbuf.buf;
/* Copy bytes back to the front of the buffer
* Take the bytes already pointed to by 'packet'
* and take the extra ones on the end. */
off=s->packet_length;
if (s->packet != s->s3->rbuf.buf)
memcpy(s->s3->rbuf.buf,s->packet,newb+off);
}
else if (s->s3->rbuf.offset != 0)
{ /* so the data is not at the start of the buffer */
memcpy(s->s3->rbuf.buf,
&(s->s3->rbuf.buf[s->s3->rbuf.offset]),newb);
s->s3->rbuf.offset=0;
}
s->s3->rbuf.left=0;
} }
else
newb=0;
/* So we now have 'newb' bytes at the front of
* s->s3->rbuf.buf and need to read some more in on the end
* We start reading into the buffer at 's->s3->rbuf.offset'
*/
s->packet=s->s3->rbuf.buf;
while (newb < n) while (newb < n)
{ {
/* Now we have off+newb bytes at the front of s->s3->rbuf.buf and need
* to read in more until we have off+n (up to off+max if possible) */
clear_sys_error(); clear_sys_error();
if (s->rbio != NULL) if (s->rbio != NULL)
{ {
s->rwstate=SSL_READING; s->rwstate=SSL_READING;
i=BIO_read(s->rbio, i=BIO_read(s->rbio, &(s->s3->rbuf.buf[off+newb]), max-newb);
(char *)&(s->s3->rbuf.buf[off+newb]),
max-newb);
} }
else else
{ {
SSLerr(SSL_F_SSL3_READ_N,SSL_R_READ_BIO_NOT_SET); SSLerr(SSL_F_SSL3_READ_N,SSL_R_READ_BIO_NOT_SET);
i= -1; i = -1;
} }
if (i <= 0) if (i <= 0)
{ {
s->s3->rbuf.left+=newb; s->s3->rbuf.left = newb;
return(i); return(i);
} }
newb+=i; newb+=i;
} }
/* record used data read */ /* done reading, now the book-keeping */
if (newb > n) s->s3->rbuf.offset = off + n;
{ s->s3->rbuf.left = newb - n;
s->s3->rbuf.offset=n+off; s->packet_length += n;
s->s3->rbuf.left=newb-n;
}
else
{
s->s3->rbuf.offset=0;
s->s3->rbuf.left=0;
}
if (extend)
s->packet_length+=n;
else
s->packet_length+=n;
return(n); return(n);
} }
@ -176,8 +216,8 @@ static int ssl3_read_n(SSL *s, int n, int max, int extend)
* It will return <= 0 if more data is needed, normally due to an error * It will return <= 0 if more data is needed, normally due to an error
* or non-blocking IO. * or non-blocking IO.
* When it finishes, one packet has been decoded and can be found in * When it finishes, one packet has been decoded and can be found in
* ssl->s3->rrec.type - is the type of record * ssl->s3->rrec.type - is the type of record
* ssl->s3->rrec.data, - data * ssl->s3->rrec.data, - data
* ssl->s3->rrec.length, - number of bytes * ssl->s3->rrec.length, - number of bytes
*/ */
static int ssl3_get_record(SSL *s) static int ssl3_get_record(SSL *s)
@ -262,7 +302,6 @@ again:
if (rr->length > (s->packet_length-SSL3_RT_HEADER_LENGTH)) if (rr->length > (s->packet_length-SSL3_RT_HEADER_LENGTH))
{ {
i=rr->length; i=rr->length;
/*-(s->packet_length-SSL3_RT_HEADER_LENGTH); */
n=ssl3_read_n(s,i,i,1); n=ssl3_read_n(s,i,i,1);
if (n <= 0) return(n); /* error or non-blocking io */ if (n <= 0) return(n); /* error or non-blocking io */
} }
@ -645,7 +684,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len)
void (*cb)()=NULL; void (*cb)()=NULL;
BIO *bio; BIO *bio;
if (s->s3->rbuf.buf == NULL) /* Not initialize yet */ if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
if (!ssl3_setup_buffers(s)) if (!ssl3_setup_buffers(s))
return(-1); return(-1);
@ -662,10 +701,10 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len)
start: start:
s->rwstate=SSL_NOTHING; s->rwstate=SSL_NOTHING;
/* s->s3->rrec.type - is the type of record /* s->s3->rrec.type - is the type of record
* s->s3->rrec.data, - data * s->s3->rrec.data, - data
* s->s3->rrec.off, - ofset into 'data' for next read * s->s3->rrec.off, - offset into 'data' for next read
* s->s3->rrec.length, - number of bytes. */ * s->s3->rrec.length, - number of bytes. */
rr= &(s->s3->rrec); rr= &(s->s3->rrec);
/* get new packet */ /* get new packet */
@ -692,16 +731,16 @@ start:
return(0); return(0);
} }
/* Check for an incoming 'Client Request' message */ /* Check for an incoming 'Hello Request' message from client */
if ((rr->type == SSL3_RT_HANDSHAKE) && (rr->length == 4) && if ((rr->type == SSL3_RT_HANDSHAKE) && (rr->length == 4) &&
(rr->data[0] == SSL3_MT_CLIENT_REQUEST) && (rr->data[0] == SSL3_MT_HELLO_REQUEST) &&
(s->session != NULL) && (s->session->cipher != NULL)) (s->session != NULL) && (s->session->cipher != NULL))
{ {
if ((rr->data[1] != 0) || (rr->data[2] != 0) || if ((rr->data[1] != 0) || (rr->data[2] != 0) ||
(rr->data[3] != 0)) (rr->data[3] != 0))
{ {
al=SSL_AD_DECODE_ERROR; al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_CLIENT_REQUEST); SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
goto err; goto err;
} }
@ -1038,4 +1077,3 @@ int ssl3_dispatch_alert(SSL *s)
} }
return(i); return(i);
} }

View File

@ -503,7 +503,7 @@ static int ssl3_send_hello_request(SSL *s)
if (s->state == SSL3_ST_SW_HELLO_REQ_A) if (s->state == SSL3_ST_SW_HELLO_REQ_A)
{ {
p=(unsigned char *)s->init_buf->data; p=(unsigned char *)s->init_buf->data;
*(p++)=SSL3_MT_CLIENT_REQUEST; *(p++)=SSL3_MT_HELLO_REQUEST;
*(p++)=0; *(p++)=0;
*(p++)=0; *(p++)=0;
*(p++)=0; *(p++)=0;

View File

@ -441,7 +441,7 @@ struct ssl_ctx_st
/* get client cert callback */ /* get client cert callback */
/**/ int (*client_cert_cb)(/* SSL *ssl, X509 **x509, EVP_PKEY **pkey */); /**/ int (*client_cert_cb)(/* SSL *ssl, X509 **x509, EVP_PKEY **pkey */);
/* what we put in client requests */ /* what we put in client cert requests */
STACK_OF(X509_NAME) *client_CA; STACK_OF(X509_NAME) *client_CA;
/**/ int quiet_shutdown; /**/ int quiet_shutdown;
@ -575,7 +575,8 @@ struct ssl_st
struct ssl2_ctx_st *s2; /* SSLv2 variables */ struct ssl2_ctx_st *s2; /* SSLv2 variables */
struct ssl3_ctx_st *s3; /* SSLv3 variables */ struct ssl3_ctx_st *s3; /* SSLv3 variables */
int read_ahead; /* Read as many input bytes as possible */ int read_ahead; /* Read as many input bytes as possible
* (for non-blocking reads) */
int hit; /* reusing a previous session */ int hit; /* reusing a previous session */
int purpose; /* Purpose setting */ int purpose; /* Purpose setting */
@ -1310,7 +1311,7 @@ int SSL_COMP_add_compression_method(int id,char *cm);
#define SSL_R_BAD_AUTHENTICATION_TYPE 102 #define SSL_R_BAD_AUTHENTICATION_TYPE 102
#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 #define SSL_R_BAD_CHANGE_CIPHER_SPEC 103
#define SSL_R_BAD_CHECKSUM 104 #define SSL_R_BAD_CHECKSUM 104
#define SSL_R_BAD_CLIENT_REQUEST 105 #define SSL_R_BAD_HELLO_REQUEST 105
#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 #define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106
#define SSL_R_BAD_DECOMPRESSION 107 #define SSL_R_BAD_DECOMPRESSION 107
#define SSL_R_BAD_DH_G_LENGTH 108 #define SSL_R_BAD_DH_G_LENGTH 108

View File

@ -158,22 +158,6 @@ extern "C" {
#define SSL3_RT_MAX_PACKET_SIZE (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) #define SSL3_RT_MAX_PACKET_SIZE (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
#define SSL3_RT_MAX_DATA_SIZE (1024*1024) #define SSL3_RT_MAX_DATA_SIZE (1024*1024)
/* the states that a SSL3_RECORD can be in
* For SSL_read it goes
* rbuf->ENCODED -> read
* ENCODED -> we need to decode everything - call decode_record
*/
#define SSL3_RS_BLANK 1
#define SSL3_RS_DATA
#define SSL3_RS_ENCODED 2
#define SSL3_RS_READ_MORE 3
#define SSL3_RS_WRITE_MORE
#define SSL3_RS_PLAIN 3
#define SSL3_RS_PART_READ 4
#define SSL3_RS_PART_WRITE 5
#define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" #define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54"
#define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" #define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52"
@ -205,7 +189,6 @@ extern "C" {
typedef struct ssl3_record_st typedef struct ssl3_record_st
{ {
/*r */ int type; /* type of record */ /*r */ int type; /* type of record */
/* */ /*int state;*/ /* any data in it? */
/*rw*/ unsigned int length; /* How many bytes available */ /*rw*/ unsigned int length; /* How many bytes available */
/*r */ unsigned int off; /* read/write offset into 'buf' */ /*r */ unsigned int off; /* read/write offset into 'buf' */
/*rw*/ unsigned char *data; /* pointer to the record data */ /*rw*/ unsigned char *data; /* pointer to the record data */
@ -215,11 +198,10 @@ typedef struct ssl3_record_st
typedef struct ssl3_buffer_st typedef struct ssl3_buffer_st
{ {
/*r */ int total; /* used in non-blocking writes */ unsigned char *buf; /* SSL3_RT_MAX_PACKET_SIZE bytes (more if
/*r */ int wanted; /* how many more bytes we need */ * SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER is set) */
/*rw*/ int left; /* how many bytes left */ int offset; /* where to 'copy from' */
/*rw*/ int offset; /* where to 'copy from' */ int left; /* how many bytes left */
/*rw*/ unsigned char *buf; /* SSL3_RT_MAX_PACKET_SIZE bytes */
} SSL3_BUFFER; } SSL3_BUFFER;
#define SSL3_CT_RSA_SIGN 1 #define SSL3_CT_RSA_SIGN 1
@ -436,7 +418,7 @@ typedef struct ssl3_ctx_st
#define SSL3_ST_SW_FINISHED_A (0x1E0|SSL_ST_ACCEPT) #define SSL3_ST_SW_FINISHED_A (0x1E0|SSL_ST_ACCEPT)
#define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT) #define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT)
#define SSL3_MT_CLIENT_REQUEST 0 #define SSL3_MT_HELLO_REQUEST 0
#define SSL3_MT_CLIENT_HELLO 1 #define SSL3_MT_CLIENT_HELLO 1
#define SSL3_MT_SERVER_HELLO 2 #define SSL3_MT_SERVER_HELLO 2
#define SSL3_MT_CERTIFICATE 11 #define SSL3_MT_CERTIFICATE 11

View File

@ -205,7 +205,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{SSL_R_BAD_AUTHENTICATION_TYPE ,"bad authentication type"}, {SSL_R_BAD_AUTHENTICATION_TYPE ,"bad authentication type"},
{SSL_R_BAD_CHANGE_CIPHER_SPEC ,"bad change cipher spec"}, {SSL_R_BAD_CHANGE_CIPHER_SPEC ,"bad change cipher spec"},
{SSL_R_BAD_CHECKSUM ,"bad checksum"}, {SSL_R_BAD_CHECKSUM ,"bad checksum"},
{SSL_R_BAD_CLIENT_REQUEST ,"bad client request"}, {SSL_R_BAD_HELLO_REQUEST ,"bad hello request"},
{SSL_R_BAD_DATA_RETURNED_BY_CALLBACK ,"bad data returned by callback"}, {SSL_R_BAD_DATA_RETURNED_BY_CALLBACK ,"bad data returned by callback"},
{SSL_R_BAD_DECOMPRESSION ,"bad decompression"}, {SSL_R_BAD_DECOMPRESSION ,"bad decompression"},
{SSL_R_BAD_DH_G_LENGTH ,"bad dh g length"}, {SSL_R_BAD_DH_G_LENGTH ,"bad dh g length"},