summaryrefslogtreecommitdiffstats
path: root/tcpd/libcouriergnutls.c
diff options
context:
space:
mode:
Diffstat (limited to 'tcpd/libcouriergnutls.c')
-rw-r--r--tcpd/libcouriergnutls.c80
1 files changed, 73 insertions, 7 deletions
diff --git a/tcpd/libcouriergnutls.c b/tcpd/libcouriergnutls.c
index f3c34d4..da57d1f 100644
--- a/tcpd/libcouriergnutls.c
+++ b/tcpd/libcouriergnutls.c
@@ -126,6 +126,7 @@ struct ssl_context_t {
const char *priority_list;
char *certfile;
+ char *keyfile;
char *dhfile;
char *trustcerts;
@@ -267,6 +268,17 @@ ssl_context tls_create(int isserver, const struct tls_info *info)
free(certfile);
}
+ if ((certfile=strdup(safe_getenv(p, "TLS_PRIVATE_KEYFILE", ""))) != NULL &&
+ *certfile)
+ {
+ p->keyfile=certfile;
+ }
+ else
+ {
+ if (certfile)
+ free(certfile);
+ }
+
switch (*safe_getenv(p, "TLS_VERIFYPEER", "P")) {
case 'n':
case 'N':
@@ -320,6 +332,8 @@ void tls_destroy(ssl_context p)
{
if (p->certfile)
free(p->certfile);
+ if (p->keyfile)
+ free(p->keyfile);
if (p->dhfile)
free(p->dhfile);
if (p->trustcerts)
@@ -749,6 +763,14 @@ static char *check_cert(const char *filename,
return NULL;
}
+static char *check_key(const char *filename,
+ gnutls_certificate_type_t cert_type,
+ const char *req_dn,
+ int isvirtual)
+{
+ return check_cert(filename, cert_type, req_dn, isvirtual);
+}
+
static int read_file(const char *file,
gnutls_datum_t *filebuf)
{
@@ -790,10 +812,12 @@ static void release_file(gnutls_datum_t *filebuf)
static int set_cert(ssl_handle ssl,
gnutls_session_t session,
gnutls_retr2_st *st,
- const char *certfilename)
+ const char *certfilename,
+ const char *keyfilename)
{
int rc;
gnutls_datum_t filebuf;
+ gnutls_datum_t keyfilebuf;
unsigned int cert_cnt;
st->ncerts=0;
@@ -803,15 +827,34 @@ static int set_cert(ssl_handle ssl,
if ((rc=read_file(certfilename, &filebuf)) < 0)
return rc;
+ if (keyfilename)
+ {
+ if ((rc=read_file(keyfilename, &keyfilebuf)) < 0)
+ {
+ release_file(&filebuf);
+ return rc;
+ }
+ }
+
switch (st->cert_type) {
case GNUTLS_CRT_X509:
cert_cnt=0;
- if ((rc=gnutls_x509_privkey_init(&ssl->x509_key)) < 0 ||
- (rc=gnutls_x509_privkey_import(ssl->x509_key, &filebuf,
- GNUTLS_X509_FMT_PEM)) < 0)
- break;
+ if (keyfilename)
+ {
+ if ((rc=gnutls_x509_privkey_init(&ssl->x509_key)) < 0 ||
+ (rc=gnutls_x509_privkey_import(ssl->x509_key, &keyfilebuf,
+ GNUTLS_X509_FMT_PEM)) < 0)
+ break;
+ }
+ else
+ {
+ if ((rc=gnutls_x509_privkey_init(&ssl->x509_key)) < 0 ||
+ (rc=gnutls_x509_privkey_import(ssl->x509_key, &filebuf,
+ GNUTLS_X509_FMT_PEM)) < 0)
+ break;
+ }
rc=gnutls_x509_crt_list_import(NULL, &cert_cnt,
&filebuf,
@@ -846,6 +889,8 @@ static int set_cert(ssl_handle ssl,
}
release_file(&filebuf);
+ if (keyfilename)
+ release_file(&keyfilebuf);
return 0;
}
@@ -862,6 +907,7 @@ static int get_server_cert(gnutls_session_t session,
size_t vhost_size;
unsigned int type=GNUTLS_NAME_DNS;
char *certfilename=NULL;
+ char *keyfilename=NULL;
int rc;
st->cert_type=gnutls_certificate_type_get(session);
@@ -897,6 +943,11 @@ static int get_server_cert(gnutls_session_t session,
st->cert_type,
vhost_buf, 1);
+ if (ssl->ctx->keyfile)
+ keyfilename=check_key(ssl->ctx->keyfile,
+ st->cert_type,
+ vhost_buf, 1);
+
if (certfilename)
break;
}
@@ -909,6 +960,12 @@ static int get_server_cert(gnutls_session_t session,
safe_getenv(ssl->ctx,
"TCPLOCALIP", ""),
0);
+ if (ssl->ctx->keyfile)
+ keyfilename=check_key(ssl->ctx->keyfile,
+ st->cert_type,
+ safe_getenv(ssl->ctx,
+ "TCPLOCALIP", ""),
+ 0);
}
if (!certfilename)
@@ -918,8 +975,10 @@ static int get_server_cert(gnutls_session_t session,
return 0;
}
- rc=set_cert(ssl, session, st, certfilename);
+ rc=set_cert(ssl, session, st, certfilename, keyfilename);
free(certfilename);
+ if (keyfilename)
+ free(keyfilename);
return rc;
}
@@ -1072,6 +1131,7 @@ static int get_client_cert(gnutls_session_t session,
ssl_handle ssl=(ssl_handle)gnutls_session_get_ptr(session);
int rc;
char *certfilename=NULL;
+ char *keyfilename=NULL;
rc= 0;
st->cert_type=gnutls_certificate_type_get(session);
@@ -1080,13 +1140,19 @@ static int get_client_cert(gnutls_session_t session,
certfilename=check_cert(ssl->ctx->certfile,
st->cert_type, "", 0);
+ if (ssl->ctx->keyfile)
+ keyfilename=check_key(ssl->ctx->keyfile,
+ st->cert_type, "", 0);
+
st->ncerts=0;
st->deinit_all=0;
if (certfilename)
{
- rc=set_cert(ssl, session, st, certfilename);
+ rc=set_cert(ssl, session, st, certfilename, keyfilename);
free(certfilename);
+ if (keyfilename)
+ free(keyfilename);
}
else
{