| 1775 | #endif |
| 1776 | |
| 1777 | int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey) |
| 1778 | { |
| 1779 | conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
| 1780 | server_rec *s = mySrvFromConn(c); |
| 1781 | SSLSrvConfigRec *sc = mySrvConfig(s); |
| 1782 | SSLDirConfigRec *dc = myDirConfigFromConn(c); |
| 1783 | const X509_NAME *ca_name, *issuer, *ca_issuer; |
| 1784 | X509_INFO *info; |
| 1785 | X509 *ca_cert; |
| 1786 | STACK_OF(X509_NAME) *ca_list; |
| 1787 | STACK_OF(X509_INFO) *certs; |
| 1788 | STACK_OF(X509) *ca_certs; |
| 1789 | STACK_OF(X509) **ca_cert_chains; |
| 1790 | int i, j, k; |
| 1791 | |
| 1792 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02267) |
| 1793 | SSLPROXY_CERT_CB_LOG_FMT "entered", |
| 1794 | sc->vhost_id); |
| 1795 | |
| 1796 | certs = (dc && dc->proxy) ? dc->proxy->pkp->certs : NULL; |
| 1797 | if (!certs || (sk_X509_INFO_num(certs) <= 0)) { |
| 1798 | ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02268) |
| 1799 | SSLPROXY_CERT_CB_LOG_FMT |
| 1800 | "downstream server wanted client certificate " |
| 1801 | "but none are configured", sc->vhost_id); |
| 1802 | return FALSE; |
| 1803 | } |
| 1804 | |
| 1805 | ca_list = SSL_get_client_CA_list(ssl); |
| 1806 | |
| 1807 | if (!ca_list || (sk_X509_NAME_num(ca_list) <= 0)) { |
| 1808 | /* |
| 1809 | * downstream server didn't send us a list of acceptable CA certs, |
| 1810 | * so we send the first client cert in the list. |
| 1811 | */ |
| 1812 | info = sk_X509_INFO_value(certs, 0); |
| 1813 | |
| 1814 | modssl_proxy_info_log(c, info, APLOGNO(02278) "no acceptable CA list"); |
| 1815 | |
| 1816 | modssl_set_cert_info(info, x509, pkey); |
| 1817 | |
| 1818 | return TRUE; |
| 1819 | } |
| 1820 | |
| 1821 | ca_cert_chains = dc->proxy->pkp->ca_certs; |
| 1822 | for (i = 0; i < sk_X509_NAME_num(ca_list); i++) { |
| 1823 | ca_name = sk_X509_NAME_value(ca_list, i); |
| 1824 | |
| 1825 | for (j = 0; j < sk_X509_INFO_num(certs); j++) { |
| 1826 | info = sk_X509_INFO_value(certs, j); |
| 1827 | issuer = X509_get_issuer_name(info->x509); |
| 1828 | |
| 1829 | /* Search certs (by issuer name) one by one*/ |
| 1830 | if (X509_NAME_cmp(issuer, ca_name) == 0) { |
| 1831 | modssl_proxy_info_log(c, info, APLOGNO(02279) |
| 1832 | "found acceptable cert"); |
| 1833 | |
| 1834 | modssl_set_cert_info(info, x509, pkey); |
nothing calls this directly
no test coverage detected