source: mod_gnutls/src/gnutls_config.c @ 787dab7

debian/masterdebian/stretch-backportsjessie-backportsmsvaupstream
Last change on this file since 787dab7 was 787dab7, checked in by Nokis Mavrogiannopoulos <nmav@…>, 12 years ago

added option to disable srp (for distributions that disable it in gnutls)

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