source: mod_gnutls/src/gnutls_config.c @ 8df5b25

debian/masterdebian/stretch-backportsjessie-backportsupstream upstream/0.4.3
Last change on this file since 8df5b25 was 8df5b25, checked in by Daniel Kahn Gillmor <dkg@…>, 8 years ago

Imported Upstream version 0.4.3

  • Property mode set to 100644
File size: 12.3 KB
Line 
1/**
2 *  Copyright 2004-2005 Paul Querna
3 *
4 *  Licensed under the Apache License, Version 2.0 (the "License");
5 *  you may not use this file except in compliance with the License.
6 *  You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 *  Unless required by applicable law or agreed to in writing, software
11 *  distributed under the License is distributed on an "AS IS" BASIS,
12 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 *  See the License for the specific language governing permissions and
14 *  limitations under the License.
15 *
16 */
17
18#include "mod_gnutls.h"
19
20static int load_datum_from_file(apr_pool_t * pool,
21                                const char *file, gnutls_datum_t * data)
22{
23    apr_file_t *fp;
24    apr_finfo_t finfo;
25    apr_status_t rv;
26    apr_size_t br = 0;
27
28    rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, APR_OS_DEFAULT,
29                       pool);
30    if (rv != APR_SUCCESS) {
31        return rv;
32    }
33
34    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
35
36    if (rv != APR_SUCCESS) {
37        return rv;
38    }
39
40    data->data = apr_palloc(pool, finfo.size + 1);
41    rv = apr_file_read_full(fp, data->data, finfo.size, &br);
42
43    if (rv != APR_SUCCESS) {
44        return rv;
45    }
46    apr_file_close(fp);
47
48    data->data[br] = '\0';
49    data->size = br;
50
51    return 0;
52}
53
54const char *mgs_set_dh_file(cmd_parms * parms, void *dummy,
55                            const char *arg)
56{
57    int ret;
58    gnutls_datum_t data;
59    const char *file;
60    apr_pool_t *spool;
61    mgs_srvconf_rec *sc =
62        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
63                                                 module_config,
64                                                 &gnutls_module);
65
66    apr_pool_create(&spool, parms->pool);
67
68    file = ap_server_root_relative(spool, arg);
69
70    if (load_datum_from_file(spool, file, &data) != 0) {
71        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
72                            "DH params '%s'", file);
73    }
74
75    ret = gnutls_dh_params_init(&sc->dh_params);
76    if (ret < 0) {
77        return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize"
78                            ": (%d) %s", ret, gnutls_strerror(ret));
79    }
80
81    ret =
82        gnutls_dh_params_import_pkcs3(sc->dh_params, &data, GNUTLS_X509_FMT_PEM);
83    if (ret < 0) {
84        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
85                            "DH params '%s': (%d) %s", file, ret,
86                            gnutls_strerror(ret));
87    }
88
89    apr_pool_destroy(spool);
90
91    return NULL;
92}
93
94const char *mgs_set_rsa_export_file(cmd_parms * parms, void *dummy,
95                                    const char *arg)
96{
97    int ret;
98    gnutls_datum_t data;
99    const char *file;
100    apr_pool_t *spool;
101    mgs_srvconf_rec *sc =
102        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
103                                                 module_config,
104                                                 &gnutls_module);
105
106    apr_pool_create(&spool, parms->pool);
107
108    file = ap_server_root_relative(spool, arg);
109
110    if (load_datum_from_file(spool, file, &data) != 0) {
111        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
112                            "RSA params '%s'", file);
113    }
114
115    ret = gnutls_rsa_params_init(&sc->rsa_params);
116    if (ret < 0) {
117        return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize"
118                            ": (%d) %s", ret, gnutls_strerror(ret));
119    }
120
121    ret =
122        gnutls_rsa_params_import_pkcs1(sc->rsa_params, &data, GNUTLS_X509_FMT_PEM);
123    if (ret != 0) {
124        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
125                            "RSA params '%s': (%d) %s", file, ret,
126                            gnutls_strerror(ret));
127    }
128
129    apr_pool_destroy(spool);
130    return NULL;
131}
132
133
134const char *mgs_set_cert_file(cmd_parms * parms, void *dummy,
135                              const char *arg)
136{
137    int ret;
138    gnutls_datum_t data;
139    const char *file;
140    apr_pool_t *spool;
141    mgs_srvconf_rec *sc =
142        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
143                                                 module_config,
144                                                 &gnutls_module);
145    apr_pool_create(&spool, parms->pool);
146
147    file = ap_server_root_relative(spool, arg);
148
149    if (load_datum_from_file(spool, file, &data) != 0) {
150        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
151                            "Certificate '%s'", file);
152    }
153
154    sc->certs_x509_num = MAX_CHAIN_SIZE;
155    ret =
156        gnutls_x509_crt_list_import(sc->certs_x509, &sc->certs_x509_num, &data, GNUTLS_X509_FMT_PEM, 0);
157    if (ret < 0) {
158        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
159                            "Certificate '%s': (%d) %s", file, ret,
160                            gnutls_strerror(ret));
161    }
162
163    apr_pool_destroy(spool);
164    return NULL;
165}
166
167const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
168                             const char *arg)
169{
170    int ret;
171    gnutls_datum_t data;
172    const char *file;
173    apr_pool_t *spool;
174    mgs_srvconf_rec *sc =
175        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
176                                                 module_config,
177                                                 &gnutls_module);
178    apr_pool_create(&spool, parms->pool);
179
180    file = ap_server_root_relative(spool, arg);
181
182    if (load_datum_from_file(spool, file, &data) != 0) {
183        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
184                            "Private Key '%s'", file);
185    }
186
187    ret = gnutls_x509_privkey_init(&sc->privkey_x509);
188    if (ret < 0) {
189        return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize"
190                            ": (%d) %s", ret, gnutls_strerror(ret));
191    }
192
193    ret =
194        gnutls_x509_privkey_import(sc->privkey_x509, &data,
195                                   GNUTLS_X509_FMT_PEM);
196    if (ret != 0) {
197        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
198                            "Private Key '%s': (%d) %s", file, ret,
199                            gnutls_strerror(ret));
200    }
201    apr_pool_destroy(spool);
202    return NULL;
203}
204
205#ifdef ENABLE_SRP
206
207const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy,
208                                     const char *arg)
209{
210    mgs_srvconf_rec *sc =
211        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
212                                                 module_config,
213                                                 &gnutls_module);
214
215    sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
216
217    return NULL;
218}
219
220const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
221                                          const char *arg)
222{
223    mgs_srvconf_rec *sc =
224        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
225                                                 module_config,
226                                                 &gnutls_module);
227
228    sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg);
229
230    return NULL;
231}
232
233#endif
234
235const char *mgs_set_cache(cmd_parms * parms, void *dummy,
236                          const char *type, const char *arg)
237{
238    const char *err;
239    mgs_srvconf_rec *sc = ap_get_module_config(parms->server->
240                                               module_config,
241                                               &gnutls_module);
242    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
243        return err;
244    }
245
246    if (strcasecmp("none", type) == 0) {
247        sc->cache_type = mgs_cache_none;
248    } else if (strcasecmp("dbm", type) == 0) {
249        sc->cache_type = mgs_cache_dbm;
250    }
251#if HAVE_APR_MEMCACHE
252    else if (strcasecmp("memcache", type) == 0) {
253        sc->cache_type = mgs_cache_memcache;
254    }
255#endif
256    else {
257        return "Invalid Type for GnuTLSCache!";
258    }
259
260    if (sc->cache_type == mgs_cache_dbm) {
261        sc->cache_config = ap_server_root_relative(parms->pool, arg);
262    } else {
263        sc->cache_config = apr_pstrdup(parms->pool, arg);
264    }
265
266    return NULL;
267}
268
269const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
270                                  const char *arg)
271{
272    int argint;
273    mgs_srvconf_rec *sc =
274        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
275                                                 module_config,
276                                                 &gnutls_module);
277
278    argint = atoi(arg);
279
280    if (argint < 0) {
281        return "GnuTLSCacheTimeout: Invalid argument";
282    } else if (argint == 0) {
283        sc->cache_timeout = 0;
284    } else {
285        sc->cache_timeout = apr_time_from_sec(argint);
286    }
287
288    return NULL;
289}
290
291const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
292                                  const char *arg)
293{
294    int mode;
295
296    if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
297        mode = GNUTLS_CERT_IGNORE;
298    } else if (strcasecmp("optional", arg) == 0
299               || strcasecmp("request", arg) == 0) {
300        mode = GNUTLS_CERT_REQUEST;
301    } else if (strcasecmp("require", arg) == 0) {
302        mode = GNUTLS_CERT_REQUIRE;
303    } else {
304        return "GnuTLSClientVerify: Invalid argument";
305    }
306
307    /* This was set from a directory context */
308    if (parms->path) {
309        mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dummy;
310        dc->client_verify_mode = mode;
311    } else {
312        mgs_srvconf_rec *sc =
313            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
314                                                     module_config,
315                                                     &gnutls_module);
316        sc->client_verify_mode = mode;
317    }
318
319    return NULL;
320}
321
322const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
323                                   const char *arg)
324{
325    int rv;
326    const char *file;
327    apr_pool_t *spool;
328    gnutls_datum_t data;
329
330    mgs_srvconf_rec *sc =
331        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
332                                                 module_config,
333                                                 &gnutls_module);
334    apr_pool_create(&spool, parms->pool);
335
336    file = ap_server_root_relative(spool, arg);
337
338    if (load_datum_from_file(spool, file, &data) != 0) {
339        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
340                            "Client CA File '%s'", file);
341    }
342
343    sc->ca_list_size = MAX_CA_CRTS;
344    rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size,
345                                     &data, GNUTLS_X509_FMT_PEM,
346                                     GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
347    if (rv < 0) {
348        return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
349                            "Client CA File '%s': (%d) %s", file, rv,
350                            gnutls_strerror(rv));
351    }
352
353    apr_pool_destroy(spool);
354    return NULL;
355}
356
357const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
358                            const char *arg)
359{
360    mgs_srvconf_rec *sc =
361        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
362                                                 module_config,
363                                                 &gnutls_module);
364    if (!strcasecmp(arg, "On")) {
365        sc->enabled = GNUTLS_ENABLED_TRUE;
366    } else if (!strcasecmp(arg, "Off")) {
367        sc->enabled = GNUTLS_ENABLED_FALSE;
368    } else {
369        return "GnuTLSEnable must be set to 'On' or 'Off'";
370    }
371
372    return NULL;
373}
374
375const char *mgs_set_export_certificates_enabled(cmd_parms * parms, void *dummy,
376                            const char *arg)
377{
378    mgs_srvconf_rec *sc =
379        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
380                                                 module_config,
381                                                 &gnutls_module);
382    if (!strcasecmp(arg, "On")) {
383        sc->export_certificates_enabled = GNUTLS_ENABLED_TRUE;
384    } else if (!strcasecmp(arg, "Off")) {
385        sc->export_certificates_enabled = GNUTLS_ENABLED_FALSE;
386    } else {
387        return "GnuTLSExportCertificates must be set to 'On' or 'Off'";
388    }
389
390    return NULL;
391}
392
393
394const char *mgs_set_priorities(cmd_parms * parms, void *dummy, const char *arg)
395{
396    int ret;
397    const char *err;
398    mgs_srvconf_rec *sc =
399        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
400                                                 module_config,
401                                                 &gnutls_module);
402
403
404    ret = gnutls_priority_init( &sc->priorities, arg, &err);
405    if (ret < 0) {
406      if (ret == GNUTLS_E_INVALID_REQUEST)
407        return apr_psprintf(parms->pool, "GnuTLS: Syntax error parsing priorities string at: %s", err);
408      return "Error setting priorities";
409    }
410
411    return NULL;
412}
413
414void *mgs_config_server_create(apr_pool_t * p, server_rec * s)
415{
416    mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
417    int ret;
418   
419    sc->enabled = GNUTLS_ENABLED_FALSE;
420
421    ret = gnutls_certificate_allocate_credentials(&sc->certs);
422    if (ret < 0) {
423        return apr_psprintf(p, "GnuTLS: Failed to initialize"
424                            ": (%d) %s", ret, gnutls_strerror(ret));
425    }
426
427    ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
428    if (ret < 0) {
429        return apr_psprintf(p, "GnuTLS: Failed to initialize"
430                            ": (%d) %s", ret, gnutls_strerror(ret));
431    }
432
433#ifdef ENABLE_SRP
434    ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
435    if (ret < 0) {
436        return apr_psprintf(p, "GnuTLS: Failed to initialize"
437                            ": (%d) %s", ret, gnutls_strerror(ret));
438    }
439
440    sc->srp_tpasswd_conf_file = NULL;
441    sc->srp_tpasswd_file = NULL;
442#endif
443
444    sc->privkey_x509 = NULL;
445    memset( sc->certs_x509, 0, sizeof(sc->certs_x509));
446    sc->certs_x509_num = 0;
447    sc->cache_timeout = apr_time_from_sec(300);
448    sc->cache_type = mgs_cache_dbm;
449    sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache");
450
451    sc->client_verify_mode = GNUTLS_CERT_IGNORE;
452
453    return sc;
454}
455
456void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv)
457{
458    mgs_dirconf_rec *new;
459/*    mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */
460    mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
461
462    new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec));
463    new->lua_bytecode = apr_pstrmemdup(p, add->lua_bytecode,
464                                       add->lua_bytecode_len);
465    new->lua_bytecode_len = add->lua_bytecode_len;
466    new->client_verify_mode = add->client_verify_mode;
467    return new;
468}
469
470void *mgs_config_dir_create(apr_pool_t * p, char *dir)
471{
472    mgs_dirconf_rec *dc = apr_palloc(p, sizeof(*dc));
473
474    dc->client_verify_mode = -1;
475    dc->lua_bytecode = NULL;
476    dc->lua_bytecode_len = 0;
477    return dc;
478}
Note: See TracBrowser for help on using the repository browser.