Allow to set DH parameters

This commit is contained in:
Pierre-Louis Bonicoli 2016-07-05 09:18:07 +02:00
parent 5db61f3982
commit 6b38449875
11 changed files with 121 additions and 126 deletions

View File

@ -7,7 +7,7 @@ src_bip_SOURCES = src/conf.y src/lex.l \
src/line.c src/line.h \
src/log.c src/log.h \
src/md5.c src/md5.h \
src/moduli.h \
src/path_util.c src/path_util.h \
src/tuple.h \
src/util.c src/util.h
src_bipmkpw_SOURCES = src/bipmkpw.c src/md5.c src/util.c

View File

@ -1,4 +1,4 @@
.TH BIP.CONF 5 "10 October 2005"
.TH BIP.CONF 5 "04 July 2016"
.SH NAME
@ -82,6 +82,10 @@ SSL connections.
\fBclient_side_ciphers\fP
OpenSSL cipher lists used for clients SSL connections.
.TP
\fBclient_side_dh_param\fP DH parameters filename\fP (default: \fB<bipdir>/dh.pem\fP)
Used for clients SSL connections, Supply at least 2048-bit parameters.
.TP
\fBssl_default_ciphers\fP
OpenSSL cipher lists used for server connections.

View File

@ -23,6 +23,11 @@ client_side_ssl = false;
# OpenSSL cipher lists used with SSL client connections.
#client_side_ciphers = "ECDHE-RSA-AES128-GCM-SHA256";
# DH parameters bip'll use when serving SSL clients.
# Supply at least 2048-bit parameters, for example using openssl:
# openssl dhparam -out dh.pem 2048;
#client_side_dh_param = "dh.pem";
# Default OpenSSL cipher lists used with outgoing connections to IRC servers.
#ssl_default_ciphers = "ECDHE-RSA-AES128-GCM-SHA256";

View File

@ -56,7 +56,7 @@ syn keyword bipKeyword contained nextgroup=bipBoolV client_side_ssl
\ log log_system
syn keyword bipKeyword contained nextgroup=bipStringV log_root
\ log_format oidentd_file pid_file client_side_ssl_pem client_side_ciphers
\ ssl_default_ciphers
\ client_side_dh_param ssl_default_ciphers
syn keyword bipKeyword contained nextgroup=bipNumericV port log_level
\ log_sync_interval
syn keyword bipKeyword contained nextgroup=bipIPV ip

View File

