Browse code

Refactored CA and extra certs code

Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: David Sommerseth <davids@redhat.com>
Signed-off-by: David Sommerseth <davids@redhat.com>

Adriaan de Jong authored on 2011/06/30 01:28:02
Showing 3 changed files
... ...
@@ -1602,114 +1602,6 @@ tls_deauthenticate (struct tls_multi *multi)
1602 1602
     }
1603 1603
 }
1604 1604
 
1605
-#if ENABLE_INLINE_FILES
1606
-
1607
-static int
1608
-use_inline_load_verify_locations (SSL_CTX *ctx, const char *ca_string)
1609
-{
1610
-  X509_STORE *store = NULL;
1611
-  X509* cert = NULL;
1612
-  BIO *in = NULL;
1613
-  int ret = 0;
1614
-
1615
-  in = BIO_new_mem_buf ((char *)ca_string, -1);
1616
-  if (!in)
1617
-    goto err;
1618
-
1619
-  for (;;)
1620
-    {
1621
-      if (!PEM_read_bio_X509 (in, &cert, 0, NULL))
1622
-	{
1623
-	  ret = 1;
1624
-	  break;
1625
-	}
1626
-      if (!cert)
1627
-	break;
1628
-
1629
-      store = SSL_CTX_get_cert_store (ctx);
1630
-      if (!store)
1631
-	break;
1632
-
1633
-      if (!X509_STORE_add_cert (store, cert))
1634
-	break;
1635
-
1636
-      if (cert)
1637
-	{
1638
-	  X509_free (cert);
1639
-	  cert = NULL;
1640
-	}
1641
-    }
1642
-
1643
- err:
1644
-  if (cert)
1645
-    X509_free (cert);
1646
-  if (in)
1647
-    BIO_free (in);
1648
-  return ret;  
1649
-}
1650
-
1651
-static int
1652
-xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
1653
-{
1654
-  return(X509_NAME_cmp(*a,*b));
1655
-}
1656
-
1657
-static STACK_OF(X509_NAME) *
1658
-use_inline_load_client_CA_file (SSL_CTX *ctx, const char *ca_string)
1659
-{
1660
-  BIO *in = NULL;
1661
-  X509 *x = NULL;
1662
-  X509_NAME *xn = NULL;
1663
-  STACK_OF(X509_NAME) *ret = NULL, *sk;
1664
-
1665
-  sk=sk_X509_NAME_new(xname_cmp);
1666
-
1667
-  in = BIO_new_mem_buf ((char *)ca_string, -1);
1668
-  if (!in)
1669
-    goto err;
1670
-
1671
-  if ((sk == NULL) || (in == NULL))
1672
-    goto err;
1673
-	
1674
-  for (;;)
1675
-    {
1676
-      if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
1677
-	break;
1678
-      if (ret == NULL)
1679
-	{
1680
-	  ret = sk_X509_NAME_new_null();
1681
-	  if (ret == NULL)
1682
-	    goto err;
1683
-	}
1684
-      if ((xn=X509_get_subject_name(x)) == NULL) goto err;
1685
-      /* check for duplicates */
1686
-      xn=X509_NAME_dup(xn);
1687
-      if (xn == NULL) goto err;
1688
-      if (sk_X509_NAME_find(sk,xn) >= 0)
1689
-	X509_NAME_free(xn);
1690
-      else
1691
-	{
1692
-	  sk_X509_NAME_push(sk,xn);
1693
-	  sk_X509_NAME_push(ret,xn);
1694
-	}
1695
-    }
1696
-
1697
-  if (0)
1698
-    {
1699
-    err:
1700
-      if (ret != NULL) sk_X509_NAME_pop_free(ret,X509_NAME_free);
1701
-      ret=NULL;
1702
-    }
1703
-  if (sk != NULL) sk_X509_NAME_free(sk);
1704
-  if (in != NULL) BIO_free(in);
1705
-  if (x != NULL) X509_free(x);
1706
-  if (ret != NULL)
1707
-    ERR_clear_error();
1708
-  return(ret);
1709
-}
1710
-
1711
-#endif
1712
-
1713 1605
 /*
1714 1606
  * Initialize SSL context.
1715 1607
  * All files are in PEM format.
... ...
@@ -1735,8 +1627,6 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
1735 1735
 
1736 1736
   tls_ctx_set_options(new_ctx, options->ssl_flags);
1737 1737
 
1738
-  ctx = new_ctx->ctx;
1739
-
1740 1738
   if (options->pkcs12_file)
1741 1739
     {
1742 1740
       if (0 != tls_ctx_load_pkcs12(new_ctx, options->pkcs12_file,
... ...
@@ -1783,94 +1673,19 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
1783 1783
 	}
1784 1784
     }
1785 1785
 
1786
+  ctx = new_ctx->ctx;
1787
+
1786 1788
   if (options->ca_file || options->ca_path)
1787 1789
     {
1788
-      int status;
1789
-
1790
-#if ENABLE_INLINE_FILES
1791
-      if (options->ca_file && !strcmp (options->ca_file, INLINE_FILE_TAG) && options->ca_file_inline)
1792
-	{
1793
-	  status = use_inline_load_verify_locations (ctx, options->ca_file_inline);
1794
-	}
1795
-      else
1796
-#endif
1797
-	{
1798
-	  /* Load CA file for verifying peer supplied certificate */
1799
-	  status = SSL_CTX_load_verify_locations (ctx, options->ca_file, NULL);
1800
-	}
1801
-      
1802
-      if (!status)
1803
-	msg (M_SSLERR, "Cannot load CA certificate file %s path %s (SSL_CTX_load_verify_locations)", np(options->ca_file), np(options->ca_path));
1804
-
1805
-      /* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */
1806
-      if (options->ca_path) {
1807
-        X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1808
-
1809
-        if (store)
1810
-	  {
1811
-	    X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
1812
-	    if (!X509_LOOKUP_add_dir(lookup, options->ca_path, X509_FILETYPE_PEM))
1813
-	      X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
1814
-	    else
1815
-	      msg(M_WARN, "WARNING: experimental option --capath %s", options->ca_path);
1816
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
1817
-	    X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1818
-#else
1819
-	    msg(M_WARN, "WARNING: this version of OpenSSL cannot handle CRL files in capath");
1820
-#endif
1821
-	  }
1822
-	else
1823
-          msg(M_SSLERR, "Cannot get certificate store (SSL_CTX_get_cert_store)");
1824
-      }
1825
-
1826
-      /* Load names of CAs from file and use it as a client CA list */
1827
-      if (options->ca_file && options->tls_server) {
1828
-        STACK_OF(X509_NAME) *cert_names = NULL;
1829
-#if ENABLE_INLINE_FILES
1830
-	if (!strcmp (options->ca_file, INLINE_FILE_TAG) && options->ca_file_inline)
1831
-	  {
1832
-	    cert_names = use_inline_load_client_CA_file (ctx, options->ca_file_inline);
1833
-	  }
1834
-	else
1835
-#endif
1836
-	  {
1837
-	    cert_names = SSL_load_client_CA_file (options->ca_file);
1838
-	  }
1839
-        if (!cert_names)
1840
-          msg (M_SSLERR, "Cannot load CA certificate file %s (SSL_load_client_CA_file)", options->ca_file);
1841
-	SSL_CTX_set_client_CA_list (ctx, cert_names);
1842
-      }
1790
+      tls_ctx_load_ca(new_ctx, options->ca_file, options->ca_file_inline,
1791
+	  options->ca_path, options->tls_server);
1843 1792
     }
