New ctrl to set current certificate.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 2 Feb 2014 02:51:30 +0000 (02:51 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 2 Feb 2014 23:12:06 +0000 (23:12 +0000)
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.
(cherry picked from commit 0f78819c8ccb7c526edbe90d5b619281366ce75c)

demos/bio/server-arg.c
doc/ssl/SSL_CTX_add1_chain_cert.pod
ssl/s3_lib.c
ssl/ssl.h
ssl/ssl_cert.c
ssl/ssl_locl.h

index be35e6210bf0cde97bcab7cd7979675c0bd85807..0d432a47627aee5dbf4fe43bd802277cbb7e41fd 100644 (file)
@@ -82,7 +82,24 @@ int main(int argc, char *argv[])
                ERR_print_errors_fp(stderr);
                goto err;
                }
-
+#if 0
+       /* Demo of how to iterate over all certificates in an SSL_CTX
+        * structure.
+        */
+       {
+       X509 *x;
+       int rv;
+       rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST);
+       while (rv)
+               {
+               X509 *x = SSL_CTX_get0_certificate(ctx);
+               X509_NAME_print_ex_fp(stdout, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
+               printf("\n");
+               rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT);
+               }
+       fflush(stdout);
+       }
+#endif
        /* Setup server side SSL bio */
        ssl_bio=BIO_new_ssl(ctx,0);
 
index a97969260d54538d72a461220515b83a6614ea44..0c977aa1a722d318cb23de062b51ce91aa801cb1 100644 (file)
@@ -7,7 +7,8 @@ SSL_CTX_add1_chain_cert, SSL_CTX_get0_chain_certs, SSL_CTX_clear_chain_certs,
 SSL_set0_chain, SSL_set1_chain, SSL_add0_chain_cert, SSL_add1_chain_cert,
 SSL_get0_chain_certs, SSL_clear_chain_certs, SSL_CTX_build_cert_chain,
 SSL_build_cert_chain, SSL_CTX_select_current_cert,
-SSL_select_current_cert - extra chain certificate processing
+SSL_select_current_cert, SSL_CTX_set_current_cert, SSL_set_current_cert - extra
+chain certificate processing
 
 =head1 SYNOPSIS
 
@@ -32,6 +33,8 @@ SSL_select_current_cert - extra chain certificate processing
 
  int SSL_CTX_select_current_cert(SSL_CTX *ctx, X509 *x509);
  int SSL_select_current_cert(SSL *ssl, X509 *x509);
+ int SSL_CTX_set_current_cert(SSL_CTX *ctx, long op);
+ int SSL_set_current_cert(SSL *ssl, long op);
 
 =head1 DESCRIPTION
 
@@ -65,8 +68,14 @@ function such as SSL_CTX_use_certificate().
 
 SSL_set0_chain(), SSL_set1_chain(), SSL_add0_chain_cert(),
 SSL_add1_chain_cert(), SSL_get0_chain_certs(), SSL_clear_chain_certs(),
-SSL_build_cert_chain() and SSL_select_current_cert() are similar except they
-apply to SSL structure B<ssl>.
+SSL_build_cert_chain(), SSL_select_current_cert() and SSL_set_current_cert()
+are similar except they apply to SSL structure B<ssl>.
+
+SSL_CTX_set_current_cert() changes the current certificate to a value based
+on the B<op> argument. Currently B<op> can be B<SSL_CERT_SET_FIRST> to use
+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
+used to iterate over all certificates in an B<SSL_CTX> structure.
 
 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
index e52d2dbb4274f2232873f0bc050b36921db495b3..bb1d50810d541c1b36131e29c879ff040526c34d 100644 (file)
@@ -3438,6 +3438,9 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
        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:
                {
@@ -3943,6 +3946,9 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
        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);
                }
index 1505816d3454e713fba5d9d5c83d2396d6cadf09..e46f8c967b69dc7ba21356c56a7cae2f87f4c0e5 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -1870,6 +1870,10 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 
 #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)
@@ -1929,6 +1933,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 #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) \
@@ -1954,6 +1961,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
        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)
index e6234eba885e23b2b6ef85eb6134d83b80078ffa..b771105785ab5a18fe5b1165f4a9160b5c625f60 100644 (file)
@@ -646,6 +646,32 @@ int ssl_cert_select_current(CERT *c, X509 *x)
        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;
index 273f277a24770f1ef79ac16b86daf2762943ac46..0faf2a1cbfcc455a4de79966ab17bb554bf54fae 100644 (file)
@@ -1001,6 +1001,8 @@ int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain);
 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);