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>
... | ... |
@@ -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 |
{ |