Browse code

Refactored load certificate functions

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>

Adriaan de Jong authored on 2011/06/30 00:59:55
Showing 3 changed files
... ...
@@ -1734,63 +1734,6 @@ use_external_private_key (SSL_CTX *ssl_ctx, X509 *cert)
1734 1734
   return 0;
1735 1735
 }
1736 1736
 
1737
-/*
1738
- * Basically a clone of SSL_CTX_use_certificate_file, but also return
1739
- * the x509 object.
1740
- */
1741
-static int
1742
-use_certificate_file(SSL_CTX *ctx, const char *file, int type, X509 **x509)
1743
-{
1744
-  int j;
1745
-  BIO *in;
1746
-  int ret=0;
1747
-  X509 *x=NULL;
1748
-
1749
-  in=BIO_new(BIO_s_file_internal());
1750
-  if (in == NULL)
1751
-    {
1752
-      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB);
1753
-      goto end;
1754
-    }
1755
-
1756
-  if (BIO_read_filename(in,file) <= 0)
1757
-    {
1758
-      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB);
1759
-      goto end;
1760
-    }
1761
-  if (type == SSL_FILETYPE_ASN1)
1762
-    {
1763
-      j=ERR_R_ASN1_LIB;
1764
-      x=d2i_X509_bio(in,NULL);
1765
-    }
1766
-  else if (type == SSL_FILETYPE_PEM)
1767
-    {
1768
-      j=ERR_R_PEM_LIB;
1769
-      x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
1770
-    }
1771
-  else
1772
-    {
1773
-      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,SSL_R_BAD_SSL_FILETYPE);
1774
-      goto end;
1775
-    }
1776
-
1777
-  if (x == NULL)
1778
-    {
1779
-      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,j);
1780
-      goto end;
1781
-    }
1782
-
1783
-  ret=SSL_CTX_use_certificate(ctx,x);
1784
- end:
1785
-  if (in != NULL)
1786
-    BIO_free(in);
1787
-  if (x509)
1788
-    *x509 = x;
1789
-  else if (x)
1790
-    X509_free (x);
1791
-  return(ret);
1792
-}
1793
-
1794 1737
 #endif
1795 1738
 
1796 1739
 #if ENABLE_INLINE_FILES
... ...
@@ -1900,36 +1843,6 @@ use_inline_load_client_CA_file (SSL_CTX *ctx, const char *ca_string)
1900 1900
 }
1901 1901
 
1902 1902
 static int
1903
-use_inline_certificate_file (SSL_CTX *ctx, const char *cert_string, X509 **x509)
1904
-{
1905
-  BIO *in = NULL;
1906
-  X509 *x = NULL;
1907
-  int ret = 0;
1908
-
1909
-  in = BIO_new_mem_buf ((char *)cert_string, -1);
1910
-  if (!in)
1911
-    goto end;
1912
-
1913
-  x = PEM_read_bio_X509 (in,
1914
-			 NULL,
1915
-			 ctx->default_passwd_callback,
1916
-			 ctx->default_passwd_callback_userdata);
1917
-  if (!x)
1918
-    goto end;
1919
-
1920
-  ret = SSL_CTX_use_certificate(ctx, x);
1921
-
1922
- end:
1923
-  if (in)
1924
-    BIO_free (in);
1925
-  if (x509)
1926
-    *x509 = x;
1927
-  else if (x)
1928
-    X509_free (x);
1929
-  return ret;
1930
-}
1931
-
1932
-static int
1933 1903
 use_inline_PrivateKey_file (SSL_CTX *ctx, const char *key_string)
