typedef struct {
int refcnt;
gnutls_certificate_credentials_t x509_cred;
+ gnutls_dh_params_t dh_params;
} x509_cred_slot;
static array x509_creds = INIT_ARRAY;
static size_t x509_cred_idx;
static gnutls_dh_params_t dh_params;
-static gnutls_priority_t priorities_cache;
+static gnutls_priority_t priorities_cache = NULL;
static bool ConnSSL_LoadServerKey_gnutls PARAMS(( void ));
#endif
assert(slot->x509_cred != NULL);
slot->refcnt--;
if ((c->ssl_state.x509_cred_idx != x509_cred_idx) && (slot->refcnt <= 0)) {
- Log(LOG_INFO, "Discarding X509 certificate credentials from slot %zd.",
- c->ssl_state.x509_cred_idx);
- /* TODO/FIXME: DH parameters will still leak memory. */
+ LogDebug("Discarding X509 certificate credentials from slot %zd.",
+ c->ssl_state.x509_cred_idx);
gnutls_certificate_free_keys(slot->x509_cred);
gnutls_certificate_free_credentials(slot->x509_cred);
slot->x509_cred = NULL;
+ gnutls_dh_params_deinit(slot->dh_params);
+ slot->dh_params = NULL;
slot->refcnt = 0;
}
#endif
if (!ConnSSL_LoadServerKey_gnutls())
goto out;
+ if (priorities_cache != NULL) {
+ gnutls_priority_deinit(priorities_cache);
+ }
if (gnutls_priority_init(&priorities_cache, Conf_SSLOptions.CipherList,
NULL) != GNUTLS_E_SUCCESS) {
Log(LOG_ERR,
return false;
}
- cert_file = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
- if (!cert_file) {
- Log(LOG_ERR, "No SSL server key configured!");
- return false;
- }
-
if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
Log(LOG_WARNING,
"Ignoring SSL \"KeyFilePassword\": Not supported by GnuTLS.");
return false;
gnutls_certificate_set_dh_params(x509_cred, dh_params);
- err = gnutls_certificate_set_x509_key_file(x509_cred, cert_file, Conf_SSLOptions.KeyFile, GNUTLS_X509_FMT_PEM);
- if (err < 0) {
- Log(LOG_ERR,
- "Failed to set certificate key file (cert %s, key %s): %s",
- cert_file,
- Conf_SSLOptions.KeyFile ? Conf_SSLOptions.KeyFile : "(NULL)",
- gnutls_strerror(err));
- return false;
+
+ cert_file = Conf_SSLOptions.CertFile ?
+ Conf_SSLOptions.CertFile : Conf_SSLOptions.KeyFile;
+ if (Conf_SSLOptions.KeyFile) {
+ err = gnutls_certificate_set_x509_key_file(x509_cred, cert_file,
+ Conf_SSLOptions.KeyFile,
+ GNUTLS_X509_FMT_PEM);
+ if (err < 0) {
+ Log(LOG_ERR,
+ "Failed to set certificate key file (cert %s, key %s): %s",
+ cert_file,
+ Conf_SSLOptions.KeyFile ? Conf_SSLOptions.KeyFile : "(NULL)",
+ gnutls_strerror(err));
+ return false;
+ }
}
/* Free currently active x509 context (if any) unless it is still in use */
slot = array_get(&x509_creds, sizeof(x509_cred_slot), x509_cred_idx);
if ((slot != NULL) && (slot->refcnt <= 0) && (slot->x509_cred != NULL)) {
- Log(LOG_INFO, "Discarding X509 certificate credentials from slot %zd.", x509_cred_idx);
- /* TODO/FIXME: DH parameters will still leak memory. */
+ LogDebug("Discarding X509 certificate credentials from slot %zd.",
+ x509_cred_idx);
gnutls_certificate_free_keys(slot->x509_cred);
gnutls_certificate_free_credentials(slot->x509_cred);
slot->x509_cred = NULL;
+ gnutls_dh_params_deinit(slot->dh_params);
+ slot->dh_params = NULL;
slot->refcnt = 0;
}
char *cert_key;
assert(ctx);
- if (!Conf_SSLOptions.KeyFile) {
- Log(LOG_ERR, "No SSL server key configured!");
- return false;
- }
-
SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
SSL_CTX_set_default_passwd_cb_userdata(ctx, &Conf_SSLOptions.KeyFilePassword);
+ if (!Conf_SSLOptions.KeyFile)
+ return true;
+
if (SSL_CTX_use_PrivateKey_file(ctx, Conf_SSLOptions.KeyFile, SSL_FILETYPE_PEM) != 1) {
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
LogOpenSSLError("Failed to add private key", Conf_SSLOptions.KeyFile);
gnutls_certificate_server_set_request(c->ssl_state.gnutls_session,
GNUTLS_CERT_REQUEST);
- Log(LOG_INFO, "Using X509 credentials from slot %zd", x509_cred_idx);
+ LogDebug("Using X509 credentials from slot %zd.", x509_cred_idx);
c->ssl_state.x509_cred_idx = x509_cred_idx;
x509_cred_slot *slot = array_get(&x509_creds, sizeof(x509_cred_slot), x509_cred_idx);
slot->refcnt++;