]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Refactored load certificate functions
authorAdriaan de Jong <dejong@fox-it.com>
Wed, 29 Jun 2011 15:59:55 +0000 (17:59 +0200)
committerDavid Sommerseth <davids@redhat.com>
Wed, 19 Oct 2011 20:45:01 +0000 (22:45 +0200)
Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: James Yonan <james@openvpn.net>
Signed-off-by: David Sommerseth <davids@redhat.com>
ssl.c
ssl_backend.h
ssl_openssl.c

diff --git a/ssl.c b/ssl.c
index a308598ec28d3854986cc18029ff0db1bd509e56..343097211971fb8652a7470285b5497376d0c7da 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -1734,63 +1734,6 @@ use_external_private_key (SSL_CTX *ssl_ctx, X509 *cert)
   return 0;
 }
 
-/*
- * Basically a clone of SSL_CTX_use_certificate_file, but also return
- * the x509 object.
- */
-static int
-use_certificate_file(SSL_CTX *ctx, const char *file, int type, X509 **x509)
-{
-  int j;
-  BIO *in;
-  int ret=0;
-  X509 *x=NULL;
-
-  in=BIO_new(BIO_s_file_internal());
-  if (in == NULL)
-    {
-      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB);
-      goto end;
-    }
-
-  if (BIO_read_filename(in,file) <= 0)
-    {
-      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB);
-      goto end;
-    }
-  if (type == SSL_FILETYPE_ASN1)
-    {
-      j=ERR_R_ASN1_LIB;
-      x=d2i_X509_bio(in,NULL);
-    }
-  else if (type == SSL_FILETYPE_PEM)
-    {
-      j=ERR_R_PEM_LIB;
-      x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
-    }
-  else
-    {
-      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,SSL_R_BAD_SSL_FILETYPE);
-      goto end;
-    }
-
-  if (x == NULL)
-    {
-      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,j);
-      goto end;
-    }
-
-  ret=SSL_CTX_use_certificate(ctx,x);
- end:
-  if (in != NULL)
-    BIO_free(in);
-  if (x509)
-    *x509 = x;
-  else if (x)
-    X509_free (x);
-  return(ret);
-}
-
 #endif
 
 #if ENABLE_INLINE_FILES
@@ -1899,36 +1842,6 @@ use_inline_load_client_CA_file (SSL_CTX *ctx, const char *ca_string)
   return(ret);
 }
 
-static int
-use_inline_certificate_file (SSL_CTX *ctx, const char *cert_string, X509 **x509)
-{
-  BIO *in = NULL;
-  X509 *x = NULL;
-  int ret = 0;
-
-  in = BIO_new_mem_buf ((char *)cert_string, -1);
-  if (!in)
-    goto end;
-
-  x = PEM_read_bio_X509 (in,
-                        NULL,
-                        ctx->default_passwd_callback,
-                        ctx->default_passwd_callback_userdata);
-  if (!x)
-    goto end;
-
-  ret = SSL_CTX_use_certificate(ctx, x);
-
- end:
-  if (in)
-    BIO_free (in);
-  if (x509)
-    *x509 = x;
-  else if (x)
-    X509_free (x);
-  return ret;
-}
-
 static int
 use_inline_PrivateKey_file (SSL_CTX *ctx, const char *key_string)
 {
@@ -1967,7 +1880,6 @@ void
 init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
 {
   SSL_CTX *ctx = NULL;
-  bool using_cert_file = false;
 
   ASSERT(NULL != new_ctx);
 
@@ -2006,43 +1918,29 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
       tls_ctx_load_cryptoapi(new_ctx, options->cryptoapi_cert);
     }
 #endif
-  else
-       {
-         X509 *my_cert = NULL;
-
-         /* Load Certificate */
-         if (options->cert_file)
-           {
-#if ENABLE_INLINE_FILES
-             if (!strcmp (options->cert_file, INLINE_FILE_TAG) && options->cert_file_inline)
-               {
-                 if (!use_inline_certificate_file (ctx, options->cert_file_inline, &my_cert))
-                   msg (M_SSLERR, "Cannot load inline certificate file");
-               }
-             else
-#endif
-               {
 #ifdef MANAGMENT_EXTERNAL_KEY
-                 if (!use_certificate_file (ctx, options->cert_file, SSL_FILETYPE_PEM, &my_cert))
-#else
-                 if (!SSL_CTX_use_certificate_file (ctx, options->cert_file, SSL_FILETYPE_PEM))
-#endif
-                   msg (M_SSLERR, "Cannot load certificate file %s", options->cert_file);
-                 using_cert_file = true;
-               }
-           }
+  else if (options->management_flags & MF_EXTERNAL_KEY)
+    {
+      X509 *my_cert = NULL;
 
-#ifdef MANAGMENT_EXTERNAL_KEY
-         if (options->management_flags & MF_EXTERNAL_KEY)
-           {
-             ASSERT (my_cert);
-             if (!use_external_private_key(ctx, my_cert))
-               msg (M_SSLERR, "Cannot enable SSL external private key capability");
-             if (my_cert)
-               X509_free(my_cert);
-           }
-         else
+      if (options->cert_file)
+        {
+          tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline, &my_cert);
+        }
+      ASSERT (my_cert);
+      if (!use_external_private_key(new_ctx->ctx, my_cert))
+       msg (M_SSLERR, "Cannot enable SSL external private key capability");
+      X509_free(my_cert);
+    }
 #endif
+  else
+    {
+      /* Use seperate PEM files for key, cert and CA certs */
+      /* Load Certificate */
+      if (options->cert_file)
+       {
+          tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline, NULL);
+       }
 
          /* Load Private Key */
          if (options->priv_key_file)
@@ -2135,13 +2033,6 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
       }
     }
 