1934 1904
 {
1935 1905
   BIO *in = NULL;
... ...
@@ -1967,7 +1880,6 @@ void
1967 1967
 init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
1968 1968
 {
1969 1969
   SSL_CTX *ctx = NULL;
1970
-  bool using_cert_file = false;
1971 1970
 
1972 1971
   ASSERT(NULL != new_ctx);
1973 1972
 
... ...
@@ -2006,43 +1918,29 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
2006 2006
       tls_ctx_load_cryptoapi(new_ctx, options->cryptoapi_cert);
2007 2007
     }
2008 2008
 #endif
2009
-  else
2010
-	{
2011
-	  X509 *my_cert = NULL;
2012
-
2013
-	  /* Load Certificate */
2014
-	  if (options->cert_file)
2015
-	    {
2016
-#if ENABLE_INLINE_FILES
2017
-	      if (!strcmp (options->cert_file, INLINE_FILE_TAG) && options->cert_file_inline)
2018
-		{
2019
-		  if (!use_inline_certificate_file (ctx, options->cert_file_inline, &my_cert))
2020
-		    msg (M_SSLERR, "Cannot load inline certificate file");
2021
-		}
2022
-	      else
2023
-#endif
2024
-		{
2025 2009
 #ifdef MANAGMENT_EXTERNAL_KEY
2026
-		  if (!use_certificate_file (ctx, options->cert_file, SSL_FILETYPE_PEM, &my_cert))
2027
-#else
2028
-		  if (!SSL_CTX_use_certificate_file (ctx, options->cert_file, SSL_FILETYPE_PEM))
2029
-#endif
2030
-		    msg (M_SSLERR, "Cannot load certificate file %s", options->cert_file);
2031
-		  using_cert_file = true;
2032
-		}
2033
-	    }
2010
+  else if (options->management_flags & MF_EXTERNAL_KEY)
2011
+    {
2012
+      X509 *my_cert = NULL;
2034 2013
 
2035
-#ifdef MANAGMENT_EXTERNAL_KEY
2036
-	  if (options->management_flags & MF_EXTERNAL_KEY)
2037
-	    {
2038
-	      ASSERT (my_cert);
2039
-	      if (!use_external_private_key(ctx, my_cert))
2040
-		msg (M_SSLERR, "Cannot enable SSL external private key capability");
2041
-	      if (my_cert)
2042
-	        X509_free(my_cert);
2043
-	    }
2044
-	  else
2014
+      if (options->cert_file)
2015
+        {
2016
+          tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline, &my_cert);
2017
+        }
2018
+      ASSERT (my_cert);
2019
+      if (!use_external_private_key(new_ctx->ctx, my_cert))
2020
+	msg (M_SSLERR, "Cannot enable SSL external private key capability");
2021
+      X509_free(my_cert);
2022
+    }
2045 2023
 #endif
2024
+  else
2025
+    {
2026
+      /* Use seperate PEM files for key, cert and CA certs */
2027
+      /* Load Certificate */
2028
+      if (options->cert_file)
2029
+	{
2030
+          tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline, NULL);
2031
+	}
2046 2032
 
2047 2033
 	  /* Load Private Key */
2048 2034
 	  if (options->priv_key_file)
... ...
@@ -2135,13 +2033,6 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
2135 2135
       }
2136 2136
     }
2137 2137
 
2138
-  /* Enable the use of certificate chains */
2139
-  if (using_cert_file)
2140
-    {
2141
-      if (!SSL_CTX_use_certificate_chain_file (ctx, options->cert_file))
2142
-	msg (M_SSLERR, "Cannot load certificate chain file %s (SSL_use_certificate_chain_file)", options->cert_file);
2143
-    }
2144
-
2145 2138
   /* Load extra certificates that are part of our own certificate
2146 2139
      chain but shouldn't be included in the verify chain */
2147 2140
   if (options->extra_certs_file || options->extra_certs_file_inline)
... ...
@@ -173,6 +173,26 @@ void tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert
173 173
 #endif /* WIN32 */
174 174
 
