source: mod_gnutls/src/gnutls_config.c @ 836c2f9

debian/masterdebian/stretch-backportsjessie-backportsmsvaupstream
Last change on this file since 836c2f9 was 836c2f9, checked in by Paul Querna <chip@…>, 15 years ago

start the CA Certificate code.

  • Property mode set to 100644
File size: 10.8 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,
22                                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_cert_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    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                            "Certificate '%s'", file);
73    }
74   
75    gnutls_x509_crt_init(&sc->cert_x509);
76    ret = gnutls_x509_crt_import(sc->cert_x509, &data, GNUTLS_X509_FMT_PEM);
77    if (ret != 0) {
78        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
79                            "Certificate'%s': (%d) %s", file, ret, 
80                            gnutls_strerror(ret));
81    }
82   
83    apr_pool_destroy(spool);
84    return NULL;
85}
86
87const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
88                                       const char *arg)
89{
90    int ret;
91    gnutls_datum_t data;
92    const char* file;
93    apr_pool_t* spool;
94    mgs_srvconf_rec *sc =
95        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
96                                                        module_config,
97                                                        &gnutls_module);
98    apr_pool_create(&spool, parms->pool);
99   
100    file = ap_server_root_relative(spool, arg);
101   
102    if (load_datum_from_file(spool, file, &data) != 0) {
103        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
104                            "Private Key '%s'", file);
105    }
106   
107    gnutls_x509_privkey_init(&sc->privkey_x509);
108    ret = gnutls_x509_privkey_import(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM);
109    if (ret != 0) {
110        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
111                            "Private Key '%s': (%d) %s", file, ret, 
112                            gnutls_strerror(ret));
113    }
114    apr_pool_destroy(spool);
115    return NULL;
116}
117
118const char *mgs_set_cache(cmd_parms * parms, void *dummy,
119                                       const char *type, const char* arg)
120{
121    const char* err;
122    mgs_srvconf_rec *sc = ap_get_module_config(parms->server->
123                                                        module_config,
124                                                        &gnutls_module);
125    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
126        return err;
127    }
128
129    if (strcasecmp("none", type) == 0) {
130        sc->cache_type = mgs_cache_none;
131    }
132    else if (strcasecmp("dbm", type) == 0) {
133        sc->cache_type = mgs_cache_dbm;
134    }
135#if HAVE_APR_MEMCACHE
136    else if (strcasecmp("memcache", type) == 0) {
137        sc->cache_type = mgs_cache_memcache;
138    }
139#endif
140    else {
141        return "Invalid Type for GnuTLSCache!";
142    }
143
144    if (sc->cache_type == mgs_cache_dbm) {
145        sc->cache_config = ap_server_root_relative(parms->pool, arg);
146    }
147    else {
148        sc->cache_config = apr_pstrdup(parms->pool, arg);
149    }
150
151    return NULL;
152}
153
154const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
155                                            const char *arg)
156{
157    int argint;
158    mgs_srvconf_rec *sc =
159    (mgs_srvconf_rec *) ap_get_module_config(parms->server->
160                                                    module_config,
161                                                    &gnutls_module);
162   
163    argint = atoi(arg);
164   
165    if (argint < 0) {
166        return "GnuTLSCacheTimeout: Invalid argument";
167    }
168    else if (argint == 0) {
169        sc->cache_timeout = 0;
170    }
171    else {
172        sc->cache_timeout = apr_time_from_sec(argint);
173    }
174   
175    return NULL;
176}
177
178const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
179                                            const char *arg)
180{
181    int mode;
182
183    if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
184        mode = GNUTLS_CERT_IGNORE;
185    }
186    else if (strcasecmp("optional", arg) == 0 || strcasecmp("request", arg) == 0) {
187        mode = GNUTLS_CERT_REQUEST;
188    }
189    else if (strcasecmp("require", arg) == 0) {
190        mode = GNUTLS_CERT_REQUIRE;
191    }
192    else {
193        return "GnuTLSClientVerify: Invalid argument";
194    }
195   
196    /* This was set from a directory context */
197    if (parms->path) {
198        mgs_dirconf_rec *dc = (mgs_dirconf_rec *)dummy;
199        dc->client_verify_mode = mode;
200    }
201    else {
202        mgs_srvconf_rec *sc =
203        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
204                                                        module_config,
205                                                        &gnutls_module);       
206        sc->client_verify_mode = mode;
207    }
208
209    return NULL;
210}
211
212const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
213                                            const char *arg)
214{
215    int rv;
216    const char* file;
217    apr_pool_t* spool;
218    gnutls_datum_t data;
219
220    mgs_srvconf_rec *sc = 
221        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
222                                                        module_config,
223                                                        &gnutls_module);       
224    apr_pool_create(&spool, parms->pool);
225
226    file = ap_server_root_relative(spool, arg);
227
228    sc->ca_list_size = 16;
229
230    load_datum_from_file(spool, file, &data);
231
232    rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size, 
233                                     &data, GNUTLS_X509_FMT_PEM,
234                                     GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
235    if (rv < 0) {
236        return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
237                            "Client CA File '%s': (%d) %s", file, rv, 
238                            gnutls_strerror(rv));   
239    }
240
241    apr_pool_destroy(spool);
242    return NULL;
243}
244
245const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
246                                      const char *arg)
247{
248    mgs_srvconf_rec *sc =
249        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
250                                                        module_config,
251                                                        &gnutls_module);
252    if (!strcasecmp(arg, "On")) {
253        sc->enabled = GNUTLS_ENABLED_TRUE;
254    }
255    else if (!strcasecmp(arg, "Off")) {
256        sc->enabled = GNUTLS_ENABLED_FALSE;
257    }
258    else {
259        return "GnuTLSEnable must be set to 'On' or 'Off'";
260    }
261
262    return NULL;
263}
264
265void *mgs_config_server_create(apr_pool_t * p, server_rec * s)
266{
267    int i;
268    mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
269   
270    sc->enabled = GNUTLS_ENABLED_FALSE;
271   
272    gnutls_certificate_allocate_credentials(&sc->certs);
273    sc->privkey_x509 = NULL;
274    sc->cert_x509 = NULL;
275    sc->cache_timeout = apr_time_from_sec(300);
276    sc->cache_type = mgs_cache_dbm;
277    sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache");
278   
279    /* TODO: Make this Configurable. But it isn't configurable in mod_ssl? */
280    sc->dh_params_file = ap_server_root_relative(p, "conf/dhfile");
281    sc->rsa_params_file = ap_server_root_relative(p, "conf/rsafile");
282   
283    /* Finish SSL Client Certificate Support */
284    sc->client_verify_mode = GNUTLS_CERT_IGNORE;
285   
286    /* TODO: Make this Configurable ! */
287    /* mod_ssl uses a flex based parser for this part.. sigh */
288    i = 0;
289    sc->ciphers[i++] = GNUTLS_CIPHER_AES_256_CBC;
290    sc->ciphers[i++] = GNUTLS_CIPHER_AES_128_CBC;
291    sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_128;
292    sc->ciphers[i++] = GNUTLS_CIPHER_3DES_CBC;
293    sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_40;
294    sc->ciphers[i] = 0;
295   
296    i = 0;
297    sc->key_exchange[i++] = GNUTLS_KX_RSA;
298    sc->key_exchange[i++] = GNUTLS_KX_RSA_EXPORT;
299    sc->key_exchange[i++] = GNUTLS_KX_DHE_DSS;
300    sc->key_exchange[i++] = GNUTLS_KX_DHE_RSA;
301    sc->key_exchange[i++] = GNUTLS_KX_ANON_DH;
302    sc->key_exchange[i++] = GNUTLS_KX_SRP;
303    sc->key_exchange[i++] = GNUTLS_KX_SRP_RSA;
304    sc->key_exchange[i++] = GNUTLS_KX_SRP_DSS;
305    sc->key_exchange[i] = 0;
306   
307    i = 0;
308    sc->macs[i++] = GNUTLS_MAC_SHA;
309    sc->macs[i++] = GNUTLS_MAC_MD5;
310    sc->macs[i++] = GNUTLS_MAC_RMD160;
311    sc->macs[i] = 0;
312   
313    i = 0;
314    sc->protocol[i++] = GNUTLS_TLS1_1;
315    sc->protocol[i++] = GNUTLS_TLS1;
316    sc->protocol[i++] = GNUTLS_SSL3;
317    sc->protocol[i] = 0;
318   
319    i = 0;
320    sc->compression[i++] = GNUTLS_COMP_NULL;
321    sc->compression[i++] = GNUTLS_COMP_ZLIB;
322    sc->compression[i++] = GNUTLS_COMP_LZO;
323    sc->compression[i] = 0;
324   
325    i = 0;
326    sc->cert_types[i++] = GNUTLS_CRT_X509;
327    sc->cert_types[i] = 0;
328   
329    return sc;
330}
331
332void *mgs_config_dir_merge(apr_pool_t *p, void *basev, void *addv)
333{
334    mgs_dirconf_rec *new;
335    mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev;
336    mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
337   
338    new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec));
339    new->lua_bytecode = apr_pstrmemdup(p, add->lua_bytecode,
340                                       add->lua_bytecode_len);
341    new->lua_bytecode_len = add->lua_bytecode_len;
342    new->client_verify_mode = add->client_verify_mode;
343    return new;
344}
345
346void *mgs_config_dir_create(apr_pool_t *p, char *dir)
347{
348    mgs_dirconf_rec *dc = apr_palloc(p, sizeof(*dc));
349   
350    dc->client_verify_mode = -1;
351    dc->lua_bytecode = NULL;
352    dc->lua_bytecode_len = 0;
353    return dc;
354}
355
Note: See TracBrowser for help on using the repository browser.