From 58964a492275ca9a59a0cd9c8155cb2491b4b909 Mon Sep 17 00:00:00 2001 From: "Ralf S. Engelschall" Date: Mon, 21 Dec 1998 10:56:39 +0000 Subject: Import of old SSLeay release: SSLeay 0.9.0b --- ssl/Makefile.ssl | 18 +- ssl/bio_ssl.c | 249 ++++++++++++++++---- ssl/s23_clnt.c | 96 +++++--- ssl/s23_lib.c | 15 +- ssl/s23_meth.c | 8 +- ssl/s23_pkt.c | 2 +- ssl/s23_srvr.c | 107 +++++---- ssl/s2_clnt.c | 25 +- ssl/s2_enc.c | 8 +- ssl/s2_lib.c | 45 ++-- ssl/s2_meth.c | 4 +- ssl/s2_pkt.c | 28 +-- ssl/s2_srvr.c | 59 ++--- ssl/s3_both.c | 137 ++++++----- ssl/s3_clnt.c | 242 +++++++++++--------- ssl/s3_enc.c | 162 ++++++++++--- ssl/s3_lib.c | 184 +++++++++------ ssl/s3_meth.c | 6 +- ssl/s3_pkt.c | 262 ++++++++++++++------- ssl/s3_srvr.c | 278 +++++++++++++---------- ssl/ssl.c | 2 +- ssl/ssl.err | 336 ++++++++++++++------------- ssl/ssl.h | 677 ++++++++++++++++++++++++++++++++++--------------------- ssl/ssl2.h | 6 +- ssl/ssl23.h | 2 +- ssl/ssl3.h | 56 ++++- ssl/ssl_algs.c | 5 +- ssl/ssl_asn1.c | 12 +- ssl/ssl_cert.c | 19 +- ssl/ssl_ciph.c | 223 ++++++++++-------- ssl/ssl_err.c | 30 ++- ssl/ssl_err2.c | 2 +- ssl/ssl_lib.c | 386 +++++++++++++++++++++++++++---- ssl/ssl_locl.h | 82 +++++-- ssl/ssl_rsa.c | 71 +++--- ssl/ssl_sess.c | 203 +++++++++++++++-- ssl/ssl_stat.c | 3 +- ssl/ssl_task.c | 2 +- ssl/ssl_txt.c | 29 ++- ssl/ssltest.c | 234 ++++++++++++++----- ssl/t1_clnt.c | 90 ++++++++ ssl/t1_enc.c | 635 +++++++++++++++++++++++++++++++++++++++++++++++++++ ssl/t1_lib.c | 151 +++++++++++++ ssl/t1_meth.c | 88 ++++++++ ssl/t1_srvr.c | 91 ++++++++ ssl/tls1.h | 115 ++++++++++ 46 files changed, 4036 insertions(+), 1449 deletions(-) create mode 100644 ssl/t1_clnt.c create mode 100644 ssl/t1_enc.c create mode 100644 ssl/t1_lib.c create mode 100644 ssl/t1_meth.c create mode 100644 ssl/t1_srvr.c create mode 100644 ssl/tls1.h (limited to 'ssl') diff --git a/ssl/Makefile.ssl b/ssl/Makefile.ssl index f6f40e44fc..f4b13bf83b 100644 --- a/ssl/Makefile.ssl +++ b/ssl/Makefile.ssl @@ -23,17 +23,19 @@ APPS= LIB=$(TOP)/libssl.a LIBSRC= \ - s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_pkt.c s2_enc.c \ - s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_pkt.c s3_enc.c s3_both.c \ - s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \ + s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_enc.c s2_pkt.c \ + s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c \ + s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \ + t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \ ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \ ssl_ciph.c ssl_stat.c ssl_rsa.c \ ssl_asn1.c ssl_txt.c ssl_algs.c \ bio_ssl.c $(ERRC).c LIBOBJ= \ - s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_pkt.o s2_enc.o \ - s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_pkt.o s3_enc.o s3_both.o \ - s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \ + s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \ + s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \ + s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \ + t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o \ ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \ ssl_ciph.o ssl_stat.o ssl_rsa.o \ ssl_asn1.o ssl_txt.o ssl_algs.o \ @@ -41,7 +43,7 @@ LIBOBJ= \ SRC= $(LIBSRC) -EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h +EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h tls1.h HEADER= $(EXHEADER) ssl_locl.h ALL= $(GENERAL) $(SRC) $(HEADER) @@ -93,6 +95,6 @@ clean: errors: perl $(TOP)/util/err-ins.pl $(ERR).err $(ERR).h - perl ../crypto/err/err_genc.pl $(ERR).h $(ERRC).c + perl ../crypto/err/err_genc.pl -s $(ERR).h $(ERRC).c # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c index 6c0babaf30..58a6d69b9b 100644 --- a/ssl/bio_ssl.c +++ b/ssl/bio_ssl.c @@ -1,5 +1,5 @@ /* ssl/bio_ssl.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -57,8 +57,10 @@ */ #include +#include #include #include +#include "crypto.h" #include "bio.h" #include "err.h" #include "ssl.h" @@ -79,6 +81,17 @@ static int ssl_new(); static int ssl_free(); #endif +typedef struct bio_ssl_st + { + SSL *ssl; /* The ssl handle :-) */ + /* re-negotiate every time the total number of bytes is this size */ + int num_renegotiates; + unsigned long renegotiate_count; + unsigned long byte_count; + unsigned long renegotiate_timeout; + unsigned long last_time; + } BIO_SSL; + static BIO_METHOD methods_sslp= { BIO_TYPE_SSL,"ssl", @@ -99,8 +112,17 @@ BIO_METHOD *BIO_f_ssl() static int ssl_new(bi) BIO *bi; { + BIO_SSL *bs; + + bs=(BIO_SSL *)Malloc(sizeof(BIO_SSL)); + if (bs == NULL) + { + BIOerr(BIO_F_SSL_NEW,ERR_R_MALLOC_FAILURE); + return(0); + } + memset(bs,0,sizeof(BIO_SSL)); bi->init=0; - bi->ptr=NULL; /* The SSL structure */ + bi->ptr=(char *)bs; bi->flags=0; return(1); } @@ -108,15 +130,20 @@ BIO *bi; static int ssl_free(a) BIO *a; { + BIO_SSL *bs; + if (a == NULL) return(0); - if (a->ptr != NULL) SSL_shutdown((SSL *)a->ptr); + bs=(BIO_SSL *)a->ptr; + if (bs->ssl != NULL) SSL_shutdown(bs->ssl); if (a->shutdown) { - if (a->init) SSL_free((SSL *)a->ptr); + if (a->init && (bs->ssl != NULL)) + SSL_free(bs->ssl); a->init=0; a->flags=0; - a->ptr=NULL; } + if (a->ptr != NULL) + Free(a->ptr); return(1); } @@ -126,49 +153,74 @@ char *out; int outl; { int ret=1; - int inflags,outflags; + BIO_SSL *sb; SSL *ssl; int retry_reason=0; + int r=0; if (out == NULL) return(0); - ssl=(SSL *)b->ptr; + sb=(BIO_SSL *)b->ptr; + ssl=sb->ssl; - inflags=outflags=b->flags; - - outflags&= ~(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY); + BIO_clear_retry_flags(b); +#if 0 if (!SSL_is_init_finished(ssl)) { - ret=SSL_do_handshake(ssl); -#if 0 +/* ret=SSL_do_handshake(ssl); */ if (ret > 0) { + outflags=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY); ret= -1; goto end; } -#endif } - if (ret > 0) - ret=SSL_read(ssl,out,outl); +#endif +/* if (ret > 0) */ + ret=SSL_read(ssl,out,outl); switch (SSL_get_error(ssl,ret)) { case SSL_ERROR_NONE: if (ret <= 0) break; + if (sb->renegotiate_count > 0) + { + sb->byte_count+=ret; + if (sb->byte_count > sb->renegotiate_count) + { + sb->byte_count=0; + sb->num_renegotiates++; + SSL_renegotiate(ssl); + r=1; + } + } + if ((sb->renegotiate_timeout > 0) && (!r)) + { + unsigned long tm; + + tm=(unsigned long)time(NULL); + if (tm > sb->last_time+sb->renegotiate_timeout) + { + sb->last_time=tm; + sb->num_renegotiates++; + SSL_renegotiate(ssl); + } + } + break; case SSL_ERROR_WANT_READ: - outflags=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY); + BIO_set_retry_read(b); break; case SSL_ERROR_WANT_WRITE: - outflags=(BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY); + BIO_set_retry_write(b); break; case SSL_ERROR_WANT_X509_LOOKUP: - outflags=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY); + BIO_set_retry_special(b); retry_reason=BIO_RR_SSL_X509_LOOKUP; break; case SSL_ERROR_WANT_CONNECT: - outflags=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY); + BIO_set_retry_special(b); retry_reason=BIO_RR_CONNECT; break; case SSL_ERROR_SYSCALL: @@ -179,7 +231,6 @@ int outl; } b->retry_reason=retry_reason; - b->flags=outflags; return(ret); } @@ -188,38 +239,61 @@ BIO *b; char *out; int outl; { - int ret; - int inflags,outflags,retry_reason=0; + int ret,r=0; + int retry_reason=0; SSL *ssl; + BIO_SSL *bs; if (out == NULL) return(0); - ssl=(SSL *)b->ptr; - - inflags=outflags=b->flags; + bs=(BIO_SSL *)b->ptr; + ssl=bs->ssl; - outflags&= ~(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY); + BIO_clear_retry_flags(b); - ret=SSL_do_handshake(ssl); - if (ret > 0) - ret=SSL_write(ssl,out,outl); +/* ret=SSL_do_handshake(ssl); + if (ret > 0) */ + ret=SSL_write(ssl,out,outl); switch (SSL_get_error(ssl,ret)) { case SSL_ERROR_NONE: if (ret <= 0) break; + if (bs->renegotiate_count > 0) + { + bs->byte_count+=ret; + if (bs->byte_count > bs->renegotiate_count) + { + bs->byte_count=0; + bs->num_renegotiates++; + SSL_renegotiate(ssl); + r=1; + } + } + if ((bs->renegotiate_timeout > 0) && (!r)) + { + unsigned long tm; + + tm=(unsigned long)time(NULL); + if (tm > bs->last_time+bs->renegotiate_timeout) + { + bs->last_time=tm; + bs->num_renegotiates++; + SSL_renegotiate(ssl); + } + } break; case SSL_ERROR_WANT_WRITE: - outflags=(BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY); + BIO_set_retry_write(b); break; case SSL_ERROR_WANT_READ: - outflags=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY); + BIO_set_retry_read(b); break; case SSL_ERROR_WANT_X509_LOOKUP: - outflags=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY); + BIO_set_retry_special(b); retry_reason=BIO_RR_SSL_X509_LOOKUP; break; case SSL_ERROR_WANT_CONNECT: - outflags=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY); + BIO_set_retry_special(b); retry_reason=BIO_RR_CONNECT; case SSL_ERROR_SYSCALL: case SSL_ERROR_SSL: @@ -228,7 +302,6 @@ int outl; } b->retry_reason=retry_reason; - b->flags=outflags; return(ret); } @@ -239,10 +312,14 @@ long num; char *ptr; { SSL **sslp,*ssl; + BIO_SSL *bs; BIO *dbio,*bio; long ret=1; - ssl=(SSL *)b->ptr; + bs=(BIO_SSL *)b->ptr; + ssl=bs->ssl; + if ((ssl == NULL) && (cmd != BIO_C_SET_SSL)) + return(0); switch (cmd) { case BIO_CTRL_RESET: @@ -262,7 +339,6 @@ char *ptr; else ret=1; break; - case BIO_CTRL_EOF: case BIO_CTRL_INFO: ret=0; break; @@ -272,17 +348,33 @@ char *ptr; else SSL_set_accept_state(ssl); break; + case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT: + ret=bs->renegotiate_timeout; + if (num < 60) num=5; + bs->renegotiate_timeout=(unsigned long)num; + bs->last_time=(unsigned long)time(NULL); + break; + case BIO_C_SET_SSL_RENEGOTIATE_BYTES: + ret=bs->renegotiate_count; + if ((long)num >=512) + bs->renegotiate_count=(unsigned long)num; + break; + case BIO_C_GET_SSL_NUM_RENEGOTIATES: + ret=bs->num_renegotiates; + break; case BIO_C_SET_SSL: - ssl_free(b); + if (ssl != NULL) + ssl_free(b); b->shutdown=(int)num; - b->ptr=ptr; ssl=(SSL *)ptr; + ((BIO_SSL *)b->ptr)->ssl=ssl; bio=SSL_get_rbio(ssl); if (bio != NULL) { if (b->next_bio != NULL) BIO_push(bio,b->next_bio); b->next_bio=bio; + CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO); } b->init=1; break; @@ -292,6 +384,8 @@ char *ptr; sslp=(SSL **)ptr; *sslp=ssl; } + else + ret=0; break; case BIO_CTRL_GET_CLOSE: ret=b->shutdown; @@ -313,10 +407,10 @@ char *ptr; BIO_copy_next_retry(b); break; case BIO_CTRL_PUSH: - if (b->next_bio != NULL) + if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) { SSL_set_bio(ssl,b->next_bio,b->next_bio); - b->next_bio->references++; + CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO); } break; case BIO_CTRL_POP: @@ -355,13 +449,35 @@ char *ptr; break; case BIO_CTRL_DUP: dbio=(BIO *)ptr; - if (dbio->ptr != NULL) - SSL_free((SSL *)dbio->ptr); - dbio->ptr=(char *)SSL_dup(ssl); - ret=(dbio->ptr != NULL); + if (((BIO_SSL *)dbio->ptr)->ssl != NULL) + SSL_free(((BIO_SSL *)dbio->ptr)->ssl); + ((BIO_SSL *)dbio->ptr)->ssl=SSL_dup(ssl); + ((BIO_SSL *)dbio->ptr)->renegotiate_count= + ((BIO_SSL *)b->ptr)->renegotiate_count; + ((BIO_SSL *)dbio->ptr)->byte_count= + ((BIO_SSL *)b->ptr)->byte_count; + ((BIO_SSL *)dbio->ptr)->renegotiate_timeout= + ((BIO_SSL *)b->ptr)->renegotiate_timeout; + ((BIO_SSL *)dbio->ptr)->last_time= + ((BIO_SSL *)b->ptr)->last_time; + ret=(((BIO_SSL *)dbio->ptr)->ssl != NULL); + break; + case BIO_C_GET_FD: + ret=BIO_ctrl(ssl->rbio,cmd,num,ptr); + break; + case BIO_CTRL_SET_CALLBACK: + SSL_set_info_callback(ssl,(void (*)())ptr); + break; + case BIO_CTRL_GET_CALLBACK: + { + void (**fptr)(); + + fptr=(void (**)())ptr; + *fptr=SSL_get_info_callback(ssl); + } break; default: - return(0); + ret=BIO_ctrl(ssl->rbio,cmd,num,ptr); break; } return(ret); @@ -378,6 +494,42 @@ char *str; return(ret); } +BIO *BIO_new_buffer_ssl_connect(ctx) +SSL_CTX *ctx; + { + BIO *ret=NULL,*buf=NULL,*ssl=NULL; + + if ((buf=BIO_new(BIO_f_buffer())) == NULL) + return(NULL); + if ((ssl=BIO_new_ssl_connect(ctx)) == NULL) + goto err; + if ((ret=BIO_push(buf,ssl)) == NULL) + goto err; + return(ret); +err: + if (buf != NULL) BIO_free(buf); + if (ssl != NULL) BIO_free(ssl); + return(NULL); + } + +BIO *BIO_new_ssl_connect(ctx) +SSL_CTX *ctx; + { + BIO *ret=NULL,*con=NULL,*ssl=NULL; + + if ((con=BIO_new(BIO_s_connect())) == NULL) + return(NULL); + if ((ssl=BIO_new_ssl(ctx,1)) == NULL) + goto err; + if ((ret=BIO_push(ssl,con)) == NULL) + goto err; + return(ret); +err: + if (con != NULL) BIO_free(con); + if (ret != NULL) BIO_free(ret); + return(NULL); + } + BIO *BIO_new_ssl(ctx,client) SSL_CTX *ctx; int client; @@ -408,9 +560,10 @@ BIO *t,*f; f=BIO_find_type(f,BIO_TYPE_SSL); if ((t == NULL) || (f == NULL)) return(0); - if ((t->ptr == NULL) || (f->ptr == NULL)) + if ( (((BIO_SSL *)t->ptr)->ssl == NULL) || + (((BIO_SSL *)f->ptr)->ssl == NULL)) return(0); - SSL_copy_session_id((SSL *)t->ptr,(SSL *)f->ptr); + SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,((BIO_SSL *)f->ptr)->ssl); return(1); } @@ -423,7 +576,7 @@ BIO *b; { if (b->method->type == BIO_TYPE_SSL) { - s=(SSL *)b->ptr; + s=((BIO_SSL *)b->ptr)->ssl; SSL_shutdown(s); break; } diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c index 57d3623f3f..a4661ebb68 100644 --- a/ssl/s23_clnt.c +++ b/ssl/s23_clnt.c @@ -1,5 +1,5 @@ /* ssl/s23_clnt.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -76,10 +76,12 @@ static int ssl23_get_server_hello(); static SSL_METHOD *ssl23_get_client_method(ver) int ver; { - if (ver == 2) + if (ver == SSL2_VERSION) return(SSLv2_client_method()); - else if (ver == 3) + else if (ver == SSL3_VERSION) return(SSLv3_client_method()); + else if (ver == TLS1_VERSION) + return(TLSv1_client_method()); else return(NULL); } @@ -111,7 +113,7 @@ SSL *s; RAND_seed((unsigned char *)&Time,sizeof(Time)); ERR_clear_error(); - errno=0; + clear_sys_error(); if (s->info_callback != NULL) cb=s->info_callback; @@ -134,7 +136,7 @@ SSL *s; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); - s->version=3; + /* s->version=TLS1_VERSION; */ s->type=SSL_ST_CONNECT; if (s->init_buf == NULL) @@ -230,8 +232,26 @@ SSL *s; p=d+9; *(d++)=SSL2_MT_CLIENT_HELLO; - *(d++)=SSL3_VERSION_MAJOR; - *(d++)=SSL3_VERSION_MINOR; + if (!(s->options & SSL_OP_NO_TLSv1)) + { + *(d++)=TLS1_VERSION_MAJOR; + *(d++)=TLS1_VERSION_MINOR; + } + else if (!(s->options & SSL_OP_NO_SSLv3)) + { + *(d++)=SSL3_VERSION_MAJOR; + *(d++)=SSL3_VERSION_MINOR; + } + else if (!(s->options & SSL_OP_NO_SSLv2)) + { + *(d++)=SSL2_VERSION_MAJOR; + *(d++)=SSL2_VERSION_MINOR; + } + else + { + SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_PROTOCOLS_AVAILABLE); + return(-1); + } /* Ciphers supported */ i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),p); @@ -251,7 +271,7 @@ SSL *s; #endif s2n(0,d); - if (s->ctx->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) + if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) ch_len=SSL2_CHALLENGE_LENGTH; else ch_len=SSL2_MAX_CHALLENGE_LENGTH; @@ -290,7 +310,6 @@ SSL *s; unsigned char *p; int i,ch_len; int n; - BIO *bbio; n=ssl23_read_bytes(s,7); @@ -306,6 +325,11 @@ SSL *s; /* we need to clean up the SSLv3 setup and put in the * sslv2 stuff. */ + if (s->options & SSL_OP_NO_SSLv2) + { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); + goto err; + } if (s->s2 == NULL) { if (!ssl2_new(s)) @@ -314,7 +338,7 @@ SSL *s; else ssl2_clear(s); - if (s->ctx->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) + if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) ch_len=SSL2_CHALLENGE_LENGTH; else ch_len=SSL2_MAX_CHALLENGE_LENGTH; @@ -355,33 +379,13 @@ SSL *s; } else if ((p[0] == SSL3_RT_HANDSHAKE) && (p[1] == SSL3_VERSION_MAJOR) && - (p[2] == SSL3_VERSION_MINOR) && + ((p[2] == SSL3_VERSION_MINOR) || + (p[2] == TLS1_VERSION_MINOR)) && (p[5] == SSL3_MT_SERVER_HELLO)) { - /* we have sslv3 */ + /* we have sslv3 or tls1 */ - if (s->bbio == NULL) - { - bbio=BIO_new(BIO_f_buffer()); - if (bbio == NULL) - { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,ERR_R_BUF_LIB); - goto err; - } - s->bbio=bbio; - } - else - bbio=s->bbio; - - BIO_reset(bbio); - if (!BIO_set_write_buffer_size(bbio,16*1024)) - { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,ERR_R_BUF_LIB); - goto err; - } - - /* start the buffering */ - s->wbio=BIO_push(s->bbio,s->wbio); + if (!ssl_init_wbio_buffer(s,1)) goto err; /* we are in this state */ s->state=SSL3_ST_CR_SRVR_HELLO_A; @@ -395,12 +399,30 @@ SSL *s; s->s3->rbuf.left=n; s->s3->rbuf.offset=0; - s->method=SSLv3_client_method(); + if ((p[2] == SSL3_VERSION_MINOR) && + !(s->options & SSL_OP_NO_SSLv3)) + { + s->version=SSL3_VERSION; + s->method=SSLv3_client_method(); + } + else if ((p[2] == TLS1_VERSION_MINOR) && + !(s->options & SSL_OP_NO_TLSv1)) + { + s->version=TLS1_VERSION; + s->method=TLSv1_client_method(); + } + else + { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL); + goto err; + } + s->handshake_func=s->method->ssl_connect; } else if ((p[0] == SSL3_RT_ALERT) && (p[1] == SSL3_VERSION_MAJOR) && - (p[2] == SSL3_VERSION_MINOR) && + ((p[2] == SSL3_VERSION_MINOR) || + (p[2] == TLS1_VERSION_MINOR)) && (p[3] == 0) && (p[4] == 2)) { @@ -421,7 +443,7 @@ SSL *s; } s->rwstate=SSL_NOTHING; - SSLerr(SSL_F_SSL3_READ_BYTES,1000+p[6]); + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,1000+p[6]); goto err; } else diff --git a/ssl/s23_lib.c b/ssl/s23_lib.c index ff19adc119..e16f641101 100644 --- a/ssl/s23_lib.c +++ b/ssl/s23_lib.c @@ -1,5 +1,5 @@ /* ssl/s23_lib.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -81,10 +81,10 @@ static SSL_CIPHER *ssl23_get_cipher_by_char(); char *SSL23_version_str="SSLv2/3 compatablity part of SSLeay 0.7.0 30-Jan-1997"; static SSL_METHOD SSLv23_data= { - 3, - ssl3_new, - ssl3_clear, - ssl3_free, + TLS1_VERSION, + tls1_new, + tls1_clear, + tls1_free, ssl_undefined_function, ssl_undefined_function, ssl23_read, @@ -101,6 +101,7 @@ static SSL_METHOD SSLv23_data= { ssl23_get_cipher, ssl_bad_method, ssl23_default_timeout, + &ssl3_undef_enc_method, }; static long ssl23_default_timeout() @@ -179,7 +180,7 @@ int len; return(0); } #endif - errno=0; + clear_sys_error(); if (SSL_in_init(s) && (!s->in_handshake)) { n=s->handshake_func(s); @@ -212,7 +213,7 @@ int len; return(0); } #endif - errno=0; + clear_sys_error(); if (SSL_in_init(s) && (!s->in_handshake)) { n=s->handshake_func(s); diff --git a/ssl/s23_meth.c b/ssl/s23_meth.c index dbe282bfd0..1eed7a54bc 100644 --- a/ssl/s23_meth.c +++ b/ssl/s23_meth.c @@ -1,5 +1,5 @@ /* ssl/s23_meth.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -63,10 +63,12 @@ static SSL_METHOD *ssl23_get_method(ver) int ver; { - if (ver == 2) + if (ver == SSL2_VERSION) return(SSLv23_method()); - else if (ver == 3) + else if (ver == SSL3_VERSION) return(SSLv3_method()); + else if (ver == TLS1_VERSION) + return(TLSv1_method()); else return(NULL); } diff --git a/ssl/s23_pkt.c b/ssl/s23_pkt.c index e9b2add0b8..c25c312772 100644 --- a/ssl/s23_pkt.c +++ b/ssl/s23_pkt.c @@ -1,5 +1,5 @@ /* ssl/s23_pkt.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c index 398f005821..c7b9ecbcf2 100644 --- a/ssl/s23_srvr.c +++ b/ssl/s23_srvr.c @@ -1,5 +1,5 @@ /* ssl/s23_srvr.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -74,10 +74,12 @@ int ssl23_get_client_hello(); static SSL_METHOD *ssl23_get_server_method(ver) int ver; { - if (ver == 2) + if (ver == SSL2_VERSION) return(SSLv2_server_method()); - else if (ver == 3) + else if (ver == SSL3_VERSION) return(SSLv3_server_method()); + else if (ver == TLS1_VERSION) + return(TLSv1_server_method()); else return(NULL); } @@ -109,7 +111,7 @@ SSL *s; RAND_seed((unsigned char *)&Time,sizeof(Time)); ERR_clear_error(); - errno=0; + clear_sys_error(); if (s->info_callback != NULL) cb=s->info_callback; @@ -132,7 +134,7 @@ SSL *s; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); - s->version=3; + /* s->version=SSL3_VERSION; */ s->type=SSL_ST_ACCEPT; if (s->init_buf == NULL) @@ -197,8 +199,7 @@ SSL *s; unsigned char *p,*d,*dd; unsigned int i; unsigned int csl,sil,cl; - int n=0,j; - BIO *bbio; + int n=0,j,tls1=0; int type=0,use_sslv2_strong=0; /* read the initial header */ @@ -219,11 +220,28 @@ SSL *s; if ((p[3] == 0x00) && (p[4] == 0x02)) { /* SSLv2 */ - type=1; + if (!(s->options & SSL_OP_NO_SSLv2)) + type=1; } else if (p[3] == SSL3_VERSION_MAJOR) { - if (s->ctx->options & SSL_OP_NON_EXPORT_FIRST) + /* SSLv3/TLSv1 */ + if (p[4] >= TLS1_VERSION_MINOR) + { + if (!(s->options & SSL_OP_NO_TLSv1)) + { + tls1=1; + s->state=SSL23_ST_SR_CLNT_HELLO_B; + } + else if (!(s->options & SSL_OP_NO_SSLv3)) + { + s->state=SSL23_ST_SR_CLNT_HELLO_B; + } + } + else if (!(s->options & SSL_OP_NO_SSLv3)) + s->state=SSL23_ST_SR_CLNT_HELLO_B; + + if (s->options & SSL_OP_NON_EXPORT_FIRST) { STACK *sk; SSL_CIPHER *c; @@ -275,30 +293,37 @@ SSL *s; } } } - /* SSLv3 */ - s->state=SSL23_ST_SR_CLNT_HELLO_B; } } else if ((p[0] == SSL3_RT_HANDSHAKE) && (p[1] == SSL3_VERSION_MAJOR) && (p[5] == SSL3_MT_CLIENT_HELLO)) { - /* true SSLv3 */ - type=3; + /* true SSLv3 or tls1 */ + if (p[2] >= TLS1_VERSION_MINOR) + { + if (!(s->options & SSL_OP_NO_TLSv1)) + { + type=3; + tls1=1; + } + else if (!(s->options & SSL_OP_NO_SSLv3)) + type=3; + } + else if (!(s->options & SSL_OP_NO_SSLv3)) + type=3; } - /* I will not introduce error codes since that will probably - * disrupt the error codes alread allocated and could play - * havoc with dynamic allocation. Upgrade to 0.9.x :-) - */ - else if ((strncmp("GET ", (char *)p,4) == 0) || - (strncmp("POST ",(char *)p,5) == 0) || - (strncmp("HEAD ",(char *)p,5) == 0) || - (strncmp("PUT ", (char *)p,4) == 0)) + else if ((strncmp("GET ", p,4) == 0) || + (strncmp("POST ",p,5) == 0) || + (strncmp("HEAD ",p,5) == 0) || + (strncmp("PUT ", p,4) == 0)) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTP_REQUEST); goto err; } - else if (strncmp("CONNECT",(char *)p,7) == 0) + else if (strncmp("CONNECT",p,7) == 0) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTPS_PROXY_REQUEST); goto err; } } @@ -306,7 +331,7 @@ SSL *s; next_bit: if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { - /* we have a SSLv3 in a SSLv2 header */ + /* we have a SSLv3/TLSv1 in a SSLv2 header */ type=2; p=s->packet; n=((p[0]&0x7f)<<8)|p[1]; @@ -334,7 +359,10 @@ next_bit: } *(d++)=SSL3_VERSION_MAJOR; - *(d++)=SSL3_VERSION_MINOR; + if (tls1) + *(d++)=TLS1_VERSION_MINOR; + else + *(d++)=SSL3_VERSION_MINOR; /* lets populate the random area */ /* get the chalenge_length */ @@ -374,7 +402,7 @@ next_bit: if (type == 1) { /* we are talking sslv2 */ - /* we need to clean up the SSLv3 setup and put in the + /* we need to clean up the SSLv3/TLSv1 setup and put in the * sslv2 stuff. */ if (s->s2 == NULL) @@ -394,7 +422,7 @@ next_bit: } s->state=SSL2_ST_GET_CLIENT_HELLO_A; - if ((s->ctx->options & SSL_OP_MSIE_SSLV2_RSA_PADDING) || + if ((s->options & SSL_OP_MSIE_SSLV2_RSA_PADDING) || use_sslv2_strong) s->s2->ssl2_rollback=0; else @@ -415,21 +443,9 @@ next_bit: if ((type == 2) || (type == 3)) { - /* we have sslv3 */ + /* we have SSLv3/TLSv1 */ - if (s->bbio == NULL) - { - bbio=BIO_new(BIO_f_buffer()); - if (bbio == NULL) - goto err; - s->bbio=bbio; - } - else - bbio=s->bbio; - BIO_reset(bbio); - if (!BIO_set_write_buffer_size(bbio,16*1024)) - goto err; - s->wbio=BIO_push(bbio,s->wbio); + if (!ssl_init_wbio_buffer(s,1)) goto err; /* we are in this state */ s->state=SSL3_ST_SR_CLNT_HELLO_A; @@ -452,7 +468,16 @@ next_bit: s->s3->rbuf.offset=0; } - s->method=SSLv3_server_method(); + if (tls1) + { + s->version=TLS1_VERSION; + s->method=TLSv1_server_method(); + } + else + { + s->version=SSL3_VERSION; + s->method=SSLv3_server_method(); + } s->handshake_func=s->method->ssl_accept; } diff --git a/ssl/s2_clnt.c b/ssl/s2_clnt.c index 67578a45ad..16df9ec565 100644 --- a/ssl/s2_clnt.c +++ b/ssl/s2_clnt.c @@ -1,5 +1,5 @@ /* ssl/s2_clnt.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -57,9 +57,6 @@ */ #include -#ifndef NO_MD5 -#include "md5.h" -#endif #include "rand.h" #include "buffer.h" #include "objects.h" @@ -92,7 +89,7 @@ static int ssl_rsa_public_encrypt(); static SSL_METHOD *ssl2_get_client_method(ver) int ver; { - if (ver == 2) + if (ver == SSL2_VERSION) return(SSLv2_client_method()); else return(NULL); @@ -125,7 +122,7 @@ SSL *s; RAND_seed((unsigned char *)&l,sizeof(l)); ERR_clear_error(); - errno=0; + clear_sys_error(); if (s->info_callback != NULL) cb=s->info_callback; @@ -149,7 +146,7 @@ SSL *s; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); - s->version=2; + s->version=SSL2_VERSION; s->type=SSL_ST_CONNECT; buf=s->init_buf; @@ -262,6 +259,7 @@ SSL *s; */ ssl_update_cache(s,SSL_SESS_CACHE_CLIENT); + if (s->hit) s->ctx->sess_hit++; ret=1; /* s->server=0; */ @@ -298,7 +296,7 @@ SSL *s; unsigned char *buf; unsigned char *p; int i,j; - STACK *sk,*cl; + STACK *sk=NULL,*cl; buf=(unsigned char *)s->init_buf->data; p=buf; @@ -350,7 +348,7 @@ SSL *s; } if (s->s2->tmp.cert_type != 0) { - if (!(s->ctx->options & + if (!(s->options & SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG)) { SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_TYPE_NOT_ZERO); @@ -448,7 +446,7 @@ SSL *s; * cert, Free's it before we increment the reference count. */ CRYPTO_w_lock(CRYPTO_LOCK_X509); s->session->peer=s->session->cert->key->x509; - s->session->peer->references++; + CRYPTO_add(&s->session->peer->references,1,CRYPTO_LOCK_X509); CRYPTO_w_unlock(CRYPTO_LOCK_X509); s->s2->conn_id_length=s->s2->tmp.conn_id_length; @@ -736,7 +734,7 @@ SSL *s; /* ok, now we calculate the checksum * do it first so we can reuse buf :-) */ p=buf; - EVP_SignInit(&ctx,EVP_md5()); + EVP_SignInit(&ctx,s->ctx->rsa_md5); EVP_SignUpdate(&ctx,s->s2->key_material, (unsigned int)s->s2->key_material_length); EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len); @@ -856,12 +854,15 @@ SSL *s; if (!s->hit) /* new session */ { /* new session-id */ + /* Make sure we were not trying to re-use an old SSL_SESSION + * or bad things can happen */ + /* ZZZZZZZZZZZZZ */ s->session->session_id_length=SSL2_SSL_SESSION_ID_LENGTH; memcpy(s->session->session_id,p,SSL2_SSL_SESSION_ID_LENGTH); } else { - if (!(s->ctx->options & SSL_OP_MICROSOFT_SESS_ID_BUG)) + if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG)) { if (memcmp(buf,s->session->session_id, (unsigned int)s->session->session_id_length) != 0) diff --git a/ssl/s2_enc.c b/ssl/s2_enc.c index b915f099e5..b43056fa14 100644 --- a/ssl/s2_enc.c +++ b/ssl/s2_enc.c @@ -1,5 +1,5 @@ /* ssl/s2_enc.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -59,9 +59,6 @@ #include #include "ssl_locl.h" -#define RS 0 -#define WS 1 - int ssl2_enc_init(s, client) SSL *s; int client; @@ -94,6 +91,9 @@ int client; rs= s->enc_read_ctx; ws= s->enc_write_ctx; + EVP_CIPHER_CTX_init(rs); + EVP_CIPHER_CTX_init(ws); + num=c->key_len; s->s2->key_material_length=num*2; diff --git a/ssl/s2_lib.c b/ssl/s2_lib.c index fb91582217..275eb52f13 100644 --- a/ssl/s2_lib.c +++ b/ssl/s2_lib.c @@ -1,5 +1,5 @@ /* ssl/s2_lib.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -69,7 +69,7 @@ static int ssl2_ok(); static long ssl2_default_timeout(); #endif -char *ssl2_version_str="SSLv2 part of SSLeay 0.8.1b 29-Jun-1998"; +char *ssl2_version_str="SSLv2 part of SSLeay 0.9.0b 29-Jun-1998"; #define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER)) @@ -139,17 +139,6 @@ SSL_CIPHER ssl2_ciphers[]={ 0, SSL_ALL_CIPHERS, }, -/* DES_64_CBC_WITH_SHA */ -#if 0 - { - 1, - SSL2_TXT_DES_64_CBC_WITH_SHA, - SSL2_CK_DES_64_CBC_WITH_SHA, - SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA0|SSL_NOT_EXP|SSL_SSLV2|SSL_LOW, - 0, - SSL_ALL_CIPHERS, - }, -#endif /* DES_192_EDE3_CBC_WITH_MD5 */ { 1, @@ -159,17 +148,6 @@ SSL_CIPHER ssl2_ciphers[]={ 0, SSL_ALL_CIPHERS, }, -/* DES_192_EDE3_CBC_WITH_SHA */ -#if 0 - { - 1, - SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA, - SSL2_CK_DES_192_EDE3_CBC_WITH_SHA, - SSL_kRSA|SSL_aRSA|SSL_3DES|SSL_SHA0|SSL_NOT_EXP|SSL_SSLV2|SSL_HIGH, - 0, - SSL_ALL_CIPHERS, - }, -#endif /* RC4_64_WITH_MD5 */ #if 1 { @@ -196,7 +174,7 @@ SSL_CIPHER ssl2_ciphers[]={ }; static SSL_METHOD SSLv2_data= { - 2, + SSL2_VERSION, ssl2_new, /* local */ ssl2_clear, /* local */ ssl2_free, /* local */ @@ -216,6 +194,7 @@ static SSL_METHOD SSLv2_data= { ssl2_get_cipher, ssl_bad_method, ssl2_default_timeout, + &ssl3_undef_enc_method, }; static long ssl2_default_timeout() @@ -254,6 +233,7 @@ SSL *s; SSL2_CTX *s2; if ((s2=(SSL2_CTX *)Malloc(sizeof(SSL2_CTX))) == NULL) goto err; + memset(s2,0,sizeof(SSL2_CTX)); if ((s2->rbuf=(unsigned char *)Malloc( SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER+2)) == NULL) goto err; @@ -302,9 +282,8 @@ SSL *s; s2->rbuf=rbuf; s2->wbuf=wbuf; s2->clear_text=1; - s2->first_packet=0; s->packet=s2->rbuf; - s->version=2; + s->version=SSL2_VERSION; s->packet_length=0; } @@ -314,7 +293,17 @@ int cmd; long larg; char *parg; { - return(0); + int ret=0; + + switch(cmd) + { + case SSL_CTRL_GET_SESSION_REUSED: + ret=s->hit; + break; + default: + break; + } + return(ret); } long ssl2_ctx_ctrl(ctx,cmd,larg,parg) diff --git a/ssl/s2_meth.c b/ssl/s2_meth.c index 0b8c2acb48..cfc8828cc7 100644 --- a/ssl/s2_meth.c +++ b/ssl/s2_meth.c @@ -1,5 +1,5 @@ /* ssl/s2_meth.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -63,7 +63,7 @@ static SSL_METHOD *ssl2_get_method(ver) int ver; { - if (ver == 2) + if (ver == SSL2_VERSION) return(SSLv2_method()); else return(NULL); diff --git a/ssl/s2_pkt.c b/ssl/s2_pkt.c index 84bea33e2e..e4167b53af 100644 --- a/ssl/s2_pkt.c +++ b/ssl/s2_pkt.c @@ -1,5 +1,5 @@ /* ssl/s2_pkt.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -70,8 +70,8 @@ #ifndef NOPROTO static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend); -static int do_ssl_write(SSL *s, const char *buf, unsigned int len); -static int write_pending(SSL *s, const char *buf, unsigned int len); +static int do_ssl_write(SSL *s, char *buf, unsigned int len); +static int write_pending(SSL *s, char *buf, unsigned int len); static int ssl_mt_error(int n); #else static int read_n(); @@ -121,7 +121,7 @@ int len; } } - errno=0; + clear_sys_error(); s->rwstate=SSL_NOTHING; if (len <= 0) return(len); @@ -231,7 +231,7 @@ int len; (s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) { SSLerr(SSL_F_SSL2_READ,SSL_R_BAD_MAC_DECODE); - return(SSL_RWERR_BAD_MAC_DECODE); + return(-1); } } INC32(s->s2->read_sequence); /* expect next number */ @@ -248,7 +248,7 @@ int len; else { SSLerr(SSL_F_SSL2_READ,SSL_R_BAD_STATE); - return(SSL_RWERR_INTERNAL_ERROR); + return(-1); } } @@ -312,7 +312,7 @@ unsigned int extend; s->packet=s->s2->rbuf; while (newb < (int)n) { - errno=0; + clear_sys_error(); if (s->rbio != NULL) { s->rwstate=SSL_READING; @@ -356,7 +356,7 @@ unsigned int extend; int ssl2_write(s, buf, len) SSL *s; -const char *buf; +char *buf; int len; { unsigned int n,tot; @@ -380,7 +380,7 @@ int len; return(-1); } - errno=0; + clear_sys_error(); s->rwstate=SSL_NOTHING; if (len <= 0) return(len); @@ -405,7 +405,7 @@ int len; static int write_pending(s,buf,len) SSL *s; -const char *buf; +char *buf; unsigned int len; { int i; @@ -414,15 +414,15 @@ unsigned int len; /* check that they have given us the same buffer to * write */ - if ((s->s2->wpend_tot != (int)len) || (s->s2->wpend_buf != buf)) + if ((s->s2->wpend_tot > (int)len) || (s->s2->wpend_buf != buf)) { SSLerr(SSL_F_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY); - return(SSL_RWERR_BAD_WRITE_RETRY); + return(-1); } for (;;) { - errno=0; + clear_sys_error(); if (s->wbio != NULL) { s->rwstate=SSL_WRITING; @@ -453,7 +453,7 @@ unsigned int len; static int do_ssl_write(s, buf, len) SSL *s; -const char *buf; +char *buf; unsigned int len; { unsigned int j,k,olen,p,mac_size,bs; diff --git a/ssl/s2_srvr.c b/ssl/s2_srvr.c index 0112397e53..c6c8ea32f1 100644 --- a/ssl/s2_srvr.c +++ b/ssl/s2_srvr.c @@ -1,5 +1,5 @@ /* ssl/s2_srvr.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -57,9 +57,6 @@ */ #include -#ifdef NO_MD5 -#include "md5.h" -#endif #include "bio.h" #include "rand.h" #include "objects.h" @@ -92,7 +89,7 @@ static int ssl_rsa_private_decrypt(); static SSL_METHOD *ssl2_get_server_method(ver) int ver; { - if (ver == 2) + if (ver == SSL2_VERSION) return(SSLv2_server_method()); else return(NULL); @@ -126,7 +123,7 @@ SSL *s; RAND_seed((unsigned char *)&l,sizeof(l)); ERR_clear_error(); - errno=0; + clear_sys_error(); if (s->info_callback != NULL) cb=s->info_callback; @@ -144,7 +141,7 @@ SSL *s; return(-1); } - errno=0; + clear_sys_error(); for (;;) { state=s->state; @@ -158,7 +155,7 @@ SSL *s; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); - s->version=2; + s->version=SSL2_VERSION; s->type=SSL_ST_ACCEPT; buf=s->init_buf; @@ -309,13 +306,13 @@ SSL *s; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); goto end; - BREAK; + /* BREAK; */ default: SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_UNKNOWN_STATE); ret= -1; goto end; - BREAK; + /* BREAK; */ } if ((cb != NULL) && (s->state != state)) @@ -336,7 +333,7 @@ end: static int get_client_master_key(s) SSL *s; { - int export,i,n,keya,ek; + int export,i,n,keya,error=0,ek; unsigned char *p; SSL_CIPHER *cp; EVP_CIPHER *c; @@ -390,7 +387,7 @@ SSL *s; memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]), (unsigned int)keya); - if (s->session->cert->key->privatekey == NULL) + if (s->session->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY); @@ -537,8 +534,8 @@ SSL *s; } else { - i=ssl_get_prev_session(s,s->s2->tmp.session_id_length, - &(p[s->s2->tmp.cipher_spec_length])); + i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]), + s->s2->tmp.session_id_length); if (i == 1) { /* previous session */ s->hit=1; @@ -656,9 +653,9 @@ SSL *s; /* put certificate type */ *(p++)=SSL2_CT_X509_CERTIFICATE; s2n(s->version,p); /* version */ - n=i2d_X509(s->cert->key->x509,NULL); + n=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL); s2n(n,p); /* certificate length */ - i2d_X509(s->cert->key->x509,&d); + i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&d); n=0; /* lets send out the ciphers we like in the @@ -687,23 +684,7 @@ SSL *s; */ if (s->hit) { - BIO *buf; - - if (s->bbio == NULL) - { - buf=BIO_new(BIO_f_buffer()); - if (buf == NULL) - { - SSLerr(SSL_F_SERVER_HELLO,ERR_LIB_BUF); - return(-1); - } - s->bbio=buf; - } - else - buf=s->bbio; - - BIO_reset(buf); - s->wbio=BIO_push(buf,s->wbio); + if (!ssl_init_wbio_buffer(s,1)) return(-1); } return(ssl2_do_write(s)); @@ -904,12 +885,12 @@ SSL *s; EVP_MD_CTX ctx; EVP_PKEY *pkey=NULL; - EVP_VerifyInit(&ctx,EVP_md5()); + EVP_VerifyInit(&ctx,s->ctx->rsa_md5); EVP_VerifyUpdate(&ctx,s->s2->key_material, (unsigned int)s->s2->key_material_length); EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH); - i=i2d_X509(s->session->cert->key->x509,NULL); + i=i2d_X509(s->session->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL); buf2=(unsigned char *)Malloc((unsigned int)i); if (buf2 == NULL) { @@ -917,7 +898,7 @@ SSL *s; goto msg_end; } p2=buf2; - i=i2d_X509(s->session->cert->key->x509,&p2); + i=i2d_X509(s->session->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2); EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i); Free(buf2); @@ -962,17 +943,17 @@ int padding; RSA *rsa; int i; - if ((c == NULL) || (c->key->privatekey == NULL)) + if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)) { SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_NO_PRIVATEKEY); return(-1); } - if (c->key->privatekey->type != EVP_PKEY_RSA) + if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA) { SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA); return(-1); } - rsa=c->key->privatekey->pkey.rsa; + rsa=c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa; /* we have the public key */ i=RSA_private_decrypt(len,from,to,rsa,padding); diff --git a/ssl/s3_both.c b/ssl/s3_both.c index 1d710eef2e..6de62e1591 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c @@ -1,5 +1,5 @@ /* ssl/s3_both.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -69,16 +69,12 @@ /* SSL3err(SSL_F_SSL3_GET_FINISHED,SSL_R_EXCESSIVE_MESSAGE_SIZE); */ -unsigned char ssl3_server_finished_const[4]= - {SSL3_MD_SERVER_FINISHED_CONST}; -unsigned char ssl3_client_finished_const[4]= - {SSL3_MD_CLIENT_FINISHED_CONST}; - -int ssl3_send_finished(s,a,b,sender) +int ssl3_send_finished(s,a,b,sender,slen) SSL *s; int a; int b; unsigned char *sender; +int slen; { unsigned char *p,*d; int i; @@ -89,11 +85,12 @@ unsigned char *sender; d=(unsigned char *)s->init_buf->data; p= &(d[4]); - i=ssl3_final_finish_mac(s,&(s->s3->finish_dgst1),sender,p); + i=s->method->ssl3_enc->final_finish_mac(s, + &(s->s3->finish_dgst1), + &(s->s3->finish_dgst2), + sender,slen,p); p+=i; l=i; - i=ssl3_final_finish_mac(s,&(s->s3->finish_dgst2),sender,p); - l+=i; *(d++)=SSL3_MT_FINISHED; l2n3(l,d); @@ -107,13 +104,12 @@ unsigned char *sender; return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } -int ssl3_get_finished(s,a,b,sender) +int ssl3_get_finished(s,a,b) SSL *s; int a; int b; -unsigned char *sender; { - int al,i,j,ok; + int al,i,ok; long n; unsigned char *p; @@ -133,7 +129,7 @@ unsigned char *sender; /* If this occurs if we has missed a message */ if (!s->s3->change_cipher_spec) { - al=SSL3_AD_UNEXPECTED_MESSAGE; + al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_GOT_A_FIN_BEFORE_A_CCS); goto f_err; } @@ -141,20 +137,18 @@ unsigned char *sender; p=(unsigned char *)s->init_buf->data; - i=EVP_MD_CTX_size(&(s->s3->finish_dgst1)); - j=EVP_MD_CTX_size(&(s->s3->finish_dgst2)); + i=s->method->ssl3_enc->finish_mac_length; - if ((i+j) != n) + if (i != n) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_BAD_DIGEST_LENGTH); goto f_err; } - if ( (memcmp( p, &(s->s3->tmp.finish_md1[0]),i) != 0) || - (memcmp(&(p[i]),&(s->s3->tmp.finish_md2[0]),j) != 0)) + if (memcmp( p, (char *)&(s->s3->tmp.finish_md[0]),i) != 0) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED); goto f_err; } @@ -204,34 +198,43 @@ X509 *x; X509_STORE_CTX xs_ctx; X509_OBJECT obj; - X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL); - + /* TLSv1 sends a chain with nothing in it, instead of an alert */ buf=s->init_buf; - for (;;) + if (!BUF_MEM_grow(buf,(int)(10))) { - n=i2d_X509(x,NULL); - if (!BUF_MEM_grow(buf,(int)(n+l+3))) + SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); + return(0); + } + if (x != NULL) + { + X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL); + + for (;;) { - SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); - return(0); + n=i2d_X509(x,NULL); + if (!BUF_MEM_grow(buf,(int)(n+l+3))) + { + SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); + return(0); + } + p=(unsigned char *)&(buf->data[l]); + l2n3(n,p); + i2d_X509(x,&p); + l+=n+3; + if (X509_NAME_cmp(X509_get_subject_name(x), + X509_get_issuer_name(x)) == 0) break; + + i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509, + X509_get_issuer_name(x),&obj); + if (i <= 0) break; + x=obj.data.x509; + /* Count is one too high since the X509_STORE_get uped the + * ref count */ + X509_free(x); } - p=(unsigned char *)&(buf->data[l]); - l2n3(n,p); - i2d_X509(x,&p); - l+=n+3; - if (X509_NAME_cmp(X509_get_subject_name(x), - X509_get_issuer_name(x)) == 0) break; - - i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509, - X509_get_issuer_name(x),&obj); - if (i <= 0) break; - x=obj.data.x509; - /* Count is one too high since the X509_STORE_get uped the - * ref count */ - X509_free(x); - } - X509_STORE_CTX_cleanup(&xs_ctx); + X509_STORE_CTX_cleanup(&xs_ctx); + } l-=7; p=(unsigned char *)&(buf->data[4]); @@ -260,7 +263,7 @@ int *ok; s->s3->tmp.reuse_message=0; if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { - al=SSL3_AD_UNEXPECTED_MESSAGE; + al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE); goto f_err; } @@ -283,7 +286,7 @@ int *ok; if ((mt >= 0) && (*p != mt)) { - al=SSL3_AD_UNEXPECTED_MESSAGE; + al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE); goto f_err; } @@ -292,7 +295,7 @@ int *ok; n2l3(p,l); if (l > (unsigned long)max) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE); goto f_err; } @@ -381,31 +384,53 @@ err: } int ssl_verify_alarm_type(type) -int type; +long type; { int al; switch(type) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - + case X509_V_ERR_UNABLE_TO_GET_CRL: + al=SSL_AD_UNKNOWN_CA; + break; case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: - case X509_V_ERR_CERT_SIGNATURE_FAILURE: - case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_CRL_NOT_YET_VALID: + al=SSL_AD_BAD_CERTIFICATE; + break; + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + al=SSL_AD_DECRYPT_ERROR; + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_CRL_HAS_EXPIRED: + al=SSL_AD_CERTIFICATE_EXPIRED; + break; + case X509_V_ERR_CERT_REVOKED: + al=SSL_AD_CERTIFICATE_REVOKED; + break; + case X509_V_ERR_OUT_OF_MEM: + al=SSL_AD_INTERNAL_ERROR; + break; case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: - al=SSL3_AD_BAD_CERTIFICATE; + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + al=SSL_AD_UNKNOWN_CA; break; - case X509_V_ERR_CERT_HAS_EXPIRED: - al=SSL3_AD_CERTIFICATE_EXPIRED; + case X509_V_ERR_APPLICATION_VERIFICATION: + al=SSL_AD_HANDSHAKE_FAILURE; break; default: - al=SSL3_AD_CERTIFICATE_UNKNOWN; + al=SSL_AD_CERTIFICATE_UNKNOWN; break; } return(al); @@ -419,7 +444,7 @@ SSL *s; if (s->s3->rbuf.buf == NULL) { - if (s->ctx->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) + if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) extra=SSL3_RT_MAX_EXTRA; else extra=0; diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 4f551d20e9..940c6a458f 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -1,5 +1,5 @@ /* ssl/s3_clnt.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -102,7 +102,7 @@ static int ssl3_check_cert_and_algorithm(); static SSL_METHOD *ssl3_get_client_method(ver) int ver; { - if (ver == 3) + if (ver == SSL3_VERSION) return(SSLv3_client_method()); else return(NULL); @@ -132,12 +132,12 @@ SSL *s; long num1; void (*cb)()=NULL; int ret= -1; - BIO *bbio,*under; + BIO *under; int new_state,state,skip=0;; RAND_seed((unsigned char *)&Time,sizeof(Time)); ERR_clear_error(); - errno=0; + clear_sys_error(); if (s->info_callback != NULL) cb=s->info_callback; @@ -156,6 +156,7 @@ SSL *s; case SSL_ST_RENEGOTIATE: s->new_session=1; s->state=SSL_ST_CONNECT; + s->ctx->sess_connect_renegotiate++; /* break */ case SSL_ST_BEFORE: case SSL_ST_CONNECT: @@ -164,7 +165,9 @@ SSL *s; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); - s->version=3; + if ((s->version & 0xff00 ) != 0x0300) + abort(); + /* s->version=SSL3_VERSION; */ s->type=SSL_ST_CONNECT; if (s->init_buf == NULL) @@ -185,27 +188,7 @@ SSL *s; if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } /* setup buffing BIO */ - if (s->bbio == NULL) - { - bbio=BIO_new(BIO_f_buffer()); - if (bbio == NULL) - { - SSLerr(SSL_F_SSL3_CONNECT,ERR_LIB_BUF); - ret= -1; - goto end; - } - s->bbio=bbio; - } - else - bbio=s->bbio; - - BIO_reset(bbio); - if (!BIO_set_write_buffer_size(bbio,16*1024)) - { - SSLerr(SSL_F_SSL3_CONNECT,ERR_LIB_BUF); - ret= -1; - goto end; - } + if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; } /* don't push the buffering BIO quite yet */ @@ -226,7 +209,8 @@ SSL *s; s->init_num=0; /* turn on buffering for the next lot of output */ - s->wbio=BIO_push(s->bbio,s->wbio); + if (s->bbio != s->wbio) + s->wbio=BIO_push(s->bbio,s->wbio); break; @@ -307,7 +291,9 @@ SSL *s; l=s->s3->tmp.new_cipher->algorithms; /* EAY EAY EAY need to check for DH fix cert * sent back */ - if ((s->s3->tmp.cert_req) && 1) + /* For TLS, cert_req is set to 2, so a cert chain + * of nothing is sent, but no verify packet is sent */ + if (s->s3->tmp.cert_req == 1) { s->state=SSL3_ST_CW_CERT_VRFY_A; } @@ -338,13 +324,13 @@ SSL *s; s->init_num=0; s->session->cipher=s->s3->tmp.new_cipher; - if (!ssl3_setup_key_block(s)) + if (!s->method->ssl3_enc->setup_key_block(s)) { ret= -1; goto end; } - if (!ssl3_change_cipher_state(s, + if (!s->method->ssl3_enc->change_cipher_state(s, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { ret= -1; @@ -357,7 +343,8 @@ SSL *s; case SSL3_ST_CW_FINISHED_B: ret=ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B, - &(ssl3_client_finished_const[0])); + s->method->ssl3_enc->client_finished, + s->method->ssl3_enc->client_finished_len); if (ret <= 0) goto end; s->state=SSL3_ST_CW_FLUSH; @@ -384,8 +371,7 @@ SSL *s; case SSL3_ST_CR_FINISHED_B: ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, - SSL3_ST_CR_FINISHED_B, - &(ssl3_server_finished_const[0])); + SSL3_ST_CR_FINISHED_B); if (ret <= 0) goto end; if (s->hit) @@ -434,6 +420,7 @@ SSL *s; s->new_session=0; ssl_update_cache(s,SSL_SESS_CACHE_CLIENT); + if (s->hit) s->ctx->sess_hit++; ret=1; /* s->server=0; */ @@ -455,7 +442,11 @@ SSL *s; /* did we do anything */ if (!s->s3->tmp.reuse_message && !skip) { - if (s->debug) BIO_flush(s->wbio); + if (s->debug) + { + if ((ret=BIO_flush(s->wbio)) <= 0) + goto end; + } if ((cb != NULL) && (s->state != state)) { @@ -502,8 +493,8 @@ SSL *s; /* Do the message type and length last */ d=p= &(buf[4]); - *(p++)=SSL3_VERSION_MAJOR; - *(p++)=SSL3_VERSION_MINOR; + *(p++)=s->version>>8; + *(p++)=s->version&0xff; /* Random stuff */ memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); @@ -572,10 +563,12 @@ SSL *s; if (!ok) return((int)n); d=p=(unsigned char *)s->init_buf->data; - if ((p[0] != SSL3_VERSION_MAJOR) && (p[1] != SSL3_VERSION_MINOR)) + if ((p[0] != (s->version>>8)) || (p[1] != (s->version&0xff))) { SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_SSL_VERSION); - goto err; + s->version=(s->version&0xff00)|p[1]; + al=SSL_AD_PROTOCOL_VERSION; + goto f_err; } p+=2; @@ -592,32 +585,36 @@ SSL *s; /* SSLref returns 16 :-( */ if (j < SSL2_SSL_SESSION_ID_LENGTH) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SSL3_SESSION_ID_TOO_SHORT); goto f_err; } } - if (j == 0) - { - s->hit=0; - memset(s->session->session_id,0,SSL_MAX_SSL_SESSION_ID_LENGTH); - s->session->session_id_length=0; - } - else if ((j == s->session->session_id_length) && + if ((j != 0) && (j == s->session->session_id_length) && (memcmp(p,s->session->session_id,j) == 0)) s->hit=1; - else + else /* a miss or crap from the other end */ { - memcpy(s->session->session_id,p,j); - s->session->session_id_length=j; + /* If we were trying for session-id reuse, make a new + * SSL_SESSION so we don't stuff up other people */ s->hit=0; + if (s->session->session_id_length > 0) + { + if (!ssl_get_new_session(s,0)) + { + al=SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } + s->session->session_id_length=j; + memcpy(s->session->session_id,p,j); /* j could be 0 */ } p+=j; c=ssl_get_cipher_by_char(s,p); if (c == NULL) { /* unknown cipher */ - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNKNOWN_CIPHER_RETURNED); goto f_err; } @@ -628,17 +625,17 @@ SSL *s; if (i < 0) { /* we did not say we would use this cipher */ - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED); goto f_err; } if (s->hit && (s->session->cipher != c)) { - if (!(s->ctx->options & + if (!(s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); goto f_err; } @@ -649,7 +646,7 @@ SSL *s; j= *(p++); if (j != 0) { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); goto f_err; } @@ -657,7 +654,7 @@ SSL *s; if (p != (d+n)) { /* wrong packet length */ - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH); goto err; } @@ -701,7 +698,7 @@ SSL *s; if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { - al=SSL3_AD_UNEXPECTED_MESSAGE; + al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_BAD_MESSAGE_TYPE); goto f_err; } @@ -716,7 +713,7 @@ SSL *s; n2l3(p,llen); if (llen+3 != n) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -725,7 +722,7 @@ SSL *s; n2l3(p,l); if ((l+nc+3) > llen) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } @@ -734,13 +731,13 @@ SSL *s; x=d2i_X509(NULL,&q,l); if (x == NULL) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_BAD_CERTIFICATE; SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,ERR_R_ASN1_LIB); goto f_err; } if (q != (p+l)) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } @@ -792,7 +789,7 @@ SSL *s; } c->cert_type=i; - x->references++; + CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); if (c->pkeys[i].x509 != NULL) X509_free(c->pkeys[i].x509); c->pkeys[i].x509=x; @@ -800,7 +797,7 @@ SSL *s; if ((s->session != NULL) && (s->session->peer != NULL)) X509_free(s->session->peer); - x->references++; + CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); s->session->peer=x; x=NULL; @@ -829,7 +826,9 @@ SSL *s; long n,alg; EVP_PKEY *pkey=NULL; RSA *rsa=NULL; +#ifndef NO_DH DH *dh=NULL; +#endif n=ssl3_get_message(s, SSL3_ST_CR_KEY_EXCH_A, @@ -885,7 +884,7 @@ SSL *s; param_len=i+2; if (param_len > n) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_MODULUS_LENGTH); goto f_err; } @@ -900,7 +899,7 @@ SSL *s; param_len+=i+2; if (param_len > n) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_E_LENGTH); goto f_err; } @@ -937,7 +936,7 @@ SSL *s; param_len=i+2; if (param_len > n) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_P_LENGTH); goto f_err; } @@ -952,7 +951,7 @@ SSL *s; param_len+=i+2; if (param_len > n) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_G_LENGTH); goto f_err; } @@ -967,7 +966,7 @@ SSL *s; param_len+=i+2; if (param_len > n) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_PUB_KEY_LENGTH); goto f_err; } @@ -994,7 +993,7 @@ SSL *s; } else if ((alg & SSL_kDHr) || (alg & SSL_kDHd)) { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER); goto f_err; } @@ -1013,7 +1012,7 @@ SSL *s; if ((i != n) || (n > j) || (n <= 0)) { /* wrong packet length */ - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_LENGTH); goto err; } @@ -1027,7 +1026,8 @@ SSL *s; q=md_buf; for (num=2; num > 0; num--) { - EVP_DigestInit(&md_ctx,(num == 2)?EVP_md5():EVP_sha1()); + EVP_DigestInit(&md_ctx,(num == 2) + ?s->ctx->md5:s->ctx->sha1); 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,param,param_len); @@ -1039,14 +1039,14 @@ SSL *s; RSA_PKCS1_PADDING); if (i <= 0) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); goto f_err; } if ((j != i) || (memcmp(p,md_buf,i) != 0)) { /* bad signature */ - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE); goto f_err; } @@ -1064,7 +1064,7 @@ SSL *s; if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey)) { /* bad signature */ - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SIGNATURE); goto f_err; } @@ -1086,7 +1086,7 @@ SSL *s; } if (n != 0) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_EXTRA_DATA_IN_MESSAGE); goto f_err; } @@ -1103,8 +1103,8 @@ static int ssl3_get_certificate_request(s) SSL *s; { int ok,ret=0; - unsigned long n,nc; - unsigned int llen,l,ctype_num,i; + unsigned long n,nc,l; + unsigned int llen,ctype_num,i; X509_NAME *xn=NULL; unsigned char *p,*d,*q; STACK *ca_sk=NULL; @@ -1132,11 +1132,23 @@ SSL *s; if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) { - ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_UNEXPECTED_MESSAGE); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_WRONG_MESSAGE_TYPE); goto err; } + /* TLS does not like anon-DH with client cert */ + if (s->version > SSL3_VERSION) + { + l=s->s3->tmp.new_cipher->algorithms; + if (l & SSL_aNULL) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER); + goto err; + } + } + d=p=(unsigned char *)s->init_buf->data; if ((ca_sk=sk_new(ca_dn_cmp)) == NULL) @@ -1157,7 +1169,7 @@ SSL *s; n2s(p,llen); if ((llen+ctype_num+2+1) != n) { - ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_ILLEGAL_PARAMETER); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH); goto err; } @@ -1167,9 +1179,9 @@ SSL *s; n2s(p,l); if ((l+nc+2) > llen) { - if ((s->ctx->options & SSL_OP_NETSCAPE_CA_DN_BUG)) + if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) goto cont; /* netscape bugs */ - ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_ILLEGAL_PARAMETER); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_TOO_LONG); goto err; } @@ -1179,11 +1191,11 @@ SSL *s; if ((xn=d2i_X509_NAME(NULL,&q,l)) == NULL) { /* If netscape tollerance is on, ignore errors */ - if (s->ctx->options & SSL_OP_NETSCAPE_CA_DN_BUG) + if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG) goto cont; else { - ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_ILLEGAL_PARAMETER); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_ASN1_LIB); goto err; } @@ -1191,7 +1203,7 @@ SSL *s; if (q != (p+l)) { - ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_ILLEGAL_PARAMETER); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_LENGTH_MISMATCH); goto err; } @@ -1248,7 +1260,7 @@ SSL *s; if (n > 0) { /* should contain no data */ - ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_ILLEGAL_PARAMETER); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_SERVER_DONE,SSL_R_LENGTH_MISMATCH); } ret=1; @@ -1258,7 +1270,7 @@ SSL *s; static int ssl3_send_client_key_exchange(s) SSL *s; { - unsigned char *p,*d; + unsigned char *p,*q,*d; int n; unsigned long l; EVP_PKEY *pkey=NULL; @@ -1291,22 +1303,33 @@ SSL *s; rsa=pkey->pkey.rsa; } - tmp_buf[0]=SSL3_VERSION_MAJOR; - tmp_buf[1]=SSL3_VERSION_MINOR; + tmp_buf[0]=s->version>>8; + tmp_buf[1]=s->version&0xff; RAND_bytes(&(tmp_buf[2]),SSL_MAX_MASTER_KEY_LENGTH-2); s->session->master_key_length=SSL_MAX_MASTER_KEY_LENGTH; - n=RSA_public_encrypt(48,tmp_buf,p,rsa, - RSA_PKCS1_PADDING); + q=p; + /* Fix buf for TLS and beyond */ + if (s->version > SSL3_VERSION) + p+=2; + n=RSA_public_encrypt(SSL_MAX_MASTER_KEY_LENGTH, + tmp_buf,p,rsa,RSA_PKCS1_PADDING); if (n <= 0) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT); goto err; } + /* Fix buf for TLS and beyond */ + if (s->version > SSL3_VERSION) + { + s2n(n,q); + n+=2; + } + s->session->master_key_length= - ssl3_generate_master_secret(s, + s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, tmp_buf,48); memset(tmp_buf,0,48); @@ -1323,7 +1346,7 @@ SSL *s; else { /* we get them from the cert */ - ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_HANDSHAKE_FAILURE); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); goto err; } @@ -1342,7 +1365,9 @@ SSL *s; /* use the 'p' output buffer for the DH key, but * make sure to clear it out afterwards */ + n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt); + if (n <= 0) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); @@ -1351,7 +1376,7 @@ SSL *s; /* generate master key from the result */ s->session->master_key_length= - ssl3_generate_master_secret(s, + s->method->ssl3_enc->generate_master_secret(s, s->session->master_key,p,n); /* clean up */ memset(p,0,n); @@ -1369,7 +1394,7 @@ SSL *s; else #endif { - ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_HANDSHAKE_FAILURE); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_INTERNAL_ERROR); goto err; } @@ -1395,8 +1420,11 @@ SSL *s; unsigned char *p,*d; unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; EVP_PKEY *pkey; - int i=0,j; + int i=0; unsigned long n; +#ifndef NO_DSA + int j; +#endif if (s->state == SSL3_ST_CW_CERT_VRFY_A) { @@ -1404,14 +1432,14 @@ SSL *s; p= &(d[4]); pkey=s->cert->key->privatekey; - ssl3_final_finish_mac(s,&(s->s3->finish_dgst2), - NULL,&(data[MD5_DIGEST_LENGTH])); + s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2), + &(data[MD5_DIGEST_LENGTH])); #ifndef NO_RSA if (pkey->type == EVP_PKEY_RSA) { - ssl3_final_finish_mac(s,&(s->s3->finish_dgst1), - NULL,&(data[0])); + s->method->ssl3_enc->cert_verify_mac(s, + &(s->s3->finish_dgst1),&(data[0])); i=RSA_private_encrypt( MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, data,&(p[2]),pkey->pkey.rsa, @@ -1507,9 +1535,16 @@ SSL *s; if (pkey != NULL) EVP_PKEY_free(pkey); if (i == 0) { - s->s3->tmp.cert_req=0; - ssl3_send_alert(s,SSL3_AL_WARNING,SSL3_AD_NO_CERTIFICATE); - return(1); + if (s->version == SSL3_VERSION) + { + s->s3->tmp.cert_req=0; + ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE); + return(1); + } + else + { + s->s3->tmp.cert_req=2; + } } /* Ok, we have a cert */ @@ -1519,7 +1554,8 @@ SSL *s; if (s->state == SSL3_ST_CW_CERT_C) { s->state=SSL3_ST_CW_CERT_D; - l=ssl3_output_cert_chain(s,s->cert->key->x509); + l=ssl3_output_cert_chain(s, + (s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509); s->init_num=(int)l; s->init_off=0; } @@ -1635,7 +1671,7 @@ SSL *s; } return(1); f_err: - ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_HANDSHAKE_FAILURE); + ssl3