@ -25,6 +25,7 @@
#include <fcntl.h>
#include "irc.h"
#include "conf.h"
#include "path_util.h"
#include "tuple.h"
#include "log.h"
#include "bip.h"
@ -42,6 +43,7 @@ int conf_css;
#ifdef HAVE_LIBSSL
char *conf_ssl_certfile;
char *conf_client_ciphers;
char *conf_client_dh_file;
char *conf_server_default_ciphers;
#endif
int conf_daemonize;
@ -1019,11 +1021,15 @@ int fireup(bip_t *bip, FILE *conf)
case LEX_CSS_PEM:
MOVE_STRING(conf_ssl_certfile, t->pdata);
break;
case LEX_DH_PARAM:
MOVE_STRING(conf_client_dh_file, t->pdata);
break;
#else
case LEX_DEFAULT_CIPHERS:
case LEX_CSS:
case LEX_CSS_CIPHERS:
case LEX_CSS_PEM:
case LEX_DH_PARAM:
mylog(LOG_WARN, "Found SSL option whereas bip is "
"not built with SSL support.");
break;
@ -1223,6 +1229,7 @@ int main(int argc, char **argv)
conf_ssl_certfile = NULL;
conf_client_ciphers = NULL;
conf_server_default_ciphers = NULL;
conf_client_dh_file = NULL;
#endif
while ((ch = getopt(argc, argv, "hvnf:s:")) != -1) {
@ -1309,24 +1316,14 @@ int main(int argc, char **argv)
#ifdef HAVE_LIBSSL
if (conf_css) {
int e, fd;
int e;
struct stat fs;
if (!conf_ssl_certfile) {
char *ap = "/bip.pem";
conf_ssl_certfile = bip_malloc(strlen(conf_biphome) +
strlen(ap) + 1);
strcpy(conf_ssl_certfile, conf_biphome);
strcat(conf_ssl_certfile, ap);
mylog(LOG_INFO, "Using default SSL certificate file: "
"%s", conf_ssl_certfile);
conf_ssl_certfile = default_path(conf_biphome, "bip.pem",
"SSL certificate");
}
if ((fd = open(conf_ssl_certfile, O_RDONLY)) == -1)
fatal("Unable to open PEM file %s for reading",
conf_ssl_certfile);
else
close(fd);
assert_path_exists(conf_ssl_certfile);
e = stat(conf_ssl_certfile, &fs);
if (e)
@ -1336,6 +1333,12 @@ int main(int argc, char **argv)
mylog(LOG_ERROR, "PEM file %s should not be world "
"readable / writable. Please fix the modes.",
conf_ssl_certfile);
if (!conf_client_dh_file) {
conf_client_dh_file = default_path(conf_biphome, "dh.pem",
"DH parameters");
}
assert_path_exists(conf_client_dh_file);
}
#endif

View File

@ -68,7 +68,7 @@ struct tuple *tuple_l_new(int type, void *p)
%}
%token LEX_IP LEX_EQ LEX_PORT LEX_CSS LEX_SEMICOLON LEX_CONNECTION LEX_NETWORK LEX_LBRA LEX_RBRA LEX_USER LEX_NAME LEX_NICK LEX_SERVER LEX_PASSWORD LEX_SRCIP LEX_HOST LEX_VHOST LEX_SOURCE_PORT LEX_NONE LEX_COMMENT LEX_BUNCH LEX_REALNAME LEX_SSL LEX_SSL_CHECK_MODE LEX_SSL_CHECK_STORE LEX_SSL_CLIENT_CERTFILE LEX_CIPHERS LEX_CSS_CIPHERS LEX_DEFAULT_CIPHERS LEX_CHANNEL LEX_KEY LEX_LOG_ROOT LEX_LOG_FORMAT LEX_LOG_LEVEL LEX_BACKLOG_LINES LEX_BACKLOG_NO_TIMESTAMP LEX_BACKLOG LEX_LOG LEX_LOG_SYSTEM LEX_LOG_SYNC_INTERVAL LEX_FOLLOW_NICK LEX_ON_CONNECT_SEND LEX_AWAY_NICK LEX_PID_FILE LEX_OIDENTD_FILE LEX_IGN_FIRST_NICK LEX_ALWAYS_BACKLOG LEX_BLRESET_ON_TALK LEX_BLRESET_CONNECTION LEX_DEFAULT_USER LEX_DEFAULT_NICK LEX_DEFAULT_REALNAME LEX_NO_CLIENT_AWAY_MSG LEX_BL_MSG_ONLY LEX_ADMIN LEX_BIP_USE_NOTICE LEX_CSS_PEM LEX_AUTOJOIN_ON_KICK LEX_IGNORE_CAPAB LEX_RECONN_TIMER
%token LEX_IP LEX_EQ LEX_PORT LEX_CSS LEX_SEMICOLON LEX_CONNECTION LEX_NETWORK LEX_LBRA LEX_RBRA LEX_USER LEX_NAME LEX_NICK LEX_SERVER LEX_PASSWORD LEX_SRCIP LEX_HOST LEX_VHOST LEX_SOURCE_PORT LEX_NONE LEX_COMMENT LEX_BUNCH LEX_REALNAME LEX_SSL LEX_SSL_CHECK_MODE LEX_SSL_CHECK_STORE LEX_SSL_CLIENT_CERTFILE LEX_CIPHERS LEX_CSS_CIPHERS LEX_DEFAULT_CIPHERS LEX_DH_PARAM LEX_CHANNEL LEX_KEY LEX_LOG_ROOT LEX_LOG_FORMAT LEX_LOG_LEVEL LEX_BACKLOG_LINES LEX_BACKLOG_NO_TIMESTAMP LEX_BACKLOG LEX_LOG LEX_LOG_SYSTEM LEX_LOG_SYNC_INTERVAL LEX_FOLLOW_NICK LEX_ON_CONNECT_SEND LEX_AWAY_NICK LEX_PID_FILE LEX_OIDENTD_FILE LEX_IGN_FIRST_NICK LEX_ALWAYS_BACKLOG LEX_BLRESET_ON_TALK LEX_BLRESET_CONNECTION LEX_DEFAULT_USER LEX_DEFAULT_NICK LEX_DEFAULT_REALNAME LEX_NO_CLIENT_AWAY_MSG LEX_BL_MSG_ONLY LEX_ADMIN LEX_BIP_USE_NOTICE LEX_CSS_PEM LEX_AUTOJOIN_ON_KICK LEX_IGNORE_CAPAB LEX_RECONN_TIMER
%union {
int number;
@ -101,6 +101,7 @@ command:
| LEX_CSS_PEM LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_CSS_PEM, $3); }
| LEX_CSS_CIPHERS LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_CSS_CIPHERS, $3); }
| LEX_DEFAULT_CIPHERS LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_DEFAULT_CIPHERS, $3); }
| LEX_DH_PARAM LEX_EQ LEX_STRING { $$ = tuple_s_new(LEX_DH_PARAM, $3); }
| LEX_LOG LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_LOG, $3); }
| LEX_LOG_SYSTEM LEX_EQ LEX_BOOL { $$ = tuple_i_new(LEX_LOG_SYSTEM, $3); }
| LEX_LOG_SYNC_INTERVAL LEX_EQ LEX_INT { $$ = tuple_i_new(

View File

@ -25,6 +25,7 @@ extern FILE *conf_global_log_file;
static BIO *errbio = NULL;
extern char *conf_ssl_certfile;
extern char *conf_client_ciphers;
extern char *conf_client_dh_file;
static int SSLize(connection_t *cn, int *nc);
static SSL_CTX *SSL_init_context(char *ciphers);
/* SSH like trust management */
@ -1126,81 +1127,39 @@ static connection_t *connection_init(int anti_flood, int ssl, int timeout,
}
#ifdef HAVE_LIBSSL
#include "moduli.h"
/* from postfix tls impl */
static DH *dh_512(void)
static int ctx_set_dh(SSL_CTX *ctx)
{
DH *dh;
BIGNUM *p;
BIGNUM *g;
static DH *dh_512;
/* Return ephemeral DH parameters. */
DH *dh = NULL;
FILE *f;
int ret;
if (dh_512 == NULL) {
if ((dh = DH_new()) == NULL) {
mylog(LOG_WARN, "SSL: cannot create DH parameter set");
return (0);
}
p = BN_bin2bn(dh512_p, sizeof(dh512_p), (BIGNUM *) 0);
g = BN_bin2bn(dh512_g, sizeof(dh512_g), (BIGNUM *) 0);
if ((p == NULL) || (g == NULL)) {
mylog(LOG_WARN, "SSL: cannot load compiled-in DH "
"parameters");
DH_free(dh);
return (0);
} else {
DH_set0_pqg(dh, p, NULL, g);
dh_512 = dh;
}
/* Should not fail: already checked in main function */
if ((f = fopen(conf_client_dh_file, "r")) == NULL) {
mylog(LOG_ERROR, "Unable to open DH parameters (%s): %s",
conf_client_dh_file, strerror(errno));
return 0;
}
return dh_512;
}
/* tls_get_dh_1024 - get 1024-bit DH parameters, compiled-in or from file */
static DH *dh_1024(void)
{
DH *dh;
BIGNUM *p;
BIGNUM *g;
static DH *dh_1024;
dh = PEM_read_DHparams(f, NULL, NULL, NULL);
fclose(f);
if (dh_1024 == NULL) {
if ((dh = DH_new()) == NULL) {
mylog(LOG_WARN, "SSL: cannot create DH parameter set");
return (0);
}
p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), (BIGNUM *) 0);
g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), (BIGNUM *) 0);
if ((p == NULL) || (g == NULL)) {
mylog(LOG_WARN, "SSL: cannot load compiled-in DH "
"parameters");
DH_free(dh);
return (0);
} else {
DH_set0_pqg(dh, p, NULL, g);
dh_1024 = dh;
}
if (dh == NULL) {
mylog(LOG_ERROR, "Could not parse DH parameters from: %s",
conf_client_dh_file);
return 0;
}
return (dh_1024);
}
/* ripped from postfix's tls_dh.c */
static DH *tmp_dh_cb(UNUSED(SSL *ssl_unused), int export, int keylength)
{
DH *ret;
ret = SSL_CTX_set_tmp_dh(ctx, dh);
DH_free(dh);
if (export && keylength == 512) {
mylog(LOG_WARN, "SSL: using 512 bits diffie hellman moduli");
ret = dh_512();
} else {
ret = dh_1024();
if (ret != 1) {
mylog(LOG_ERROR, "Unable to set DH parameters: %s",
ERR_error_string(ERR_get_error(), NULL));
return 0;
}
return ret;
return 1;
}
#endif
@ -1247,6 +1206,14 @@ connection_t *accept_new(connection_t *cn)
connection_free(conn);
return NULL;
}
if (!ctx_set_dh(sslctx)) {
mylog(LOG_ERROR, "SSL Unable to load DH "
"parameters");
connection_free(conn);
return NULL;
}
if (!SSL_CTX_use_certificate_chain_file(sslctx,
conf_ssl_certfile))
mylog(LOG_WARN, "SSL: Unable to load "
@ -1255,10 +1222,6 @@ connection_t *accept_new(connection_t *cn)
conf_ssl_certfile,
SSL_FILETYPE_PEM))
mylog(LOG_WARN, "SSL: Unable to load key file");
/* diffie hellman key generation need us to feed some
data that can be static ... */
SSL_CTX_set_tmp_dh_callback(sslctx, tmp_dh_cb);
}
conn->ssl_h = SSL_new(sslctx);

