New ctrl to set current certificate.

New ctrl sets current certificate based on certain criteria. Currently
two options: set the first valid certificate as current and set the
next valid certificate as current. Using these an application can
iterate over all certificates in an SSL_CTX or SSL structure.
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 5c8aa13..ed50be1 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3431,6 +3431,9 @@
 	case SSL_CTRL_SELECT_CURRENT_CERT:
 		return ssl_cert_select_current(s->cert, (X509 *)parg);
 
+	case SSL_CTRL_SET_CURRENT_CERT:
+		return ssl_cert_set_current(s->cert, larg);
+
 #ifndef OPENSSL_NO_EC
 	case SSL_CTRL_GET_CURVES:
 		{
@@ -3937,6 +3940,9 @@
 	case SSL_CTRL_SELECT_CURRENT_CERT:
 		return ssl_cert_select_current(ctx->cert, (X509 *)parg);
 
+	case SSL_CTRL_SET_CURRENT_CERT:
+		return ssl_cert_set_current(ctx->cert, larg);
+
 	default:
 		return(0);
 		}
diff --git a/ssl/ssl.h b/ssl/ssl.h
index aa3be29..ee5e996 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -1942,6 +1942,10 @@
 
 #define SSL_CTRL_GET_CHAIN_CERTS		115
 #define SSL_CTRL_SELECT_CURRENT_CERT		116
+#define SSL_CTRL_SET_CURRENT_CERT		117
+
+#define SSL_CERT_SET_FIRST			1
+#define SSL_CERT_SET_NEXT			2
 
 #define DTLSv1_get_timeout(ssl, arg) \
 	SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
@@ -2001,6 +2005,9 @@
 #define SSL_CTX_select_current_cert(ctx,x509) \
 	SSL_CTX_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509)
 
+#define SSL_CTX_set_current_cert(ctx, op) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
+
 #define SSL_CTX_set0_verify_cert_store(ctx,st) \
 	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st)
 #define SSL_CTX_set1_verify_cert_store(ctx,st) \
@@ -2026,6 +2033,8 @@
 	SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
 #define SSL_select_current_cert(ctx,x509) \
 	SSL_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509)
+#define SSL_set_current_cert(ctx,op) \
+	SSL_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
 
 #define SSL_set0_verify_cert_store(s,st) \
 	SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st)
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 005d82d..47c8b86 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -624,6 +624,32 @@
 	return 0;
 	}
 
+int ssl_cert_set_current(CERT *c, long op)
+	{
+	int i, idx;
+	if (!c)
+		return 0;
+	if (op == SSL_CERT_SET_FIRST)
+		idx = 0;
+	else if (op == SSL_CERT_SET_NEXT)
+		{
+		idx = (int)(c->key - c->pkeys + 1);
+		if (idx >= SSL_PKEY_NUM)
+			return 0;
+		}
+	else
+		return 0;
+	for (i = idx; i < SSL_PKEY_NUM; i++)
+		{
+		if (c->pkeys[i].x509)
+			{
+			c->key = &c->pkeys[i];
+			return 1;
+			}
+		}
+	return 0;
+	}
+
 void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg)
 	{
 	c->cert_cb = cb;
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index c493f7e..fd6b883 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -999,6 +999,8 @@
 int ssl_cert_add0_chain_cert(CERT *c, X509 *x);
 int ssl_cert_add1_chain_cert(CERT *c, X509 *x);
 int ssl_cert_select_current(CERT *c, X509 *x);
+int ssl_cert_set_current(CERT *c, long arg);
+X509 *ssl_cert_get0_next_certificate(CERT *c, int first);
 void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg);
 
 int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);