summaryrefslogtreecommitdiffstatsabout
path: root/src/gnutls_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnutls_config.c')
-rw-r--r--src/gnutls_config.c328
1 files changed, 328 insertions, 0 deletions
diff --git a/src/gnutls_config.c b/src/gnutls_config.c
new file mode 100644
index 0000000..2c29ccb
--- /dev/null
+++ b/src/gnutls_config.c
@@ -0,0 +1,328 @@
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 mod_gnutls_srvconf_rec *sc =
63 (mod_gnutls_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 mod_gnutls_srvconf_rec *sc =
95 (mod_gnutls_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 mod_gnutls_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 = mod_gnutls_cache_none;
131 }
132 else if (strcasecmp("dbm", type) == 0) {
133 sc->cache_type = mod_gnutls_cache_dbm;
134 }
135#if HAVE_APR_MEMCACHE
136 else if (strcasecmp("memcache", type) == 0) {
137 sc->cache_type = mod_gnutls_cache_memcache;
138 }
139#endif
140 else {
141 return "Invalid Type for GnuTLSCache!";
142 }
143
144 if (sc->cache_type == mod_gnutls_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 mod_gnutls_srvconf_rec *sc =
159 (mod_gnutls_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 mod_gnutls_dirconf_rec *dc = (mod_gnutls_dirconf_rec *)dummy;
199 dc->client_verify_mode = mode;
200 }
201 else {
202 mod_gnutls_srvconf_rec *sc =
203 (mod_gnutls_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 mod_gnutls_srvconf_rec *sc =
218 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
219 module_config,
220 &gnutls_module);
221 file = ap_server_root_relative(parms->pool, arg);
222 rv = gnutls_certificate_set_x509_trust_file(sc->certs,
223 file, GNUTLS_X509_FMT_PEM);
224
225 if (rv < 0) {
226 return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
227 "Client CA File '%s': (%d) %s", file, rv,
228 gnutls_strerror(rv));
229 }
230 return NULL;
231}
232
233const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
234 const char *arg)
235{
236 mod_gnutls_srvconf_rec *sc =
237 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
238 module_config,
239 &gnutls_module);
240 if (!strcasecmp(arg, "On")) {
241 sc->enabled = GNUTLS_ENABLED_TRUE;
242 }
243 else if (!strcasecmp(arg, "Off")) {
244 sc->enabled = GNUTLS_ENABLED_FALSE;
245 }
246 else {
247 return "GnuTLSEnable must be set to 'On' or 'Off'";
248 }
249
250 return NULL;
251}
252
253void *mgs_config_server_create(apr_pool_t * p, server_rec * s)
254{
255 int i;
256 mod_gnutls_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
257
258 sc->enabled = GNUTLS_ENABLED_FALSE;
259
260 gnutls_certificate_allocate_credentials(&sc->certs);
261 sc->privkey_x509 = NULL;
262 sc->cert_x509 = NULL;
263 sc->cache_timeout = apr_time_from_sec(300);
264 sc->cache_type = mod_gnutls_cache_dbm;
265 sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache");
266
267 /* TODO: Make this Configurable. But it isn't configurable in mod_ssl? */
268 sc->dh_params_file = ap_server_root_relative(p, "conf/dhfile");
269 sc->rsa_params_file = ap_server_root_relative(p, "conf/rsafile");
270
271 /* Finish SSL Client Certificate Support */
272 sc->client_verify_mode = GNUTLS_CERT_IGNORE;
273
274 /* TODO: Make this Configurable ! */
275 /* mod_ssl uses a flex based parser for this part.. sigh */
276 i = 0;
277 sc->ciphers[i++] = GNUTLS_CIPHER_AES_256_CBC;
278 sc->ciphers[i++] = GNUTLS_CIPHER_AES_128_CBC;
279 sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_128;
280 sc->ciphers[i++] = GNUTLS_CIPHER_3DES_CBC;
281 sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_40;
282 sc->ciphers[i] = 0;
283
284 i = 0;
285 sc->key_exchange[i++] = GNUTLS_KX_RSA;
286 sc->key_exchange[i++] = GNUTLS_KX_RSA_EXPORT;
287 sc->key_exchange[i++] = GNUTLS_KX_DHE_DSS;
288 sc->key_exchange[i++] = GNUTLS_KX_DHE_RSA;
289 sc->key_exchange[i++] = GNUTLS_KX_ANON_DH;
290 sc->key_exchange[i++] = GNUTLS_KX_SRP;
291 sc->key_exchange[i++] = GNUTLS_KX_SRP_RSA;
292 sc->key_exchange[i++] = GNUTLS_KX_SRP_DSS;
293 sc->key_exchange[i] = 0;
294
295 i = 0;
296 sc->macs[i++] = GNUTLS_MAC_SHA;
297 sc->macs[i++] = GNUTLS_MAC_MD5;
298 sc->macs[i++] = GNUTLS_MAC_RMD160;
299 sc->macs[i] = 0;
300
301 i = 0;
302 sc->protocol[i++] = GNUTLS_TLS1_1;
303 sc->protocol[i++] = GNUTLS_TLS1;
304 sc->protocol[i++] = GNUTLS_SSL3;
305 sc->protocol[i] = 0;
306
307 i = 0;
308 sc->compression[i++] = GNUTLS_COMP_NULL;
309 sc->compression[i++] = GNUTLS_COMP_ZLIB;
310 sc->compression[i++] = GNUTLS_COMP_LZO;
311 sc->compression[i] = 0;
312
313 i = 0;
314 sc->cert_types[i++] = GNUTLS_CRT_X509;
315 sc->cert_types[i] = 0;
316
317 return sc;
318}
319
320void *mgs_config_dir_create(apr_pool_t *p, char *dir)
321{
322 mod_gnutls_dirconf_rec *dc = apr_palloc(p, sizeof(*dc));
323
324 dc->client_verify_mode = -1;
325
326 return dc;
327}
328