mirror of
https://github.com/openssl/openssl.git
synced 2025-03-19 19:50:42 +08:00
New structure type SESS_CERT used instead of CERT inside SSL_SESSION.
While modifying the sources, I found some inconsistencies on the use of s->cert vs. s->session->sess_cert; I don't know if those could really have caused problems, but possibly this is a proper bug-fix and not just a clean-up.
This commit is contained in:
parent
0981259ada
commit
b56bce4fc7
9
CHANGES
9
CHANGES
@ -50,11 +50,12 @@
|
||||
Changing settings for an SSL_CTX *ctx after having done s = SSL_new(ctx)
|
||||
does not influence s as it used to.
|
||||
|
||||
Projected further changes:
|
||||
In order to clean up things more thoroughly, inside SSL_SESSION
|
||||
we should not use CERT any longer, but a new structure SESS_CERT
|
||||
that holds per-session data, and CERT should hold only those
|
||||
values that can have meaningful defaults in an SSL_CTX.
|
||||
we don't use CERT any longer, but a new structure SESS_CERT
|
||||
that holds per-session data (if available); currently, this is
|
||||
the peer's certificate chain and, for clients, the server's certificate
|
||||
and temporary key. CERT holds only those values that can have
|
||||
meaningful defaults in an SSL_CTX.
|
||||
[Bodo Moeller]
|
||||
|
||||
*) New function X509V3_EXT_i2d() to create an X509_EXTENSION structure
|
||||
|
@ -158,6 +158,7 @@ extern int verify_depth;
|
||||
|
||||
static char *cipher=NULL;
|
||||
static int s_server_verify=SSL_VERIFY_NONE;
|
||||
static int s_server_session_id_context = 1; /* anything will do */
|
||||
static char *s_cert_file=TEST_CERT,*s_key_file=NULL;
|
||||
static char *s_dcert_file=NULL,*s_dkey_file=NULL;
|
||||
#ifdef FIONBIO
|
||||
@ -521,6 +522,8 @@ bad:
|
||||
if (cipher != NULL)
|
||||
SSL_CTX_set_cipher_list(ctx,cipher);
|
||||
SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
|
||||
SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
|
||||
sizeof s_server_session_id_context);
|
||||
|
||||
SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
|
||||
|
||||
|
@ -98,13 +98,14 @@ extern "C" {
|
||||
#define CRYPTO_LOCK_SSL_CTX 12
|
||||
#define CRYPTO_LOCK_SSL_CERT 13
|
||||
#define CRYPTO_LOCK_SSL_SESSION 14
|
||||
#define CRYPTO_LOCK_SSL 15
|
||||
#define CRYPTO_LOCK_RAND 16
|
||||
#define CRYPTO_LOCK_MALLOC 17
|
||||
#define CRYPTO_LOCK_BIO 18
|
||||
#define CRYPTO_LOCK_BIO_GETHOSTBYNAME 19
|
||||
#define CRYPTO_LOCK_RSA_BLINDING 20
|
||||
#define CRYPTO_NUM_LOCKS 21
|
||||
#define CRYPTO_LOCK_SSL_SESS_CERT 15
|
||||
#define CRYPTO_LOCK_SSL 16
|
||||
#define CRYPTO_LOCK_RAND 17
|
||||
#define CRYPTO_LOCK_MALLOC 18
|
||||
#define CRYPTO_LOCK_BIO 19
|
||||
#define CRYPTO_LOCK_BIO_GETHOSTBYNAME 20
|
||||
#define CRYPTO_LOCK_RSA_BLINDING 21
|
||||
#define CRYPTO_NUM_LOCKS 22
|
||||
|
||||
#define CRYPTO_LOCK 1
|
||||
#define CRYPTO_UNLOCK 2
|
||||
|
@ -72,7 +72,7 @@ static int client_hello(SSL *s);
|
||||
static int client_master_key(SSL *s);
|
||||
static int client_finished(SSL *s);
|
||||
static int client_certificate(SSL *s);
|
||||
static int ssl_rsa_public_encrypt(CERT *c, int len, unsigned char *from,
|
||||
static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
|
||||
unsigned char *to,int padding);
|
||||
#define BREAK break
|
||||
|
||||
@ -431,9 +431,10 @@ static int get_server_hello(SSL *s)
|
||||
s->session->cipher=sk_SSL_CIPHER_value(cl,i);
|
||||
}
|
||||
|
||||
if ((s->session != NULL) && (s->session->peer != NULL))
|
||||
if (s->session->peer != NULL)
|
||||
X509_free(s->session->peer);
|
||||
|
||||
#if 0 /* What is all this meant to accomplish?? */
|
||||
/* hmmm, can we have the problem of the other session with this
|
||||
* cert, Free's it before we increment the reference count. */
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509);
|
||||
@ -442,6 +443,11 @@ static int get_server_hello(SSL *s)
|
||||
/*CRYPTO_add(&s->session->peer->references,1,CRYPTO_LOCK_X509);*/
|
||||
s->session->peer->references++;
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
|
||||
#else
|
||||
s->session->peer = s->session->sess_cert->peer_key->x509;
|
||||
/* peer_key->x509 has been set by ssl2_set_certificate. */
|
||||
CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509);
|
||||
#endif
|
||||
|
||||
s->s2->conn_id_length=s->s2->tmp.conn_id_length;
|
||||
memcpy(s->s2->conn_id,p,s->s2->tmp.conn_id_length);
|
||||
@ -733,7 +739,7 @@ static int client_certificate(SSL *s)
|
||||
EVP_SignUpdate(&ctx,s->s2->key_material,
|
||||
(unsigned int)s->s2->key_material_length);
|
||||
EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len);
|
||||
n=i2d_X509(s->session->sess_cert->key->x509,&p);
|
||||
n=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
|
||||
EVP_SignUpdate(&ctx,buf,(unsigned int)n);
|
||||
|
||||
p=buf;
|
||||
@ -874,7 +880,7 @@ int ssl2_set_certificate(SSL *s, int type, int len, unsigned char *data)
|
||||
{
|
||||
STACK_OF(X509) *sk=NULL;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
CERT *c=NULL;
|
||||
SESS_CERT *sc=NULL;
|
||||
int i;
|
||||
X509 *x509=NULL;
|
||||
int ret=0;
|
||||
@ -900,22 +906,18 @@ int ssl2_set_certificate(SSL *s, int type, int len, unsigned char *data)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* cert for ssl */
|
||||
c=ssl_cert_new();
|
||||
if (c == NULL)
|
||||
/* server's cert for this session */
|
||||
sc=ssl_sess_cert_new();
|
||||
if (sc == NULL)
|
||||
{
|
||||
ret= -1;
|
||||
goto err;
|
||||
}
|
||||
if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
|
||||
s->session->sess_cert=sc;
|
||||
|
||||
/* cert for session */
|
||||
if (s->session->sess_cert) ssl_cert_free(s->session->sess_cert);
|
||||
s->session->sess_cert=c;
|
||||
|
||||
/* c->cert_type=type; */
|
||||
|
||||
c->pkeys[SSL_PKEY_RSA_ENC].x509=x509;
|
||||
c->key= &(c->pkeys[SSL_PKEY_RSA_ENC]);
|
||||
sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509=x509;
|
||||
sc->peer_key= &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]);
|
||||
|
||||
pkey=X509_get_pubkey(x509);
|
||||
x509=NULL;
|
||||
@ -930,7 +932,7 @@ int ssl2_set_certificate(SSL *s, int type, int len, unsigned char *data)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ssl_set_cert_type(c,SSL2_CT_X509_CERTIFICATE))
|
||||
if (!ssl_set_peer_cert_type(sc,SSL2_CT_X509_CERTIFICATE))
|
||||
goto err;
|
||||
ret=1;
|
||||
err:
|
||||
@ -940,14 +942,14 @@ err:
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static int ssl_rsa_public_encrypt(CERT *c, int len, unsigned char *from,
|
||||
static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
|
||||
unsigned char *to, int padding)
|
||||
{
|
||||
EVP_PKEY *pkey=NULL;
|
||||
int i= -1;
|
||||
|
||||
if ((c == NULL) || (c->key->x509 == NULL) ||
|
||||
((pkey=X509_get_pubkey(c->key->x509)) == NULL))
|
||||
if ((sc == NULL) || (sc->peer_key->x509 == NULL) ||
|
||||
((pkey=X509_get_pubkey(sc->peer_key->x509)) == NULL))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_NO_PUBLICKEY);
|
||||
return(-1);
|
||||
|
@ -122,8 +122,7 @@ int ssl2_accept(SSL *s)
|
||||
if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
|
||||
s->in_handshake++;
|
||||
|
||||
if (((s->session == NULL) || (s->session->sess_cert == NULL)) &&
|
||||
(s->cert == NULL))
|
||||
if (s->cert == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
|
||||
return(-1);
|
||||
@ -376,7 +375,7 @@ static int get_client_master_key(SSL *s)
|
||||
memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]),
|
||||
(unsigned int)keya);
|
||||
|
||||
if (s->session->sess_cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)
|
||||
if (s->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);
|
||||
@ -600,6 +599,30 @@ static int server_hello(SSL *s)
|
||||
*(p++)=SSL2_MT_SERVER_HELLO; /* type */
|
||||
hit=s->hit;
|
||||
*(p++)=(unsigned char)hit;
|
||||
#if 1
|
||||
if (!hit)
|
||||
{
|
||||
if (s->session->sess_cert != NULL)
|
||||
/* This can't really happen because get_client_hello
|
||||
* has called ssl_get_new_session, which does not set
|
||||
* sess_cert. */
|
||||
ssl_sess_cert_free(s->session->sess_cert);
|
||||
s->session->sess_cert = ssl_sess_cert_new();
|
||||
if (s->session->sess_cert == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
/* If 'hit' is set, then s->sess_cert may be non-NULL or NULL,
|
||||
* depending on whether it survived in the internal cache
|
||||
* or was retrieved from an external cache.
|
||||
* If it is NULL, we cannot put any useful data in it anyway,
|
||||
* so we don't touch it.
|
||||
*/
|
||||
|
||||
#else /* That's what used to be done when cert_st and sess_cert_st were
|
||||
* the same. */
|
||||
if (!hit)
|
||||
{ /* else add cert to session */
|
||||
CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
|
||||
@ -619,8 +642,9 @@ static int server_hello(SSL *s)
|
||||
s->session->sess_cert=s->cert;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s->session->sess_cert == NULL)
|
||||
if (s->cert == NULL)
|
||||
{
|
||||
ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
|
||||
SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED);
|
||||
@ -873,7 +897,7 @@ static int request_certificate(SSL *s)
|
||||
(unsigned int)s->s2->key_material_length);
|
||||
EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
|
||||
|
||||
i=i2d_X509(s->session->sess_cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
|
||||
i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
|
||||
buf2=(unsigned char *)Malloc((unsigned int)i);
|
||||
if (buf2 == NULL)
|
||||
{
|
||||
@ -881,7 +905,7 @@ static int request_certificate(SSL *s)
|
||||
goto msg_end;
|
||||
}
|
||||
p2=buf2;
|
||||
i=i2d_X509(s->session->sess_cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
|
||||
i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
|
||||
EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
|
||||
Free(buf2);
|
||||
|
||||
|
@ -679,7 +679,7 @@ static int ssl3_get_server_certificate(SSL *s)
|
||||
X509 *x=NULL;
|
||||
unsigned char *p,*d,*q;
|
||||
STACK_OF(X509) *sk=NULL;
|
||||
CERT *c;
|
||||
SESS_CERT *sc;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
|
||||
n=ssl3_get_message(s,
|
||||
@ -764,13 +764,13 @@ static int ssl3_get_server_certificate(SSL *s)
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
c=ssl_cert_new();
|
||||
if (c == NULL) goto err;
|
||||
sc=ssl_sess_cert_new();
|
||||
if (sc == NULL) goto err;
|
||||
|
||||
if (s->session->sess_cert) ssl_cert_free(s->session->sess_cert);
|
||||
s->session->sess_cert=c;
|
||||
if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
|
||||
s->session->sess_cert=sc;
|
||||
|
||||
c->cert_chain=sk;
|
||||
sc->cert_chain=sk;
|
||||
x=sk_X509_value(sk,0);
|
||||
sk=NULL;
|
||||
|
||||
@ -793,14 +793,16 @@ static int ssl3_get_server_certificate(SSL *s)
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
c->cert_type=i;
|
||||
sc->peer_cert_type=i;
|
||||
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;
|
||||
c->key= &(c->pkeys[i]);
|
||||
if (sc->peer_pkeys[i].x509 != NULL) /* Why would this ever happen?
|
||||
* We just created sc a couple of
|
||||
* lines ago. */
|
||||
X509_free(sc->peer_pkeys[i].x509);
|
||||
sc->peer_pkeys[i].x509=x;
|
||||
sc->peer_key= &(sc->peer_pkeys[i]);
|
||||
|
||||
if ((s->session != NULL) && (s->session->peer != NULL))
|
||||
if (s->session->peer != NULL)
|
||||
X509_free(s->session->peer);
|
||||
CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
|
||||
s->session->peer=x;
|
||||
@ -857,23 +859,23 @@ static int ssl3_get_key_exchange(SSL *s)
|
||||
if (s->session->sess_cert != NULL)
|
||||
{
|
||||
#ifndef NO_RSA
|
||||
if (s->session->sess_cert->rsa_tmp != NULL)
|
||||
if (s->session->sess_cert->peer_rsa_tmp != NULL)
|
||||
{
|
||||
RSA_free(s->session->sess_cert->rsa_tmp);
|
||||
s->session->sess_cert->rsa_tmp=NULL;
|
||||
RSA_free(s->session->sess_cert->peer_rsa_tmp);
|
||||
s->session->sess_cert->peer_rsa_tmp=NULL;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_DH
|
||||
if (s->session->sess_cert->dh_tmp)
|
||||
if (s->session->sess_cert->peer_dh_tmp)
|
||||
{
|
||||
DH_free(s->session->sess_cert->dh_tmp);
|
||||
s->session->sess_cert->dh_tmp=NULL;
|
||||
DH_free(s->session->sess_cert->peer_dh_tmp);
|
||||
s->session->sess_cert->peer_dh_tmp=NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
s->session->sess_cert=ssl_cert_new();
|
||||
s->session->sess_cert=ssl_sess_cert_new();
|
||||
}
|
||||
|
||||
param_len=0;
|
||||
@ -920,13 +922,13 @@ static int ssl3_get_key_exchange(SSL *s)
|
||||
|
||||
/* this should be because we are using an export cipher */
|
||||
if (alg & SSL_aRSA)
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->pkeys[SSL_PKEY_RSA_ENC].x509);
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
|
||||
else
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
s->session->sess_cert->rsa_tmp=rsa;
|
||||
s->session->sess_cert->peer_rsa_tmp=rsa;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -986,16 +988,16 @@ static int ssl3_get_key_exchange(SSL *s)
|
||||
|
||||
#ifndef NO_RSA
|
||||
if (alg & SSL_aRSA)
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->pkeys[SSL_PKEY_RSA_ENC].x509);
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
|
||||
else
|
||||
#endif
|
||||
#ifndef NO_DSA
|
||||
if (alg & SSL_aDSS)
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->pkeys[SSL_PKEY_DSA_SIGN].x509);
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
|
||||
#endif
|
||||
/* else anonymous DH, so no certificate or pkey. */
|
||||
|
||||
s->session->sess_cert->dh_tmp=dh;
|
||||
s->session->sess_cert->peer_dh_tmp=dh;
|
||||
dh=NULL;
|
||||
}
|
||||
else if ((alg & SSL_kDHr) || (alg & SSL_kDHd))
|
||||
@ -1311,11 +1313,11 @@ static int ssl3_send_client_key_exchange(SSL *s)
|
||||
RSA *rsa;
|
||||
unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
|
||||
|
||||
if (s->session->sess_cert->rsa_tmp != NULL)
|
||||
rsa=s->session->sess_cert->rsa_tmp;
|
||||
if (s->session->sess_cert->peer_rsa_tmp != NULL)
|
||||
rsa=s->session->sess_cert->peer_rsa_tmp;
|
||||
else
|
||||
{
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->pkeys[SSL_PKEY_RSA_ENC].x509);
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
|
||||
if ((pkey == NULL) ||
|
||||
(pkey->type != EVP_PKEY_RSA) ||
|
||||
(pkey->pkey.rsa == NULL))
|
||||
@ -1368,8 +1370,8 @@ static int ssl3_send_client_key_exchange(SSL *s)
|
||||
{
|
||||
DH *dh_srvr,*dh_clnt;
|
||||
|
||||
if (s->session->sess_cert->dh_tmp != NULL)
|
||||
dh_srvr=s->session->sess_cert->dh_tmp;
|
||||
if (s->session->sess_cert->peer_dh_tmp != NULL)
|
||||
dh_srvr=s->session->sess_cert->peer_dh_tmp;
|
||||
else
|
||||
{
|
||||
/* we get them from the cert */
|
||||
@ -1597,7 +1599,7 @@ static int ssl3_check_cert_and_algorithm(SSL *s)
|
||||
int i,idx;
|
||||
long algs;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
CERT *c;
|
||||
SESS_CERT *sc;
|
||||
#ifndef NO_RSA
|
||||
RSA *rsa;
|
||||
#endif
|
||||
@ -1605,9 +1607,9 @@ static int ssl3_check_cert_and_algorithm(SSL *s)
|
||||
DH *dh;
|
||||
#endif
|
||||
|
||||
c=s->session->sess_cert;
|
||||
sc=s->session->sess_cert;
|
||||
|
||||
if (c == NULL)
|
||||
if (sc == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
@ -1620,17 +1622,17 @@ static int ssl3_check_cert_and_algorithm(SSL *s)
|
||||
return(1);
|
||||
|
||||
#ifndef NO_RSA
|
||||
rsa=s->session->sess_cert->rsa_tmp;
|
||||
rsa=s->session->sess_cert->peer_rsa_tmp;
|
||||
#endif
|
||||
#ifndef NO_DH
|
||||
dh=s->session->sess_cert->dh_tmp;
|
||||
dh=s->session->sess_cert->peer_dh_tmp;
|
||||
#endif
|
||||
|
||||
/* This is the passed certificate */
|
||||
|
||||
idx=c->cert_type;
|
||||
pkey=X509_get_pubkey(c->pkeys[idx].x509);
|
||||
i=X509_certificate_type(c->pkeys[idx].x509,pkey);
|
||||
idx=sc->peer_cert_type;
|
||||
pkey=X509_get_pubkey(sc->peer_pkeys[idx].x509);
|
||||
i=X509_certificate_type(sc->peer_pkeys[idx].x509,pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
|
||||
|
@ -110,7 +110,6 @@ int ssl3_accept(SSL *s)
|
||||
void (*cb)()=NULL;
|
||||
long num1;
|
||||
int ret= -1;
|
||||
CERT *ct;
|
||||
int new_state,state,skip=0;
|
||||
|
||||
RAND_seed(&Time,sizeof(Time));
|
||||
@ -126,17 +125,11 @@ int ssl3_accept(SSL *s)
|
||||
if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
|
||||
s->in_handshake++;
|
||||
|
||||
#ifdef undef
|
||||
/* FIX THIS EAY EAY EAY */
|
||||
/* we don't actually need a cert, we just need a cert or a DH_tmp */
|
||||
if (((s->session == NULL) || (s->session->sess_cert == NULL)) &&
|
||||
(s->cert == NULL))
|
||||
if (s->cert == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
|
||||
ret= -1;
|
||||
goto end;
|
||||
return(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -261,15 +254,6 @@ int ssl3_accept(SSL *s)
|
||||
case SSL3_ST_SW_KEY_EXCH_A:
|
||||
case SSL3_ST_SW_KEY_EXCH_B:
|
||||
l=s->s3->tmp.new_cipher->algorithms;
|
||||
if (s->session->sess_cert == NULL)
|
||||
{
|
||||
if (s->cert != NULL)
|
||||
{
|
||||
CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
|
||||
s->session->sess_cert=s->cert;
|
||||
}
|
||||
}
|
||||
ct=s->session->sess_cert;
|
||||
|
||||
/* clear this, it may get reset by
|
||||
* send_server_key_exchange */
|
||||
@ -283,9 +267,9 @@ int ssl3_accept(SSL *s)
|
||||
if (s->s3->tmp.use_rsa_tmp
|
||||
|| (l & (SSL_DH|SSL_kFZA))
|
||||
|| ((l & SSL_kRSA)
|
||||
&& (ct->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
|
||||
&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
|
||||
|| (SSL_IS_EXPORT(l)
|
||||
&& EVP_PKEY_size(ct->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_EXPORT_PKEYLENGTH(l)
|
||||
&& EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_EXPORT_PKEYLENGTH(l)
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -898,7 +882,7 @@ static int ssl3_send_server_key_exchange(SSL *s)
|
||||
if (s->state == SSL3_ST_SW_KEY_EXCH_A)
|
||||
{
|
||||
type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK;
|
||||
cert=s->session->sess_cert;
|
||||
cert=s->cert;
|
||||
|
||||
buf=s->init_buf;
|
||||
|
||||
@ -1207,11 +1191,7 @@ static int ssl3_get_client_key_exchange(SSL *s)
|
||||
/* FIX THIS UP EAY EAY EAY EAY */
|
||||
if (s->s3->tmp.use_rsa_tmp)
|
||||
{
|
||||
if ((s->session->sess_cert != NULL) &&
|
||||
(s->session->sess_cert->rsa_tmp != NULL))
|
||||
rsa=s->session->sess_cert->rsa_tmp;
|
||||
else if ((s->cert != NULL) &&
|
||||
(s->cert->rsa_tmp != NULL))
|
||||
if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL))
|
||||
rsa=s->cert->rsa_tmp;
|
||||
/* Don't do a callback because rsa_tmp should
|
||||
* be sent already */
|
||||
@ -1643,11 +1623,23 @@ static int ssl3_get_client_certificate(SSL *s)
|
||||
}
|
||||
}
|
||||
|
||||
/* This should not be needed */
|
||||
if (s->session->peer != NULL)
|
||||
if (s->session->peer != NULL) /* This should not be needed */
|
||||
X509_free(s->session->peer);
|
||||
s->session->peer=sk_X509_shift(sk);
|
||||
|
||||
/* With the current implementation, sess_cert will always be NULL
|
||||
* when we arrive here. */
|
||||
if (s->session->sess_cert == NULL)
|
||||
{
|
||||
s->session->sess_cert = ssl_sess_cert_new();
|
||||
if (s->session->sess_cert == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (s->session->sess_cert->cert_chain != NULL)
|
||||
sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free);
|
||||
s->session->sess_cert->cert_chain=sk;
|
||||
|
||||
sk=NULL;
|
||||
|
@ -241,11 +241,10 @@ typedef struct ssl_session_st
|
||||
int not_resumable;
|
||||
|
||||
/* The cert is the certificate used to establish this connection */
|
||||
struct cert_st /* CERT */ *sess_cert;
|
||||
/* XXX should be struct sess_cert_st *sess_cert */
|
||||
struct sess_cert_st /* SESS_CERT */ *sess_cert;
|
||||
|
||||
/* This is the cert for the other end.
|
||||
* On clients, it will be the same as sess_cert->key->x509
|
||||
* On clients, it will be the same as sess_cert->peer_key->x509
|
||||
* (the latter is not enough as sess_cert is not retained
|
||||
* in the external representation of sessions, see ssl_asn1.c). */
|
||||
X509 *peer;
|
||||
@ -1215,6 +1214,7 @@ int SSL_COMP_add_compression_method(int id,char *cm);
|
||||
#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188
|
||||
#define SSL_F_SSL_SESSION_NEW 189
|
||||
#define SSL_F_SSL_SESSION_PRINT_FP 190
|
||||
#define SSL_F_SSL_SESS_CERT_NEW 225
|
||||
#define SSL_F_SSL_SET_CERT 191
|
||||
#define SSL_F_SSL_SET_FD 192
|
||||
#define SSL_F_SSL_SET_PKEY 193
|
||||
|
@ -318,12 +318,9 @@ void ssl_cert_free(CERT *c)
|
||||
EVP_PKEY_free(c->pkeys[i].publickey);
|
||||
#endif
|
||||
}
|
||||
if (c->cert_chain != NULL)
|
||||
sk_X509_pop_free(c->cert_chain,X509_free);
|
||||
Free(c);
|
||||
}
|
||||
|
||||
#if 1
|
||||
int ssl_cert_inst(CERT **o)
|
||||
{
|
||||
/* Create a CERT if there isn't already one
|
||||
@ -352,32 +349,76 @@ int ssl_cert_inst(CERT **o)
|
||||
return(1);
|
||||
}
|
||||
|
||||
#else /* Not needed any longer: SSL's always have their own copy */
|
||||
int ssl_cert_instantiate(CERT **o, CERT *d)
|
||||
|
||||
SESS_CERT *ssl_sess_cert_new(void)
|
||||
{
|
||||
CERT *n;
|
||||
if (o == NULL)
|
||||
SESS_CERT *ret;
|
||||
|
||||
ret = Malloc(sizeof *ret);
|
||||
if (ret == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CERT_INSTANTIATE, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return(0);
|
||||
SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (*o != NULL && (d == NULL || *o != d))
|
||||
return(1);
|
||||
if ((n = ssl_cert_new()) == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CERT_INSTANTIATE, ERR_R_MALLOC_FAILURE);
|
||||
return(0);
|
||||
}
|
||||
if (*o != NULL)
|
||||
ssl_cert_free(*o);
|
||||
*o = n;
|
||||
return(1);
|
||||
|
||||
memset(ret, 0 ,sizeof *ret);
|
||||
ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
|
||||
ret->references = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ssl_sess_cert_free(SESS_CERT *sc)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (sc == NULL)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
|
||||
#ifdef REF_PRINT
|
||||
REF_PRINT("SESS_CERT", sc);
|
||||
#endif
|
||||
if (i > 0)
|
||||
return;
|
||||
#ifdef REF_CHECK
|
||||
if (i < 0)
|
||||
{
|
||||
fprintf(stderr,"ssl_sess_cert_free, bad reference count\n");
|
||||
abort(); /* ok */
|
||||
}
|
||||
#endif
|
||||
|
||||
int ssl_set_cert_type(CERT *c,int type)
|
||||
/* i == 0 */
|
||||
if (sc->cert_chain != NULL)
|
||||
sk_X509_pop_free(sc->cert_chain, X509_free);
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++)
|
||||
{
|
||||
if (sc->peer_pkeys[i].x509 != NULL)
|
||||
X509_free(sc->peer_pkeys[i].x509);
|
||||
#if 0 /* We don't have the peer's private key. These lines are just
|
||||
* here as a reminder that we're still using a not-quite-appropriate
|
||||
* data structure. */
|
||||
if (sc->peer_pkeys[i].privatekey != NULL)
|
||||
EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NO_RSA
|
||||
if (sc->peer_rsa_tmp != NULL)
|
||||
RSA_free(sc->peer_rsa_tmp);
|
||||
#endif
|
||||
#ifndef NO_DH
|
||||
if (sc->peer_dh_tmp != NULL)
|
||||
DH_free(sc->peer_dh_tmp);
|
||||
#endif
|
||||
|
||||
Free(sc);
|
||||
}
|
||||
|
||||
int ssl_set_peer_cert_type(SESS_CERT *sc,int type)
|
||||
{
|
||||
c->cert_type=type;
|
||||
sc->peer_cert_type = type;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -165,6 +165,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{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_SESS_CERT_NEW,0), "SSL_SESS_CERT_NEW"},
|
||||
{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"},
|
||||
|
@ -275,18 +275,31 @@ typedef struct cert_st
|
||||
|
||||
CERT_PKEY pkeys[SSL_PKEY_NUM];
|
||||
|
||||
STACK_OF(X509) *cert_chain; /* XXX should only exist in sess_cert_st */
|
||||
|
||||
int references; /* >1 only if SSL_copy_session_id is used */
|
||||
} CERT;
|
||||
|
||||
|
||||
#if 0 /* XXX not yet */
|
||||
typedef struct sess_cert_st
|
||||
{
|
||||
/* anything that we want to keep per session */
|
||||
} SESS_CERT;
|
||||
{
|
||||
STACK_OF(X509) *cert_chain; /* as received from peer (not for SSL2) */
|
||||
|
||||
/* The 'peer_...' members are used only by clients. */
|
||||
int peer_cert_type;
|
||||
|
||||
CERT_PKEY *peer_key; /* points to an element of peer_pkeys (never NULL!) */
|
||||
CERT_PKEY peer_pkeys[SSL_PKEY_NUM];
|
||||
/* Obviously we don't have the private keys of these,
|
||||
* so maybe we shouldn't even use the CERT_PKEY type here. */
|
||||
|
||||
#ifndef NO_RSA
|
||||
RSA *peer_rsa_tmp; /* not used for SSL 2 */
|
||||
#endif
|
||||
#ifndef NO_DH
|
||||
DH *peer_dh_tmp; /* not used for SSL 2 */
|
||||
#endif
|
||||
|
||||
int references; /* actually always 1 at the moment */
|
||||
} SESS_CERT;
|
||||
|
||||
|
||||
/*#define MAC_DEBUG */
|
||||
@ -353,13 +366,11 @@ void ssl_clear_cipher_ctx(SSL *s);
|
||||
int ssl_clear_bad_session(SSL *s);
|
||||
CERT *ssl_cert_new(void);
|
||||
CERT *ssl_cert_dup(CERT *cert);
|
||||
#if 1
|
||||
int ssl_cert_inst(CERT **o);
|
||||
#else
|
||||
int ssl_cert_instantiate(CERT **o, CERT *d);
|
||||
#endif
|
||||
void ssl_cert_free(CERT *c);
|
||||
int ssl_set_cert_type(CERT *c, int type);
|
||||
SESS_CERT *ssl_sess_cert_new(void);
|
||||
void ssl_sess_cert_free(SESS_CERT *sc);
|
||||
int ssl_set_peer_cert_type(SESS_CERT *c, int type);
|
||||
int ssl_get_new_session(SSL *s, int session);
|
||||
int ssl_get_prev_session(SSL *s, unsigned char *session,int len);
|
||||
int ssl_cipher_id_cmp(SSL_CIPHER *a,SSL_CIPHER *b);
|
||||
|
@ -115,6 +115,8 @@ SSL_SESSION *SSL_SESSION_new(void)
|
||||
|
||||
int ssl_get_new_session(SSL *s, int session)
|
||||
{
|
||||
/* This gets used by clients and servers. */
|
||||
|
||||
SSL_SESSION *ss=NULL;
|
||||
|
||||
if ((ss=SSL_SESSION_new()) == NULL) return(0);
|
||||
@ -183,6 +185,8 @@ int ssl_get_new_session(SSL *s, int session)
|
||||
|
||||
int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
|
||||
{
|
||||
/* This is used only by servers. */
|
||||
|
||||
SSL_SESSION *ret=NULL,data;
|
||||
int copy=1;
|
||||
|
||||
@ -377,7 +381,7 @@ void SSL_SESSION_free(SSL_SESSION *ss)
|
||||
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);
|
||||
if (ss->sess_cert != NULL) ssl_cert_free(ss->sess_cert);
|
||||
if (ss->sess_cert != NULL) ssl_sess_cert_free(ss->sess_cert);
|
||||
if (ss->peer != NULL) X509_free(ss->peer);
|
||||
if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers);
|
||||
memset(ss,0,sizeof(*ss));
|
||||
|
Loading…
x
Reference in New Issue
Block a user