Option to set current cert to server certificate.

(cherry picked from commit daddd9a950e491c31f9500d5e570bc7eb96b2823)
This commit is contained in:
Dr. Stephen Henson 2014-02-21 19:42:03 +00:00
parent a466be6243
commit 58b86e4235
4 changed files with 29 additions and 0 deletions

View File

@ -77,6 +77,14 @@ the first valid certificate or B<SSL_CERT_SET_NEXT> to set the next valid
certificate after the current certificate. These two operations can be certificate after the current certificate. These two operations can be
used to iterate over all certificates in an B<SSL_CTX> structure. used to iterate over all certificates in an B<SSL_CTX> structure.
SSL_set_current_cert() also supports the option B<SSL_CERT_SET_SERVER>.
If B<ssl> is a server and has sent a certificate to a connected client
this option sets that certificate to the current certificate and returns 1.
If the negotiated ciphersuite is anonymous (and thus no certificate will
be sent) 2 is returned and the current certificate is unchanged. If B<ssl>
is not a server or a certificate has not been sent 0 is returned and
the current certificate is unchanged.
All these functions are implemented as macros. Those containing a B<1> All these functions are implemented as macros. Those containing a B<1>
increment the reference count of the supplied certificate or chain so it must increment the reference count of the supplied certificate or chain so it must
be freed at some point after the operation. Those containing a B<0> do be freed at some point after the operation. Those containing a B<0> do

View File

@ -3432,6 +3432,24 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
return ssl_cert_select_current(s->cert, (X509 *)parg); return ssl_cert_select_current(s->cert, (X509 *)parg);
case SSL_CTRL_SET_CURRENT_CERT: case SSL_CTRL_SET_CURRENT_CERT:
if (larg == SSL_CERT_SET_SERVER)
{
CERT_PKEY *cpk;
const SSL_CIPHER *cipher;
if (!s->server)
return 0;
cipher = s->s3->tmp.new_cipher;
if (!cipher)
return 0;
/* No certificate for unauthenticated ciphersuites */
if (cipher->algorithm_auth & SSL_aNULL)
return 2;
cpk = ssl_get_server_send_pkey(s);
if (!cpk)
return 0;
s->cert->key = cpk;
return 1;
}
return ssl_cert_set_current(s->cert, larg); return ssl_cert_set_current(s->cert, larg);
#ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_EC

View File

@ -1942,6 +1942,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CERT_SET_FIRST 1 #define SSL_CERT_SET_FIRST 1
#define SSL_CERT_SET_NEXT 2 #define SSL_CERT_SET_NEXT 2
#define SSL_CERT_SET_SERVER 3
#define DTLSv1_get_timeout(ssl, arg) \ #define DTLSv1_get_timeout(ssl, arg) \
SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)

View File

@ -2672,6 +2672,8 @@ CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
int i; int i;
c = s->cert; c = s->cert;
if (!s->s3 || !s->s3->tmp.new_cipher)
return NULL;
ssl_set_cert_masks(c, s->s3->tmp.new_cipher); ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL