Commit b56bce4f authored by Bodo Möller's avatar Bodo Möller
Browse files

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.
parent 0981259a
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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));

+8 −7
Original line number Diff line number Diff line
@@ -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
+21 −19
Original line number Diff line number Diff line
@@ -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);
+30 −6
Original line number Diff line number Diff line
@@ -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);

Loading