1844 1793
 
1845 1794
   /* Load extra certificates that are part of our own certificate
1846 1795
      chain but shouldn't be included in the verify chain */
1847 1796
   if (options->extra_certs_file || options->extra_certs_file_inline)
1848 1797
     {
1849
-      BIO *bio;
1850
-      X509 *cert;
1851
-#if ENABLE_INLINE_FILES
1852
-      if (!strcmp (options->extra_certs_file, INLINE_FILE_TAG) && options->extra_certs_file_inline)
1853
-	{
1854
-	  bio = BIO_new_mem_buf ((char *)options->extra_certs_file_inline, -1);
1855
-	}
1856
-      else
1857
-#endif
1858
-	{
1859
-	  bio = BIO_new(BIO_s_file());
1860
-	  if (BIO_read_filename(bio, options->extra_certs_file) <= 0)
1861
-	    msg (M_SSLERR, "Cannot load extra-certs file: %s", options->extra_certs_file);
1862
-	}
1863
-      for (;;)
1864
-	{
1865
-	  cert = NULL;
1866
-	  if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */
1867
-	    break;
1868
-	  if (!cert)
1869
-	    msg (M_SSLERR, "Error reading extra-certs certificate");
1870
-	  if (SSL_CTX_add_extra_chain_cert(ctx, cert) != 1)
1871
-	    msg (M_SSLERR, "Error adding extra-certs certificate");
1872
-	}
1873
-      BIO_free (bio);
1798
+      tls_ctx_load_extra_certs(new_ctx, options->extra_certs_file, options->extra_certs_file_inline);
1874 1799
     }
