source: mod_gnutls/src/gnutls_hooks.c @ 84cb5b2

debian/masterdebian/stretch-backportsjessie-backportsmsvaupstream
Last change on this file since 84cb5b2 was 84cb5b2, checked in by Paul Querna <chip@…>, 15 years ago
  • add lua to do client verification
  • only use gcrypt locking when required to
  • Property mode set to 100644
File size: 21.1 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#include "http_vhost.h"
20#include "ap_mpm.h"
21
22#if !USING_2_1_RECENT
23extern server_rec *ap_server_conf;
24#endif
25
26#if APR_HAS_THREADS
27GCRY_THREAD_OPTION_PTHREAD_IMPL;
28#endif
29
30#if MOD_GNUTLS_DEBUG
31static apr_file_t* debug_log_fp;
32#endif
33
34static int mpm_is_threaded;
35
36static apr_status_t mgs_cleanup_pre_config(void *data)
37{
38    gnutls_global_deinit();
39    return APR_SUCCESS;
40}
41
42#if MOD_GNUTLS_DEBUG
43static void gnutls_debug_log_all( int level, const char* str)
44{
45    apr_file_printf(debug_log_fp, "<%d> %s\n", level, str);
46}
47#endif
48
49int mgs_hook_pre_config(apr_pool_t * pconf,
50                        apr_pool_t * plog, apr_pool_t * ptemp)
51{
52
53#if APR_HAS_THREADS
54    ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_is_threaded);
55    if (mpm_is_threaded) {
56        gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
57    }
58#else
59    mpm_is_threaded = 0;
60#endif
61
62    gnutls_global_init();
63
64    apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config,
65                              apr_pool_cleanup_null);
66
67#if MOD_GNUTLS_DEBUG
68    apr_file_open(&debug_log_fp, "/tmp/gnutls_debug",
69                  APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, pconf);
70
71    gnutls_global_set_log_level(9);
72    gnutls_global_set_log_function(gnutls_debug_log_all);
73#endif
74
75    return OK;
76}
77
78
79static gnutls_datum load_params(const char* file, server_rec* s, 
80                                apr_pool_t* pool) 
81{
82    gnutls_datum ret = { NULL, 0 };
83    apr_file_t* fp;
84    apr_finfo_t finfo;
85    apr_status_t rv;
86    apr_size_t br = 0;
87
88    rv = apr_file_open(&fp, file, APR_READ|APR_BINARY, APR_OS_DEFAULT, 
89                       pool);
90    if (rv != APR_SUCCESS) {
91        ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s, 
92                     "GnuTLS failed to load params file at: %s", file);
93        return ret;
94    }
95
96    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
97
98    if (rv != APR_SUCCESS) {
99        ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s, 
100                     "GnuTLS failed to stat params file at: %s", file);
101        return ret;
102    }
103
104    ret.data = apr_palloc(pool, finfo.size+1);
105    rv = apr_file_read_full(fp, ret.data, finfo.size, &br);
106
107    if (rv != APR_SUCCESS) {
108        ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s, 
109                     "GnuTLS failed to read params file at: %s", file);
110        return ret;
111    }
112    apr_file_close(fp);
113    ret.data[br] = '\0';
114    ret.size = br;
115
116    return ret;
117}
118
119int mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
120                                       apr_pool_t * ptemp,
121                                       server_rec * base_server)
122{
123    int rv;
124    int data_len;
125    server_rec *s;
126    gnutls_dh_params_t dh_params;
127    gnutls_rsa_params_t rsa_params;
128    mgs_srvconf_rec *sc;
129    mgs_srvconf_rec *sc_base;
130    void *data = NULL;
131    int first_run = 0;
132    const char *userdata_key = "mgs_init";
133         
134    apr_pool_userdata_get(&data, userdata_key, base_server->process->pool);
135    if (data == NULL) {
136        first_run = 1;
137        apr_pool_userdata_set((const void *)1, userdata_key, 
138                              apr_pool_cleanup_null, 
139                              base_server->process->pool);
140    }
141
142
143    {
144        gnutls_datum pdata;
145        apr_pool_t* tpool;
146        s = base_server;
147        sc_base = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
148                                                             &gnutls_module);
149
150        apr_pool_create(&tpool, p);
151
152        gnutls_dh_params_init(&dh_params);
153
154        pdata = load_params(sc_base->dh_params_file, s, tpool);
155
156        if (pdata.size != 0) {
157            rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, 
158                                               GNUTLS_X509_FMT_PEM);
159            if (rv != 0) {
160                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 
161                             "GnuTLS: Unable to load DH Params: (%d) %s",
162                             rv, gnutls_strerror(rv));
163                exit(rv);
164            }
165        }
166        else {
167            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 
168                         "GnuTLS: Unable to load DH Params."
169                         " Shutting Down.");
170            exit(-1);
171        }
172        apr_pool_clear(tpool);
173
174        gnutls_rsa_params_init(&rsa_params);
175
176        pdata = load_params(sc_base->rsa_params_file, s, tpool);
177
178        if (pdata.size != 0) {
179            rv = gnutls_rsa_params_import_pkcs1(rsa_params, &pdata, 
180                                                GNUTLS_X509_FMT_PEM);
181            if (rv != 0) {
182                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 
183                             "GnuTLS: Unable to load RSA Params: (%d) %s",
184                             rv, gnutls_strerror(rv));
185                exit(rv);
186            }
187        }
188        else {
189            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 
190                         "GnuTLS: Unable to load RSA Params."
191                         " Shutting Down.");
192            exit(-1);
193        }
194
195        apr_pool_destroy(tpool);
196        rv = mgs_cache_post_config(p, s, sc_base);
197        if (rv != 0) {
198            ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s, 
199                         "GnuTLS: Post Config for GnuTLSCache Failed."
200                         " Shutting Down.");
201            exit(-1);
202        }
203         
204        for (s = base_server; s; s = s->next) {
205            sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
206                                                                 &gnutls_module);
207            sc->cache_type = sc_base->cache_type;
208            sc->cache_config = sc_base->cache_config;
209
210            gnutls_certificate_set_rsa_export_params(sc->certs, 
211                                                     rsa_params);
212            gnutls_certificate_set_dh_params(sc->certs, dh_params);
213
214            if (sc->cert_x509 == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
215                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
216                             "[GnuTLS] - Host '%s:%d' is missing a "
217                             "Certificate File!",
218                         s->server_hostname, s->port);
219                exit(-1);
220            }
221           
222            if (sc->privkey_x509 == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
223                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
224                             "[GnuTLS] - Host '%s:%d' is missing a "
225                             "Private Key File!",
226                             s->server_hostname, s->port);
227                exit(-1);
228            }
229           
230            rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509, 
231                                               GNUTLS_OID_X520_COMMON_NAME, 0, 0,
232                                               NULL, &data_len);
233           
234            if (data_len < 1) {
235                sc->enabled = GNUTLS_ENABLED_FALSE;
236                sc->cert_cn = NULL;
237                continue;
238            }
239           
240            sc->cert_cn = apr_palloc(p, data_len);
241            rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509, 
242                                               GNUTLS_OID_X520_COMMON_NAME, 0, 0,
243                                               sc->cert_cn, &data_len);
244        }
245    }
246
247    ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION);
248
249    return OK;
250}
251
252void mgs_hook_child_init(apr_pool_t *p, server_rec *s)
253{
254    apr_status_t rv = APR_SUCCESS;
255    mgs_srvconf_rec *sc = ap_get_module_config(s->module_config,
256                                                      &gnutls_module);
257
258    if (sc->cache_type != mgs_cache_none) {
259        rv = mgs_cache_child_init(p, s, sc);
260        if(rv != APR_SUCCESS) {
261            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
262                             "[GnuTLS] - Failed to run Cache Init");
263        }
264    }
265    else {
266        ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
267                     "[GnuTLS] - No Cache Configured. Hint: GnuTLSCache");
268    }
269}
270
271const char *mgs_hook_http_scheme(const request_rec * r)
272{
273    mgs_srvconf_rec *sc =
274        (mgs_srvconf_rec *) ap_get_module_config(r->server->
275                                                        module_config,
276                                                        &gnutls_module);
277
278    if (sc->enabled == GNUTLS_ENABLED_FALSE) {
279        return NULL;
280    }
281
282    return "https";
283}
284
285apr_port_t mgs_hook_default_port(const request_rec * r)
286{
287    mgs_srvconf_rec *sc =
288        (mgs_srvconf_rec *) ap_get_module_config(r->server->
289                                                        module_config,
290                                                        &gnutls_module);
291
292    if (sc->enabled == GNUTLS_ENABLED_FALSE) {
293        return 0;
294    }
295
296    return 443;
297}
298
299#define MAX_HOST_LEN 255
300
301#if USING_2_1_RECENT
302typedef struct
303{
304    mgs_handle_t *ctxt;
305    mgs_srvconf_rec *sc;
306    const char* sni_name;
307} vhost_cb_rec;
308
309static int vhost_cb (void* baton, conn_rec* conn, server_rec* s)
310{
311    mgs_srvconf_rec *tsc;
312    vhost_cb_rec* x = baton;
313
314    tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
315                                                          &gnutls_module);
316   
317    if (tsc->enabled != GNUTLS_ENABLED_TRUE || tsc->cert_cn == NULL) {
318        return 0;
319    }
320   
321    /* The CN can contain a * -- this will match those too. */
322    if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) {
323        /* found a match */
324#if MOD_GNUTLS_DEBUG
325        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
326                     x->ctxt->c->base_server,
327                     "GnuTLS: Virtual Host CB: "
328                     "'%s' == '%s'", tsc->cert_cn, x->sni_name);
329#endif
330        /* Because we actually change the server used here, we need to reset
331         * things like ClientVerify.
332         */
333        x->sc = tsc;
334        /* Shit. Crap. Dammit. We *really* should rehandshake here, as our
335         * certificate structure *should* change when the server changes.
336         * acccckkkkkk.
337         */
338        return 1;
339    }
340    return 0;
341}
342#endif
343
344mgs_srvconf_rec* mgs_find_sni_server(gnutls_session_t session) 
345{
346    int rv;
347    int sni_type;
348    int data_len = MAX_HOST_LEN;
349    char sni_name[MAX_HOST_LEN];
350    mgs_handle_t *ctxt;
351#if USING_2_1_RECENT
352    vhost_cb_rec cbx;
353#else
354    server_rec* s;
355    mgs_srvconf_rec *tsc;   
356#endif
357   
358    ctxt = gnutls_transport_get_ptr(session);
359   
360    sni_type = gnutls_certificate_type_get(session);
361    if (sni_type != GNUTLS_CRT_X509) {
362        /* In theory, we could support OpenPGP Certificates. Theory != code. */
363        ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
364                     ctxt->c->base_server,
365                     "GnuTLS: Only x509 Certificates are currently supported.");
366        return NULL;
367    }
368   
369    rv = gnutls_server_name_get(ctxt->session, sni_name, 
370                                &data_len, &sni_type, 0);
371   
372    if (rv != 0) {
373        return NULL;
374    }
375   
376    if (sni_type != GNUTLS_NAME_DNS) {
377        ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
378                     ctxt->c->base_server,
379                     "GnuTLS: Unknown type '%d' for SNI: "
380                     "'%s'", sni_type, sni_name);
381        return NULL;
382    }
383   
384    /**
385     * Code in the Core already sets up the c->base_server as the base
386     * for this IP/Port combo.  Trust that the core did the 'right' thing.
387     */
388#if USING_2_1_RECENT
389    cbx.ctxt = ctxt;
390    cbx.sc = NULL;
391    cbx.sni_name = sni_name;
392   
393    rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx);
394    if (rv == 1) {
395        return cbx.sc;
396    }
397#else
398    for (s = ap_server_conf; s; s = s->next) {
399       
400        tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
401                                                       &gnutls_module);
402        if (tsc->enabled != GNUTLS_ENABLED_TRUE) {
403            continue;
404        }
405#if MOD_GNUTLS_DEBUG
406        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
407                     ctxt->c->base_server,
408                     "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X  sc: 0x%08X", tsc->cert_cn, rv,
409                     gnutls_pk_algorithm_get_name(gnutls_x509_privkey_get_pk_algorithm(ctxt->sc->privkey_x509)),
410                     (unsigned int)s, (unsigned int)s->next, (unsigned int)tsc);
411#endif           
412        /* The CN can contain a * -- this will match those too. */
413        if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) {
414#if MOD_GNUTLS_DEBUG
415            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
416                         ctxt->c->base_server,
417                         "GnuTLS: Virtual Host: "
418                         "'%s' == '%s'", tsc->cert_cn, sni_name);
419#endif
420            return tsc;
421        }
422    }
423#endif
424    return NULL;
425}
426
427
428static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret) 
429{
430    mgs_handle_t *ctxt;
431    mgs_srvconf_rec *tsc;
432   
433    ctxt = gnutls_transport_get_ptr(session);
434
435    ret->type = GNUTLS_CRT_X509;
436    ret->ncerts = 1;
437    ret->deinit_all = 0;
438
439    tsc = mgs_find_sni_server(session);
440   
441    if (tsc != NULL) {
442        ctxt->sc = tsc;
443        gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode);
444    }
445   
446    ret->cert.x509 = &ctxt->sc->cert_x509;
447    ret->key.x509 = ctxt->sc->privkey_x509;
448    return 0;
449}
450
451static mgs_handle_t* create_gnutls_handle(apr_pool_t* pool, conn_rec * c)
452{
453    mgs_handle_t *ctxt;
454    mgs_srvconf_rec *sc =
455        (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
456                                                        module_config,
457                                                        &gnutls_module);
458
459    ctxt = apr_pcalloc(pool, sizeof(*ctxt));
460    ctxt->c = c;
461    ctxt->sc = sc;
462    ctxt->status = 0;
463
464    ctxt->input_rc = APR_SUCCESS;
465    ctxt->input_bb = apr_brigade_create(c->pool, c->bucket_alloc);
466    ctxt->input_cbuf.length = 0;
467
468    ctxt->output_rc = APR_SUCCESS;
469    ctxt->output_bb = apr_brigade_create(c->pool, c->bucket_alloc);
470    ctxt->output_blen = 0;
471    ctxt->output_length = 0;
472
473    gnutls_init(&ctxt->session, GNUTLS_SERVER);
474
475    gnutls_protocol_set_priority(ctxt->session, sc->protocol);
476    gnutls_cipher_set_priority(ctxt->session, sc->ciphers);
477    gnutls_compression_set_priority(ctxt->session, sc->compression);
478    gnutls_kx_set_priority(ctxt->session, sc->key_exchange);
479    gnutls_mac_set_priority(ctxt->session, sc->macs);
480    gnutls_certificate_type_set_priority(ctxt->session, sc->cert_types);
481
482    mgs_cache_session_init(ctxt);
483   
484    gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs);
485
486    gnutls_certificate_server_set_retrieve_function(sc->certs, cert_retrieve_fn);
487    gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode);
488    return ctxt;
489}
490
491int mgs_hook_pre_connection(conn_rec * c, void *csd)
492{
493    mgs_handle_t *ctxt;
494    mgs_srvconf_rec *sc =
495        (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
496                                                        module_config,
497                                                        &gnutls_module);
498
499    if (!(sc && (sc->enabled == GNUTLS_ENABLED_TRUE))) {
500        return DECLINED;
501    }
502
503    ctxt = create_gnutls_handle(c->pool, c);
504
505    ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
506
507    gnutls_transport_set_pull_function(ctxt->session,
508                                       mgs_transport_read);
509    gnutls_transport_set_push_function(ctxt->session,
510                                       mgs_transport_write);
511    gnutls_transport_set_ptr(ctxt->session, ctxt);
512   
513    ctxt->input_filter = ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt, 
514                                             NULL, c);
515    ctxt->output_filter = ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt,
516                                               NULL, c);
517
518    return OK;
519}
520
521int mgs_hook_fixups(request_rec *r)
522{
523    unsigned char sbuf[GNUTLS_MAX_SESSION_ID];
524    char buf[AP_IOBUFSIZE];
525    const char* tmp;
526    int len;
527    mgs_handle_t *ctxt;
528    int rv = OK;
529   
530    apr_table_t *env = r->subprocess_env;
531
532    ctxt = ap_get_module_config(r->connection->conn_config, &gnutls_module);
533
534    if(!ctxt) {
535        return DECLINED;
536    }
537
538    apr_table_setn(env, "HTTPS", "on");
539
540    apr_table_setn(env, "GNUTLS_VERSION_INTERFACE", MOD_GNUTLS_VERSION);
541    apr_table_setn(env, "GNUTLS_VERSION_LIBRARY", LIBGNUTLS_VERSION);
542
543    apr_table_setn(env, "SSL_PROTOCOL",
544                   gnutls_protocol_get_name(gnutls_protocol_get_version(ctxt->session)));
545
546    apr_table_setn(env, "SSL_CIPHER",
547                   gnutls_cipher_get_name(gnutls_cipher_get(ctxt->session)));
548
549    apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE");
550
551    tmp = apr_psprintf(r->pool, "%d",
552              8 * gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session)));
553
554    apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp);
555
556    apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp);
557
558    len = sizeof(sbuf);
559    gnutls_session_get_id(ctxt->session, sbuf, &len);
560    tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
561    apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp));
562
563    /* TODO: There are many other env vars that we need to add */
564    {
565        len = sizeof(buf);
566        gnutls_x509_crt_get_dn(ctxt->sc->cert_x509, buf, &len);
567        apr_table_setn(env, "SSL_SERVER_S_DN", apr_pstrmemdup(r->pool, buf, len));
568           
569        len = sizeof(buf);
570        gnutls_x509_crt_get_issuer_dn(ctxt->sc->cert_x509, buf, &len);
571        apr_table_setn(env, "SSL_SERVER_I_DN", apr_pstrmemdup(r->pool, buf, len));
572    }
573    return rv;
574}
575
576int mgs_hook_authz(request_rec *r)
577{
578    int rv;
579    int status;
580    mgs_handle_t *ctxt;
581    mgs_dirconf_rec *dc = ap_get_module_config(r->per_dir_config,
582                                                      &gnutls_module);
583   
584    ctxt = ap_get_module_config(r->connection->conn_config, &gnutls_module);
585   
586    if (!ctxt) {
587        return DECLINED;
588    }
589    ap_add_common_vars(r);
590    mgs_hook_fixups(r);
591    status = mgs_authz_lua(r);
592    if (status != 0) {
593        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, 
594                      "GnuTLS: FAILED Lua Authorization Test");
595        return HTTP_FORBIDDEN;
596    }
597    if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) {
598        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, 
599                      "GnuTLS: Directory set to Ignore Client Certificate!");
600        return DECLINED;
601    }
602
603    if (ctxt->sc->client_verify_mode < dc->client_verify_mode) {
604        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, 
605                     "GnuTLS: Attempting to rehandshake with peer. %d %d",
606                      ctxt->sc->client_verify_mode, dc->client_verify_mode);
607       
608        gnutls_certificate_server_set_request(ctxt->session,
609                                              dc->client_verify_mode);
610   
611        if (mgs_rehandshake(ctxt) != 0) {
612            return HTTP_FORBIDDEN;
613        }
614    }
615    else if (ctxt->sc->client_verify_mode == GNUTLS_CERT_IGNORE) {
616#if MOD_GNUTLS_DEBUG
617        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 
618                      "GnuTLS: Peer is set to IGNORE");
619#endif
620        return DECLINED;
621    }
622   
623    rv = gnutls_certificate_verify_peers2(ctxt->session, &status);
624
625    if (rv < 0) {
626        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 
627                     "GnuTLS: Failed to Verify Peer: (%d) %s", 
628                     rv, gnutls_strerror(rv));
629        return HTTP_FORBIDDEN;
630    }
631   
632    if (status < 0) {
633        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 
634                     "GnuTLS: Peer Status is invalid."); 
635        return HTTP_FORBIDDEN;
636    }
637   
638    if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
639        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 
640                     "GnuTLS: Could not find Signer for Peer Certificate"); 
641    }
642   
643    if (status & GNUTLS_CERT_SIGNER_NOT_CA) {
644        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 
645                     "GnuTLS: Could not find CA for Peer Certificate"); 
646    }
647   
648    if (status & GNUTLS_CERT_INVALID) {
649        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 
650                     "GnuTLS: Peer Certificate is invalid."); 
651        return HTTP_FORBIDDEN;
652    }
653    else if (status & GNUTLS_CERT_REVOKED) {
654        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 
655                     "GnuTLS: Peer Certificate is revoked."); 
656        return HTTP_FORBIDDEN;
657    }
658   
659    /* TODO: OpenPGP Certificates */
660    if (gnutls_certificate_type_get(ctxt->session) != GNUTLS_CRT_X509) {
661        ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, 
662                     "GnuTLS: Only x509 is supported for client certificates");         
663        return HTTP_FORBIDDEN;
664    }
665    /* TODO: Further Verification. */
666    ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, 
667                 "GnuTLS: Verified Peer.");             
668    return OK;
669}
670
Note: See TracBrowser for help on using the repository browser.