No actual change, but the cert_st member of struct ssl_session_st is now
called sess_cert instead of just cert.  This is in preparation of further
changes: Probably often when s->session->sess_cert is used, we should
use s->cert instead; s->session->sess_cert should be a new structure
containing only the stuff that is for just one connection (e.g.
the peer's certificate, which the SSL client implementations currently
store in s->session->[sess_]cert, which is a very confusing thing to do).
Submitted by:
Reviewed by:
PR:
diff --git a/ssl/s2_clnt.c b/ssl/s2_clnt.c
index 600d8c3..0f188ec 100644
--- a/ssl/s2_clnt.c
+++ b/ssl/s2_clnt.c
@@ -437,7 +437,7 @@
 	/* 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);
-	s->session->peer=s->session->cert->key->x509;
+	s->session->peer=s->session->sess_cert->key->x509;
 	/* Shouldn't do this: already locked */
 	/*CRYPTO_add(&s->session->peer->references,1,CRYPTO_LOCK_X509);*/
 	s->session->peer->references++;
@@ -570,7 +570,7 @@
 		memcpy(d,sess->master_key,(unsigned int)clear);
 		d+=clear;
 
-		enc=ssl_rsa_public_encrypt(sess->cert,enc,
+		enc=ssl_rsa_public_encrypt(sess->sess_cert,enc,
 			&(sess->master_key[clear]),d,
 			(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
 		if (enc <= 0)
@@ -733,7 +733,7 @@
 		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->cert->key->x509,&p);
+		n=i2d_X509(s->session->sess_cert->key->x509,&p);
 		EVP_SignUpdate(&ctx,buf,(unsigned int)n);
 
 		p=buf;
@@ -909,8 +909,8 @@
 		}
 
 	/* cert for session */
-	if (s->session->cert) ssl_cert_free(s->session->cert);
-	s->session->cert=c;
+	if (s->session->sess_cert) ssl_cert_free(s->session->sess_cert);
+	s->session->sess_cert=c;
 
 /*	c->cert_type=type; */
 
diff --git a/ssl/s2_srvr.c b/ssl/s2_srvr.c
index e7eff6f..d5bf0dd 100644
--- a/ssl/s2_srvr.c
+++ b/ssl/s2_srvr.c
@@ -122,7 +122,7 @@
 	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
 	s->in_handshake++;
 
-	if (((s->session == NULL) || (s->session->cert == NULL)) &&
+	if (((s->session == NULL) || (s->session->sess_cert == NULL)) &&
 		(s->cert == NULL))
 		{
 		SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
@@ -376,7 +376,7 @@
 	memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]),
 		(unsigned int)keya);
 
-	if (s->session->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)
+	if (s->session->sess_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);
@@ -603,24 +603,24 @@
 		if (!hit)
 			{			/* else add cert to session */
 			CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
-			if (s->session->cert != NULL)
-				ssl_cert_free(s->session->cert);
-			s->session->cert=s->cert;		
+			if (s->session->sess_cert != NULL)
+				ssl_cert_free(s->session->sess_cert);
+			s->session->sess_cert=s->cert;		
 			}
 		else	/* We have a session id-cache hit, if the
 			 * session-id has no certificate listed against
 			 * the 'cert' structure, grab the 'old' one
 			 * listed against the SSL connection */
 			{
-			if (s->session->cert == NULL)
+			if (s->session->sess_cert == NULL)
 				{
 				CRYPTO_add(&s->cert->references,1,
 					CRYPTO_LOCK_SSL_CERT);
-				s->session->cert=s->cert;
+				s->session->sess_cert=s->cert;
 				}
 			}
 
-		if (s->session->cert == NULL)
+		if (s->session->sess_cert == NULL)
 			{
 			ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
 			SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED);
@@ -873,7 +873,7 @@
 			(unsigned int)s->s2->key_material_length);
 		EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
 