1875 1800
 
1876 1801
 #if P2MP_SERVER
... ...
@@ -227,6 +227,41 @@ int tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, X509 *cert);
227 227
 #endif
228 228
 
229 229
 /**
230
+ * Load certificate authority certificates from the given file or path.
231
+ *
232
+ * Note that not all SSL libraries support loading from a path.
233
+ *
234
+ * @param ctx			TLS context to use
235
+ * @param ca_file		The file name to load the CAs from, or
236
+ * 				"[[INLINE]]" in the case of inline files.
237
+ * @param ca_file_inline	A string containing the CAs
238
+ * @param ca_path		The path to load the CAs from
239
+ */
240
+void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
241
+#if ENABLE_INLINE_FILES
242
+    const char *ca_file_inline,
243
+#endif
244
+    const char *ca_path, bool tls_server
245
+    );
246
+
247
+/**
248
+ * Load extra certificate authority certificates from the given file or path.
249
+ * These Load extra certificates that are part of our own certificate
250
+ * chain but shouldn't be included in the verify chain.
251
+ *
252
+ *
253
+ * @param ctx				TLS context to use
254
+ * @param extra_certs_file		The file name to load the certs from, or
255
+ * 					"[[INLINE]]" in the case of inline files.
256
+ * @param extra_certs_file_inline	A string containing the certs
257
+ */
258
+void tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file
259
+#if ENABLE_INLINE_FILES
260
+    , const char *extra_certs_file_inline
261
+#endif
262
+    );
263
+
264
+/*
230 265
  * Show the TLS ciphers that are available for us to use in the OpenSSL
231 266
  * library.
232 267
  */
... ...
@@ -645,6 +645,214 @@ tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, X509 *cert)
645 645
 
646 646
 #endif
647 647
 