View File

@ -112,6 +112,7 @@ list_t *parse_conf(FILE *file, int *err)
"bip_use_notice" { return LEX_BIP_USE_NOTICE; }
"client_side_ssl_pem" { return LEX_CSS_PEM; }
"client_side_ciphers" { return LEX_CSS_CIPHERS; }
"client_side_dh_param" { return LEX_DH_PARAM; }
"ignore_server_capab" { return LEX_IGNORE_CAPAB; }
"reconn_timer" { return LEX_RECONN_TIMER; }
\"[^"]*\" {

View File

@ -1,38 +0,0 @@
/* ripped from postfix tls_dh.c */
/*
* Compiled-in DH parameters. These are used when no parameters are
* explicitly loaded from file.
*
* XXX What is the origin of these parameters?
*/
static unsigned char dh512_p[] = {
0x88, 0x3F, 0x00, 0xAF, 0xFC, 0x0C, 0x8A, 0xB8, 0x35, 0xCD, 0xE5, 0xC2,
0x0F, 0x55, 0xDF, 0x06, 0x3F, 0x16, 0x07, 0xBF, 0xCE, 0x13, 0x35, 0xE4,
0x1C, 0x1E, 0x03, 0xF3, 0xAB, 0x17, 0xF6, 0x63, 0x50, 0x63, 0x67, 0x3E,
0x10, 0xD7, 0x3E, 0xB4, 0xEB, 0x46, 0x8C, 0x40, 0x50, 0xE6, 0x91, 0xA5,
0x6E, 0x01, 0x45, 0xDE, 0xC9, 0xB1, 0x1F, 0x64, 0x54, 0xFA, 0xD9, 0xAB,
0x4F, 0x70, 0xBA, 0x5B,
};
static unsigned char dh512_g[] = {
0x02,
};
static unsigned char dh1024_p[] = {
0xB0, 0xFE, 0xB4, 0xCF, 0xD4, 0x55, 0x07, 0xE7, 0xCC, 0x88, 0x59, 0x0D,
0x17, 0x26, 0xC5, 0x0C, 0xA5, 0x4A, 0x92, 0x23, 0x81, 0x78, 0xDA, 0x88,
0xAA, 0x4C, 0x13, 0x06, 0xBF, 0x5D, 0x2F, 0x9E, 0xBC, 0x96, 0xB8, 0x51,
0x00, 0x9D, 0x0C, 0x0D, 0x75, 0xAD, 0xFD, 0x3B, 0xB1, 0x7E, 0x71, 0x4F,
0x3F, 0x91, 0x54, 0x14, 0x44, 0xB8, 0x30, 0x25, 0x1C, 0xEB, 0xDF, 0x72,
0x9C, 0x4C, 0xF1, 0x89, 0x0D, 0x68, 0x3F, 0x94, 0x8E, 0xA4, 0xFB, 0x76,
0x89, 0x18, 0xB2, 0x91, 0x16, 0x90, 0x01, 0x99, 0x66, 0x8C, 0x53, 0x81,
0x4E, 0x27, 0x3D, 0x99, 0xE7, 0x5A, 0x7A, 0xAF, 0xD5, 0xEC, 0xE2, 0x7E,
0xFA, 0xED, 0x01, 0x18, 0xC2, 0x78, 0x25, 0x59, 0x06, 0x5C, 0x39, 0xF6,
0xCD, 0x49, 0x54, 0xAF, 0xC1, 0xB1, 0xEA, 0x4A, 0xF9, 0x53, 0xD0, 0xDF,
0x6D, 0xAF, 0xD4, 0x93, 0xE7, 0xBA, 0xAE, 0x9B,
};
static unsigned char dh1024_g[] = {
0x02,
};

