From a0aae68cf6f3383f248c0e1991973224f2e4498f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bodo=20M=C3=B6ller?= Date: Mon, 25 Dec 2000 18:40:46 +0000 Subject: Fix SSL_peek and SSL_pending. --- ssl/s2_lib.c | 3 --- ssl/s2_pkt.c | 58 +++++++++++++++++++++++++++++----------------------------- ssl/s3_lib.c | 3 +-- ssl/s3_pkt.c | 28 ++++++++++++++-------------- 4 files changed, 44 insertions(+), 48 deletions(-) (limited to 'ssl') diff --git a/ssl/s2_lib.c b/ssl/s2_lib.c index 52a2b27963..a89958607c 100644 --- a/ssl/s2_lib.c +++ b/ssl/s2_lib.c @@ -260,9 +260,6 @@ SSL_CIPHER *ssl2_get_cipher(unsigned int u) int ssl2_pending(SSL *s) { - /* Unlike ssl2_pending, this one probably works (if read-ahead - * is disabled), but it should be examined - * XXX */ return(s->s2->ract_data_length); } diff --git a/ssl/s2_pkt.c b/ssl/s2_pkt.c index 2866d61fa4..0ec9ee3393 100644 --- a/ssl/s2_pkt.c +++ b/ssl/s2_pkt.c @@ -138,7 +138,7 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) return -1; } -ssl2_read_again: + ssl2_read_again: if (SSL_in_init(s) && !s->in_handshake) { n=s->handshake_func(s); @@ -162,13 +162,22 @@ ssl2_read_again: n=len; memcpy(buf,s->s2->ract_data,(unsigned int)n); - s->s2->ract_data_length-=n; - s->s2->ract_data+=n; - if (s->s2->ract_data_length == 0) - s->rstate=SSL_ST_READ_HEADER; + if (!peek) + { + s->s2->ract_data_length-=n; + s->s2->ract_data+=n; + if (s->s2->ract_data_length == 0) + s->rstate=SSL_ST_READ_HEADER; + } + return(n); } + /* s->s2->ract_data_length == 0 + * + * Fill the buffer, then goto ssl2_read_again. + */ + if (s->rstate == SSL_ST_READ_HEADER) { if (s->first_packet) @@ -266,33 +275,24 @@ ssl2_read_again: INC32(s->s2->read_sequence); /* expect next number */ /* s->s2->ract_data is now available for processing */ -#if 1 - /* How should we react when a packet containing 0 - * bytes is received? (Note that SSLeay/OpenSSL itself - * never sends such packets; see ssl2_write.) - * Returning 0 would be interpreted by the caller as - * indicating EOF, so it's not a good idea. - * Instead, we just continue reading. Note that using - * select() for blocking sockets *never* guarantees + /* Possibly the packet that we just read had 0 actual data bytes. + * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.) + * In this case, returning 0 would be interpreted by the caller + * as indicating EOF, so it's not a good idea. Instead, we just + * continue reading; thus ssl2_read_internal may have to process + * multiple packets before it can return. + * + * [Note that using select() for blocking sockets *never* guarantees * that the next SSL_read will not block -- the available - * data may contain incomplete packets, and except for SSL 2 - * renegotiation can confuse things even more. */ + * data may contain incomplete packets, and except for SSL 2, + * renegotiation can confuse things even more.] */ goto ssl2_read_again; /* This should really be - * "return ssl2_read(s,buf,len)", - * but that would allow for - * denial-of-service attacks if a - * C compiler is used that does not - * recognize end-recursion. */ -#else - /* If a 0 byte packet was sent, return 0, otherwise - * we play havoc with people using select with - * blocking sockets. Let them handle a packet at a time, - * they should really be using non-blocking sockets. */ - if (s->s2->ract_data_length == 0) - return(0); - return(ssl2_read(s,buf,len)); -#endif + * "return ssl2_read(s,buf,len)", + * but that would allow for + * denial-of-service attacks if a + * C compiler is used that does not + * recognize end-recursion. */ } else { diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index f2bfb15a5a..47768cc281 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -782,8 +782,7 @@ SSL_CIPHER *ssl3_get_cipher(unsigned int u) int ssl3_pending(SSL *s) { - /* The problem is that it may not be the correct record type */ - return(s->s3->rrec.length); /* FIXME */ + return (s->s3->rrec.type == SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length : 0; } int ssl3_new(SSL *s) diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c index 92d9a4ab1b..9ab76604a6 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c @@ -711,17 +711,12 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) SSL3_RECORD *rr; void (*cb)()=NULL; - if (peek) - { - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_FIXME); /* proper implementation not yet completed */ - return -1; - } - if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ if (!ssl3_setup_buffers(s)) return(-1); - if ((type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE) && type) + if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE) && type) || + (peek && (type != SSL3_RT_APPLICATION_DATA))) { SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_INTERNAL_ERROR); return -1; @@ -734,6 +729,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) unsigned char *dst = buf; unsigned int k; + /* peek == 0 */ n = 0; while ((len > 0) && (s->s3->handshake_fragment_len > 0)) { @@ -769,7 +765,7 @@ start: * s->s3->rrec.length, - number of bytes. */ rr = &(s->s3->rrec); - /* get new packet */ + /* get new packet if necessary */ if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) { ret=ssl3_get_record(s); @@ -787,7 +783,8 @@ start: goto err; } - /* If the other end has shutdown, throw anything we read away */ + /* If the other end has shut down, throw anything we read away + * (even in 'peek' mode) */ if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { rr->length=0; @@ -816,12 +813,15 @@ start: n = (unsigned int)len; memcpy(buf,&(rr->data[rr->off]),n); - rr->length-=n; - rr->off+=n; - if (rr->length == 0) + if (!peek) { - s->rstate=SSL_ST_READ_HEADER; - rr->off=0; + rr->length-=n; + rr->off+=n; + if (rr->length == 0) + { + s->rstate=SSL_ST_READ_HEADER; + rr->off=0; + } } return(n); } -- cgit v1.2.3