Add support for providing CRLs to libtls - once a CRL is provided we
authorjsing <jsing@openbsd.org>
Thu, 6 Jul 2017 17:12:22 +0000 (17:12 +0000)
committerjsing <jsing@openbsd.org>
Thu, 6 Jul 2017 17:12:22 +0000 (17:12 +0000)
enable CRL checking for the full certificate chain.

Based on a diff from Jack Burton <jack at saosce dot com dot au>, thanks!

Discussed with beck@

lib/libtls/Symbols.list
lib/libtls/tls.c
lib/libtls/tls.h
lib/libtls/tls_config.c
lib/libtls/tls_internal.h

index 3124c64..6d174bc 100644 (file)
@@ -26,6 +26,8 @@ tls_config_set_ca_path
 tls_config_set_cert_file
 tls_config_set_cert_mem
 tls_config_set_ciphers
+tls_config_set_crl_file
+tls_config_set_crl_mem
 tls_config_set_dheparams
 tls_config_set_ecdhecurve
 tls_config_set_key_file
index f64f6d7..ed85727 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.c,v 1.67 2017/06/22 18:03:57 jsing Exp $ */
+/* $OpenBSD: tls.c,v 1.68 2017/07/06 17:12:22 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -26,6 +26,8 @@
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
+#include <openssl/safestack.h>
+#include <openssl/ssl.h>
 #include <openssl/x509.h>
 
 #include <tls.h>
@@ -464,8 +466,15 @@ tls_configure_ssl_verify(struct tls *ctx, SSL_CTX *ssl_ctx, int verify)
 {
        size_t ca_len = ctx->config->ca_len;
        char *ca_mem = ctx->config->ca_mem;
+       char *crl_mem = ctx->config->crl_mem;
+       size_t crl_len = ctx->config->crl_len;
        char *ca_free = NULL;
+       STACK_OF(X509_INFO) *xis = NULL;
+       X509_STORE *store;
+       X509_INFO *xi;
+       BIO *bio = NULL;
        int rv = -1;
+       int i;
 
        SSL_CTX_set_verify(ssl_ctx, verify, NULL);
        SSL_CTX_set_cert_verify_callback(ssl_ctx, tls_ssl_cert_verify_cb, ctx);
@@ -499,10 +508,41 @@ tls_configure_ssl_verify(struct tls *ctx, SSL_CTX *ssl_ctx, int verify)
                goto err;
        }
 
+       if (crl_mem != NULL) {
+               if (crl_len > INT_MAX) {
+                       tls_set_errorx(ctx, "crl too long");
+                       goto err;
+               }
+               if ((bio = BIO_new_mem_buf(crl_mem, crl_len)) == NULL) {
+                       tls_set_errorx(ctx, "failed to create buffer");
+                       goto err;
+               }
+               if ((xis = PEM_X509_INFO_read_bio(bio, NULL, tls_password_cb,
+                   NULL)) == NULL) {
+                       tls_set_errorx(ctx, "failed to parse crl");
+                       goto err;
+               }
+               store = SSL_CTX_get_cert_store(ssl_ctx);
+               for (i = 0; i < sk_X509_INFO_num(xis); i++) {
+                       xi = sk_X509_INFO_value(xis, i);
+                       if (xi->crl == NULL)
+                               continue;
+                       if (!X509_STORE_add_crl(store, xi->crl)) {
+                               tls_set_error(ctx, "failed to add crl");
+                               goto err;
+                       }
+                       xi->crl = NULL;
+               }
+               X509_VERIFY_PARAM_set_flags(store->param,
+                   X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
+       }
+
  done:
        rv = 0;
 
  err:
+       sk_X509_INFO_pop_free(xis, X509_INFO_free);
+       BIO_free(bio);
        free(ca_free);
 
        return (rv);
index 4fad451..1a6701b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.h,v 1.49 2017/05/06 20:57:45 jsing Exp $ */
+/* $OpenBSD: tls.h,v 1.50 2017/07/06 17:12:22 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -105,6 +105,9 @@ int tls_config_set_cert_file(struct tls_config *_config,
 int tls_config_set_cert_mem(struct tls_config *_config, const uint8_t *_cert,
     size_t _len);
 int tls_config_set_ciphers(struct tls_config *_config, const char *_ciphers);
+int tls_config_set_crl_file(struct tls_config *_config, const char *_crl_file);
+int tls_config_set_crl_mem(struct tls_config *_config, const uint8_t *_crl,
+    size_t _len);
 int tls_config_set_dheparams(struct tls_config *_config, const char *_params);
 int tls_config_set_ecdhecurve(struct tls_config *_config, const char *_name);
 int tls_config_set_key_file(struct tls_config *_config, const char *_key_file);
index 8f0bd70..fe049d1 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_config.c,v 1.40 2017/05/06 20:59:28 jsing Exp $ */
+/* $OpenBSD: tls_config.c,v 1.41 2017/07/06 17:12:22 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -268,6 +268,7 @@ tls_config_free(struct tls_config *config)
        free((char *)config->ca_mem);
        free((char *)config->ca_path);
        free((char *)config->ciphers);
+       free((char *)config->crl_mem);
 
        free(config);
 }
@@ -299,6 +300,7 @@ tls_config_clear_keys(struct tls_config *config)
                tls_keypair_clear(kp);
 
        tls_config_set_ca_mem(config, NULL, 0);
+       tls_config_set_crl_mem(config, NULL, 0);
 }
 
 int
@@ -578,6 +580,20 @@ tls_config_set_ciphers(struct tls_config *config, const char *ciphers)
        return -1;
 }
 
+int
+tls_config_set_crl_file(struct tls_config *config, const char *crl_file)
+{
+       return tls_config_load_file(&config->error, "CRL", crl_file,
+           &config->crl_mem, &config->crl_len);
+}
+
+int
+tls_config_set_crl_mem(struct tls_config *config, const uint8_t *crl,
+    size_t len)
+{
+       return set_mem(&config->crl_mem, &config->crl_len, crl, len);
+}
+
 int
 tls_config_set_dheparams(struct tls_config *config, const char *params)
 {
index c0c5521..bed9d6e 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_internal.h,v 1.61 2017/06/22 18:03:57 jsing Exp $ */
+/* $OpenBSD: tls_internal.h,v 1.62 2017/07/06 17:12:22 jsing Exp $ */
 /*
  * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -84,6 +84,8 @@ struct tls_config {
        size_t ca_len;
        const char *ciphers;
        int ciphers_server;
+       char *crl_mem;
+       size_t crl_len;
        int dheparams;
        int ecdhecurve;
        struct tls_keypair *keypair;