Changeset 180e49f in mod_gnutls for src/gnutls_hooks.c


Ignore:
Timestamp:
Jan 11, 2013, 12:58:31 AM (7 years ago)
Author:
Daniel Kahn Gillmor <dkg@…>
Branches:
debian/master, debian/stretch-backports, jessie-backports, upstream
Children:
2b1118c, ae29683
Parents:
17eb1a1
Message:

Imported Upstream version 0.5.10

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/gnutls_hooks.c

    r17eb1a1 r180e49f  
    4141static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt);
    4242/* use side==0 for server and side==1 for client */
    43 static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert,
    44                                      int side,
     43static void mgs_add_common_cert_vars(request_rec * r,
     44                                     gnutls_x509_crt_t cert, int side,
    4545                                     int export_certificates_enabled);
    46 static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert,
    47                                      int side,
    48                                      int export_certificates_enabled);
     46static void mgs_add_common_pgpcert_vars(request_rec * r,
     47                                        gnutls_openpgp_crt_t cert,
     48                                        int side,
     49                                        int export_certificates_enabled);
    4950
    5051static apr_status_t mgs_cleanup_pre_config(void *data)
    5152{
    52     gnutls_free(session_ticket_key.data);
    53     session_ticket_key.data = NULL;
    54     session_ticket_key.size = 0;
    55     gnutls_global_deinit();
    56     return APR_SUCCESS;
     53        gnutls_free(session_ticket_key.data);
     54        session_ticket_key.data = NULL;
     55        session_ticket_key.size = 0;
     56        gnutls_global_deinit();
     57        return APR_SUCCESS;
    5758}
    5859
     
    6061static void gnutls_debug_log_all(int level, const char *str)
    6162{
    62     apr_file_printf(debug_log_fp, "<%d> %s\n", level, str);
    63 }
     63        apr_file_printf(debug_log_fp, "<%d> %s\n", level, str);
     64}
     65
    6466#define _gnutls_log apr_file_printf
    6567#else
    66 # define _gnutls_log(...) 
     68# define _gnutls_log(...)
    6769#endif
    6870
     
    7173                    apr_pool_t * plog, apr_pool_t * ptemp)
    7274{
    73 int ret;
     75        int ret;
    7476
    7577#if MOD_GNUTLS_DEBUG
    76     apr_file_open(&debug_log_fp, "/tmp/gnutls_debug",
    77                   APR_APPEND | APR_WRITE | APR_CREATE, APR_OS_DEFAULT,
    78                   pconf);
    79 
    80     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    81 
    82     gnutls_global_set_log_level(9);
    83     gnutls_global_set_log_function(gnutls_debug_log_all);
    84     _gnutls_log(debug_log_fp, "gnutls: %s\n", gnutls_check_version(NULL));
     78        apr_file_open(&debug_log_fp, "/tmp/gnutls_debug",
     79                      APR_APPEND | APR_WRITE | APR_CREATE, APR_OS_DEFAULT,
     80                      pconf);
     81
     82        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     83
     84        gnutls_global_set_log_level(9);
     85        gnutls_global_set_log_function(gnutls_debug_log_all);
     86        _gnutls_log(debug_log_fp, "gnutls: %s\n",
     87                    gnutls_check_version(NULL));
    8588#endif
    8689
    8790#if APR_HAS_THREADS
    88     ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_is_threaded);
     91        ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_is_threaded);
    8992#if (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR < 11) || GNUTLS_VERSION_MAJOR < 2
    90     if (mpm_is_threaded) {
    91         gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
    92     }
     93        if (mpm_is_threaded) {
     94                gcry_control(GCRYCTL_SET_THREAD_CBS,
     95                             &gcry_threads_pthread);
     96        }
    9397#endif
    9498#else
    95     mpm_is_threaded = 0;
    96 #endif
    97 
    98 
    99     if (gnutls_check_version(LIBGNUTLS_VERSION)==NULL) {
    100         _gnutls_log(debug_log_fp, "gnutls_check_version() failed. Required: gnutls-%s Found: gnutls-%s\n",
    101           LIBGNUTLS_VERSION, gnutls_check_version(NULL));
    102         return -3;
    103     }
    104 
    105     ret = gnutls_global_init();
    106     if (ret < 0) {
    107         _gnutls_log(debug_log_fp, "gnutls_global_init: %s\n", gnutls_strerror(ret));
    108         return -3;
    109     }
    110    
    111     ret = gnutls_session_ticket_key_generate( &session_ticket_key);
    112     if (ret < 0) {
    113         _gnutls_log(debug_log_fp, "gnutls_session_ticket_key_generate: %s\n", gnutls_strerror(ret));
    114     }
    115 
    116     apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config,
    117                               apr_pool_cleanup_null);
    118 
    119 
    120     return OK;
     99        mpm_is_threaded = 0;
     100#endif
     101
     102
     103        if (gnutls_check_version(LIBGNUTLS_VERSION) == NULL) {
     104                _gnutls_log(debug_log_fp,
     105                            "gnutls_check_version() failed. Required: gnutls-%s Found: gnutls-%s\n",
     106                            LIBGNUTLS_VERSION, gnutls_check_version(NULL));
     107                return -3;
     108        }
     109
     110        ret = gnutls_global_init();
     111        if (ret < 0) {
     112                _gnutls_log(debug_log_fp, "gnutls_global_init: %s\n",
     113                            gnutls_strerror(ret));
     114                return -3;
     115        }
     116
     117        ret = gnutls_session_ticket_key_generate(&session_ticket_key);
     118        if (ret < 0) {
     119                _gnutls_log(debug_log_fp,
     120                            "gnutls_session_ticket_key_generate: %s\n",
     121                            gnutls_strerror(ret));
     122        }
     123
     124        apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config,
     125                                  apr_pool_cleanup_null);
     126
     127
     128        return OK;
    121129}
    122130
    123131static int mgs_select_virtual_server_cb(gnutls_session_t session)
    124132{
    125     mgs_handle_t *ctxt;
    126     mgs_srvconf_rec *tsc;
    127     int ret;
    128     int cprio[2];
    129 
    130     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    131 
    132     ctxt = gnutls_transport_get_ptr(session);
    133 
    134     /* find the virtual server */
    135     tsc = mgs_find_sni_server(session);
    136 
    137     if (tsc != NULL)
    138         ctxt->sc = tsc;
    139 
    140     gnutls_certificate_server_set_request(session,
    141                                               ctxt->sc->client_verify_mode);
    142 
    143     /* set the new server credentials
    144      */
    145 
    146     gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
    147                            ctxt->sc->certs);
    148 
    149     gnutls_credentials_set(session, GNUTLS_CRD_ANON, ctxt->sc->anon_creds);
     133        mgs_handle_t *ctxt;
     134        mgs_srvconf_rec *tsc;
     135        int ret;
     136        int cprio[2];
     137
     138        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     139
     140        ctxt = gnutls_transport_get_ptr(session);
     141
     142        /* find the virtual server */
     143        tsc = mgs_find_sni_server(session);
     144
     145        if (tsc != NULL)
     146                ctxt->sc = tsc;
     147
     148        gnutls_certificate_server_set_request(session,
     149                                              ctxt->
     150                                              sc->client_verify_mode);
     151
     152        /* set the new server credentials
     153         */
     154
     155        gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
     156                               ctxt->sc->certs);
     157
     158        gnutls_credentials_set(session, GNUTLS_CRD_ANON,
     159                               ctxt->sc->anon_creds);
    150160
    151161#ifdef ENABLE_SRP
    152     if (ctxt->sc->srp_tpasswd_conf_file != NULL
    153         && ctxt->sc->srp_tpasswd_file != NULL) {
    154         gnutls_credentials_set(session, GNUTLS_CRD_SRP,
    155                                ctxt->sc->srp_creds);
    156     }
    157 #endif
    158 
    159     /* update the priorities - to avoid negotiating a ciphersuite that is not
    160      * enabled on this virtual server. Note that here we ignore the version
    161      * negotiation.
    162      */   
    163     ret = gnutls_priority_set(session, ctxt->sc->priorities);
    164     /* actually it shouldn't fail since we have checked at startup */
    165     if (ret < 0)
    166         return ret;
    167 
    168     /* If both certificate types are not present disallow them from
    169      * being negotiated.
    170      */
    171     if (ctxt->sc->certs_x509[0] != NULL && ctxt->sc->cert_pgp == NULL) {
    172         cprio[0] = GNUTLS_CRT_X509;
    173         cprio[1] = 0;
    174         gnutls_certificate_type_set_priority( session, cprio);
    175     } else if (ctxt->sc->cert_pgp != NULL && ctxt->sc->certs_x509[0]==NULL) {
    176         cprio[0] = GNUTLS_CRT_OPENPGP;
    177         cprio[1] = 0;
    178         gnutls_certificate_type_set_priority( session, cprio);
    179     }
    180 
    181     return 0;
     162        if (ctxt->sc->srp_tpasswd_conf_file != NULL
     163            && ctxt->sc->srp_tpasswd_file != NULL) {
     164                gnutls_credentials_set(session, GNUTLS_CRD_SRP,
     165                                       ctxt->sc->srp_creds);
     166        }
     167#endif
     168
     169        /* update the priorities - to avoid negotiating a ciphersuite that is not
     170         * enabled on this virtual server. Note that here we ignore the version
     171         * negotiation.
     172         */
     173        ret = gnutls_priority_set(session, ctxt->sc->priorities);
     174        /* actually it shouldn't fail since we have checked at startup */
     175        if (ret < 0)
     176                return ret;
     177
     178        /* If both certificate types are not present disallow them from
     179         * being negotiated.
     180         */
     181        if (ctxt->sc->certs_x509[0] != NULL && ctxt->sc->cert_pgp == NULL) {
     182                cprio[0] = GNUTLS_CRT_X509;
     183                cprio[1] = 0;
     184                gnutls_certificate_type_set_priority(session, cprio);
     185        } else if (ctxt->sc->cert_pgp != NULL
     186                   && ctxt->sc->certs_x509[0] == NULL) {
     187                cprio[0] = GNUTLS_CRT_OPENPGP;
     188                cprio[1] = 0;
     189                gnutls_certificate_type_set_priority(session, cprio);
     190        }
     191
     192        return 0;
    182193}
    183194
    184195static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st * ret)
    185196{
    186     mgs_handle_t *ctxt;
    187 
    188     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    189     ctxt = gnutls_transport_get_ptr(session);
    190 
    191     if (ctxt == NULL)
    192         return GNUTLS_E_INTERNAL_ERROR;
    193 
    194     if (gnutls_certificate_type_get( session) == GNUTLS_CRT_X509) {
    195         ret->type = GNUTLS_CRT_X509;
    196         ret->ncerts = ctxt->sc->certs_x509_num;
    197         ret->deinit_all = 0;
    198 
    199         ret->cert.x509 = ctxt->sc->certs_x509;
    200         ret->key.x509 = ctxt->sc->privkey_x509;
    201        
    202         return 0;
    203     } else if (gnutls_certificate_type_get( session) == GNUTLS_CRT_OPENPGP) {
    204         ret->type = GNUTLS_CRT_OPENPGP;
    205         ret->ncerts = 1;
    206         ret->deinit_all = 0;
    207 
    208         ret->cert.pgp = ctxt->sc->cert_pgp;
    209         ret->key.pgp = ctxt->sc->privkey_pgp;
    210 
    211         return 0;
    212    
    213     }
    214 
    215     return GNUTLS_E_INTERNAL_ERROR;
     197        mgs_handle_t *ctxt;
     198
     199        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     200        ctxt = gnutls_transport_get_ptr(session);
     201
     202        if (ctxt == NULL)
     203                return GNUTLS_E_INTERNAL_ERROR;
     204
     205        if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) {
     206                ret->type = GNUTLS_CRT_X509;
     207                ret->ncerts = ctxt->sc->certs_x509_num;
     208                ret->deinit_all = 0;
     209
     210                ret->cert.x509 = ctxt->sc->certs_x509;
     211                ret->key.x509 = ctxt->sc->privkey_x509;
     212
     213                return 0;
     214        } else if (gnutls_certificate_type_get(session) ==
     215                   GNUTLS_CRT_OPENPGP) {
     216                ret->type = GNUTLS_CRT_OPENPGP;
     217                ret->ncerts = 1;
     218                ret->deinit_all = 0;
     219
     220                ret->cert.pgp = ctxt->sc->cert_pgp;
     221                ret->key.pgp = ctxt->sc->privkey_pgp;
     222
     223                return 0;
     224
     225        }
     226
     227        return GNUTLS_E_INTERNAL_ERROR;
    216228}
    217229
     
    234246                       gnutls_x509_crt_t cert, char **cert_cn)
    235247{
    236     int rv = 0, i;
    237     size_t data_len;
    238 
    239 
    240     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
    241     *cert_cn = NULL;
    242 
    243     data_len = 0;
    244     rv = gnutls_x509_crt_get_dn_by_oid(cert,
    245                                        GNUTLS_OID_X520_COMMON_NAME,
    246                                        0, 0, NULL, &data_len);
    247 
    248     if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) {
    249         *cert_cn = apr_palloc(p, data_len);
     248        int rv = 0, i;
     249        size_t data_len;
     250
     251
     252        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     253        *cert_cn = NULL;
     254
     255        data_len = 0;
    250256        rv = gnutls_x509_crt_get_dn_by_oid(cert,
    251                                            GNUTLS_OID_X520_COMMON_NAME, 0,
    252                                            0, *cert_cn, &data_len);
    253     } else {                    /* No CN return subject alternative name */
    254         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
    255                      "No common name found in certificate for '%s:%d'. Looking for subject alternative name...",
    256                      s->server_hostname, s->port);
    257         rv = 0;
    258         /* read subject alternative name */
    259         for (i = 0; !(rv < 0); i++) {
    260             data_len = 0;
    261             rv = gnutls_x509_crt_get_subject_alt_name(cert, i,
    262                                                       NULL, &data_len,
    263                                                       NULL);
    264 
    265             if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) {
    266                 /* FIXME: not very efficient. What if we have several alt names
    267                  * before DNSName?
    268                  */
    269                 *cert_cn = apr_palloc(p, data_len + 1);
    270 
    271                 rv = gnutls_x509_crt_get_subject_alt_name(cert, i,
    272                                                           *cert_cn,
    273                                                           &data_len, NULL);
    274                 (*cert_cn)[data_len] = 0;
    275 
    276                 if (rv == GNUTLS_SAN_DNSNAME)
    277                     break;
    278             }
    279         }
    280     }
    281 
    282     return rv;
     257                                           GNUTLS_OID_X520_COMMON_NAME,
     258                                           0, 0, NULL, &data_len);
     259
     260        if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) {
     261                *cert_cn = apr_palloc(p, data_len);
     262                rv = gnutls_x509_crt_get_dn_by_oid(cert,
     263                                                   GNUTLS_OID_X520_COMMON_NAME,
     264                                                   0, 0, *cert_cn,
     265                                                   &data_len);
     266        } else {                /* No CN return subject alternative name */
     267                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
     268                             "No common name found in certificate for '%s:%d'. Looking for subject alternative name...",
     269                             s->server_hostname, s->port);
     270                rv = 0;
     271                /* read subject alternative name */
     272                for (i = 0; !(rv < 0); i++) {
     273                        data_len = 0;
     274                        rv = gnutls_x509_crt_get_subject_alt_name(cert, i,
     275                                                                  NULL,
     276                                                                  &data_len,
     277                                                                  NULL);
     278
     279                        if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER
     280                            && data_len > 1) {
     281                                /* FIXME: not very efficient. What if we have several alt names
     282                                 * before DNSName?
     283                                 */
     284                                *cert_cn = apr_palloc(p, data_len + 1);
     285
     286                                rv = gnutls_x509_crt_get_subject_alt_name
     287                                    (cert, i, *cert_cn, &data_len, NULL);
     288                                (*cert_cn)[data_len] = 0;
     289
     290                                if (rv == GNUTLS_SAN_DNSNAME)
     291                                        break;
     292                        }
     293                }
     294        }
     295
     296        return rv;
    283297}
    284298
    285299static int read_pgpcrt_cn(server_rec * s, apr_pool_t * p,
    286                        gnutls_openpgp_crt_t cert, char **cert_cn)
    287 {
    288     int rv = 0;
    289     size_t data_len;
    290 
    291 
    292     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    293     *cert_cn = NULL;
    294 
    295     data_len = 0;
    296     rv = gnutls_openpgp_crt_get_name(cert, 0, NULL, &data_len);
    297 
    298     if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) {
    299         *cert_cn = apr_palloc(p, data_len);
    300         rv = gnutls_openpgp_crt_get_name(cert, 0, *cert_cn, &data_len);
    301     } else {                    /* No CN return subject alternative name */
    302         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
    303                      "No name found in PGP certificate for '%s:%d'.",
    304                      s->server_hostname, s->port);
    305     }
    306 
    307     return rv;
     300                          gnutls_openpgp_crt_t cert, char **cert_cn)
     301{
     302        int rv = 0;
     303        size_t data_len;
     304
     305
     306        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     307        *cert_cn = NULL;
     308
     309        data_len = 0;
     310        rv = gnutls_openpgp_crt_get_name(cert, 0, NULL, &data_len);
     311
     312        if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) {
     313                *cert_cn = apr_palloc(p, data_len);
     314                rv = gnutls_openpgp_crt_get_name(cert, 0, *cert_cn,
     315                                                 &data_len);
     316        } else {                /* No CN return subject alternative name */
     317                ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
     318                             "No name found in PGP certificate for '%s:%d'.",
     319                             s->server_hostname, s->port);
     320        }
     321
     322        return rv;
    308323}
    309324
     
    313328                     apr_pool_t * ptemp, server_rec * base_server)
    314329{
    315     int rv;
    316     server_rec *s;
    317     gnutls_dh_params_t dh_params = NULL;
    318     gnutls_rsa_params_t rsa_params = NULL;
    319     mgs_srvconf_rec *sc;
    320     mgs_srvconf_rec *sc_base;
    321     void *data = NULL;
    322     int first_run = 0;
    323     const char *userdata_key = "mgs_init";
    324 
    325     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    326     apr_pool_userdata_get(&data, userdata_key, base_server->process->pool);
    327     if (data == NULL) {
    328         first_run = 1;
    329         apr_pool_userdata_set((const void *) 1, userdata_key,
    330                               apr_pool_cleanup_null,
     330        int rv;
     331        server_rec *s;
     332        gnutls_dh_params_t dh_params = NULL;
     333        gnutls_rsa_params_t rsa_params = NULL;
     334        mgs_srvconf_rec *sc;
     335        mgs_srvconf_rec *sc_base;
     336        void *data = NULL;
     337        int first_run = 0;
     338        const char *userdata_key = "mgs_init";
     339
     340        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     341        apr_pool_userdata_get(&data, userdata_key,
    331342                              base_server->process->pool);
    332     }
    333 
    334 
    335     {
     343        if (data == NULL) {
     344                first_run = 1;
     345                apr_pool_userdata_set((const void *) 1, userdata_key,
     346                                      apr_pool_cleanup_null,
     347                                      base_server->process->pool);
     348        }
     349
     350
    336351        s = base_server;
    337352        sc_base =
     
    342357
    343358        if (sc_base->dh_params == NULL) {
    344             gnutls_datum pdata = { (void *) static_dh_params, sizeof(static_dh_params) };
    345             /* loading defaults */
    346             rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata,
    347                                                GNUTLS_X509_FMT_PEM);
    348 
    349             if (rv < 0) {
    350                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    351                      "GnuTLS: Unable to load DH Params: (%d) %s",
    352                      rv, gnutls_strerror(rv));
    353                 exit(rv);
    354             }
    355         } else dh_params = sc_base->dh_params;
    356 
    357         if (sc_base->rsa_params != NULL)
    358             rsa_params = sc_base->rsa_params;
     359                gnutls_datum pdata = {
     360                        (void *) static_dh_params,
     361                        sizeof(static_dh_params)
     362                };
     363                /* loading defaults */
     364                rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata,
     365                                                   GNUTLS_X509_FMT_PEM);
     366
     367                if (rv < 0) {
     368                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     369                                     "GnuTLS: Unable to load DH Params: (%d) %s",
     370                                     rv, gnutls_strerror(rv));
     371                        exit(rv);
     372                }
     373        } else
     374                dh_params = sc_base->dh_params;
     375
     376        if (sc_base->rsa_params != NULL)
     377                rsa_params = sc_base->rsa_params;
    359378
    360379        /* else not an error but RSA-EXPORT ciphersuites are not available
     
    363382        rv = mgs_cache_post_config(p, s, sc_base);
    364383        if (rv != 0) {
    365             ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
    366                          "GnuTLS: Post Config for GnuTLSCache Failed."
    367                          " Shutting Down.");
    368             exit(-1);
     384                ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
     385                             "GnuTLS: Post Config for GnuTLSCache Failed."
     386                             " Shutting Down.");
     387                exit(-1);
    369388        }
    370389
    371390        for (s = base_server; s; s = s->next) {
    372             void *load = NULL;
    373             sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    374                                                           &gnutls_module);
    375             sc->cache_type = sc_base->cache_type;
    376             sc->cache_config = sc_base->cache_config;
    377 
    378             /* Check if the priorities have been set */
    379             if (sc->priorities == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
    380                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    381                      "GnuTLS: Host '%s:%d' is missing the GnuTLSPriorities directive!",
    382                              s->server_hostname, s->port);
    383                 exit(-1);
    384             }
    385            
    386             /* Check if DH or RSA params have been set per host */
    387             if (sc->rsa_params != NULL)
    388                 load = sc->rsa_params;
    389             else if (rsa_params) load = rsa_params;
    390            
    391             if (load != NULL)
    392                 gnutls_certificate_set_rsa_export_params(sc->certs, load);
    393 
    394 
    395             load = NULL;
    396             if (sc->dh_params != NULL)
    397                 load = sc->dh_params;
    398             else if (dh_params) load = dh_params;
    399            
    400             if (load != NULL) { /* not needed but anyway */
    401                 gnutls_certificate_set_dh_params(sc->certs, load);
    402                 gnutls_anon_set_server_dh_params(sc->anon_creds, load);
    403             }
    404 
    405             gnutls_certificate_server_set_retrieve_function(sc->certs,
    406                                                             cert_retrieve_fn);
     391                void *load = NULL;
     392                sc = (mgs_srvconf_rec *)
     393                    ap_get_module_config(s->module_config, &gnutls_module);
     394                sc->cache_type = sc_base->cache_type;
     395                sc->cache_config = sc_base->cache_config;
     396
     397                /* Check if the priorities have been set */
     398                if (sc->priorities == NULL
     399                    && sc->enabled == GNUTLS_ENABLED_TRUE) {
     400                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     401                                     "GnuTLS: Host '%s:%d' is missing the GnuTLSPriorities directive!",
     402                                     s->server_hostname, s->port);
     403                        exit(-1);
     404                }
     405
     406                /* Check if DH or RSA params have been set per host */
     407                if (sc->rsa_params != NULL)
     408                        load = sc->rsa_params;
     409                else if (rsa_params)
     410                        load = rsa_params;
     411
     412                if (load != NULL)
     413                        gnutls_certificate_set_rsa_export_params(sc->certs,
     414                                                                 load);
     415
     416
     417                load = NULL;
     418                if (sc->dh_params != NULL)
     419                        load = sc->dh_params;
     420                else if (dh_params)
     421                        load = dh_params;
     422
     423                if (load != NULL) {     /* not needed but anyway */
     424                        gnutls_certificate_set_dh_params(sc->certs, load);
     425                        gnutls_anon_set_server_dh_params(sc->anon_creds,
     426                                                         load);
     427                }
     428
     429                gnutls_certificate_server_set_retrieve_function(sc->certs,
     430                                                                cert_retrieve_fn);
    407431
    408432#ifdef ENABLE_SRP
    409             if (sc->srp_tpasswd_conf_file != NULL
    410                 && sc->srp_tpasswd_file != NULL) {
    411                 rv = gnutls_srp_set_server_credentials_file(sc->srp_creds,
    412                                                             sc->
    413                                                             srp_tpasswd_file,
    414                                                             sc->
    415                                                             srp_tpasswd_conf_file);
    416 
    417                 if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) {
    418                     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    419                                  "[GnuTLS] - Host '%s:%d' is missing a "
    420                                  "SRP password or conf File!",
    421                                  s->server_hostname, s->port);
    422                     exit(-1);
    423                 }
    424             }
    425 #endif
    426 
    427             if (sc->certs_x509[0] == NULL &&
    428                 sc->cert_pgp == NULL &&
    429                 sc->enabled == GNUTLS_ENABLED_TRUE) {
    430                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    431                              "[GnuTLS] - Host '%s:%d' is missing a "
    432                              "Certificate File!", s->server_hostname,
    433                              s->port);
    434                 exit(-1);
    435             }
    436 
    437             if (sc->enabled == GNUTLS_ENABLED_TRUE &&
    438               ((sc->certs_x509[0] != NULL && sc->privkey_x509 == NULL) ||
    439               (sc->cert_pgp != NULL && sc->privkey_pgp == NULL))) {
    440                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    441                              "[GnuTLS] - Host '%s:%d' is missing a "
    442                              "Private Key File!",
    443                              s->server_hostname, s->port);
    444                 exit(-1);
    445             }
    446 
    447             if (sc->enabled == GNUTLS_ENABLED_TRUE) {
    448                 rv = read_crt_cn(s, p, sc->certs_x509[0], &sc->cert_cn);
    449                 if (rv < 0 && sc->cert_pgp != NULL)  /* try openpgp certificate */
    450                     rv = read_pgpcrt_cn(s, p, sc->cert_pgp, &sc->cert_cn);
    451 
    452                 if (rv < 0) {
    453                     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    454                                  "[GnuTLS] - Cannot find a certificate for host '%s:%d'!",
    455                                  s->server_hostname, s->port);
    456                     sc->cert_cn = NULL;
    457                     continue;
    458                 }
    459             }
    460         }
    461     }
    462 
    463     ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION);
    464 
    465     return OK;
     433                if (sc->srp_tpasswd_conf_file != NULL
     434                    && sc->srp_tpasswd_file != NULL) {
     435                        rv = gnutls_srp_set_server_credentials_file
     436                            (sc->srp_creds, sc->srp_tpasswd_file,
     437                             sc->srp_tpasswd_conf_file);
     438
     439                        if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) {
     440                                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0,
     441                                             s,
     442                                             "[GnuTLS] - Host '%s:%d' is missing a "
     443                                             "SRP password or conf File!",
     444                                             s->server_hostname, s->port);
     445                                exit(-1);
     446                        }
     447                }
     448#endif
     449
     450                if (sc->certs_x509[0] == NULL &&
     451                    sc->cert_pgp == NULL &&
     452                    sc->enabled == GNUTLS_ENABLED_TRUE) {
     453                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     454                                     "[GnuTLS] - Host '%s:%d' is missing a "
     455                                     "Certificate File!",
     456                                     s->server_hostname, s->port);
     457                        exit(-1);
     458                }
     459
     460                if (sc->enabled == GNUTLS_ENABLED_TRUE &&
     461                    ((sc->certs_x509[0] != NULL
     462                      && sc->privkey_x509 == NULL) || (sc->cert_pgp != NULL
     463                                                       && sc->privkey_pgp
     464                                                       == NULL))) {
     465                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     466                                     "[GnuTLS] - Host '%s:%d' is missing a "
     467                                     "Private Key File!",
     468                                     s->server_hostname, s->port);
     469                        exit(-1);
     470                }
     471
     472                if (sc->enabled == GNUTLS_ENABLED_TRUE) {
     473                        rv = read_crt_cn(s, p, sc->certs_x509[0],
     474                                         &sc->cert_cn);
     475                        if (rv < 0 && sc->cert_pgp != NULL)     /* try openpgp certificate */
     476                                rv = read_pgpcrt_cn(s, p, sc->cert_pgp,
     477                                                    &sc->cert_cn);
     478
     479                        if (rv < 0) {
     480                                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0,
     481                                             s,
     482                                             "[GnuTLS] - Cannot find a certificate for host '%s:%d'!",
     483                                             s->server_hostname, s->port);
     484                                sc->cert_cn = NULL;
     485                                continue;
     486                        }
     487                }
     488        }
     489
     490
     491        ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION);
     492
     493        return OK;
    466494}
    467495
    468496void mgs_hook_child_init(apr_pool_t * p, server_rec * s)
    469497{
    470     apr_status_t rv = APR_SUCCESS;
    471     mgs_srvconf_rec *sc = ap_get_module_config(s->module_config,
    472                                                &gnutls_module);
    473 
    474     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
    475     if (sc->cache_type != mgs_cache_none) {
    476         rv = mgs_cache_child_init(p, s, sc);
    477         if (rv != APR_SUCCESS) {
    478             ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
    479                          "[GnuTLS] - Failed to run Cache Init");
    480         }
    481     } else {
    482         ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
    483                      "[GnuTLS] - No Cache Configured. Hint: GnuTLSCache");
    484     }
     498        apr_status_t rv = APR_SUCCESS;
     499        mgs_srvconf_rec *sc = ap_get_module_config(s->module_config,
     500                                                   &gnutls_module);
     501
     502        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     503        if (sc->cache_type != mgs_cache_none) {
     504                rv = mgs_cache_child_init(p, s, sc);
     505                if (rv != APR_SUCCESS) {
     506                        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
     507                                     "[GnuTLS] - Failed to run Cache Init");
     508                }
     509        }
    485510}
    486511
    487512const char *mgs_hook_http_scheme(const request_rec * r)
    488513{
    489     mgs_srvconf_rec *sc;
    490    
    491     if (r == NULL)
    492         return NULL;
    493    
    494     sc =
    495         (mgs_srvconf_rec *) ap_get_module_config(r->server->module_config,
    496                                                  &gnutls_module);
    497 
    498     _gnutls_log(debug_log_fp,  "%s: %d\n", __func__, __LINE__);
    499     if (sc->enabled == GNUTLS_ENABLED_FALSE) {
    500         return NULL;
    501     }
    502 
    503     return "https";
     514        mgs_srvconf_rec *sc;
     515
     516        if (r == NULL)
     517                return NULL;
     518
     519        sc = (mgs_srvconf_rec *) ap_get_module_config(r->
     520                                                      server->module_config,
     521                                                      &gnutls_module);
     522
     523        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     524        if (sc->enabled == GNUTLS_ENABLED_FALSE) {
     525                return NULL;
     526        }
     527
     528        return "https";
    504529}
    505530
    506531apr_port_t mgs_hook_default_port(const request_rec * r)
    507532{
    508     mgs_srvconf_rec *sc;
    509    
    510     if (r == NULL)
    511         return 0;
    512    
    513     sc =
    514         (mgs_srvconf_rec *) ap_get_module_config(r->server->module_config,
    515                                                  &gnutls_module);
    516 
    517     _gnutls_log(debug_log_fp,  "%s: %d\n", __func__, __LINE__);
    518     if (sc->enabled == GNUTLS_ENABLED_FALSE) {
    519         return 0;
    520     }
    521 
    522     return 443;
     533        mgs_srvconf_rec *sc;
     534
     535        if (r == NULL)
     536                return 0;
     537
     538        sc = (mgs_srvconf_rec *) ap_get_module_config(r->
     539                                                      server->module_config,
     540                                                      &gnutls_module);
     541
     542        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     543        if (sc->enabled == GNUTLS_ENABLED_FALSE) {
     544                return 0;
     545        }
     546
     547        return 443;
    523548}
    524549
     
    527552#if USING_2_1_RECENT
    528553typedef struct {
    529     mgs_handle_t *ctxt;
    530     mgs_srvconf_rec *sc;
    531     const char *sni_name;
     554        mgs_handle_t *ctxt;
     555        mgs_srvconf_rec *sc;
     556        const char *sni_name;
    532557} vhost_cb_rec;
    533558
    534559static int vhost_cb(void *baton, conn_rec * conn, server_rec * s)
    535560{
    536     mgs_srvconf_rec *tsc;
    537     vhost_cb_rec *x = baton;
    538 
    539     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
    540     tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    541                                                    &gnutls_module);
    542 
    543     if (tsc->enabled != GNUTLS_ENABLED_TRUE || tsc->cert_cn == NULL) {
     561        mgs_srvconf_rec *tsc;
     562        vhost_cb_rec *x = baton;
     563
     564        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     565        tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
     566                                                       &gnutls_module);
     567
     568        if (tsc->enabled != GNUTLS_ENABLED_TRUE || tsc->cert_cn == NULL) {
     569                return 0;
     570        }
     571
     572        /* The CN can contain a * -- this will match those too. */
     573        if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) {
     574                /* found a match */
     575#if MOD_GNUTLS_DEBUG
     576                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
     577                             x->ctxt->c->base_server,
     578                             "GnuTLS: Virtual Host CB: "
     579                             "'%s' == '%s'", tsc->cert_cn, x->sni_name);
     580#endif
     581                /* Because we actually change the server used here, we need to reset
     582                 * things like ClientVerify.
     583                 */
     584                x->sc = tsc;
     585                /* Shit. Crap. Dammit. We *really* should rehandshake here, as our
     586                 * certificate structure *should* change when the server changes.
     587                 * acccckkkkkk.
     588                 */
     589                return 1;
     590        } else {
     591#if MOD_GNUTLS_DEBUG
     592                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
     593                             x->ctxt->c->base_server,
     594                             "GnuTLS: Virtual Host CB: "
     595                             "'%s' != '%s'", tsc->cert_cn, x->sni_name);
     596#endif
     597
     598        }
    544599        return 0;
    545     }
    546 
    547     /* The CN can contain a * -- this will match those too. */
    548     if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) {
    549         /* found a match */
    550 #if MOD_GNUTLS_DEBUG
    551         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
    552                      x->ctxt->c->base_server,
    553                      "GnuTLS: Virtual Host CB: "
    554                      "'%s' == '%s'", tsc->cert_cn, x->sni_name);
    555 #endif
    556         /* Because we actually change the server used here, we need to reset
    557          * things like ClientVerify.
    558          */
    559         x->sc = tsc;
    560         /* Shit. Crap. Dammit. We *really* should rehandshake here, as our
    561          * certificate structure *should* change when the server changes.
    562          * acccckkkkkk.
    563          */
    564         return 1;
    565     } else {
    566 #if MOD_GNUTLS_DEBUG
    567         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
    568                      x->ctxt->c->base_server,
    569                      "GnuTLS: Virtual Host CB: "
    570                      "'%s' != '%s'", tsc->cert_cn, x->sni_name);
    571 #endif
    572 
    573     }
    574     return 0;
    575600}
    576601#endif
     
    578603mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session)
    579604{
    580     int rv;
    581     unsigned int sni_type;
    582     size_t data_len = MAX_HOST_LEN;
    583     char sni_name[MAX_HOST_LEN];
    584     mgs_handle_t *ctxt;
     605        int rv;
     606        unsigned int sni_type;
     607        size_t data_len = MAX_HOST_LEN;
     608        char sni_name[MAX_HOST_LEN];
     609        mgs_handle_t *ctxt;
    585610#if USING_2_1_RECENT
    586     vhost_cb_rec cbx;
     611        vhost_cb_rec cbx;
    587612#else
    588     server_rec *s;
    589     mgs_srvconf_rec *tsc;
    590 #endif
    591 
    592     if (session == NULL)
    593         return NULL;
    594 
    595     _gnutls_log(debug_log_fp,  "%s: %d\n", __func__, __LINE__);
    596     ctxt = gnutls_transport_get_ptr(session);
    597 
    598     rv = gnutls_server_name_get(ctxt->session, sni_name,
    599                                 &data_len, &sni_type, 0);
    600 
    601     if (rv != 0) {
    602         return NULL;
    603     }
    604 
    605     if (sni_type != GNUTLS_NAME_DNS) {
    606         ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
    607                      ctxt->c->base_server,
    608                      "GnuTLS: Unknown type '%d' for SNI: "
    609                      "'%s'", sni_type, sni_name);
    610         return NULL;
    611     }
     613        server_rec *s;
     614        mgs_srvconf_rec *tsc;
     615#endif
     616
     617        if (session == NULL)
     618                return NULL;
     619
     620        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     621        ctxt = gnutls_transport_get_ptr(session);
     622
     623        rv = gnutls_server_name_get(ctxt->session, sni_name,
     624                                    &data_len, &sni_type, 0);
     625
     626        if (rv != 0) {
     627                return NULL;
     628        }
     629
     630        if (sni_type != GNUTLS_NAME_DNS) {
     631                ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
     632                             ctxt->c->base_server,
     633                             "GnuTLS: Unknown type '%d' for SNI: "
     634                             "'%s'", sni_type, sni_name);
     635                return NULL;
     636        }
    612637
    613638    /**
     
    616641     */
    617642#if USING_2_1_RECENT
    618     cbx.ctxt = ctxt;
    619     cbx.sc = NULL;
    620     cbx.sni_name = sni_name;
    621 
    622     rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx);
    623     if (rv == 1) {
    624         return cbx.sc;
    625     }
     643        cbx.ctxt = ctxt;
     644        cbx.sc = NULL;
     645        cbx.sni_name = sni_name;
     646
     647        rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx);
     648        if (rv == 1) {
     649                return cbx.sc;
     650        }
    626651#else
    627     for (s = ap_server_conf; s; s = s->next) {
    628 
    629         tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    630                                                        &gnutls_module);
    631         if (tsc->enabled != GNUTLS_ENABLED_TRUE) {
    632             continue;
    633         }
     652        for (s = ap_server_conf; s; s = s->next) {
     653
     654                tsc =
     655                    (mgs_srvconf_rec *)
     656                    ap_get_module_config(s->module_config, &gnutls_module);
     657                if (tsc->enabled != GNUTLS_ENABLED_TRUE) {
     658                        continue;
     659                }
    634660#if MOD_GNUTLS_DEBUG
    635         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
    636                      ctxt->c->base_server,
    637                      "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X  sc: 0x%08X",
    638                      tsc->cert_cn, rv,
    639                      gnutls_pk_algorithm_get_name
    640                      (gnutls_x509_privkey_get_pk_algorithm
    641                       (ctxt->sc->privkey_x509)), (unsigned int) s,
    642                      (unsigned int) s->next, (unsigned int) tsc);
    643 #endif
    644         /* The CN can contain a * -- this will match those too. */
    645         if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) {
     661                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
     662                             ctxt->c->base_server,
     663                             "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X  sc: 0x%08X",
     664                             tsc->cert_cn, rv,
     665                             gnutls_pk_algorithm_get_name
     666                             (gnutls_x509_privkey_get_pk_algorithm
     667                              (ctxt->sc->privkey_x509)), (unsigned int) s,
     668                             (unsigned int) s->next, (unsigned int) tsc);
     669#endif
     670                /* The CN can contain a * -- this will match those too. */
     671                if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) {
    646672#if MOD_GNUTLS_DEBUG
    647             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
    648                          ctxt->c->base_server,
    649                          "GnuTLS: Virtual Host: "
    650                          "'%s' == '%s'", tsc->cert_cn, sni_name);
    651 #endif
    652             return tsc;
    653         }
    654     }
    655 #endif
    656     return NULL;
     673                        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
     674                                     ctxt->c->base_server,
     675                                     "GnuTLS: Virtual Host: "
     676                                     "'%s' == '%s'", tsc->cert_cn,
     677                                     sni_name);
     678#endif
     679                        return tsc;
     680                }
     681        }
     682#endif
     683        return NULL;
    657684}
    658685
    659686
    660687static const int protocol_priority[] = {
    661     GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0
     688        GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0
    662689};
    663690
     
    665692static mgs_handle_t *create_gnutls_handle(apr_pool_t * pool, conn_rec * c)
    666693{
    667     mgs_handle_t *ctxt;
    668     mgs_srvconf_rec *sc =
    669         (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
    670                                                  module_config,
    671                                                  &gnutls_module);
    672 
    673     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
    674     ctxt = apr_pcalloc(pool, sizeof(*ctxt));
    675     ctxt->c = c;
    676     ctxt->sc = sc;
    677     ctxt->status = 0;
    678 
    679     ctxt->input_rc = APR_SUCCESS;
    680     ctxt->input_bb = apr_brigade_create(c->pool, c->bucket_alloc);
    681     ctxt->input_cbuf.length = 0;
    682 
    683     ctxt->output_rc = APR_SUCCESS;
    684     ctxt->output_bb = apr_brigade_create(c->pool, c->bucket_alloc);
    685     ctxt->output_blen = 0;
    686     ctxt->output_length = 0;
    687 
    688     gnutls_init(&ctxt->session, GNUTLS_SERVER);
    689     if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0)
    690         gnutls_session_ticket_enable_server(ctxt->session, &session_ticket_key);
    691 
    692     /* because we don't set any default priorities here (we set later at
    693      * the user hello callback) we need to at least set this in order for
    694      * gnutls to be able to read packets.
    695      */
    696     gnutls_protocol_set_priority(ctxt->session, protocol_priority);
    697 
    698     gnutls_handshake_set_post_client_hello_function(ctxt->session,
    699                                                     mgs_select_virtual_server_cb);
    700 
    701     mgs_cache_session_init(ctxt);
    702 
    703     return ctxt;
     694        mgs_handle_t *ctxt;
     695        mgs_srvconf_rec *sc =
     696            (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
     697                                                     module_config,
     698                                                     &gnutls_module);
     699
     700        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     701        ctxt = apr_pcalloc(pool, sizeof(*ctxt));
     702        ctxt->c = c;
     703        ctxt->sc = sc;
     704        ctxt->status = 0;
     705
     706        ctxt->input_rc = APR_SUCCESS;
     707        ctxt->input_bb = apr_brigade_create(c->pool, c->bucket_alloc);
     708        ctxt->input_cbuf.length = 0;
     709
     710        ctxt->output_rc = APR_SUCCESS;
     711        ctxt->output_bb = apr_brigade_create(c->pool, c->bucket_alloc);
     712        ctxt->output_blen = 0;
     713        ctxt->output_length = 0;
     714
     715        gnutls_init(&ctxt->session, GNUTLS_SERVER);
     716        if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0)
     717                gnutls_session_ticket_enable_server(ctxt->session,
     718                                                    &session_ticket_key);
     719
     720        /* because we don't set any default priorities here (we set later at
     721         * the user hello callback) we need to at least set this in order for
     722         * gnutls to be able to read packets.
     723         */
     724        gnutls_protocol_set_priority(ctxt->session, protocol_priority);
     725
     726        gnutls_handshake_set_post_client_hello_function(ctxt->session,
     727                                                        mgs_select_virtual_server_cb);
     728
     729        mgs_cache_session_init(ctxt);
     730
     731        return ctxt;
    704732}
    705733
    706734int mgs_hook_pre_connection(conn_rec * c, void *csd)
    707735{
    708     mgs_handle_t *ctxt;
    709     mgs_srvconf_rec *sc;
    710 
    711     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
    712    
    713     if (c == NULL)
    714         return DECLINED;
    715    
    716     sc =
    717         (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
    718                                                  module_config,
    719                                                  &gnutls_module);
    720 
    721     if (!(sc && (sc->enabled == GNUTLS_ENABLED_TRUE))) {
     736        mgs_handle_t *ctxt;
     737        mgs_srvconf_rec *sc;
     738
     739        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     740
     741        if (c == NULL) {
     742                return DECLINED;
     743        }
     744
     745        sc = (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
     746                                                      module_config,
     747                                                      &gnutls_module);
     748
     749        if (!(sc && (sc->enabled == GNUTLS_ENABLED_TRUE))) {
     750                return DECLINED;
     751        }
     752
     753        if (c->remote_addr->hostname || apr_strnatcmp(c->remote_ip,c->local_ip) == 0) {
     754        /* Connection initiated by Apache (mod_proxy) => ignore */
     755                return OK;
     756        }
     757               
     758        ctxt = create_gnutls_handle(c->pool, c);
     759
     760        ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
     761
     762        gnutls_transport_set_pull_function(ctxt->session,
     763                                           mgs_transport_read);
     764        gnutls_transport_set_push_function(ctxt->session,
     765                                           mgs_transport_write);
     766        gnutls_transport_set_ptr(ctxt->session, ctxt);
     767
     768        ctxt->input_filter =
     769            ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt, NULL, c);
     770        ctxt->output_filter =
     771            ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt, NULL, c);
     772
     773        return OK;
     774}
     775
     776int mgs_hook_fixups(request_rec * r)
     777{
     778        unsigned char sbuf[GNUTLS_MAX_SESSION_ID];
     779        char buf[AP_IOBUFSIZE];
     780        const char *tmp;
     781        size_t len;
     782        mgs_handle_t *ctxt;
     783        int rv = OK;
     784
     785        if (r == NULL)
     786                return DECLINED;
     787
     788        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     789        apr_table_t *env = r->subprocess_env;
     790
     791        ctxt =
     792            ap_get_module_config(r->connection->conn_config,
     793                                 &gnutls_module);
     794
     795        if (!ctxt || ctxt->session == NULL) {
     796                return DECLINED;
     797        }
     798
     799        apr_table_setn(env, "HTTPS", "on");
     800
     801        apr_table_setn(env, "SSL_VERSION_LIBRARY",
     802                       "GnuTLS/" LIBGNUTLS_VERSION);
     803        apr_table_setn(env, "SSL_VERSION_INTERFACE",
     804                       "mod_gnutls/" MOD_GNUTLS_VERSION);
     805
     806        apr_table_setn(env, "SSL_PROTOCOL",
     807                       gnutls_protocol_get_name(gnutls_protocol_get_version
     808                                                (ctxt->session)));
     809
     810        /* should have been called SSL_CIPHERSUITE instead */
     811        apr_table_setn(env, "SSL_CIPHER",
     812                       gnutls_cipher_suite_get_name(gnutls_kx_get
     813                                                    (ctxt->session),
     814                                                    gnutls_cipher_get
     815                                                    (ctxt->session),
     816                                                    gnutls_mac_get
     817                                                    (ctxt->session)));
     818
     819        apr_table_setn(env, "SSL_COMPRESS_METHOD",
     820                       gnutls_compression_get_name(gnutls_compression_get
     821                                                   (ctxt->session)));
     822
     823#ifdef ENABLE_SRP
     824        tmp = gnutls_srp_server_get_username(ctxt->session);
     825        apr_table_setn(env, "SSL_SRP_USER", (tmp != NULL) ? tmp : "");
     826#endif
     827
     828        if (apr_table_get(env, "SSL_CLIENT_VERIFY") == NULL)
     829                apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE");
     830
     831        unsigned int key_size =
     832            8 *
     833            gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session));
     834        tmp = apr_psprintf(r->pool, "%u", key_size);
     835
     836        apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp);
     837
     838        apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp);
     839
     840        apr_table_setn(env, "SSL_CIPHER_EXPORT",
     841                       (key_size <= 40) ? "true" : "false");
     842
     843        len = sizeof(sbuf);
     844        gnutls_session_get_id(ctxt->session, sbuf, &len);
     845        tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
     846        apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp));
     847
     848        if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509)
     849                mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0,
     850                                         ctxt->
     851                                         sc->export_certificates_enabled);
     852        else if (gnutls_certificate_type_get(ctxt->session) ==
     853                 GNUTLS_CRT_OPENPGP)
     854                mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0,
     855                                            ctxt->
     856                                            sc->export_certificates_enabled);
     857
     858        return rv;
     859}
     860
     861int mgs_hook_authz(request_rec * r)
     862{
     863        int rv;
     864        mgs_handle_t *ctxt;
     865        mgs_dirconf_rec *dc;
     866
     867        if (r == NULL)
     868                return DECLINED;
     869
     870        dc = ap_get_module_config(r->per_dir_config, &gnutls_module);
     871
     872        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     873        ctxt =
     874            ap_get_module_config(r->connection->conn_config,
     875                                 &gnutls_module);
     876
     877        if (!ctxt || ctxt->session == NULL) {
     878                return DECLINED;
     879        }
     880
     881        if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) {
     882                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     883                              "GnuTLS: Directory set to Ignore Client Certificate!");
     884        } else {
     885                if (ctxt->sc->client_verify_mode < dc->client_verify_mode) {
     886                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     887                                      "GnuTLS: Attempting to rehandshake with peer. %d %d",
     888                                      ctxt->sc->client_verify_mode,
     889                                      dc->client_verify_mode);
     890
     891                        /* If we already have a client certificate, there's no point in
     892                         * re-handshaking... */
     893                        rv = mgs_cert_verify(r, ctxt);
     894                        if (rv != DECLINED && rv != HTTP_FORBIDDEN)
     895                                return rv;
     896
     897                        gnutls_certificate_server_set_request
     898                            (ctxt->session, dc->client_verify_mode);
     899
     900                        if (mgs_rehandshake(ctxt) != 0) {
     901                                return HTTP_FORBIDDEN;
     902                        }
     903                } else if (ctxt->sc->client_verify_mode ==
     904                           GNUTLS_CERT_IGNORE) {
     905#if MOD_GNUTLS_DEBUG
     906                        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     907                                      "GnuTLS: Peer is set to IGNORE");
     908#endif
     909                        return DECLINED;
     910                }
     911                rv = mgs_cert_verify(r, ctxt);
     912                if (rv != DECLINED &&
     913                    (rv != HTTP_FORBIDDEN ||
     914                     dc->client_verify_mode == GNUTLS_CERT_REQUIRE)) {
     915                        return rv;
     916                }
     917        }
     918
    722919        return DECLINED;
    723     }
    724 
    725     if(c->remote_addr->hostname)
    726       /* Connection initiated by Apache (mod_proxy) => ignore */
    727       return OK;
    728 
    729     ctxt = create_gnutls_handle(c->pool, c);
    730 
    731     ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
    732 
    733     gnutls_transport_set_pull_function(ctxt->session, mgs_transport_read);
    734     gnutls_transport_set_push_function(ctxt->session, mgs_transport_write);
    735     gnutls_transport_set_ptr(ctxt->session, ctxt);
    736 
    737     ctxt->input_filter =
    738         ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt, NULL, c);
    739     ctxt->output_filter =
    740         ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt, NULL, c);
    741 
    742     return OK;
    743 }
    744 
    745 int mgs_hook_fixups(request_rec * r)
    746 {
    747     unsigned char sbuf[GNUTLS_MAX_SESSION_ID];
    748     char buf[AP_IOBUFSIZE];
    749     const char *tmp;
    750     size_t len;
    751     mgs_handle_t *ctxt;
    752     int rv = OK;
    753 
    754     if (r == NULL)
    755         return DECLINED;
    756 
    757     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
    758     apr_table_t *env = r->subprocess_env;
    759 
    760     ctxt =
    761         ap_get_module_config(r->connection->conn_config, &gnutls_module);
    762 
    763     if (!ctxt || ctxt->session == NULL) {
    764         return DECLINED;
    765     }
    766 
    767     apr_table_setn(env, "HTTPS", "on");
    768 
    769     apr_table_setn(env, "SSL_VERSION_LIBRARY",
    770                    "GnuTLS/" LIBGNUTLS_VERSION);
    771     apr_table_setn(env, "SSL_VERSION_INTERFACE",
    772                    "mod_gnutls/" MOD_GNUTLS_VERSION);
    773 
    774     apr_table_setn(env, "SSL_PROTOCOL",
    775                    gnutls_protocol_get_name(gnutls_protocol_get_version
    776                                             (ctxt->session)));
    777 
    778     /* should have been called SSL_CIPHERSUITE instead */
    779     apr_table_setn(env, "SSL_CIPHER",
    780                    gnutls_cipher_suite_get_name(gnutls_kx_get
    781                                                 (ctxt->session),
    782                                                 gnutls_cipher_get(ctxt->
    783                                                                   session),
    784                                                 gnutls_mac_get(ctxt->
    785                                                                session)));
    786 
    787     apr_table_setn(env, "SSL_COMPRESS_METHOD",
    788                    gnutls_compression_get_name(gnutls_compression_get
    789                                                (ctxt->session)));
    790 
    791 #ifdef ENABLE_SRP
    792     tmp = gnutls_srp_server_get_username(ctxt->session);
    793     apr_table_setn(env, "SSL_SRP_USER", (tmp!=NULL)?tmp:"");
    794 #endif
    795 
    796     if (apr_table_get(env, "SSL_CLIENT_VERIFY") == NULL)
    797         apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE");
    798 
    799     unsigned int key_size =
    800         8 * gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session));
    801     tmp = apr_psprintf(r->pool, "%u", key_size);
    802 
    803     apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp);
    804 
    805     apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp);
    806 
    807     apr_table_setn(env, "SSL_CIPHER_EXPORT",
    808                    (key_size <= 40) ? "true" : "false");
    809 
    810     len = sizeof(sbuf);
    811     gnutls_session_get_id(ctxt->session, sbuf, &len);
    812     tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
    813     apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp));
    814 
    815     if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509)
    816         mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0,
    817                              ctxt->sc->export_certificates_enabled);
    818     else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP)
    819         mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0,
    820                              ctxt->sc->export_certificates_enabled);
    821 
    822     return rv;
    823 }
    824 
    825 int mgs_hook_authz(request_rec * r)
    826 {
    827     int rv;
    828     mgs_handle_t *ctxt;
    829     mgs_dirconf_rec *dc;
    830    
    831     if (r == NULL)
    832         return DECLINED;
    833    
    834     dc = ap_get_module_config(r->per_dir_config,
    835                                                &gnutls_module);
    836 
    837     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
    838     ctxt =
    839         ap_get_module_config(r->connection->conn_config, &gnutls_module);
    840 
    841     if (!ctxt || ctxt->session == NULL) {
    842         return DECLINED;
    843     }
    844 
    845     if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) {
    846         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
    847                       "GnuTLS: Directory set to Ignore Client Certificate!");
    848     } else {
    849         if (ctxt->sc->client_verify_mode < dc->client_verify_mode) {
    850             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
    851                           "GnuTLS: Attempting to rehandshake with peer. %d %d",
    852                           ctxt->sc->client_verify_mode,
    853                           dc->client_verify_mode);
    854 
    855             /* If we already have a client certificate, there's no point in
    856              * re-handshaking... */
    857             rv = mgs_cert_verify(r, ctxt);
    858             if (rv != DECLINED && rv != HTTP_FORBIDDEN)
    859                 return rv;
    860 
    861             gnutls_certificate_server_set_request(ctxt->session,
    862                                                   dc->client_verify_mode);
    863 
    864             if (mgs_rehandshake(ctxt) != 0) {
    865                 return HTTP_FORBIDDEN;
    866             }
    867         } else if (ctxt->sc->client_verify_mode == GNUTLS_CERT_IGNORE) {
    868 #if MOD_GNUTLS_DEBUG
    869             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    870                           "GnuTLS: Peer is set to IGNORE");
    871 #endif
    872             return DECLINED;
    873         }
    874         rv = mgs_cert_verify(r, ctxt);
    875         if (rv != DECLINED &&
    876             (rv != HTTP_FORBIDDEN ||
    877              dc->client_verify_mode == GNUTLS_CERT_REQUIRE)) {
    878             return rv;
    879         }
    880     }
    881 
    882     return DECLINED;
    883920}
    884921
     
    896933                         int export_certificates_enabled)
    897934{
    898     unsigned char sbuf[64];     /* buffer to hold serials */
    899     char buf[AP_IOBUFSIZE];
    900     const char *tmp;
    901     char *tmp2;
    902     size_t len;
    903     int ret, i;
    904 
    905     if (r == NULL)
    906         return;
    907 
    908     apr_table_t *env = r->subprocess_env;
    909 
    910     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
    911     if (export_certificates_enabled != 0) {
    912         char cert_buf[10 * 1024];
    913         len = sizeof(cert_buf);
    914 
    915         if (gnutls_x509_crt_export
    916             (cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0)
    917             apr_table_setn(env,
    918                            apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL),
    919                            apr_pstrmemdup(r->pool, cert_buf, len));
    920 
    921     }
    922 
    923     len = sizeof(buf);
    924     gnutls_x509_crt_get_dn(cert, buf, &len);
    925     apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_S_DN", NULL),
    926                    apr_pstrmemdup(r->pool, buf, len));
    927 
    928     len = sizeof(buf);
    929     gnutls_x509_crt_get_issuer_dn(cert, buf, &len);
    930     apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_I_DN", NULL),
    931                    apr_pstrmemdup(r->pool, buf, len));
    932 
    933     len = sizeof(sbuf);
    934     gnutls_x509_crt_get_serial(cert, sbuf, &len);
    935     tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
    936     apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_M_SERIAL", NULL),
    937                    apr_pstrdup(r->pool, tmp));
    938 
    939     ret = gnutls_x509_crt_get_version(cert);
    940     if (ret > 0)
     935        unsigned char sbuf[64]; /* buffer to hold serials */
     936        char buf[AP_IOBUFSIZE];
     937        const char *tmp;
     938        char *tmp2;
     939        size_t len;
     940        int ret, i;
     941
     942        if (r == NULL)
     943                return;
     944
     945        apr_table_t *env = r->subprocess_env;
     946
     947        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     948        if (export_certificates_enabled != 0) {
     949                char cert_buf[10 * 1024];
     950                len = sizeof(cert_buf);
     951
     952                if (gnutls_x509_crt_export
     953                    (cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0)
     954                        apr_table_setn(env,
     955                                       apr_pstrcat(r->pool, MGS_SIDE,
     956                                                   "_CERT", NULL),
     957                                       apr_pstrmemdup(r->pool, cert_buf,
     958                                                      len));
     959
     960        }
     961
     962        len = sizeof(buf);
     963        gnutls_x509_crt_get_dn(cert, buf, &len);
     964        apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_S_DN", NULL),
     965                       apr_pstrmemdup(r->pool, buf, len));
     966
     967        len = sizeof(buf);
     968        gnutls_x509_crt_get_issuer_dn(cert, buf, &len);
     969        apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_I_DN", NULL),
     970                       apr_pstrmemdup(r->pool, buf, len));
     971
     972        len = sizeof(sbuf);
     973        gnutls_x509_crt_get_serial(cert, sbuf, &len);
     974        tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
    941975        apr_table_setn(env,
    942                        apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", NULL),
    943                        apr_psprintf(r->pool, "%u", ret));
    944 
    945     apr_table_setn(env,
    946        apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL), "X.509");
    947 
    948     tmp =
    949         mgs_time2sz(gnutls_x509_crt_get_expiration_time
    950                     (cert), buf, sizeof(buf));
    951     apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL),
    952                    apr_pstrdup(r->pool, tmp));
    953 
    954     tmp =
    955         mgs_time2sz(gnutls_x509_crt_get_activation_time
    956                     (cert), buf, sizeof(buf));
    957     apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL),
    958                    apr_pstrdup(r->pool, tmp));
    959 
    960     ret = gnutls_x509_crt_get_signature_algorithm(cert);
    961     if (ret >= 0) {
    962         apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG", NULL),
    963                        gnutls_sign_algorithm_get_name(ret));
    964     }
    965 
    966     ret = gnutls_x509_crt_get_pk_algorithm(cert, NULL);
    967     if (ret >= 0) {
    968         apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL),
    969                        gnutls_pk_algorithm_get_name(ret));
    970     }
    971 
    972     /* export all the alternative names (DNS, RFC822 and URI) */
    973     for (i = 0; !(ret < 0); i++) {
    974         len = 0;
    975         ret = gnutls_x509_crt_get_subject_alt_name(cert, i,
    976                                                    NULL, &len, NULL);
    977 
    978         if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER && len > 1) {
    979             tmp2 = apr_palloc(r->pool, len + 1);
    980 
    981             ret =
    982                 gnutls_x509_crt_get_subject_alt_name(cert, i, tmp2, &len,
    983                                                      NULL);
    984             tmp2[len] = 0;
    985 
    986             if (ret == GNUTLS_SAN_DNSNAME) {
     976                       apr_pstrcat(r->pool, MGS_SIDE, "_M_SERIAL", NULL),
     977                       apr_pstrdup(r->pool, tmp));
     978
     979        ret = gnutls_x509_crt_get_version(cert);
     980        if (ret > 0)
    987981                apr_table_setn(env,
    988                        apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i),
    989                        apr_psprintf(r->pool, "DNSNAME:%s", tmp2));
    990             } else if (ret == GNUTLS_SAN_RFC822NAME) {
     982                               apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION",
     983                                           NULL), apr_psprintf(r->pool,
     984                                                               "%u", ret));
     985
     986        apr_table_setn(env,
     987                       apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL),
     988                       "X.509");
     989
     990        tmp =
     991            mgs_time2sz(gnutls_x509_crt_get_expiration_time
     992                        (cert), buf, sizeof(buf));
     993        apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL),
     994                       apr_pstrdup(r->pool, tmp));
     995
     996        tmp =
     997            mgs_time2sz(gnutls_x509_crt_get_activation_time
     998                        (cert), buf, sizeof(buf));
     999        apr_table_setn(env,
     1000                       apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL),
     1001                       apr_pstrdup(r->pool, tmp));
     1002
     1003        ret = gnutls_x509_crt_get_signature_algorithm(cert);
     1004        if (ret >= 0) {
    9911005                apr_table_setn(env,
    992                        apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i),
    993                        apr_psprintf(r->pool, "RFC822NAME:%s", tmp2));
    994             } else if (ret == GNUTLS_SAN_URI) {
     1006                               apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG",
     1007                                           NULL),
     1008                               gnutls_sign_algorithm_get_name(ret));
     1009        }
     1010
     1011        ret = gnutls_x509_crt_get_pk_algorithm(cert, NULL);
     1012        if (ret >= 0) {
    9951013                apr_table_setn(env,
    996                        apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i),
    997                        apr_psprintf(r->pool, "URI:%s", tmp2));
    998             } else {
     1014                               apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY",
     1015                                           NULL),
     1016                               gnutls_pk_algorithm_get_name(ret));
     1017        }
     1018
     1019        /* export all the alternative names (DNS, RFC822 and URI) */
     1020        for (i = 0; !(ret < 0); i++) {
     1021                len = 0;
     1022                ret = gnutls_x509_crt_get_subject_alt_name(cert, i,
     1023                                                           NULL, &len,
     1024                                                           NULL);
     1025
     1026                if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER && len > 1) {
     1027                        tmp2 = apr_palloc(r->pool, len + 1);
     1028
     1029                        ret =
     1030                            gnutls_x509_crt_get_subject_alt_name(cert, i,
     1031                                                                 tmp2,
     1032                                                                 &len,
     1033                                                                 NULL);
     1034                        tmp2[len] = 0;
     1035
     1036                        if (ret == GNUTLS_SAN_DNSNAME) {
     1037                                apr_table_setn(env,
     1038                                               apr_psprintf(r->pool,
     1039                                                            "%s_S_AN%u",
     1040                                                            MGS_SIDE, i),
     1041                                               apr_psprintf(r->pool,
     1042                                                            "DNSNAME:%s",
     1043                                                            tmp2));
     1044                        } else if (ret == GNUTLS_SAN_RFC822NAME) {
     1045                                apr_table_setn(env,
     1046                                               apr_psprintf(r->pool,
     1047                                                            "%s_S_AN%u",
     1048                                                            MGS_SIDE, i),
     1049                                               apr_psprintf(r->pool,
     1050                                                            "RFC822NAME:%s",
     1051                                                            tmp2));
     1052                        } else if (ret == GNUTLS_SAN_URI) {
     1053                                apr_table_setn(env,
     1054                                               apr_psprintf(r->pool,
     1055                                                            "%s_S_AN%u",
     1056                                                            MGS_SIDE, i),
     1057                                               apr_psprintf(r->pool,
     1058                                                            "URI:%s",
     1059                                                            tmp2));
     1060                        } else {
     1061                                apr_table_setn(env,
     1062                                               apr_psprintf(r->pool,
     1063                                                            "%s_S_AN%u",
     1064                                                            MGS_SIDE, i),
     1065                                               "UNSUPPORTED");
     1066                        }
     1067                }
     1068        }
     1069}
     1070
     1071static void
     1072mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert,
     1073                            int side, int export_certificates_enabled)
     1074{
     1075        unsigned char sbuf[64]; /* buffer to hold serials */
     1076        char buf[AP_IOBUFSIZE];
     1077        const char *tmp;
     1078        size_t len;
     1079        int ret;
     1080
     1081        if (r == NULL)
     1082                return;
     1083
     1084        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     1085        apr_table_t *env = r->subprocess_env;
     1086
     1087        if (export_certificates_enabled != 0) {
     1088                char cert_buf[10 * 1024];
     1089                len = sizeof(cert_buf);
     1090
     1091                if (gnutls_openpgp_crt_export
     1092                    (cert, GNUTLS_OPENPGP_FMT_BASE64, cert_buf, &len) >= 0)
     1093                        apr_table_setn(env,
     1094                                       apr_pstrcat(r->pool, MGS_SIDE,
     1095                                                   "_CERT", NULL),
     1096                                       apr_pstrmemdup(r->pool, cert_buf,
     1097                                                      len));
     1098
     1099        }
     1100
     1101        len = sizeof(buf);
     1102        gnutls_openpgp_crt_get_name(cert, 0, buf, &len);
     1103        apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_NAME", NULL),
     1104                       apr_pstrmemdup(r->pool, buf, len));
     1105
     1106        len = sizeof(sbuf);
     1107        gnutls_openpgp_crt_get_fingerprint(cert, sbuf, &len);
     1108        tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
     1109        apr_table_setn(env,
     1110                       apr_pstrcat(r->pool, MGS_SIDE, "_FINGERPRINT",
     1111                                   NULL), apr_pstrdup(r->pool, tmp));
     1112
     1113        ret = gnutls_openpgp_crt_get_version(cert);
     1114        if (ret > 0)
    9991115                apr_table_setn(env,
    1000                        apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i),
    1001                        "UNSUPPORTED");
    1002             }
    1003         }
    1004     }
    1005 }
    1006 
    1007 static void
    1008 mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side,
    1009                          int export_certificates_enabled)
    1010 {
    1011     unsigned char sbuf[64];     /* buffer to hold serials */
    1012     char buf[AP_IOBUFSIZE];
    1013     const char *tmp;
    1014     size_t len;
    1015     int ret;
    1016    
    1017     if (r == NULL)
    1018         return;
    1019 
    1020     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
    1021     apr_table_t *env = r->subprocess_env;
    1022 
    1023     if (export_certificates_enabled != 0) {
    1024         char cert_buf[10 * 1024];
    1025         len = sizeof(cert_buf);
    1026 
    1027         if (gnutls_openpgp_crt_export
    1028             (cert, GNUTLS_OPENPGP_FMT_BASE64, cert_buf, &len) >= 0)
    1029             apr_table_setn(env,
    1030                            apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL),
    1031                            apr_pstrmemdup(r->pool, cert_buf, len));
    1032 
    1033     }
    1034 
    1035     len = sizeof(buf);
    1036     gnutls_openpgp_crt_get_name(cert, 0, buf, &len);
    1037     apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_NAME", NULL),
    1038                    apr_pstrmemdup(r->pool, buf, len));
    1039 
    1040     len = sizeof(sbuf);
    1041     gnutls_openpgp_crt_get_fingerprint(cert, sbuf, &len);
    1042     tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
    1043     apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_FINGERPRINT", NULL),
    1044                    apr_pstrdup(r->pool, tmp));
    1045 
    1046     ret = gnutls_openpgp_crt_get_version(cert);
    1047     if (ret > 0)
     1116                               apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION",
     1117                                           NULL), apr_psprintf(r->pool,
     1118                                                               "%u", ret));
     1119
    10481120        apr_table_setn(env,
    1049                        apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", NULL),
    1050                        apr_psprintf(r->pool, "%u", ret));
    1051 
    1052     apr_table_setn(env,
    1053        apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL), "OPENPGP");
    1054 
    1055     tmp =
    1056         mgs_time2sz(gnutls_openpgp_crt_get_expiration_time
    1057                     (cert), buf, sizeof(buf));
    1058     apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL),
    1059                    apr_pstrdup(r->pool, tmp));
    1060 
    1061     tmp =
    1062         mgs_time2sz(gnutls_openpgp_crt_get_creation_time
    1063                     (cert), buf, sizeof(buf));
    1064     apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL),
    1065                    apr_pstrdup(r->pool, tmp));
    1066 
    1067     ret = gnutls_openpgp_crt_get_pk_algorithm(cert, NULL);
    1068     if (ret >= 0) {
    1069         apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL),
    1070                        gnutls_pk_algorithm_get_name(ret));
    1071     }
     1121                       apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL),
     1122                       "OPENPGP");
     1123
     1124        tmp =
     1125            mgs_time2sz(gnutls_openpgp_crt_get_expiration_time
     1126                        (cert), buf, sizeof(buf));
     1127        apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL),
     1128                       apr_pstrdup(r->pool, tmp));
     1129
     1130        tmp =
     1131            mgs_time2sz(gnutls_openpgp_crt_get_creation_time
     1132                        (cert), buf, sizeof(buf));
     1133        apr_table_setn(env,
     1134                       apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL),
     1135                       apr_pstrdup(r->pool, tmp));
     1136
     1137        ret = gnutls_openpgp_crt_get_pk_algorithm(cert, NULL);
     1138        if (ret >= 0) {
     1139                apr_table_setn(env,
     1140                               apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY",
     1141                                          NULL),
     1142                               gnutls_pk_algorithm_get_name(ret));
     1143        }
    10721144
    10731145}
     
    10761148static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt)
    10771149{
    1078     const gnutls_datum_t *cert_list;
    1079     unsigned int cert_list_size, status;
    1080     int rv = GNUTLS_E_NO_CERTIFICATE_FOUND, ret;
    1081     unsigned int ch_size = 0;
    1082     union {
    1083       gnutls_x509_crt_t x509[MAX_CHAIN_SIZE];
    1084       gnutls_openpgp_crt_t pgp;
    1085     } cert;
    1086     apr_time_t expiration_time, cur_time;
    1087 
    1088     if (r == NULL || ctxt == NULL || ctxt->session == NULL)
    1089         return HTTP_FORBIDDEN;
    1090 
    1091     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    1092     cert_list =
    1093         gnutls_certificate_get_peers(ctxt->session, &cert_list_size);
    1094 
    1095     if (cert_list == NULL || cert_list_size == 0) {
    1096         /* It is perfectly OK for a client not to send a certificate if on REQUEST mode
     1150        const gnutls_datum_t *cert_list;
     1151        unsigned int cert_list_size, status;
     1152        int rv = GNUTLS_E_NO_CERTIFICATE_FOUND, ret;
     1153        unsigned int ch_size = 0;
     1154        union {
     1155                gnutls_x509_crt_t x509[MAX_CHAIN_SIZE];
     1156                gnutls_openpgp_crt_t pgp;
     1157        } cert;
     1158        apr_time_t expiration_time, cur_time;
     1159
     1160        if (r == NULL || ctxt == NULL || ctxt->session == NULL)
     1161                return HTTP_FORBIDDEN;
     1162
     1163        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     1164        cert_list =
     1165            gnutls_certificate_get_peers(ctxt->session, &cert_list_size);
     1166
     1167        if (cert_list == NULL || cert_list_size == 0) {
     1168                /* It is perfectly OK for a client not to send a certificate if on REQUEST mode
     1169                 */
     1170                if (ctxt->sc->client_verify_mode == GNUTLS_CERT_REQUEST)
     1171                        return OK;
     1172
     1173                /* no certificate provided by the client, but one was required. */
     1174                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1175                              "GnuTLS: Failed to Verify Peer: "
     1176                              "Client did not submit a certificate");
     1177                return HTTP_FORBIDDEN;
     1178        }
     1179
     1180        if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) {
     1181                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     1182                              "GnuTLS: A Chain of %d certificate(s) was provided for validation",
     1183                              cert_list_size);
     1184
     1185                for (ch_size = 0; ch_size < cert_list_size; ch_size++) {
     1186                        gnutls_x509_crt_init(&cert.x509[ch_size]);
     1187                        rv = gnutls_x509_crt_import(cert.x509[ch_size],
     1188                                                    &cert_list[ch_size],
     1189                                                    GNUTLS_X509_FMT_DER);
     1190                        // When failure to import, leave the loop
     1191                        if (rv != GNUTLS_E_SUCCESS) {
     1192                                if (ch_size < 1) {
     1193                                        ap_log_rerror(APLOG_MARK,
     1194                                                      APLOG_INFO, 0, r,
     1195                                                      "GnuTLS: Failed to Verify Peer: "
     1196                                                      "Failed to import peer certificates.");
     1197                                        ret = HTTP_FORBIDDEN;
     1198                                        goto exit;
     1199                                }
     1200                                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1201                                              "GnuTLS: Failed to import some peer certificates. Using %d certificates",
     1202                                              ch_size);
     1203                                rv = GNUTLS_E_SUCCESS;
     1204                                break;
     1205                        }
     1206                }
     1207        } else if (gnutls_certificate_type_get(ctxt->session) ==
     1208                   GNUTLS_CRT_OPENPGP) {
     1209                if (cert_list_size > 1) {
     1210                        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1211                                      "GnuTLS: Failed to Verify Peer: "
     1212                                      "Chained Client Certificates are not supported.");
     1213                        return HTTP_FORBIDDEN;
     1214                }
     1215
     1216                gnutls_openpgp_crt_init(&cert.pgp);
     1217                rv = gnutls_openpgp_crt_import(cert.pgp, &cert_list[0],
     1218                                               GNUTLS_OPENPGP_FMT_RAW);
     1219
     1220        } else
     1221                return HTTP_FORBIDDEN;
     1222
     1223        if (rv < 0) {
     1224                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1225                              "GnuTLS: Failed to Verify Peer: "
     1226                              "Failed to import peer certificates.");
     1227                ret = HTTP_FORBIDDEN;
     1228                goto exit;
     1229        }
     1230
     1231        if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) {
     1232                apr_time_ansi_put(&expiration_time,
     1233                                  gnutls_x509_crt_get_expiration_time
     1234                                  (cert.x509[0]));
     1235
     1236                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     1237                              "GnuTLS: Verifying list of  %d certificate(s)",
     1238                              ch_size);
     1239                rv = gnutls_x509_crt_list_verify(cert.x509, ch_size,
     1240                                                 ctxt->sc->ca_list,
     1241                                                 ctxt->sc->ca_list_size,
     1242                                                 NULL, 0, 0, &status);
     1243        } else {
     1244                apr_time_ansi_put(&expiration_time,
     1245                                  gnutls_openpgp_crt_get_expiration_time
     1246                                  (cert.pgp));
     1247
     1248                rv = gnutls_openpgp_crt_verify_ring(cert.pgp,
     1249                                                    ctxt->sc->pgp_list, 0,
     1250                                                    &status);
     1251        }
     1252
     1253        if (rv < 0) {
     1254                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1255                              "GnuTLS: Failed to Verify Peer certificate: (%d) %s",
     1256                              rv, gnutls_strerror(rv));
     1257                if (rv == GNUTLS_E_NO_CERTIFICATE_FOUND)
     1258                        ap_log_rerror(APLOG_MARK, APLOG_EMERG, 0, r,
     1259                                      "GnuTLS: No certificate was found for verification. Did you set the GnuTLSX509CAFile or GnuTLSPGPKeyringFile directives?");
     1260                ret = HTTP_FORBIDDEN;
     1261                goto exit;
     1262        }
     1263
     1264        /* TODO: X509 CRL Verification. */
     1265        /* May add later if anyone needs it.
    10971266         */
    1098         if (ctxt->sc->client_verify_mode == GNUTLS_CERT_REQUEST)
    1099             return OK;
    1100 
    1101         /* no certificate provided by the client, but one was required. */
    1102         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1103                       "GnuTLS: Failed to Verify Peer: "
    1104                       "Client did not submit a certificate");
    1105         return HTTP_FORBIDDEN;
    1106     }
    1107 
    1108     if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) {
    1109         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
    1110             "GnuTLS: A Chain of %d certificate(s) was provided for validation", cert_list_size);
    1111 
    1112         for (ch_size = 0; ch_size<cert_list_size; ch_size++) {
    1113             gnutls_x509_crt_init(&cert.x509[ch_size]);
    1114             rv = gnutls_x509_crt_import(cert.x509[ch_size], &cert_list[ch_size], GNUTLS_X509_FMT_DER);
    1115             // When failure to import, leave the loop
    1116             if ( rv != GNUTLS_E_SUCCESS ) {
    1117                 if (ch_size < 1) {
    1118                     ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1119                             "GnuTLS: Failed to Verify Peer: "
    1120                             "Failed to import peer certificates.");
    1121                     ret = HTTP_FORBIDDEN;
    1122                     goto exit;
    1123                 }
    1124                 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1125                         "GnuTLS: Failed to import some peer certificates. Using %d certificates",
    1126                         ch_size);
    1127                 rv = GNUTLS_E_SUCCESS;
    1128                 break;
    1129             }
    1130         }
    1131     } else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) {
    1132         if (cert_list_size > 1) {
    1133             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1134                       "GnuTLS: Failed to Verify Peer: "
    1135                       "Chained Client Certificates are not supported.");
    1136             return HTTP_FORBIDDEN;
    1137         }
    1138 
    1139         gnutls_openpgp_crt_init(&cert.pgp);
    1140         rv = gnutls_openpgp_crt_import(cert.pgp, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW);
    1141 
    1142     } else return HTTP_FORBIDDEN;
    1143  
    1144     if (rv < 0) {
    1145        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1146                       "GnuTLS: Failed to Verify Peer: "
    1147                       "Failed to import peer certificates.");
    1148        ret = HTTP_FORBIDDEN;
    1149        goto exit;
    1150     }
    1151 
    1152     if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) {
    1153         apr_time_ansi_put(&expiration_time,
    1154                       gnutls_x509_crt_get_expiration_time(cert.x509[0]));
    1155 
    1156         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
    1157             "GnuTLS: Verifying list of  %d certificate(s)", ch_size);
    1158         rv = gnutls_x509_crt_list_verify(cert.x509, ch_size,
    1159                 ctxt->sc->ca_list, ctxt->sc->ca_list_size,
    1160                 NULL, 0, 0, &status);
    1161     } else {
    1162         apr_time_ansi_put(&expiration_time,
    1163                       gnutls_openpgp_crt_get_expiration_time(cert.pgp));
    1164 
    1165         rv = gnutls_openpgp_crt_verify_ring(cert.pgp, ctxt->sc->pgp_list,
    1166                       0, &status);
    1167     }
    1168 
    1169     if (rv < 0) {
    1170         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1171                       "GnuTLS: Failed to Verify Peer certificate: (%d) %s",
    1172                       rv, gnutls_strerror(rv));
    1173         if (rv == GNUTLS_E_NO_CERTIFICATE_FOUND)
    1174             ap_log_rerror(APLOG_MARK, APLOG_EMERG, 0, r,
    1175                       "GnuTLS: No certificate was found for verification. Did you set the GnuTLSX509CAFile or GnuTLSPGPKeyringFile directives?");
    1176         ret = HTTP_FORBIDDEN;
    1177         goto exit;
    1178     }
    1179 
    1180     /* TODO: X509 CRL Verification. */
    1181     /* May add later if anyone needs it.
    1182      */
    1183     /* ret = gnutls_x509_crt_check_revocation(crt, crl_list, crl_list_size); */
    1184 
    1185     cur_time = apr_time_now();
    1186 
    1187     if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
    1188         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1189                       "GnuTLS: Could not find Signer for Peer Certificate");
    1190     }
    1191 
    1192     if (status & GNUTLS_CERT_SIGNER_NOT_CA) {
    1193         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1194                       "GnuTLS: Peer's Certificate signer is not a CA");
    1195     }
    1196 
    1197     if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {
    1198         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1199                       "GnuTLS: Peer's Certificate is using insecure algorithms");
    1200     }
    1201 
    1202     if (status & GNUTLS_CERT_EXPIRED || status & GNUTLS_CERT_NOT_ACTIVATED) {
    1203         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1204                       "GnuTLS: Peer's Certificate signer is expired or not yet activated");
    1205     }
    1206 
    1207     if (status & GNUTLS_CERT_INVALID) {
    1208         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1209                       "GnuTLS: Peer Certificate is invalid.");
    1210     } else if (status & GNUTLS_CERT_REVOKED) {
    1211         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    1212                       "GnuTLS: Peer Certificate is revoked.");
    1213     }
    1214 
    1215     if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509)
    1216         mgs_add_common_cert_vars(r, cert.x509[0], 1,
    1217                              ctxt->sc->export_certificates_enabled);
    1218     else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP)
    1219         mgs_add_common_pgpcert_vars(r, cert.pgp, 1,
    1220                              ctxt->sc->export_certificates_enabled);
    1221 
    1222     {
    1223         /* days remaining */
    1224         unsigned long remain =
    1225             (apr_time_sec(expiration_time) -
    1226              apr_time_sec(cur_time)) / 86400;
    1227         apr_table_setn(r->subprocess_env, "SSL_CLIENT_V_REMAIN",
    1228                        apr_psprintf(r->pool, "%lu", remain));
    1229     }
    1230 
    1231     if (status == 0) {
    1232         apr_table_setn(r->subprocess_env, "SSL_CLIENT_VERIFY", "SUCCESS");
    1233         ret = OK;
    1234     } else {
    1235         apr_table_setn(r->subprocess_env, "SSL_CLIENT_VERIFY", "FAILED");
    1236         if (ctxt->sc->client_verify_mode == GNUTLS_CERT_REQUEST)
    1237             ret = OK;
    1238         else
    1239             ret = HTTP_FORBIDDEN;
    1240     }
    1241 
    1242   exit:
    1243     if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) {
    1244         int i;
    1245         for (i=0; i<ch_size; i++) {
    1246             gnutls_x509_crt_deinit(cert.x509[i]);
    1247         }
    1248     } else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP)
    1249         gnutls_openpgp_crt_deinit(cert.pgp);
    1250     return ret;
    1251 
    1252 
    1253 }
     1267        /* ret = gnutls_x509_crt_check_revocation(crt, crl_list, crl_list_size); */
     1268
     1269        cur_time = apr_time_now();
     1270
     1271        if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
     1272                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1273                              "GnuTLS: Could not find Signer for Peer Certificate");
     1274        }
     1275
     1276        if (status & GNUTLS_CERT_SIGNER_NOT_CA) {
     1277                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1278                              "GnuTLS: Peer's Certificate signer is not a CA");
     1279        }
     1280
     1281        if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {
     1282                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1283                              "GnuTLS: Peer's Certificate is using insecure algorithms");
     1284        }
     1285
     1286        if (status & GNUTLS_CERT_EXPIRED
     1287            || status & GNUTLS_CERT_NOT_ACTIVATED) {
     1288                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1289                              "GnuTLS: Peer's Certificate signer is expired or not yet activated");
     1290        }
     1291
     1292        if (status & GNUTLS_CERT_INVALID) {
     1293                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1294                              "GnuTLS: Peer Certificate is invalid.");
     1295        } else if (status & GNUTLS_CERT_REVOKED) {
     1296                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1297                              "GnuTLS: Peer Certificate is revoked.");
     1298        }
     1299
     1300        if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509)
     1301                mgs_add_common_cert_vars(r, cert.x509[0], 1,
     1302                                         ctxt->
     1303                                         sc->export_certificates_enabled);
     1304        else if (gnutls_certificate_type_get(ctxt->session) ==
     1305                 GNUTLS_CRT_OPENPGP)
     1306                mgs_add_common_pgpcert_vars(r, cert.pgp, 1,
     1307                                            ctxt->
     1308                                            sc->export_certificates_enabled);
     1309
     1310        {
     1311                /* days remaining */
     1312                unsigned long remain =
     1313                    (apr_time_sec(expiration_time) -
     1314                     apr_time_sec(cur_time)) / 86400;
     1315                apr_table_setn(r->subprocess_env, "SSL_CLIENT_V_REMAIN",
     1316                               apr_psprintf(r->pool, "%lu", remain));
     1317        }
     1318
     1319        if (status == 0) {
     1320                apr_table_setn(r->subprocess_env, "SSL_CLIENT_VERIFY",
     1321                               "SUCCESS");
     1322                ret = OK;
     1323        } else {
     1324                apr_table_setn(r->subprocess_env, "SSL_CLIENT_VERIFY",
     1325                               "FAILED");
     1326                if (ctxt->sc->client_verify_mode == GNUTLS_CERT_REQUEST)
     1327                        ret = OK;
     1328                else
     1329                        ret = HTTP_FORBIDDEN;
     1330        }
     1331
     1332      exit:
     1333        if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) {
     1334                int i;
     1335                for (i = 0; i < ch_size; i++) {
     1336                        gnutls_x509_crt_deinit(cert.x509[i]);
     1337                }
     1338        } else if (gnutls_certificate_type_get(ctxt->session) ==
     1339                   GNUTLS_CRT_OPENPGP)
     1340                gnutls_openpgp_crt_deinit(cert.pgp);
     1341        return ret;
     1342
     1343
     1344}
Note: See TracChangeset for help on using the changeset viewer.