Changeset 031acac in mod_gnutls for src/gnutls_hooks.c


Ignore:
Timestamp:
Jul 3, 2014, 1:00:29 PM (5 years ago)
Author:
Nikos Mavrogiannopoulos <nmav@…>
Branches:
debian/master, debian/stretch-backports, jessie-backports, master, upstream
Children:
7314438
Parents:
765cac2
git-author:
Nikos Mavrogiannopoulos <nmav@…> (06/24/14 10:28:03)
git-committer:
Nikos Mavrogiannopoulos <nmav@…> (07/03/14 13:00:29)
Message:

Use the new (3.1.3+) GnuTLS APIs to obtain private keys.

This allows the loading a private key from a PKCS #11 or a TPM URL
(the GnuTLSPIN and GnuTLSSRKPIN variables should be set), and loading
encrypted private keys in PKCS #8, PKCS #12 or openssl format.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/gnutls_hooks.c

    r765cac2 r031acac  
    169169
    170170static int cert_retrieve_fn(gnutls_session_t session,
    171                                                         const gnutls_datum_t * req_ca_rdn, int nreqs,
    172                                                         const gnutls_pk_algorithm_t * pk_algos, int pk_algos_length,
    173                                                         gnutls_retr2_st *ret) {
    174 
    175 
    176         _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    177 
    178         mgs_handle_t *ctxt;
     171                            const gnutls_datum_t * req_ca_rdn, int nreqs,
     172                            const gnutls_pk_algorithm_t * pk_algos, int pk_algos_length,
     173                            gnutls_pcert_st **pcerts, unsigned int *pcert_length,
     174                            gnutls_privkey_t *privkey)
     175{
     176    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     177
     178    mgs_handle_t *ctxt;
    179179
    180180    if (session == NULL) {
    181181                // ERROR INVALID SESSION
    182                 ret->ncerts = 0;
    183                 ret->deinit_all = 1;
    184182        return -1;
    185         }
     183    }
     184
    186185    ctxt = gnutls_transport_get_ptr(session);
    187186
    188187    if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) {
    189188                // X509 CERTIFICATE
    190                 ret->cert_type = GNUTLS_CRT_X509;
    191                 ret->key_type = GNUTLS_PRIVKEY_X509;
    192         ret->ncerts = ctxt->sc->certs_x509_chain_num;
    193         ret->deinit_all = 0;
    194         ret->cert.x509 = ctxt->sc->certs_x509_chain;
    195         ret->key.x509 = ctxt->sc->privkey_x509;
     189        *pcerts = ctxt->sc->certs_x509_chain;
     190        *pcert_length = ctxt->sc->certs_x509_chain_num;
     191        *privkey = ctxt->sc->privkey_x509;
    196192        return 0;
    197193    } else if (gnutls_certificate_type_get(session) == GNUTLS_CRT_OPENPGP) {
    198194                // OPENPGP CERTIFICATE
    199                 ret->cert_type = GNUTLS_CRT_OPENPGP;
    200                 ret->key_type = GNUTLS_PRIVKEY_OPENPGP;
    201         ret->ncerts = 1;
    202         ret->deinit_all = 0;
    203         ret->cert.pgp = ctxt->sc->cert_pgp;
    204         ret->key.pgp = ctxt->sc->privkey_pgp;
     195        *pcerts = ctxt->sc->cert_pgp;
     196        *pcert_length = 1;
     197        *privkey = ctxt->sc->privkey_pgp;
    205198        return 0;
    206199    } else {
    207200                // UNKNOWN CERTIFICATE
    208                 ret->ncerts = 0;
    209                 ret->deinit_all = 1;
    210201            return -1;
    211202        }
    212203}
    213 
    214 /* 2048-bit group parameters from SRP specification */
    215 const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"
    216         "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n"
    217         "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n"
    218         "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n"
    219         "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n"
    220         "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n"
    221         "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n"
    222         "-----END DH PARAMETERS-----\n";
    223204
    224205/* Read the common name or the alternative name of the certificate.
     
    320301    }
    321302
    322 
    323303    s = base_server;
    324304    sc_base = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
    325305
    326     gnutls_dh_params_init(&dh_params);
    327 
    328     if (sc_base->dh_params == NULL) {
    329         gnutls_datum_t pdata = {
    330             (void *) static_dh_params,
    331             sizeof(static_dh_params)
    332         };
    333         rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, GNUTLS_X509_FMT_PEM);
    334         /* Generate DH Params
    335         int dh_bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH,
    336                 GNUTLS_SEC_PARAM_NORMAL);
    337         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    338             "GnuTLS: Generating DH Params of %i bits.  "
    339             "To avoid this use GnuTLSDHFile to specify DH Params for this host",
    340             dh_bits);
    341 #if MOD_GNUTLS_DEBUG
    342             ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
    343                     "GnuTLS: Generated DH Params of %i bits",dh_bits);
    344 #endif
    345         rv = gnutls_dh_params_generate2 (dh_params,dh_bits);
    346         */
    347         if (rv < 0) {
    348             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    349                     "GnuTLS: Unable to generate or load DH Params: (%d) %s",
    350                     rv, gnutls_strerror(rv));
    351             exit(rv);
    352         }
    353     } else {
    354         dh_params = sc_base->dh_params;
    355     }
    356306
    357307    rv = mgs_cache_post_config(p, s, sc_base);
     
    368318        sc->cache_config = sc_base->cache_config;
    369319        sc->cache_timeout = sc_base->cache_timeout;
     320
     321        rv = mgs_load_files(p, s);
     322        if (rv != 0) {
     323            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     324                "GnuTLS: Loading required files failed."
     325                " Shutting Down.");
     326            exit(-1);
     327        }
    370328
    371329        /* defaults for unset values: */
     
    381339            sc->client_verify_method = mgs_cvm_cartel;
    382340
    383 
    384341        /* Check if the priorities have been set */
    385342        if (sc->priorities == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
     
    399356        }
    400357
    401         gnutls_certificate_set_retrieve_function(sc->certs, cert_retrieve_fn);
    402 
    403 #ifdef ENABLE_SRP
    404         if (sc->srp_tpasswd_conf_file != NULL
    405                 && sc->srp_tpasswd_file != NULL) {
    406             rv = gnutls_srp_set_server_credentials_file
    407                     (sc->srp_creds, sc->srp_tpasswd_file,
    408                     sc->srp_tpasswd_conf_file);
    409 
    410             if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) {
    411                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0,
    412                         s,
    413                         "[GnuTLS] - Host '%s:%d' is missing a "
    414                         "SRP password or conf File!",
    415                         s->server_hostname, s->port);
    416                 exit(-1);
    417             }
    418         }
    419 #endif
     358        gnutls_certificate_set_retrieve_function2(sc->certs, cert_retrieve_fn);
    420359
    421360        if ((sc->certs_x509_chain == NULL || sc->certs_x509_chain_num < 1) &&
    422361            sc->cert_pgp == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
    423362                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    424                                                 "[GnuTLS] - Host '%s:%d' is missing a Certificate File!",
     363                                                "GnuTLS: Host '%s:%d' is missing a Certificate File!",
    425364                                                s->server_hostname, s->port);
    426365            exit(-1);
    427366        }
    428 
    429367        if (sc->enabled == GNUTLS_ENABLED_TRUE &&
    430             ((sc->certs_x509_chain != NULL && sc->certs_x509_chain_num > 0 && sc->privkey_x509 == NULL) ||
    431              (sc->cert_pgp != NULL && sc->privkey_pgp == NULL))) {
     368            ((sc->certs_x509_chain_num > 0 && sc->privkey_x509 == NULL) ||
     369             (sc->cert_crt_pgp[0] != NULL && sc->privkey_pgp == NULL))) {
    432370                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    433                                                 "[GnuTLS] - Host '%s:%d' is missing a Private Key File!",
     371                                                "GnuTLS: Host '%s:%d' is missing a Private Key File!",
    434372                                                s->server_hostname, s->port);
    435373            exit(-1);
     
    439377            rv = -1;
    440378            if (sc->certs_x509_chain_num > 0) {
    441                 rv = read_crt_cn(s, p, sc->certs_x509_chain[0], &sc->cert_cn);
     379                rv = read_crt_cn(s, p, sc->certs_x509_crt_chain[0], &sc->cert_cn);
    442380            }
    443381            if (rv < 0 && sc->cert_pgp != NULL) {
    444                 rv = read_pgpcrt_cn(s, p, sc->cert_pgp, &sc->cert_cn);
     382                rv = read_pgpcrt_cn(s, p, sc->cert_crt_pgp[0], &sc->cert_cn);
    445383                        }
    446384
    447385            if (rv < 0) {
    448386                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    449                                                         "[GnuTLS] - Cannot find a certificate for host '%s:%d'!",
     387                                                        "GnuTLS: Cannot find a certificate for host '%s:%d'!",
    450388                                                        s->server_hostname, s->port);
    451389                sc->cert_cn = NULL;
     
    472410}
    473411
    474 void mgs_hook_child_init(apr_pool_t * p, server_rec * s) {
     412void mgs_hook_child_init(apr_pool_t * p, server_rec *s) {
    475413    apr_status_t rv = APR_SUCCESS;
    476     mgs_srvconf_rec *sc = ap_get_module_config(s->module_config,
    477             &gnutls_module);
    478 
    479     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     414    mgs_srvconf_rec *sc =
     415        (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
     416
     417    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     418    /* if we use PKCS #11 reinitialize it */
     419
     420    if (mgs_pkcs11_reinit(s) < 0) {
     421            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
     422                    "GnuTLS: Failed to reinitialize PKCS #11");
     423            exit(-1);
     424    }
     425
    480426    if (sc->cache_type != mgs_cache_none) {
    481427        rv = mgs_cache_child_init(p, s, sc);
    482428        if (rv != APR_SUCCESS) {
    483429            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
    484                     "[GnuTLS] - Failed to run Cache Init");
     430                    "GnuTLS: Failed to run Cache Init");
    485431        }
    486432    }
     
    603549
    604550    if (tsc->certs_x509_chain_num > 0) {
    605         /* why are we doing this check? */
    606         ret = gnutls_x509_crt_check_hostname(tsc->certs_x509_chain[0], s->server_hostname);
     551        /* this check is there to warn administrator of any missing hostname
     552         * in the certificate. */
     553        ret = gnutls_x509_crt_check_hostname(tsc->certs_x509_crt_chain[0], s->server_hostname);
    607554        if (0 == ret)
    608             ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
    609                          "GnuTLS: Error checking certificate for hostname "
     555            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
     556                         "GnuTLS: the certificate doesn't match requested hostname "
    610557                         "'%s'", s->server_hostname);
    611558    } else {
     
    819766
    820767    if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) {
    821                 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509_chain[0], 0, ctxt->sc->export_certificates_size);
    822         } else if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_OPENPGP) {
    823         mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0, ctxt->sc->export_certificates_size);
    824         }
     768        mgs_add_common_cert_vars(r, ctxt->sc->certs_x509_crt_chain[0], 0, ctxt->sc->export_certificates_size);
     769    } else if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_OPENPGP) {
     770        mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_crt_pgp[0], 0, ctxt->sc->export_certificates_size);
     771    }
    825772
    826773    return rv;
Note: See TracChangeset for help on using the changeset viewer.