-  /* Enable the use of certificate chains */
-  if (using_cert_file)
-    {
-      if (!SSL_CTX_use_certificate_chain_file (ctx, options->cert_file))
-       msg (M_SSLERR, "Cannot load certificate chain file %s (SSL_use_certificate_chain_file)", options->cert_file);
-    }
-
   /* Load extra certificates that are part of our own certificate
      chain but shouldn't be included in the verify chain */
   if (options->extra_certs_file || options->extra_certs_file_inline)
index 127647f0957e58ae800626422c3ce18d11b23f78..0af14697b5849ae2cdac21fa8632bd64c23bd30b 100644 (file)
@@ -172,6 +172,26 @@ int tls_ctx_load_pkcs11(struct tls_root_ctx *ctx,
 void tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert);
 #endif /* WIN32 */
 
+/**
+ * Load certificate file into the given TLS context. If the given certificate
+ * file contains a certificate chain, load the whole chain.
+ *
+ * @param ctx                  TLS context to use
+ * @param cert_file            The file name to load the certificate from, or
+ *                             "[[INLINE]]" in the case of inline files.
+ * @param cert_file_inline     A string containing the certificate
+ * @param x509                 An optional certificate, if x509 is NULL,
+ *                             do nothing, if x509 is not NULL, *x509 will be
+ *                             allocated and filled with the loaded certificate.
+ *                             *x509 must be NULL.
+ */
+void tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
+#if ENABLE_INLINE_FILES
+    const char *cert_file_inline,
+#endif
+    X509 **x509
+    );
+
 /**
  * Show the TLS ciphers that are available for us to use in the OpenSSL
  * library.
index e774f56df7779c19311cba594137a6001a9fa1a9..5980080efb36f6f6741cf7d1d688ad40790c8a4b 100644 (file)
@@ -343,6 +343,101 @@ tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)
 }
 #endif /* WIN32 */
 
+/*
+ * Based on SSL_CTX_use_certificate_file, return an x509 object for the
+ * given file.
+ */
+static int
+tls_ctx_read_certificate_file(SSL_CTX *ctx, const char *file, X509 **x509)
+{
+  int j;
+  BIO *in;
+  int ret=0;
+  X509 *x=NULL;
+
+  in=BIO_new(BIO_s_file_internal());
+  if (in == NULL)
+    {
+      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
+      goto end;
+    }
+
+  if (BIO_read_filename(in,file) <= 0)
+    {
+      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
+      goto end;
+    }
+
+  x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
+    ctx->default_passwd_callback_userdata);
+  if (x == NULL)
+    {
+      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB);
+      goto end;
+    }
+
+ end:
+  if (in != NULL)
+    BIO_free(in);
+  if (x509)
+    *x509 = x;
+  else if (x)
+    X509_free (x);
+  return(ret);
+}
+
+void
+tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
+#if ENABLE_INLINE_FILES
+    const char *cert_file_inline,
+#endif
+    X509 **x509
+    )
+{
+  ASSERT(NULL != ctx);
+  if (NULL != x509)
+    ASSERT(NULL == *x509);
+
+#if ENABLE_INLINE_FILES
+  if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_file_inline)
+    {
+      BIO *in = NULL;
+      X509 *x = NULL;
+      int ret = 0;
+
+      in = BIO_new_mem_buf ((char *)cert_file_inline, -1);
+      if (in)
+       {
+         x = PEM_read_bio_X509 (in,
+                            NULL,
+                            ctx->ctx->default_passwd_callback,
+                            ctx->ctx->default_passwd_callback_userdata);
+         BIO_free (in);
+         if (x) {
+           ret = SSL_CTX_use_certificate(ctx->ctx, x);
+           if (x509)
+             *x509 = x;
+           else
+             X509_free (x);
+         }
+       }
+
+      if (!ret)
+        msg (M_SSLERR, "Cannot load inline certificate file");
+    }
+  else
+#endif /* ENABLE_INLINE_FILES */
+    {
+      if (!SSL_CTX_use_certificate_chain_file (ctx->ctx, cert_file))
+       msg (M_SSLERR, "Cannot load certificate file %s", cert_file);
+      if (x509)
+       {
+         if (!tls_ctx_read_certificate_file(ctx->ctx, cert_file, x509))
+           msg (M_SSLERR, "Cannot load certificate file %s", cert_file);
+       }
+    }
+}
+
 void
 show_available_tls_ciphers ()
 {