From a554fd917ad5e5050665b441a614e66959938ede Mon Sep 17 00:00:00 2001 From: beck <> Date: Sat, 5 Nov 2016 15:13:26 +0000 Subject: Add support for server side OCSP stapling to libtls. Add support for server side OCSP stapling to netcat. --- src/lib/libtls/Symbols.list | 2 ++ src/lib/libtls/tls.h | 4 +++- src/lib/libtls/tls_config.c | 16 +++++++++++++++- src/lib/libtls/tls_init.3 | 18 ++++++++++++++++-- src/lib/libtls/tls_internal.h | 9 ++++----- src/lib/libtls/tls_ocsp.c | 34 ++++++++++++++++++++++++++++++++-- src/lib/libtls/tls_server.c | 8 +++++++- src/usr.bin/nc/nc.1 | 11 +++++++++-- src/usr.bin/nc/netcat.c | 12 ++++++++++-- 9 files changed, 98 insertions(+), 16 deletions(-) diff --git a/src/lib/libtls/Symbols.list b/src/lib/libtls/Symbols.list index 9074d5e011..7ed1d58bdc 100644 --- a/src/lib/libtls/Symbols.list +++ b/src/lib/libtls/Symbols.list @@ -29,6 +29,8 @@ tls_config_set_key_file tls_config_set_key_mem tls_config_set_keypair_file tls_config_set_keypair_mem +tls_config_set_ocsp_staple_mem +tls_config_set_ocsp_staple_file tls_config_set_protocols tls_config_set_verify_depth tls_config_verify diff --git a/src/lib/libtls/tls.h b/src/lib/libtls/tls.h index 2f998d4561..2f8c721a15 100644 --- a/src/lib/libtls/tls.h +++ b/src/lib/libtls/tls.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls.h,v 1.40 2016/11/04 05:13:13 beck Exp $ */ +/* $OpenBSD: tls.h,v 1.41 2016/11/05 15:13:26 beck Exp $ */ /* * Copyright (c) 2014 Joel Sing * @@ -106,6 +106,8 @@ int tls_config_set_keypair_file(struct tls_config *_config, const char *_cert_file, const char *_key_file); int tls_config_set_keypair_mem(struct tls_config *_config, const uint8_t *_cert, size_t _cert_len, const uint8_t *_key, size_t _key_len); +int tls_config_set_ocsp_staple_mem(struct tls_config *_config, char *_staple, size_t _len); +int tls_config_set_ocsp_staple_file(struct tls_config *_config, const char *_staple_file); void tls_config_set_protocols(struct tls_config *_config, uint32_t _protocols); void tls_config_set_verify_depth(struct tls_config *_config, int _verify_depth); diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c index 218a4c4e72..3ac674e597 100644 --- a/src/lib/libtls/tls_config.c +++ b/src/lib/libtls/tls_config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_config.c,v 1.31 2016/11/04 19:01:04 jsing Exp $ */ +/* $OpenBSD: tls_config.c,v 1.32 2016/11/05 15:13:26 beck Exp $ */ /* * Copyright (c) 2014 Joel Sing * @@ -227,6 +227,7 @@ tls_config_free(struct tls_config *config) free((char *)config->ca_mem); free((char *)config->ca_path); free((char *)config->ciphers); + free(config->ocsp_staple); free(config); } @@ -641,3 +642,16 @@ tls_config_verify_client_optional(struct tls_config *config) { config->verify_client = 2; } + +int +tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file) +{ + return tls_config_load_file(&config->error, "OCSP", staple_file, + &config->ocsp_staple, &config->ocsp_staple_len); +} + +int +tls_config_set_ocsp_staple_mem(struct tls_config *config, char *staple, size_t len) +{ + return set_mem(&config->ocsp_staple, &config->ocsp_staple_len, staple, len); +} diff --git a/src/lib/libtls/tls_init.3 b/src/lib/libtls/tls_init.3 index 88195deb2e..a6ab619c19 100644 --- a/src/lib/libtls/tls_init.3 +++ b/src/lib/libtls/tls_init.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tls_init.3,v 1.77 2016/11/04 05:13:13 beck Exp $ +.\" $OpenBSD: tls_init.3,v 1.78 2016/11/05 15:13:26 beck Exp $ .\" .\" Copyright (c) 2014 Ted Unangst .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: November 4 2016 $ +.Dd $Mdocdate: November 5 2016 $ .Dt TLS_INIT 3 .Os .Sh NAME @@ -39,6 +39,8 @@ .Nm tls_config_set_key_mem , .Nm tls_config_set_keypair_file , .Nm tls_config_set_keypair_mem , +.Nm tls_config_set_ocsp_staple_mem , +.Nm tls_config_set_ocsp_staple_file , .Nm tls_config_set_protocols , .Nm tls_config_set_verify_depth , .Nm tls_config_prefer_ciphers_client , @@ -134,6 +136,10 @@ .Fn tls_config_set_keypair_file "struct tls_config *config" "const char *cert_file" "const char *key_file" .Ft "int" .Fn tls_config_set_keypair_mem "struct tls_config *config" "const uint8_t *cert" "size_t cert_len" "const uint8_t *key" "size_t key_len" +.Ft "int" +.Fn tls_config_set_ocsp_staple_mem "struct tls_config *config" "const char *staple" "size_t len" +.Ft "int" +.Fn tls_config_set_ocsp_staple_file "struct tls_config *config" "const char *staple_file .Ft "void" .Fn tls_config_set_protocols "struct tls_config *config" "uint32_t protocols" .Ft "void" @@ -365,6 +371,14 @@ used as an alternative certificate for Server Name Indication (server only). adds an additional public certificate and private key from memory, used as an alternative certificate for Server Name Indication (server only). .It +.Fn tls_config_set_ocsp_staple_mem +adds a DER encoded OCSP response to be stapled during the TLS handshake from +memory. +.It +.Fn tls_config_set_ocsp_staple_file +adds a DER encoded OCSP response to be stapled during the TLS handshake from +the specified file. +.It .Fn tls_config_set_alpn sets the ALPN protocols that are supported. The alpn string is a comma separated list of protocols, in order of preference. diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h index 65b65371b2..1db186a05f 100644 --- a/src/lib/libtls/tls_internal.h +++ b/src/lib/libtls/tls_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_internal.h,v 1.49 2016/11/05 14:50:05 beck Exp $ */ +/* $OpenBSD: tls_internal.h,v 1.50 2016/11/05 15:13:26 beck Exp $ */ /* * Copyright (c) 2014 Jeremie Courreges-Anglas * Copyright (c) 2014 Joel Sing @@ -67,6 +67,8 @@ struct tls_config { int ecdhecurve; struct tls_keypair *keypair; int ocsp_require_stapling; + char *ocsp_staple; + size_t ocsp_staple_len; uint32_t protocols; int verify_cert; int verify_client; @@ -110,10 +112,6 @@ struct tls_ocsp { /* responder location */ char *ocsp_url; - /* request blob */ - uint8_t *request_data; - size_t request_size; - /* cert data, this struct does not own these */ X509 *main_cert; STACK_OF(X509) *extra_certs; @@ -208,6 +206,7 @@ int tls_conninfo_populate(struct tls *ctx); void tls_conninfo_free(struct tls_conninfo *conninfo); int tls_ocsp_verify_cb(SSL *ssl, void *arg); +int tls_ocsp_stapling_cb(SSL *ssl, void *arg); void tls_ocsp_free(struct tls_ocsp *ctx); struct tls_ocsp *tls_ocsp_setup_from_peer(struct tls *ctx); diff --git a/src/lib/libtls/tls_ocsp.c b/src/lib/libtls/tls_ocsp.c index 2da88f4281..9ed60a2aa9 100644 --- a/src/lib/libtls/tls_ocsp.c +++ b/src/lib/libtls/tls_ocsp.c @@ -50,8 +50,6 @@ tls_ocsp_free(struct tls_ocsp *ocsp) ocsp->ocsp_result = NULL; free(ocsp->ocsp_url); ocsp->ocsp_url = NULL; - free(ocsp->request_data); - ocsp->request_data = NULL; free(ocsp); } @@ -322,6 +320,38 @@ tls_ocsp_verify_cb(SSL *ssl, void *arg) return (res == 0) ? 1 : 0; } + +/* Staple the OCSP information in ctx->ocsp to the server handshake. */ +int +tls_ocsp_stapling_cb(SSL *ssl, void *arg) +{ + struct tls *ctx; + unsigned char *ocsp_staple = NULL; + int ret = SSL_TLSEXT_ERR_ALERT_FATAL; + + if ((ctx = SSL_get_app_data(ssl)) == NULL) + goto err; + + if (ctx->config->ocsp_staple == NULL || + ctx->config->ocsp_staple_len == 0) + return SSL_TLSEXT_ERR_NOACK; + + if ((ocsp_staple = malloc(ctx->config->ocsp_staple_len)) == NULL) + goto err; + + memcpy(ocsp_staple, ctx->config->ocsp_staple, + ctx->config->ocsp_staple_len); + if (SSL_set_tlsext_status_ocsp_resp(ctx->ssl_conn, ocsp_staple, + ctx->config->ocsp_staple_len) != 1) + goto err; + + ret = SSL_TLSEXT_ERR_OK; + err: + if (ret != SSL_TLSEXT_ERR_OK) + free(ocsp_staple); + return ret; +} + /* * Public API */ diff --git a/src/lib/libtls/tls_server.c b/src/lib/libtls/tls_server.c index e3b03e1301..a9a5902add 100644 --- a/src/lib/libtls/tls_server.c +++ b/src/lib/libtls/tls_server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_server.c,v 1.29 2016/11/04 19:01:29 jsing Exp $ */ +/* $OpenBSD: tls_server.c,v 1.30 2016/11/05 15:13:26 beck Exp $ */ /* * Copyright (c) 2014 Joel Sing * @@ -48,6 +48,7 @@ tls_server_conn(struct tls *ctx) return (NULL); conn_ctx->flags |= TLS_SERVER_CONN; + conn_ctx->config = ctx->config; return (conn_ctx); } @@ -213,6 +214,11 @@ tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx, if (ctx->config->ciphers_server == 1) SSL_CTX_set_options(*ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + if (SSL_CTX_set_tlsext_status_cb(ctx->ssl_ctx, tls_ocsp_stapling_cb) != 1) { + tls_set_errorx(ctx, "failed to add OCSP stapling callback"); + goto err; + } + /* * Set session ID context to a random value. We don't support * persistent caching of sessions so it is OK to set a temporary diff --git a/src/usr.bin/nc/nc.1 b/src/usr.bin/nc/nc.1 index 8c7790f72a..2dda57af92 100644 --- a/src/usr.bin/nc/nc.1 +++ b/src/usr.bin/nc/nc.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: nc.1,v 1.76 2016/11/04 07:34:17 jmc Exp $ +.\" $OpenBSD: nc.1,v 1.77 2016/11/05 15:13:26 beck Exp $ .\" .\" Copyright (c) 1996 David Sacerdote .\" All rights reserved. @@ -25,7 +25,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: November 4 2016 $ +.Dd $Mdocdate: November 5 2016 $ .Dt NC 1 .Os .Sh NAME @@ -43,6 +43,7 @@ .Op Fl M Ar ttl .Op Fl m Ar minttl .Op Fl O Ar length +.Op Fl o Ar staplefile .Op Fl P Ar proxy_username .Op Fl p Ar source_port .Op Fl R Ar CAfile @@ -187,6 +188,12 @@ Do not do any DNS or service lookups on any specified addresses, hostnames or ports. .It Fl O Ar length Specifies the size of the TCP send buffer. +.It Fl o Ar staplefile +Specifies the filename from which to load data to be stapled +during the TLS handshake. +The file is expected to contain an OSCP response from an OCSP server in +DER format. +May only be used with TLS and when a certificate is being used. .It Fl P Ar proxy_username Specifies a username to present to a proxy server that requires authentication. If no username is specified then authentication will not be attempted. diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c index b71c0426dc..4a841fb96d 100644 --- a/src/usr.bin/nc/netcat.c +++ b/src/usr.bin/nc/netcat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netcat.c,v 1.167 2016/11/04 05:13:13 beck Exp $ */ +/* $OpenBSD: netcat.c,v 1.168 2016/11/05 15:13:26 beck Exp $ */ /* * Copyright (c) 2001 Eric Jackson * Copyright (c) 2015 Bob Beck. All rights reserved. @@ -100,6 +100,7 @@ int rtableid = -1; int usetls; /* use TLS */ char *Cflag; /* Public cert file */ char *Kflag; /* Private key file */ +char *oflag; /* OCSP stapling file */ char *Rflag = DEFAULT_CA_FILE; /* Root CA file */ int tls_cachanged; /* Using non-default CA file */ int TLSopt; /* TLS options */ @@ -163,7 +164,7 @@ main(int argc, char *argv[]) signal(SIGPIPE, SIG_IGN); while ((ch = getopt(argc, argv, - "46C:cDde:FH:hI:i:K:klM:m:NnO:P:p:R:rSs:T:tUuV:vw:X:x:z")) != -1) { + "46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:R:rSs:T:tUuV:vw:X:x:z")) != -1) { switch (ch) { case '4': family = AF_INET; @@ -295,6 +296,9 @@ main(int argc, char *argv[]) errx(1, "TCP send window %s: %s", errstr, optarg); break; + case 'o': + oflag = optarg; + break; case 'S': Sflag = 1; break; @@ -380,6 +384,8 @@ main(int argc, char *argv[]) errx(1, "you must specify -c to use -C"); if (Kflag && !usetls) errx(1, "you must specify -c to use -K"); + if (oflag && !Cflag) + errx(1, "you must specify -C to use -o"); if (tls_cachanged && !usetls) errx(1, "you must specify -c to use -R"); if (tls_expecthash && !usetls) @@ -455,6 +461,8 @@ main(int argc, char *argv[]) errx(1, "%s", tls_config_error(tls_cfg)); if (Kflag && tls_config_set_key_file(tls_cfg, Kflag) == -1) errx(1, "%s", tls_config_error(tls_cfg)); + if (oflag && tls_config_set_ocsp_staple_file(tls_cfg, oflag) == -1) + errx(1, "%s", tls_config_error(tls_cfg)); if (TLSopt & TLS_LEGACY) { tls_config_set_protocols(tls_cfg, TLS_PROTOCOLS_ALL); tls_config_set_ciphers(tls_cfg, "all"); -- cgit v1.2.3-55-g6feb