diff --git a/doc/ocserv.1 b/doc/ocserv.1 index d7e8bead..01816b0f 100644 --- a/doc/ocserv.1 +++ b/doc/ocserv.1 @@ -1,8 +1,8 @@ -.TH ocserv 1 "16 Feb 2013" "0.0.1" "User Commands" +.TH ocserv 1 "18 Feb 2013" "0.0.1" "User Commands" .\" .\" DO NOT EDIT THIS FILE (ocserv-args.man) .\" -.\" It has been AutoGen-ed February 16, 2013 at 06:46:07 PM by AutoGen 5.16 +.\" It has been AutoGen-ed February 18, 2013 at 10:23:45 PM by AutoGen 5.16 .\" From the definitions ../src/ocserv-args.def.tmp .\" and the template file agman-cmd.tpl .\" @@ -191,6 +191,12 @@ try\-mtu\-discovery = false server\-cert = /path/to/cert.pem server\-key = /path/to/key.pem .sp +# In case PKCS #11 tokens or TPM are used the PINs have to be available +# in files. The srk\-pin\-file is applicable to TPM keys only (It's the storage +# root key). +.in -file = /path/to/pin.txt +#srk\-pin\-file = /path/to/srkpin.txt +.sp # The Certificate Authority that will be used # to verify clients if certificate authentication # is set. diff --git a/src/config.c b/src/config.c index 50c6f679..f8344ef9 100644 --- a/src/config.c +++ b/src/config.c @@ -132,6 +132,9 @@ unsigned j; } free(auth); + /* When adding allocated data, remember to modify + * reload_cfg_file(); + */ READ_STRING("listen-host", config->name, 0); READ_NUMERIC("tcp-port", config->port, 1); @@ -141,6 +144,8 @@ unsigned j; READ_STRING("server-cert", config->cert, 1); READ_STRING("server-key", config->key, 1); + READ_STRING("pin-file", config->pin_file, 0); + READ_STRING("srk-pin-file", config->srk_pin_file, 0); READ_STRING("ca-cert", config->ca, 0); READ_STRING("crl", config->crl, 0); @@ -269,6 +274,8 @@ unsigned i; DEL(config->name); DEL(config->cert); DEL(config->key); + DEL(config->pin_file); + DEL(config->srk_pin_file); DEL(config->ca); DEL(config->crl); DEL(config->cert_user_oid); diff --git a/src/main.c b/src/main.c index cd8f20b9..816804f5 100644 --- a/src/main.c +++ b/src/main.c @@ -568,6 +568,13 @@ int main(int argc, char** argv) exit(1); } + flags = LOG_PID|LOG_NDELAY; +#ifdef LOG_PERROR + if (config.debug != 0) + flags |= LOG_PERROR; +#endif + openlog("ocserv", flags, LOG_DAEMON); + /* Initialize GnuTLS */ tls_global_init(&s); @@ -579,12 +586,6 @@ int main(int argc, char** argv) write_pid_file(); alarm(MAINTAINANCE_TIME(&s)); - flags = LOG_PID|LOG_NDELAY; -#ifdef LOG_PERROR - if (config.debug != 0) - flags |= LOG_PERROR; -#endif - openlog("ocserv", flags, LOG_DAEMON); syslog_open = 1; diff --git a/src/ocserv-args.c b/src/ocserv-args.c index a00e3042..d459db18 100644 --- a/src/ocserv-args.c +++ b/src/ocserv-args.c @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.c) * - * It has been AutoGen-ed February 16, 2013 at 06:46:06 PM by AutoGen 5.16 + * It has been AutoGen-ed February 18, 2013 at 10:29:19 PM by AutoGen 5.16 * From the definitions ocserv-args.def * and the template file options * diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 8c414549..f7ee5159 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -107,10 +107,18 @@ dpd = 240 try-mtu-discovery = false # The key and the certificates of the server -# The key may be a file, or any URL supported by GnuTLS (i.e., tpmkey or pkcs11) +# The key may be a file, or any URL supported by GnuTLS (e.g., +# tpmkey:uuid=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx;storage=user +# or pkcs11:object=my-vpn-key;object-type=private) server-cert = /path/to/cert.pem server-key = /path/to/key.pem +# In case PKCS #11 or TPM keys are used the PINs should be available +# in files. The srk-pin-file is applicable to TPM keys only (It's the storage +# root key). +pin-file = /path/to/pin.txt +#srk-pin-file = /path/to/srkpin.txt + # The Certificate Authority that will be used # to verify clients if certificate authentication # is set. diff --git a/src/ocserv-args.h b/src/ocserv-args.h index 45572f11..a2fa4e72 100644 --- a/src/ocserv-args.h +++ b/src/ocserv-args.h @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.h) * - * It has been AutoGen-ed February 16, 2013 at 06:46:06 PM by AutoGen 5.16 + * It has been AutoGen-ed February 18, 2013 at 10:29:19 PM by AutoGen 5.16 * From the definitions ocserv-args.def * and the template file options * diff --git a/src/tlslib.c b/src/tlslib.c index 00dd00d8..1d1717b1 100644 --- a/src/tlslib.c +++ b/src/tlslib.c @@ -224,13 +224,68 @@ static int verify_certificate_cb(gnutls_session_t session) return GNUTLS_E_CERTIFICATE_ERROR; } else { - oclog(ws, LOG_INFO, "Client certificate verification succeeded"); + oclog(ws, LOG_INFO, "client certificate verification succeeded"); } /* notify gnutls to continue handshake normally */ return 0; } +int pin_callback (void *user, int attempt, const char *token_url, + const char *token_label, unsigned int flags, char *pin, + size_t pin_max) +{ +struct cfg_st * config = user; +int srk = 0, fd, ret; +const char* file; + + if (flags & GNUTLS_PIN_FINAL_TRY) { + syslog(LOG_ERR, "PIN callback: final try before locking; not attempting to unlock"); + return -1; + } + + if (flags & GNUTLS_PIN_WRONG) { + syslog(LOG_ERR, "PIN callback: wrong PIN was entered for '%s' (%s)", token_label, token_url); + return -1; + } + + if (config->pin_file == NULL) { + syslog(LOG_ERR, "PIN required for '%s' but pin-file was not set", token_label); + return -1; + } + + if (strcmp(token_url, "SRK") == 0 || strcmp(token_label, "SRK") == 0) { + srk = 1; + file = config->srk_pin_file; + } else { + file = config->pin_file; + } + + if (srk != 0 && config->srk_pin_file == NULL) { + syslog(LOG_ERR, "PIN required for '%s' but srk-pin-file was not set", token_label); + return -1; + } + + fd = open(file, O_RDONLY); + if (fd < 0) { + syslog(LOG_ERR, "Could not open PIN file '%s'", file); + return -1; + } + + ret = read(fd, pin, pin_max); + close(fd); + if (ret <= 1) { + syslog(LOG_ERR, "Could not read from PIN file '%s'", file); + return -1; + } + + if (pin[ret-1] == '\n' || pin[ret-1] == '\r') + pin[ret-1] = 0; + pin[ret] = 0; + + return 0; +} + void tls_global_init(main_server_st* s) { int ret; @@ -248,6 +303,8 @@ const char* perr; ret = gnutls_certificate_allocate_credentials(&s->creds.xcred); GNUTLS_FATAL_ERR(ret); + gnutls_certificate_set_pin_function (s->creds.xcred, pin_callback, s->config); + if (s->config->key != NULL && strncmp(s->config->key, "pkcs11:", 7) != 0) { ret = gnutls_certificate_set_x509_key_file(s->creds.xcred, s->config->cert, @@ -259,7 +316,7 @@ const char* perr; exit(1); } } else { -#ifdef HAVE_PKCS11 +#ifndef HAVE_PKCS11 fprintf(stderr, "Cannot load key, GnuTLS is compiled without pkcs11 support\n"); exit(1); #endif @@ -311,6 +368,8 @@ const char* perr; ret = gnutls_certificate_allocate_credentials(&s->creds.xcred); GNUTLS_FATAL_ERR(ret); + + gnutls_certificate_set_pin_function (s->creds.xcred, pin_callback, s->config); if (s->config->key != NULL && strncmp(s->config->key, "pkcs11:", 7) != 0) { ret = @@ -323,7 +382,7 @@ const char* perr; exit(1); } } else { -#ifdef HAVE_PKCS11 +#ifndef HAVE_PKCS11 mslog(s, NULL, LOG_ERR, "Cannot load key, GnuTLS is compiled without pkcs11 support\n"); exit(1); #endif diff --git a/src/vpn.h b/src/vpn.h index 088ea15f..28242527 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -55,6 +55,8 @@ struct cfg_st { char *name; /* server name */ unsigned int port; unsigned int udp_port; + char *pin_file; + char *srk_pin_file; char *cert; char *key; char *ca;