diff options
author | Ralf S. Engelschall <rse@openssl.org> | 1998-12-21 10:56:39 +0000 |
---|---|---|
committer | Ralf S. Engelschall <rse@openssl.org> | 1998-12-21 10:56:39 +0000 |
commit | 58964a492275ca9a59a0cd9c8155cb2491b4b909 (patch) | |
tree | c7b16876a5789463bbbb468ef4829c8129b3d718 /ssl | |
parent | d02b48c63a58ea4367a0e905979f140b7d090f86 (diff) | |
download | openssl-58964a492275ca9a59a0cd9c8155cb2491b4b909.tar.gz |
Import of old SSLeay release: SSLeay 0.9.0b
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/Makefile.ssl | 18 | ||||
-rw-r--r-- | ssl/bio_ssl.c | 249 | ||||
-rw-r--r-- | ssl/s23_clnt.c | 96 | ||||
-rw-r--r-- | ssl/s23_lib.c | 15 | ||||
-rw-r--r-- | ssl/s23_meth.c | 8 | ||||
-rw-r--r-- | ssl/s23_pkt.c | 2 | ||||
-rw-r--r-- | ssl/s23_srvr.c | 107 | ||||
-rw-r--r-- | ssl/s2_clnt.c | 25 | ||||
-rw-r--r-- | ssl/s2_enc.c | 8 | ||||
-rw-r--r-- | ssl/s2_lib.c | 45 | ||||
-rw-r--r-- | ssl/s2_meth.c | 4 | ||||
-rw-r--r-- | ssl/s2_pkt.c | 28 | ||||
-rw-r--r-- | ssl/s2_srvr.c | 59 | ||||
-rw-r--r-- | ssl/s3_both.c | 137 | ||||
-rw-r--r-- | ssl/s3_clnt.c | 242 | ||||
-rw-r--r-- | ssl/s3_enc.c | 162 | ||||
-rw-r--r-- | ssl/s3_lib.c | 184 | ||||
-rw-r--r-- | ssl/s3_meth.c | 6 | ||||
-rw-r--r-- | ssl/s3_pkt.c | 262 | ||||
-rw-r--r-- | ssl/s3_srvr.c | 278 | ||||
-rw-r--r-- | ssl/ssl.c | 2 | ||||
-rw-r--r-- | ssl/ssl.err | 336 | ||||
-rw-r--r-- | ssl/ssl.h | 677 | ||||
-rw-r--r-- | ssl/ssl2.h | 6 | ||||
-rw-r--r-- | ssl/ssl23.h | 2 | ||||
-rw-r--r-- | ssl/ssl3.h | 56 | ||||
-rw-r--r-- | ssl/ssl_algs.c | 5 | ||||
-rw-r--r-- | ssl/ssl_asn1.c | 12 | ||||
-rw-r--r-- | ssl/ssl_cert.c | 19 | ||||
-rw-r--r-- | ssl/ssl_ciph.c | 223 | ||||
-rw-r--r-- | ssl/ssl_err.c | 30 | ||||
-rw-r--r-- | ssl/ssl_err2.c | 2 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 386 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 82 | ||||
-rw-r--r-- | ssl/ssl_rsa.c | 71 | ||||
-rw-r--r-- | ssl/ssl_sess.c | 203 | ||||
-rw-r--r-- | ssl/ssl_stat.c | 3 | ||||
-rw-r--r-- | ssl/ssl_task.c | 2 | ||||
-rw-r--r-- | ssl/ssl_txt.c | 29 | ||||
-rw-r--r-- | ssl/ssltest.c | 234 | ||||
-rw-r--r-- | ssl/t1_clnt.c | 90 | ||||
-rw-r--r-- | ssl/t1_enc.c | 635 | ||||
-rw-r--r-- | ssl/t1_lib.c | 151 | ||||
-rw-r--r-- | ssl/t1_meth.c | 88 | ||||
-rw-r--r-- | ssl/t1_srvr.c | 91 | ||||
-rw-r--r-- | ssl/tls1.h | 115 |
46 files changed, 4036 insertions, 1449 deletions
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 <stdio.h> +#include <stdlib.h> #include <string.h> #include <errno.h> +#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 <stdio.h> -#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 <stdio.h> #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 <stdio.h> -#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_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); err: return(0); } diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index f1cd25e3d3..bbd9b637c5 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -1,5 +1,5 @@ /* ssl/s3_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 @@ -76,6 +76,56 @@ static unsigned char ssl3_pad_2[48]={ 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c, 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c }; +#ifndef NO_PROTO +static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx, + unsigned char *sender, int len, unsigned char *p); +#else +static int ssl3_handshake_mac(); +#endif + +static void ssl3_generate_key_block(s,km,num) +SSL *s; +unsigned char *km; +int num; + { + MD5_CTX m5; + SHA_CTX s1; + unsigned char buf[8],smd[SHA_DIGEST_LENGTH]; + unsigned char c='A'; + int i,j,k; + + k=0; + for (i=0; i<num; i+=MD5_DIGEST_LENGTH) + { + k++; + for (j=0; j<k; j++) + buf[j]=c; + c++; + SHA1_Init( &s1); + SHA1_Update(&s1,buf,k); + SHA1_Update(&s1,s->session->master_key, + s->session->master_key_length); + SHA1_Update(&s1,s->s3->server_random,SSL3_RANDOM_SIZE); + SHA1_Update(&s1,s->s3->client_random,SSL3_RANDOM_SIZE); + SHA1_Final( smd,&s1); + + MD5_Init( &m5); + MD5_Update(&m5,s->session->master_key, + s->session->master_key_length); + MD5_Update(&m5,smd,SHA_DIGEST_LENGTH); + if ((i+MD5_DIGEST_LENGTH) > num) + { + MD5_Final(smd,&m5); + memcpy(km,smd,(num-i)); + } + else + MD5_Final(km,&m5); + + km+=MD5_DIGEST_LENGTH; + } + memset(smd,0,SHA_DIGEST_LENGTH); + } + int ssl3_change_cipher_state(s,which) SSL *s; int which; @@ -122,6 +172,8 @@ int which; mac_secret= &(s->s3->write_mac_secret[0]); } + EVP_CIPHER_CTX_init(dd); + p=s->s3->tmp.key_block; i=EVP_MD_size(m); j=(exp)?5:EVP_CIPHER_key_length(c); @@ -164,18 +216,20 @@ int which; MD5_Final(&(exp_key[0]),&md); key= &(exp_key[0]); - MD5_Init(&md); - MD5_Update(&md,er1,SSL3_RANDOM_SIZE); - MD5_Update(&md,er2,SSL3_RANDOM_SIZE); - MD5_Final(&(exp_iv[0]),&md); - iv= &(exp_iv[0]); + if (k > 0) + { + MD5_Init(&md); + MD5_Update(&md,er1,SSL3_RANDOM_SIZE); + MD5_Update(&md,er2,SSL3_RANDOM_SIZE); + MD5_Final(&(exp_iv[0]),&md); + iv= &(exp_iv[0]); + } } - s->session->key_arg_length=k; - if (k > 0) - memcpy(&(s->session->key_arg[0]),iv,k); + s->session->key_arg_length=0; EVP_CipherInit(dd,c,key,iv,(which & SSL3_CC_WRITE)); + memset(&(exp_key[0]),0,sizeof(exp_key)); memset(&(exp_iv[0]),0,sizeof(exp_iv)); return(1); @@ -305,7 +359,7 @@ int send; if (i > bs) { SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - ssl3_send_alert(s,SSL3_AL_FATAL,SSL3_AD_BAD_RECORD_MAC); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPT_ERROR); return(0); } rec->length-=i; @@ -317,8 +371,8 @@ int send; void ssl3_init_finished_mac(s) SSL *s; { - EVP_DigestInit(&(s->s3->finish_dgst1),EVP_md5()); - EVP_DigestInit(&(s->s3->finish_dgst2),EVP_sha1()); + EVP_DigestInit(&(s->s3->finish_dgst1),s->ctx->md5); + EVP_DigestInit(&(s->s3->finish_dgst2),s->ctx->sha1); } void ssl3_finish_mac(s,buf,len) @@ -330,10 +384,34 @@ int len; EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len); } -int ssl3_final_finish_mac(s,in_ctx,sender,p) +int ssl3_cert_verify_mac(s,ctx,p) +SSL *s; +EVP_MD_CTX *ctx; +unsigned char *p; + { + return(ssl3_handshake_mac(s,ctx,NULL,0,p)); + } + +int ssl3_final_finish_mac(s,ctx1,ctx2,sender,len,p) +SSL *s; +EVP_MD_CTX *ctx1,*ctx2; +unsigned char *sender; +int len; +unsigned char *p; + { + int ret; + + ret=ssl3_handshake_mac(s,ctx1,sender,len,p); + p+=ret; + ret+=ssl3_handshake_mac(s,ctx2,sender,len,p); + return(ret); + } + +static int ssl3_handshake_mac(s,in_ctx,sender,len,p) SSL *s; EVP_MD_CTX *in_ctx; unsigned char *sender; +int len; unsigned char *p; { unsigned int ret; @@ -348,7 +426,7 @@ unsigned char *p; npad=(48/n)*n; if (sender != NULL) - EVP_DigestUpdate(&ctx,sender,4); + EVP_DigestUpdate(&ctx,sender,len); EVP_DigestUpdate(&ctx,s->session->master_key, s->session->master_key_length); EVP_DigestUpdate(&ctx,ssl3_pad_1,npad); @@ -397,19 +475,6 @@ int send; md_size=EVP_MD_size(hash); npad=(48/md_size)*md_size; -#ifdef MAC_DEBUG -printf("npad=%d md_size=%d",npad,md_size); -printf("\nmsec="); -for (i=0; i<md_size; i++) printf("%02X ",mac_sec[i]); -printf("\npad1="); -for (i=0; i<npad; i++) printf("%02X ",ssl3_pad_1[i]); -printf("\nseq ="); -for (i=0; i<8; i++) printf("%02X ",seq[i]); -printf("\nreqt=%02X len=%04X\n",rec->type,rec->length); -for (i=0; i<rec->length; i++) printf("%02X",rec->input[i]); -printf("\n"); -#endif - /* Chop the digest off the end :-) */ EVP_DigestInit( &md_ctx,hash); @@ -433,12 +498,6 @@ printf("\n"); for (i=7; i>=0; i--) if (++seq[i]) break; -#ifdef MAC_DEBUG -printf("md="); -for (i=0; i<md_size; i++) printf("%02X ",md[i]); -printf("\n"); -#endif - return(md_size); } @@ -460,7 +519,7 @@ int len; for (i=0; i<3; i++) { - EVP_DigestInit(&ctx,EVP_sha1()); + EVP_DigestInit(&ctx,s->ctx->sha1); EVP_DigestUpdate(&ctx,salt[i],strlen((char *)salt[i])); EVP_DigestUpdate(&ctx,p,len); EVP_DigestUpdate(&ctx,&(s->s3->client_random[0]), @@ -469,7 +528,7 @@ int len; SSL3_RANDOM_SIZE); EVP_DigestFinal(&ctx,buf,&n); - EVP_DigestInit(&ctx,EVP_md5()); + EVP_DigestInit(&ctx,s->ctx->md5); EVP_DigestUpdate(&ctx,p,len); EVP_DigestUpdate(&ctx,buf,n); EVP_DigestFinal(&ctx,out,&n); @@ -479,3 +538,36 @@ int len; return(ret); } +int ssl3_alert_code(code) +int code; + { + switch (code) + { + case SSL_AD_CLOSE_NOTIFY: return(SSL3_AD_CLOSE_NOTIFY); + case SSL_AD_UNEXPECTED_MESSAGE: return(SSL3_AD_UNEXPECTED_MESSAGE); + case SSL_AD_BAD_RECORD_MAC: return(SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECRYPTION_FAILED: return(SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_RECORD_OVERFLOW: return(SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE); + case SSL_AD_HANDSHAKE_FAILURE: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_CERTIFICATE: return(SSL3_AD_NO_CERTIFICATE); + case SSL_AD_BAD_CERTIFICATE: return(SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE); + case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED); + case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED); + case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN); + case SSL_AD_ILLEGAL_PARAMETER: return(SSL3_AD_ILLEGAL_PARAMETER); + case SSL_AD_UNKNOWN_CA: return(SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_ACCESS_DENIED: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_DECODE_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_DECRYPT_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_EXPORT_RESTRICION: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_PROTOCOL_VERSION: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_INSUFFICIENT_SECURITY:return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_INTERNAL_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_USER_CANCLED: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_RENEGOTIATION: return(-1); /* Don't send it :-) */ + default: return(-1); + } + } + diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index b7bac8e10f..0fd945025d 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -1,5 +1,5 @@ /* ssl/s3_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 @@ -60,7 +60,7 @@ #include "objects.h" #include "ssl_locl.h" -char *ssl3_version_str="SSLv3 part of SSLeay 0.8.1b 29-Jun-1998"; +char *ssl3_version_str="SSLv3 part of SSLeay 0.9.0b 29-Jun-1998"; #define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers)/sizeof(SSL_CIPHER)) @@ -131,8 +131,8 @@ SSL_CIPHER ssl3_ciphers[]={ /* Cipher 1B */ { 1, - SSL3_TXT_ADH_DES_196_CBC_SHA, - SSL3_CK_ADH_DES_196_CBC_SHA, + SSL3_TXT_ADH_DES_192_CBC_SHA, + SSL3_CK_ADH_DES_192_CBC_SHA, SSL_kEDH |SSL_aNULL|SSL_3DES |SSL_SHA1|SSL_NOT_EXP|SSL_SSLV3, 0, SSL_ALL_CIPHERS, @@ -358,8 +358,22 @@ SSL_CIPHER ssl3_ciphers[]={ /* end of list */ }; +static SSL3_ENC_METHOD SSLv3_enc_data={ + ssl3_enc, + ssl3_mac, + ssl3_setup_key_block, + ssl3_generate_master_secret, + ssl3_change_cipher_state, + ssl3_final_finish_mac, + MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, + ssl3_cert_verify_mac, + SSL3_MD_CLIENT_FINISHED_CONST,4, + SSL3_MD_SERVER_FINISHED_CONST,4, + ssl3_alert_code, + }; + static SSL_METHOD SSLv3_data= { - 3, + SSL3_VERSION, ssl3_new, ssl3_clear, ssl3_free, @@ -379,6 +393,7 @@ static SSL_METHOD SSLv3_data= { ssl3_get_cipher, ssl_bad_method, ssl3_default_timeout, + &SSLv3_enc_data, }; static long ssl3_default_timeout() @@ -420,14 +435,18 @@ SSL *s; SSL3_CTX *s3; if ((s3=(SSL3_CTX *)Malloc(sizeof(SSL3_CTX))) == NULL) goto err; + memset(s3,0,sizeof(SSL3_CTX)); s->s3=s3; + /* s->s3->tmp.ca_names=NULL; s->s3->tmp.key_block=NULL; + s->s3->tmp.key_block_length=0; s->s3->rbuf.buf=NULL; s->s3->wbuf.buf=NULL; + */ - ssl3_clear(s); + s->method->ssl_clear(s); return(1); err: return(0); @@ -465,16 +484,14 @@ SSL *s; wp=s->s3->wbuf.buf; memset(s->s3,0,sizeof(SSL3_CTX)); - if (rp != NULL) - { - s->packet= &(s->s3->rbuf.buf[0]); - s->s3->rbuf.buf=rp; - s->s3->wbuf.buf=wp; - } - else - s->packet=NULL; + if (rp != NULL) s->s3->rbuf.buf=rp; + if (wp != NULL) s->s3->wbuf.buf=wp; s->packet_length=0; - s->version=3; + s->s3->renegotiate=0; + s->s3->total_renegotiations=0; + s->s3->num_renegotiations=0; + s->s3->in_read_app_data=0; + s->version=SSL3_VERSION; } long ssl3_ctrl(s,cmd,larg,parg) @@ -483,7 +500,29 @@ int cmd; long larg; char *parg; { - return(0); + int ret=0; + + switch (cmd) + { + case SSL_CTRL_GET_SESSION_REUSED: + ret=s->hit; + break; + case SSL_CTRL_GET_CLIENT_CERT_REQUEST: + break; + case SSL_CTRL_GET_NUM_RENEGOTIATIONS: + ret=s->s3->num_renegotiations; + break; + case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS: + ret=s->s3->num_renegotiations; + s->s3->num_renegotiations=0; + break; + case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS: + ret=s->s3->total_renegotiations; + break; + default: + break; + } + return(ret); } long ssl3_ctx_ctrl(ctx,cmd,larg,parg) @@ -623,49 +662,6 @@ unsigned char *p; return(2); } -void ssl3_generate_key_block(s,km,num) -SSL *s; -unsigned char *km; -int num; - { - MD5_CTX m5; - SHA_CTX s1; - unsigned char buf[8],smd[SHA_DIGEST_LENGTH]; - unsigned char c='A'; - int i,j,k; - - k=0; - for (i=0; i<num; i+=MD5_DIGEST_LENGTH) - { - k++; - for (j=0; j<k; j++) - buf[j]=c; - c++; - SHA1_Init( &s1); - SHA1_Update(&s1,buf,k); - SHA1_Update(&s1,s->session->master_key, - s->session->master_key_length); - SHA1_Update(&s1,s->s3->server_random,SSL3_RANDOM_SIZE); - SHA1_Update(&s1,s->s3->client_random,SSL3_RANDOM_SIZE); - SHA1_Final( smd,&s1); - - MD5_Init( &m5); - MD5_Update(&m5,s->session->master_key, - s->session->master_key_length); - MD5_Update(&m5,smd,SHA_DIGEST_LENGTH); - if ((i+MD5_DIGEST_LENGTH) > num) - { - MD5_Final(smd,&m5); - memcpy(km,smd,(num-i)); - } - else - MD5_Final(km,&m5); - - km+=MD5_DIGEST_LENGTH; - } - memset(smd,0,SHA_DIGEST_LENGTH); - } - int ssl3_part_read(s,i) SSL *s; int i; @@ -754,7 +750,8 @@ unsigned char *p; p[ret++]=SSL3_CT_DSS_FIXED_DH; #endif } - if (alg & (SSL_kEDH|SSL_kDHd|SSL_kDHr)) + if ((s->version == SSL3_VERSION) && + (alg & (SSL_kEDH|SSL_kDHd|SSL_kDHr))) { #ifndef NO_RSA p[ret++]=SSL3_CT_RSA_EPHEMERAL_DH; @@ -767,7 +764,7 @@ unsigned char *p; #ifndef NO_RSA p[ret++]=SSL3_CT_RSA_SIGN; #endif -/* p[ret++]=SSL3_CT_DSS_SIGN; */ + p[ret++]=SSL3_CT_DSS_SIGN; return(ret); } @@ -787,7 +784,7 @@ SSL *s; { s->shutdown|=SSL_SENT_SHUTDOWN; #if 1 - ssl3_send_alert(s,SSL3_AL_WARNING,SSL3_AD_CLOSE_NOTIFY); + ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_CLOSE_NOTIFY); #endif /* our shutdown alert has been sent now, and if it still needs * to be written, s->s3->alert_dispatch will be true */ @@ -814,7 +811,7 @@ SSL *s; int ssl3_write(s,buf,len) SSL *s; -const char *buf; +char *buf; int len; { int ret,n; @@ -827,7 +824,8 @@ int len; return(0); } #endif - errno=0; + clear_sys_error(); + if (s->s3->renegotiate) ssl3_renegotiate_check(s); /* This is an experimental flag that sends the * last handshake message in the same packet as the first @@ -867,6 +865,7 @@ int len; (char *)buf,len); if (ret <= 0) return(ret); } + return(ret); } @@ -875,8 +874,24 @@ SSL *s; char *buf; int len; { - errno=0; - return(ssl3_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len)); + int ret; + + clear_sys_error(); + if (s->s3->renegotiate) ssl3_renegotiate_check(s); + s->s3->in_read_app_data=1; + ret=ssl3_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len); + if ((ret == -1) && (s->s3->in_read_app_data == 0)) + { + ERR_get_error(); /* clear the error */ + s->s3->in_read_app_data=0; + s->in_handshake++; + ret=ssl3_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len); + s->in_handshake--; + } + else + s->s3->in_read_app_data=0; + + return(ret); } int ssl3_peek(s,buf,len) @@ -889,7 +904,12 @@ int len; rr= &(s->s3->rrec); if ((rr->length == 0) || (rr->type != SSL3_RT_APPLICATION_DATA)) - return(0); + { + n=ssl3_read(s,buf,1); + if (n <= 0) return(n); + rr->length++; + rr->off--; + } if ((unsigned int)len > rr->length) n=rr->length; @@ -908,8 +928,34 @@ SSL *s; if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) return(0); - if (!SSL_in_init(s)) - s->state=SSL_ST_RENEGOTIATE; + s->s3->renegotiate=1; return(1); } +int ssl3_renegotiate_check(s) +SSL *s; + { + int ret=0; + + if (s->s3->renegotiate) + { + if ( (s->s3->rbuf.left == 0) && + (s->s3->wbuf.left == 0) && + !SSL_in_init(s)) + { +/* +if we are the server, and we have sent a 'RENEGOTIATE' message, we +need to go to SSL_ST_ACCEPT. +*/ + /* SSL_ST_ACCEPT */ + s->state=SSL_ST_RENEGOTIATE; + s->s3->renegotiate=0; + s->s3->num_renegotiations++; + s->s3->total_renegotiations++; + ret=1; + } + } + return(ret); + } + + diff --git a/ssl/s3_meth.c b/ssl/s3_meth.c index 4762b21442..3d66b4643a 100644 --- a/ssl/s3_meth.c +++ b/ssl/s3_meth.c @@ -1,5 +1,5 @@ /* ssl/s3_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,9 +63,9 @@ static SSL_METHOD *ssl3_get_method(ver) int ver; { - if (ver == 3) + if (ver == SSL3_VERSION) return(SSLv3_method()); - else + else return(NULL); } diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c index 3be69ef138..2385080347 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c @@ -1,5 +1,5 @@ /* ssl/s3_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 @@ -87,12 +87,14 @@ static int ssl3_write_pending(SSL *s, int type, char *buf, unsigned int len); static int ssl3_get_record(SSL *s); static int do_compress(SSL *ssl); static int do_uncompress(SSL *ssl); +static int do_change_cipher_spec(SSL *ssl); #else static int do_ssl3_write(); static int ssl3_write_pending(); static int ssl3_get_record(); static int do_compress(); static int do_uncompress(); +static int do_change_cipher_spec(); #endif static int ssl3_read_n(s,n,max,extend) @@ -159,7 +161,7 @@ int extend; while (newb < n) { - errno=0; + clear_sys_error(); if (s->rbio != NULL) { s->rwstate=SSL_READING; @@ -211,6 +213,7 @@ int extend; static int ssl3_get_record(s) SSL *s; { + char tmp_buf[512]; int ssl_major,ssl_minor,al; int n,i,ret= -1; SSL3_BUFFER *rb; @@ -226,7 +229,7 @@ SSL *s; rb= &(s->s3->rbuf); sess=s->session; - 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; @@ -257,25 +260,27 @@ again: } else { - if ( (ssl_major != SSL3_VERSION_MAJOR) || - (ssl_minor != SSL3_VERSION_MINOR)) - { - al=SSL3_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); - goto f_err; - } + if (version != s->version) + { + SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); + /* Send back error using their + * version number :-) */ + s->version=version; + al=SSL_AD_PROTOCOL_VERSION; + goto f_err; + } } - if (s->version != SSL3_VERSION_MAJOR) + if ((version>>8) != SSL3_VERSION_MAJOR) { - SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_INTERNAL_ERROR); + SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); goto err; } if (rr->length > (unsigned int)SSL3_RT_MAX_ENCRYPTED_LENGTH+extra) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_RECORD_OVERFLOW; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG); goto f_err; } @@ -319,20 +324,25 @@ again: /* check is not needed I belive */ if (rr->length > (unsigned int)SSL3_RT_MAX_ENCRYPTED_LENGTH+extra) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_RECORD_OVERFLOW; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG); goto f_err; } /* decrypt in place in 'rr->input' */ rr->data=rr->input; + memcpy(tmp_buf,rr->input,(rr->length > 512)?512:rr->length); - if (!ssl3_enc(s,0)) + if (!s->method->ssl3_enc->enc(s,0)) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECRYPT_ERROR; goto f_err; } - +#ifdef TLS_DEBUG +printf("dec %d\n",rr->length); +{ int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); } +printf("\n"); +#endif /* r->length is now the compressed data plus mac */ if ( (sess == NULL) || (s->enc_read_ctx == NULL) || @@ -345,24 +355,24 @@ again: if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_RECORD_OVERFLOW; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); goto f_err; } /* check MAC for rr->input' */ if (rr->length < mac_size) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); goto f_err; } rr->length-=mac_size; - i=ssl3_mac(s,md,0); + i=s->method->ssl3_enc->mac(s,md,0); if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0) { - al=SSL3_AD_BAD_RECORD_MAC; + al=SSL_AD_BAD_RECORD_MAC; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_MAC_DECODE); - ret=SSL_RWERR_BAD_MAC_DECODE; + ret= -1; goto f_err; } } @@ -373,13 +383,13 @@ again: if (rr->length > (unsigned int)SSL3_RT_MAX_COMPRESSED_LENGTH+extra) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_RECORD_OVERFLOW; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG); goto f_err; } if (!do_uncompress(s)) { - al=SSL3_AD_DECOMPRESSION_FAILURE; + al=SSL_AD_DECOMPRESSION_FAILURE; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION); goto f_err; } @@ -387,7 +397,7 @@ again: if (rr->length > (unsigned int)SSL3_RT_MAX_PLAIN_LENGTH+extra) { - al=SSL3_AD_DECOMPRESSION_FAILURE; + al=SSL_AD_RECORD_OVERFLOW; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DATA_LENGTH_TOO_LONG); goto f_err; } @@ -426,7 +436,7 @@ SSL *ssl; return(1); } -/* Call this write a data +/* Call this to write data * It will return <= 0 if not all data has been sent or non-blocking IO. */ int ssl3_write_bytes(s,type,buf,len) @@ -460,7 +470,7 @@ int len; nw=SSL3_RT_MAX_PLAIN_LENGTH; else nw=n; - + i=do_ssl3_write(s,type,&(buf[tot]),nw); if (i <= 0) { @@ -526,8 +536,8 @@ unsigned int len; *(p++)=type&0xff; wr->type=type; - *(p++)=SSL3_VERSION_MAJOR; - *(p++)=SSL3_VERSION_MINOR; + *(p++)=(s->version>>8); + *(p++)=s->version&0xff; /* record where we are to write out packet length */ plen=p; @@ -562,14 +572,14 @@ unsigned int len; if (mac_size != 0) { - ssl3_mac(s,&(p[wr->length]),1); + s->method->ssl3_enc->mac(s,&(p[wr->length]),1); wr->length+=mac_size; wr->input=p; wr->data=p; } /* ssl3_enc can only have an error on read */ - ssl3_enc(s,1); + s->method->ssl3_enc->enc(s,1); /* record length after mac and block padding */ s2n(wr->length,plen); @@ -604,16 +614,17 @@ unsigned int len; { int i; - if ((s->s3->wpend_tot != (int)len) || (s->s3->wpend_buf != buf) +/* XXXX */ + if ((s->s3->wpend_tot > (int)len) || (s->s3->wpend_buf != buf) || (s->s3->wpend_type != type)) { SSLerr(SSL_F_SSL3_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; @@ -647,14 +658,14 @@ int len; { int al,i,j,n,ret; SSL3_RECORD *rr; - unsigned char *sender; void (*cb)()=NULL; + BIO *bio; if (s->s3->rbuf.buf == NULL) /* Not initalised yet */ if (!ssl3_setup_buffers(s)) return(-1); - if (!s->in_handshake && SSL_in_before(s)) + if (!s->in_handshake && SSL_in_init(s)) { i=s->handshake_func(s); if (i < 0) return(i); @@ -684,7 +695,7 @@ start: if (s->s3->change_cipher_spec && (rr->type != SSL3_RT_HANDSHAKE)) { - al=SSL3_AD_UNEXPECTED_MESSAGE; + al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); goto err; } @@ -705,21 +716,25 @@ start: if ((rr->data[1] != 0) || (rr->data[2] != 0) || (rr->data[3] != 0)) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_CLIENT_REQUEST); goto err; } if (SSL_is_init_finished(s) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && + !s->s3->renegotiate) { ssl3_renegotiate(s); - n=s->handshake_func(s); - if (n < 0) return(n); - if (n == 0) + if (ssl3_renegotiate_check(s)) { - SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); - return(-1); + n=s->handshake_func(s); + if (n < 0) return(n); + if (n == 0) + { + SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); + return(-1); + } } } rr->length=0; @@ -734,7 +749,7 @@ start: { if ((rr->length != 2) || (rr->off != 0)) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_ALERT_RECORD); goto f_err; } @@ -759,7 +774,7 @@ start: if (i == 1) { s->s3->warn_alert=n; - if (n == SSL3_AD_CLOSE_NOTIFY) + if (n == SSL_AD_CLOSE_NOTIFY) { s->shutdown|=SSL_RECEIVED_SHUTDOWN; return(0); @@ -767,16 +782,20 @@ start: } else if (i == 2) { + char tmp[16]; + s->rwstate=SSL_NOTHING; s->s3->fatal_alert=n; SSLerr(SSL_F_SSL3_READ_BYTES,1000+n); + sprintf(tmp,"%d",n); + ERR_add_error_data(2,"SSL alert number ",tmp); s->shutdown|=SSL_RECEIVED_SHUTDOWN; SSL_CTX_remove_session(s->ctx,s->session); return(0); } else { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE); goto f_err; } @@ -797,43 +816,17 @@ start: if ( (rr->length != 1) || (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { - i=SSL3_AD_ILLEGAL_PARAMETER; + i=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC); goto err; } rr->length=0; - s->s3->change_cipher_spec=1; - - if (s->state & SSL_ST_ACCEPT) - i=SSL3_CHANGE_CIPHER_SERVER_READ; - else - i=SSL3_CHANGE_CIPHER_CLIENT_READ; - - if (s->s3->tmp.key_block == NULL) - { - s->session->cipher=s->s3->tmp.new_cipher; - if (!ssl3_setup_key_block(s)) - goto err; - } - - if (!ssl3_change_cipher_state(s,i)) + if (!do_change_cipher_spec(s)) goto err; - - /* we have to record the message digest at - * this point so we can get it before we read - * the finished message */ - sender=(s->state & SSL_ST_CONNECT) - ?&(ssl3_server_finished_const[0]) - :&(ssl3_client_finished_const[0]); - - ssl3_final_finish_mac(s,&(s->s3->finish_dgst1), - sender,&(s->s3->tmp.finish_md1[0])); - ssl3_final_finish_mac(s,&(s->s3->finish_dgst2), - sender,&(s->s3->tmp.finish_md2[0])); - - goto start; + else + goto start; } /* else we have a handshake */ @@ -853,12 +846,68 @@ start: SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); return(-1); } - goto start; + + /* 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 non-blocking world */ + + s->rwstate=SSL_READING; + bio=SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return(-1); } - al=SSL3_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD); - goto f_err; + switch (rr->type) + { + default: +#ifndef NO_TLS + /* TLS just ignores unknown message types */ + if (s->version == TLS1_VERSION) + { + goto start; + } +#endif + case SSL3_RT_CHANGE_CIPHER_SPEC: + case SSL3_RT_ALERT: + case SSL3_RT_HANDSHAKE: + al=SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD); + goto f_err; + case SSL3_RT_APPLICATION_DATA: + /* At this point, we were expecting something else, + * but have application data. What we do is set the + * error, and return -1. On the way out, if the + * library was running inside ssl3_read() and it makes + * sense to read application data at this point, we + * will indulge it. This will mostly happen during + * session renegotiation. + */ + if (s->s3->in_read_app_data && + (s->s3->total_renegotiations != 0) && + (( + (s->state & SSL_ST_CONNECT) && + (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && + (s->state <= SSL3_ST_CR_SRVR_HELLO_A) + ) || ( + (s->state & SSL_ST_ACCEPT) && + (s->state <= SSL3_ST_SW_HELLO_REQ_A) && + (s->state >= SSL3_ST_SR_CLNT_HELLO_A) + ) + )) + { + s->s3->in_read_app_data=0; + return(-1); + } + else + { + al=SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD); + goto f_err; + } + } } /* make sure that we are not getting application data when we @@ -866,7 +915,7 @@ start: if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && (s->enc_read_ctx == NULL)) { - al=SSL3_AD_UNEXPECTED_MESSAGE; + al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE); goto f_err; } @@ -882,7 +931,10 @@ start: rr->length-=n; rr->off+=n; if (rr->length <= 0) + { s->rstate=SSL_ST_READ_HEADER; + rr->off=0; + } if (type == SSL3_RT_HANDSHAKE) ssl3_finish_mac(s,(unsigned char *)buf,n); @@ -893,6 +945,49 @@ err: return(-1); } +static int do_change_cipher_spec(s) +SSL *s; + { + int i; + unsigned char *sender; + int slen; + + if (s->state & SSL_ST_ACCEPT) + i=SSL3_CHANGE_CIPHER_SERVER_READ; + else + i=SSL3_CHANGE_CIPHER_CLIENT_READ; + + if (s->s3->tmp.key_block == NULL) + { + s->session->cipher=s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) return(0); + } + + if (!s->method->ssl3_enc->change_cipher_state(s,i)) + return(0); + + /* we have to record the message digest at + * this point so we can get it before we read + * the finished message */ + if (s->state & SSL_ST_CONNECT) + { + sender=s->method->ssl3_enc->server_finished; + slen=s->method->ssl3_enc->server_finished_len; + } + else + { + sender=s->method->ssl3_enc->client_finished; + slen=s->method->ssl3_enc->client_finished_len; + } + + s->method->ssl3_enc->final_finish_mac(s, + &(s->s3->finish_dgst1), + &(s->s3->finish_dgst2), + sender,slen,&(s->s3->tmp.finish_md[0])); + + return(1); + } + int ssl3_do_write(s,type) SSL *s; int type; @@ -914,6 +1009,9 @@ SSL *s; int level; int desc; { + /* Map tls/ssl alert value to correct one */ + desc=s->method->ssl3_enc->alert_value(desc); + if (desc < 0) return; /* If a fatal one, remove from cache */ if ((level == 2) && (s->session != NULL)) SSL_CTX_remove_session(s->ctx,s->session); diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index ebff57506f..64903af151 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -1,5 +1,5 @@ /* ssl/s3_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 @@ -96,14 +96,13 @@ static int ssl3_get_cert_verify(); static int ssl3_get_client_key_exchange(); static int ssl3_get_client_certificate(); static int ssl3_send_hello_request(); -static SSL_METHOD *ssl3_get_server_method(); #endif static SSL_METHOD *ssl3_get_server_method(ver) int ver; { - if (ver == 3) + if (ver == SSL3_VERSION) return(SSLv3_server_method()); else return(NULL); @@ -134,12 +133,12 @@ SSL *s; long num1; int ret= -1; CERT *ct; - 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; @@ -179,7 +178,9 @@ SSL *s; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); - s->version=3; + if ((s->version>>8) != 3) + abort(); + /* s->version=SSL3_VERSION; */ s->type=SSL_ST_ACCEPT; if (s->init_buf == NULL) @@ -206,39 +207,19 @@ SSL *s; /* Ok, we now need to push on a buffering BIO so that * the output is sent in a way that TCP likes :-) */ - if (s->bbio == NULL) - { - bbio=BIO_new(BIO_f_buffer()); - if (bbio == NULL) - { - SSLerr(SSL_F_SSL3_ACCEPT,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_ACCEPT,ERR_LIB_BUF); - ret= -1; - goto end; - } + if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; } - s->wbio=BIO_push(bbio,s->wbio); - - s->ctx->sess_accept++; s->init_num=0; if (s->state != SSL_ST_RENEGOTIATE) { s->state=SSL3_ST_SR_CLNT_HELLO_A; ssl3_init_finished_mac(s); + s->ctx->sess_accept++; } else { + s->ctx->sess_accept_renegotiate++; s->state=SSL3_ST_SW_HELLO_REQ_A; } break; @@ -269,7 +250,7 @@ SSL *s; s->state=SSL_ST_OK; ret=1; goto end; - break; + /* break; */ case SSL3_ST_SR_CLNT_HELLO_A: case SSL3_ST_SR_CLNT_HELLO_B: @@ -328,7 +309,7 @@ SSL *s; /* clear this, it may get reset by * send_server_key_exchange */ - if (s->ctx->options & SSL_OP_EPHEMERAL_RSA) + if (s->options & SSL_OP_EPHEMERAL_RSA) s->s3->tmp.use_rsa_tmp=1; else s->s3->tmp.use_rsa_tmp=0; @@ -364,10 +345,12 @@ SSL *s; { /* no cert request */ skip=1; + s->s3->tmp.cert_request=0; s->state=SSL3_ST_SW_SRVR_DONE_A; } else { + s->s3->tmp.cert_request=1; ret=ssl3_send_certificate_request(s); if (ret <= 0) goto end; s->state=SSL3_ST_SW_SRVR_DONE_A; @@ -417,10 +400,12 @@ SSL *s; /* We need to get hashes here so if there is * a client cert, it can be verified */ - ssl3_final_finish_mac(s,&(s->s3->finish_dgst1), - NULL,&(s->s3->tmp.finish_md1[0])); - ssl3_final_finish_mac(s,&(s->s3->finish_dgst2), - NULL,&(s->s3->tmp.finish_md2[0])); + s->method->ssl3_enc->cert_verify_mac(s, + &(s->s3->finish_dgst1), + &(s->s3->tmp.finish_md[0])); + s->method->ssl3_enc->cert_verify_mac(s, + &(s->s3->finish_dgst2), + &(s->s3->tmp.finish_md[MD5_DIGEST_LENGTH])); break; @@ -438,8 +423,7 @@ SSL *s; case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, - SSL3_ST_SR_FINISHED_B, - &(ssl3_client_finished_const[0])); + SSL3_ST_SR_FINISHED_B); if (ret <= 0) goto end; if (s->hit) s->state=SSL_ST_OK; @@ -452,7 +436,8 @@ SSL *s; case SSL3_ST_SW_CHANGE_B: s->session->cipher=s->s3->tmp.new_cipher; - if (!ssl3_setup_key_block(s)) { ret= -1; goto end; } + if (!s->method->ssl3_enc->setup_key_block(s)) + { ret= -1; goto end; } ret=ssl3_send_change_cipher_spec(s, SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B); @@ -461,7 +446,7 @@ SSL *s; s->state=SSL3_ST_SW_FINISHED_A; s->init_num=0; - if (!ssl3_change_cipher_state(s, + if (!s->method->ssl3_enc->change_cipher_state(s, SSL3_CHANGE_CIPHER_SERVER_WRITE)) { ret= -1; @@ -474,7 +459,8 @@ SSL *s; case SSL3_ST_SW_FINISHED_B: ret=ssl3_send_finished(s, SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B, - &(ssl3_server_finished_const[0])); + s->method->ssl3_enc->server_finished, + s->method->ssl3_enc->server_finished_len); if (ret <= 0) goto end; s->state=SSL3_ST_SW_FLUSH; if (s->hit) @@ -513,18 +499,23 @@ SSL *s; if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); goto end; - break; + /* break; */ default: SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_UNKNOWN_STATE); ret= -1; goto end; - break; + /* break; */ } 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)) { @@ -578,6 +569,12 @@ SSL *s; SSL_CIPHER *c; STACK *ciphers=NULL; + /* We do this so that we will respond with our native type. + * If we are TLSv1 and we get SSLv3, we will respond with TLSv1, + * This down switching should be handled by a different method. + * If we are SSLv3, we will respond with SSLv3, even if prompted with + * TLSv1. + */ if (s->state == SSL3_ST_SR_CLNT_HELLO_A) { s->first_packet=1; @@ -593,11 +590,9 @@ SSL *s; if (!ok) return((int)n); d=p=(unsigned char *)s->init_buf->data; - if (p[0] != SSL3_VERSION_MAJOR) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_WRONG_SSL_VERSION); - goto err; - } + /* The version number has already been checked in ssl3_get_message. + * I a native TLSv1/SSLv3 method, the match must be correct except + * perhaps for the first message */ p+=2; /* load the client random */ @@ -615,7 +610,7 @@ SSL *s; } else { - i=ssl_get_prev_session(s,j,p); + i=ssl_get_prev_session(s,p,j); if (i == 1) { /* previous session */ s->hit=1; @@ -632,14 +627,14 @@ SSL *s; if ((i == 0) && (j != 0)) { /* we need a cipher if we are not resuming a session */ - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_SPECIFIED); goto f_err; } if ((i+p) > (d+n)) { /* not enough data */ - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -667,7 +662,7 @@ SSL *s; } if (j == 0) { - if ((s->ctx->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_num(ciphers) == 1)) + if ((s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_num(ciphers) == 1)) { /* Very bad for multi-threading.... */ s->session->cipher= @@ -677,7 +672,7 @@ SSL *s; { /* we need to have the cipher in the cipher * list if we are asked to reuse it */ - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_CIPHER_MISSING); goto f_err; } @@ -693,18 +688,22 @@ SSL *s; if (j >= i) { /* no compress */ - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_COMPRESSION_SPECIFIED); goto f_err; } - if (p > (d+n)) + /* TLS does not mind if there is extra stuff */ + if (s->version == SSL3_VERSION) { - /* wrong number of bytes, - * there could be more to follow */ - al=SSL3_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH); - goto f_err; + if (p > (d+n)) + { + /* wrong number of bytes, + * there could be more to follow */ + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH); + goto f_err; + } } /* do nothing with compression */ @@ -719,7 +718,7 @@ SSL *s; s->session->ciphers=ciphers; if (ciphers == NULL) { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_PASSED); goto f_err; } @@ -729,7 +728,7 @@ SSL *s; if (c == NULL) { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER); goto f_err; } @@ -743,7 +742,7 @@ SSL *s; SSL_CIPHER *nc=NULL; SSL_CIPHER *ec=NULL; - if (s->ctx->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) + if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) { sk=s->session->ciphers; for (i=0; i<sk_num(sk); i++) @@ -806,8 +805,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->server_random,SSL3_RANDOM_SIZE); @@ -819,7 +818,10 @@ SSL *s; * back the new session-id or we send back a 0 length * session-id if we want it to be single use. * Currently I will not implement the '0' length session-id + * 12-Jan-98 - I'll now support the '0' length stuff. */ + if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) + s->session->session_id_length=0; sl=s->session->session_id_length; *(p++)=sl; @@ -920,7 +922,7 @@ SSL *s; } if (rsa == NULL) { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY); goto f_err; } @@ -940,7 +942,7 @@ SSL *s; SSL_NOT_EXP)?0:1); if (dhp == NULL) { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY); goto f_err; } @@ -953,7 +955,7 @@ SSL *s; s->s3->tmp.dh=dh; if (((dhp->pub_key == NULL) || (dhp->priv_key == NULL) || - (s->ctx->options & SSL_OP_SINGLE_DH_USE)) && + (s->options & SSL_OP_SINGLE_DH_USE)) && (!DH_generate_key(dh))) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB); @@ -977,7 +979,7 @@ SSL *s; else #endif { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); goto f_err; } @@ -992,7 +994,7 @@ SSL *s; if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher)) == NULL) { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_DECODE_ERROR; goto f_err; } kn=EVP_PKEY_size(pkey); @@ -1030,7 +1032,8 @@ SSL *s; j=0; 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,&(d[4]),n); @@ -1072,7 +1075,7 @@ SSL *s; #endif { /* Is this error check actually needed? */ - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE); goto f_err; } @@ -1135,7 +1138,7 @@ SSL *s; goto err; } p=(unsigned char *)&(buf->data[4+n]); - if (!(s->ctx->options & SSL_OP_NETSCAPE_CA_DN_BUG)) + if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) { s2n(j,p); i2d_X509_NAME(name,&p); @@ -1181,9 +1184,11 @@ SSL *s; unsigned long l; unsigned char *p; RSA *rsa=NULL; - BIGNUM *pub=NULL; EVP_PKEY *pkey=NULL; +#ifndef NO_DH + BIGNUM *pub=NULL; DH *dh_srvr; +#endif n=ssl3_get_message(s, SSL3_ST_SR_KEY_EXCH_A, @@ -1213,7 +1218,7 @@ SSL *s; * be sent already */ if (rsa == NULL) { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_PKEY); goto f_err; @@ -1226,22 +1231,41 @@ SSL *s; (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_RSA_CERTIFICATE); goto f_err; } rsa=pkey->pkey.rsa; } + /* TLS */ + if (s->version > SSL3_VERSION) + { + n2s(p,i); + if (n != i+2) + { + if (!(s->options & SSL_OP_TLS_D5_BUG)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + goto err; + } + else + p-=2; + } + else + n=i; + } + i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING); + #if 1 /* If a bad decrypt, use a dud master key */ if ((i != SSL_MAX_MASTER_KEY_LENGTH) || - (p[0] != 3) || - (p[1] != 0)) + ((p[0] != (s->version>>8)) || + (p[1] != (s->version & 0xff)))) { - p[0]=3; - p[1]=0; + p[0]=(s->version>>8); + p[1]=(s->version & 0xff); RAND_bytes(&(p[2]),SSL_MAX_MASTER_KEY_LENGTH-2); i=SSL_MAX_MASTER_KEY_LENGTH; } @@ -1262,7 +1286,7 @@ SSL *s; #endif s->session->master_key_length= - ssl3_generate_master_secret(s, + s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, p,i); memset(p,0,i); @@ -1272,11 +1296,10 @@ SSL *s; #ifndef NO_DH if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { - n2s(p,i); if (n != i+2) { - if (!(s->ctx->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) + if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); goto err; @@ -1290,7 +1313,7 @@ SSL *s; if (n == 0L) /* the parameters are in the cert */ { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_DECODE_DH_CERTS); goto f_err; } @@ -1298,7 +1321,7 @@ SSL *s; { if (s->s3->tmp.dh == NULL) { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY); goto f_err; } @@ -1312,6 +1335,7 @@ SSL *s; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BN_LIB); goto err; } + i=DH_compute_key(p,pub,dh_srvr); if (i <= 0) @@ -1326,13 +1350,13 @@ SSL *s; BN_clear_free(pub); pub=NULL; s->session->master_key_length= - ssl3_generate_master_secret(s, + s->method->ssl3_enc->generate_master_secret(s, s->session->master_key,p,i); } else #endif { - al=SSL3_AD_HANDSHAKE_FAILURE; + al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNKNOWN_CIPHER_TYPE); goto f_err; } @@ -1340,7 +1364,9 @@ SSL *s; return(1); f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); +#if !defined(NO_DH) || !defined(NO_RSA) err: +#endif return(-1); } @@ -1380,8 +1406,8 @@ SSL *s; s->s3->tmp.reuse_message=1; if ((peer != NULL) && (type | EVP_PKT_SIGN)) { + al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE); - al=SSL3_AD_UNEXPECTED_MESSAGE; goto f_err; } ret=1; @@ -1391,21 +1417,21 @@ SSL *s; if (peer == NULL) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_NO_CLIENT_CERT_RECEIVED); - al=SSL3_AD_UNEXPECTED_MESSAGE; + al=SSL_AD_UNEXPECTED_MESSAGE; goto f_err; } if (!(type & EVP_PKT_SIGN)) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE); - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_ILLEGAL_PARAMETER; goto f_err; } if (s->s3->change_cipher_spec) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_CCS_RECEIVED_EARLY); - al=SSL3_AD_UNEXPECTED_MESSAGE; + al=SSL_AD_UNEXPECTED_MESSAGE; goto f_err; } @@ -1416,7 +1442,7 @@ SSL *s; if (i > n) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_LENGTH_MISMATCH); - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; goto f_err; } @@ -1424,7 +1450,7 @@ SSL *s; if ((i > j) || (n > j) || (n <= 0)) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_WRONG_SIGNATURE_SIZE); - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; goto f_err; } @@ -1434,17 +1460,15 @@ SSL *s; i=RSA_public_decrypt(i,p,p,pkey->pkey.rsa,RSA_PKCS1_PADDING); if (i < 0) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_RSA_DECRYPT); goto f_err; } if ((i != (MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH)) || - memcmp(&(s->s3->tmp.finish_md1[0]), - p,MD5_DIGEST_LENGTH) || - memcmp(&(s->s3->tmp.finish_md2[0]), - &(p[MD5_DIGEST_LENGTH]),SHA_DIGEST_LENGTH)) + memcmp(&(s->s3->tmp.finish_md[0]),p, + MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH)) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_RSA_SIGNATURE); goto f_err; } @@ -1454,12 +1478,13 @@ SSL *s; #ifndef NO_DSA if (pkey->type == EVP_PKEY_DSA) { - j=DSA_verify(pkey->save_type,s->s3->tmp.finish_md2, + j=DSA_verify(pkey->save_type, + &(s->s3->tmp.finish_md[MD5_DIGEST_LENGTH]), SHA_DIGEST_LENGTH,p,i,pkey->pkey.dsa); if (j <= 0) { /* bad signature */ - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_DSA_SIGNATURE); goto f_err; } @@ -1468,7 +1493,7 @@ SSL *s; #endif { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_INTERNAL_ERROR); - al=SSL3_AD_UNSUPPORTED_CERTIFICATE; + al=SSL_AD_UNSUPPORTED_CERTIFICATE; goto f_err; } @@ -1511,7 +1536,14 @@ SSL *s; (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - al=SSL3_AD_NO_CERTIFICATE; + al=SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } + /* If tls asked for a client cert we must return a 0 list */ + if ((s->version > SSL3_VERSION) && s->s3->tmp.cert_request) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); + al=SSL_AD_UNEXPECTED_MESSAGE; goto f_err; } s->s3->tmp.reuse_message=1; @@ -1520,7 +1552,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_CLIENT_CERTIFICATE,SSL_R_WRONG_MESSAGE_TYPE); goto f_err; } @@ -1535,7 +1567,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_CLIENT_CERTIFICATE,SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -1544,7 +1576,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_CLIENT_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } @@ -1558,7 +1590,7 @@ SSL *s; } if (p != (q+l)) { - al=SSL3_AD_ILLEGAL_PARAMETER; + al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } @@ -1573,22 +1605,36 @@ SSL *s; if (sk_num(sk) <= 0) { - al=SSL3_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATES_PASSED); - goto f_err; + /* TLS does not mind 0 certs returned */ + if (s->version == SSL3_VERSION) + { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATES_RETURNED); + goto f_err; + } + /* Fail for TLS only if we required a certificate */ + else if ((s->verify_mode & SSL_VERIFY_PEER) && + (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + al=SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } } - i=ssl_verify_cert_chain(s,sk); - if (!i) + else { - al=ssl_verify_alarm_type(s->verify_result); - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED); - goto f_err; + i=ssl_verify_cert_chain(s,sk); + if (!i) + { + al=ssl_verify_alarm_type(s->verify_result); + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED); + goto f_err; + } } /* This should not be needed */ if (s->session->peer != NULL) X509_free(s->session->peer); - s->session->peer=(X509 *)sk_shift(sk); ret=1; @@ -1,5 +1,5 @@ /* ssl/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 diff --git a/ssl/ssl.err b/ssl/ssl.err index f3bc5d37ab..c54326c624 100644 --- a/ssl/ssl.err +++ b/ssl/ssl.err @@ -82,29 +82,34 @@ #define SSL_F_SSL_GET_NEW_SESSION 178 #define SSL_F_SSL_GET_SERVER_SEND_CERT 179 #define SSL_F_SSL_GET_SIGN_PKEY 180 -#define SSL_F_SSL_LOAD_CLIENT_CA_FILE 181 -#define SSL_F_SSL_NEW 182 -#define SSL_F_SSL_RSA_PRIVATE_DECRYPT 183 -#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 184 -#define SSL_F_SSL_SESSION_NEW 185 -#define SSL_F_SSL_SESSION_PRINT_FP 186 -#define SSL_F_SSL_SET_FD 187 -#define SSL_F_SSL_SET_PKEY 188 -#define SSL_F_SSL_SET_RFD 189 -#define SSL_F_SSL_SET_SESSION 190 -#define SSL_F_SSL_SET_WFD 191 -#define SSL_F_SSL_UNDEFINED_FUNCTION 192 -#define SSL_F_SSL_USE_CERTIFICATE 193 -#define SSL_F_SSL_USE_CERTIFICATE_ASN1 194 -#define SSL_F_SSL_USE_CERTIFICATE_FILE 195 -#define SSL_F_SSL_USE_PRIVATEKEY 196 -#define SSL_F_SSL_USE_PRIVATEKEY_ASN1 197 -#define SSL_F_SSL_USE_PRIVATEKEY_FILE 198 -#define SSL_F_SSL_USE_RSAPRIVATEKEY 199 -#define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 200 -#define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 201 -#define SSL_F_SSL_WRITE 202 -#define SSL_F_WRITE_PENDING 203 +#define SSL_F_SSL_INIT_WBIO_BUFFER 181 +#define SSL_F_SSL_LOAD_CLIENT_CA_FILE 182 +#define SSL_F_SSL_NEW 183 +#define SSL_F_SSL_RSA_PRIVATE_DECRYPT 184 +#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 185 +#define SSL_F_SSL_SESSION_NEW 186 +#define SSL_F_SSL_SESSION_PRINT_FP 187 +#define SSL_F_SSL_SET_CERT 188 +#define SSL_F_SSL_SET_FD 189 +#define SSL_F_SSL_SET_PKEY 190 +#define SSL_F_SSL_SET_RFD 191 +#define SSL_F_SSL_SET_SESSION 192 +#define SSL_F_SSL_SET_WFD 193 +#define SSL_F_SSL_UNDEFINED_FUNCTION 194 +#define SSL_F_SSL_USE_CERTIFICATE 195 +#define SSL_F_SSL_USE_CERTIFICATE_ASN1 196 +#define SSL_F_SSL_USE_CERTIFICATE_FILE 197 +#define SSL_F_SSL_USE_PRIVATEKEY 198 +#define SSL_F_SSL_USE_PRIVATEKEY_ASN1 199 +#define SSL_F_SSL_USE_PRIVATEKEY_FILE 200 +#define SSL_F_SSL_USE_RSAPRIVATEKEY 201 +#define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 202 +#define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 203 +#define SSL_F_SSL_WRITE 204 +#define SSL_F_TLS1_CHANGE_CIPHER_STATE 205 +#define SSL_F_TLS1_ENC 206 +#define SSL_F_TLS1_SETUP_KEY_BLOCK 207 +#define SSL_F_WRITE_PENDING 208 /* Reason codes. */ #define SSL_R_APP_DATA_IN_HANDSHAKE 100 @@ -123,103 +128,109 @@ #define SSL_R_BAD_MAC_DECODE 113 #define SSL_R_BAD_MESSAGE_TYPE 114 #define SSL_R_BAD_PACKET_LENGTH 115 -#define SSL_R_BAD_RESPONSE_ARGUMENT 116 -#define SSL_R_BAD_RSA_DECRYPT 117 -#define SSL_R_BAD_RSA_ENCRYPT 118 -#define SSL_R_BAD_RSA_E_LENGTH 119 -#define SSL_R_BAD_RSA_MODULUS_LENGTH 120 -#define SSL_R_BAD_RSA_SIGNATURE 121 -#define SSL_R_BAD_SIGNATURE 122 -#define SSL_R_BAD_SSL_FILETYPE 123 -#define SSL_R_BAD_SSL_SESSION_ID_LENGTH 124 -#define SSL_R_BAD_STATE 125 -#define SSL_R_BAD_WRITE_RETRY 126 -#define SSL_R_BIO_NOT_SET 127 -#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 128 -#define SSL_R_BN_LIB 129 -#define SSL_R_CA_DN_LENGTH_MISMATCH 130 -#define SSL_R_CA_DN_TOO_LONG 131 -#define SSL_R_CCS_RECEIVED_EARLY 132 -#define SSL_R_CERTIFICATE_VERIFY_FAILED 133 -#define SSL_R_CERT_LENGTH_MISMATCH 134 -#define SSL_R_CHALLENGE_IS_DIFFERENT 135 -#define SSL_R_CIPHER_CODE_WRONG_LENGTH 136 -#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 137 -#define SSL_R_CIPHER_TABLE_SRC_ERROR 138 -#define SSL_R_COMPRESSED_LENGTH_TOO_LONG 139 -#define SSL_R_COMPRESSION_FAILURE 140 -#define SSL_R_CONNECTION_ID_IS_DIFFERENT 141 -#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 142 -#define SSL_R_DATA_LENGTH_TOO_LONG 143 -#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 144 -#define SSL_R_DIGEST_CHECK_FAILED 145 -#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 146 -#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 147 -#define SSL_R_EXCESSIVE_MESSAGE_SIZE 148 -#define SSL_R_EXTRA_DATA_IN_MESSAGE 149 -#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 150 -#define SSL_R_INTERNAL_ERROR 151 -#define SSL_R_INVALID_CHALLENGE_LENGTH 152 -#define SSL_R_LENGTH_MISMATCH 153 -#define SSL_R_LENGTH_TOO_SHORT 154 -#define SSL_R_LIBRARY_HAS_NO_CIPHERS 155 -#define SSL_R_MISSING_DH_DSA_CERT 156 -#define SSL_R_MISSING_DH_KEY 157 -#define SSL_R_MISSING_DH_RSA_CERT 158 -#define SSL_R_MISSING_DSA_SIGNING_CERT 159 -#define SSL_R_MISSING_EXPORT_TMP_DH_KEY 160 -#define SSL_R_MISSING_EXPORT_TMP_RSA_KEY 161 -#define SSL_R_MISSING_RSA_CERTIFICATE 162 -#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 163 -#define SSL_R_MISSING_RSA_SIGNING_CERT 164 -#define SSL_R_MISSING_TMP_DH_KEY 165 -#define SSL_R_MISSING_TMP_RSA_KEY 166 -#define SSL_R_MISSING_TMP_RSA_PKEY 167 -#define SSL_R_MISSING_VERIFY_MESSAGE 168 -#define SSL_R_NON_SSLV2_INITIAL_PACKET 169 -#define SSL_R_NO_CERTIFICATES_PASSED 170 -#define SSL_R_NO_CERTIFICATE_ASSIGNED 171 -#define SSL_R_NO_CERTIFICATE_RETURNED 172 -#define SSL_R_NO_CERTIFICATE_SET 173 -#define SSL_R_NO_CERTIFICATE_SPECIFIED 174 -#define SSL_R_NO_CIPHERS_AVAILABLE 175 -#define SSL_R_NO_CIPHERS_PASSED 176 -#define SSL_R_NO_CIPHERS_SPECIFIED 177 -#define SSL_R_NO_CIPHER_LIST 178 -#define SSL_R_NO_CIPHER_MATCH 179 -#define SSL_R_NO_CLIENT_CERT_RECEIVED 180 -#define SSL_R_NO_COMPRESSION_SPECIFIED 181 -#define SSL_R_NO_PRIVATEKEY 182 -#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 183 -#define SSL_R_NO_PUBLICKEY 184 -#define SSL_R_NO_SHARED_CIPHER 185 -#define SSL_R_NULL_SSL_CTX 186 -#define SSL_R_NULL_SSL_METHOD_PASSED 187 -#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 188 -#define SSL_R_PACKET_LENGTH_TOO_LONG 189 -#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 190 -#define SSL_R_PEER_ERROR 191 -#define SSL_R_PEER_ERROR_CERTIFICATE 192 -#define SSL_R_PEER_ERROR_NO_CERTIFICATE 193 -#define SSL_R_PEER_ERROR_NO_CIPHER 194 -#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 195 -#define SSL_R_PRE_MAC_LENGTH_TOO_LONG 196 -#define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 197 -#define SSL_R_PROTOCOL_IS_SHUTDOWN 198 -#define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 199 -#define SSL_R_PUBLIC_KEY_IS_NOT_RSA 200 -#define SSL_R_PUBLIC_KEY_NOT_RSA 201 -#define SSL_R_READ_BIO_NOT_SET 202 -#define SSL_R_READ_WRONG_PACKET_TYPE 203 -#define SSL_R_RECORD_LENGTH_MISMATCH 204 -#define SSL_R_RECORD_TOO_LARGE 205 -#define SSL_R_REQUIRED_CIPHER_MISSING 206 -#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 207 -#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 208 -#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 209 -#define SSL_R_SHORT_READ 210 -#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 211 -#define SSL_R_SSL3_SESSION_ID_TOO_SHORT 212 +#define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +#define SSL_R_BAD_RESPONSE_ARGUMENT 117 +#define SSL_R_BAD_RSA_DECRYPT 118 +#define SSL_R_BAD_RSA_ENCRYPT 119 +#define SSL_R_BAD_RSA_E_LENGTH 120 +#define SSL_R_BAD_RSA_MODULUS_LENGTH 121 +#define SSL_R_BAD_RSA_SIGNATURE 122 +#define SSL_R_BAD_SIGNATURE 123 +#define SSL_R_BAD_SSL_FILETYPE 124 +#define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125 +#define SSL_R_BAD_STATE 126 +#define SSL_R_BAD_WRITE_RETRY 127 +#define SSL_R_BIO_NOT_SET 128 +#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 +#define SSL_R_BN_LIB 130 +#define SSL_R_CA_DN_LENGTH_MISMATCH 131 +#define SSL_R_CA_DN_TOO_LONG 132 +#define SSL_R_CCS_RECEIVED_EARLY 133 +#define SSL_R_CERTIFICATE_VERIFY_FAILED 134 +#define SSL_R_CERT_LENGTH_MISMATCH 135 +#define SSL_R_CHALLENGE_IS_DIFFERENT 136 +#define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 +#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 +#define SSL_R_CIPHER_TABLE_SRC_ERROR 139 +#define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +#define SSL_R_COMPRESSION_FAILURE 141 +#define SSL_R_CONNECTION_ID_IS_DIFFERENT 142 +#define SSL_R_CONNECTION_TYPE_NOT_SET 143 +#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 144 +#define SSL_R_DATA_LENGTH_TOO_LONG 145 +#define SSL_R_DECRYPTION_FAILED 146 +#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 147 +#define SSL_R_DIGEST_CHECK_FAILED 148 +#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 149 +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 150 +#define SSL_R_EXCESSIVE_MESSAGE_SIZE 151 +#define SSL_R_EXTRA_DATA_IN_MESSAGE 152 +#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 153 +#define SSL_R_HTTPS_PROXY_REQUEST 154 +#define SSL_R_HTTP_REQUEST 155 +#define SSL_R_INTERNAL_ERROR 156 +#define SSL_R_INVALID_CHALLENGE_LENGTH 157 +#define SSL_R_LENGTH_MISMATCH 158 +#define SSL_R_LENGTH_TOO_SHORT 159 +#define SSL_R_LIBRARY_HAS_NO_CIPHERS 160 +#define SSL_R_MISSING_DH_DSA_CERT 161 +#define SSL_R_MISSING_DH_KEY 162 +#define SSL_R_MISSING_DH_RSA_CERT 163 +#define SSL_R_MISSING_DSA_SIGNING_CERT 164 +#define SSL_R_MISSING_EXPORT_TMP_DH_KEY 165 +#define SSL_R_MISSING_EXPORT_TMP_RSA_KEY 166 +#define SSL_R_MISSING_RSA_CERTIFICATE 167 +#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 168 +#define SSL_R_MISSING_RSA_SIGNING_CERT 169 +#define SSL_R_MISSING_TMP_DH_KEY 170 +#define SSL_R_MISSING_TMP_RSA_KEY 171 +#define SSL_R_MISSING_TMP_RSA_PKEY 172 +#define SSL_R_MISSING_VERIFY_MESSAGE 173 +#define SSL_R_NON_SSLV2_INITIAL_PACKET 174 +#define SSL_R_NO_CERTIFICATES_RETURNED 175 +#define SSL_R_NO_CERTIFICATE_ASSIGNED 176 +#define SSL_R_NO_CERTIFICATE_RETURNED 177 +#define SSL_R_NO_CERTIFICATE_SET 178 +#define SSL_R_NO_CERTIFICATE_SPECIFIED 179 +#define SSL_R_NO_CIPHERS_AVAILABLE 180 +#define SSL_R_NO_CIPHERS_PASSED 181 +#define SSL_R_NO_CIPHERS_SPECIFIED 182 +#define SSL_R_NO_CIPHER_LIST 183 +#define SSL_R_NO_CIPHER_MATCH 184 +#define SSL_R_NO_CLIENT_CERT_RECEIVED 185 +#define SSL_R_NO_COMPRESSION_SPECIFIED 186 +#define SSL_R_NO_PRIVATEKEY 187 +#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 188 +#define SSL_R_NO_PROTOCOLS_AVAILABLE 189 +#define SSL_R_NO_PUBLICKEY 190 +#define SSL_R_NO_SHARED_CIPHER 191 +#define SSL_R_NULL_SSL_CTX 192 +#define SSL_R_NULL_SSL_METHOD_PASSED 193 +#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 194 +#define SSL_R_PACKET_LENGTH_TOO_LONG 195 +#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 196 +#define SSL_R_PEER_ERROR 197 +#define SSL_R_PEER_ERROR_CERTIFICATE 198 +#define SSL_R_PEER_ERROR_NO_CERTIFICATE 199 +#define SSL_R_PEER_ERROR_NO_CIPHER 200 +#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 201 +#define SSL_R_PRE_MAC_LENGTH_TOO_LONG 202 +#define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 203 +#define SSL_R_PROTOCOL_IS_SHUTDOWN 204 +#define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 205 +#define SSL_R_PUBLIC_KEY_IS_NOT_RSA 206 +#define SSL_R_PUBLIC_KEY_NOT_RSA 207 +#define SSL_R_READ_BIO_NOT_SET 208 +#define SSL_R_READ_WRONG_PACKET_TYPE 209 +#define SSL_R_RECORD_LENGTH_MISMATCH 210 +#define SSL_R_RECORD_TOO_LARGE 211 +#define SSL_R_REQUIRED_CIPHER_MISSING 212 +#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 213 +#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 214 +#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 215 +#define SSL_R_SHORT_READ 216 +#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 217 +#define SSL_R_SSL3_SESSION_ID_TOO_SHORT 218 #define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 #define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 #define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 @@ -229,44 +240,51 @@ #define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 #define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 #define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 -#define SSL_R_SSLV3_ALERT_PEER_ERROR_CERTIFICATE 213 -#define SSL_R_SSLV3_ALERT_PEER_ERROR_NO_CERTIFICATE 214 -#define SSL_R_SSLV3_ALERT_PEER_ERROR_NO_CIPHER 215 -#define SSL_R_SSLV3_ALERT_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 216 +#define SSL_R_SSLV3_ALERT_PEER_ERROR_CERTIFICATE 219 +#define SSL_R_SSLV3_ALERT_PEER_ERROR_NO_CERTIFICATE 220 +#define SSL_R_SSLV3_ALERT_PEER_ERROR_NO_CIPHER 221 +#define SSL_R_SSLV3_ALERT_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 222 #define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 -#define SSL_R_SSLV3_ALERT_UNKNOWN_REMOTE_ERROR_TYPE 217 +#define SSL_R_SSLV3_ALERT_UNKNOWN_REMOTE_ERROR_TYPE 223 #define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 -#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 218 -#define SSL_R_SSL_HANDSHAKE_FAILURE 219 -#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 220 -#define SSL_R_SSL_SESSION_ID_IS_DIFFERENT 221 -#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 222 -#define SSL_R_UNABLE_TO_DECODE_DH_CERTS 223 -#define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY 224 -#define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS 225 -#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 226 -#define SSL_R_UNABLE_TO_FIND_SSL_METHOD 227 -#define SSL_R_UNEXPECTED_MESSAGE 228 -#define SSL_R_UNEXPECTED_RECORD 229 -#define SSL_R_UNKNOWN_ALERT_TYPE 230 -#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 231 -#define SSL_R_UNKNOWN_CIPHER_RETURNED 232 -#define SSL_R_UNKNOWN_CIPHER_TYPE 233 -#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 234 -#define SSL_R_UNKNOWN_PKEY_TYPE 235 -#define SSL_R_UNKNOWN_PROTOCOL 236 -#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 237 -#define SSL_R_UNKNOWN_SSL_VERSION 238 -#define SSL_R_UNKNOWN_STATE 239 -#define SSL_R_UNSUPPORTED_CIPHER 240 -#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 241 -#define SSL_R_UNSUPPORTED_SSL_VERSION 242 -#define SSL_R_WRITE_BIO_NOT_SET 243 -#define SSL_R_WRONG_CIPHER_RETURNED 244 -#define SSL_R_WRONG_MESSAGE_TYPE 245 -#define SSL_R_WRONG_NUMBER_OF_KEY_BITS 246 -#define SSL_R_WRONG_SIGNATURE_LENGTH 247 -#define SSL_R_WRONG_SIGNATURE_SIZE 248 -#define SSL_R_WRONG_SSL_VERSION 249 -#define SSL_R_WRONG_VERSION_NUMBER 250 -#define SSL_R_X509_LIB 251 +#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 224 +#define SSL_R_SSL_HANDSHAKE_FAILURE 225 +#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 226 +#define SSL_R_SSL_SESSION_ID_IS_DIFFERENT 227 +#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 228 +#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 229 +#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 230 +#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 231 +#define SSL_R_UNABLE_TO_DECODE_DH_CERTS 232 +#define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY 233 +#define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS 234 +#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 235 +#define SSL_R_UNABLE_TO_FIND_SSL_METHOD 236 +#define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES 237 +#define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 238 +#define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 239 +#define SSL_R_UNEXPECTED_MESSAGE 240 +#define SSL_R_UNEXPECTED_RECORD 241 +#define SSL_R_UNKNOWN_ALERT_TYPE 242 +#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 243 +#define SSL_R_UNKNOWN_CIPHER_RETURNED 244 +#define SSL_R_UNKNOWN_CIPHER_TYPE 245 +#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 246 +#define SSL_R_UNKNOWN_PKEY_TYPE 247 +#define SSL_R_UNKNOWN_PROTOCOL 248 +#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 249 +#define SSL_R_UNKNOWN_SSL_VERSION 250 +#define SSL_R_UNKNOWN_STATE 251 +#define SSL_R_UNSUPPORTED_CIPHER 252 +#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 253 +#define SSL_R_UNSUPPORTED_PROTOCOL 254 +#define SSL_R_UNSUPPORTED_SSL_VERSION 255 +#define SSL_R_WRITE_BIO_NOT_SET 256 +#define SSL_R_WRONG_CIPHER_RETURNED 257 +#define SSL_R_WRONG_MESSAGE_TYPE 258 +#define SSL_R_WRONG_NUMBER_OF_KEY_BITS 259 +#define SSL_R_WRONG_SIGNATURE_LENGTH 260 +#define SSL_R_WRONG_SIGNATURE_SIZE 261 +#define SSL_R_WRONG_SSL_VERSION 262 +#define SSL_R_WRONG_VERSION_NUMBER 263 +#define SSL_R_X509_LIB 264 @@ -1,5 +1,5 @@ /* ssl/ssl.h */ -/* 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 @@ -118,7 +118,6 @@ extern "C" { #define SSL_TXT_RC2 "RC2" #define SSL_TXT_IDEA "IDEA" #define SSL_TXT_MD5 "MD5" -#define SSL_TXT_SHA0 "SHA0" #define SSL_TXT_SHA1 "SHA1" #define SSL_TXT_SHA "SHA" #define SSL_TXT_EXP "EXP" @@ -130,22 +129,18 @@ extern "C" { /* 'DEFAULT' at the start of the cipher list insert the following string * in addition to this being the default cipher string */ #ifndef NO_RSA -#define SSL_DEFAULT_CIPHER_LIST "!ADH:RC4+RSA:HIGH:MEDIUM:LOW:EXP:+SSLv2:+EXP" +#define SSL_DEFAULT_CIPHER_LIST "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP" #else #define SSL_ALLOW_ADH #define SSL_DEFAULT_CIPHER_LIST "HIGH:MEDIUM:LOW:ADH+3DES:ADH+RC4:ADH+DES:+EXP" #endif +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ #define SSL_SENT_SHUTDOWN 1 #define SSL_RECEIVED_SHUTDOWN 2 -#define SSL_CTX_set_quiet_shutdown(ctx,y) ((ctx)->quiet_shutdown=(y)); -#define SSL_CTX_get_quiet_shutdown(ctx) ((ctx)->quiet_shutdown); -#define SSL_set_quiet_shutdown(s,y) ((s)->quiet_shutdown=(y)); -#define SSL_get_quiet_shutdown(s) ((s)->quiet_shutdown); -#define SSL_set_shutdown(s,mode) ((s)->shutdown=(mode)) -#define SSL_get_shutdown(s) ((s)->shutdown) -#define SSL_version(s) ((s)->version) +#include "crypto.h" +#include "lhash.h" #include "buffer.h" #include "bio.h" #include "x509.h" @@ -153,6 +148,9 @@ extern "C" { #define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 #define SSL_FILETYPE_PEM X509_FILETYPE_PEM +/* This is needed to stop compilers complaining about the + * 'struct ssl_st *' function parameters used to prototype callbacks + * in SSL_CTX. */ typedef struct ssl_st *ssl_crock_st; /* used to hold info on the particular ciphers used */ @@ -166,7 +164,7 @@ typedef struct ssl_cipher_st unsigned long mask; /* used for matching */ } SSL_CIPHER; -/* Used to hold functions for SSLv2 or SSLv3 functions */ +/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ typedef struct ssl_method_st { int version; @@ -189,6 +187,7 @@ typedef struct ssl_method_st SSL_CIPHER *(*get_cipher)(); struct ssl_method_st *(*get_ssl_method)(); long (*get_timeout)(); + struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ } SSL_METHOD; typedef struct ssl_compression_st @@ -248,28 +247,39 @@ typedef struct ssl_session_st STACK /* SSL_CIPHER */ *ciphers; /* shared ciphers? */ - char *app_data; /* application specific data */ + CRYPTO_EX_DATA ex_data; /* application specific data */ + + /* These are used to make removal of session-ids more + * efficient and to implement a maximum cache size. */ + struct ssl_session_st *prev,*next; } SSL_SESSION; #define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L #define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L -#define SSL_OP_NETSCAPE_CA_DN_BUG 0x00000004L #define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L #define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L #define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L #define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x00000040L #define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x00000080L +#define SSL_OP_TLS_D5_BUG 0x00000100L +#define SSL_OP_TLS_BLOCK_PADDING_BUG 0x00000200L /* If set, only use tmp_dh parameters once */ #define SSL_OP_SINGLE_DH_USE 0x00100000L /* Set to also use the tmp_rsa key when doing RSA operations. */ #define SSL_OP_EPHEMERAL_RSA 0x00200000L +#define SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000L #define SSL_OP_NON_EXPORT_FIRST 0x40000000L #define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x80000000L #define SSL_OP_ALL 0x000FFFFFL #define SSL_CTX_set_options(ctx,op) ((ctx)->options|=(op)) +#define SSL_set_options(ssl,op) ((ssl)->options|=(op)) + +#define SSL_OP_NO_SSLv2 0x01000000L +#define SSL_OP_NO_SSLv3 0x02000000L +#define SSL_OP_NO_TLSv1 0x04000000L /* Normally you will only use these if your application wants to use * the certificate store in other places, perhaps PKCS7 */ @@ -278,6 +288,8 @@ typedef struct ssl_session_st (X509_STORE_free((ctx)->cert_store),(ctx)->cert_store=(cs)) +#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) + typedef struct ssl_ctx_st { SSL_METHOD *method; @@ -289,6 +301,11 @@ typedef struct ssl_ctx_st struct x509_store_st /* X509_STORE */ *cert_store; struct lhash_st /* LHASH */ *sessions; /* a set of SSL_SESSION's */ + /* Most session-ids that will be cached, default is + * SSL_SESSION_CACHE_SIZE_DEFAULT. 0 is unlimited. */ + unsigned long session_cache_size; + struct ssl_session_st *session_cache_head; + struct ssl_session_st *session_cache_tail; /* This can have one of 2 values, ored together, * SSL_SESS_CACHE_CLIENT, @@ -322,12 +339,15 @@ typedef struct ssl_ctx_st SSL_SESSION *(*get_session_cb)(); #endif - int sess_connect; /* SSL new (expensive) connection - started */ - int sess_connect_good; /* SSL new (expensive) connection - finished */ - int sess_accept; /* SSL new (expensive) accept - started */ - int sess_accept_good; /* SSL new (expensive) accept - finished */ + int sess_connect; /* SSL new connection - started */ + int sess_connect_renegotiate;/* SSL renegotiatene - requested */ + int sess_connect_good; /* SSL new connection/renegotiate - finished */ + int sess_accept; /* SSL new accept - started */ + int sess_accept_renegotiate;/* SSL renegotiatene - requested */ + int sess_accept_good; /* SSL accept/renegotiate - finished */ int sess_miss; /* session lookup misses */ int sess_timeout; /* session reuse attempt on timeouted session */ + int sess_cache_full; /* session removed due to full cache */ int sess_hit; /* session reuse actually done */ int sess_cb_hit; /* session-id that was not in the cache was * passed back via the callback. This @@ -360,16 +380,22 @@ typedef struct ssl_ctx_st int quiet_shutdown; - char *app_data; + CRYPTO_EX_DATA ex_data; + + EVP_MD *rsa_md5;/* For SSLv2 - name is 'ssl2-md5' */ + EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */ + EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3->sha1' */ } SSL_CTX; -#define SSL_SESS_CACHE_OFF 0x00 -#define SSL_SESS_CACHE_CLIENT 0x01 -#define SSL_SESS_CACHE_SERVER 0x02 +#define SSL_SESS_CACHE_OFF 0x0000 +#define SSL_SESS_CACHE_CLIENT 0x0001 +#define SSL_SESS_CACHE_SERVER 0x0002 #define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) -#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x80 - -#define SSL_session_reused(s) ((s)->hit) +#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 +/* This one, when set, makes the server session-id lookup not look + * in the cache. If there is an application get_session callback + * defined, this will still get called. */ +#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 #define SSL_CTX_sessions(ctx) ((ctx)->sessions) /* You will need to include lhash.h to access the following #define */ @@ -377,11 +403,17 @@ typedef struct ssl_ctx_st #define SSL_CTX_sess_connect(ctx) ((ctx)->sess_connect) #define SSL_CTX_sess_connect_good(ctx) ((ctx)->sess_connect_good) #define SSL_CTX_sess_accept(ctx) ((ctx)->sess_accept) +#define SSL_CTX_sess_accept_renegotiate(ctx) ((ctx)->sess_accept_renegotiate) +#define SSL_CTX_sess_connect_renegotiate(ctx) ((ctx)->sess_connect_renegotiate) #define SSL_CTX_sess_accept_good(ctx) ((ctx)->sess_accept_good) #define SSL_CTX_sess_hits(ctx) ((ctx)->sess_hit) #define SSL_CTX_sess_cb_hits(ctx) ((ctx)->sess_cb_hit) #define SSL_CTX_sess_misses(ctx) ((ctx)->sess_miss) #define SSL_CTX_sess_timeouts(ctx) ((ctx)->sess_timeout) +#define SSL_CTX_sess_cache_full(ctx) ((ctx)->sess_cache_full) + +#define SSL_CTX_sess_set_cache_size(ctx,t) ((ctx)->session_cache_size=(t)) +#define SSL_CTX_sess_get_cache_size(ctx) ((ctx)->session_cache_size) #define SSL_CTX_sess_set_new_cb(ctx,cb) ((ctx)->new_session_cb=(cb)) #define SSL_CTX_sess_get_new_cb(ctx) ((ctx)->new_session_cb) @@ -510,30 +542,29 @@ typedef struct ssl_st int debug; /* extra application data */ - int verify_result; - char *app_data; + long verify_result; + CRYPTO_EX_DATA ex_data; /* for server side, keep the list of CA_dn we can use */ STACK /* X509_NAME */ *client_CA; + int references; + unsigned long options; int first_packet; } SSL; #include "ssl2.h" #include "ssl3.h" +#include "tls1.h" /* This is mostly sslv3 with a few tweaks */ #include "ssl23.h" -/* application stuff */ -#define SSL_set_verify_result(s,arg) ((s)->verify_result=(long)arg) -#define SSL_get_verify_result(s) ((s)->verify_result) -#define SSL_set_app_data(s,arg) ((s)->app_data=(char *)arg) -#define SSL_get_app_data(s) ((s)->app_data) - -#define SSL_SESSION_set_app_data(s,arg) ((s)->app_data=(char *)arg) -#define SSL_SESSION_get_app_data(s) ((s)->app_data) - -#define SSL_CTX_set_app_data(ctx,arg) ((ctx)->app_data=(char *)arg) -#define SSL_CTX_get_app_data(ctx) ((ctx)->app_data) +/* compatablity */ +#define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)arg)) +#define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) +#define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0,(char *)a)) +#define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) +#define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) +#define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0,(char *)arg)) /* The following are the possible values for ssl->state are are * used to indicate where we are upto in the SSL connection establishment. @@ -542,7 +573,6 @@ typedef struct ssl_st * It can also be useful to work out where you were when the connection * failed */ -#define SSL_state(a) ((a)->state) #define SSL_ST_CONNECT 0x1000 #define SSL_ST_ACCEPT 0x2000 #define SSL_ST_MASK 0x0FFF @@ -551,10 +581,6 @@ typedef struct ssl_st #define SSL_ST_OK 0x03 #define SSL_ST_RENEGOTIATE (0x04|SSL_ST_INIT) -/* SSL info callback functions */ -#define SSL_set_info_callback(ssl,cb) ((ssl)->info_callback=(cb)) -#define SSL_get_info_callback(ssl) ((ssl)->info_callback) - #define SSL_CB_LOOP 0x01 #define SSL_CB_EXIT 0x02 #define SSL_CB_READ 0x04 @@ -570,11 +596,12 @@ typedef struct ssl_st #define SSL_CB_HANDSHAKE_DONE 0x20 /* Is the SSL_connection established? */ -#define SSL_is_init_finished(a) ((a)->state == SSL_ST_OK) -#define SSL_in_init(a) ((a)->state&SSL_ST_INIT) -#define SSL_in_before(a) ((a)->state&SSL_ST_BEFORE) -#define SSL_in_connect_init(a) ((a)->state&SSL_ST_CONNECT) -#define SSL_in_accept_init(a) ((a)->state&SSL_ST_ACCEPT) +#define SSL_get_state(a) SSL_state(a) +#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK) +#define SSL_in_init(a) (SSL_state(a)&SSL_ST_INIT) +#define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE) +#define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT) +#define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT) /* The following 2 states are kept in ssl->rstate when reads fail, * you should not need these */ @@ -589,20 +616,6 @@ typedef struct ssl_st #define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 #define SSL_VERIFY_CLIENT_ONCE 0x04 -#define SSL_RWERR_BAD_WRITE_RETRY (-2) -#define SSL_RWERR_BAD_MAC_DECODE (-3) -#define SSL_RWERR_INTERNAL_ERROR (-4) /* should not get this one */ -#define SSL_RWERR_WRONG_RECORD_TYPE (-5) /* used internally */ - -#define SSL_CTX_set_default_verify_paths(ctx) \ - X509_STORE_set_default_paths((ctx)->cert_store) -#define SSL_CTX_load_verify_locations(ctx,CAfile,CApath) \ - X509_STORE_load_locations((ctx)->cert_store,\ - (CAfile),(CApath)) - -#define SSL_get_session(s) ((s)->session) -#define SSL_get_SSL_CTX(s) ((s)->ctx) - /* this is for backward compatablility */ #if 0 /* NEW_SSLEAY */ #define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c) @@ -620,6 +633,10 @@ typedef struct ssl_st SSL_CIPHER_get_version(SSL_get_current_cipher(s)) #define SSL_get_cipher_name(s) \ SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +#define SSL_get_time(a) SSL_SESSION_get_time(a) +#define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) +#define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) +#define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) /* VMS linker has a 31 char name limit */ #define SSL_CTX_set_cert_verify_callback(a,b,c) \ @@ -643,6 +660,32 @@ typedef struct ssl_st PEM_STRING_SSL_SESSION,bp, (char *)x, NULL,NULL,0,NULL) #endif +/* These alert types are for SSLv3 and TLSv1 */ +#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE /* fatal */ +#define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC /* fatal */ +#define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED +#define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW +#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE/* fatal */ +#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE/* fatal */ +#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE /* Not for TLS */ +#define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE +#define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE +#define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED +#define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED +#define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN +#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER /* fatal */ +#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA /* fatal */ +#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED /* fatal */ +#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR /* fatal */ +#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +#define SSL_AD_EXPORT_RESTRICION TLS1_AD_EXPORT_RESTRICION/* fatal */ +#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION /* fatal */ +#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY/* fatal */ +#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR /* fatal */ +#define SSL_AD_USER_CANCLED TLS1_AD_USER_CANCLED +#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION + #define SSL_ERROR_NONE 0 #define SSL_ERROR_SSL 1 #define SSL_ERROR_WANT_READ 2 @@ -652,11 +695,26 @@ typedef struct ssl_st #define SSL_ERROR_ZERO_RETURN 6 #define SSL_ERROR_WANT_CONNECT 7 -#define SSL_CTRL_NEED_TMP_RSA 1 -#define SSL_CTRL_SET_TMP_RSA 2 -#define SSL_CTRL_SET_TMP_DH 3 -#define SSL_CTRL_SET_TMP_RSA_CB 4 -#define SSL_CTRL_SET_TMP_DH_CB 5 +#define SSL_CTRL_NEED_TMP_RSA 1 +#define SSL_CTRL_SET_TMP_RSA 2 +#define SSL_CTRL_SET_TMP_DH 3 +#define SSL_CTRL_SET_TMP_RSA_CB 4 +#define SSL_CTRL_SET_TMP_DH_CB 5 +/* Add these ones */ +#define SSL_CTRL_GET_SESSION_REUSED 6 +#define SSL_CTRL_GET_CLIENT_CERT_REQUEST 7 +#define SSL_CTRL_GET_NUM_RENEGOTIATIONS 8 +#define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 9 +#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 10 + +#define SSL_session_reused(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) +#define SSL_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) +#define SSL_clear_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) +#define SSL_total_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) #define SSL_CTX_need_tmp_RSA(ctx) \ SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL) @@ -672,13 +730,15 @@ typedef struct ssl_st #define SSL_CTX_set_tmp_rsa_callback(ctx,cb) \ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA_CB,0,(char *)cb) #define SSL_CTX_set_tmp_dh_callback(ctx,dh) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,0,(char *)cb) + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,0,(char *)dh) #ifndef NOPROTO #ifdef HEADER_BIO_H BIO_METHOD *BIO_f_ssl(void); BIO *BIO_new_ssl(SSL_CTX *ctx,int client); +BIO *BIO_new_ssl_connect(SSL_CTX *ctx); +BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); int BIO_ssl_copy_session_id(BIO *to,BIO *from); void BIO_ssl_shutdown(BIO *ssl_bio); @@ -717,27 +777,37 @@ int (*SSL_get_verify_callback(SSL *s))(); void SSL_set_verify(SSL *s, int mode, int (*callback) ()); int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len); -int SSL_use_RSAPrivateKey_file(SSL *ssl, char *file, int type); int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, unsigned char *d, long len); -int SSL_use_PrivateKey_file(SSL *ssl, char *file, int type); int SSL_use_certificate(SSL *ssl, X509 *x); int SSL_use_certificate_ASN1(SSL *ssl, int len, unsigned char *d); + +#ifndef NO_STDIO +int SSL_use_RSAPrivateKey_file(SSL *ssl, char *file, int type); +int SSL_use_PrivateKey_file(SSL *ssl, char *file, int type); int SSL_use_certificate_file(SSL *ssl, char *file, int type); +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, char *file, int type); +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, char *file, int type); +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, char *file, int type); +STACK * SSL_load_client_CA_file(char *file); +#endif + void ERR_load_SSL_strings(void ); void SSL_load_error_strings(void ); char * SSL_state_string(SSL *s); char * SSL_rstate_string(SSL *s); char * SSL_state_string_long(SSL *s); char * SSL_rstate_string_long(SSL *s); -long SSL_get_time(SSL_SESSION *s); -long SSL_set_time(SSL_SESSION *s, long t); -long SSL_get_timeout(SSL_SESSION *s); -long SSL_set_timeout(SSL_SESSION *s, long t); +long SSL_SESSION_get_time(SSL_SESSION *s); +long SSL_SESSION_set_time(SSL_SESSION *s, long t); +long SSL_SESSION_get_timeout(SSL_SESSION *s); +long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); void SSL_copy_session_id(SSL *to,SSL *from); SSL_SESSION *SSL_SESSION_new(void); -#ifndef WIN16 +unsigned long SSL_SESSION_hash(SSL_SESSION *a); +int SSL_SESSION_cmp(SSL_SESSION *a,SSL_SESSION *b); +#ifndef NO_FP_API int SSL_SESSION_print_fp(FILE *fp,SSL_SESSION *ses); #endif #ifdef HEADER_BIO_H @@ -762,14 +832,11 @@ void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int (*callback)()); void SSL_CTX_set_cert_verify_cb(SSL_CTX *ctx, int (*cb)(),char *arg); int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, unsigned char *d, long len); -int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, char *file, int type); int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); int SSL_CTX_use_PrivateKey_ASN1(int pk,SSL_CTX *ctx, unsigned char *d, long len); -int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, char *file, int type); int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, unsigned char *d); -int SSL_CTX_use_certificate_file(SSL_CTX *ctx, char *file, int type); void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx,int (*cb)()); @@ -793,17 +860,21 @@ char * SSL_get_version(SSL *s); /* This sets the 'default' SSL version that SSL_new() will create */ int SSL_CTX_set_ssl_version(SSL_CTX *ctx,SSL_METHOD *meth); -SSL_METHOD *SSLv2_method(void); /* sslv2 */ -SSL_METHOD *SSLv2_server_method(void); /* sslv2 */ -SSL_METHOD *SSLv2_client_method(void); /* sslv2 */ +SSL_METHOD *SSLv2_method(void); /* SSLv2 */ +SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */ +SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */ -SSL_METHOD *SSLv3_method(void); /* sslv3 */ -SSL_METHOD *SSLv3_server_method(void); /* sslv3 */ -SSL_METHOD *SSLv3_client_method(void); /* sslv3 */ +SSL_METHOD *SSLv3_method(void); /* SSLv3 */ +SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */ +SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */ -SSL_METHOD *SSLv23_method(void); /* sslv3 but can rollback to v2 */ -SSL_METHOD *SSLv23_server_method(void); /* sslv3 but can rollback to v2 */ -SSL_METHOD *SSLv23_client_method(void); /* sslv3 but can rollback to v2 */ +SSL_METHOD *SSLv23_method(void); /* SSLv3 but can rollback to v2 */ +SSL_METHOD *SSLv23_server_method(void); /* SSLv3 but can rollback to v2 */ +SSL_METHOD *SSLv23_client_method(void); /* SSLv3 but can rollback to v2 */ + +SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ +SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ +SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */ STACK *SSL_get_ciphers(SSL *s); @@ -818,7 +889,6 @@ char *SSL_alert_type_string(int value); char *SSL_alert_desc_string_long(int value); char *SSL_alert_desc_string(int value); -STACK *SSL_load_client_CA_file(char *file); void SSL_set_client_CA_list(SSL *s, STACK *list); void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK *list); STACK *SSL_get_client_CA_list(SSL *s); @@ -841,10 +911,45 @@ SSL *SSL_dup(SSL *ssl); X509 *SSL_get_certificate(SSL *ssl); /* EVP_PKEY */ struct evp_pkey_st *SSL_get_privatekey(SSL *ssl); +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode); +int SSL_CTX_get_quiet_shutdown(SSL_CTX *ctx); +void SSL_set_quiet_shutdown(SSL *ssl,int mode); +int SSL_get_quiet_shutdown(SSL *ssl); +void SSL_set_shutdown(SSL *ssl,int mode); +int SSL_get_shutdown(SSL *ssl); +int SSL_version(SSL *ssl); +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); +int SSL_CTX_load_verify_locations(SSL_CTX *ctx,char *CAfile,char *CApath); +SSL_SESSION *SSL_get_session(SSL *ssl); +SSL_CTX *SSL_get_SSL_CTX(SSL *ssl); +void SSL_set_info_callback(SSL *ssl,void (*cb)()); +void (*SSL_get_info_callback(SSL *ssl))(); +int SSL_state(SSL *ssl); + +void SSL_set_verify_result(SSL *ssl,long v); +long SSL_get_verify_result(SSL *ssl); + +int SSL_set_ex_data(SSL *ssl,int idx,char *data); +char *SSL_get_ex_data(SSL *ssl,int idx); +int SSL_get_ex_new_index(long argl, char *argp, int (*new_func)(), + int (*dup_func)(), void (*free_func)()); + +int SSL_SESSION_set_ex_data(SSL_SESSION *ss,int idx,char *data); +char *SSL_SESSION_get_ex_data(SSL_SESSION *ss,int idx); +int SSL_SESSION_get_ex_new_index(long argl, char *argp, int (*new_func)(), + int (*dup_func)(), void (*free_func)()); + +int SSL_CTX_set_ex_data(SSL_CTX *ssl,int idx,char *data); +char *SSL_CTX_get_ex_data(SSL_CTX *ssl,int idx); +int SSL_CTX_get_ex_new_index(long argl, char *argp, int (*new_func)(), + int (*dup_func)(), void (*free_func)()); + #else BIO_METHOD *BIO_f_ssl(); BIO *BIO_new_ssl(); +BIO *BIO_new_ssl_connect(); +BIO *BIO_new_buffer_ssl_connect(); int BIO_ssl_copy_session_id(); void BIO_ssl_shutdown(); @@ -881,27 +986,37 @@ int SSL_get_verify_mode(); void SSL_set_verify(); int SSL_use_RSAPrivateKey(); int SSL_use_RSAPrivateKey_ASN1(); -int SSL_use_RSAPrivateKey_file(); int SSL_use_PrivateKey(); int SSL_use_PrivateKey_ASN1(); -int SSL_use_PrivateKey_file(); int SSL_use_certificate(); int SSL_use_certificate_ASN1(); + +#ifndef NO_STDIO +int SSL_use_RSAPrivateKey_file(); +int SSL_use_PrivateKey_file(); int SSL_use_certificate_file(); +int SSL_CTX_use_RSAPrivateKey_file(); +int SSL_CTX_use_PrivateKey_file(); +int SSL_CTX_use_certificate_file(); +STACK * SSL_load_client_CA_file(); +#endif + void ERR_load_SSL_strings(); void SSL_load_error_strings(); char * SSL_state_string(); char * SSL_rstate_string(); char * SSL_state_string_long(); char * SSL_rstate_string_long(); -long SSL_get_time(); -long SSL_set_time(); -long SSL_get_timeout(); -long SSL_set_timeout(); +long SSL_SESSION_get_time(); +long SSL_SESSION_set_time(); +long SSL_SESSION_get_timeout(); +long SSL_SESSION_set_timeout(); void SSL_copy_session_id(); SSL_SESSION *SSL_SESSION_new(); -#ifndef WIN16 +unsigned long SSL_SESSION_hash(); +int SSL_SESSION_cmp(); +#ifndef NO_FP_API int SSL_SESSION_print_fp(); #endif #ifdef HEADER_BIO_H @@ -926,13 +1041,10 @@ void SSL_CTX_set_verify(); void SSL_CTX_set_cert_verify_cb(); int SSL_CTX_use_RSAPrivateKey(); int SSL_CTX_use_RSAPrivateKey_ASN1(); -int SSL_CTX_use_RSAPrivateKey_file(); int SSL_CTX_use_PrivateKey(); int SSL_CTX_use_PrivateKey_ASN1(); -int SSL_CTX_use_PrivateKey_file(); int SSL_CTX_use_certificate(); int SSL_CTX_use_certificate_ASN1(); -int SSL_CTX_use_certificate_file(); void SSL_CTX_set_default_passwd_cb(); @@ -967,6 +1079,10 @@ SSL_METHOD *SSLv23_method(); SSL_METHOD *SSLv23_server_method(); SSL_METHOD *SSLv23_client_method(); +SSL_METHOD *TLSv1_method(); +SSL_METHOD *TLSv1_server_method(); +SSL_METHOD *TLSv1_client_method(); + STACK *SSL_get_ciphers(); int SSL_do_handshake(); @@ -980,7 +1096,6 @@ char *SSL_alert_type_string(); char *SSL_alert_desc_string_long(); char *SSL_alert_desc_string(); -STACK *SSL_load_client_CA_file(); void SSL_set_client_CA_list(); void SSL_CTX_set_client_CA_list(); STACK *SSL_get_client_CA_list(); @@ -1005,6 +1120,36 @@ X509 *SSL_get_certificate(); #ifdef this_is_for_mk1mf_pl EVP *SSL_get_privatekey(); + +void SSL_CTX_set_quiet_shutdown(); +int SSL_CTX_get_quiet_shutdown(); +void SSL_set_quiet_shutdown(); +int SSL_get_quiet_shutdown(); +void SSL_set_shutdown(); +int SSL_get_shutdown(); +int SSL_version(); +int SSL_CTX_set_default_verify_paths(); +int SSL_CTX_load_verify_locations(); +SSL_SESSION *SSL_get_session(); +SSL_CTX *SSL_get_SSL_CTX(); +void SSL_set_info_callback(); +int (*SSL_get_info_callback())(); +int SSL_state(); +void SSL_set_verify_result(); +long SSL_get_verify_result(); + +int SSL_set_ex_data(); +char *SSL_get_ex_data(); +int SSL_get_ex_new_index(); + +int SSL_SESSION_set_ex_data(); +char *SSL_SESSION_get_ex_data(); +int SSL_SESSION_get_ex_new_index(); + +int SSL_CTX_set_ex_data(); +char *SSL_CTX_get_ex_data(); +int SSL_CTX_get_ex_new_index(); + #endif #endif @@ -1094,29 +1239,34 @@ EVP *SSL_get_privatekey(); #define SSL_F_SSL_GET_NEW_SESSION 178 #define SSL_F_SSL_GET_SERVER_SEND_CERT 179 #define SSL_F_SSL_GET_SIGN_PKEY 180 -#define SSL_F_SSL_LOAD_CLIENT_CA_FILE 181 -#define SSL_F_SSL_NEW 182 -#define SSL_F_SSL_RSA_PRIVATE_DECRYPT 183 -#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 184 -#define SSL_F_SSL_SESSION_NEW 185 -#define SSL_F_SSL_SESSION_PRINT_FP 186 -#define SSL_F_SSL_SET_FD 187 -#define SSL_F_SSL_SET_PKEY 188 -#define SSL_F_SSL_SET_RFD 189 -#define SSL_F_SSL_SET_SESSION 190 -#define SSL_F_SSL_SET_WFD 191 -#define SSL_F_SSL_UNDEFINED_FUNCTION 192 -#define SSL_F_SSL_USE_CERTIFICATE 193 -#define SSL_F_SSL_USE_CERTIFICATE_ASN1 194 -#define SSL_F_SSL_USE_CERTIFICATE_FILE 195 -#define SSL_F_SSL_USE_PRIVATEKEY 196 -#define SSL_F_SSL_USE_PRIVATEKEY_ASN1 197 -#define SSL_F_SSL_USE_PRIVATEKEY_FILE 198 -#define SSL_F_SSL_USE_RSAPRIVATEKEY 199 -#define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 200 -#define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 201 -#define SSL_F_SSL_WRITE 202 -#define SSL_F_WRITE_PENDING 203 +#define SSL_F_SSL_INIT_WBIO_BUFFER 181 +#define SSL_F_SSL_LOAD_CLIENT_CA_FILE 182 +#define SSL_F_SSL_NEW 183 +#define SSL_F_SSL_RSA_PRIVATE_DECRYPT 184 +#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 185 +#define SSL_F_SSL_SESSION_NEW 186 +#define SSL_F_SSL_SESSION_PRINT_FP 187 +#define SSL_F_SSL_SET_CERT 188 +#define SSL_F_SSL_SET_FD 189 +#define SSL_F_SSL_SET_PKEY 190 +#define SSL_F_SSL_SET_RFD 191 +#define SSL_F_SSL_SET_SESSION 192 +#define SSL_F_SSL_SET_WFD 193 +#define SSL_F_SSL_UNDEFINED_FUNCTION 194 +#define SSL_F_SSL_USE_CERTIFICATE 195 +#define SSL_F_SSL_USE_CERTIFICATE_ASN1 196 +#define SSL_F_SSL_USE_CERTIFICATE_FILE 197 +#define SSL_F_SSL_USE_PRIVATEKEY 198 +#define SSL_F_SSL_USE_PRIVATEKEY_ASN1 199 +#define SSL_F_SSL_USE_PRIVATEKEY_FILE 200 +#define SSL_F_SSL_USE_RSAPRIVATEKEY 201 +#define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 202 +#define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 203 +#define SSL_F_SSL_WRITE 204 +#define SSL_F_TLS1_CHANGE_CIPHER_STATE 205 +#define SSL_F_TLS1_ENC 206 +#define SSL_F_TLS1_SETUP_KEY_BLOCK 207 +#define SSL_F_WRITE_PENDING 208 /* Reason codes. */ #define SSL_R_APP_DATA_IN_HANDSHAKE 100 @@ -1135,103 +1285,109 @@ EVP *SSL_get_privatekey(); #define SSL_R_BAD_MAC_DECODE 113 #define SSL_R_BAD_MESSAGE_TYPE 114 #define SSL_R_BAD_PACKET_LENGTH 115 -#define SSL_R_BAD_RESPONSE_ARGUMENT 116 -#define SSL_R_BAD_RSA_DECRYPT 117 -#define SSL_R_BAD_RSA_ENCRYPT 118 -#define SSL_R_BAD_RSA_E_LENGTH 119 -#define SSL_R_BAD_RSA_MODULUS_LENGTH 120 -#define SSL_R_BAD_RSA_SIGNATURE 121 -#define SSL_R_BAD_SIGNATURE 122 -#define SSL_R_BAD_SSL_FILETYPE 123 -#define SSL_R_BAD_SSL_SESSION_ID_LENGTH 124 -#define SSL_R_BAD_STATE 125 -#define SSL_R_BAD_WRITE_RETRY 126 -#define SSL_R_BIO_NOT_SET 127 -#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 128 -#define SSL_R_BN_LIB 129 -#define SSL_R_CA_DN_LENGTH_MISMATCH 130 -#define SSL_R_CA_DN_TOO_LONG 131 -#define SSL_R_CCS_RECEIVED_EARLY 132 -#define SSL_R_CERTIFICATE_VERIFY_FAILED 133 -#define SSL_R_CERT_LENGTH_MISMATCH 134 -#define SSL_R_CHALLENGE_IS_DIFFERENT 135 -#define SSL_R_CIPHER_CODE_WRONG_LENGTH 136 -#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 137 -#define SSL_R_CIPHER_TABLE_SRC_ERROR 138 -#define SSL_R_COMPRESSED_LENGTH_TOO_LONG 139 -#define SSL_R_COMPRESSION_FAILURE 140 -#define SSL_R_CONNECTION_ID_IS_DIFFERENT 141 -#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 142 -#define SSL_R_DATA_LENGTH_TOO_LONG 143 -#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 144 -#define SSL_R_DIGEST_CHECK_FAILED 145 -#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 146 -#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 147 -#define SSL_R_EXCESSIVE_MESSAGE_SIZE 148 -#define SSL_R_EXTRA_DATA_IN_MESSAGE 149 -#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 150 -#define SSL_R_INTERNAL_ERROR 151 -#define SSL_R_INVALID_CHALLENGE_LENGTH 152 -#define SSL_R_LENGTH_MISMATCH 153 -#define SSL_R_LENGTH_TOO_SHORT 154 -#define SSL_R_LIBRARY_HAS_NO_CIPHERS 155 -#define SSL_R_MISSING_DH_DSA_CERT 156 -#define SSL_R_MISSING_DH_KEY 157 -#define SSL_R_MISSING_DH_RSA_CERT 158 -#define SSL_R_MISSING_DSA_SIGNING_CERT 159 -#define SSL_R_MISSING_EXPORT_TMP_DH_KEY 160 -#define SSL_R_MISSING_EXPORT_TMP_RSA_KEY 161 -#define SSL_R_MISSING_RSA_CERTIFICATE 162 -#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 163 -#define SSL_R_MISSING_RSA_SIGNING_CERT 164 -#define SSL_R_MISSING_TMP_DH_KEY 165 -#define SSL_R_MISSING_TMP_RSA_KEY 166 -#define SSL_R_MISSING_TMP_RSA_PKEY 167 -#define SSL_R_MISSING_VERIFY_MESSAGE 168 -#define SSL_R_NON_SSLV2_INITIAL_PACKET 169 -#define SSL_R_NO_CERTIFICATES_PASSED 170 -#define SSL_R_NO_CERTIFICATE_ASSIGNED 171 -#define SSL_R_NO_CERTIFICATE_RETURNED 172 -#define SSL_R_NO_CERTIFICATE_SET 173 -#define SSL_R_NO_CERTIFICATE_SPECIFIED 174 -#define SSL_R_NO_CIPHERS_AVAILABLE 175 -#define SSL_R_NO_CIPHERS_PASSED 176 -#define SSL_R_NO_CIPHERS_SPECIFIED 177 -#define SSL_R_NO_CIPHER_LIST 178 -#define SSL_R_NO_CIPHER_MATCH 179 -#define SSL_R_NO_CLIENT_CERT_RECEIVED 180 -#define SSL_R_NO_COMPRESSION_SPECIFIED 181 -#define SSL_R_NO_PRIVATEKEY 182 -#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 183 -#define SSL_R_NO_PUBLICKEY 184 -#define SSL_R_NO_SHARED_CIPHER 185 -#define SSL_R_NULL_SSL_CTX 186 -#define SSL_R_NULL_SSL_METHOD_PASSED 187 -#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 188 -#define SSL_R_PACKET_LENGTH_TOO_LONG 189 -#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 190 -#define SSL_R_PEER_ERROR 191 -#define SSL_R_PEER_ERROR_CERTIFICATE 192 -#define SSL_R_PEER_ERROR_NO_CERTIFICATE 193 -#define SSL_R_PEER_ERROR_NO_CIPHER 194 -#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 195 -#define SSL_R_PRE_MAC_LENGTH_TOO_LONG 196 -#define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 197 -#define SSL_R_PROTOCOL_IS_SHUTDOWN 198 -#define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 199 -#define SSL_R_PUBLIC_KEY_IS_NOT_RSA 200 -#define SSL_R_PUBLIC_KEY_NOT_RSA 201 -#define SSL_R_READ_BIO_NOT_SET 202 -#define SSL_R_READ_WRONG_PACKET_TYPE 203 -#define SSL_R_RECORD_LENGTH_MISMATCH 204 -#define SSL_R_RECORD_TOO_LARGE 205 -#define SSL_R_REQUIRED_CIPHER_MISSING 206 -#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 207 -#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 208 -#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 209 -#define SSL_R_SHORT_READ 210 -#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 211 -#define SSL_R_SSL3_SESSION_ID_TOO_SHORT 212 +#define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +#define SSL_R_BAD_RESPONSE_ARGUMENT 117 +#define SSL_R_BAD_RSA_DECRYPT 118 +#define SSL_R_BAD_RSA_ENCRYPT 119 +#define SSL_R_BAD_RSA_E_LENGTH 120 +#define SSL_R_BAD_RSA_MODULUS_LENGTH 121 +#define SSL_R_BAD_RSA_SIGNATURE 122 +#define SSL_R_BAD_SIGNATURE 123 +#define SSL_R_BAD_SSL_FILETYPE 124 +#define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125 +#define SSL_R_BAD_STATE 126 +#define SSL_R_BAD_WRITE_RETRY 127 +#define SSL_R_BIO_NOT_SET 128 +#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 +#define SSL_R_BN_LIB 130 +#define SSL_R_CA_DN_LENGTH_MISMATCH 131 +#define SSL_R_CA_DN_TOO_LONG 132 +#define SSL_R_CCS_RECEIVED_EARLY 133 +#define SSL_R_CERTIFICATE_VERIFY_FAILED 134 +#define SSL_R_CERT_LENGTH_MISMATCH 135 +#define SSL_R_CHALLENGE_IS_DIFFERENT 136 +#define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 +#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 +#define SSL_R_CIPHER_TABLE_SRC_ERROR 139 +#define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +#define SSL_R_COMPRESSION_FAILURE 141 +#define SSL_R_CONNECTION_ID_IS_DIFFERENT 142 +#define SSL_R_CONNECTION_TYPE_NOT_SET 143 +#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 144 +#define SSL_R_DATA_LENGTH_TOO_LONG 145 +#define SSL_R_DECRYPTION_FAILED 146 +#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 147 +#define SSL_R_DIGEST_CHECK_FAILED 148 +#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 149 +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 150 +#define SSL_R_EXCESSIVE_MESSAGE_SIZE 151 +#define SSL_R_EXTRA_DATA_IN_MESSAGE 152 +#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 153 +#define SSL_R_HTTPS_PROXY_REQUEST 154 +#define SSL_R_HTTP_REQUEST 155 +#define SSL_R_INTERNAL_ERROR 156 +#define SSL_R_INVALID_CHALLENGE_LENGTH 157 +#define SSL_R_LENGTH_MISMATCH 158 +#define SSL_R_LENGTH_TOO_SHORT 159 +#define SSL_R_LIBRARY_HAS_NO_CIPHERS 160 +#define SSL_R_MISSING_DH_DSA_CERT 161 +#define SSL_R_MISSING_DH_KEY 162 +#define SSL_R_MISSING_DH_RSA_CERT 163 +#define SSL_R_MISSING_DSA_SIGNING_CERT 164 +#define SSL_R_MISSING_EXPORT_TMP_DH_KEY 165 +#define SSL_R_MISSING_EXPORT_TMP_RSA_KEY 166 +#define SSL_R_MISSING_RSA_CERTIFICATE 167 +#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 168 +#define SSL_R_MISSING_RSA_SIGNING_CERT 169 +#define SSL_R_MISSING_TMP_DH_KEY 170 +#define SSL_R_MISSING_TMP_RSA_KEY 171 +#define SSL_R_MISSING_TMP_RSA_PKEY 172 +#define SSL_R_MISSING_VERIFY_MESSAGE 173 +#define SSL_R_NON_SSLV2_INITIAL_PACKET 174 +#define SSL_R_NO_CERTIFICATES_RETURNED 175 +#define SSL_R_NO_CERTIFICATE_ASSIGNED 176 +#define SSL_R_NO_CERTIFICATE_RETURNED 177 +#define SSL_R_NO_CERTIFICATE_SET 178 +#define SSL_R_NO_CERTIFICATE_SPECIFIED 179 +#define SSL_R_NO_CIPHERS_AVAILABLE 180 +#define SSL_R_NO_CIPHERS_PASSED 181 +#define SSL_R_NO_CIPHERS_SPECIFIED 182 +#define SSL_R_NO_CIPHER_LIST 183 +#define SSL_R_NO_CIPHER_MATCH 184 +#define SSL_R_NO_CLIENT_CERT_RECEIVED 185 +#define SSL_R_NO_COMPRESSION_SPECIFIED 186 +#define SSL_R_NO_PRIVATEKEY 187 +#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 188 +#define SSL_R_NO_PROTOCOLS_AVAILABLE 189 +#define SSL_R_NO_PUBLICKEY 190 +#define SSL_R_NO_SHARED_CIPHER 191 +#define SSL_R_NULL_SSL_CTX 192 +#define SSL_R_NULL_SSL_METHOD_PASSED 193 +#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 194 +#define SSL_R_PACKET_LENGTH_TOO_LONG 195 +#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 196 +#define SSL_R_PEER_ERROR 197 +#define SSL_R_PEER_ERROR_CERTIFICATE 198 +#define SSL_R_PEER_ERROR_NO_CERTIFICATE 199 +#define SSL_R_PEER_ERROR_NO_CIPHER 200 +#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 201 +#define SSL_R_PRE_MAC_LENGTH_TOO_LONG 202 +#define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 203 +#define SSL_R_PROTOCOL_IS_SHUTDOWN 204 +#define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 205 +#define SSL_R_PUBLIC_KEY_IS_NOT_RSA 206 +#define SSL_R_PUBLIC_KEY_NOT_RSA 207 +#define SSL_R_READ_BIO_NOT_SET 208 +#define SSL_R_READ_WRONG_PACKET_TYPE 209 +#define SSL_R_RECORD_LENGTH_MISMATCH 210 +#define SSL_R_RECORD_TOO_LARGE 211 +#define SSL_R_REQUIRED_CIPHER_MISSING 212 +#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 213 +#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 214 +#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 215 +#define SSL_R_SHORT_READ 216 +#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 217 +#define SSL_R_SSL3_SESSION_ID_TOO_SHORT 218 #define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 #define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 #define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 @@ -1241,47 +1397,54 @@ EVP *SSL_get_privatekey(); #define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 #define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 #define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 -#define SSL_R_SSLV3_ALERT_PEER_ERROR_CERTIFICATE 213 -#define SSL_R_SSLV3_ALERT_PEER_ERROR_NO_CERTIFICATE 214 -#define SSL_R_SSLV3_ALERT_PEER_ERROR_NO_CIPHER 215 -#define SSL_R_SSLV3_ALERT_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 216 +#define SSL_R_SSLV3_ALERT_PEER_ERROR_CERTIFICATE 219 +#define SSL_R_SSLV3_ALERT_PEER_ERROR_NO_CERTIFICATE 220 +#define SSL_R_SSLV3_ALERT_PEER_ERROR_NO_CIPHER 221 +#define SSL_R_SSLV3_ALERT_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 222 #define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 -#define SSL_R_SSLV3_ALERT_UNKNOWN_REMOTE_ERROR_TYPE 217 +#define SSL_R_SSLV3_ALERT_UNKNOWN_REMOTE_ERROR_TYPE 223 #define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 -#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 218 -#define SSL_R_SSL_HANDSHAKE_FAILURE 219 -#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 220 -#define SSL_R_SSL_SESSION_ID_IS_DIFFERENT 221 -#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 222 -#define SSL_R_UNABLE_TO_DECODE_DH_CERTS 223 -#define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY 224 -#define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS 225 -#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 226 -#define SSL_R_UNABLE_TO_FIND_SSL_METHOD 227 -#define SSL_R_UNEXPECTED_MESSAGE 228 -#define SSL_R_UNEXPECTED_RECORD 229 -#define SSL_R_UNKNOWN_ALERT_TYPE 230 -#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 231 -#define SSL_R_UNKNOWN_CIPHER_RETURNED 232 -#define SSL_R_UNKNOWN_CIPHER_TYPE 233 -#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 234 -#define SSL_R_UNKNOWN_PKEY_TYPE 235 -#define SSL_R_UNKNOWN_PROTOCOL 236 -#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 237 -#define SSL_R_UNKNOWN_SSL_VERSION 238 -#define SSL_R_UNKNOWN_STATE 239 -#define SSL_R_UNSUPPORTED_CIPHER 240 -#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 241 -#define SSL_R_UNSUPPORTED_SSL_VERSION 242 -#define SSL_R_WRITE_BIO_NOT_SET 243 -#define SSL_R_WRONG_CIPHER_RETURNED 244 -#define SSL_R_WRONG_MESSAGE_TYPE 245 -#define SSL_R_WRONG_NUMBER_OF_KEY_BITS 246 -#define SSL_R_WRONG_SIGNATURE_LENGTH 247 -#define SSL_R_WRONG_SIGNATURE_SIZE 248 -#define SSL_R_WRONG_SSL_VERSION 249 -#define SSL_R_WRONG_VERSION_NUMBER 250 -#define SSL_R_X509_LIB 251 +#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 224 +#define SSL_R_SSL_HANDSHAKE_FAILURE 225 +#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 226 +#define SSL_R_SSL_SESSION_ID_IS_DIFFERENT 227 +#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 228 +#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 229 +#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 230 +#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 231 +#define SSL_R_UNABLE_TO_DECODE_DH_CERTS 232 +#define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY 233 +#define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS 234 +#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 235 +#define SSL_R_UNABLE_TO_FIND_SSL_METHOD 236 +#define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES 237 +#define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 238 +#define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 239 +#define SSL_R_UNEXPECTED_MESSAGE 240 +#define SSL_R_UNEXPECTED_RECORD 241 +#define SSL_R_UNKNOWN_ALERT_TYPE 242 +#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 243 +#define SSL_R_UNKNOWN_CIPHER_RETURNED 244 +#define SSL_R_UNKNOWN_CIPHER_TYPE 245 +#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 246 +#define SSL_R_UNKNOWN_PKEY_TYPE 247 +#define SSL_R_UNKNOWN_PROTOCOL 248 +#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 249 +#define SSL_R_UNKNOWN_SSL_VERSION 250 +#define SSL_R_UNKNOWN_STATE 251 +#define SSL_R_UNSUPPORTED_CIPHER 252 +#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 253 +#define SSL_R_UNSUPPORTED_PROTOCOL 254 +#define SSL_R_UNSUPPORTED_SSL_VERSION 255 +#define SSL_R_WRITE_BIO_NOT_SET 256 +#define SSL_R_WRONG_CIPHER_RETURNED 257 +#define SSL_R_WRONG_MESSAGE_TYPE 258 +#define SSL_R_WRONG_NUMBER_OF_KEY_BITS 259 +#define SSL_R_WRONG_SIGNATURE_LENGTH 260 +#define SSL_R_WRONG_SIGNATURE_SIZE 261 +#define SSL_R_WRONG_SSL_VERSION 262 +#define SSL_R_WRONG_VERSION_NUMBER 263 +#define SSL_R_X509_LIB 264 #ifdef __cplusplus } diff --git a/ssl/ssl2.h b/ssl/ssl2.h index db353f5841..3dc94e520b 100644 --- a/ssl/ssl2.h +++ b/ssl/ssl2.h @@ -1,5 +1,5 @@ /* ssl/ssl2.h */ -/* 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 @@ -64,6 +64,9 @@ extern "C" { #endif /* Protocol Version Codes */ +#define SSL2_VERSION 0x0002 +#define SSL2_VERSION_MAJOR 0x00 +#define SSL2_VERSION_MINOR 0x02 #define SSL2_CLIENT_VERSION 0x0002 #define SSL2_SERVER_VERSION 0x0002 @@ -150,7 +153,6 @@ extern "C" { typedef struct ssl2_ctx_st { - int first_packet; /* enable first packet checking in server */ int three_byte_header; int clear_text; /* clear text */ int escape; /* not used in SSLv2 */ diff --git a/ssl/ssl23.h b/ssl/ssl23.h index 6e6f26bbb3..d3228983c7 100644 --- a/ssl/ssl23.h +++ b/ssl/ssl23.h @@ -1,5 +1,5 @@ /* ssl/ssl23.h */ -/* 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/ssl3.h b/ssl/ssl3.h index 9675ec2d7d..95772eef60 100644 --- a/ssl/ssl3.h +++ b/ssl/ssl3.h @@ -1,5 +1,5 @@ /* ssl/ssl3.h */ -/* 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 @@ -94,7 +94,7 @@ extern "C" { #define SSL3_CK_ADH_RC4_128_MD5 0x03000018 #define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 #define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A -#define SSL3_CK_ADH_DES_196_CBC_SHA 0x0300001B +#define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B #define SSL3_CK_FZA_DMS_NULL_SHA 0x0300001C #define SSL3_CK_FZA_DMS_FZA_SHA 0x0300001D @@ -106,7 +106,7 @@ extern "C" { #define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" #define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" #define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" -#define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-MD5" +#define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" #define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" #define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" #define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" @@ -121,7 +121,7 @@ extern "C" { #define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" #define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" #define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" -#define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC" +#define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" #define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" #define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" @@ -129,7 +129,7 @@ extern "C" { #define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" #define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" #define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" -#define SSL3_TXT_ADH_DES_196_CBC_SHA "ADH-DES-CBC3-SHA" +#define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" #define SSL3_TXT_FZA_DMS_NULL_SHA "FZA-NULL-SHA" #define SSL3_TXT_FZA_DMS_FZA_SHA "FZA-FZA-CBC-SHA" @@ -172,8 +172,8 @@ extern "C" { #define SSL3_RS_PART_READ 4 #define SSL3_RS_PART_WRITE 5 -#define SSL3_MD_CLIENT_FINISHED_CONST 0x43,0x4C,0x4E,0x54 -#define SSL3_MD_SERVER_FINISHED_CONST 0x53,0x52,0x56,0x52 +#define SSL3_MD_CLIENT_FINISHED_CONST {0x43,0x4C,0x4E,0x54} +#define SSL3_MD_SERVER_FINISHED_CONST {0x53,0x52,0x56,0x52} #define SSL3_VERSION 0x0300 #define SSL3_VERSION_MAJOR 0x03 @@ -236,6 +236,34 @@ typedef struct ssl3_compression_st { #define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 #define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 #define SSL3_FLAGS_POP_BUFFER 0x0004 +#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 + +#if 0 +#define AD_CLOSE_NOTIFY 0 +#define AD_UNEXPECTED_MESSAGE 1 +#define AD_BAD_RECORD_MAC 2 +#define AD_DECRYPTION_FAILED 3 +#define AD_RECORD_OVERFLOW 4 +#define AD_DECOMPRESSION_FAILURE 5 /* fatal */ +#define AD_HANDSHAKE_FAILURE 6 /* fatal */ +#define AD_NO_CERTIFICATE 7 /* Not under TLS */ +#define AD_BAD_CERTIFICATE 8 +#define AD_UNSUPPORTED_CERTIFICATE 9 +#define AD_CERTIFICATE_REVOKED 10 +#define AD_CERTIFICATE_EXPIRED 11 +#define AD_CERTIFICATE_UNKNOWN 12 +#define AD_ILLEGAL_PARAMETER 13 /* fatal */ +#define AD_UNKNOWN_CA 14 /* fatal */ +#define AD_ACCESS_DENIED 15 /* fatal */ +#define AD_DECODE_ERROR 16 /* fatal */ +#define AD_DECRYPT_ERROR 17 +#define AD_EXPORT_RESTRICION 18 /* fatal */ +#define AD_PROTOCOL_VERSION 19 /* fatal */ +#define AD_INSUFFICIENT_SECURITY 20 /* fatal */ +#define AD_INTERNAL_ERROR 21 /* fatal */ +#define AD_USER_CANCLED 22 +#define AD_NO_RENEGOTIATION 23 +#endif typedef struct ssl3_ctx_st { @@ -279,9 +307,17 @@ typedef struct ssl3_ctx_st int alert_dispatch; char send_alert[2]; + /* This flag is set when we should renegotiate ASAP, basically when + * there is no more data in the read or write buffers */ + int renegotiate; + int total_renegotiations; + int num_renegotiations; + + int in_read_app_data; + struct { - unsigned char finish_md1[EVP_MAX_MD_SIZE]; - unsigned char finish_md2[EVP_MAX_MD_SIZE]; + /* Actually only needs to be 16+20 for SSLv3 and 12 for TLS */ + unsigned char finish_md[EVP_MAX_MD_SIZE*2]; unsigned long message_size; int message_type; @@ -309,6 +345,7 @@ typedef struct ssl3_ctx_st EVP_CIPHER *new_sym_enc; EVP_MD *new_hash; SSL_COMPRESSION *new_compression; + int cert_request; } tmp; } SSL3_CTX; @@ -353,6 +390,7 @@ typedef struct ssl3_ctx_st /* extra state */ #define SSL3_ST_SW_FLUSH (0x100|SSL_ST_ACCEPT) /* read from client */ +/* Do not change the number values, they do matter */ #define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT) #define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT) #define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT) diff --git a/ssl/ssl_algs.c b/ssl/ssl_algs.c index 36b03335bb..65f3a59386 100644 --- a/ssl/ssl_algs.c +++ b/ssl/ssl_algs.c @@ -1,5 +1,5 @@ /* ssl/ssl_algs.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 @@ -82,9 +82,12 @@ void SSLeay_add_ssl_algorithms() #endif #ifndef NO_MD5 EVP_add_digest(EVP_md5()); + EVP_add_alias(SN_md5,"ssl2-md5"); + EVP_add_alias(SN_md5,"ssl3-md5"); #endif #ifndef NO_SHA1 EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ + EVP_add_alias(SN_sha1,"ssl3-sha1"); #endif #if !defined(NO_SHA1) && !defined(NO_DSA) EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c index 873497a877..116a83de64 100644 --- a/ssl/ssl_asn1.c +++ b/ssl/ssl_asn1.c @@ -1,5 +1,5 @@ /* ssl/ssl_asn1.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 @@ -116,7 +116,7 @@ unsigned char **pp; l=in->cipher_id; else l=in->cipher->id; - if (in->ssl_version == 2) + if (in->ssl_version == SSL2_VERSION) { a.cipher.length=3; buf[0]=((unsigned char)(l>>16L))&0xff; @@ -221,7 +221,7 @@ long length; os.data=NULL; os.length=0; M_ASN1_D2I_get(osp,d2i_ASN1_OCTET_STRING); - if (ssl_version == 2) + if (ssl_version == SSL2_VERSION) { if (os.length != 3) { @@ -233,7 +233,7 @@ long length; ((unsigned long)os.data[1]<< 8L)| (unsigned long)os.data[2]; } - else if (ssl_version == 3) + else if ((ssl_version>>8) == 3) { if (os.length != 2) { @@ -254,9 +254,9 @@ long length; ret->cipher_id=id; M_ASN1_D2I_get(osp,d2i_ASN1_OCTET_STRING); - if (ssl_version == 3) + if ((ssl_version>>8) == SSL3_VERSION) i=SSL3_MAX_SSL_SESSION_ID_LENGTH; - else /* if (ssl_version == 2) */ + else /* if (ssl_version == SSL2_VERSION) */ i=SSL2_MAX_SSL_SESSION_ID_LENGTH; if (os.length > i) diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 0c040d9cf3..c1cb86e1b7 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -1,5 +1,5 @@ /* ssl/ssl_cert.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 @@ -94,6 +94,9 @@ CERT *c; int i; i=CRYPTO_add(&c->references,-1,CRYPTO_LOCK_SSL_CERT); +#ifdef REF_PRINT + REF_PRINT("CERT",c); +#endif if (i > 0) return; #ifdef REF_CHECK if (i < 0) @@ -215,7 +218,8 @@ SSL *s; { if (s->type == SSL_ST_CONNECT) { /* we are in the client */ - if ((s->version == 3) && (s->s3 != NULL)) + if (((s->version>>8) == SSL3_VERSION_MAJOR) && + (s->s3 != NULL)) return(s->s3->tmp.ca_names); else return(NULL); @@ -270,6 +274,7 @@ X509_NAME **a,**b; return(X509_NAME_cmp(*a,*b)); } +#ifndef NO_STDIO STACK *SSL_load_client_CA_file(file) char *file; { @@ -280,11 +285,9 @@ char *file; ret=sk_new(NULL); sk=sk_new(name_cmp); -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + + in=BIO_new(BIO_s_file_internal()); + if ((ret == NULL) || (sk == NULL) || (in == NULL)) { SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE); @@ -322,5 +325,5 @@ err: if (x != NULL) X509_free(x); return(ret); } - +#endif diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 9fed3ad59a..820994408b 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -1,5 +1,5 @@ /* ssl/ssl_ciph.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,11 +74,10 @@ static EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={ }; #define SSL_MD_MD5_IDX 0 -#define SSL_MD_SHA0_IDX 1 -#define SSL_MD_SHA1_IDX 2 -#define SSL_MD_NUM_IDX 3 +#define SSL_MD_SHA1_IDX 1 +#define SSL_MD_NUM_IDX 2 static EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={ - NULL,NULL,NULL, + NULL,NULL, }; typedef struct cipher_sort_st @@ -90,16 +89,24 @@ typedef struct cipher_sort_st #define CIPHER_ADD 1 #define CIPHER_KILL 2 #define CIPHER_DEL 3 -#define CIPHER_ORDER 4 +#define CIPHER_ORD 4 typedef struct cipher_choice_st { int type; unsigned long algorithms; unsigned long mask; - STACK *order; + long top; } CIPHER_CHOICE; +typedef struct cipher_order_st + { + SSL_CIPHER *cipher; + int active; + int dead; + struct cipher_order_st *next,*prev; + } CIPHER_ORDER; + static SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_ALL, 0,SSL_ALL, 0,SSL_ALL}, /* must be first */ {0,SSL_TXT_kRSA,0,SSL_kRSA, 0,SSL_MKEY_MASK}, @@ -126,7 +133,6 @@ static SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_eFZA,0,SSL_eFZA, 0,SSL_ENC_MASK}, {0,SSL_TXT_MD5, 0,SSL_MD5, 0,SSL_MAC_MASK}, - {0,SSL_TXT_SHA0,0,SSL_SHA0, 0,SSL_MAC_MASK}, {0,SSL_TXT_SHA1,0,SSL_SHA1, 0,SSL_MAC_MASK}, {0,SSL_TXT_SHA, 0,SSL_SHA, 0,SSL_MAC_MASK}, @@ -169,8 +175,6 @@ static void load_ciphers() ssl_digest_methods[SSL_MD_MD5_IDX]= EVP_get_digestbyname(SN_md5); - ssl_digest_methods[SSL_MD_SHA0_IDX]= - EVP_get_digestbyname(SN_sha); ssl_digest_methods[SSL_MD_SHA1_IDX]= EVP_get_digestbyname(SN_sha1); } @@ -225,9 +229,6 @@ EVP_MD **md; case SSL_MD5: i=SSL_MD_MD5_IDX; break; - case SSL_SHA0: - i=SSL_MD_SHA0_IDX; - break; case SSL_SHA1: i=SSL_MD_SHA1_IDX; break; @@ -246,6 +247,25 @@ EVP_MD **md; return(0); } +#define ITEM_SEP(a) \ + (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) + +static void ll_append_tail(head,curr,tail) +CIPHER_ORDER **head,*curr,**tail; + { + if (curr == *tail) return; + if (curr == *head) + *head=curr->next; + if (curr->prev != NULL) + curr->prev->next=curr->next; + if (curr->next != NULL) /* should always be true */ + curr->next->prev=curr->prev; + (*tail)->next=curr; + curr->prev= *tail; + curr->next=NULL; + *tail=curr; + } + STACK *ssl_create_cipher_list(ssl_method,cipher_list,cipher_list_by_id,str) SSL_METHOD *ssl_method; STACK **cipher_list,**cipher_list_by_id; @@ -262,9 +282,11 @@ char *str; int i,j,k,num=0,ch,multi; unsigned long al; STACK *ca_list=NULL; - STACK *c_list=NULL; - int old_x,old_y,current_x,num_x; + int current_x,num_x; CIPHER_CHOICE *ops=NULL; + CIPHER_ORDER *list=NULL,*head=NULL,*tail=NULL,*curr,*tail2,*curr2; + int list_num; + int type; SSL_CIPHER c_tmp,*cp; if (str == NULL) return(NULL); @@ -278,6 +300,7 @@ char *str; goto err; } strcpy(tmp_str,SSL_DEFAULT_CIPHER_LIST); + strcat(tmp_str,":"); strcat(tmp_str,&(str[7])); str=tmp_str; } @@ -286,7 +309,6 @@ char *str; num=ssl_method->num_ciphers(); if ((ret=(STACK *)sk_new(NULL)) == NULL) goto err; - if ((c_list=(STACK *)sk_new(NULL)) == NULL) goto err; if ((ca_list=(STACK *)sk_new(cmp_by_name)) == NULL) goto err; mask =SSL_kFZA; @@ -312,20 +334,42 @@ char *str; mask|=(ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL)?SSL_eFZA:0; mask|=(ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL)?SSL_MD5 :0; - mask|=(ssl_digest_methods[SSL_MD_SHA0_IDX] == NULL)?SSL_SHA0:0; mask|=(ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL)?SSL_SHA1:0; + if ((list=(CIPHER_ORDER *)Malloc(sizeof(CIPHER_ORDER)*num)) == NULL) + goto err; + /* Get the initial list of ciphers */ + list_num=0; for (i=0; i<num; i++) { c=ssl_method->get_cipher((unsigned int)i); /* drop those that use any of that is not available */ if ((c != NULL) && c->valid && !(c->algorithms & mask)) { - if (!sk_push(c_list,(char *)c)) goto err; + list[list_num].cipher=c; + list[list_num].next=NULL; + list[list_num].prev=NULL; + list[list_num].active=0; + list_num++; if (!sk_push(ca_list,(char *)c)) goto err; } } + + for (i=1; i<list_num-1; i++) + { + list[i].prev= &(list[i-1]); + list[i].next= &(list[i+1]); + } + if (list_num > 0) + { + head= &(list[0]); + head->prev=NULL; + head->next= &(list[1]); + tail= &(list[list_num-1]); + tail->prev= &(list[list_num-2]); + tail->next=NULL; + } /* special case */ cipher_aliases[0].algorithms= ~mask; @@ -346,12 +390,11 @@ char *str; /* how many parameters are there? */ num=1; for (l=str; *l; l++) - if (*l == ':') num++; + if (ITEM_SEP(*l)) + num++; ops=(CIPHER_CHOICE *)Malloc(sizeof(CIPHER_CHOICE)*num); if (ops == NULL) goto err; memset(ops,0,sizeof(CIPHER_CHOICE)*num); - for (i=0; i<num; i++) - if ((ops[i].order=sk_new_null()) == NULL) goto err; /* we now parse the input string and create our operations */ l=str; @@ -361,16 +404,19 @@ char *str; for (;;) { ch= *l; + + if (ch == '\0') break; + if (ch == '-') { j=CIPHER_DEL; l++; } else if (ch == '+') - { j=CIPHER_ORDER; l++; } + { j=CIPHER_ORD; l++; } else if (ch == '!') { j=CIPHER_KILL; l++; } else { j=CIPHER_ADD; } - if (*l == ':') + if (ITEM_SEP(ch)) { l++; continue; @@ -395,20 +441,20 @@ char *str; if (i >= (CL_BUF-2)) break; } buf[i]='\0'; - if (ch != '\0') l++; /* check for multi-part specification */ - multi=(ch == '+')?1:0; + if (ch == '+') + { + multi=1; + l++; + } + else + multi=0; c_tmp.name=buf; j=sk_find(ca_list,(char *)&c_tmp); if (j < 0) - { - if (ch == '\0') - break; - else - continue; - } + goto end_loop; cp=(SSL_CIPHER *)sk_value(ca_list,j); ops[current_x].algorithms|=cp->algorithms; @@ -419,87 +465,86 @@ char *str; } current_x++; if (ch == '\0') break; +end_loop: + /* Make sure we scan until the next valid start point */ + while ((*l != '\0') && ITEM_SEP(*l)) + l++; } num_x=current_x; current_x=0; -#ifdef CIPHER_DEBUG - printf("<--->\n"); -#endif - - for (i=0; i<sk_num(c_list); i++) + /* We will now process the list of ciphers, once for each category, to + * decide what we should do with it. */ + for (j=0; j<num_x; j++) { - old_x= -1; - old_y= -1; - cp=(SSL_CIPHER *)sk_value(c_list,i); -#ifdef CIPHER_DEBUG - printf("[%s]\n",cp->name); -#endif - for (j=0; j<num_x; j++) + algorithms=ops[j].algorithms; + type=ops[j].type; + mask=ops[j].mask; + + curr=head; + curr2=head; + tail2=tail; + for (;;) { - algorithms=ops[j].algorithms; - ma=ops[j].mask & cp->algorithms; -#ifdef CIPHER_DEBUG - printf(" %s %08lX&%08lX==0 || %08lX != %08lX \n", - cp->name,ops[j].mask,cp->algorithms,ma,algorithms); -#endif + if ((curr == NULL) || (curr == tail2)) break; + curr=curr2; + curr2=curr->next; + + cp=curr->cipher; + ma=mask & cp->algorithms; if ((ma == 0) || ((ma & algorithms) != ma)) { + /* does not apply */ continue; } - k=ops[j].type; -#ifdef CIPHER_DEBUG - printf(">>%s\n",cp->name); -#endif /* add the cipher if it has not been added yet. */ - if (k == CIPHER_ADD) + if (type == CIPHER_ADD) { - if (old_x < 0) + if (!curr->active) { - old_x=j; - old_y=sk_num(ops[j].order); - sk_push(ops[j].order,(char *)cp); + ll_append_tail(&head,curr,&tail); + curr->active=1; } } /* Move the added cipher to this location */ - else if (k == CIPHER_ORDER) + else if (type == CIPHER_ORD) { - if (old_x >= 0) + if (curr->active) { - sk_value(ops[old_x].order,old_y)=NULL; - old_y=sk_num(ops[j].order); - sk_push(ops[j].order,(char *)cp); - old_x=j; + ll_append_tail(&head,curr,&tail); } } - /* Remove added cipher */ - else if ((k == CIPHER_DEL) || (k == CIPHER_KILL)) + else if (type == CIPHER_DEL) + curr->active=0; + if (type == CIPHER_KILL) { - if (old_x >= 0) - { - sk_value(ops[old_x].order,old_y)=NULL; - old_x= -1; - } - if (k == CIPHER_KILL) - break; + if (head == curr) + head=curr->next; + else + curr->prev->next=curr->next; + if (tail == curr) + tail=curr->prev; + curr->active=0; + if (curr->next != NULL) + curr->next->prev=curr->prev; + if (curr->prev != NULL) + curr->prev->next=curr->next; + curr->next=NULL; + curr->prev=NULL; } } } - for (i=0; i<num_x; i++) + for (curr=head; curr != NULL; curr=curr->next) { - for (j=0; j<sk_num(ops[i].order); j++) + if (curr->active) { - cp=(SSL_CIPHER *)sk_value(ops[i].order,j); - if (cp != NULL) - { - sk_push(ret,(char *)cp); + sk_push(ret,(char *)curr->cipher); #ifdef CIPHER_DEBUG - printf("<%s>\n",cp->name); + printf("<%s>\n",curr->cipher->name); #endif - } } } @@ -528,16 +573,10 @@ char *str; ret=NULL; err: if (tmp_str) Free(tmp_str); - if (ops != NULL) - { - for (i=0; i<num; i++) - if (ops[i].order != NULL) - sk_free(ops[i].order); - Free(ops); - } + if (ops != NULL) Free(ops); if (ret != NULL) sk_free(ret); - if (c_list != NULL) sk_free(c_list); if (ca_list != NULL) sk_free(ca_list); + if (list != NULL) Free(list); return(ok); } @@ -639,9 +678,6 @@ int len; case SSL_MD5: mac="MD5"; break; - case SSL_SHA0: - mac="SHA0"; - break; case SSL_SHA1: mac="SHA1"; break; @@ -667,9 +703,10 @@ SSL_CIPHER *c; { int i; + if (c == NULL) return("(NONE)"); i=(int)(c->id>>24L); if (i == 3) - return("SSLv3"); + return("TLSv1/SSLv3"); else if (i == 2) return("SSLv2"); else diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 18a1a22a82..bcbb98591f 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -60,6 +60,7 @@ #include "ssl.h" /* BEGIN ERROR CODES */ +#ifndef NO_ERR static ERR_STRING_DATA SSL_str_functs[]= { {ERR_PACK(0,SSL_F_CLIENT_CERTIFICATE,0), "CLIENT_CERTIFICATE"}, @@ -143,12 +144,14 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_PACK(0,SSL_F_SSL_GET_NEW_SESSION,0), "SSL_GET_NEW_SESSION"}, {ERR_PACK(0,SSL_F_SSL_GET_SERVER_SEND_CERT,0), "SSL_GET_SERVER_SEND_CERT"}, {ERR_PACK(0,SSL_F_SSL_GET_SIGN_PKEY,0), "SSL_GET_SIGN_PKEY"}, +{ERR_PACK(0,SSL_F_SSL_INIT_WBIO_BUFFER,0), "SSL_INIT_WBIO_BUFFER"}, {ERR_PACK(0,SSL_F_SSL_LOAD_CLIENT_CA_FILE,0), "SSL_load_client_CA_file"}, {ERR_PACK(0,SSL_F_SSL_NEW,0), "SSL_new"}, {ERR_PACK(0,SSL_F_SSL_RSA_PRIVATE_DECRYPT,0), "SSL_RSA_PRIVATE_DECRYPT"}, {ERR_PACK(0,SSL_F_SSL_RSA_PUBLIC_ENCRYPT,0), "SSL_RSA_PUBLIC_ENCRYPT"}, {ERR_PACK(0,SSL_F_SSL_SESSION_NEW,0), "SSL_SESSION_new"}, {ERR_PACK(0,SSL_F_SSL_SESSION_PRINT_FP,0), "SSL_SESSION_print_fp"}, +{ERR_PACK(0,SSL_F_SSL_SET_CERT,0), "SSL_SET_CERT"}, {ERR_PACK(0,SSL_F_SSL_SET_FD,0), "SSL_set_fd"}, {ERR_PACK(0,SSL_F_SSL_SET_PKEY,0), "SSL_SET_PKEY"}, {ERR_PACK(0,SSL_F_SSL_SET_RFD,0), "SSL_set_rfd"}, @@ -165,6 +168,9 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_PACK(0,SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1,0), "SSL_use_RSAPrivateKey_ASN1"}, {ERR_PACK(0,SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,0), "SSL_use_RSAPrivateKey_file"}, {ERR_PACK(0,SSL_F_SSL_WRITE,0), "SSL_write"}, +{ERR_PACK(0,SSL_F_TLS1_CHANGE_CIPHER_STATE,0), "TLS1_CHANGE_CIPHER_STATE"}, +{ERR_PACK(0,SSL_F_TLS1_ENC,0), "TLS1_ENC"}, +{ERR_PACK(0,SSL_F_TLS1_SETUP_KEY_BLOCK,0), "TLS1_SETUP_KEY_BLOCK"}, {ERR_PACK(0,SSL_F_WRITE_PENDING,0), "WRITE_PENDING"}, {0,NULL}, }; @@ -187,6 +193,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {SSL_R_BAD_MAC_DECODE ,"bad mac decode"}, {SSL_R_BAD_MESSAGE_TYPE ,"bad message type"}, {SSL_R_BAD_PACKET_LENGTH ,"bad packet length"}, +{SSL_R_BAD_PROTOCOL_VERSION_NUMBER ,"bad protocol version number"}, {SSL_R_BAD_RESPONSE_ARGUMENT ,"bad response argument"}, {SSL_R_BAD_RSA_DECRYPT ,"bad rsa decrypt"}, {SSL_R_BAD_RSA_ENCRYPT ,"bad rsa encrypt"}, @@ -213,8 +220,10 @@ static ERR_STRING_DATA SSL_str_reasons[]= {SSL_R_COMPRESSED_LENGTH_TOO_LONG ,"compressed length too long"}, {SSL_R_COMPRESSION_FAILURE ,"compression failure"}, {SSL_R_CONNECTION_ID_IS_DIFFERENT ,"connection id is different"}, +{SSL_R_CONNECTION_TYPE_NOT_SET ,"connection type not set"}, {SSL_R_DATA_BETWEEN_CCS_AND_FINISHED ,"data between ccs and finished"}, {SSL_R_DATA_LENGTH_TOO_LONG ,"data length too long"}, +{SSL_R_DECRYPTION_FAILED ,"decryption failed"}, {SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG ,"dh public value length is wrong"}, {SSL_R_DIGEST_CHECK_FAILED ,"digest check failed"}, {SSL_R_ENCRYPTED_LENGTH_TOO_LONG ,"encrypted length too long"}, @@ -222,6 +231,8 @@ static ERR_STRING_DATA SSL_str_reasons[]= {SSL_R_EXCESSIVE_MESSAGE_SIZE ,"excessive message size"}, {SSL_R_EXTRA_DATA_IN_MESSAGE ,"extra data in message"}, {SSL_R_GOT_A_FIN_BEFORE_A_CCS ,"got a fin before a ccs"}, +{SSL_R_HTTPS_PROXY_REQUEST ,"https proxy request"}, +{SSL_R_HTTP_REQUEST ,"http request"}, {SSL_R_INTERNAL_ERROR ,"internal error"}, {SSL_R_INVALID_CHALLENGE_LENGTH ,"invalid challenge length"}, {SSL_R_LENGTH_MISMATCH ,"length mismatch"}, @@ -241,7 +252,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {SSL_R_MISSING_TMP_RSA_PKEY ,"missing tmp rsa pkey"}, {SSL_R_MISSING_VERIFY_MESSAGE ,"missing verify message"}, {SSL_R_NON_SSLV2_INITIAL_PACKET ,"non sslv2 initial packet"}, -{SSL_R_NO_CERTIFICATES_PASSED ,"no certificates passed"}, +{SSL_R_NO_CERTIFICATES_RETURNED ,"no certificates returned"}, {SSL_R_NO_CERTIFICATE_ASSIGNED ,"no certificate assigned"}, {SSL_R_NO_CERTIFICATE_RETURNED ,"no certificate returned"}, {SSL_R_NO_CERTIFICATE_SET ,"no certificate set"}, @@ -255,6 +266,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {SSL_R_NO_COMPRESSION_SPECIFIED ,"no compression specified"}, {SSL_R_NO_PRIVATEKEY ,"no privatekey"}, {SSL_R_NO_PRIVATE_KEY_ASSIGNED ,"no private key assigned"}, +{SSL_R_NO_PROTOCOLS_AVAILABLE ,"no protocols available"}, {SSL_R_NO_PUBLICKEY ,"no publickey"}, {SSL_R_NO_SHARED_CIPHER ,"no shared cipher"}, {SSL_R_NULL_SSL_CTX ,"null ssl ctx"}, @@ -304,12 +316,18 @@ static ERR_STRING_DATA SSL_str_reasons[]= {SSL_R_SSL_HANDSHAKE_FAILURE ,"ssl handshake failure"}, {SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS ,"ssl library has no ciphers"}, {SSL_R_SSL_SESSION_ID_IS_DIFFERENT ,"ssl session id is different"}, +{SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER,"tls client cert req with anon cipher"}, +{SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST,"tls peer did not respond with certificate list"}, +{SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG,"tls rsa encrypted value length is wrong"}, {SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER ,"tried to use unsupported cipher"}, {SSL_R_UNABLE_TO_DECODE_DH_CERTS ,"unable to decode dh certs"}, {SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY ,"unable to extract public key"}, {SSL_R_UNABLE_TO_FIND_DH_PARAMETERS ,"unable to find dh parameters"}, {SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS,"unable to find public key parameters"}, {SSL_R_UNABLE_TO_FIND_SSL_METHOD ,"unable to find ssl method"}, +{SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES ,"unable to load ssl2 md5 routines"}, +{SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES ,"unable to load ssl3 md5 routines"}, +{SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES ,"unable to load ssl3 sha1 routines"}, {SSL_R_UNEXPECTED_MESSAGE ,"unexpected message"}, {SSL_R_UNEXPECTED_RECORD ,"unexpected record"}, {SSL_R_UNKNOWN_ALERT_TYPE ,"unknown alert type"}, @@ -324,6 +342,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {SSL_R_UNKNOWN_STATE ,"unknown state"}, {SSL_R_UNSUPPORTED_CIPHER ,"unsupported cipher"}, {SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM ,"unsupported compression algorithm"}, +{SSL_R_UNSUPPORTED_PROTOCOL ,"unsupported protocol"}, {SSL_R_UNSUPPORTED_SSL_VERSION ,"unsupported ssl version"}, {SSL_R_WRITE_BIO_NOT_SET ,"write bio not set"}, {SSL_R_WRONG_CIPHER_RETURNED ,"wrong cipher returned"}, @@ -337,14 +356,19 @@ static ERR_STRING_DATA SSL_str_reasons[]= {0,NULL}, }; +#endif + void ERR_load_SSL_strings() { static int init=1; - if (init) - { + if (init); + {; init=0; +#ifndef NO_ERR ERR_load_strings(ERR_LIB_SSL,SSL_str_functs); ERR_load_strings(ERR_LIB_SSL,SSL_str_reasons); +#endif + } } diff --git a/ssl/ssl_err2.c b/ssl/ssl_err2.c index a159fbb7cd..0b91f7b8d2 100644 --- a/ssl/ssl_err2.c +++ b/ssl/ssl_err2.c @@ -1,5 +1,5 @@ /* ssl/ssl_err2.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/ssl_lib.c b/ssl/ssl_lib.c index be091b1e75..f562ec6b14 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1,5 +1,5 @@ /* ssl/ssl_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 @@ -61,13 +61,21 @@ #include "lhash.h" #include "ssl_locl.h" -#ifndef NOPROTO -static unsigned long conn_hash(SSL_SESSION *a); -#else -static unsigned long conn_hash(); -#endif +char *SSL_version_str="SSLeay 0.9.0b 29-Jun-1998"; + +static STACK *ssl_meth=NULL; +static STACK *ssl_ctx_meth=NULL; +static int ssl_meth_num=0; +static int ssl_ctx_meth_num=0; -char *SSL_version_str="SSLeay 0.8.1b 29-Jun-1998"; +SSL3_ENC_METHOD ssl3_undef_enc_method={ + ssl_undefined_function, + ssl_undefined_function, + ssl_undefined_function, + ssl_undefined_function, + ssl_undefined_function, + ssl_undefined_function, + }; void SSL_clear(s) SSL *s; @@ -178,7 +186,12 @@ SSL_CTX *ctx; } s->quiet_shutdown=ctx->quiet_shutdown; + s->references=1; + s->options=ctx->options; SSL_clear(s); + + CRYPTO_new_ex_data(ssl_meth,(char *)s,&s->ex_data); + return(s); err: SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE); @@ -188,6 +201,23 @@ err: void SSL_free(s) SSL *s; { + int i; + + i=CRYPTO_add(&s->references,-1,CRYPTO_LOCK_SSL); +#ifdef REF_PRINT + REF_PRINT("SSL",s); +#endif + if (i > 0) return; +#ifdef REF_CHECK + if (i < 0) + { + fprintf(stderr,"SSL_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + + CRYPTO_free_ex_data(ssl_meth,(char *)s,&s->ex_data); + if (s->bbio != NULL) { /* If the buffering BIO is in place, pop it off */ @@ -196,6 +226,7 @@ SSL *s; s->wbio=BIO_pop(s->wbio); } BIO_free(s->bbio); + s->bbio=NULL; } if (s->rbio != NULL) BIO_free_all(s->rbio); @@ -303,12 +334,18 @@ int fd; int ret=0; BIO *bio=NULL; - bio=BIO_new(BIO_s_socket()); + if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET) + || ((int)BIO_get_fd(s->rbio,NULL) != fd)) + { + bio=BIO_new(BIO_s_socket()); - if (bio == NULL) - { SSLerr(SSL_F_SSL_SET_WFD,ERR_R_BUF_LIB); goto err; } - BIO_set_fd(bio,fd,BIO_NOCLOSE); - SSL_set_bio(s,SSL_get_rbio(s),bio); + if (bio == NULL) + { SSLerr(SSL_F_SSL_SET_WFD,ERR_R_BUF_LIB); goto err; } + BIO_set_fd(bio,fd,BIO_NOCLOSE); + SSL_set_bio(s,SSL_get_rbio(s),bio); + } + else + SSL_set_bio(s,SSL_get_rbio(s),SSL_get_rbio(s)); ret=1; err: return(ret); @@ -321,15 +358,21 @@ int fd; int ret=0; BIO *bio=NULL; - bio=BIO_new(BIO_s_socket()); - - if (bio == NULL) + if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET) + || ((int)BIO_get_fd(s->wbio,NULL) != fd)) { - SSLerr(SSL_F_SSL_SET_RFD,ERR_R_BUF_LIB); - goto err; + bio=BIO_new(BIO_s_socket()); + + if (bio == NULL) + { + SSLerr(SSL_F_SSL_SET_RFD,ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio,fd,BIO_NOCLOSE); + SSL_set_bio(s,bio,SSL_get_wbio(s)); } - BIO_set_fd(bio,fd,BIO_NOCLOSE); - SSL_set_bio(s,bio,SSL_get_wbio(s)); + else + SSL_set_bio(s,SSL_get_wbio(s),SSL_get_wbio(s)); ret=1; err: return(ret); @@ -449,6 +492,7 @@ SSL *t,*f; if (tmp != NULL) ssl_cert_free(tmp); } +/* Fix this so it checks all the valid key/cert options */ int SSL_CTX_check_private_key(ctx) SSL_CTX *ctx; { @@ -467,6 +511,7 @@ SSL_CTX *ctx; return(X509_check_private_key(ctx->default_cert->key->x509, ctx->default_cert->key->privatekey)); } +/* Fix this function so that it takes an optional type parameter */ int SSL_check_private_key(ssl) SSL *ssl; { @@ -560,6 +605,7 @@ SSL *s; int SSL_renegotiate(s) SSL *s; { + s->new_session=1; return(s->method->ssl_renegotiate(s)); } @@ -614,7 +660,7 @@ SSL *s; { return(s->cipher_list); } - else if ((s != NULL) && (s->ctx != NULL) && + else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) { return(s->ctx->cipher_list); @@ -699,13 +745,14 @@ int len; p=buf; sk=s->session->ciphers; - len--; for (i=0; i<sk_num(sk); i++) { + /* Decrement for either the ':' or a '\0' */ + len--; c=(SSL_CIPHER *)sk_value(sk,i); for (cp=c->name; *cp; ) { - if (--len == 0) + if (len-- == 0) { *p='\0'; return(buf); @@ -787,27 +834,25 @@ err: return(NULL); } -static unsigned long conn_hash(a) +unsigned long SSL_SESSION_hash(a) SSL_SESSION *a; { unsigned long l; l= (a->session_id[0] )|(a->session_id[1]<< 8L)| - (a->session_id[1]<<16L)|(a->session_id[2]<<24L); + (a->session_id[2]<<16L)|(a->session_id[3]<<24L); return(l); } -static int session_cmp(a, b) +int SSL_SESSION_cmp(a, b) SSL_SESSION *a; SSL_SESSION *b; { - int i; - - i=a->session_id_length - b->session_id_length; - if (i == 0) - return(memcmp(a->session_id,b->session_id, - a->session_id_length)); - else return(1); + if (a->ssl_version != b->ssl_version) + return(1); + if (a->session_id_length != b->session_id_length) + return(1); + return(memcmp(a->session_id,b->session_id,a->session_id_length)); } SSL_CTX *SSL_CTX_new(meth) @@ -830,6 +875,9 @@ SSL_METHOD *meth; ret->cert_store=NULL; ret->session_cache_mode=SSL_SESS_CACHE_SERVER; + ret->session_cache_size=SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; + ret->session_cache_head=NULL; + ret->session_cache_tail=NULL; /* We take the system default */ ret->session_timeout=meth->get_timeout(); @@ -841,9 +889,12 @@ SSL_METHOD *meth; ret->sess_connect=0; ret->sess_connect_good=0; ret->sess_accept=0; + ret->sess_accept_renegotiate=0; + ret->sess_connect_renegotiate=0; ret->sess_accept_good=0; ret->sess_miss=0; ret->sess_timeout=0; + ret->sess_cache_full=0; ret->sess_hit=0; ret->sess_cb_hit=0; @@ -870,7 +921,7 @@ SSL_METHOD *meth; ret->default_passwd_callback=NULL; ret->client_cert_cb=NULL; - ret->sessions=lh_new(conn_hash,session_cmp); + ret->sessions=lh_new(SSL_SESSION_hash,SSL_SESSION_cmp); if (ret->sessions == NULL) goto err; ret->cert_store=X509_STORE_new(); if (ret->cert_store == NULL) goto err; @@ -884,9 +935,27 @@ SSL_METHOD *meth; goto err2; } + if ((ret->rsa_md5=EVP_get_digestbyname("ssl2-md5")) == NULL) + { + SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES); + goto err2; + } + if ((ret->md5=EVP_get_digestbyname("ssl3-md5")) == NULL) + { + SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES); + goto err2; + } + if ((ret->sha1=EVP_get_digestbyname("ssl3-sha1")) == NULL) + { + SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES); + goto err2; + } + if ((ret->client_CA=sk_new_null()) == NULL) goto err; + CRYPTO_new_ex_data(ssl_ctx_meth,(char *)ret,&ret->ex_data); + return(ret); err: SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE); @@ -903,6 +972,9 @@ SSL_CTX *a; if (a == NULL) return; i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_SSL_CTX); +#ifdef REF_PRINT + REF_PRINT("SSL_CTX",a); +#endif if (i > 0) return; #ifdef REF_CHECK if (i < 0) @@ -911,6 +983,7 @@ SSL_CTX *a; abort(); /* ok */ } #endif + CRYPTO_free_ex_data(ssl_ctx_meth,(char *)a,&a->ex_data); if (a->sessions != NULL) { @@ -1126,22 +1199,34 @@ void ssl_update_cache(s,mode) SSL *s; int mode; { + int i; + + /* If the session_id_length is 0, we are not supposed to cache it, + * and it would be rather hard to do anyway :-) */ + if (s->session->session_id_length == 0) return; + if ((s->ctx->session_cache_mode & mode) && (!s->hit) && SSL_CTX_add_session(s->ctx,s->session) && (s->ctx->new_session_cb != NULL)) { - CRYPTO_add(&s->session->references,1, - CRYPTO_LOCK_SSL_SESSION); + CRYPTO_add(&s->session->references,1,CRYPTO_LOCK_SSL_SESSION); if (!s->ctx->new_session_cb(s,s->session)) SSL_SESSION_free(s->session); } /* auto flush every 255 connections */ - if ((!(s->ctx->session_cache_mode & - SSL_SESS_CACHE_NO_AUTO_CLEAR)) && - ((s->ctx->sess_connect_good & 0xff) == 0)) - SSL_CTX_flush_sessions(s->ctx,time(NULL)); + i=s->ctx->session_cache_mode; + if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && + ((i & mode) == mode)) + { + if ( (((mode & SSL_SESS_CACHE_CLIENT) + ?s->ctx->sess_connect_good + :s->ctx->sess_accept_good) & 0xff) == 0xff) + { + SSL_CTX_flush_sessions(s->ctx,time(NULL)); + } + } } SSL_METHOD *SSL_get_ssl_method(s) @@ -1231,7 +1316,7 @@ int i; if (i == 0) { - if (s->version == 2) + if (s->version == SSL2_VERSION) { /* assume it is the socket being closed */ return(SSL_ERROR_ZERO_RETURN); @@ -1239,7 +1324,7 @@ int i; else { if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) && - (s->s3->warn_alert == SSL3_AD_CLOSE_NOTIFY)) + (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) return(SSL_ERROR_ZERO_RETURN); } } @@ -1249,15 +1334,19 @@ int i; int SSL_do_handshake(s) SSL *s; { + int ret=1; + if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_DO_HANDSHAKE,SSL_R_INTERNAL_ERROR); + SSLerr(SSL_F_SSL_DO_HANDSHAKE,SSL_R_CONNECTION_TYPE_NOT_SET); return(-1); } + if (s->s3->renegotiate) ssl3_renegotiate_check(s); if (SSL_in_init(s) || SSL_in_before(s)) - return(s->handshake_func(s)); - else - return(1); + { + ret=s->handshake_func(s); + } + return(ret); } /* For the next 2 functions, SSL_clear() sets shutdown and so @@ -1299,9 +1388,11 @@ int ver; char *SSL_get_version(s) SSL *s; { - if (s->version == 3) + if (s->version == TLS1_VERSION) + return("TLSv1"); + else if (s->version == SSL3_VERSION) return("SSLv3"); - else if (s->version == 2) + else if (s->version == SSL2_VERSION) return("SSLv2"); else return("unknown"); @@ -1327,9 +1418,11 @@ SSL *s; SSL_set_info_callback(ret,SSL_get_info_callback(s)); ret->debug=s->debug; + ret->options=s->options; /* copy app data, a little dangerous perhaps */ - SSL_set_app_data(ret,SSL_get_app_data(s)); + if (!CRYPTO_dup_ex_data(ssl_meth,&ret->ex_data,&s->ex_data)) + goto err; /* setup rbio, and wbio */ if (s->rbio != NULL) @@ -1341,7 +1434,7 @@ SSL *s; { if (s->wbio != s->rbio) { - if (!BIO_dup_state(s->wbio,(char *)&ret->rbio)) + if (!BIO_dup_state(s->wbio,(char *)&ret->wbio)) goto err; } else @@ -1405,6 +1498,7 @@ SSL *s; } } +/* Fix this function so that it takes an optional type parameter */ X509 *SSL_get_certificate(s) SSL *s; { @@ -1414,6 +1508,7 @@ SSL *s; return(NULL); } +/* Fix this function so that it takes an optional type parameter */ EVP_PKEY *SSL_get_privatekey(s) SSL *s; { @@ -1431,3 +1526,196 @@ SSL *s; return(NULL); } +int ssl_init_wbio_buffer(s,push) +SSL *s; +int push; + { + BIO *bbio; + + if (s->bbio == NULL) + { + bbio=BIO_new(BIO_f_buffer()); + if (bbio == NULL) return(0); + s->bbio=bbio; + } + else + { + bbio=s->bbio; + if (s->bbio == s->wbio) + s->wbio=BIO_pop(s->wbio); + } + BIO_reset(bbio); +/* if (!BIO_set_write_buffer_size(bbio,16*1024)) */ + if (!BIO_set_read_buffer_size(bbio,1)) + { + SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER,ERR_R_BUF_LIB); + return(0); + } + if (push) + { + if (s->wbio != bbio) + s->wbio=BIO_push(bbio,s->wbio); + } + else + { + if (s->wbio == bbio) + s->wbio=BIO_pop(bbio); + } + return(1); + } + +void SSL_CTX_set_quiet_shutdown(ctx,mode) +SSL_CTX *ctx; +int mode; + { + ctx->quiet_shutdown=mode; + } + +int SSL_CTX_get_quiet_shutdown(ctx) +SSL_CTX *ctx; + { + return(ctx->quiet_shutdown); + } + +void SSL_set_quiet_shutdown(s,mode) +SSL *s; +int mode; + { + s->quiet_shutdown=mode; + } + +int SSL_get_quiet_shutdown(s) +SSL *s; + { + return(s->quiet_shutdown); + } + +void SSL_set_shutdown(s,mode) +SSL *s; +int mode; + { + s->shutdown=mode; + } + +int SSL_get_shutdown(s) +SSL *s; + { + return(s->shutdown); + } + +int SSL_version(s) +SSL *s; + { + return(s->version); + } + +SSL_CTX *SSL_get_SSL_CTX(ssl) +SSL *ssl; + { + return(ssl->ctx); + } + +int SSL_CTX_set_default_verify_paths(ctx) +SSL_CTX *ctx; + { + return(X509_STORE_set_default_paths(ctx->cert_store)); + } + +int SSL_CTX_load_verify_locations(ctx,CAfile,CApath) +SSL_CTX *ctx; +char *CAfile; +char *CApath; + { + return(X509_STORE_load_locations(ctx->cert_store,CAfile,CApath)); + } + +void SSL_set_info_callback(ssl,cb) +SSL *ssl; +void (*cb)(); + { + ssl->info_callback=cb; + } + +void (*SSL_get_info_callback(ssl))() +SSL *ssl; + { + return(ssl->info_callback); + } + +int SSL_state(ssl) +SSL *ssl; + { + return(ssl->state); + } + +void SSL_set_verify_result(ssl,arg) +SSL *ssl; +long arg; + { + ssl->verify_result=arg; + } + +long SSL_get_verify_result(ssl) +SSL *ssl; + { + return(ssl->verify_result); + } + +int SSL_get_ex_new_index(argl,argp,new_func,dup_func,free_func) +long argl; +char *argp; +int (*new_func)(); +int (*dup_func)(); +void (*free_func)(); + { + ssl_meth_num++; + return(CRYPTO_get_ex_new_index(ssl_meth_num-1, + &ssl_meth,argl,argp,new_func,dup_func,free_func)); + } + +int SSL_set_ex_data(s,idx,arg) +SSL *s; +int idx; +char *arg; + { + return(CRYPTO_set_ex_data(&s->ex_data,idx,arg)); + } + +char *SSL_get_ex_data(s,idx) +SSL *s; +int idx; + { + return(CRYPTO_get_ex_data(&s->ex_data,idx)); + } + +int SSL_CTX_get_ex_new_index(argl,argp,new_func,dup_func,free_func) +long argl; +char *argp; +int (*new_func)(); +int (*dup_func)(); +void (*free_func)(); + { + ssl_ctx_meth_num++; + return(CRYPTO_get_ex_new_index(ssl_ctx_meth_num-1, + &ssl_ctx_meth,argl,argp,new_func,dup_func,free_func)); + } + +int SSL_CTX_set_ex_data(s,idx,arg) +SSL_CTX *s; +int idx; +char *arg; + { + return(CRYPTO_set_ex_data(&s->ex_data,idx,arg)); + } + +char *SSL_CTX_get_ex_data(s,idx) +SSL_CTX *s; +int idx; + { + return(CRYPTO_get_ex_data(&s->ex_data,idx)); + } + +#if defined(_WINDLL) && defined(WIN16) +#include "../crypto/bio/bss_file.c" +#endif + diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index ef3a70e93e..b29517081b 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1,5 +1,5 @@ /* ssl/ssl_locl.h */ -/* 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,11 +63,7 @@ #include <string.h> #include <errno.h> -#ifdef FLAT_INC #include "e_os.h" -#else -#include "../e_os.h" -#endif #include "buffer.h" #include "bio.h" @@ -188,11 +184,10 @@ #define SSL_eFZA 0x00008000L #define SSL_eNULL 0x00010000L -#define SSL_MAC_MASK 0x000e0000L +#define SSL_MAC_MASK 0x00060000L #define SSL_MD5 0x00020000L -#define SSL_SHA0 0x00040000L -#define SSL_SHA1 0x00080000L -#define SSL_SHA (SSL_SHA0|SSL_SHA1) +#define SSL_SHA1 0x00040000L +#define SSL_SHA (SSL_SHA1) #define SSL_EXP_MASK 0x00300000L #define SSL_EXP 0x00100000L @@ -298,9 +293,27 @@ typedef struct cert_st #define ssl_get_cipher_by_char(ssl,ptr) \ ((ssl)->method->get_cipher_by_char(ptr)) -extern unsigned char ssl3_client_finished_const[4]; -extern unsigned char ssl3_server_finished_const[4]; - +/* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff + * It is a bit of a mess of functions, but hell, think of it as + * an opaque strucute :-) */ +typedef struct ssl3_enc_method + { + int (*enc)(); + int (*mac)(); + int (*setup_key_block)(); + int (*generate_master_secret)(); + int (*change_cipher_state)(); + int (*final_finish_mac)(); + int finish_mac_length; + int (*cert_verify_mac)(); + unsigned char client_finished[20]; + int client_finished_len; + unsigned char server_finished[20]; + int server_finished_len; + int (*alert_value)(); + } SSL3_ENC_METHOD; + +extern SSL3_ENC_METHOD ssl3_undef_enc_method; extern SSL_CIPHER ssl2_ciphers[]; extern SSL_CIPHER ssl3_ciphers[]; @@ -317,7 +330,7 @@ CERT *ssl_cert_new(void); void ssl_cert_free(CERT *c); int ssl_set_cert_type(CERT *c, int type); int ssl_get_new_session(SSL *s, int session); -int ssl_get_prev_session(SSL *s, int len, unsigned char *session); +int ssl_get_prev_session(SSL *s, unsigned char *session,int len); int ssl_cipher_id_cmp(SSL_CIPHER *a,SSL_CIPHER *b); int ssl_cipher_ptr_id_cmp(SSL_CIPHER **ap,SSL_CIPHER **bp); STACK *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,STACK **skp); @@ -333,7 +346,7 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *,SSL_CIPHER *); int ssl_cert_type(X509 *x,EVP_PKEY *pkey); void ssl_set_cert_masks(CERT *c); STACK *ssl_get_ciphers_by_id(SSL *s); -int ssl_verify_alarm_type(int type); +int ssl_verify_alarm_type(long type); int ssl2_enc_init(SSL *s, int client); void ssl2_generate_key_material(SSL *s); @@ -354,7 +367,7 @@ int ssl2_accept(SSL *s); int ssl2_connect(SSL *s); int ssl2_read(SSL *s, char *buf, int len); int ssl2_peek(SSL *s, char *buf, int len); -int ssl2_write(SSL *s, const char *buf, int len); +int ssl2_write(SSL *s, char *buf, int len); int ssl2_shutdown(SSL *s); void ssl2_clear(SSL *s); long ssl2_ctrl(SSL *s,int cmd, long larg, char *parg); @@ -365,7 +378,7 @@ SSL_CIPHER *ssl3_get_cipher_by_char(unsigned char *p); int ssl3_put_cipher_by_char(SSL_CIPHER *c,unsigned char *p); void ssl3_init_finished_mac(SSL *s); int ssl3_send_server_certificate(SSL *s); -int ssl3_get_finished(SSL *s,int state_a,int state_b,unsigned char *sender); +int ssl3_get_finished(SSL *s,int state_a,int state_b); int ssl3_setup_key_block(SSL *s); int ssl3_send_change_cipher_spec(SSL *s,int state_a,int state_b); int ssl3_change_cipher_state(SSL *s,int which); @@ -376,17 +389,18 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, int len); int ssl3_get_req_cert_type(SSL *s,unsigned char *p); long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); -int ssl3_send_finished(SSL *s, int a, int b, unsigned char *sender); +int ssl3_send_finished(SSL *s, int a, int b, unsigned char *sender,int slen); int ssl3_num_ciphers(void); SSL_CIPHER *ssl3_get_cipher(unsigned int u); int ssl3_renegotiate(SSL *ssl); +int ssl3_renegotiate_check(SSL *ssl); int ssl3_dispatch_alert(SSL *s); int ssl3_read_bytes(SSL *s, int type, char *buf, int len); -void ssl3_generate_key_block(SSL *s, unsigned char *km, int num); int ssl3_part_read(SSL *s, int i); int ssl3_write_bytes(SSL *s, int type, char *buf, int len); -int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *in_ctx, - unsigned char *sender, unsigned char *p); +int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1,EVP_MD_CTX *ctx2, + unsigned char *sender, int slen,unsigned char *p); +int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *in, unsigned char *p); void ssl3_finish_mac(SSL *s, unsigned char *buf, int len); int ssl3_enc(SSL *s, int send_data); int ssl3_mac(SSL *ssl, unsigned char *md, int send_data); @@ -399,7 +413,7 @@ int ssl3_accept(SSL *s); int ssl3_connect(SSL *s); int ssl3_read(SSL *s, char *buf, int len); int ssl3_peek(SSL *s,char *buf, int len); -int ssl3_write(SSL *s, const char *buf, int len); +int ssl3_write(SSL *s, char *buf, int len); int ssl3_shutdown(SSL *s); void ssl3_clear(SSL *s); long ssl3_ctrl(SSL *s,int cmd, long larg, char *parg); @@ -411,6 +425,28 @@ int ssl23_connect(SSL *s); int ssl23_read_bytes(SSL *s, int n); int ssl23_write_bytes(SSL *s); +int tls1_new(SSL *s); +void tls1_free(SSL *s); +void tls1_clear(SSL *s); +long tls1_ctrl(SSL *s,int cmd, long larg, char *parg); +SSL_METHOD *tlsv1_base_method(void ); + + +int ssl_init_wbio_buffer(SSL *s, int push); + +int tls1_change_cipher_state(SSL *s, int which); +int tls1_setup_key_block(SSL *s); +int tls1_enc(SSL *s, int snd); +int tls1_final_finish_mac(SSL *s, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx, + unsigned char *str, int slen, unsigned char *p); +int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in, unsigned char *p); +int tls1_mac(SSL *ssl, unsigned char *md, int snd); +int tls1_generate_master_secret(SSL *s, unsigned char *out, + unsigned char *p, int len); +int tls1_alert_code(int code); +int ssl3_alert_code(int code); + + #else SSL_METHOD *ssl_bad_method(); @@ -485,9 +521,9 @@ int ssl3_send_finished(); int ssl3_num_ciphers(); SSL_CIPHER *ssl3_get_cipher(); int ssl3_renegotiate(); +int ssl3_renegotiate_check(); int ssl3_dispatch_alert(); int ssl3_read_bytes(); -void ssl3_generate_key_block(); int ssl3_part_read(); int ssl3_write_bytes(); int ssl3_final_finish_mac(); @@ -515,6 +551,8 @@ int ssl23_connect(); int ssl23_read_bytes(); int ssl23_write_bytes(); +int ssl_init_wbio_buffer(); + #endif #endif diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 3a7b8d3c36..140475e5fb 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -1,5 +1,5 @@ /* ssl/ssl_rsa.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 @@ -99,6 +99,7 @@ X509 *x; return(ssl_set_cert(c,x)); } +#ifndef NO_STDIO int SSL_use_certificate_file(ssl, file, type) SSL *ssl; char *file; @@ -109,11 +110,7 @@ int type; int ret=0; X509 *x=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB); @@ -122,7 +119,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB); goto end; } @@ -154,6 +150,7 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif int SSL_use_certificate_ASN1(ssl, len, d) SSL *ssl; @@ -232,7 +229,16 @@ EVP_PKEY *pkey; if (c->pkeys[i].x509 != NULL) { - if (!X509_check_private_key(c->pkeys[i].x509,pkey)) +#ifndef NO_RSA + /* Don't check the public/private key, this is mostly + * for smart cards. */ + if ((pkey->type == EVP_PKEY_RSA) && + (RSA_flags(pkey->pkey.rsa) & + RSA_METHOD_FLAG_NO_CHECK)) + ok=1; + else +#endif + if (!X509_check_private_key(c->pkeys[i].x509,pkey)) { if ((i == SSL_PKEY_DH_RSA) || (i == SSL_PKEY_DH_DSA)) { @@ -277,6 +283,7 @@ EVP_PKEY *pkey; } #ifndef NO_RSA +#ifndef NO_STDIO int SSL_use_RSAPrivateKey_file(ssl, file, type) SSL *ssl; char *file; @@ -286,11 +293,7 @@ int type; BIO *in; RSA *rsa=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB); @@ -299,7 +302,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB); goto end; } @@ -330,6 +332,7 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif int SSL_use_RSAPrivateKey_ASN1(ssl,d,len) SSL *ssl; @@ -383,6 +386,7 @@ EVP_PKEY *pkey; return(ret); } +#ifndef NO_STDIO int SSL_use_PrivateKey_file(ssl, file, type) SSL *ssl; char *file; @@ -392,11 +396,7 @@ int type; BIO *in; EVP_PKEY *pkey=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB); @@ -405,7 +405,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB); goto end; } @@ -431,6 +430,7 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif int SSL_use_PrivateKey_ASN1(type,ssl,d,len) int type; @@ -491,14 +491,14 @@ X509 *x; pkey=X509_get_pubkey(x); if (pkey == NULL) { - SSLerr(SSL_F_SSL_SET_PKEY,SSL_R_X509_LIB); + SSLerr(SSL_F_SSL_SET_CERT,SSL_R_X509_LIB); return(0); } i=ssl_cert_type(x,pkey); if (i < 0) { - SSLerr(SSL_F_SSL_SET_PKEY,SSL_R_UNKNOWN_CERTIFICATE_TYPE); + SSLerr(SSL_F_SSL_SET_CERT,SSL_R_UNKNOWN_CERTIFICATE_TYPE); return(0); } @@ -547,6 +547,7 @@ X509 *x; return(1); } +#ifndef NO_STDIO int SSL_CTX_use_certificate_file(ctx, file, type) SSL_CTX *ctx; char *file; @@ -557,11 +558,7 @@ int type; int ret=0; X509 *x=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB); @@ -570,7 +567,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB); goto end; } @@ -602,6 +598,7 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif int SSL_CTX_use_certificate_ASN1(ctx, len, d) SSL_CTX *ctx; @@ -663,6 +660,7 @@ RSA *rsa; return(ret); } +#ifndef NO_STDIO int SSL_CTX_use_RSAPrivateKey_file(ctx, file, type) SSL_CTX *ctx; char *file; @@ -672,11 +670,7 @@ int type; BIO *in; RSA *rsa=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB); @@ -685,7 +679,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB); goto end; } @@ -716,6 +709,7 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif int SSL_CTX_use_RSAPrivateKey_ASN1(ctx,d,len) SSL_CTX *ctx; @@ -766,6 +760,7 @@ EVP_PKEY *pkey; return(ssl_set_pkey(c,pkey)); } +#ifndef NO_STDIO int SSL_CTX_use_PrivateKey_file(ctx, file, type) SSL_CTX *ctx; char *file; @@ -775,11 +770,7 @@ int type; BIO *in; EVP_PKEY *pkey=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB); @@ -788,7 +779,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB); goto end; } @@ -814,6 +804,7 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif int SSL_CTX_use_PrivateKey_ASN1(type,ctx,d,len) int type; diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index af65c65dac..8212600e40 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -1,5 +1,5 @@ /* ssl/ssl_sess.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 @@ -61,6 +61,51 @@ #include "rand.h" #include "ssl_locl.h" +#ifndef NOPROTO +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); +static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s); +#else +static void SSL_SESSION_list_remove(); +static void SSL_SESSION_list_add(); +#endif + +static ssl_session_num=0; +static STACK *ssl_session_meth=NULL; + +SSL_SESSION *SSL_get_session(ssl) +SSL *ssl; + { + return(ssl->session); + } + +int SSL_SESSION_get_ex_new_index(argl,argp,new_func,dup_func,free_func) +long argl; +char *argp; +int (*new_func)(); +int (*dup_func)(); +void (*free_func)(); + { + ssl_session_num++; + return(CRYPTO_get_ex_new_index(ssl_session_num-1, + &ssl_session_meth, + argl,argp,new_func,dup_func,free_func)); + } + +int SSL_SESSION_set_ex_data(s,idx,arg) +SSL_SESSION *s; +int idx; +char *arg; + { + return(CRYPTO_set_ex_data(&s->ex_data,idx,arg)); + } + +char *SSL_SESSION_get_ex_data(s,idx) +SSL_SESSION *s; +int idx; + { + return(CRYPTO_get_ex_data(&s->ex_data,idx)); + } + SSL_SESSION *SSL_SESSION_new() { SSL_SESSION *ss; @@ -76,6 +121,9 @@ SSL_SESSION *SSL_SESSION_new() ss->references=1; ss->timeout=60*5+4; /* 5 minute timeout by default */ ss->time=time(NULL); + ss->prev=NULL; + ss->next=NULL; + CRYPTO_new_ex_data(ssl_session_meth,(char *)ss,&ss->ex_data); return(ss); } @@ -101,12 +149,17 @@ int session; { if (s->version == SSL2_CLIENT_VERSION) { - ss->ssl_version=2; + ss->ssl_version=SSL2_VERSION; ss->session_id_length=SSL2_SSL_SESSION_ID_LENGTH; } - else if (s->version == SSL3_VERSION_MAJOR) + else if (s->version == SSL3_VERSION) { - ss->ssl_version=3; + ss->ssl_version=SSL3_VERSION; + ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH; + } + else if (s->version == TLS1_VERSION) + { + ss->ssl_version=TLS1_VERSION; ss->session_id_length=SSL3_SSL_SESSION_ID_LENGTH; } else @@ -140,23 +193,26 @@ int session; return(1); } -int ssl_get_prev_session(s, len, session) +int ssl_get_prev_session(s,session_id,len) SSL *s; +unsigned char *session_id; int len; -unsigned char *session; { - SSL_SESSION *ret,data; + SSL_SESSION *ret=NULL,data; /* conn_init();*/ data.ssl_version=s->version; data.session_id_length=len; if (len > SSL_MAX_SSL_SESSION_ID_LENGTH) return(0); - memcpy(data.session_id,session,len);; + memcpy(data.session_id,session_id,len);; - CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,(char *)&data); - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) + { + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,(char *)&data); + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + } if (ret == NULL) { @@ -165,7 +221,7 @@ unsigned char *session; s->ctx->sess_miss++; ret=NULL; if ((s->ctx->get_session_cb != NULL) && - ((ret=s->ctx->get_session_cb(s,session,len,©)) + ((ret=s->ctx->get_session_cb(s,session_id,len,©)) != NULL)) { s->ctx->sess_cb_hit++; @@ -188,7 +244,7 @@ unsigned char *session; p=buf; l=ret->cipher_id; l2n(l,p); - if (ret->ssl_version == 3) + if ((ret->ssl_version>>8) == SSL3_VERSION_MAJOR) ret->cipher=ssl_get_cipher_by_char(s,&(buf[2])); else ret->cipher=ssl_get_cipher_by_char(s,&(buf[1])); @@ -227,6 +283,7 @@ int SSL_CTX_add_session(ctx,c) SSL_CTX *ctx; SSL_SESSION *c; { + int ret=0; SSL_SESSION *s; /* conn_init(); */ @@ -234,7 +291,10 @@ SSL_SESSION *c; CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); s=(SSL_SESSION *)lh_insert(ctx->sessions,(char *)c); - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + + /* Put on the end of the queue unless it is already in the cache */ + if (s == NULL) + SSL_SESSION_list_add(ctx,c); /* If the same session if is being 're-added', Free the old * one when the last person stops using it. @@ -243,10 +303,27 @@ SSL_SESSION *c; if (s != NULL) { SSL_SESSION_free(s); - return(0); + ret=0; } else - return(1); + { + ret=1; + + if (SSL_CTX_sess_get_cache_size(ctx) > 0) + { + while (SSL_CTX_sess_number(ctx) > + SSL_CTX_sess_get_cache_size(ctx)) + { + if (!SSL_CTX_remove_session(ctx, + ctx->session_cache_tail)) + break; + else + ctx->sess_cache_full++; + } + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + return(ret); } int SSL_CTX_remove_session(ctx,c) @@ -256,11 +333,15 @@ SSL_SESSION *c; SSL_SESSION *r; int ret=0; - if ((c->session_id_length != 0) && (c != NULL)) + if ((c != NULL) && (c->session_id_length != 0)) { CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); r=(SSL_SESSION *)lh_delete(ctx->sessions,(char *)c); - if (r != NULL) ret=1; + if (r != NULL) + { + ret=1; + SSL_SESSION_list_remove(ctx,c); + } CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); @@ -268,7 +349,7 @@ SSL_SESSION *c; { r->not_resumable=1; if (ctx->remove_session_cb != NULL) - ctx->remove_session_cb(ctx,c); + ctx->remove_session_cb(ctx,r); SSL_SESSION_free(r); } } @@ -283,6 +364,9 @@ SSL_SESSION *ss; int i; i=CRYPTO_add(&ss->references,-1,CRYPTO_LOCK_SSL_SESSION); +#ifdef REF_PRINT + REF_PRINT("SSL_SESSION",ss); +#endif if (i > 0) return; #ifdef REF_CHECK if (i < 0) @@ -292,6 +376,8 @@ SSL_SESSION *ss; } #endif + CRYPTO_free_ex_data(ssl_session_meth,(char *)ss,&ss->ex_data); + memset(ss->key_arg,0,SSL_MAX_KEY_ARG_LENGTH); memset(ss->master_key,0,SSL_MAX_MASTER_KEY_LENGTH); memset(ss->session_id,0,SSL_MAX_SSL_SESSION_ID_LENGTH); @@ -335,10 +421,18 @@ SSL_SESSION *session; /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL);*/ ret=1; } + else + { + if (s->session != NULL) + { + SSL_SESSION_free(s->session); + s->session=NULL; + } + } return(ret); } -long SSL_set_timeout(s,t) +long SSL_SESSION_set_timeout(s,t) SSL_SESSION *s; long t; { @@ -347,21 +441,21 @@ long t; return(1); } -long SSL_get_timeout(s) +long SSL_SESSION_get_timeout(s) SSL_SESSION *s; { if (s == NULL) return(0); return(s->timeout); } -long SSL_get_time(s) +long SSL_SESSION_get_time(s) SSL_SESSION *s; { if (s == NULL) return(0); return(s->time); } -long SSL_set_time(s,t) +long SSL_SESSION_set_time(s,t) SSL_SESSION *s; long t; { @@ -383,7 +477,10 @@ TIMEOUT_PARAM *p; { if ((p->time == 0) || (p->time > (s->time+s->timeout))) /* timeout */ { + /* The reason we don't call SSL_CTX_remove_session() is to + * save on locking overhead */ lh_delete(p->cache,(char *)s); + SSL_SESSION_list_remove(p->ctx,s); s->not_resumable=1; if (p->ctx->remove_session_cb != NULL) p->ctx->remove_session_cb(p->ctx,s); @@ -423,3 +520,63 @@ SSL *s; else return(0); } + +/* locked by SSL_CTX in the calling function */ +static void SSL_SESSION_list_remove(ctx,s) +SSL_CTX *ctx; +SSL_SESSION *s; + { + if ((s->next == NULL) || (s->prev == NULL)) return; + + if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) + { /* last element in list */ + if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) + { /* only one element in list */ + ctx->session_cache_head=NULL; + ctx->session_cache_tail=NULL; + } + else + { + ctx->session_cache_tail=s->prev; + s->prev->next=(SSL_SESSION *)&(ctx->session_cache_tail); + } + } + else + { + if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) + { /* first element in list */ + ctx->session_cache_head=s->next; + s->next->prev=(SSL_SESSION *)&(ctx->session_cache_head); + } + else + { /* middle of list */ + s->next->prev=s->prev; + s->prev->next=s->next; + } + } + s->prev=s->next=NULL; + } + +static void SSL_SESSION_list_add(ctx,s) +SSL_CTX *ctx; +SSL_SESSION *s; + { + if ((s->next != NULL) && (s->prev != NULL)) + SSL_SESSION_list_remove(ctx,s); + + if (ctx->session_cache_head == NULL) + { + ctx->session_cache_head=s; + ctx->session_cache_tail=s; + s->prev=(SSL_SESSION *)&(ctx->session_cache_head); + s->next=(SSL_SESSION *)&(ctx->session_cache_tail); + } + else + { + s->next=ctx->session_cache_head; + s->next->prev=s; + s->prev=(SSL_SESSION *)&(ctx->session_cache_head); + ctx->session_cache_head=s; + } + } + diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c index 328ccc94ff..a1daf25dd4 100644 --- a/ssl/ssl_stat.c +++ b/ssl/ssl_stat.c @@ -1,5 +1,5 @@ /* ssl/ssl_stat.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 @@ -207,6 +207,7 @@ SSL *s; { case SSL_ST_READ_HEADER: str="read header"; break; case SSL_ST_READ_BODY: str="read body"; break; + case SSL_ST_READ_DONE: str="read done"; break; default: str="unknown"; break; } return(str); diff --git a/ssl/ssl_task.c b/ssl/ssl_task.c index c27ce913e7..ab72166665 100644 --- a/ssl/ssl_task.c +++ b/ssl/ssl_task.c @@ -1,5 +1,5 @@ /* ssl/ssl_task.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/ssl_txt.c b/ssl/ssl_txt.c index b9cb9ef673..ce60e1a6dd 100644 --- a/ssl/ssl_txt.c +++ b/ssl/ssl_txt.c @@ -1,5 +1,5 @@ /* ssl/ssl_txt.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 @@ -60,7 +60,7 @@ #include "buffer.h" #include "ssl_locl.h" -#ifndef WIN16 +#ifndef NO_FP_API int SSL_SESSION_print_fp(fp, x) FILE *fp; SSL_SESSION *x; @@ -68,7 +68,7 @@ SSL_SESSION *x; BIO *b; int ret; - if ((b=BIO_new(BIO_s_file())) == NULL) + if ((b=BIO_new(BIO_s_file_internal())) == NULL) { SSLerr(SSL_F_SSL_SESSION_PRINT_FP,ERR_R_BUF_LIB); return(0); @@ -85,11 +85,30 @@ BIO *bp; SSL_SESSION *x; { int i; - char str[128]; + char str[128],*s; if (x == NULL) goto err; if (BIO_puts(bp,"SSL-Session:\n") <= 0) goto err; - sprintf(str," Cipher : %s\n",(x->cipher == NULL)?"unknown":x->cipher->name); + if (x->ssl_version == SSL2_VERSION) + s="SSLv2"; + else if (x->ssl_version == SSL3_VERSION) + s="SSLv3"; + else if (x->ssl_version == TLS1_VERSION) + s="TLSv1"; + else + s="unknown"; + sprintf(str," Protocol : %s\n",s); + if (BIO_puts(bp,str) <= 0) goto err; + + if (x->cipher == NULL) + { + if (((x->cipher_id) & 0xff000000) == 0x02000000) + sprintf(str," Cipher : %06lX\n",x->cipher_id&0xffffff); + else + sprintf(str," Cipher : %04lX\n",x->cipher_id&0xffff); + } + else + sprintf(str," Cipher : %s\n",(x->cipher == NULL)?"unknown":x->cipher->name); if (BIO_puts(bp,str) <= 0) goto err; if (BIO_puts(bp," Session-ID: ") <= 0) goto err; for (i=0; i<(int)x->session_id_length; i++) diff --git a/ssl/ssltest.c b/ssl/ssltest.c index b8d657f3ba..f9dca4e3ef 100644 --- a/ssl/ssltest.c +++ b/ssl/ssltest.c @@ -1,5 +1,5 @@ /* ssl/ssltest.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 @@ -60,18 +60,13 @@ #include <stdlib.h> #include <string.h> #include <errno.h> -#ifdef WIN16 -#define APPS_WIN16 -#endif +#include "e_os.h" #include "bio.h" #include "crypto.h" -#include "../e_os.h" #include "x509.h" #include "ssl.h" #include "err.h" - -#ifdef WIN16 -#define APPS_WIN16 +#ifdef WINDOWS #include "../crypto/bio/bss_file.c" #endif @@ -80,24 +75,31 @@ #ifndef NOPROTO int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int export); +#ifndef NO_DSA static DH *get_dh512(void); +#endif #else int MS_CALLBACK verify_callback(); +static RSA MS_CALLBACK *tmp_rsa_cb(); +#ifndef NO_DSA static DH *get_dh512(); #endif +#endif BIO *bio_err=NULL; BIO *bio_stdout=NULL; static char *cipher=NULL; int verbose=0; +int debug=0; #ifdef FIONBIO static int s_nbio=0; #endif #ifndef NOPROTO -int doit(SSL_CTX *s_ctx,SSL_CTX *c_ctx); +int doit(SSL *s_ssl,SSL *c_ssl,long bytes); #else int doit(); #endif @@ -109,14 +111,25 @@ static void sv_usage() fprintf(stderr," -server_auth - check server certificate\n"); fprintf(stderr," -client_auth - do client authentication\n"); fprintf(stderr," -v - more output\n"); + fprintf(stderr," -d - debug output\n"); + fprintf(stderr," -reuse - use session-id reuse\n"); + fprintf(stderr," -num <val> - number of connections to perform\n"); + fprintf(stderr," -bytes <val> - number of bytes to swap between client/server\n"); #ifndef NO_SSL2 fprintf(stderr," -ssl2 - use SSLv2\n"); #endif #ifndef NO_SSL3 fprintf(stderr," -ssl3 - use SSLv3\n"); #endif +#ifndef NO_TLS1 + fprintf(stderr," -tls1 - use TLSv1\n"); +#endif fprintf(stderr," -CApath arg - PEM format directory of CA's\n"); fprintf(stderr," -CAfile arg - PEM format file of CA's\n"); + fprintf(stderr," -cert arg - Certificate file\n"); + fprintf(stderr," -s_cert arg - Just the server certificate file\n"); + fprintf(stderr," -c_cert arg - Just the client certificate file\n"); + fprintf(stderr," -cipher arg - The cipher list\n"); } int main(argc, argv) @@ -125,15 +138,21 @@ char *argv[]; { char *CApath=NULL,*CAfile=NULL; int badop=0; - int ssl2=0,ssl3=0,ret=1; + int tls1=0,ssl2=0,ssl3=0,ret=1; int client_auth=0; - int server_auth=0; + int server_auth=0,i; char *server_cert=TEST_SERVER_CERT; char *client_cert=TEST_CLIENT_CERT; SSL_CTX *s_ctx=NULL; SSL_CTX *c_ctx=NULL; SSL_METHOD *meth=NULL; + SSL *c_ssl,*s_ssl; + int number=1,reuse=0; + long bytes=1L; + SSL_CIPHER *ciph; +#ifndef NO_DH DH *dh; +#endif bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE); @@ -151,10 +170,31 @@ char *argv[]; client_auth=1; else if (strcmp(*argv,"-v") == 0) verbose=1; + else if (strcmp(*argv,"-d") == 0) + debug=1; + else if (strcmp(*argv,"-reuse") == 0) + reuse=1; else if (strcmp(*argv,"-ssl2") == 0) ssl2=1; + else if (strcmp(*argv,"-tls1") == 0) + tls1=1; else if (strcmp(*argv,"-ssl3") == 0) ssl3=1; + else if (strncmp(*argv,"-num",4) == 0) + { + if (--argc < 1) goto bad; + number= atoi(*(++argv)); + if (number == 0) number=1; + } + else if (strcmp(*argv,"-bytes") == 0) + { + if (--argc < 1) goto bad; + bytes= atol(*(++argv)); + if (bytes == 0L) bytes=1L; + i=strlen(argv[0]); + if (argv[0][i-1] == 'k') bytes*=1024L; + if (argv[0][i-1] == 'm') bytes*=1024L*1024L; + } else if (strcmp(*argv,"-cert") == 0) { if (--argc < 1) goto bad; @@ -210,6 +250,9 @@ bad: if (ssl2) meth=SSLv2_method(); else + if (tls1) + meth=TLSv1_method(); + else if (ssl3) meth=SSLv3_method(); else @@ -239,7 +282,11 @@ bad: #ifndef NO_DH dh=get_dh512(); SSL_CTX_set_tmp_dh(s_ctx,dh); - DH_free(dh); + DH_free(dh); +#endif + +#ifndef NO_RSA + SSL_CTX_set_tmp_rsa_callback(s_ctx,tmp_rsa_cb); #endif if (!SSL_CTX_use_certificate_file(s_ctx,server_cert,SSL_FILETYPE_PEM)) @@ -266,9 +313,9 @@ bad: (!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) || (!SSL_CTX_set_default_verify_paths(c_ctx))) { - fprintf(stderr,"SSL_load_verify_locations\n"); + /* fprintf(stderr,"SSL_load_verify_locations\n"); */ ERR_print_errors(bio_err); - goto end; + /* goto end; */ } if (client_auth) @@ -285,7 +332,29 @@ bad: verify_callback); } - ret=doit(s_ctx,c_ctx); + c_ssl=SSL_new(c_ctx); + s_ssl=SSL_new(s_ctx); + + for (i=0; i<number; i++) + { + if (!reuse) SSL_set_session(c_ssl,NULL); + ret=doit(s_ssl,c_ssl,bytes); + } + + if (!verbose) + { + ciph=SSL_get_current_cipher(c_ssl); + fprintf(stdout,"Protocol %s, cipher %s, %s\n", + SSL_get_version(c_ssl), + SSL_CIPHER_get_version(ciph), + SSL_CIPHER_get_name(ciph)); + } + if ((number > 1) || (bytes > 1L)) + printf("%d handshakes of %ld bytes done\n",number,bytes); + + SSL_free(s_ssl); + SSL_free(c_ssl); + end: if (s_ctx != NULL) SSL_CTX_free(s_ctx); if (c_ctx != NULL) SSL_CTX_free(c_ctx); @@ -303,33 +372,26 @@ end: #define C_DONE 1 #define S_DONE 2 -int doit(s_ctx,c_ctx) -SSL_CTX *s_ctx,*c_ctx; +int doit(s_ssl,c_ssl,count) +SSL *s_ssl,*c_ssl; +long count; { - static char cbuf[200],sbuf[200]; + MS_STATIC char cbuf[1024*8],sbuf[1024*8]; + long cw_num=count,cr_num=count; + long sw_num=count,sr_num=count; int ret=1; - SSL *c_ssl=NULL; - SSL *s_ssl=NULL; BIO *c_to_s=NULL; BIO *s_to_c=NULL; BIO *c_bio=NULL; BIO *s_bio=NULL; int c_r,c_w,s_r,s_w; int c_want,s_want; - int i; + int i,j; int done=0; int c_write,s_write; int do_server=0,do_client=0; SSL_CIPHER *ciph; - c_ssl=SSL_new(c_ctx); - s_ssl=SSL_new(s_ctx); - if ((s_ssl == NULL) || (c_ssl == NULL)) - { - ERR_print_errors(bio_err); - goto err; - } - c_to_s=BIO_new(BIO_s_mem()); s_to_c=BIO_new(BIO_s_mem()); if ((s_to_c == NULL) || (c_to_s == NULL)) @@ -348,11 +410,11 @@ SSL_CTX *s_ctx,*c_ctx; SSL_set_connect_state(c_ssl); SSL_set_bio(c_ssl,s_to_c,c_to_s); - BIO_set_ssl(c_bio,c_ssl,BIO_CLOSE); + BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE); SSL_set_accept_state(s_ssl); SSL_set_bio(s_ssl,c_to_s,s_to_c); - BIO_set_ssl(s_bio,s_ssl,BIO_CLOSE); + BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE); c_r=0; s_r=1; c_w=1; s_w=0; @@ -372,26 +434,26 @@ SSL_CTX *s_ctx,*c_ctx; i=(int)BIO_pending(c_bio); if ((i && c_r) || c_w) do_client=1; - if (do_server && verbose) + if (do_server && debug) { if (SSL_in_init(s_ssl)) printf("server waiting in SSL_accept - %s\n", SSL_state_string_long(s_ssl)); - else if (s_write) +/* else if (s_write) printf("server:SSL_write()\n"); - else - printf("server:SSL_read()\n"); + else + printf("server:SSL_read()\n"); */ } - if (do_client && verbose) + if (do_client && debug) { if (SSL_in_init(c_ssl)) printf("client waiting in SSL_connect - %s\n", SSL_state_string_long(c_ssl)); - else if (c_write) +/* else if (c_write) printf("client:SSL_write()\n"); else - printf("client:SSL_read()\n"); + printf("client:SSL_read()\n"); */ } if (!do_client && !do_server) @@ -404,7 +466,9 @@ SSL_CTX *s_ctx,*c_ctx; { if (c_write) { - i=BIO_write(c_bio,"hello from client\n",18); + j=(cw_num > (long)sizeof(cbuf)) + ?sizeof(cbuf):(int)cw_num; + i=BIO_write(c_bio,cbuf,j); if (i < 0) { c_r=0; @@ -430,13 +494,17 @@ SSL_CTX *s_ctx,*c_ctx; } else { + if (debug) + printf("client wrote %d\n",i); /* ok */ + s_r=1; c_write=0; + cw_num-=i; } } else { - i=BIO_read(c_bio,cbuf,100); + i=BIO_read(c_bio,cbuf,sizeof(cbuf)); if (i < 0) { c_r=0; @@ -462,10 +530,20 @@ SSL_CTX *s_ctx,*c_ctx; } else { - done|=C_DONE; - fprintf(stdout,"CLIENT:from server:"); - fwrite(cbuf,1,i,stdout); - fflush(stdout); + if (debug) + printf("client read %d\n",i); + cr_num-=i; + if (sw_num > 0) + { + s_write=1; + s_w=1; + } + if (cr_num <= 0) + { + s_write=1; + s_w=1; + done=S_DONE|C_DONE; + } } } } @@ -474,7 +552,7 @@ SSL_CTX *s_ctx,*c_ctx; { if (!s_write) { - i=BIO_read(s_bio,sbuf,100); + i=BIO_read(s_bio,sbuf,sizeof(cbuf)); if (i < 0) { s_r=0; @@ -501,16 +579,27 @@ SSL_CTX *s_ctx,*c_ctx; } else { - s_write=1; - s_w=1; - fprintf(stdout,"SERVER:from client:"); - fwrite(sbuf,1,i,stdout); - fflush(stdout); + if (debug) + printf("server read %d\n",i); + sr_num-=i; + if (cw_num > 0) + { + c_write=1; + c_w=1; + } + if (sr_num <= 0) + { + s_write=1; + s_w=1; + c_write=0; + } } } else { - i=BIO_write(s_bio,"hello from server\n",18); + j=(sw_num > (long)sizeof(sbuf))? + sizeof(sbuf):(int)sw_num; + i=BIO_write(s_bio,sbuf,j); if (i < 0) { s_r=0; @@ -537,9 +626,13 @@ SSL_CTX *s_ctx,*c_ctx; } else { + if (debug) + printf("server wrote %d\n",i); + sw_num-=i; s_write=0; - s_r=1; - done|=S_DONE; + c_r=1; + if (sw_num <= 0) + done|=S_DONE; } } } @@ -548,8 +641,11 @@ SSL_CTX *s_ctx,*c_ctx; } ciph=SSL_get_current_cipher(c_ssl); - fprintf(stdout,"DONE, used %s, %s\n",SSL_CIPHER_get_version(ciph), - SSL_CIPHER_get_name(ciph)); + if (verbose) + fprintf(stdout,"DONE, protocol %s, cipher %s, %s\n", + SSL_get_version(c_ssl), + SSL_CIPHER_get_version(ciph), + SSL_CIPHER_get_name(ciph)); ret=0; err: /* We have to set the BIO's to NULL otherwise they will be @@ -572,8 +668,8 @@ err: if (c_to_s != NULL) BIO_free(c_to_s); if (s_to_c != NULL) BIO_free(s_to_c); - if (c_bio != NULL) BIO_free(c_bio); - if (s_bio != NULL) BIO_free(s_bio); + if (c_bio != NULL) BIO_free_all(c_bio); + if (s_bio != NULL) BIO_free_all(s_bio); return(ret); } @@ -607,6 +703,7 @@ X509_STORE_CTX *ctx; return(ok); } +#ifndef NO_DH static unsigned char dh512_p[]={ 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, @@ -623,13 +720,32 @@ static DH *get_dh512() { DH *dh=NULL; -#ifndef NO_DH if ((dh=DH_new()) == NULL) return(NULL); dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); if ((dh->p == NULL) || (dh->g == NULL)) return(NULL); -#endif return(dh); } +#endif + +static RSA MS_CALLBACK *tmp_rsa_cb(s,export) +SSL *s; +int export; + { + static RSA *rsa_tmp=NULL; + + if (rsa_tmp == NULL) + { + BIO_printf(bio_err,"Generating temp (512 bit) RSA key..."); + BIO_flush(bio_err); +#ifndef NO_RSA + rsa_tmp=RSA_generate_key(512,RSA_F4,NULL,NULL); +#endif + BIO_printf(bio_err,"\n"); + BIO_flush(bio_err); + } + return(rsa_tmp); + } + diff --git a/ssl/t1_clnt.c b/ssl/t1_clnt.c new file mode 100644 index 0000000000..986d2436e2 --- /dev/null +++ b/ssl/t1_clnt.c @@ -0,0 +1,90 @@ +/* ssl/t1_clnt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "buffer.h" +#include "rand.h" +#include "objects.h" +#include "evp.h" +#include "ssl_locl.h" + +static SSL_METHOD *tls1_get_client_method(ver) +int ver; + { + if (ver == TLS1_VERSION) + return(TLSv1_client_method()); + else + return(NULL); + } + +SSL_METHOD *TLSv1_client_method() + { + static int init=1; + static SSL_METHOD TLSv1_client_data; + + if (init) + { + init=0; + memcpy((char *)&TLSv1_client_data,(char *)tlsv1_base_method(), + sizeof(SSL_METHOD)); + TLSv1_client_data.ssl_connect=ssl3_connect; + TLSv1_client_data.get_ssl_method=tls1_get_client_method; + } + return(&TLSv1_client_data); + } + diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c new file mode 100644 index 0000000000..fbdd3bffb5 --- /dev/null +++ b/ssl/t1_enc.c @@ -0,0 +1,635 @@ +/* ssl/t1_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "evp.h" +#include "hmac.h" +#include "ssl_locl.h" + +static void tls1_P_hash(md,sec,sec_len,seed,seed_len,out,olen) +EVP_MD *md; +unsigned char *sec; +int sec_len; +unsigned char *seed; +int seed_len; +unsigned char *out; +int olen; + { + int chunk,n; + unsigned int j; + HMAC_CTX ctx; + HMAC_CTX ctx_tmp; + unsigned char A1[HMAC_MAX_MD_CBLOCK]; + unsigned int A1_len; + + chunk=EVP_MD_size(md); + + HMAC_Init(&ctx,sec,sec_len,md); + HMAC_Update(&ctx,seed,seed_len); + HMAC_Final(&ctx,A1,&A1_len); + + n=0; + for (;;) + { + HMAC_Init(&ctx,NULL,0,NULL); /* re-init */ + HMAC_Update(&ctx,A1,A1_len); + memcpy(&ctx_tmp,&ctx,sizeof(ctx)); /* Copy for A2 */ /* not needed for last one */ + HMAC_Update(&ctx,seed,seed_len); + + if (olen > chunk) + { + HMAC_Final(&ctx,out,&j); + out+=j; + olen-=j; + HMAC_Final(&ctx_tmp,A1,&A1_len); /* calc the next A1 value */ + } + else /* last one */ + { + HMAC_Final(&ctx,A1,&A1_len); + memcpy(out,A1,olen); + break; + } + } + HMAC_cleanup(&ctx); + HMAC_cleanup(&ctx_tmp); + memset(A1,0,sizeof(A1)); + } + +static void tls1_PRF(md5,sha1,label,label_len,sec,slen,out1,out2,olen) +EVP_MD *md5; +EVP_MD *sha1; +unsigned char *label; +int label_len; +unsigned char *sec; +int slen; +unsigned char *out1; +unsigned char *out2; +int olen; + { + int len,i; + unsigned char *S1,*S2; + + len=slen/2; + S1=sec; + S2= &(sec[len]); + len+=(slen&1); /* add for odd, make longer */ + + + tls1_P_hash(md5 ,S1,len,label,label_len,out1,olen); + tls1_P_hash(sha1,S2,len,label,label_len,out2,olen); + + for (i=0; i<olen; i++) + out1[i]^=out2[i]; + } + +static void tls1_generate_key_block(s,km,tmp,num) +SSL *s; +unsigned char *km,*tmp; +int num; + { + unsigned char *p; + unsigned char buf[SSL3_RANDOM_SIZE*2+ + TLS_MD_MAX_CONST_SIZE]; + p=buf; + + memcpy(p,TLS_MD_KEY_EXPANSION_CONST, + TLS_MD_KEY_EXPANSION_CONST_SIZE); + p+=TLS_MD_KEY_EXPANSION_CONST_SIZE; + memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); + p+=SSL3_RANDOM_SIZE; + memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); + p+=SSL3_RANDOM_SIZE; + + tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,p-buf, + s->session->master_key,s->session->master_key_length, + km,tmp,num); + } + +int tls1_change_cipher_state(s,which) +SSL *s; +int which; + { + unsigned char *p,*key_block,*mac_secret; + unsigned char *exp_label,buf[TLS_MD_MAX_CONST_SIZE+ + SSL3_RANDOM_SIZE*2]; + unsigned char tmp1[EVP_MAX_KEY_LENGTH]; + unsigned char tmp2[EVP_MAX_KEY_LENGTH]; + unsigned char iv1[EVP_MAX_IV_LENGTH*2]; + unsigned char iv2[EVP_MAX_IV_LENGTH*2]; + unsigned char *ms,*key,*iv,*er1,*er2; + int client_write; + EVP_CIPHER_CTX *dd; + EVP_CIPHER *c; + SSL_COMPRESSION *comp; + EVP_MD *m; + int exp,n,i,j,k,exp_label_len; + + exp=(s->s3->tmp.new_cipher->algorithms & SSL_EXPORT)?1:0; + c=s->s3->tmp.new_sym_enc; + m=s->s3->tmp.new_hash; + comp=s->s3->tmp.new_compression; + key_block=s->s3->tmp.key_block; + + if (which & SSL3_CC_READ) + { + if ((s->enc_read_ctx == NULL) && + ((s->enc_read_ctx=(EVP_CIPHER_CTX *) + Malloc(sizeof(EVP_CIPHER_CTX))) == NULL)) + goto err; + dd= s->enc_read_ctx; + s->read_hash=m; + s->read_compression=comp; + memset(&(s->s3->read_sequence[0]),0,8); + mac_secret= &(s->s3->read_mac_secret[0]); + } + else + { + if ((s->enc_write_ctx == NULL) && + ((s->enc_write_ctx=(EVP_CIPHER_CTX *) + Malloc(sizeof(EVP_CIPHER_CTX))) == NULL)) + goto err; + dd= s->enc_write_ctx; + s->write_hash=m; + s->write_compression=comp; + memset(&(s->s3->write_sequence[0]),0,8); + mac_secret= &(s->s3->write_mac_secret[0]); + } + + EVP_CIPHER_CTX_init(dd); + + p=s->s3->tmp.key_block; + i=EVP_MD_size(m); + j=(exp)?5:EVP_CIPHER_key_length(c); + k=EVP_CIPHER_iv_length(c); + er1= &(s->s3->client_random[0]); + er2= &(s->s3->server_random[0]); + if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || + (which == SSL3_CHANGE_CIPHER_SERVER_READ)) + { + ms= &(p[ 0]); n=i+i; + key= &(p[ n]); n+=j+j; + iv= &(p[ n]); n+=k+k; + exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; + exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; + client_write=1; + } + else + { + n=i; + ms= &(p[ n]); n+=i+j; + key= &(p[ n]); n+=j+k; + iv= &(p[ n]); n+=k; + exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; + exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; + client_write=0; + } + + if (n > s->s3->tmp.key_block_length) + { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_INTERNAL_ERROR); + goto err2; + } + + memcpy(mac_secret,ms,i); +#ifdef TLS_DEBUG +printf("which = %04X\nmac key=",which); +{ int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); } +#endif + if (exp) + { + /* In here I set both the read and write key/iv to the + * same value since only the correct one will be used :-). + */ + p=buf; + memcpy(p,exp_label,exp_label_len); + p+=exp_label_len; + memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); + p+=SSL3_RANDOM_SIZE; + memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); + p+=SSL3_RANDOM_SIZE; + tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,p-buf,key,j, + tmp1,tmp2,EVP_CIPHER_key_length(c)); + key=tmp1; + + if (k > 0) + { + p=buf; + memcpy(p,TLS_MD_IV_BLOCK_CONST, + TLS_MD_IV_BLOCK_CONST_SIZE); + p+=TLS_MD_IV_BLOCK_CONST_SIZE; + memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); + p+=SSL3_RANDOM_SIZE; + memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); + p+=SSL3_RANDOM_SIZE; + tls1_PRF(s->ctx->md5,s->ctx->sha1, + buf,p-buf,"",0,iv1,iv2,k*2); + if (client_write) + iv=iv1; + else + iv= &(iv1[k]); + } + } + + s->session->key_arg_length=0; + + EVP_CipherInit(dd,c,key,iv,(which & SSL3_CC_WRITE)); +#ifdef TLS_DEBUG +printf("which = %04X\nkey=",which); +{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); } +printf("\niv="); +{ int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); } +printf("\n"); +#endif + + memset(tmp1,0,sizeof(tmp1)); + memset(tmp2,0,sizeof(tmp1)); + memset(iv1,0,sizeof(iv1)); + memset(iv2,0,sizeof(iv2)); + return(1); +err: + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); +err2: + return(0); + } + +int tls1_setup_key_block(s) +SSL *s; + { + unsigned char *p1,*p2; + EVP_CIPHER *c; + EVP_MD *hash; + int num,exp; + + if (s->s3->tmp.key_block_length != 0) + return(1); + + if (!ssl_cipher_get_evp(s->session->cipher,&c,&hash)) + { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return(0); + } + + s->s3->tmp.new_sym_enc=c; + s->s3->tmp.new_hash=hash; + + exp=(s->session->cipher->algorithms & SSL_EXPORT)?1:0; + + num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c); + num*=2; + + ssl3_cleanup_key_block(s); + + if ((p1=(unsigned char *)Malloc(num)) == NULL) + goto err; + if ((p2=(unsigned char *)Malloc(num)) == NULL) + goto err; + + s->s3->tmp.key_block_length=num; + s->s3->tmp.key_block=p1; + + +#ifdef TLS_DEBUG +printf("client random\n"); +{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); } +printf("server random\n"); +{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); } +printf("pre-master\n"); +{ int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); } +#endif + tls1_generate_key_block(s,p1,p2,num); + memset(p2,0,num); + Free(p2); +#ifdef TLS_DEBUG +printf("\nkey block\n"); +{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); } +#endif + + return(1); +err: + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); + return(0); + } + +int tls1_enc(s,send) +SSL *s; +int send; + { + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; + int bs,i,ii,j,k,n=0; + EVP_CIPHER *enc; + SSL_COMPRESSION *comp; + + if (send) + { + if (s->write_hash != NULL) + n=EVP_MD_size(s->write_hash); + ds=s->enc_write_ctx; + rec= &(s->s3->wrec); + if (s->enc_write_ctx == NULL) + { enc=NULL; comp=NULL; } + else + { + enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx); + comp=s->write_compression; + } + } + else + { + if (s->read_hash != NULL) + n=EVP_MD_size(s->read_hash); + ds=s->enc_read_ctx; + rec= &(s->s3->rrec); + if (s->enc_read_ctx == NULL) + { enc=NULL; comp=NULL; } + else + { + enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx); + comp=s->read_compression; + } + } + + if ((s->session == NULL) || (ds == NULL) || + ((enc == NULL) && (comp == NULL))) + { + memcpy(rec->data,rec->input,rec->length); + rec->input=rec->data; + } + else + { + l=rec->length; + bs=EVP_CIPHER_block_size(ds->cipher); + + if ((bs != 1) && send) + { + i=bs-((int)l%bs); + + /* Add weird padding of upto 256 bytes */ + + /* we need to add 'i' padding bytes of value j */ + j=i-1; + if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) + { + if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) + j++; + } + for (k=(int)l; k<(int)(l+i); k++) + rec->input[k]=j; + l+=i; + rec->length+=i; + } + + EVP_Cipher(ds,rec->data,rec->input,l); + + if ((bs != 1) && !send) + { + ii=i=rec->data[l-1]; + i++; + if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) + { + /* First packet is even in size, so check */ + if ((memcmp(s->s3->read_sequence, + "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) + s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; + if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) + i--; + } + if (i > (int)rec->length) + { + SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); + return(0); + } + for (j=(int)(l-i); j<(int)l; j++) + { + if (rec->data[j] != ii) + { + SSLerr(SSL_F_TLS1_ENC,SSL_R_DECRYPTION_FAILED); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); + return(0); + } + } + rec->length-=i; + } + } + return(1); + } + +int tls1_cert_verify_mac(s,in_ctx,out) +SSL *s; +EVP_MD_CTX *in_ctx; +unsigned char *out; + { + unsigned int ret; + EVP_MD_CTX ctx; + + memcpy(&ctx,in_ctx,sizeof(EVP_MD_CTX)); + EVP_DigestFinal(&ctx,out,&ret); + return((int)ret); + } + +int tls1_final_finish_mac(s,in1_ctx,in2_ctx,str,slen,out) +SSL *s; +EVP_MD_CTX *in1_ctx,*in2_ctx; +unsigned char *str; +int slen; +unsigned char *out; + { + unsigned int i; + EVP_MD_CTX ctx; + unsigned char buf[TLS_MD_MAX_CONST_SIZE+MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; + unsigned char *q,buf2[12]; + + q=buf; + memcpy(q,str,slen); + q+=slen; + + memcpy(&ctx,in1_ctx,sizeof(EVP_MD_CTX)); + EVP_DigestFinal(&ctx,q,&i); + q+=i; + memcpy(&ctx,in2_ctx,sizeof(EVP_MD_CTX)); + EVP_DigestFinal(&ctx,q,&i); + q+=i; + + tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,q-buf, + s->session->master_key,s->session->master_key_length, + out,buf2,12); + memset(&ctx,0,sizeof(EVP_MD_CTX)); + + return((int)12); + } + +int tls1_mac(ssl,md,send) +SSL *ssl; +unsigned char *md; +int send; + { + SSL3_RECORD *rec; + unsigned char *mac_sec,*seq; + EVP_MD *hash; + unsigned int md_size; + int i; + HMAC_CTX hmac; + unsigned char buf[5]; + + if (send) + { + rec= &(ssl->s3->wrec); + mac_sec= &(ssl->s3->write_mac_secret[0]); + seq= &(ssl->s3->write_sequence[0]); + hash=ssl->write_hash; + } + else + { + rec= &(ssl->s3->rrec); + mac_sec= &(ssl->s3->read_mac_secret[0]); + seq= &(ssl->s3->read_sequence[0]); + hash=ssl->read_hash; + } + + md_size=EVP_MD_size(hash); + + buf[0]=rec->type; + buf[1]=TLS1_VERSION_MAJOR; + buf[2]=TLS1_VERSION_MINOR; + buf[3]=rec->length>>8; + buf[4]=rec->length&0xff; + + /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ + HMAC_Init(&hmac,mac_sec,EVP_MD_size(hash),hash); + HMAC_Update(&hmac,seq,8); + HMAC_Update(&hmac,buf,5); + HMAC_Update(&hmac,rec->input,rec->length); + HMAC_Final(&hmac,md,&md_size); + +#ifdef TLS_DEBUG +printf("sec="); +{int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); } +printf("seq="); +{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); } +printf("buf="); +{int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); } +printf("rec="); +{int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); } +#endif + + for (i=7; i>=0; i--) + if (++seq[i]) break; + +#ifdef TLS_DEBUG +{int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); } +#endif + return(md_size); + } + +int tls1_generate_master_secret(s,out,p,len) +SSL *s; +unsigned char *out; +unsigned char *p; +int len; + { + unsigned char buf[SSL3_RANDOM_SIZE*2+TLS_MD_MASTER_SECRET_CONST_SIZE]; + unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH]; + + /* Setup the stuff to munge */ + memcpy(buf,TLS_MD_MASTER_SECRET_CONST, + TLS_MD_MASTER_SECRET_CONST_SIZE); + memcpy(&(buf[TLS_MD_MASTER_SECRET_CONST_SIZE]), + s->s3->client_random,SSL3_RANDOM_SIZE); + memcpy(&(buf[SSL3_RANDOM_SIZE+TLS_MD_MASTER_SECRET_CONST_SIZE]), + s->s3->server_random,SSL3_RANDOM_SIZE); + tls1_PRF(s->ctx->md5,s->ctx->sha1, + buf,TLS_MD_MASTER_SECRET_CONST_SIZE+SSL3_RANDOM_SIZE*2,p,len, + s->session->master_key,buff,SSL3_MASTER_SECRET_SIZE); + return(SSL3_MASTER_SECRET_SIZE); + } + +int tls1_alert_code(code) +int code; + { + switch (code) + { + case SSL_AD_CLOSE_NOTIFY: return(SSL3_AD_CLOSE_NOTIFY); + case SSL_AD_UNEXPECTED_MESSAGE: return(SSL3_AD_UNEXPECTED_MESSAGE); + case SSL_AD_BAD_RECORD_MAC: return(SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECRYPTION_FAILED: return(TLS1_AD_DECRYPTION_FAILED); + case SSL_AD_RECORD_OVERFLOW: return(TLS1_AD_RECORD_OVERFLOW); + case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE); + case SSL_AD_HANDSHAKE_FAILURE: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_CERTIFICATE: return(-1); + case SSL_AD_BAD_CERTIFICATE: return(SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE); + case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED); + case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED); + case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN); + case SSL_AD_ILLEGAL_PARAMETER: return(SSL3_AD_ILLEGAL_PARAMETER); + case SSL_AD_UNKNOWN_CA: return(TLS1_AD_UNKNOWN_CA); + case SSL_AD_ACCESS_DENIED: return(TLS1_AD_ACCESS_DENIED); + case SSL_AD_DECODE_ERROR: return(TLS1_AD_DECODE_ERROR); + case SSL_AD_DECRYPT_ERROR: return(TLS1_AD_DECRYPT_ERROR); + case SSL_AD_EXPORT_RESTRICION: return(TLS1_AD_EXPORT_RESTRICION); + case SSL_AD_PROTOCOL_VERSION: return(TLS1_AD_PROTOCOL_VERSION); + case SSL_AD_INSUFFICIENT_SECURITY:return(TLS1_AD_INSUFFICIENT_SECURITY); + case SSL_AD_INTERNAL_ERROR: return(TLS1_AD_INTERNAL_ERROR); + case SSL_AD_USER_CANCLED: return(TLS1_AD_USER_CANCLED); + case SSL_AD_NO_RENEGOTIATION: return(TLS1_AD_NO_RENEGOTIATION); + default: return(-1); + } + } + diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c new file mode 100644 index 0000000000..f9fbfa414c --- /dev/null +++ b/ssl/t1_lib.c @@ -0,0 +1,151 @@ +/* ssl/t1_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "objects.h" +#include "ssl_locl.h" + +char *tls1_version_str="TLSv1 part of SSLeay 0.9.0b 29-Jun-1998"; + +#ifndef NO_PROTO +static long tls1_default_timeout(void); +#else +static long tls1_default_timeout(); +#endif + +static SSL3_ENC_METHOD TLSv1_enc_data={ + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + }; + +static SSL_METHOD TLSv1_data= { + TLS1_VERSION, + tls1_new, + tls1_clear, + tls1_free, + ssl_undefined_function, + ssl_undefined_function, + ssl3_read, + ssl3_peek, + ssl3_write, + ssl3_shutdown, + ssl3_renegotiate, + ssl3_ctrl, + ssl3_ctx_ctrl, + ssl3_get_cipher_by_char, + ssl3_put_cipher_by_char, + ssl3_pending, + ssl3_num_ciphers, + ssl3_get_cipher, + ssl_bad_method, + tls1_default_timeout, + &TLSv1_enc_data, + }; + +static long tls1_default_timeout() + { + /* 2 hours, the 24 hours mentioned in the TLSv1 spec + * is way too long for http, the cache would over fill */ + return(60*60*2); + } + +SSL_METHOD *tlsv1_base_method() + { + return(&TLSv1_data); + } + +int tls1_new(s) +SSL *s; + { + if (!ssl3_new(s)) return(0); + s->method->ssl_clear(s); + return(1); + } + +void tls1_free(s) +SSL *s; + { + ssl3_free(s); + } + +void tls1_clear(s) +SSL *s; + { + ssl3_clear(s); + s->version=TLS1_VERSION; + } + +#if 0 +long tls1_ctrl(s,cmd,larg,parg) +SSL *s; +int cmd; +long larg; +char *parg; + { + return(0); + } +#endif diff --git a/ssl/t1_meth.c b/ssl/t1_meth.c new file mode 100644 index 0000000000..512c2078e7 --- /dev/null +++ b/ssl/t1_meth.c @@ -0,0 +1,88 @@ +/* ssl/t1_meth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "objects.h" +#include "ssl_locl.h" + +static SSL_METHOD *tls1_get_method(ver) +int ver; + { + if (ver == TLS1_VERSION) + return(TLSv1_method()); + else + return(NULL); + } + +SSL_METHOD *TLSv1_method() + { + static int init=1; + static SSL_METHOD TLSv1_data; + + if (init) + { + init=0; + memcpy((char *)&TLSv1_data,(char *)tlsv1_base_method(), + sizeof(SSL_METHOD)); + TLSv1_data.ssl_connect=ssl3_connect; + TLSv1_data.ssl_accept=ssl3_accept; + TLSv1_data.get_ssl_method=tls1_get_method; + } + return(&TLSv1_data); + } + diff --git a/ssl/t1_srvr.c b/ssl/t1_srvr.c new file mode 100644 index 0000000000..8cf0addcd9 --- /dev/null +++ b/ssl/t1_srvr.c @@ -0,0 +1,91 @@ +/* ssl/t1_srvr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "buffer.h" +#include "rand.h" +#include "objects.h" +#include "evp.h" +#include "x509.h" +#include "ssl_locl.h" + +static SSL_METHOD *tls1_get_server_method(ver) +int ver; + { + if (ver == TLS1_VERSION) + return(TLSv1_server_method()); + else + return(NULL); + } + +SSL_METHOD *TLSv1_server_method() + { + static int init=1; + static SSL_METHOD TLSv1_server_data; + + if (init) + { + init=0; + memcpy((char *)&TLSv1_server_data,(char *)tlsv1_base_method(), + sizeof(SSL_METHOD)); + TLSv1_server_data.ssl_accept=ssl3_accept; + TLSv1_server_data.get_ssl_method=tls1_get_server_method; + } + return(&TLSv1_server_data); + } + diff --git a/ssl/tls1.h b/ssl/tls1.h new file mode 100644 index 0000000000..60978613ef --- /dev/null +++ b/ssl/tls1.h @@ -0,0 +1,115 @@ +/* ssl/tls1.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_TLS1_H +#define HEADER_TLS1_H + +#include "buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TLS1_VERSION 0x0301 +#define TLS1_VERSION_MAJOR 0x03 +#define TLS1_VERSION_MINOR 0x01 + +#define TLS1_AD_DECRYPTION_FAILED 21 +#define TLS1_AD_RECORD_OVERFLOW 22 +#define TLS1_AD_UNKNOWN_CA 48 /* fatal */ +#define TLS1_AD_ACCESS_DENIED 49 /* fatal */ +#define TLS1_AD_DECODE_ERROR 50 /* fatal */ +#define TLS1_AD_DECRYPT_ERROR 51 +#define TLS1_AD_EXPORT_RESTRICION 60 /* fatal */ +#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */ +#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */ +#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */ +#define TLS1_AD_USER_CANCLED 90 +#define TLS1_AD_NO_RENEGOTIATION 100 + +#define TLS_CT_RSA_SIGN 1 +#define TLS_CT_DSS_SIGN 2 +#define TLS_CT_RSA_FIXED_DH 3 +#define TLS_CT_DSS_FIXED_DH 4 +#define TLS_CT_NUMBER 4 + +#define TLS1_FINISH_MAC_LENGTH 12 + +#define TLS_MD_MAX_CONST_SIZE 20 +#define TLS_MD_CLIENT_FINISH_CONST "client finished" +#define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 +#define TLS_MD_SERVER_FINISH_CONST "server finished" +#define TLS_MD_SERVER_FINISH_CONST_SIZE 15 +#define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_KEY_EXPANSION_CONST "key expansion" +#define TLS_MD_KEY_EXPANSION_CONST_SIZE 13 +#define TLS_MD_CLIENT_WRITE_KEY_CONST "client write key" +#define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_IV_BLOCK_CONST "IV block" +#define TLS_MD_IV_BLOCK_CONST_SIZE 8 +#define TLS_MD_MASTER_SECRET_CONST "master secret" +#define TLS_MD_MASTER_SECRET_CONST_SIZE 13 + +#ifdef __cplusplus +} +#endif +#endif + |