-		i=i2d_X509(s->session->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
+		i=i2d_X509(s->session->sess_cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
 		buf2=(unsigned char *)Malloc((unsigned int)i);
 		if (buf2 == NULL)
 			{
@@ -881,7 +881,7 @@
 			goto msg_end;
 			}
 		p2=buf2;
-		i=i2d_X509(s->session->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
+		i=i2d_X509(s->session->sess_cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
 		EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
 		Free(buf2);
 
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index e0871c4..98c1f18 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -767,8 +767,8 @@
 	c=ssl_cert_new();
 	if (c == NULL) goto err;
 
-	if (s->session->cert) ssl_cert_free(s->session->cert);
-	s->session->cert=c;
+	if (s->session->sess_cert) ssl_cert_free(s->session->sess_cert);
+	s->session->sess_cert=c;
 
 	c->cert_chain=sk;
 	x=sk_X509_value(sk,0);
@@ -854,26 +854,26 @@
 
 	param=p=(unsigned char *)s->init_buf->data;
 
-	if (s->session->cert != NULL)
+	if (s->session->sess_cert != NULL)
 		{
 #ifndef NO_RSA
-		if (s->session->cert->rsa_tmp != NULL)
+		if (s->session->sess_cert->rsa_tmp != NULL)
 			{
-			RSA_free(s->session->cert->rsa_tmp);
-			s->session->cert->rsa_tmp=NULL;
+			RSA_free(s->session->sess_cert->rsa_tmp);
+			s->session->sess_cert->rsa_tmp=NULL;
 			}
 #endif
 #ifndef NO_DH
-		if (s->session->cert->dh_tmp)
+		if (s->session->sess_cert->dh_tmp)
 			{
-			DH_free(s->session->cert->dh_tmp);
-			s->session->cert->dh_tmp=NULL;
+			DH_free(s->session->sess_cert->dh_tmp);
+			s->session->sess_cert->dh_tmp=NULL;
 			}
 #endif
 		}
 	else
 		{
-		s->session->cert=ssl_cert_new();
+		s->session->sess_cert=ssl_cert_new();
 		}
 
 	param_len=0;
@@ -918,16 +918,15 @@
 		p+=i;
 		n-=param_len;
 
-/*		s->session->cert->rsa_tmp=rsa;*/
 		/* this should be because we are using an export cipher */
 		if (alg & SSL_aRSA)
-			pkey=X509_get_pubkey(s->session->cert->pkeys[SSL_PKEY_RSA_ENC].x509);
+			pkey=X509_get_pubkey(s->session->sess_cert->pkeys[SSL_PKEY_RSA_ENC].x509);
 		else
 			{
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_INTERNAL_ERROR);
 			goto err;
 			}
-		s->session->cert->rsa_tmp=rsa;
+		s->session->sess_cert->rsa_tmp=rsa;
 		}
 	else
 #endif
@@ -987,16 +986,16 @@
 
 #ifndef NO_RSA
 		if (alg & SSL_aRSA)
-			pkey=X509_get_pubkey(s->session->cert->pkeys[SSL_PKEY_RSA_ENC].x509);
+			pkey=X509_get_pubkey(s->session->sess_cert->pkeys[SSL_PKEY_RSA_ENC].x509);
 		else
 #endif
 #ifndef NO_DSA
 		if (alg & SSL_aDSS)
-			pkey=X509_get_pubkey(s->session->cert->pkeys[SSL_PKEY_DSA_SIGN].x509);
+			pkey=X509_get_pubkey(s->session->sess_cert->pkeys[SSL_PKEY_DSA_SIGN].x509);
 #endif
 		/* else anonymous DH, so no certificate or pkey. */
 
-		s->session->cert->dh_tmp=dh;
+		s->session->sess_cert->dh_tmp=dh;
 		dh=NULL;
 		}
 	else if ((alg & SSL_kDHr) || (alg & SSL_kDHd))
@@ -1312,11 +1311,11 @@
 			RSA *rsa;
 			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
 
-			if (s->session->cert->rsa_tmp != NULL)
-				rsa=s->session->cert->rsa_tmp;
+			if (s->session->sess_cert->rsa_tmp != NULL)
+				rsa=s->session->sess_cert->rsa_tmp;
 			else
 				{
-				pkey=X509_get_pubkey(s->session->cert->pkeys[SSL_PKEY_RSA_ENC].x509);
+				pkey=X509_get_pubkey(s->session->sess_cert->pkeys[SSL_PKEY_RSA_ENC].x509);
 				if ((pkey == NULL) ||
 					(pkey->type != EVP_PKEY_RSA) ||
 					(pkey->pkey.rsa == NULL))
@@ -1369,8 +1368,8 @@
 			{
 			DH *dh_srvr,*dh_clnt;
 
-			if (s->session->cert->dh_tmp != NULL)
-				dh_srvr=s->session->cert->dh_tmp;
+			if (s->session->sess_cert->dh_tmp != NULL)
+				dh_srvr=s->session->sess_cert->dh_tmp;
 			else
 				{
 				/* we get them from the cert */
@@ -1606,7 +1605,7 @@
 	DH *dh;
 #endif
 
-	c=s->session->cert;
+	c=s->session->sess_cert;
 
 	if (c == NULL)
 		{
@@ -1621,10 +1620,10 @@
 		return(1);
 
 #ifndef NO_RSA
-	rsa=s->session->cert->rsa_tmp;
+	rsa=s->session->sess_cert->rsa_tmp;
 #endif
 #ifndef NO_DH
-	dh=s->session->cert->dh_tmp;
+	dh=s->session->sess_cert->dh_tmp;
 #endif
 
 	/* This is the passed certificate */
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index bdd1d91..e15d135 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -129,7 +129,7 @@
 #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->cert == NULL)) &&
+	if (((s->session == NULL) || (s->session->sess_cert == NULL)) &&
 		(s->cert == NULL))
 		{
 		SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
@@ -261,15 +261,15 @@
 		case SSL3_ST_SW_KEY_EXCH_A:
 		case SSL3_ST_SW_KEY_EXCH_B:
 			l=s->s3->tmp.new_cipher->algorithms;
-			if (s->session->cert == NULL)
+			if (s->session->sess_cert == NULL)
 				{
 				if (s->cert != NULL)
 					{
 					CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
-					s->session->cert=s->cert;
+					s->session->sess_cert=s->cert;
 					}
 				}
-			ct=s->session->cert;
+			ct=s->session->sess_cert;
 
 			/* clear this, it may get reset by
 			 * send_server_key_exchange */
@@ -898,7 +898,7 @@
 	if (s->state == SSL3_ST_SW_KEY_EXCH_A)
 		{
 		type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK;
-		cert=s->session->cert;
+		cert=s->session->sess_cert;
 
 		buf=s->init_buf;
 
@@ -1207,9 +1207,9 @@
 		/* FIX THIS UP EAY EAY EAY EAY */
 		if (s->s3->tmp.use_rsa_tmp)
 			{
-			if ((s->session->cert != NULL) &&
-				(s->session->cert->rsa_tmp != NULL))
-				rsa=s->session->cert->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))
 				rsa=s->cert->rsa_tmp;
@@ -1648,7 +1648,7 @@
 		X509_free(s->session->peer);
 	s->session->peer=sk_X509_shift(sk);
 
-	s->session->cert->cert_chain=sk;
+	s->session->sess_cert->cert_chain=sk;
 
 	sk=NULL;
 
diff --git a/ssl/ssl.h b/ssl/ssl.h
index a48d597..48792b3 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -241,11 +241,13 @@
 	int not_resumable;
 
 	/* The cert is the certificate used to establish this connection */
-	struct cert_st /* CERT */ *cert;
+	struct cert_st /* CERT */ *sess_cert;
 	/* XXX should be struct sess_cert_st *sess_cert */
 
-	/* This is the cert for the other end.  On servers, it will be
-	 * the same as cert->x509 */
+	/* This is the cert for the other end.
+	 * On clients, it will be the same as sess_cert->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;
 
 	int references;
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index cbc89b8..dda7882 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -510,10 +510,10 @@
 	{
 	STACK_OF(X509) *r;
 	
-	if ((s == NULL) || (s->session == NULL) || (s->session->cert == NULL))
+	if ((s == NULL) || (s->session == NULL) || (s->session->sess_cert == NULL))
 		r=NULL;
 	else
-		r=s->session->cert->cert_chain;
+		r=s->session->sess_cert->cert_chain;
 
 	return(r);
 	}
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index 099abb2..88d4b50 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -377,7 +377,7 @@
 	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->cert != NULL) ssl_cert_free(ss->cert);
+	if (ss->sess_cert != NULL) ssl_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));