X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fssl-gnutls.c;h=ba4cf0232aa4be76be73cc0318e1690ddebcbb2e;hb=2daf44115026999612b7a4a48cf35bfa711c35c4;hp=e27d31462e2b738836987379dd6e51d05737cfd8;hpb=26902200a8061d8e9211e5104abbf2acc84ed7b9;p=ashd.git diff --git a/src/ssl-gnutls.c b/src/ssl-gnutls.c index e27d314..ba4cf02 100644 --- a/src/ssl-gnutls.c +++ b/src/ssl-gnutls.c @@ -67,8 +67,6 @@ struct sslconn { struct charbuf in; }; -static gnutls_dh_params_t dhparams; - static int tlsblock(int fd, gnutls_session_t sess, time_t to) { if(gnutls_record_get_direction(sess)) @@ -260,6 +258,23 @@ out: free(pd); } +static gnutls_dh_params_t dhparams(void) +{ + static int inited = 0; + static gnutls_dh_params_t pars; + int ret; + + if(!inited) { + if(((ret = gnutls_dh_params_init(&pars)) != 0) || + ((ret = gnutls_dh_params_generate2(pars, 2048)) != 0)) { + flog(LOG_ERR, "GnuTLS could not generate Diffie-Hellman parameters: %s", gnutls_strerror(ret)); + exit(1); + } + inited = 1; + } + return(pars); +} + static void init(void) { static int inited = 0; @@ -272,11 +287,6 @@ static void init(void) flog(LOG_ERR, "could not initialize GnuTLS: %s", gnutls_strerror(ret)); exit(1); } - if(((ret = gnutls_dh_params_init(&dhparams)) != 0) || - ((ret = gnutls_dh_params_generate2(dhparams, 2048)) != 0)) { - flog(LOG_ERR, "GnuTLS could not generate Diffie-Hellman parameters: %s", gnutls_strerror(ret)); - exit(1); - } } static struct namedcreds *readncreds(char *file) @@ -346,7 +356,7 @@ static struct namedcreds *readncreds(char *file) flog(LOG_ERR, "ssl: could not use certificate from %s: %s", file, gnutls_strerror(ret)); exit(1); } - gnutls_certificate_set_dh_params(nc->creds, dhparams); + gnutls_certificate_set_dh_params(nc->creds, dhparams()); return(nc); } @@ -398,11 +408,24 @@ void handlegnussl(int argc, char **argp, char **argv) printf("\tcrl=CRL-FILE [no default]\n"); printf("\t\tThe name of a file to read revocation lists from.\n"); printf("\t\tMay be given multiple times.\n"); + printf("\tncert=CERT-FILE [no default]\n"); + printf("\t\tThe name of a file to read a named certificate from,\n"); + printf("\t\tfor use with SNI-enabled clients.\n"); + printf("\t\tMay be given multiple times.\n"); + printf("\tncertdir=DIR [no default]\n"); + printf("\t\tRead all *.crt files in the given directory as if they\n"); + printf("\t\twere given with `ncert' options.\n"); + printf("\t\tMay be given multiple times.\n"); printf("\tport=PORT [443]\n"); printf("\t\tThe TCP port to listen on.\n"); printf("\n"); printf("\tAll X.509 data files must be PEM-encoded.\n"); - printf("\tSee the manpage for information on specifying multiple\n\tcertificates to support SNI operation.\n"); + printf("\tIf any certificates were given with `ncert' options, they will be\n"); + printf("\tused if a client explicitly names one of them with a\n"); + printf("\tserver-name indication. If a client indicates no server name,\n"); + printf("\tor if a server-name indication does not match any given\n"); + printf("\tcertificate, the certificate given with the `cert' option will\n"); + printf("\tbe used instead.\n"); exit(0); } else if(!strcmp(argp[i], "cert")) { crtfile = argv[i]; @@ -445,17 +468,17 @@ void handlegnussl(int argc, char **argp, char **argv) flog(LOG_ERR, "ssl: needs certificate file at the very least"); exit(1); } + if((fd = listensock6(port)) < 0) { + flog(LOG_ERR, "could not listen on IPv6 port (port %i): %s", port, strerror(errno)); + exit(1); + } if(keyfile == NULL) keyfile = crtfile; if((ret = gnutls_certificate_set_x509_key_file(creds, crtfile, keyfile, GNUTLS_X509_FMT_PEM)) != 0) { flog(LOG_ERR, "ssl: could not load certificate or key: %s", gnutls_strerror(ret)); exit(1); } - gnutls_certificate_set_dh_params(creds, dhparams); - if((fd = listensock6(port)) < 0) { - flog(LOG_ERR, "could not listen on IPv6 port (port %i): %s", port, strerror(errno)); - exit(1); - } + gnutls_certificate_set_dh_params(creds, dhparams()); bufadd(ncreds, NULL); omalloc(pd); pd->fd = fd;