Changeset 3b4c0d0 in mod_gnutls for src/gnutls_hooks.c


Ignore:
Timestamp:
Dec 20, 2012, 11:29:16 PM (7 years ago)
Author:
Dash Shendy <neuromancer@…>
Branches:
debian/master, debian/stretch-backports, jessie-backports, master, msva, upstream
Children:
8780e34
Parents:
8c03808
Message:
  • Added Comments to Header Structures
  • Refactored the following:

mod_gnutls.h.in:

  • struct mgs_srvconf_rec{}

gnutls_config.c:

  • mgs_set_cert_file()
  • mgs_set_key_file()
  • mgs_set_priorities()
  • mgs_config_server_create()

gnutls_hooks.c

  • mgs_hook_pre_config()
  • mgs_select_virtual_server_cb()
  • cert_retrieve_fn()
  • read_crt_cn()
  • mgs_hook_post_config()
  • mgs_find_sni_server()
  • mgs_add_common_cert_vars()
  • mgs_add_common_pgpcert_vars()

Signed-off-by: Dash Shendy <neuromancer@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/gnutls_hooks.c

    r8c03808 r3b4c0d0  
    3535static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt);
    3636/* use side==0 for server and side==1 for client */
    37 static void mgs_add_common_cert_vars(request_rec * r,
    38         gnutls_x509_crt_t cert, int side,
    39         int export_certificates_enabled);
    40 static void mgs_add_common_pgpcert_vars(request_rec * r,
    41         gnutls_openpgp_crt_t cert,
    42         int side,
    43         int export_certificates_enabled);
    44 
     37static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side);
     38static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side);
     39
     40/* Pool Cleanup Function */
    4541apr_status_t mgs_cleanup_pre_config(void *data) {
     42        /* Free all session data */
    4643    gnutls_free(session_ticket_key.data);
    4744    session_ticket_key.data = NULL;
    4845    session_ticket_key.size = 0;
     46        /* Deinitialize GnuTLS Library */
    4947    gnutls_global_deinit();
    5048    return APR_SUCCESS;
    5149}
    5250
     51/* Logging Function for Maintainers */
    5352#if MOD_GNUTLS_DEBUG
    5453static void gnutls_debug_log_all(int level, const char *str) {
     
    6059#endif
    6160
    62 int mgs_hook_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
    63          apr_pool_t * ptemp) {
     61/* Pre-Configuration HOOK: Runs First */
     62int mgs_hook_pre_config(apr_pool_t * pconf, apr_pool_t * plog, apr_pool_t * ptemp) {
     63
     64/* Maintainer Logging */
    6465#if MOD_GNUTLS_DEBUG
    65     apr_file_open(&debug_log_fp, "/tmp/gnutls_debug",
    66             APR_APPEND | APR_WRITE | APR_CREATE, APR_OS_DEFAULT,
    67             pconf);
    68 
     66    apr_file_open(&debug_log_fp, "/tmp/gnutls_debug", APR_APPEND | APR_WRITE | APR_CREATE, APR_OS_DEFAULT, pconf);
    6967    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    7068    gnutls_global_set_log_level(9);
     
    7270    _gnutls_log(debug_log_fp, "gnutls: %s\n", gnutls_check_version(NULL));
    7371#endif   
     72
    7473    int ret;
    75 
    76     if (gnutls_check_version(LIBGNUTLS_VERSION) == NULL) {
    77         _gnutls_log(debug_log_fp,
    78                 "gnutls_check_version() failed. Required: gnutls-%s Found: gnutls-%s\n",
    79                 LIBGNUTLS_VERSION, gnutls_check_version(NULL));
    80         return DECLINED;
    81     }
    82 
     74        const char * req_GnuTLSVer = "2.12.0";
     75
     76        /* Check for required GnuTLS Library Version */
     77    if (gnutls_check_version(req_GnuTLSVer) == NULL) {
     78                ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, plog, "gnutls_check_version() failed. Required: "
     79                                        "gnutls-%s Found: gnutls-%s\n", LIBGNUTLS_VERSION, gnutls_check_version(NULL));
     80                exit(-1);
     81    }
     82
     83        /* Initialize GnuTLS Library */
    8384    ret = gnutls_global_init();
    8485    if (ret < 0) {
    85         _gnutls_log(debug_log_fp, "gnutls_global_init: %s\n",
    86                 gnutls_strerror(ret));
    87         return DECLINED;
    88     }
    89 
     86                ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, plog, "gnutls_global_init: %s\n", gnutls_strerror(ret));
     87                exit(-1);
     88    }
     89
     90        /* Generate a Session Key */
    9091    ret = gnutls_session_ticket_key_generate(&session_ticket_key);
    9192    if (ret < 0) {
    92         _gnutls_log(debug_log_fp,
    93                 "gnutls_session_ticket_key_generate: %s\n",
    94                 gnutls_strerror(ret));
    95     }
    96 
    97     apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config,
    98             apr_pool_cleanup_null);
    99 
     93                ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, plog, "gnutls_session_ticket_key_generate: %s\n", gnutls_strerror(ret));
     94                exit(-1);
     95    }
     96
     97        /* Register a pool clean-up function */
     98    apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config, apr_pool_cleanup_null);\
    10099
    101100    return OK;
     
    103102
    104103static int mgs_select_virtual_server_cb(gnutls_session_t session) {
    105     mgs_handle_t *ctxt;
    106     mgs_srvconf_rec *tsc;
     104
     105    mgs_handle_t *ctxt = NULL;
     106    mgs_srvconf_rec *tsc = NULL;
    107107    int ret = 0;
    108108
     
    114114    tsc = mgs_find_sni_server(session);
    115115
    116     if (tsc != NULL)
     116    if (tsc == NULL) {
     117        // No TLS vhost configured!
     118                return GNUTLS_E_NO_CERTIFICATE_FOUND;
     119        } else {
     120        // Found a TLS vhost
    117121        ctxt->sc = tsc;
    118 
    119     gnutls_certificate_server_set_request(session,
    120             ctxt->
    121             sc->client_verify_mode);
    122 
    123     /* set the new server credentials
    124      */
    125 
    126     gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
    127             ctxt->sc->certs);
    128 
    129     gnutls_credentials_set(session, GNUTLS_CRD_ANON,
    130             ctxt->sc->anon_creds);
     122        }
     123
     124    gnutls_certificate_server_set_request(session, ctxt->sc->client_verify_mode);
     125
     126    /* Set Anon credentials */
     127    gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs);
     128        /* Set x509 credentials */
     129    gnutls_credentials_set(session, GNUTLS_CRD_ANON, ctxt->sc->anon_creds);
    131130
    132131#ifdef ENABLE_SRP
    133     if (ctxt->sc->srp_tpasswd_conf_file != NULL
    134             && ctxt->sc->srp_tpasswd_file != NULL) {
    135         gnutls_credentials_set(session, GNUTLS_CRD_SRP,
    136                 ctxt->sc->srp_creds);
     132        /* Set SRP credentials */
     133    if (ctxt->sc->srp_tpasswd_conf_file != NULL && ctxt->sc->srp_tpasswd_file != NULL) {
     134        gnutls_credentials_set(session, GNUTLS_CRD_SRP, ctxt->sc->srp_creds);
    137135    }
    138136#endif
     
    142140     * negotiation.
    143141     */
    144     ret = gnutls_priority_set(session, ctxt->sc->priorities);
     142
     143        ret = gnutls_priority_set_direct(session, "NORMAL", NULL);
     144    //ret = gnutls_priority_set(session, ctxt->sc->priorities);
    145145    /* actually it shouldn't fail since we have checked at startup */
    146146    return ret;
    147 }
    148 
    149 static int cert_retrieve_fn(gnutls_session_t session,
    150         const gnutls_datum_t * req_ca_rdn, int nreqs,
    151         const gnutls_pk_algorithm_t * pk_algos, int pk_algos_length,
    152         gnutls_retr2_st *ret) {
     147
     148}
     149
     150static int cert_retrieve_fn(gnutls_session_t session,
     151                                                        const gnutls_datum_t * req_ca_rdn, int nreqs,
     152                                                        const gnutls_pk_algorithm_t * pk_algos, int pk_algos_length,
     153                                                        gnutls_retr2_st *ret) {
    153154   
    154     mgs_handle_t *ctxt;
    155 
    156     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    157     ctxt = gnutls_transport_get_ptr(session);
    158 
    159     if (ctxt == NULL)
    160         return GNUTLS_E_INTERNAL_ERROR;
    161 
    162     if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) {
    163         ret->cert_type = GNUTLS_CRT_X509;
    164         ret->key_type = GNUTLS_PRIVKEY_X509;
    165         ret->ncerts = ctxt->sc->certs_x509_num;
     155   
     156        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     157
     158        mgs_handle_t *ctxt = gnutls_transport_get_ptr(session);
     159
     160    if (session == NULL) {
     161                // ERROR INVALID SESSION
     162                ret->ncerts = 0;
     163                ret->deinit_all = 1;
     164        return -1;
     165        } else if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) {
     166                // X509 CERTIFICATE
     167                ret->cert_type = GNUTLS_CRT_X509;
     168                ret->key_type = GNUTLS_PRIVKEY_X509;
     169        ret->ncerts = ctxt->sc->certs_x509_chain_num;
    166170        ret->deinit_all = 0;
    167 
    168         ret->cert.x509 = ctxt->sc->certs_x509;
     171        ret->cert.x509 = ctxt->sc->certs_x509_chain;
    169172        ret->key.x509 = ctxt->sc->privkey_x509;
    170 
    171173        return 0;
    172174    } else if (gnutls_certificate_type_get(session) == GNUTLS_CRT_OPENPGP) {
    173         ret->cert_type = GNUTLS_CRT_OPENPGP;
    174         ret->key_type = GNUTLS_PRIVKEY_OPENPGP;       
     175                // OPENPGP CERTIFICATE
     176                ret->cert_type = GNUTLS_CRT_OPENPGP;
     177                ret->key_type = GNUTLS_PRIVKEY_OPENPGP;       
    175178        ret->ncerts = 1;
    176179        ret->deinit_all = 0;
    177 
    178180        ret->cert.pgp = ctxt->sc->cert_pgp;
    179181        ret->key.pgp = ctxt->sc->privkey_pgp;
    180 
    181182        return 0;
    182 
    183     }
    184 
    185     return GNUTLS_E_INTERNAL_ERROR;
     183    } else {
     184                // UNKNOWN CERTIFICATE
     185                ret->ncerts = 0;
     186                ret->deinit_all = 1;
     187            return -1;
     188        }
    186189}
    187190
     
    201204 * Returns negative on error.
    202205 */
    203 static int read_crt_cn(server_rec * s, apr_pool_t * p,
    204         gnutls_x509_crt_t cert, char **cert_cn) {
     206static int read_crt_cn(server_rec * s, apr_pool_t * p, gnutls_x509_crt_t cert, char **cert_cn) {
     207
    205208    int rv = 0, i;
    206209    size_t data_len;
     
    211214
    212215    data_len = 0;
    213     rv = gnutls_x509_crt_get_dn_by_oid(cert,
    214             GNUTLS_OID_X520_COMMON_NAME,
    215             0, 0, NULL, &data_len);
     216    rv = gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, NULL, &data_len);
    216217
    217218    if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) {
     
    279280}
    280281
    281 int
    282 mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
    283         apr_pool_t * ptemp, server_rec * base_server) {
     282int mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, server_rec * base_server) {
     283
    284284    int rv;
    285285    server_rec *s;
     
    292292
    293293    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    294     apr_pool_userdata_get(&data, userdata_key,
    295             base_server->process->pool);
     294
     295    apr_pool_userdata_get(&data, userdata_key, base_server->process->pool);
    296296    if (data == NULL) {
    297297        first_run = 1;
    298         apr_pool_userdata_set((const void *) 1, userdata_key,
    299                 apr_pool_cleanup_null,
    300                 base_server->process->pool);
     298        apr_pool_userdata_set((const void *) 1, userdata_key, apr_pool_cleanup_null, base_server->process->pool);
    301299    }
    302300
    303301
    304302    s = base_server;
    305     sc_base =
    306             (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    307             &gnutls_module);
     303    sc_base = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
    308304
    309305    gnutls_dh_params_init(&dh_params);
     
    314310            sizeof(static_dh_params)
    315311        };
    316         rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata,
    317                 GNUTLS_X509_FMT_PEM);       
     312        rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, GNUTLS_X509_FMT_PEM);       
    318313        /* Generate DH Params
    319314        int dh_bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH,
     
    348343
    349344    for (s = base_server; s; s = s->next) {
    350         sc = (mgs_srvconf_rec *)
    351                 ap_get_module_config(s->module_config, &gnutls_module);
     345        sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
    352346        sc->cache_type = sc_base->cache_type;
    353347        sc->cache_config = sc_base->cache_config;
     
    361355        }
    362356
    363         /* Check if DH or RSA params have been set per host */
    364         if (sc->rsa_params != NULL) {
    365             gnutls_certificate_set_rsa_export_params(sc->certs, sc->rsa_params);       
    366         }
    367         /* else not an error but RSA-EXPORT ciphersuites are not available */
    368 
     357        /* Check if DH params have been set per host */
    369358        if (sc->dh_params != NULL) {
    370359            gnutls_certificate_set_dh_params(sc->certs, sc->dh_params);
     
    395384#endif
    396385
    397         if (sc->certs_x509[0] == NULL &&
    398                 sc->cert_pgp == NULL &&
    399                 sc->enabled == GNUTLS_ENABLED_TRUE) {
    400             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    401                     "[GnuTLS] - Host '%s:%d' is missing a "
    402                     "Certificate File!",
    403                     s->server_hostname, s->port);
     386        if (sc->certs_x509_chain == NULL && sc->cert_pgp == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
     387                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     388                                                "[GnuTLS] - Host '%s:%d' is missing a Certificate File!",
     389                                                s->server_hostname, s->port);
    404390            exit(-1);
    405391        }
    406392
    407         if (sc->enabled == GNUTLS_ENABLED_TRUE &&
    408                 ((sc->certs_x509[0] != NULL
    409                 && sc->privkey_x509 == NULL) || (sc->cert_pgp != NULL
    410                 && sc->privkey_pgp
    411                 == NULL))) {
    412             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    413                     "[GnuTLS] - Host '%s:%d' is missing a "
    414                     "Private Key File!",
    415                     s->server_hostname, s->port);
     393        if (sc->enabled == GNUTLS_ENABLED_TRUE && ((sc->certs_x509_chain != NULL && sc->privkey_x509 == NULL) || (sc->cert_pgp != NULL && sc->privkey_pgp == NULL))) {
     394                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     395                                                "[GnuTLS] - Host '%s:%d' is missing a Private Key File!",
     396                                                s->server_hostname, s->port);
    416397            exit(-1);
    417398        }
    418399
    419400        if (sc->enabled == GNUTLS_ENABLED_TRUE) {
    420             rv = read_crt_cn(s, p, sc->certs_x509[0],
    421                     &sc->cert_cn);
    422             if (rv < 0 && sc->cert_pgp != NULL) /* try openpgp certificate */
    423                 rv = read_pgpcrt_cn(s, p, sc->cert_pgp,
    424                     &sc->cert_cn);
     401            rv = read_crt_cn(s, p, sc->certs_x509_chain[sc->certs_x509_chain_num-1], &sc->cert_cn);
     402            if (rv < 0 && sc->cert_pgp != NULL) {
     403                rv = read_pgpcrt_cn(s, p, sc->cert_pgp, &sc->cert_cn);
     404                        }
    425405
    426406            if (rv < 0) {
    427                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0,
    428                         s,
    429                         "[GnuTLS] - Cannot find a certificate for host '%s:%d'!",
    430                         s->server_hostname, s->port);
     407                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     408                                                        "[GnuTLS] - Cannot find a certificate for host '%s:%d'!",
     409                                                        s->server_hostname, s->port);
    431410                sc->cert_cn = NULL;
    432411                continue;
     
    569548        return 0;
    570549    }
     550   
     551        int ret = gnutls_x509_crt_check_hostname(tsc->certs_x509_chain[tsc->certs_x509_chain_num-1], s->server_hostname);
    571552   
    572     return check_server_aliases(x, s, tsc);
     553        return check_server_aliases(x, s, tsc);
    573554}
    574555#endif
     
    662643
    663644    /* Set Default Priority */
    664     gnutls_set_default_priority(ctxt->session);
     645        gnutls_priority_set_direct (ctxt->session, "NORMAL", NULL);
    665646    /* Set Handshake function */
    666647    gnutls_handshake_set_post_client_hello_function(ctxt->session,
     
    771752    apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp));
    772753
    773     if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509)
    774         mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0,
    775             ctxt->
    776             sc->export_certificates_enabled);
    777     else if (gnutls_certificate_type_get(ctxt->session) ==
    778             GNUTLS_CRT_OPENPGP)
    779         mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0,
    780             ctxt->sc->export_certificates_enabled);
     754    if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) {
     755                mgs_add_common_cert_vars(r, ctxt->sc->certs_x509_chain[ctxt->sc->certs_x509_chain_num], 0);
     756        } else if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_OPENPGP) {
     757        mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0);
     758        }
    781759
    782760    return rv;
     
    853831#define MGS_SIDE ((side==0)?"SSL_SERVER":"SSL_CLIENT")
    854832
    855 static void
    856 mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side,
    857         int export_certificates_enabled) {
     833static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side) {
    858834    unsigned char sbuf[64]; /* buffer to hold serials */
    859835    char buf[AP_IOBUFSIZE];
     
    869845
    870846    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    871     if (export_certificates_enabled != 0) {
    872         char cert_buf[10 * 1024];
    873         len = sizeof (cert_buf);
    874 
    875         if (gnutls_x509_crt_export
    876                 (cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0)
    877             apr_table_setn(env,
    878                 apr_pstrcat(r->pool, MGS_SIDE,
    879                 "_CERT", NULL),
    880                 apr_pstrmemdup(r->pool, cert_buf,
    881                 len));
    882 
    883     }
    884847
    885848    len = sizeof (buf);
     
    992955}
    993956
    994 static void
    995 mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert,
    996         int side, int export_certificates_enabled) {
    997     unsigned char sbuf[64]; /* buffer to hold serials */
     957static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side) {
     958
     959        unsigned char sbuf[64]; /* buffer to hold serials */
    998960    char buf[AP_IOBUFSIZE];
    999961    const char *tmp;
     
    1006968    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    1007969    apr_table_t *env = r->subprocess_env;
    1008 
    1009     if (export_certificates_enabled != 0) {
    1010         char cert_buf[10 * 1024];
    1011         len = sizeof (cert_buf);
    1012 
    1013         if (gnutls_openpgp_crt_export
    1014                 (cert, GNUTLS_OPENPGP_FMT_BASE64, cert_buf, &len) >= 0)
    1015             apr_table_setn(env,
    1016                 apr_pstrcat(r->pool, MGS_SIDE,
    1017                 "_CERT", NULL),
    1018                 apr_pstrmemdup(r->pool, cert_buf,
    1019                 len));
    1020 
    1021     }
    1022970
    1023971    len = sizeof (buf);
     
    12211169
    12221170    if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509)
    1223         mgs_add_common_cert_vars(r, cert.x509[0], 1,
    1224             ctxt->
    1225             sc->export_certificates_enabled);
     1171        mgs_add_common_cert_vars(r, cert.x509[0], 1);
    12261172    else if (gnutls_certificate_type_get(ctxt->session) ==
    12271173            GNUTLS_CRT_OPENPGP)
    1228         mgs_add_common_pgpcert_vars(r, cert.pgp, 1,
    1229             ctxt->
    1230             sc->export_certificates_enabled);
     1174        mgs_add_common_pgpcert_vars(r, cert.pgp, 1);
    12311175
    12321176    {
Note: See TracChangeset for help on using the changeset viewer.