/* 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
#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="OpenSSL 0.9.2 31-Dec-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)
+int SSL_clear(s)
SSL *s;
{
int state;
- if (s->method == NULL) return;
+ if (s->method == NULL)
+ {
+ SSLerr(SSL_F_SSL_CLEAR,SSL_R_NO_METHOD_SPECIFIED);
+ return(0);
+ }
s->error=0;
s->hit=0;
+ s->shutdown=0;
+#if 0
/* This is set if we are doing dynamic renegotiation so keep
* the old cipher. It is sort of a SSL_clear_lite :-) */
- if (s->new_session) return;
+ if (s->new_session) return(1);
+#endif
state=s->state; /* Keep to check if we throw away the session-id */
s->type=0;
+ s->state=SSL_ST_BEFORE|((s->server)?SSL_ST_ACCEPT:SSL_ST_CONNECT);
+
s->version=s->method->version;
+ s->client_version=s->version;
s->rwstate=SSL_NOTHING;
- s->state=SSL_ST_BEFORE;
s->rstate=SSL_ST_READ_HEADER;
- s->read_ahead=s->ctx->default_read_ahead;
-
-/* s->shutdown=(SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); */
+ s->read_ahead=s->ctx->read_ahead;
if (s->init_buf != NULL)
{
s->session=NULL;
}
- s->shutdown=(SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
s->first_packet=0;
- s->method->ssl_clear(s);
+#if 1
+ /* Check to see if we were changed into a different method, if
+ * so, revert back if we are not doing session-id reuse. */
+ if ((s->session == NULL) && (s->method != s->ctx->method))
+ {
+ s->method->ssl_free(s);
+ s->method=s->ctx->method;
+ if (!s->method->ssl_new(s))
+ return(0);
+ }
+ else
+#endif
+ s->method->ssl_clear(s);
+ return(1);
}
/* Used to change an SSL_CTXs default SSL method type */
}
else
s->cert=NULL;
- s->verify_mode=ctx->default_verify_mode;
+ s->verify_mode=ctx->verify_mode;
s->verify_callback=ctx->default_verify_callback;
CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
s->ctx=ctx;
}
s->quiet_shutdown=ctx->quiet_shutdown;
+ s->references=1;
+ s->server=(ctx->method->ssl_accept == ssl_undefined_function)?0: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);
void SSL_free(s)
SSL *s;
{
+ int i;
+
+ if(s == NULL)
+ return;
+
+ 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 */
s->wbio=BIO_pop(s->wbio);
}
BIO_free(s->bbio);
+ s->bbio=NULL;
}
if (s->rbio != NULL)
BIO_free_all(s->rbio);
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);
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);
int SSL_CTX_get_verify_mode(ctx)
SSL_CTX *ctx;
{
- return(ctx->default_verify_mode);
+ return(ctx->verify_mode);
}
int (*SSL_CTX_get_verify_callback(ctx))()
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;
{
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;
{
int SSL_write(s,buf,num)
SSL *s;
-char *buf;
+const char *buf;
int num;
{
if (s->shutdown & SSL_SENT_SHUTDOWN)
int SSL_renegotiate(s)
SSL *s;
{
+ s->new_session=1;
return(s->method->ssl_renegotiate(s));
}
long larg;
char *parg;
{
- return(s->method->ssl_ctrl(s,cmd,larg,parg));
+ long l;
+
+ switch (cmd)
+ {
+ case SSL_CTRL_GET_READ_AHEAD:
+ return(s->read_ahead);
+ case SSL_CTRL_SET_READ_AHEAD:
+ l=s->read_ahead;
+ s->read_ahead=larg;
+ return(l);
+ case SSL_CTRL_OPTIONS:
+ return(s->options|=larg);
+ default:
+ return(s->method->ssl_ctrl(s,cmd,larg,parg));
+ }
+ return(0);
}
long SSL_CTX_ctrl(ctx,cmd,larg,parg)
long larg;
char *parg;
{
- return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg));
+ long l;
+
+ switch (cmd)
+ {
+ case SSL_CTRL_GET_READ_AHEAD:
+ return(ctx->read_ahead);
+ case SSL_CTRL_SET_READ_AHEAD:
+ l=ctx->read_ahead;
+ ctx->read_ahead=larg;
+ return(l);
+
+ case SSL_CTRL_SET_SESS_CACHE_SIZE:
+ l=ctx->session_cache_size;
+ ctx->session_cache_size=larg;
+ return(l);
+ case SSL_CTRL_GET_SESS_CACHE_SIZE:
+ return(ctx->session_cache_size);
+ case SSL_CTRL_SET_SESS_CACHE_MODE:
+ l=ctx->session_cache_mode;
+ ctx->session_cache_mode=larg;
+ return(l);
+ case SSL_CTRL_GET_SESS_CACHE_MODE:
+ return(ctx->session_cache_mode);
+
+ case SSL_CTRL_SESS_NUMBER:
+ return(ctx->sessions->num_items);
+ case SSL_CTRL_SESS_CONNECT:
+ return(ctx->stats.sess_connect);
+ case SSL_CTRL_SESS_CONNECT_GOOD:
+ return(ctx->stats.sess_connect_good);
+ case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
+ return(ctx->stats.sess_connect_renegotiate);
+ case SSL_CTRL_SESS_ACCEPT:
+ return(ctx->stats.sess_accept);
+ case SSL_CTRL_SESS_ACCEPT_GOOD:
+ return(ctx->stats.sess_accept_good);
+ case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
+ return(ctx->stats.sess_accept_renegotiate);
+ case SSL_CTRL_SESS_HIT:
+ return(ctx->stats.sess_hit);
+ case SSL_CTRL_SESS_CB_HIT:
+ return(ctx->stats.sess_cb_hit);
+ case SSL_CTRL_SESS_MISSES:
+ return(ctx->stats.sess_miss);
+ case SSL_CTRL_SESS_TIMEOUTS:
+ return(ctx->stats.sess_timeout);
+ case SSL_CTRL_SESS_CACHE_FULL:
+ return(ctx->stats.sess_cache_full);
+ case SSL_CTRL_OPTIONS:
+ return(ctx->options|=larg);
+ default:
+ return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg));
+ }
+ return(0);
}
int ssl_cipher_id_cmp(a,b)
{
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);
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);
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);
+ l=(unsigned long)
+ ((unsigned int) a->session_id[0] )|
+ ((unsigned int) a->session_id[1]<< 8L)|
+ ((unsigned long)a->session_id[2]<<16L)|
+ ((unsigned long)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)
SSL_METHOD *meth;
{
- SSL_CTX *ret;
+ SSL_CTX *ret=NULL;
if (meth == NULL)
{
SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_NULL_SSL_METHOD_PASSED);
return(NULL);
}
+
+ if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0)
+ {
+ SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
+ goto err;
+ }
ret=(SSL_CTX *)Malloc(sizeof(SSL_CTX));
if (ret == NULL)
goto err;
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();
ret->remove_session_cb=NULL;
ret->get_session_cb=NULL;
- ret->sess_connect=0;
- ret->sess_connect_good=0;
- ret->sess_accept=0;
- ret->sess_accept_good=0;
- ret->sess_miss=0;
- ret->sess_timeout=0;
- ret->sess_hit=0;
- ret->sess_cb_hit=0;
+ memset((char *)&ret->stats,0,sizeof(ret->stats));
ret->references=1;
ret->quiet_shutdown=0;
ret->app_verify_callback=NULL;
ret->app_verify_arg=NULL;
- ret->default_read_ahead=0;
- ret->default_verify_mode=SSL_VERIFY_NONE;
+ ret->read_ahead=0;
+ ret->verify_mode=SSL_VERIFY_NONE;
ret->default_verify_callback=NULL;
if ((ret->default_cert=ssl_cert_new()) == NULL)
goto err;
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;
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);
+
+ ret->extra_certs=NULL;
+ ret->comp_methods=SSL_COMP_get_compression_methods();
+
return(ret);
err:
SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE);
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)
abort(); /* ok */
}
#endif
+ CRYPTO_free_ex_data(ssl_ctx_meth,(char *)a,&a->ex_data);
if (a->sessions != NULL)
{
ssl_cert_free(a->default_cert);
if (a->client_CA != NULL)
sk_pop_free(a->client_CA,X509_NAME_free);
+ if (a->extra_certs != NULL)
+ sk_pop_free(a->extra_certs,X509_free);
+ if (a->comp_methods != NULL)
+ sk_pop_free(a->comp_methods,free);
Free((char *)a);
}
void SSL_CTX_set_verify(ctx,mode,cb)
SSL_CTX *ctx;
int mode;
+#ifndef NOPROTO
+int (*cb)(int, X509_STORE_CTX *);
+#else
int (*cb)();
+#endif
{
- ctx->default_verify_mode=mode;
+ ctx->verify_mode=mode;
ctx->default_verify_callback=cb;
/* This needs cleaning up EAY EAY EAY */
X509_STORE_set_verify_cb_func(ctx->cert_store,cb);
}
-void ssl_set_cert_masks(c)
+void ssl_set_cert_masks(c,cipher)
CERT *c;
+SSL_CIPHER *cipher;
{
CERT_PKEY *cpk;
int rsa_enc,rsa_tmp,rsa_sign,dh_tmp,dh_rsa,dh_dsa,dsa_sign;
int rsa_enc_export,dh_rsa_export,dh_dsa_export;
- int rsa_tmp_export,dh_tmp_export;
+ int rsa_tmp_export,dh_tmp_export,kl;
unsigned long mask,emask;
if ((c == NULL) || (c->valid)) return;
+ kl=SSL_C_EXPORT_PKEYLENGTH(cipher);
+
#ifndef NO_RSA
- rsa_tmp=((c->rsa_tmp != NULL) || (c->rsa_tmp_cb != NULL))?1:0;
- rsa_tmp_export=((c->rsa_tmp_cb != NULL) ||
- (rsa_tmp && (RSA_size(c->rsa_tmp)*8 <= 512)))?1:0;
+ rsa_tmp=(c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL);
+ rsa_tmp_export=(c->rsa_tmp_cb != NULL ||
+ (rsa_tmp && RSA_size(c->rsa_tmp)*8 <= kl));
#else
rsa_tmp=rsa_tmp_export=0;
#endif
#ifndef NO_DH
- dh_tmp=((c->dh_tmp != NULL) || (c->dh_tmp_cb != NULL))?1:0;
- dh_tmp_export=((c->dh_tmp_cb != NULL) ||
- (dh_tmp && (DH_size(c->dh_tmp)*8 <= 512)))?1:0;
+ dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
+ dh_tmp_export=(c->dh_tmp_cb != NULL ||
+ (dh_tmp && DH_size(c->dh_tmp)*8 <= kl));
#else
dh_tmp=dh_tmp_export=0;
#endif
cpk= &(c->pkeys[SSL_PKEY_RSA_ENC]);
- rsa_enc= ((cpk->x509 != NULL) && (cpk->privatekey != NULL))?1:0;
- rsa_enc_export=(rsa_enc && (EVP_PKEY_size(cpk->privatekey)*8 <= 512))?1:0;
+ rsa_enc= (cpk->x509 != NULL && cpk->privatekey != NULL);
+ rsa_enc_export=(rsa_enc && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
cpk= &(c->pkeys[SSL_PKEY_RSA_SIGN]);
- rsa_sign=((cpk->x509 != NULL) && (cpk->privatekey != NULL))?1:0;
+ rsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL);
cpk= &(c->pkeys[SSL_PKEY_DSA_SIGN]);
- dsa_sign=((cpk->x509 != NULL) && (cpk->privatekey != NULL))?1:0;
+ dsa_sign=(cpk->x509 != NULL && cpk->privatekey != NULL);
cpk= &(c->pkeys[SSL_PKEY_DH_RSA]);
- dh_rsa= ((cpk->x509 != NULL) && (cpk->privatekey != NULL))?1:0;
- dh_rsa_export=(dh_rsa && (EVP_PKEY_size(cpk->privatekey)*8 <= 512))?1:0;
+ dh_rsa= (cpk->x509 != NULL && cpk->privatekey != NULL);
+ dh_rsa_export=(dh_rsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
cpk= &(c->pkeys[SSL_PKEY_DH_DSA]);
/* FIX THIS EAY EAY EAY */
- dh_dsa= ((cpk->x509 != NULL) && (cpk->privatekey != NULL))?1:0;
- dh_dsa_export=(dh_dsa && (EVP_PKEY_size(cpk->privatekey)*8 <= 512))?1:0;
+ dh_dsa= (cpk->x509 != NULL && cpk->privatekey != NULL);
+ dh_dsa_export=(dh_dsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
mask=0;
emask=0;
int i,export;
c=s->cert;
- ssl_set_cert_masks(c);
+ ssl_set_cert_masks(c,s->s3->tmp.new_cipher);
alg=s->s3->tmp.new_cipher->algorithms;
- export=(alg & SSL_EXPORT)?1:0;
- mask=(export)?c->export_mask:c->mask;
+ export=SSL_IS_EXPORT(alg);
+ mask=export?c->export_mask:c->mask;
kalg=alg&(SSL_MKEY_MASK|SSL_AUTH_MASK);
if (kalg & SSL_kDHr)
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->stats.sess_connect_good
+ :s->ctx->stats.sess_accept_good) & 0xff) == 0xff)
+ {
+ SSL_CTX_flush_sessions(s->ctx,time(NULL));
+ }
+ }
}
SSL_METHOD *SSL_get_ssl_method(s)
int i;
{
int reason;
+ unsigned long l;
BIO *bio;
if (i > 0) return(SSL_ERROR_NONE);
- if (ERR_peek_error() != 0)
- return(SSL_ERROR_SSL);
+ /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake
+ * etc, where we do encode the error */
+ if ((l=ERR_peek_error()) != 0)
+ {
+ if (ERR_GET_LIB(l) == ERR_LIB_SYS)
+ return(SSL_ERROR_SYSCALL);
+ else
+ return(SSL_ERROR_SSL);
+ }
if ((i < 0) && SSL_want_read(s))
{
if (i == 0)
{
- if (s->version == 2)
+ if (s->version == SSL2_VERSION)
{
/* assume it is the socket being closed */
return(SSL_ERROR_ZERO_RETURN);
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);
}
}
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);
}
+
+ s->method->ssl_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
void SSL_set_accept_state(s)
SSL *s;
{
+ s->server=1;
s->shutdown=0;
s->state=SSL_ST_ACCEPT|SSL_ST_BEFORE;
s->handshake_func=s->method->ssl_accept;
void SSL_set_connect_state(s)
SSL *s;
{
+ s->server=0;
s->shutdown=0;
s->state=SSL_ST_CONNECT|SSL_ST_BEFORE;
s->handshake_func=s->method->ssl_connect;
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");
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)
{
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
ret->shutdown=s->shutdown;
ret->state=s->state;
ret->handshake_func=s->handshake_func;
+ ret->server=s->server;
if (0)
{
Free(s->enc_write_ctx);
s->enc_write_ctx=NULL;
}
+ if (s->expand != NULL)
+ {
+ COMP_CTX_free(s->expand);
+ s->expand=NULL;
+ }
+ if (s->compress != NULL)
+ {
+ COMP_CTX_free(s->compress);
+ s->compress=NULL;
+ }
}
+/* Fix this function so that it takes an optional type parameter */
X509 *SSL_get_certificate(s)
SSL *s;
{
return(NULL);
}
+/* Fix this function so that it takes an optional type parameter */
EVP_PKEY *SSL_get_privatekey(s)
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_free_wbio_buffer(s)
+SSL *s;
+ {
+ BIO *under;
+
+ if (s->bbio == NULL) return;
+
+ if (s->bbio == s->wbio)
+ {
+ /* remove buffering */
+ under=BIO_pop(s->wbio);
+ if (under != NULL)
+ s->wbio=under;
+ else
+ abort(); /* ok */
+ }
+ BIO_free(s->bbio);
+ s->bbio=NULL;
+ }
+
+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);
+ }
+
+#ifndef NO_STDIO
+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));
+ }
+#endif
+
+void SSL_set_info_callback(ssl,cb)
+SSL *ssl;
+void (*cb)();
+ {
+ ssl->info_callback=cb;
+ }
+
+void (*SSL_get_info_callback(ssl))()
+SSL *ssl;
+ {
+ return((void (*)())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;
+void *arg;
+ {
+ return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
+ }
+
+void *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;
+void *arg;
+ {
+ return(CRYPTO_set_ex_data(&s->ex_data,idx,arg));
+ }
+
+void *SSL_CTX_get_ex_data(s,idx)
+SSL_CTX *s;
+int idx;
+ {
+ return(CRYPTO_get_ex_data(&s->ex_data,idx));
+ }
+
+int ssl_ok(s)
+SSL *s;
+ {
+ return(1);
+ }
+
+X509_STORE *SSL_CTX_get_cert_store(ctx)
+SSL_CTX *ctx;
+ {
+ return(ctx->cert_store);
+ }
+
+void SSL_CTX_set_cert_store(ctx,store)
+SSL_CTX *ctx;
+X509_STORE *store;
+ {
+ if (ctx->cert_store != NULL)
+ X509_STORE_free(ctx->cert_store);
+ ctx->cert_store=store;
+ }
+
+int SSL_want(s)
+SSL *s;
+ {
+ return(s->rwstate);
+ }
+
+void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,RSA *(*cb)(SSL *ssl,int export,
+ int keylength))
+ { SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA_CB,0,(char *)cb); }
+
+void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int export,
+ int keylength))
+ { SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,0,(char *)dh); }
+
+#if defined(_WINDLL) && defined(WIN16)
+#include "../crypto/bio/bss_file.c"
+#endif
+