Changeset 031acac in mod_gnutls


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.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • README

    r765cac2 r031acac  
    2121-------------
    2222
    23  * GnuTLS          >= 2.12.6 <http://www.gnutls.org/> (3.* preferred)
     23 * GnuTLS          >= 3.1.3 <http://www.gnutls.org/> (3.2.* preferred)
    2424 * Apache HTTPD    >= 2.2 <http://httpd.apache.org/> (2.4.* preferred)
    2525 * autotools & gcc
  • configure.ac

    r765cac2 r031acac  
    2828)
    2929
    30 PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 2.12.6])
     30PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.1.3])
    3131
    3232LIBGNUTLS_VERSION=`pkg-config --modversion gnutls`
  • docs/mod_gnutls_manual.mdwn

    r765cac2 r031acac  
    367367as protection against statistical attacks to ciphertext data in order to
    368368achieve maximum compatibility (some broken mobile clients need this).
     369
     370`GnuTLSPIN`
     371------------------
     372
     373Set the PIN to be used to access encrypted key files or PKCS #11 objects.
     374
     375    GnuTLSPIN XXXXXX
     376
     377Default: *none*\
     378Context: server config, virtual host
     379
     380Takes a string to be used as a PIN for the protected objects in
     381a security module, or as a key to be used to decrypt PKCS #8, PKCS #12,
     382or openssl encrypted keys.
     383
     384`GnuTLSSRKPIN`
     385------------------
     386
     387Set the SRK PIN to be used to unlaccess the TPM.
     388
     389    GnuTLSSRKPIN XXXXXX
     390
     391Default: *none*\
     392Context: server config, virtual host
     393
     394Takes a string to be used as a PIN for the protected objects in
     395the TPM module.
    369396
    370397`GnuTLSExportCertificates`
  • include/mod_gnutls.h.in

    r765cac2 r031acac  
    3434#include <gnutls/extra.h>
    3535#endif
     36#include <gnutls/abstract.h>
    3637#include <gnutls/openpgp.h>
    3738#include <gnutls/x509.h>
     
    104105/* Server Configuration Record */
    105106typedef struct {
     107    /* --- Configuration values --- */
     108        /* Is the module enabled? */
     109    int enabled;
     110        /* Is mod_proxy enabled? */
     111    int proxy_enabled;
     112        /* A Plain HTTP request */
     113    int non_ssl_request;
     114
     115    /* PIN used for PKCS #11 operations */
     116    char *pin;
     117
     118    /* the SRK PIN used in TPM operations */
     119    char *srk_pin;
     120
     121    char *x509_cert_file;
     122    char *x509_key_file;
     123    char *x509_ca_file;
     124
     125    char *pgp_cert_file;
     126    char *pgp_key_file;
     127    char *pgp_ring_file;
     128
     129    char *dh_file;
     130   
     131    char *priorities_str;
     132
     133    const char* srp_tpasswd_file;
     134    const char* srp_tpasswd_conf_file;
     135
     136        /* Cache timeout value */
     137    int cache_timeout;
     138        /* Chose Cache Type */
     139    mgs_cache_e cache_type;
     140    const char* cache_config;
     141
     142        /* GnuTLS uses Session Tickets */
     143    int tickets;
     144
     145    /* --- Things initialized at _child_init --- */
     146
    106147        /* x509 Certificate Structure */
    107148    gnutls_certificate_credentials_t certs;
     
    113154    char* cert_cn;
    114155        /* Current x509 Certificate SAN [Subject Alternate Name]s*/
    115         char* cert_san[MAX_CERT_SAN];
    116         /* A x509 Certificate Chain */
    117     gnutls_x509_crt_t *certs_x509_chain;
    118         /* Current x509 Certificate Private Key */
    119     gnutls_x509_privkey_t privkey_x509;
    120         /* OpenPGP Certificate */
    121     gnutls_openpgp_crt_t cert_pgp;
    122         /* OpenPGP Certificate Private Key */
    123     gnutls_openpgp_privkey_t privkey_pgp;
     156    char* cert_san[MAX_CERT_SAN];
     157        /* An x509 Certificate Chain */
     158    gnutls_pcert_st *certs_x509_chain;
     159    gnutls_x509_crt_t *certs_x509_crt_chain;
    124160        /* Number of Certificates in Chain */
    125161    unsigned int certs_x509_chain_num;
    126         /* Is the module enabled? */
    127     int enabled;
     162
     163        /* Current x509 Certificate Private Key */
     164    gnutls_privkey_t privkey_x509;
     165
     166        /* OpenPGP Certificate */
     167    gnutls_pcert_st *cert_pgp;
     168    gnutls_openpgp_crt_t *cert_crt_pgp;
     169
     170        /* OpenPGP Certificate Private Key */
     171    gnutls_privkey_t privkey_pgp;
     172
    128173    /* Export full certificates to CGI environment: */
    129174    int export_certificates_size;
     
    132177        /* GnuTLS DH Parameters */
    133178    gnutls_dh_params_t dh_params;
    134         /* Cache timeout value */
    135     int cache_timeout;
    136         /* Chose Cache Type */
    137     mgs_cache_e cache_type;
    138     const char* cache_config;
    139     const char* srp_tpasswd_file;
    140     const char* srp_tpasswd_conf_file;
    141179        /* A list of CA Certificates */
    142180    gnutls_x509_crt_t *ca_list;
     
    151189        /* Last Cache timestamp */
    152190    apr_time_t last_cache_check;
    153         /* GnuTLS uses Session Tickets */
    154     int tickets;
    155         /* Is mod_proxy enabled? */
    156     int proxy_enabled;
    157         /* A Plain HTTP request */
    158     int non_ssl_request;
    159191} mgs_srvconf_rec;
    160192
     
    302334
    303335/**
     336 * Perform any reinitialization required in PKCS #11
     337 */
     338int mgs_pkcs11_reinit(server_rec * s);
     339
     340/**
    304341 * Convert a SSL Session ID into a Null Terminated Hex Encoded String
    305342 * @param id raw SSL Session ID
     
    321358
    322359/* Configuration Functions */
     360
     361/* Loads all files set in the configuration */
     362int mgs_load_files(apr_pool_t * p, server_rec * s);
    323363
    324364const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
     
    354394const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
    355395                                   const char *arg);
     396const char *mgs_set_pin(cmd_parms * parms, void *dummy,
     397                                   const char *arg);
     398
     399const char *mgs_set_srk_pin(cmd_parms * parms, void *dummy,
     400                                   const char *arg);
    356401
    357402const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
  • src/gnutls_config.c

    r765cac2 r031acac  
    2020#include "mod_gnutls.h"
    2121#include "apr_lib.h"
     22#include <gnutls/abstract.h>
     23
     24#define INIT_CA_SIZE 128
    2225
    2326#ifdef APLOG_USE_MODULE
     
    2528#endif
    2629
     30static int pin_callback(void *user, int attempt, const char *token_url,
     31                        const char *token_label, unsigned int flags,
     32                        char *pin, size_t pin_max)
     33{
     34    mgs_srvconf_rec *sc = user;
     35
     36    if (sc->pin == NULL || flags & GNUTLS_PIN_FINAL_TRY ||
     37        flags & GNUTLS_PIN_WRONG) {
     38        return -1;
     39    }
     40
     41    if (token_label && strcmp(token_label, "SRK") == 0) {
     42         snprintf(pin, pin_max, "%s", sc->srk_pin);
     43    } else {
     44         snprintf(pin, pin_max, "%s", sc->pin);
     45    }
     46    return 0;
     47}
     48
    2749static int load_datum_from_file(apr_pool_t * pool,
    28         const char *file, gnutls_datum_t * data) {
     50                                const char *file, gnutls_datum_t * data)
     51{
    2952    apr_file_t *fp;
    3053    apr_finfo_t finfo;
     
    3356
    3457    rv = apr_file_open(&fp, file, APR_READ | APR_BINARY,
    35             APR_OS_DEFAULT, pool);
     58                       APR_OS_DEFAULT, pool);
    3659    if (rv != APR_SUCCESS) {
    37         return rv;
     60        return rv;
    3861    }
    3962
     
    4164
    4265    if (rv != APR_SUCCESS) {
    43         return rv;
     66        return rv;
    4467    }
    4568
     
    4871
    4972    if (rv != APR_SUCCESS) {
    50         return rv;
     73        return rv;
    5174    }
    5275    apr_file_close(fp);
     
    5881}
    5982
    60 const char *mgs_set_dh_file(cmd_parms * parms, void *dummy,
    61         const char *arg) {
     83/* 2048-bit group parameters from SRP specification */
     84const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"
     85        "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n"
     86        "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n"
     87        "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n"
     88        "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n"
     89        "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n"
     90        "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n"
     91        "-----END DH PARAMETERS-----\n";
     92
     93int mgs_load_files(apr_pool_t * p, server_rec * s)
     94{
     95    apr_pool_t *spool;
     96    const char *file;
     97    gnutls_datum_t data;
    6298    int ret;
    63     gnutls_datum_t data;
    64     const char *file;
    65     apr_pool_t *spool;
    66     mgs_srvconf_rec *sc =
    67             (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    68             module_config,
    69             &gnutls_module);
    70 
    71     apr_pool_create(&spool, parms->pool);
    72 
    73     file = ap_server_root_relative(spool, arg);
    74 
    75     if (load_datum_from_file(spool, file, &data) != 0) {
    76         return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
    77                 "DH params '%s'", file);
    78     }
    79 
    80     ret = gnutls_dh_params_init(&sc->dh_params);
    81     if (ret < 0) {
    82         return apr_psprintf(parms->pool,
    83                 "GnuTLS: Failed to initialize"
    84                 ": (%d) %s", ret,
    85                 gnutls_strerror(ret));
    86     }
    87 
    88     ret =
    89             gnutls_dh_params_import_pkcs3(sc->dh_params, &data,
    90             GNUTLS_X509_FMT_PEM);
    91     if (ret < 0) {
    92         return apr_psprintf(parms->pool,
    93                 "GnuTLS: Failed to Import "
    94                 "DH params '%s': (%d) %s", file, ret,
    95                 gnutls_strerror(ret));
    96     }
    97 
    98     apr_pool_destroy(spool);
    99 
    100     return NULL;
    101 }
    102 
    103 const char *mgs_set_cert_file(cmd_parms * parms, void *dummy, const char *arg) {
    104 
    105     int ret;
    106     gnutls_datum_t data;
    107     const char *file;
    108     apr_pool_t *spool;
    109 
    110     mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module);
    111     apr_pool_create(&spool, parms->pool);
    112 
    113     file = ap_server_root_relative(spool, arg);
    114 
    115     if (load_datum_from_file(spool, file, &data) != 0) {
    116                 apr_pool_destroy(spool);
    117         return apr_psprintf(parms->pool, "GnuTLS: Error Reading Certificate '%s'", file);
    118     }
    119 
    120     sc->certs_x509_chain_num = MAX_CHAIN_SIZE;
    121     ret = gnutls_x509_crt_list_import(sc->certs_x509_chain, &sc->certs_x509_chain_num, &data, GNUTLS_X509_FMT_PEM, 0);
    122     if (ret < 0) {
    123                 apr_pool_destroy(spool);
    124         return apr_psprintf(parms->pool, "GnuTLS: Failed to Import Certificate '%s': (%d) %s", file, ret, gnutls_strerror(ret));
    125     }
    126 
    127         apr_pool_destroy(spool);
    128     return NULL;
    129 
    130 }
    131 
    132 const char *mgs_set_key_file(cmd_parms * parms, void *dummy, const char *arg) {
    133 
    134     int ret;
    135     gnutls_datum_t data;
    136     const char *file;
    137     apr_pool_t *spool;
    138     const char *out;
    139 
    140         mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module);
    141 
    142         apr_pool_create(&spool, parms->pool);
    143 
    144     file = ap_server_root_relative(spool, arg);
    145 
    146     if (load_datum_from_file(spool, file, &data) != 0) {
    147         out = apr_psprintf(parms->pool, "GnuTLS: Error Reading Private Key '%s'", file);
    148                 apr_pool_destroy(spool);
    149         return out;
    150     }
    151 
    152     ret = gnutls_x509_privkey_init(&sc->privkey_x509);
    153 
    154     if (ret < 0) {
    155                 apr_pool_destroy(spool);
    156         return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize: (%d) %s", ret, gnutls_strerror(ret));
    157     }
    158 
    159     ret = gnutls_x509_privkey_import(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM);
    160 
    161     if (ret < 0) {
    162         ret = gnutls_x509_privkey_import_pkcs8(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM, NULL, GNUTLS_PKCS_PLAIN);
    163         }
    164 
    165     if (ret < 0) {
    166         out = apr_psprintf(parms->pool, "GnuTLS: Failed to Import Private Key '%s': (%d) %s", file, ret, gnutls_strerror(ret));
    167                 apr_pool_destroy(spool);
    168         return out;
    169     }
    170 
    171     apr_pool_destroy(spool);
    172 
    173     return NULL;
    174 }
    175 
    176 const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy,
    177         const char *arg) {
    178     int ret;
    179     gnutls_datum_t data;
    180     const char *file;
    181     apr_pool_t *spool;
    182     mgs_srvconf_rec *sc =
    183             (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    184             module_config,
    185             &gnutls_module);
    186     apr_pool_create(&spool, parms->pool);
    187 
    188     file = ap_server_root_relative(spool, arg);
    189 
    190     if (load_datum_from_file(spool, file, &data) != 0) {
    191         return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
    192                 "Certificate '%s'", file);
    193     }
    194 
    195     ret = gnutls_openpgp_crt_init(&sc->cert_pgp);
    196     if (ret < 0) {
    197         return apr_psprintf(parms->pool, "GnuTLS: Failed to Init "
    198                 "PGP Certificate: (%d) %s", ret,
    199                 gnutls_strerror(ret));
    200     }
    201 
    202     ret =
    203             gnutls_openpgp_crt_import(sc->cert_pgp, &data,
    204             GNUTLS_OPENPGP_FMT_BASE64);
    205     if (ret < 0) {
    206         return apr_psprintf(parms->pool,
    207                 "GnuTLS: Failed to Import "
    208                 "PGP Certificate '%s': (%d) %s", file,
    209                 ret, gnutls_strerror(ret));
    210     }
    211 
    212     apr_pool_destroy(spool);
    213     return NULL;
    214 }
    215 
    216 const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy,
    217         const char *arg) {
    218     int ret;
    219     gnutls_datum_t data;
    220     const char *file;
    221     apr_pool_t *spool;
    222     mgs_srvconf_rec *sc =
    223             (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    224             module_config,
    225             &gnutls_module);
    226     apr_pool_create(&spool, parms->pool);
    227 
    228     file = ap_server_root_relative(spool, arg);
    229 
    230     if (load_datum_from_file(spool, file, &data) != 0) {
    231         return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
    232                 "Private Key '%s'", file);
    233     }
    234 
    235     ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp);
    236     if (ret < 0) {
    237         return apr_psprintf(parms->pool,
    238                 "GnuTLS: Failed to initialize"
    239                 ": (%d) %s", ret,
    240                 gnutls_strerror(ret));
    241     }
    242 
    243     ret =
    244             gnutls_openpgp_privkey_import(sc->privkey_pgp, &data,
    245             GNUTLS_OPENPGP_FMT_BASE64, NULL,
    246             0);
    247     if (ret != 0) {
    248         return apr_psprintf(parms->pool,
    249                 "GnuTLS: Failed to Import "
    250                 "PGP Private Key '%s': (%d) %s", file,
    251                 ret, gnutls_strerror(ret));
    252     }
    253     apr_pool_destroy(spool);
    254     return NULL;
    255 }
    256 
    257 const char *mgs_set_tickets(cmd_parms * parms, void *dummy,
    258         const char *arg) {
    259     mgs_srvconf_rec *sc =
    260             (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    261             module_config,
    262             &gnutls_module);
    263 
    264     sc->tickets = 0;
    265     if (strcasecmp("on", arg) == 0) {
    266         sc->tickets = 1;
    267     }
    268 
    269     return NULL;
    270 }
    271 
    272 
    273 #ifdef ENABLE_SRP
    274 
    275 const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy,
    276         const char *arg) {
    277     mgs_srvconf_rec *sc =
    278             (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    279             module_config,
    280             &gnutls_module);
    281 
    282     sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
    283 
    284     return NULL;
    285 }
    286 
    287 const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
    288         const char *arg) {
    289     mgs_srvconf_rec *sc =
    290             (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    291             module_config,
    292             &gnutls_module);
    293 
    294     sc->srp_tpasswd_conf_file =
    295             ap_server_root_relative(parms->pool, arg);
    296 
    297     return NULL;
    298 }
    299 
    300 #endif
    301 
    302 const char *mgs_set_cache(cmd_parms * parms, void *dummy,
    303         const char *type, const char *arg) {
    304     const char *err;
    305     mgs_srvconf_rec *sc =
    306             ap_get_module_config(parms->server->module_config,
    307             &gnutls_module);
    308     if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
    309         return err;
    310     }
    311 
    312     if (strcasecmp("none", type) == 0) {
    313         sc->cache_type = mgs_cache_none;
    314         sc->cache_config = NULL;
    315         return NULL;
    316     } else if (strcasecmp("dbm", type) == 0) {
    317         sc->cache_type = mgs_cache_dbm;
    318     } else if (strcasecmp("gdbm", type) == 0) {
    319         sc->cache_type = mgs_cache_gdbm;
    320     }
    321 #if HAVE_APR_MEMCACHE
    322     else if (strcasecmp("memcache", type) == 0) {
    323         sc->cache_type = mgs_cache_memcache;
    324     }
    325 #endif
    326     else {
    327         return "Invalid Type for GnuTLSCache!";
    328     }
    329 
    330     if (arg == NULL)
    331         return "Invalid argument 2 for GnuTLSCache!";
    332 
    333     if (sc->cache_type == mgs_cache_dbm
    334             || sc->cache_type == mgs_cache_gdbm) {
    335         sc->cache_config =
    336                 ap_server_root_relative(parms->pool, arg);
    337     } else {
    338         sc->cache_config = apr_pstrdup(parms->pool, arg);
    339     }
    340 
    341     return NULL;
    342 }
    343 
    344 const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
    345         const char *arg) {
    346     int argint;
    347     const char *err;
    348     mgs_srvconf_rec *sc =
    349             (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    350             module_config,
    351             &gnutls_module);
    352 
    353     if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
    354         return err;
    355     }
    356 
    357     argint = atoi(arg);
    358 
    359     if (argint < 0) {
    360         return "GnuTLSCacheTimeout: Invalid argument";
    361     } else if (argint == 0) {
    362         sc->cache_timeout = 0;
    363     } else {
    364         sc->cache_timeout = apr_time_from_sec(argint);
    365     }
    366 
    367     return NULL;
    368 }
    369 
    370 const char *mgs_set_client_verify_method(cmd_parms * parms, void *dummy,
    371         const char *arg) {
    372     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)ap_get_module_config(parms->server->module_config, &gnutls_module);
    373 
    374     if (strcasecmp("cartel", arg) == 0) {
    375         sc->client_verify_method = mgs_cvm_cartel;
    376     } else if (strcasecmp("msva", arg) == 0) {
    377 #ifdef ENABLE_MSVA
    378         sc->client_verify_method = mgs_cvm_msva;
    379 #else
    380         return "GnuTLSClientVerifyMethod: msva is not supported";
    381 #endif
    382     } else {
    383         return "GnuTLSClientVerifyMethod: Invalid argument";
    384     }
    385 
    386     return NULL;
    387 }
    388 
    389 const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
    390         const char *arg) {
    391     int mode;
    392 
    393     if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
    394         mode = GNUTLS_CERT_IGNORE;
    395     } else if (strcasecmp("optional", arg) == 0
    396             || strcasecmp("request", arg) == 0) {
    397         mode = GNUTLS_CERT_REQUEST;
    398     } else if (strcasecmp("require", arg) == 0) {
    399         mode = GNUTLS_CERT_REQUIRE;
    400     } else {
    401         return "GnuTLSClientVerify: Invalid argument";
    402     }
    403 
    404     /* This was set from a directory context */
    405     if (parms->path) {
    406         mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dummy;
    407         dc->client_verify_mode = mode;
    408     } else {
    409         mgs_srvconf_rec *sc =
    410                 (mgs_srvconf_rec *)
    411                 ap_get_module_config(parms->server->module_config,
    412                 &gnutls_module);
    413         sc->client_verify_mode = mode;
    414     }
    415 
    416     return NULL;
    417 }
    418 
    419 #define INIT_CA_SIZE 128
    420 
    421 const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
    422         const char *arg) {
    423     int rv;
    424     const char *file;
    425     apr_pool_t *spool;
    426     gnutls_datum_t data;
    427 
    428     mgs_srvconf_rec *sc =
    429             (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    430             module_config,
    431             &gnutls_module);
    432     apr_pool_create(&spool, parms->pool);
    433 
    434     file = ap_server_root_relative(spool, arg);
    435 
    436     if (load_datum_from_file(spool, file, &data) != 0) {
    437         return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
    438                 "Client CA File '%s'", file);
    439     }
    440 
    441     sc->ca_list_size = INIT_CA_SIZE;
    442     sc->ca_list = malloc(sc->ca_list_size * sizeof (*sc->ca_list));
    443     if (sc->ca_list == NULL) {
    444         return apr_psprintf(parms->pool,
    445                 "mod_gnutls: Memory allocation error");
    446     }
    447 
    448     rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size,
    449             &data, GNUTLS_X509_FMT_PEM,
    450             GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
    451     if (rv < 0 && rv != GNUTLS_E_SHORT_MEMORY_BUFFER) {
    452         return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
    453                 "Client CA File '%s': (%d) %s", file,
    454                 rv, gnutls_strerror(rv));
    455     }
    456 
    457     if (INIT_CA_SIZE < sc->ca_list_size) {
    458         sc->ca_list =
    459                 realloc(sc->ca_list,
    460                 sc->ca_list_size * sizeof (*sc->ca_list));
    461         if (sc->ca_list == NULL) {
    462             return apr_psprintf(parms->pool,
    463                     "mod_gnutls: Memory allocation error");
    464         }
    465 
    466         /* re-read */
    467         rv = gnutls_x509_crt_list_import(sc->ca_list,
    468                 &sc->ca_list_size, &data,
    469                 GNUTLS_X509_FMT_PEM, 0);
    470 
    471         if (rv < 0) {
    472             return apr_psprintf(parms->pool,
    473                     "GnuTLS: Failed to load "
    474                     "Client CA File '%s': (%d) %s",
    475                     file, rv, gnutls_strerror(rv));
    476         }
    477     }
    478 
    479     apr_pool_destroy(spool);
    480     return NULL;
    481 }
    482 
    483 const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
    484         const char *arg) {
    485     int rv;
    486     const char *file;
    487     apr_pool_t *spool;
    488     gnutls_datum_t data;
    489 
    490     mgs_srvconf_rec *sc =
    491             (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    492             module_config,
    493             &gnutls_module);
    494     apr_pool_create(&spool, parms->pool);
    495 
    496     file = ap_server_root_relative(spool, arg);
    497 
    498     if (load_datum_from_file(spool, file, &data) != 0) {
    499         return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
    500                 "Keyring File '%s'", file);
    501     }
    502 
    503     rv = gnutls_openpgp_keyring_init(&sc->pgp_list);
    504     if (rv < 0) {
    505         return apr_psprintf(parms->pool,
    506                 "GnuTLS: Failed to initialize"
    507                 "keyring: (%d) %s", rv,
    508                 gnutls_strerror(rv));
    509     }
    510 
    511     rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data,
    512             GNUTLS_OPENPGP_FMT_BASE64);
    513     if (rv < 0) {
    514         return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
    515                 "Keyring File '%s': (%d) %s", file, rv,
    516                 gnutls_strerror(rv));
    517     }
    518 
    519     apr_pool_destroy(spool);
    520     return NULL;
    521 }
    522 
    523 const char *mgs_set_proxy_engine(cmd_parms * parms, void *dummy,
    524         const char *arg) {
    525 
    526     mgs_srvconf_rec *sc =(mgs_srvconf_rec *)
    527             ap_get_module_config(parms->server->module_config, &gnutls_module);
    528 
    529     if (!strcasecmp(arg, "On")) {
    530         sc->proxy_enabled = GNUTLS_ENABLED_TRUE;
    531     } else if (!strcasecmp(arg, "Off")) {
    532         sc->proxy_enabled = GNUTLS_ENABLED_FALSE;
    533     } else {
    534         return "SSLProxyEngine must be set to 'On' or 'Off'";
    535     }
    536 
    537     return NULL;
    538 }
    539 
    540 const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
    541         const char *arg) {
    542     mgs_srvconf_rec *sc =
    543             (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    544             module_config,
    545             &gnutls_module);
    546     if (!strcasecmp(arg, "On")) {
    547         sc->enabled = GNUTLS_ENABLED_TRUE;
    548     } else if (!strcasecmp(arg, "Off")) {
    549         sc->enabled = GNUTLS_ENABLED_FALSE;
    550     } else {
    551         return "GnuTLSEnable must be set to 'On' or 'Off'";
    552     }
    553 
    554     return NULL;
    555 }
    556 
    557 const char *mgs_set_export_certificates_size(cmd_parms * parms, void *dummy, const char *arg) {
    558     mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module);
    559     if (!strcasecmp(arg, "On")) {
    560         sc->export_certificates_size = 16 * 1024;
    561     } else if (!strcasecmp(arg, "Off")) {
    562         sc->export_certificates_size = 0;
    563     } else {
    564         char* endptr;
    565         sc->export_certificates_size = strtol(arg, &endptr, 10);
    566         while (apr_isspace(*endptr)) endptr++;
    567         if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') {
    568             ;
    569         } else if (*endptr == 'k' || *endptr == 'K') {
    570             sc->export_certificates_size *= 1024;
    571         } else {
    572             return "GnuTLSExportCertificates must be set to a size (in bytes) or 'On' or 'Off'";
    573         }
    574     }
    575 
    576     return NULL;
    577 }
    578 
    579 const char *mgs_set_priorities(cmd_parms * parms, void *dummy, const char *arg) {
    580 
    581         int ret;
    582     const char *err;
    583 
    584     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    585                                                   ap_get_module_config(parms->server->module_config, &gnutls_module);
    586 
    587     ret = gnutls_priority_init(&sc->priorities, arg, &err);
    588 
    589     if (ret < 0) {
    590         if (ret == GNUTLS_E_INVALID_REQUEST) {
    591             return apr_psprintf(parms->pool,
    592                                                                 "GnuTLS: Syntax error parsing priorities string at: %s", err);
    593                 }
    594         return "Error setting priorities";
    595     }
    596 
    597     return NULL;
    598 }
    599 
    600 static mgs_srvconf_rec *_mgs_config_server_create(apr_pool_t * p, char** err) {
    601     mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof (*sc));
    602     int ret;
    603 
    604     sc->enabled = GNUTLS_ENABLED_UNSET;
     99    mgs_srvconf_rec *sc =
     100        (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
     101                                                 &gnutls_module);
     102
     103    apr_pool_create(&spool, p);
     104
     105    sc->cert_pgp = apr_pcalloc(p, sizeof(sc->cert_pgp[0]));
     106    sc->cert_crt_pgp = apr_pcalloc(p, sizeof(sc->cert_crt_pgp[0]));
     107    sc->certs_x509_chain =
     108        apr_pcalloc(p, MAX_CHAIN_SIZE * sizeof(sc->certs_x509_chain[0]));
     109    sc->certs_x509_crt_chain =
     110        apr_pcalloc(p,
     111                    MAX_CHAIN_SIZE * sizeof(sc->certs_x509_crt_chain[0]));
    605112
    606113    ret = gnutls_certificate_allocate_credentials(&sc->certs);
    607114    if (ret < 0) {
    608         *err = apr_psprintf(p, "GnuTLS: Failed to initialize"
    609                             ": (%d) %s", ret,
    610                             gnutls_strerror(ret));
    611         return NULL;
     115        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     116                     "GnuTLS: Failed to initialize" ": (%d) %s", ret,
     117                     gnutls_strerror(ret));
     118        ret = -1;
     119        goto cleanup;
    612120    }
    613121
    614122    ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
    615123    if (ret < 0) {
    616         *err = apr_psprintf(p, "GnuTLS: Failed to initialize"
    617                             ": (%d) %s", ret,
    618                             gnutls_strerror(ret));
    619         return NULL;
    620     }
     124        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     125                     "GnuTLS: Failed to initialize" ": (%d) %s", ret,
     126                     gnutls_strerror(ret));
     127        ret = -1;
     128        goto cleanup;
     129    }
     130
     131    /* Load SRP parameters */
    621132#ifdef ENABLE_SRP
    622133    ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
    623134    if (ret < 0) {
    624         *err =  apr_psprintf(p, "GnuTLS: Failed to initialize"
    625                              ": (%d) %s", ret,
    626                              gnutls_strerror(ret));
    627         return NULL;
    628     }
    629 
    630     sc->srp_tpasswd_conf_file = NULL;
    631     sc->srp_tpasswd_file = NULL;
     135        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     136                     "GnuTLS: Failed to initialize" ": (%d) %s", ret,
     137                     gnutls_strerror(ret));
     138        ret = -1;
     139        goto cleanup;
     140    }
     141
     142    if (sc->srp_tpasswd_conf_file != NULL && sc->srp_tpasswd_file != NULL) {
     143        ret = gnutls_srp_set_server_credentials_file
     144            (sc->srp_creds, sc->srp_tpasswd_file,
     145             sc->srp_tpasswd_conf_file);
     146
     147        if (ret < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) {
     148            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0,
     149                         s,
     150                         "GnuTLS: Host '%s:%d' is missing a "
     151                         "SRP password or conf File!",
     152                         s->server_hostname, s->port);
     153            ret = -1;
     154            goto cleanup;
     155        }
     156    }
    632157#endif
    633158
     159    ret = gnutls_dh_params_init(&sc->dh_params);
     160    if (ret < 0) {
     161            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     162                         "GnuTLS: Failed to initialize"
     163                         ": (%d) %s", ret, gnutls_strerror(ret));
     164            ret = -1;
     165            goto cleanup;
     166    }
     167
     168    /* Load DH parameters */
     169    if (sc->dh_file) {
     170        if (load_datum_from_file(spool, sc->dh_file, &data) != 0) {
     171            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     172                         "GnuTLS: Error Reading " "DH params '%s'", sc->dh_file);
     173            ret = -1;
     174            goto cleanup;
     175        }
     176
     177
     178        ret =
     179            gnutls_dh_params_import_pkcs3(sc->dh_params, &data,
     180                                          GNUTLS_X509_FMT_PEM);
     181        if (ret < 0) {
     182            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     183                         "GnuTLS: Failed to Import "
     184                         "DH params '%s': (%d) %s", sc->dh_file, ret,
     185                         gnutls_strerror(ret));
     186            ret = -1;
     187            goto cleanup;
     188        }
     189    } else {
     190        gnutls_datum_t pdata = {
     191            (void *) static_dh_params,
     192            sizeof(static_dh_params)
     193        };
     194
     195        ret = gnutls_dh_params_import_pkcs3(sc->dh_params, &pdata, GNUTLS_X509_FMT_PEM);
     196        if (ret < 0) {
     197            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     198                    "GnuTLS: Unable to generate or load DH Params: (%d) %s",
     199                    ret, gnutls_strerror(ret));
     200            ret = -1;
     201            goto cleanup;
     202        }
     203    }
     204
     205    if (sc->x509_cert_file != NULL) {
     206        unsigned int chain_num, i;
     207        unsigned format = GNUTLS_X509_FMT_PEM;
     208
     209        /* Load X.509 certificate */
     210        if (strncmp(sc->x509_cert_file, "pkcs11:", 7) == 0) {
     211            gnutls_pkcs11_obj_t obj;
     212
     213            file = sc->x509_cert_file;
     214
     215            ret = gnutls_pkcs11_obj_init(&obj);
     216            if (ret < 0) {
     217                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     218                             "GnuTLS: Error Initializing PKCS #11 object");
     219                ret = -1;
     220                goto cleanup;
     221            }
     222
     223            gnutls_pkcs11_obj_set_pin_function(obj, pin_callback, sc);
     224
     225            ret = gnutls_pkcs11_obj_import_url(obj, file, GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
     226            if (ret < 0) {
     227                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     228                             "GnuTLS: Error Importing PKCS #11 object: '%s': %s",
     229                             file, gnutls_strerror(ret));
     230                ret = -1;
     231                goto cleanup;
     232            }
     233
     234            format = GNUTLS_X509_FMT_DER;
     235            ret = gnutls_pkcs11_obj_export2(obj, &data);
     236            if (ret < 0) {
     237                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     238                             "GnuTLS: Error Exporting a PKCS #11 object: '%s': %s",
     239                             file, gnutls_strerror(ret));
     240                ret = -1;
     241                goto cleanup;
     242            }
     243
     244            gnutls_pkcs11_obj_deinit(obj);
     245        } else {
     246            file = ap_server_root_relative(spool, sc->x509_cert_file);
     247
     248            ret = gnutls_load_file(file, &data);
     249            if (ret < 0) {
     250                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     251                             "GnuTLS: Error Reading Certificate '%s': %s",
     252                             file, gnutls_strerror(ret));
     253                ret = -1;
     254                goto cleanup;
     255            }
     256        }
     257
     258        ret =
     259            gnutls_x509_crt_list_import2(&sc->certs_x509_crt_chain,
     260                                        &chain_num, &data, format,
     261                                        GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
     262        gnutls_free(data.data);
     263        sc->certs_x509_chain_num = chain_num;
     264
     265        if (ret < 0) {
     266            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     267                         "GnuTLS: Failed to Import Certificate Chain '%s': (%d) %s",
     268                         file, ret, gnutls_strerror(ret));
     269            ret = -1;
     270            goto cleanup;
     271        }
     272
     273        for (i = 0; i < chain_num; i++) {
     274            ret =
     275                gnutls_pcert_import_x509(&sc->certs_x509_chain[i],
     276                                         sc->certs_x509_crt_chain[i], 0);
     277            if (ret < 0) {
     278                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     279                             "GnuTLS: Failed to Import pCertificate '%s': (%d) %s",
     280                             file, ret, gnutls_strerror(ret));
     281                ret = -1;
     282                goto cleanup;
     283            }
     284        }
     285        sc->certs_x509_chain_num = chain_num;
     286    }
     287
     288    if (sc->x509_key_file) {
     289        ret = gnutls_privkey_init(&sc->privkey_x509);
     290        if (ret < 0) {
     291            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     292                         "GnuTLS: Failed to initialize: (%d) %s", ret,
     293                         gnutls_strerror(ret));
     294            ret = -1;
     295            goto cleanup;
     296        }
     297
     298        if (gnutls_url_is_supported(sc->x509_key_file) != 0) {
     299            file = sc->x509_key_file;
     300
     301            gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback,
     302                                            sc);
     303
     304            ret = gnutls_privkey_import_url(sc->privkey_x509, file, 0);
     305
     306            if (ret < 0) {
     307                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     308                             "GnuTLS: Failed to Import Private Key URL '%s': (%d) %s",
     309                             file, ret, gnutls_strerror(ret));
     310                ret = -1;
     311                goto cleanup;
     312            }
     313        } else {
     314            file = ap_server_root_relative(spool, sc->x509_key_file);
     315
     316            if (load_datum_from_file(spool, file, &data) != 0) {
     317                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     318                             "GnuTLS: Error Reading Private Key '%s'",
     319                             file);
     320                ret = -1;
     321                goto cleanup;
     322            }
     323
     324            ret =
     325                gnutls_privkey_import_x509_raw(sc->privkey_x509, &data,
     326                                               GNUTLS_X509_FMT_PEM, sc->pin,
     327                                               0);
     328
     329            if (ret < 0) {
     330                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     331                             "GnuTLS: Failed to Import Private Key '%s': (%d) %s",
     332                             file, ret, gnutls_strerror(ret));
     333                ret = -1;
     334                goto cleanup;
     335            }
     336        }
     337    }
     338
     339    /* Load the X.509 CA file */
     340    if (sc->x509_ca_file) {
     341        if (load_datum_from_file(spool, sc->x509_ca_file, &data) != 0) {
     342            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     343                         "GnuTLS: Error Reading " "Client CA File '%s'",
     344                         sc->x509_ca_file);
     345            ret = -1;
     346            goto cleanup;
     347        }
     348
     349        ret = gnutls_x509_crt_list_import2(&sc->ca_list, &sc->ca_list_size,
     350                                         &data, GNUTLS_X509_FMT_PEM, 0);
     351        if (ret < 0) {
     352            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     353                         "GnuTLS: Failed to load "
     354                         "Client CA File '%s': (%d) %s", sc->x509_ca_file,
     355                         ret, gnutls_strerror(ret));
     356            ret = -1;
     357            goto cleanup;
     358        }
     359    }
     360
     361    if (sc->pgp_cert_file) {
     362        if (load_datum_from_file(spool, sc->pgp_cert_file, &data) != 0) {
     363            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     364                         "GnuTLS: Error Reading " "Certificate '%s'",
     365                         sc->pgp_cert_file);
     366            ret = -1;
     367            goto cleanup;
     368        }
     369
     370        ret = gnutls_openpgp_crt_init(&sc->cert_crt_pgp[0]);
     371        if (ret < 0) {
     372            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     373                         "GnuTLS: Failed to Init "
     374                         "PGP Certificate: (%d) %s", ret,
     375                         gnutls_strerror(ret));
     376            ret = -1;
     377            goto cleanup;
     378        }
     379
     380        ret =
     381            gnutls_openpgp_crt_import(sc->cert_crt_pgp[0], &data,
     382                                      GNUTLS_OPENPGP_FMT_BASE64);
     383        if (ret < 0) {
     384            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     385                         "GnuTLS: Failed to Import "
     386                         "PGP Certificate: (%d) %s", ret,
     387                         gnutls_strerror(ret));
     388            ret = -1;
     389            goto cleanup;
     390        }
     391
     392        ret =
     393            gnutls_pcert_import_openpgp(sc->cert_pgp, sc->cert_crt_pgp[0],
     394                                        0);
     395        if (ret < 0) {
     396            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     397                         "GnuTLS: Failed to Import "
     398                         "PGP pCertificate: (%d) %s", ret,
     399                         gnutls_strerror(ret));
     400            ret = -1;
     401            goto cleanup;
     402        }
     403    }
     404
     405    /* Load the PGP key file */
     406    if (sc->pgp_key_file) {
     407        if (load_datum_from_file(spool, sc->pgp_key_file, &data) != 0) {
     408            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     409                         "GnuTLS: Error Reading " "Private Key '%s'",
     410                         sc->pgp_key_file);
     411            ret = -1;
     412            goto cleanup;
     413        }
     414
     415        ret = gnutls_privkey_init(&sc->privkey_pgp);
     416        if (ret < 0) {
     417            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     418                         "GnuTLS: Failed to initialize"
     419                         ": (%d) %s", ret, gnutls_strerror(ret));
     420            ret = -1;
     421            goto cleanup;
     422        }
     423
     424        ret =
     425            gnutls_privkey_import_openpgp_raw(sc->privkey_pgp, &data,
     426                                              GNUTLS_OPENPGP_FMT_BASE64,
     427                                              NULL, NULL);
     428        if (ret != 0) {
     429            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     430                         "GnuTLS: Failed to Import "
     431                         "PGP Private Key '%s': (%d) %s",
     432                         sc->pgp_key_file, ret, gnutls_strerror(ret));
     433            ret = -1;
     434            goto cleanup;
     435        }
     436    }
     437
     438    /* Load the keyring file */
     439    if (sc->pgp_ring_file) {
     440        if (load_datum_from_file(spool, sc->pgp_ring_file, &data) != 0) {
     441            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     442                         "GnuTLS: Error Reading " "Keyring File '%s'",
     443                         sc->pgp_ring_file);
     444            ret = -1;
     445            goto cleanup;
     446        }
     447
     448        ret = gnutls_openpgp_keyring_init(&sc->pgp_list);
     449        if (ret < 0) {
     450            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     451                         "GnuTLS: Failed to initialize"
     452                         "keyring: (%d) %s", ret, gnutls_strerror(ret));
     453            ret = -1;
     454            goto cleanup;
     455        }
     456
     457        ret = gnutls_openpgp_keyring_import(sc->pgp_list, &data,
     458                                           GNUTLS_OPENPGP_FMT_BASE64);
     459        if (ret < 0) {
     460            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     461                         "GnuTLS: Failed to load "
     462                         "Keyring File '%s': (%d) %s", sc->pgp_ring_file,
     463                         ret, gnutls_strerror(ret));
     464            ret = -1;
     465            goto cleanup;
     466        }
     467    }
     468
     469    if (sc->priorities_str) {
     470        const char *err;
     471        ret =
     472            gnutls_priority_init(&sc->priorities, sc->priorities_str,
     473                                 &err);
     474
     475        if (ret < 0) {
     476            if (ret == GNUTLS_E_INVALID_REQUEST) {
     477                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     478                             "GnuTLS: Syntax error parsing priorities string at: %s",
     479                             err);
     480            } else {
     481                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     482                             "GnuTLS: error parsing priorities string");
     483
     484            }
     485            ret = -1;
     486            goto cleanup;
     487        }
     488    }
     489
     490    ret = 0;
     491  cleanup:
     492    apr_pool_destroy(spool);
     493
     494    return ret;
     495}
     496
     497int mgs_pkcs11_reinit(server_rec * base_server)
     498{
     499    int ret;
     500    server_rec *s;
     501    mgs_srvconf_rec *sc;
     502
     503    gnutls_pkcs11_reinit();
     504
     505    for (s = base_server; s; s = s->next) {
     506        sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
     507
     508            /* gnutls caches the session in a private key, so we need to open
     509             * a new one */
     510            if (sc->x509_key_file && gnutls_url_is_supported(sc->x509_key_file) != 0) {
     511                gnutls_privkey_deinit(sc->privkey_x509);
     512
     513                ret = gnutls_privkey_init(&sc->privkey_x509);
     514                if (ret < 0) {
     515                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
     516                                 "GnuTLS: Failed to initialize: (%d) %s", ret,
     517                                 gnutls_strerror(ret));
     518                    goto fail;
     519                }
     520
     521                gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback, sc);
     522
     523                ret = gnutls_privkey_import_url(sc->privkey_x509, sc->x509_key_file, 0);
     524                if (ret < 0) {
     525                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
     526                             "GnuTLS: Failed to Re-Import Private Key URL '%s': (%d) %s",
     527                             sc->x509_key_file, ret, gnutls_strerror(ret));
     528                    goto fail;
     529                }
     530            }
     531    }
     532
     533    return 0;
     534
     535 fail:
     536    gnutls_privkey_deinit(sc->privkey_x509);
     537    return -1;
     538}
     539
     540const char *mgs_set_dh_file(cmd_parms * parms, void *dummy,
     541                            const char *arg)
     542{
     543    mgs_srvconf_rec *sc =
     544        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     545                                                 module_config,
     546                                                 &gnutls_module);
     547
     548    sc->dh_file = ap_server_root_relative(parms->pool, arg);
     549
     550    return NULL;
     551}
     552
     553const char *mgs_set_cert_file(cmd_parms * parms, void *dummy,
     554                              const char *arg)
     555{
     556
     557    mgs_srvconf_rec *sc =
     558        (mgs_srvconf_rec *) ap_get_module_config(parms->
     559                                                 server->module_config,
     560                                                 &gnutls_module);
     561
     562    sc->x509_cert_file = apr_pstrdup(parms->pool, arg);
     563
     564    return NULL;
     565
     566}
     567
     568const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
     569                             const char *arg)
     570{
     571
     572    mgs_srvconf_rec *sc =
     573        (mgs_srvconf_rec *) ap_get_module_config(parms->
     574                                                 server->module_config,
     575                                                 &gnutls_module);
     576
     577    sc->x509_key_file = apr_pstrdup(parms->pool, arg);
     578
     579    return NULL;
     580}
     581
     582const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy,
     583                                 const char *arg)
     584{
     585    mgs_srvconf_rec *sc =
     586        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     587                                                 module_config,
     588                                                 &gnutls_module);
     589
     590    sc->pgp_cert_file = ap_server_root_relative(parms->pool, arg);
     591
     592    return NULL;
     593}
     594
     595const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy,
     596                                const char *arg)
     597{
     598    mgs_srvconf_rec *sc =
     599        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     600                                                 module_config,
     601                                                 &gnutls_module);
     602
     603    sc->pgp_key_file = ap_server_root_relative(parms->pool, arg);
     604
     605    return NULL;
     606}
     607
     608const char *mgs_set_tickets(cmd_parms * parms, void *dummy,
     609                            const char *arg)
     610{
     611    mgs_srvconf_rec *sc =
     612        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     613                                                 module_config,
     614                                                 &gnutls_module);
     615
     616    sc->tickets = 0;
     617    if (strcasecmp("on", arg) == 0) {
     618        sc->tickets = 1;
     619    }
     620
     621    return NULL;
     622}
     623
     624
     625#ifdef ENABLE_SRP
     626
     627const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy,
     628                                     const char *arg)
     629{
     630    mgs_srvconf_rec *sc =
     631        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     632                                                 module_config,
     633                                                 &gnutls_module);
     634
     635    sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
     636
     637    return NULL;
     638}
     639
     640const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
     641                                          const char *arg)
     642{
     643    mgs_srvconf_rec *sc =
     644        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     645                                                 module_config,
     646                                                 &gnutls_module);
     647
     648    sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg);
     649
     650    return NULL;
     651}
     652
     653#endif
     654
     655const char *mgs_set_cache(cmd_parms * parms, void *dummy,
     656                          const char *type, const char *arg)
     657{
     658    const char *err;
     659    mgs_srvconf_rec *sc =
     660        ap_get_module_config(parms->server->module_config,
     661                             &gnutls_module);
     662    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
     663        return err;
     664    }
     665
     666    if (strcasecmp("none", type) == 0) {
     667        sc->cache_type = mgs_cache_none;
     668        sc->cache_config = NULL;
     669        return NULL;
     670    } else if (strcasecmp("dbm", type) == 0) {
     671        sc->cache_type = mgs_cache_dbm;
     672    } else if (strcasecmp("gdbm", type) == 0) {
     673        sc->cache_type = mgs_cache_gdbm;
     674    }
     675#if HAVE_APR_MEMCACHE
     676    else if (strcasecmp("memcache", type) == 0) {
     677        sc->cache_type = mgs_cache_memcache;
     678    }
     679#endif
     680    else {
     681        return "Invalid Type for GnuTLSCache!";
     682    }
     683
     684    if (arg == NULL)
     685        return "Invalid argument 2 for GnuTLSCache!";
     686
     687    if (sc->cache_type == mgs_cache_dbm
     688        || sc->cache_type == mgs_cache_gdbm) {
     689        sc->cache_config = ap_server_root_relative(parms->pool, arg);
     690    } else {
     691        sc->cache_config = apr_pstrdup(parms->pool, arg);
     692    }
     693
     694    return NULL;
     695}
     696
     697const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
     698                                  const char *arg)
     699{
     700    int argint;
     701    const char *err;
     702    mgs_srvconf_rec *sc =
     703        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     704                                                 module_config,
     705                                                 &gnutls_module);
     706
     707    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
     708        return err;
     709    }
     710
     711    argint = atoi(arg);
     712
     713    if (argint < 0) {
     714        return "GnuTLSCacheTimeout: Invalid argument";
     715    } else if (argint == 0) {
     716        sc->cache_timeout = 0;
     717    } else {
     718        sc->cache_timeout = apr_time_from_sec(argint);
     719    }
     720
     721    return NULL;
     722}
     723
     724const char *mgs_set_client_verify_method(cmd_parms * parms, void *dummy,
     725                                         const char *arg)
     726{
     727    mgs_srvconf_rec *sc =
     728        (mgs_srvconf_rec *) ap_get_module_config(parms->
     729                                                 server->module_config,
     730                                                 &gnutls_module);
     731
     732    if (strcasecmp("cartel", arg) == 0) {
     733        sc->client_verify_method = mgs_cvm_cartel;
     734    } else if (strcasecmp("msva", arg) == 0) {
     735#ifdef ENABLE_MSVA
     736        sc->client_verify_method = mgs_cvm_msva;
     737#else
     738        return "GnuTLSClientVerifyMethod: msva is not supported";
     739#endif
     740    } else {
     741        return "GnuTLSClientVerifyMethod: Invalid argument";
     742    }
     743
     744    return NULL;
     745}
     746
     747const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
     748                                  const char *arg)
     749{
     750    int mode;
     751
     752    if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
     753        mode = GNUTLS_CERT_IGNORE;
     754    } else if (strcasecmp("optional", arg) == 0
     755               || strcasecmp("request", arg) == 0) {
     756        mode = GNUTLS_CERT_REQUEST;
     757    } else if (strcasecmp("require", arg) == 0) {
     758        mode = GNUTLS_CERT_REQUIRE;
     759    } else {
     760        return "GnuTLSClientVerify: Invalid argument";
     761    }
     762
     763    /* This was set from a directory context */
     764    if (parms->path) {
     765        mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dummy;
     766        dc->client_verify_mode = mode;
     767    } else {
     768        mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     769            ap_get_module_config(parms->server->module_config,
     770                                 &gnutls_module);
     771        sc->client_verify_mode = mode;
     772    }
     773
     774    return NULL;
     775}
     776
     777const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
     778                                   const char *arg)
     779{
     780    mgs_srvconf_rec *sc =
     781        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     782                                                 module_config,
     783                                                 &gnutls_module);
     784
     785    sc->x509_ca_file = ap_server_root_relative(parms->pool, arg);
     786
     787    return NULL;
     788}
     789
     790const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
     791                                 const char *arg)
     792{
     793    mgs_srvconf_rec *sc =
     794        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     795                                                 module_config,
     796                                                 &gnutls_module);
     797
     798    sc->pgp_ring_file = ap_server_root_relative(parms->pool, arg);
     799
     800    return NULL;
     801}
     802
     803const char *mgs_set_proxy_engine(cmd_parms * parms, void *dummy,
     804                                 const char *arg)
     805{
     806
     807    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     808        ap_get_module_config(parms->server->module_config, &gnutls_module);
     809
     810    if (!strcasecmp(arg, "On")) {
     811        sc->proxy_enabled = GNUTLS_ENABLED_TRUE;
     812    } else if (!strcasecmp(arg, "Off")) {
     813        sc->proxy_enabled = GNUTLS_ENABLED_FALSE;
     814    } else {
     815        return "SSLProxyEngine must be set to 'On' or 'Off'";
     816    }
     817
     818    return NULL;
     819}
     820
     821const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
     822                            const char *arg)
     823{
     824    mgs_srvconf_rec *sc =
     825        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     826                                                 module_config,
     827                                                 &gnutls_module);
     828    if (!strcasecmp(arg, "On")) {
     829        sc->enabled = GNUTLS_ENABLED_TRUE;
     830    } else if (!strcasecmp(arg, "Off")) {
     831        sc->enabled = GNUTLS_ENABLED_FALSE;
     832    } else {
     833        return "GnuTLSEnable must be set to 'On' or 'Off'";
     834    }
     835
     836    return NULL;
     837}
     838
     839const char *mgs_set_export_certificates_size(cmd_parms * parms,
     840                                             void *dummy, const char *arg)
     841{
     842    mgs_srvconf_rec *sc =
     843        (mgs_srvconf_rec *) ap_get_module_config(parms->
     844                                                 server->module_config,
     845                                                 &gnutls_module);
     846    if (!strcasecmp(arg, "On")) {
     847        sc->export_certificates_size = 16 * 1024;
     848    } else if (!strcasecmp(arg, "Off")) {
     849        sc->export_certificates_size = 0;
     850    } else {
     851        char *endptr;
     852        sc->export_certificates_size = strtol(arg, &endptr, 10);
     853        while (apr_isspace(*endptr))
     854            endptr++;
     855        if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') {
     856            ;
     857        } else if (*endptr == 'k' || *endptr == 'K') {
     858            sc->export_certificates_size *= 1024;
     859        } else {
     860            return
     861                "GnuTLSExportCertificates must be set to a size (in bytes) or 'On' or 'Off'";
     862        }
     863    }
     864
     865    return NULL;
     866}
     867
     868const char *mgs_set_priorities(cmd_parms * parms, void *dummy,
     869                               const char *arg)
     870{
     871
     872    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     873        ap_get_module_config(parms->server->module_config, &gnutls_module);
     874
     875    sc->priorities_str = apr_pstrdup(parms->pool, arg);
     876
     877    return NULL;
     878}
     879
     880const char *mgs_set_pin(cmd_parms * parms, void *dummy, const char *arg)
     881{
     882
     883    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     884        ap_get_module_config(parms->server->module_config, &gnutls_module);
     885
     886    sc->pin = apr_pstrdup(parms->pool, arg);
     887
     888    return NULL;
     889}
     890
     891const char *mgs_set_srk_pin(cmd_parms * parms, void *dummy, const char *arg)
     892{
     893
     894    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     895        ap_get_module_config(parms->server->module_config, &gnutls_module);
     896
     897    sc->srk_pin = apr_pstrdup(parms->pool, arg);
     898
     899    return NULL;
     900}
     901
     902static mgs_srvconf_rec *_mgs_config_server_create(apr_pool_t * p,
     903                                                  char **err)
     904{
     905    mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
     906
     907    sc->enabled = GNUTLS_ENABLED_UNSET;
     908
     909
    634910    sc->privkey_x509 = NULL;
    635         /* Initialize all Certificate Chains */
    636     /* FIXME: how do we indicate that this is unset for a merge? (that
    637      * is, how can a subordinate server override the chain by setting
    638      * an empty one?  what would that even look like in the
    639      * configuration?) */
    640         sc->certs_x509_chain = malloc(MAX_CHAIN_SIZE * sizeof (*sc->certs_x509_chain));
     911    sc->privkey_pgp = NULL;
    641912    sc->certs_x509_chain_num = 0;
    642     sc->cache_timeout = -1; /* -1 means "unset" */
     913    sc->cache_timeout = -1;     /* -1 means "unset" */
    643914    sc->cache_type = mgs_cache_unset;
    644915    sc->cache_config = NULL;
     
    656927}
    657928
    658 void *mgs_config_server_create(apr_pool_t * p, server_rec * s) {
     929void *mgs_config_server_create(apr_pool_t * p, server_rec * s)
     930{
    659931    char *err = NULL;
    660932    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
    661     if (sc) return sc; else return err;
     933    if (sc)
     934        return sc;
     935    else
     936        return err;
    662937}
    663938
     
    665940#define gnutls_srvconf_assign(t) sc->t = add->t
    666941
    667 void *mgs_config_server_merge(apr_pool_t *p, void *BASE, void *ADD) {
     942void *mgs_config_server_merge(apr_pool_t * p, void *BASE, void *ADD)
     943{
    668944    int i;
    669945    char *err = NULL;
    670     mgs_srvconf_rec *base = (mgs_srvconf_rec *)BASE;
    671     mgs_srvconf_rec *add = (mgs_srvconf_rec *)ADD;
     946    mgs_srvconf_rec *base = (mgs_srvconf_rec *) BASE;
     947    mgs_srvconf_rec *add = (mgs_srvconf_rec *) ADD;
    672948    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
    673     if (NULL == sc) return err;
     949    if (NULL == sc)
     950        return err;
    674951
    675952    gnutls_srvconf_merge(enabled, GNUTLS_ENABLED_UNSET);
     
    681958    gnutls_srvconf_merge(srp_tpasswd_file, NULL);
    682959    gnutls_srvconf_merge(srp_tpasswd_conf_file, NULL);
    683     gnutls_srvconf_merge(privkey_x509, NULL);
    684     gnutls_srvconf_merge(priorities, NULL);
    685     gnutls_srvconf_merge(dh_params, NULL);
     960    gnutls_srvconf_merge(x509_cert_file, NULL);
     961
     962    gnutls_srvconf_merge(x509_key_file, NULL);
     963    gnutls_srvconf_merge(x509_ca_file, NULL);
     964    gnutls_srvconf_merge(pin, NULL);
     965    gnutls_srvconf_merge(pgp_cert_file, NULL);
     966    gnutls_srvconf_merge(pgp_key_file, NULL);
     967    gnutls_srvconf_merge(pgp_ring_file, NULL);
     968    gnutls_srvconf_merge(dh_file, NULL);
     969    gnutls_srvconf_merge(priorities_str, NULL);
    686970
    687971    /* FIXME: the following items are pre-allocated, and should be
    688972     * properly disposed of before assigning in order to avoid leaks;
    689973     * so at the moment, we can't actually have them in the config.
    690      * what happens during de-allocation?
    691 
    692      * This is probably leaky.
    693      */
     974     * what happens during de-allocation? */
     975    gnutls_srvconf_assign(ca_list);
     976    gnutls_srvconf_assign(ca_list_size);
     977    gnutls_srvconf_assign(cert_pgp);
     978    gnutls_srvconf_assign(cert_crt_pgp);
     979    gnutls_srvconf_assign(pgp_list);
    694980    gnutls_srvconf_assign(certs);
    695981    gnutls_srvconf_assign(anon_creds);
    696982    gnutls_srvconf_assign(srp_creds);
    697983    gnutls_srvconf_assign(certs_x509_chain);
     984    gnutls_srvconf_assign(certs_x509_crt_chain);
    698985    gnutls_srvconf_assign(certs_x509_chain_num);
    699986
     
    702989    gnutls_srvconf_assign(cert_cn);
    703990    for (i = 0; i < MAX_CERT_SAN; i++)
    704         gnutls_srvconf_assign(cert_san[i]);
    705     gnutls_srvconf_assign(ca_list);
    706     gnutls_srvconf_assign(ca_list_size);
    707     gnutls_srvconf_assign(cert_pgp);
    708     gnutls_srvconf_assign(pgp_list);
    709     gnutls_srvconf_assign(privkey_pgp);
     991        gnutls_srvconf_assign(cert_san[i]);
    710992
    711993    return sc;
     
    715997#undef gnutls_srvconf_assign
    716998
    717 void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv) {
     999void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv)
     1000{
    7181001    mgs_dirconf_rec *new;
    7191002    /*    mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */
    7201003    mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
    7211004
    722     new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof (mgs_dirconf_rec));
     1005    new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec));
    7231006    new->client_verify_mode = add->client_verify_mode;
    7241007    return new;
    7251008}
    7261009
    727 void *mgs_config_dir_create(apr_pool_t * p, char *dir) {
    728     mgs_dirconf_rec *dc = apr_palloc(p, sizeof (*dc));
     1010void *mgs_config_dir_create(apr_pool_t * p, char *dir)
     1011{
     1012    mgs_dirconf_rec *dc = apr_palloc(p, sizeof(*dc));
    7291013    dc->client_verify_mode = -1;
    7301014    return dc;
    7311015}
    732 
  • 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;
  • src/mod_gnutls.c

    r765cac2 r031acac  
    101101    RSRC_CONF | OR_AUTHCFG,
    102102    "Enable SSL Proxy Engine"),
     103    AP_INIT_RAW_ARGS("GnuTLSPIN", mgs_set_pin,
     104    NULL,
     105    RSRC_CONF,
     106    "The PIN to use in case of encrypted keys or PKCS #11 tokens."),
     107    AP_INIT_RAW_ARGS("GnuTLSSRKPIN", mgs_set_srk_pin,
     108    NULL,
     109    RSRC_CONF,
     110    "The SRK PIN to use in case of TPM keys."),
    103111    AP_INIT_TAKE1("GnuTLSClientVerify", mgs_set_client_verify,
    104112    NULL,
Note: See TracChangeset for help on using the changeset viewer.