Add client cert engine to SSL routines.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 1 Jun 2008 22:33:24 +0000 (22:33 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 1 Jun 2008 22:33:24 +0000 (22:33 +0000)
CHANGES
ssl/d1_clnt.c
ssl/s3_clnt.c
ssl/ssl.h
ssl/ssl_locl.h
ssl/ssl_sess.c

diff --git a/CHANGES b/CHANGES
index 9aac3ebff70988bbffa522d856d4b33390dc09cc..c5c50787cdbd051ce959af1b3a7977f05a42ea5b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,9 @@
 
  Changes between 0.9.8g and 0.9.9  [xx XXX xxxx]
 
+  *) Expand ENGINE to support engine supplied SSL client certificate functions.
+     [Steve Henson]
+
   *) Revamp of LHASH to provide stronger type-checking. Still to come:
      STACK, TXT_DB, bsearch, qsort.
      [Ben Laurie]
index 322c017f76371879a1d5149097256f8dfaa3054a..f4e9df9810a1810587e45d32711109f9f6355dca 100644 (file)
@@ -1096,8 +1096,7 @@ int dtls1_send_client_certificate(SSL *s)
                 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
                 * We then get retied later */
                i=0;
-               if (s->ctx->client_cert_cb != NULL)
-                       i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
+               i = ssl_do_client_cert_cb(s, &x509, &pkey);
                if (i < 0)
                        {
                        s->rwstate=SSL_X509_LOOKUP;
index 23875f00e0e082b55548c03d151eba3e47ffb6f2..8f96120d2e963b5719b8b650dde16834fed9933b 100644 (file)
 #include <openssl/dh.h>
 #endif
 #include <openssl/bn.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
 
 static const SSL_METHOD *ssl3_get_client_method(int ver);
 static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
@@ -2723,8 +2726,7 @@ int ssl3_send_client_certificate(SSL *s)
                 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
                 * We then get retied later */
                i=0;
-               if (s->ctx->client_cert_cb != NULL)
-                       i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
+               i = ssl_do_client_cert_cb(s, &x509, &pkey);
                if (i < 0)
                        {
                        s->rwstate=SSL_X509_LOOKUP;
@@ -2948,3 +2950,21 @@ static int ssl3_check_finished(SSL *s)
        return 1;
        }
 #endif
+
+int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
+       {
+       int i = 0;
+#ifndef OPENSSL_NO_ENGINE
+       if (s->ctx->client_cert_engine)
+               {
+               i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s,
+                                               SSL_get_client_CA_list(s),
+                                               px509, ppkey, NULL, NULL);
+               if (i != 0)
+                       return i;
+               }
+#endif
+       if (s->ctx->client_cert_cb)
+               i = s->ctx->client_cert_cb(s,px509,ppkey);
+       return i;
+       }
index 3c1b74aa4bb81973cd10da6d7954b2eff0e4fea5..6adf11d7a75f4204385032897f15bfd34463a2c7 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -798,6 +798,12 @@ struct ssl_ctx_st
         */
        unsigned int max_send_fragment;
 
+#ifndef OPENSSL_ENGINE
+       /* Engine to pass requests for client certs to
+        */
+       ENGINE *client_cert_engine;
+#endif
+
 #ifndef OPENSSL_NO_TLSEXT
        /* TLS extensions servername callback */
        int (*tlsext_servername_callback)(SSL*, int *, void *);
@@ -879,6 +885,7 @@ void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl,int type,
 void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
 void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
 int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
 void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
 void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
 
index a65071a47aa65ce38679a5883df1106f8668f8d6..55b23304c1ad0b6f2a2de97c21d566faa5141dd1 100644 (file)
@@ -927,6 +927,7 @@ int ssl3_get_cert_status(SSL *s);
 int ssl3_get_server_done(SSL *s);
 int ssl3_send_client_verify(SSL *s);
 int ssl3_send_client_certificate(SSL *s);
+int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
 int ssl3_send_client_key_exchange(SSL *s);
 int ssl3_get_key_exchange(SSL *s);
 int ssl3_get_server_certificate(SSL *s);
index 33d302aa410fd637a16fc8d825d993e624e4e672..12cc486b1baaa9972c3a68c06eb591d8d4163e92 100644 (file)
 #include <stdio.h>
 #include <openssl/lhash.h>
 #include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
 #include "ssl_locl.h"
 
 static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
@@ -998,6 +1001,25 @@ int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL * ssl, X509 ** x509 , EVP_PK
        return ctx->client_cert_cb;
        }
 
+#ifndef OPENSSL_NO_ENGINE
+int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
+       {
+       if (!ENGINE_init(e))
+               {
+               SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB);
+               return 0;
+               }
+       if(!ENGINE_get_ssl_client_cert_function(e))
+               {
+               SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, SSL_R_NO_CLIENT_CERT_METHOD);
+               ENGINE_finish(e);
+               return 0;
+               }
+       ctx->client_cert_engine = e;
+       return 1;
+       }
+#endif
+
 void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
        int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len))
        {