648
+#if ENABLE_INLINE_FILES
649
+static int
650
+xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
651
+{
652
+  return(X509_NAME_cmp(*a,*b));
653
+}
654
+
655
+static STACK_OF(X509_NAME) *
656
+use_inline_load_client_CA_file (SSL_CTX *ctx, const char *ca_string)
657
+{
658
+  BIO *in = NULL;
659
+  X509 *x = NULL;
660
+  X509_NAME *xn = NULL;
661
+  STACK_OF(X509_NAME) *ret = NULL, *sk;
662
+
663
+  sk=sk_X509_NAME_new(xname_cmp);
664
+
665
+  in = BIO_new_mem_buf ((char *)ca_string, -1);
666
+  if (!in)
667
+    goto err;
668
+
669
+  if ((sk == NULL) || (in == NULL))
670
+    goto err;
671
+
672
+  for (;;)
673
+    {
674
+      if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
675
+	break;
676
+      if (ret == NULL)
677
+	{
678
+	  ret = sk_X509_NAME_new_null();
679
+	  if (ret == NULL)
680
+	    goto err;
681
+	}
682
+      if ((xn=X509_get_subject_name(x)) == NULL) goto err;
683
+      /* check for duplicates */
684
+      xn=X509_NAME_dup(xn);
685
+      if (xn == NULL) goto err;
686
+      if (sk_X509_NAME_find(sk,xn) >= 0)
687
+	X509_NAME_free(xn);
688
+      else
689
+	{
690
+	  sk_X509_NAME_push(sk,xn);
691
+	  sk_X509_NAME_push(ret,xn);
692
+	}
693
+    }
694
+
695
+  if (0)
696
+    {
697
+    err:
698
+      if (ret != NULL) sk_X509_NAME_pop_free(ret,X509_NAME_free);
699
+      ret=NULL;
700
+    }
701
+  if (sk != NULL) sk_X509_NAME_free(sk);
702
+  if (in != NULL) BIO_free(in);
703
+  if (x != NULL) X509_free(x);
704
+  if (ret != NULL)
705
+    ERR_clear_error();
706
+  return(ret);
707
+}
708
+
709
+static int
710
+use_inline_load_verify_locations (SSL_CTX *ctx, const char *ca_string)
711
+{
712
+  X509_STORE *store = NULL;
713
+  X509* cert = NULL;
714
+  BIO *in = NULL;
715
+  int ret = 0;
716
+
717
+  in = BIO_new_mem_buf ((char *)ca_string, -1);
718
+  if (!in)
719
+    goto err;
720
+
721
+  for (;;)
722
+    {
723
+      if (!PEM_read_bio_X509 (in, &cert, 0, NULL))
724
+	{
725
+	  ret = 1;
726
+	  break;
727
+	}
728
+      if (!cert)
729
+	break;
730
+
731
+      store = SSL_CTX_get_cert_store (ctx);
732
+      if (!store)
733
+	break;
734
+
735
+      if (!X509_STORE_add_cert (store, cert))
736
+	break;
737
+
738
+      if (cert)
739
+	{
740
+	  X509_free (cert);
741
+	  cert = NULL;
742
+	}
743
+    }
744
+
745
+ err:
746
+  if (cert)
747
+    X509_free (cert);
748
+  if (in)
749
+    BIO_free (in);
750
+  return ret;
751
+}
752
+#endif /* ENABLE_INLINE_FILES */
753
+
754
+void
755
+tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
756
+#if ENABLE_INLINE_FILES
757
+    const char *ca_file_inline,
758
+#endif
759
+    const char *ca_path, bool tls_server
760
+    )
761
+{
762
+  int status;
763
+
764
+  ASSERT(NULL != ctx);
765
+
766
+#if ENABLE_INLINE_FILES
767
+  if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline)
768
+	{
769
+	  status = use_inline_load_verify_locations (ctx->ctx, ca_file_inline);
770
+	}
771
+  else
772
+#endif
773
+	{
774
+	  /* Load CA file for verifying peer supplied certificate */
775
+	  status = SSL_CTX_load_verify_locations (ctx->ctx, ca_file, ca_path);
776
+	}
777
+
778
+  if (!status)
779
+	msg (M_SSLERR, "Cannot load CA certificate file %s path %s (SSL_CTX_load_verify_locations)", np(ca_file), np(ca_path));
780
+
781
+  /* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */
782
+  if (ca_path) {
783
+    X509_STORE *store = SSL_CTX_get_cert_store(ctx->ctx);
784
+
785
+    if (store)
786
+	  {
787
+	    X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
788
+	    if (!X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM))
789
+	      X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
790
+	    else
791
+	      msg(M_WARN, "WARNING: experimental option --capath %s", ca_path);
792
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
793
+	    X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
794
+#else
795
+	    msg(M_WARN, "WARNING: this version of OpenSSL cannot handle CRL files in capath");
796
+#endif
797
+	  }
798
+	else
799
+      msg(M_SSLERR, "Cannot get certificate store (SSL_CTX_get_cert_store)");
800
+  }
801
+
802
+  /* Load names of CAs from file and use it as a client CA list */
803
+  if (ca_file && tls_server) {
804
+    STACK_OF(X509_NAME) *cert_names = NULL;
805
+#if ENABLE_INLINE_FILES
806
+	if (!strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline)
807
+	  {
808
+	    cert_names = use_inline_load_client_CA_file (ctx->ctx, ca_file_inline);
809
+	  }
810
+	else
811
+#endif
812
+	  {
813
+	    cert_names = SSL_load_client_CA_file (ca_file);
814
+	  }
815
+    if (!cert_names)
816
+      msg (M_SSLERR, "Cannot load CA certificate file %s (SSL_load_client_CA_file)", ca_file);
817
+    SSL_CTX_set_client_CA_list (ctx->ctx, cert_names);
818
+  }
819
+
820
+}
821
+
822
+void
823
+tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file
824
+#if ENABLE_INLINE_FILES
825
+    , const char *extra_certs_file_inline
826
+#endif
827
+    )
828
+{
829
+  BIO *bio;
830
+  X509 *cert;
831
+#if ENABLE_INLINE_FILES
832
+  if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline)
833
+    {
834
+      bio = BIO_new_mem_buf ((char *)extra_certs_file_inline, -1);
835
+    }
836
+  else
837
+#endif
838
+    {
839
+      bio = BIO_new(BIO_s_file());
840
+      if (BIO_read_filename(bio, extra_certs_file) <= 0)
841
+	msg (M_SSLERR, "Cannot load extra-certs file: %s", extra_certs_file);
842
+    }
843
+  for (;;)
844
+    {
845
+      cert = NULL;
846
+      if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */
847
+	break;
848
+      if (!cert)
849
+	msg (M_SSLERR, "Error reading extra-certs certificate");
850
+      if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1)
851
+	msg (M_SSLERR, "Error adding extra-certs certificate");
852
+    }
853
+  BIO_free (bio);
854
+}
855
+
648 856
 void
649 857
 show_available_tls_ciphers ()
650 858
 {