37
src/path_util.c Normal file
View File

@ -0,0 +1,37 @@
/*
* This file is part of the bip project
* Copyright (C) 2016 Pierre-Louis Bonicoli
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* See the file "COPYING" for the exact licensing terms.
*/
#include "path_util.h"
#include "util.h"
#include <stdio.h>
#include <string.h>
char *default_path(const char *biphome, const char *filename, const char *desc)
{
char *conf_file;
// '/' and NULL
conf_file = bip_malloc(strlen(biphome) + strlen(filename) + 2);
strcpy(conf_file, biphome);
conf_file[strlen(biphome)] = '/';
strcat(conf_file, filename);
mylog(LOG_INFO, "Using default %s: %s", desc, conf_file);
return conf_file;
}
void assert_path_exists(char *path)
{
FILE* f;
if ((f = fopen(path, "r")) == NULL)
fatal("Unable to open file %s for reading", path);
else
fclose(f);
}

19
src/path_util.h Normal file
View File

@ -0,0 +1,19 @@
/*
* This file is part of the bip project
* Copyright (C) 2016 Pierre-Louis Bonicoli
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* See the file "COPYING" for the exact licensing terms.
*/
#ifndef PATH_UTIL_H
#define PATH_UTIL_H
/* return path of filename located in bip home directory */
char *default_path(const char *biphome, const char *filename, const char *desc);
/* exit program if path doesn't exist */
void assert_path_exists(char *path);
#endif