175 175
 /**
176
+ * Load certificate file into the given TLS context. If the given certificate
177
+ * file contains a certificate chain, load the whole chain.
178
+ *
179
+ * @param ctx			TLS context to use
180
+ * @param cert_file		The file name to load the certificate from, or
181
+ * 				"[[INLINE]]" in the case of inline files.
182
+ * @param cert_file_inline	A string containing the certificate
183
+ * @param x509			An optional certificate, if x509 is NULL,
184
+ * 				do nothing, if x509 is not NULL, *x509 will be
185
+ * 				allocated and filled with the loaded certificate.
186
+ * 				*x509 must be NULL.
187
+ */
188
+void tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
189
+#if ENABLE_INLINE_FILES
190
+    const char *cert_file_inline,
191
+#endif
192
+    X509 **x509
193
+    );
194
+
195
+/**
176 196
  * Show the TLS ciphers that are available for us to use in the OpenSSL
177 197
  * library.
178 198
  */
... ...
@@ -343,6 +343,101 @@ tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)
343 343
 }
344 344
 #endif /* WIN32 */
345 345
 
346
+/*
347
+ * Based on SSL_CTX_use_certificate_file, return an x509 object for the
348
+ * given file.
349
+ */
350
+static int
351
+tls_ctx_read_certificate_file(SSL_CTX *ctx, const char *file, X509 **x509)
352
+{
353
+  int j;
354
+  BIO *in;
355
+  int ret=0;
356
+  X509 *x=NULL;
357
+
358
+  in=BIO_new(BIO_s_file_internal());
359
+  if (in == NULL)
360
+    {
361
+      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
362
+      goto end;
363
+    }
364
+
365
+  if (BIO_read_filename(in,file) <= 0)
366
+    {
367
+      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
368
+      goto end;
369
+    }
370
+
371
+  x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
372
+    ctx->default_passwd_callback_userdata);
373
+  if (x == NULL)
374
+    {
375
+      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB);
376
+      goto end;
377
+    }
378
+
379
+ end:
380
+  if (in != NULL)
381
+    BIO_free(in);
382
+  if (x509)
383
+    *x509 = x;
384
+  else if (x)
385
+    X509_free (x);
386
+  return(ret);
387
+}
388
+
389
+void
390
+tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
391
+#if ENABLE_INLINE_FILES
392
+    const char *cert_file_inline,
393
+#endif
394
+    X509 **x509
395
+    )
396
+{
397
+  ASSERT(NULL != ctx);
398
+  if (NULL != x509)
399
+    ASSERT(NULL == *x509);
400
+
401
+#if ENABLE_INLINE_FILES
402
+  if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_file_inline)
403
+    {
404
+      BIO *in = NULL;
405
+      X509 *x = NULL;
406
+      int ret = 0;
407
+
408
+      in = BIO_new_mem_buf ((char *)cert_file_inline, -1);
409
+      if (in)
410
+	{
411
+	  x = PEM_read_bio_X509 (in,
412
+			     NULL,
413
+			     ctx->ctx->default_passwd_callback,
414
+			     ctx->ctx->default_passwd_callback_userdata);
415
+	  BIO_free (in);
416
+	  if (x) {
417
+	    ret = SSL_CTX_use_certificate(ctx->ctx, x);
418
+	    if (x509)
419
+	      *x509 = x;
420
+	    else
421
+	      X509_free (x);
422
+	  }
423
+	}
424
+
425
+      if (!ret)
426
+        msg (M_SSLERR, "Cannot load inline certificate file");
427
+    }
428
+  else
429
+#endif /* ENABLE_INLINE_FILES */
430
+    {
431
+      if (!SSL_CTX_use_certificate_chain_file (ctx->ctx, cert_file))
432
+	msg (M_SSLERR, "Cannot load certificate file %s", cert_file);
433
+      if (x509)
434
+	{
435
+	  if (!tls_ctx_read_certificate_file(ctx->ctx, cert_file, x509))
436
+	    msg (M_SSLERR, "Cannot load certificate file %s", cert_file);
437
+	}
438
+    }
439
+}
440
+
346 441
 void
347 442
 show_available_tls_ciphers ()
348 443
 {