Lines 33-40
Link Here
|
33 |
#include "mod_md.h" |
33 |
#include "mod_md.h" |
34 |
|
34 |
|
35 |
static apr_status_t ssl_init_ca_cert_path(server_rec *, apr_pool_t *, const char *, |
35 |
static apr_status_t ssl_init_ca_cert_path(server_rec *, apr_pool_t *, const char *, |
36 |
STACK_OF(X509_NAME) *, STACK_OF(X509_INFO) *); |
36 |
STACK_OF(X509_NAME) *, STACK_OF(X509_INFO) *, |
|
|
37 |
int nocanon); |
37 |
|
38 |
|
|
|
39 |
/* Returns a stack of X509_NAMEs corresponding to the subject names of |
40 |
* every cert found from in either or both of PEM file 'file' or |
41 |
* directory of PEM files, 'dir'. The set of names returned are |
42 |
* unique, with comparison after canonicalization if nocanon is zero, |
43 |
* or using a bitwise comparison otherwise. */ |
44 |
static STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, apr_pool_t *p, |
45 |
const char *file, const char *dir, |
46 |
int nocanon); |
47 |
|
38 |
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_server, |
48 |
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_server, |
39 |
(server_rec *s,apr_pool_t *p,int is_proxy,SSL_CTX *ctx), |
49 |
(server_rec *s,apr_pool_t *p,int is_proxy,SSL_CTX *ctx), |
40 |
(s,p,is_proxy,ctx), OK, DECLINED) |
50 |
(s,p,is_proxy,ctx), OK, DECLINED) |
Lines 868-878
Link Here
|
868 |
if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) { |
878 |
if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) { |
869 |
ca_list = ssl_init_FindCAList(s, ptemp, |
879 |
ca_list = ssl_init_FindCAList(s, ptemp, |
870 |
mctx->pks->ca_name_file, |
880 |
mctx->pks->ca_name_file, |
871 |
mctx->pks->ca_name_path); |
881 |
mctx->pks->ca_name_path, |
|
|
882 |
1 /* no canonicalization */); |
872 |
} else |
883 |
} else |
873 |
ca_list = ssl_init_FindCAList(s, ptemp, |
884 |
ca_list = ssl_init_FindCAList(s, ptemp, |
874 |
mctx->auth.ca_cert_file, |
885 |
mctx->auth.ca_cert_file, |
875 |
mctx->auth.ca_cert_path); |
886 |
mctx->auth.ca_cert_path, |
|
|
887 |
0 /* with canonicalization */); |
876 |
if (sk_X509_NAME_num(ca_list) <= 0) { |
888 |
if (sk_X509_NAME_num(ca_list) <= 0) { |
877 |
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01896) |
889 |
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01896) |
878 |
"Unable to determine list of acceptable " |
890 |
"Unable to determine list of acceptable " |
Lines 1504-1510
Link Here
|
1504 |
} |
1516 |
} |
1505 |
|
1517 |
|
1506 |
if (pkp->cert_path) { |
1518 |
if (pkp->cert_path) { |
1507 |
ssl_init_ca_cert_path(s, ptemp, pkp->cert_path, NULL, sk); |
1519 |
ssl_init_ca_cert_path(s, ptemp, pkp->cert_path, NULL, sk, 0); |
1508 |
} |
1520 |
} |
1509 |
|
1521 |
|
1510 |
if ((ncerts = sk_X509_INFO_num(sk)) <= 0) { |
1522 |
if ((ncerts = sk_X509_INFO_num(sk)) <= 0) { |
Lines 2016-2031
Link Here
|
2016 |
return(X509_NAME_cmp(*a, *b)); |
2028 |
return(X509_NAME_cmp(*a, *b)); |
2017 |
} |
2029 |
} |
2018 |
|
2030 |
|
|
|
2031 |
static int ssl_init_FindCAList_X509BitNameCmp(const X509_NAME * const *a, |
2032 |
const X509_NAME * const *b) |
2033 |
{ |
2034 |
unsigned char *xa = NULL, *xb = NULL; |
2035 |
int lena, lenb, rv; |
2036 |
|
2037 |
/* X509_NAME_cmp() itself casts away constness in this way, so |
2038 |
* assume it's safe: */ |
2039 |
lena = i2d_X509_NAME((X509_NAME *)*a, &xa); |
2040 |
lenb = i2d_X509_NAME((X509_NAME *)*b, &xb); |
2041 |
|
2042 |
if (lena < 0 || lenb < 0) |
2043 |
rv = -2; |
2044 |
else if (lena != lenb) |
2045 |
rv = lena - lenb; |
2046 |
else /* lena == lenb */ |
2047 |
rv = memcmp(xa, xb, lena); |
2048 |
|
2049 |
OPENSSL_free(xa); |
2050 |
OPENSSL_free(xb); |
2051 |
|
2052 |
return rv; |
2053 |
} |
2054 |
|
2055 |
static STACK_OF(X509_NAME) *load_x509_names(const char *file) |
2056 |
{ |
2057 |
BIO *bio; |
2058 |
X509 *x509; |
2059 |
STACK_OF(X509_NAME) *sk = sk_X509_NAME_new_null(); |
2060 |
|
2061 |
if ((bio = BIO_new(BIO_s_file())) == NULL) |
2062 |
return sk; |
2063 |
if (BIO_read_filename(bio, file) <= 0) { |
2064 |
BIO_free(bio); |
2065 |
ERR_clear_error(); |
2066 |
return sk; |
2067 |
} |
2068 |
|
2069 |
while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { |
2070 |
X509_NAME *name = X509_get_subject_name(x509); |
2071 |
|
2072 |
sk_X509_NAME_push(sk, X509_NAME_dup(name)); |
2073 |
|
2074 |
X509_free(x509); |
2075 |
} |
2076 |
|
2077 |
ERR_clear_error(); |
2078 |
BIO_free(bio); |
2079 |
|
2080 |
return sk; |
2081 |
} |
2082 |
|
2019 |
static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list, |
2083 |
static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list, |
2020 |
server_rec *s, apr_pool_t *ptemp, |
2084 |
server_rec *s, apr_pool_t *ptemp, |
2021 |
const char *file) |
2085 |
const char *file, int nocanon) |
2022 |
{ |
2086 |
{ |
2023 |
int n; |
2087 |
int n; |
2024 |
STACK_OF(X509_NAME) *sk; |
2088 |
STACK_OF(X509_NAME) *sk; |
2025 |
|
2089 |
|
2026 |
sk = (STACK_OF(X509_NAME) *) |
2090 |
if (nocanon) { |
2027 |
SSL_load_client_CA_file(file); |
2091 |
/* SSL_load_client_CA_file() uses X509_NAME_cmp() internally |
2028 |
|
2092 |
* with canonical name comparison; to avoid that use a simpler |
|
|
2093 |
* replacement for that function. */ |
2094 |
sk = load_x509_names(file); |
2095 |
} |
2096 |
else { |
2097 |
sk = SSL_load_client_CA_file(file); |
2098 |
} |
2099 |
|
2029 |
if (!sk) { |
2100 |
if (!sk) { |
2030 |
return; |
2101 |
return; |
2031 |
} |
2102 |
} |
Lines 2060-2066
Link Here
|
2060 |
apr_pool_t *ptemp, |
2131 |
apr_pool_t *ptemp, |
2061 |
const char *path, |
2132 |
const char *path, |
2062 |
STACK_OF(X509_NAME) *ca_list, |
2133 |
STACK_OF(X509_NAME) *ca_list, |
2063 |
STACK_OF(X509_INFO) *xi_list) |
2134 |
STACK_OF(X509_INFO) *xi_list, |
|
|
2135 |
int nocanon) |
2064 |
{ |
2136 |
{ |
2065 |
apr_dir_t *dir; |
2137 |
apr_dir_t *dir; |
2066 |
apr_finfo_t direntry; |
2138 |
apr_finfo_t direntry; |
Lines 2078-2084
Link Here
|
2078 |
} |
2150 |
} |
2079 |
file = apr_pstrcat(ptemp, path, "/", direntry.name, NULL); |
2151 |
file = apr_pstrcat(ptemp, path, "/", direntry.name, NULL); |
2080 |
if (ca_list) { |
2152 |
if (ca_list) { |
2081 |
ssl_init_PushCAList(ca_list, s, ptemp, file); |
2153 |
ssl_init_PushCAList(ca_list, s, ptemp, file, nocanon); |
2082 |
} |
2154 |
} |
2083 |
if (xi_list) { |
2155 |
if (xi_list) { |
2084 |
load_x509_info(ptemp, xi_list, file); |
2156 |
load_x509_info(ptemp, xi_list, file); |
Lines 2093-2099
Link Here
|
2093 |
STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, |
2165 |
STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, |
2094 |
apr_pool_t *ptemp, |
2166 |
apr_pool_t *ptemp, |
2095 |
const char *ca_file, |
2167 |
const char *ca_file, |
2096 |
const char *ca_path) |
2168 |
const char *ca_path, |
|
|
2169 |
int nocanon) |
2097 |
{ |
2170 |
{ |
2098 |
STACK_OF(X509_NAME) *ca_list; |
2171 |
STACK_OF(X509_NAME) *ca_list; |
2099 |
|
2172 |
|
Lines 2101-2113
Link Here
|
2101 |
* Start with a empty stack/list where new |
2174 |
* Start with a empty stack/list where new |
2102 |
* entries get added in sorted order. |
2175 |
* entries get added in sorted order. |
2103 |
*/ |
2176 |
*/ |
2104 |
ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp); |
2177 |
if (nocanon) |
|
|
2178 |
ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509BitNameCmp); |
2179 |
else |
2180 |
ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp); |
2105 |
|
2181 |
|
2106 |
/* |
2182 |
/* |
2107 |
* Process CA certificate bundle file |
2183 |
* Process CA certificate bundle file |
2108 |
*/ |
2184 |
*/ |
2109 |
if (ca_file) { |
2185 |
if (ca_file) { |
2110 |
ssl_init_PushCAList(ca_list, s, ptemp, ca_file); |
2186 |
ssl_init_PushCAList(ca_list, s, ptemp, ca_file, nocanon); |
2111 |
/* |
2187 |
/* |
2112 |
* If ca_list is still empty after trying to load ca_file |
2188 |
* If ca_list is still empty after trying to load ca_file |
2113 |
* then the file failed to load, and users should hear about that. |
2189 |
* then the file failed to load, and users should hear about that. |
Lines 2124-2130
Link Here
|
2124 |
*/ |
2200 |
*/ |
2125 |
if (ca_path && |
2201 |
if (ca_path && |
2126 |
ssl_init_ca_cert_path(s, ptemp, |
2202 |
ssl_init_ca_cert_path(s, ptemp, |
2127 |
ca_path, ca_list, NULL) != APR_SUCCESS) { |
2203 |
ca_path, ca_list, NULL, nocanon) != APR_SUCCESS) { |
2128 |
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02211) |
2204 |
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02211) |
2129 |
"Failed to open Certificate Path `%s'", ca_path); |
2205 |
"Failed to open Certificate Path `%s'", ca_path); |
2130 |
sk_X509_NAME_pop_free(ca_list, X509_NAME_free); |
2206 |
sk_X509_NAME_pop_free(ca_list, X509_NAME_free); |