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

asynciodebian/masterdebian/stretch-backportsjessie-backportsmsvaproxy-ticketupstream
Last change on this file since 8bd529f was e5bbda4, checked in by Nokis Mavrogiannopoulos <nmav@…>, 13 years ago

Initial support for openpgp keys

  • Property mode set to 100644
File size: 15.2 KB
RevLine 
[46b85d8]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
[7bebb42]20static int load_datum_from_file(apr_pool_t * pool,
21                                const char *file, gnutls_datum_t * data)
[46b85d8]22{
[7bebb42]23    apr_file_t *fp;
[46b85d8]24    apr_finfo_t finfo;
25    apr_status_t rv;
26    apr_size_t br = 0;
[7bebb42]27
28    rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, APR_OS_DEFAULT,
29                       pool);
[46b85d8]30    if (rv != APR_SUCCESS) {
[7bebb42]31        return rv;
[46b85d8]32    }
[7bebb42]33
[46b85d8]34    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
[7bebb42]35
[46b85d8]36    if (rv != APR_SUCCESS) {
[7bebb42]37        return rv;
[46b85d8]38    }
[7bebb42]39
40    data->data = apr_palloc(pool, finfo.size + 1);
[46b85d8]41    rv = apr_file_read_full(fp, data->data, finfo.size, &br);
[7bebb42]42
[46b85d8]43    if (rv != APR_SUCCESS) {
[7bebb42]44        return rv;
[46b85d8]45    }
46    apr_file_close(fp);
[7bebb42]47
[46b85d8]48    data->data[br] = '\0';
49    data->size = br;
[7bebb42]50
[46b85d8]51    return 0;
52}
53
[7bebb42]54const char *mgs_set_dh_file(cmd_parms * parms, void *dummy,
55                            const char *arg)
56{
[a3c97d1]57    int ret;
58    gnutls_datum_t data;
59    const char *file;
60    apr_pool_t *spool;
[7bebb42]61    mgs_srvconf_rec *sc =
62        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
63                                                 module_config,
64                                                 &gnutls_module);
65
[a3c97d1]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
[b077bdd]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
[a3c97d1]81    ret =
82        gnutls_dh_params_import_pkcs3(sc->dh_params, &data, GNUTLS_X509_FMT_PEM);
[b077bdd]83    if (ret < 0) {
[a3c97d1]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);
[7bebb42]90
91    return NULL;
92}
93
94const char *mgs_set_rsa_export_file(cmd_parms * parms, void *dummy,
95                                    const char *arg)
96{
[a3c97d1]97    int ret;
98    gnutls_datum_t data;
99    const char *file;
100    apr_pool_t *spool;
[7bebb42]101    mgs_srvconf_rec *sc =
102        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
103                                                 module_config,
104                                                 &gnutls_module);
105
[a3c97d1]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
[b077bdd]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
[a3c97d1]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    }
[7bebb42]128
[a3c97d1]129    apr_pool_destroy(spool);
[7bebb42]130    return NULL;
131}
132
133
[46b85d8]134const char *mgs_set_cert_file(cmd_parms * parms, void *dummy,
[7bebb42]135                              const char *arg)
[46b85d8]136{
137    int ret;
138    gnutls_datum_t data;
[7bebb42]139    const char *file;
140    apr_pool_t *spool;
[c301152]141    mgs_srvconf_rec *sc =
[7bebb42]142        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
143                                                 module_config,
144                                                 &gnutls_module);
[46b85d8]145    apr_pool_create(&spool, parms->pool);
[7bebb42]146
[46b85d8]147    file = ap_server_root_relative(spool, arg);
148
149    if (load_datum_from_file(spool, file, &data) != 0) {
[7bebb42]150        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
151                            "Certificate '%s'", file);
[46b85d8]152    }
[7bebb42]153
[5e81262]154    sc->certs_x509_num = MAX_CHAIN_SIZE;
[7bebb42]155    ret =
[5e81262]156        gnutls_x509_crt_list_import(sc->certs_x509, &sc->certs_x509_num, &data, GNUTLS_X509_FMT_PEM, 0);
157    if (ret < 0) {
[7bebb42]158        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
[a3c97d1]159                            "Certificate '%s': (%d) %s", file, ret,
[7bebb42]160                            gnutls_strerror(ret));
[46b85d8]161    }
[7bebb42]162
[46b85d8]163    apr_pool_destroy(spool);
164    return NULL;
165}
166
167const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
[7bebb42]168                             const char *arg)
[46b85d8]169{
170    int ret;
171    gnutls_datum_t data;
[7bebb42]172    const char *file;
173    apr_pool_t *spool;
[c301152]174    mgs_srvconf_rec *sc =
[7bebb42]175        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
176                                                 module_config,
177                                                 &gnutls_module);
[46b85d8]178    apr_pool_create(&spool, parms->pool);
[7bebb42]179
[46b85d8]180    file = ap_server_root_relative(spool, arg);
[7bebb42]181
[46b85d8]182    if (load_datum_from_file(spool, file, &data) != 0) {
[7bebb42]183        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
184                            "Private Key '%s'", file);
[46b85d8]185    }
[7bebb42]186
[b077bdd]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
[7bebb42]193    ret =
194        gnutls_x509_privkey_import(sc->privkey_x509, &data,
195                                   GNUTLS_X509_FMT_PEM);
[46b85d8]196    if (ret != 0) {
[7bebb42]197        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
198                            "Private Key '%s': (%d) %s", file, ret,
199                            gnutls_strerror(ret));
[46b85d8]200    }
201    apr_pool_destroy(spool);
202    return NULL;
203}
204
[e5bbda4]205const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy,
206                              const char *arg)
207{
208    int ret;
209    gnutls_datum_t data;
210    const char *file;
211    apr_pool_t *spool;
212    mgs_srvconf_rec *sc =
213        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
214                                                 module_config,
215                                                 &gnutls_module);
216    apr_pool_create(&spool, parms->pool);
217
218    file = ap_server_root_relative(spool, arg);
219
220    if (load_datum_from_file(spool, file, &data) != 0) {
221        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
222                            "Certificate '%s'", file);
223    }
224
225    ret = gnutls_openpgp_crt_init( &sc->cert_pgp);
226    if (ret < 0) {
227        return apr_psprintf(parms->pool, "GnuTLS: Failed to Init "
228                            "PGP Certificate: (%d) %s", ret,
229                            gnutls_strerror(ret));
230    }
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
[7bebb42]284const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy,
285                                     const char *arg)
286{
287    mgs_srvconf_rec *sc =
288        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
289                                                 module_config,
290                                                 &gnutls_module);
291
292    sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
293
294    return NULL;
295}
296
297const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
298                                          const char *arg)
299{
300    mgs_srvconf_rec *sc =
301        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
302                                                 module_config,
303                                                 &gnutls_module);
304
305    sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg);
306
307    return NULL;
308}
309
[46b85d8]310const char *mgs_set_cache(cmd_parms * parms, void *dummy,
[7bebb42]311                          const char *type, const char *arg)
[46b85d8]312{
[7bebb42]313    const char *err;
[c301152]314    mgs_srvconf_rec *sc = ap_get_module_config(parms->server->
[7bebb42]315                                               module_config,
316                                               &gnutls_module);
[46b85d8]317    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
[7bebb42]318        return err;
[46b85d8]319    }
320
321    if (strcasecmp("none", type) == 0) {
[7bebb42]322        sc->cache_type = mgs_cache_none;
323    } else if (strcasecmp("dbm", type) == 0) {
324        sc->cache_type = mgs_cache_dbm;
[46b85d8]325    }
326#if HAVE_APR_MEMCACHE
327    else if (strcasecmp("memcache", type) == 0) {
[7bebb42]328        sc->cache_type = mgs_cache_memcache;
[46b85d8]329    }
330#endif
331    else {
[7bebb42]332        return "Invalid Type for GnuTLSCache!";
[46b85d8]333    }
334
[c301152]335    if (sc->cache_type == mgs_cache_dbm) {
[7bebb42]336        sc->cache_config = ap_server_root_relative(parms->pool, arg);
337    } else {
338        sc->cache_config = apr_pstrdup(parms->pool, arg);
[46b85d8]339    }
340
341    return NULL;
342}
343
344const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
[7bebb42]345                                  const char *arg)
[46b85d8]346{
347    int argint;
[c301152]348    mgs_srvconf_rec *sc =
[7bebb42]349        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
350                                                 module_config,
351                                                 &gnutls_module);
352
[46b85d8]353    argint = atoi(arg);
[7bebb42]354
[46b85d8]355    if (argint < 0) {
[7bebb42]356        return "GnuTLSCacheTimeout: Invalid argument";
357    } else if (argint == 0) {
358        sc->cache_timeout = 0;
359    } else {
360        sc->cache_timeout = apr_time_from_sec(argint);
[46b85d8]361    }
[7bebb42]362
[46b85d8]363    return NULL;
364}
365
366const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
[7bebb42]367                                  const char *arg)
[46b85d8]368{
369    int mode;
370
371    if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
[7bebb42]372        mode = GNUTLS_CERT_IGNORE;
373    } else if (strcasecmp("optional", arg) == 0
374               || strcasecmp("request", arg) == 0) {
375        mode = GNUTLS_CERT_REQUEST;
376    } else if (strcasecmp("require", arg) == 0) {
377        mode = GNUTLS_CERT_REQUIRE;
378    } else {
379        return "GnuTLSClientVerify: Invalid argument";
[46b85d8]380    }
[7bebb42]381
[46b85d8]382    /* This was set from a directory context */
383    if (parms->path) {
[7bebb42]384        mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dummy;
385        dc->client_verify_mode = mode;
386    } else {
387        mgs_srvconf_rec *sc =
388            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
389                                                     module_config,
390                                                     &gnutls_module);
391        sc->client_verify_mode = mode;
[46b85d8]392    }
393
394    return NULL;
395}
396
397const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
[7bebb42]398                                   const char *arg)
[46b85d8]399{
400    int rv;
[7bebb42]401    const char *file;
402    apr_pool_t *spool;
[836c2f9]403    gnutls_datum_t data;
404
[7bebb42]405    mgs_srvconf_rec *sc =
406        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
407                                                 module_config,
408                                                 &gnutls_module);
[836c2f9]409    apr_pool_create(&spool, parms->pool);
410
411    file = ap_server_root_relative(spool, arg);
412
[7bebb42]413    if (load_datum_from_file(spool, file, &data) != 0) {
414        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
415                            "Client CA File '%s'", file);
416    }
[836c2f9]417
[7bebb42]418    sc->ca_list_size = MAX_CA_CRTS;
419    rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size,
420                                     &data, GNUTLS_X509_FMT_PEM,
421                                     GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
[46b85d8]422    if (rv < 0) {
[7bebb42]423        return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
424                            "Client CA File '%s': (%d) %s", file, rv,
425                            gnutls_strerror(rv));
[46b85d8]426    }
[836c2f9]427
428    apr_pool_destroy(spool);
[46b85d8]429    return NULL;
430}
431
[e5bbda4]432const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
433                                   const char *arg)
434{
435    int rv;
436    const char *file;
437    apr_pool_t *spool;
438    gnutls_datum_t data;
439
440    mgs_srvconf_rec *sc =
441        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
442                                                 module_config,
443                                                 &gnutls_module);
444    apr_pool_create(&spool, parms->pool);
445
446    file = ap_server_root_relative(spool, arg);
447
448    if (load_datum_from_file(spool, file, &data) != 0) {
449        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
450                            "Keyring File '%s'", file);
451    }
452
453    rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data, GNUTLS_OPENPGP_FMT_BASE64);
454    if (rv < 0) {
455        return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
456                            "Keyring File '%s': (%d) %s", file, rv,
457                            gnutls_strerror(rv));
458    }
459
460    apr_pool_destroy(spool);
461    return NULL;
462}
463
[46b85d8]464const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
[7bebb42]465                            const char *arg)
[46b85d8]466{
[c301152]467    mgs_srvconf_rec *sc =
[7bebb42]468        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
469                                                 module_config,
470                                                 &gnutls_module);
[46b85d8]471    if (!strcasecmp(arg, "On")) {
[7bebb42]472        sc->enabled = GNUTLS_ENABLED_TRUE;
473    } else if (!strcasecmp(arg, "Off")) {
474        sc->enabled = GNUTLS_ENABLED_FALSE;
475    } else {
476        return "GnuTLSEnable must be set to 'On' or 'Off'";
[46b85d8]477    }
[7bebb42]478
479    return NULL;
480}
481
482const char *mgs_set_export_certificates_enabled(cmd_parms * parms, void *dummy,
483                            const char *arg)
484{
485    mgs_srvconf_rec *sc =
486        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
487                                                 module_config,
488                                                 &gnutls_module);
489    if (!strcasecmp(arg, "On")) {
490        sc->export_certificates_enabled = GNUTLS_ENABLED_TRUE;
491    } else if (!strcasecmp(arg, "Off")) {
492        sc->export_certificates_enabled = GNUTLS_ENABLED_FALSE;
493    } else {
494        return "GnuTLSExportCertificates must be set to 'On' or 'Off'";
[46b85d8]495    }
[7bebb42]496
497    return NULL;
498}
499
500
501const char *mgs_set_priorities(cmd_parms * parms, void *dummy, const char *arg)
502{
503    int ret;
[fd73a08]504    const char *err;
[7bebb42]505    mgs_srvconf_rec *sc =
506        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
507                                                 module_config,
508                                                 &gnutls_module);
509
510
511    ret = gnutls_priority_init( &sc->priorities, arg, &err);
512    if (ret < 0) {
513      if (ret == GNUTLS_E_INVALID_REQUEST)
514        return apr_psprintf(parms->pool, "GnuTLS: Syntax error parsing priorities string at: %s", err);
515      return "Error setting priorities";
[46b85d8]516    }
517
518    return NULL;
519}
520
521void *mgs_config_server_create(apr_pool_t * p, server_rec * s)
522{
[c301152]523    mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
[b077bdd]524    int ret;
525   
[46b85d8]526    sc->enabled = GNUTLS_ENABLED_FALSE;
[7bebb42]527
[b077bdd]528    ret = gnutls_certificate_allocate_credentials(&sc->certs);
529    if (ret < 0) {
530        return apr_psprintf(p, "GnuTLS: Failed to initialize"
531                            ": (%d) %s", ret, gnutls_strerror(ret));
532    }
533
534    ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
535    if (ret < 0) {
536        return apr_psprintf(p, "GnuTLS: Failed to initialize"
537                            ": (%d) %s", ret, gnutls_strerror(ret));
538    }
539
540    ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
541    if (ret < 0) {
542        return apr_psprintf(p, "GnuTLS: Failed to initialize"
543                            ": (%d) %s", ret, gnutls_strerror(ret));
544    }
[7bebb42]545
546    sc->srp_tpasswd_conf_file = NULL;
547    sc->srp_tpasswd_file = NULL;
[46b85d8]548    sc->privkey_x509 = NULL;
[5e81262]549    memset( sc->certs_x509, 0, sizeof(sc->certs_x509));
550    sc->certs_x509_num = 0;
[46b85d8]551    sc->cache_timeout = apr_time_from_sec(300);
[c301152]552    sc->cache_type = mgs_cache_dbm;
[46b85d8]553    sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache");
[7bebb42]554
[46b85d8]555    sc->client_verify_mode = GNUTLS_CERT_IGNORE;
[7bebb42]556
[46b85d8]557    return sc;
558}
559
[7bebb42]560void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv)
[84cb5b2]561{
562    mgs_dirconf_rec *new;
[7bebb42]563/*    mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */
[84cb5b2]564    mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
[7bebb42]565
[84cb5b2]566    new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec));
567    new->lua_bytecode = apr_pstrmemdup(p, add->lua_bytecode,
[7bebb42]568                                       add->lua_bytecode_len);
[84cb5b2]569    new->lua_bytecode_len = add->lua_bytecode_len;
570    new->client_verify_mode = add->client_verify_mode;
571    return new;
572}
573
[7bebb42]574void *mgs_config_dir_create(apr_pool_t * p, char *dir)
[46b85d8]575{
[c301152]576    mgs_dirconf_rec *dc = apr_palloc(p, sizeof(*dc));
[7bebb42]577
[46b85d8]578    dc->client_verify_mode = -1;
[84cb5b2]579    dc->lua_bytecode = NULL;
580    dc->lua_bytecode_len = 0;
[46b85d8]581    return dc;
582}
Note: See TracBrowser for help on using the repository browser.