-/* $OpenBSD: tls.c,v 1.44 2016/08/12 15:10:59 jsing Exp $ */
+/* $OpenBSD: tls.c,v 1.45 2016/08/13 13:05:51 jsing Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
if (!required &&
keypair->cert_mem == NULL &&
- keypair->key_mem == NULL &&
- keypair->cert_file == NULL &&
- keypair->key_file == NULL)
+ keypair->key_mem == NULL)
return(0);
if (keypair->cert_mem != NULL) {
pkey = NULL;
}
- if (keypair->cert_file != NULL) {
- if (SSL_CTX_use_certificate_chain_file(ssl_ctx,
- keypair->cert_file) != 1) {
- tls_set_errorx(ctx, "failed to load certificate file");
- goto err;
- }
- }
- if (keypair->key_file != NULL) {
- if (SSL_CTX_use_PrivateKey_file(ssl_ctx,
- keypair->key_file, SSL_FILETYPE_PEM) != 1) {
- tls_set_errorx(ctx, "failed to load private key file");
- goto err;
- }
- }
-
if (SSL_CTX_check_private_key(ssl_ctx) != 1) {
tls_set_errorx(ctx, "private/public key mismatch");
goto err;
int
tls_configure_ssl_verify(struct tls *ctx, int verify)
{
+ size_t ca_len = ctx->config->ca_len;
+ char *ca_mem = ctx->config->ca_mem;
+ char *ca_free = NULL;
+
SSL_CTX_set_verify(ctx->ssl_ctx, verify, NULL);
- if (ctx->config->ca_mem != NULL) {
- /* XXX do this in set. */
- if (ctx->config->ca_len > INT_MAX) {
+ /* If no CA has been specified, attempt to load the default. */
+ if (ctx->config->ca_mem == NULL && ctx->config->ca_path == NULL) {
+ if (tls_config_load_file(&ctx->error, "CA", _PATH_SSL_CA_FILE,
+ &ca_mem, &ca_len) != 0)
+ goto err;
+ ca_free = ca_mem;
+ }
+
+ if (ca_mem != NULL) {
+ if (ca_len > INT_MAX) {
tls_set_errorx(ctx, "ca too long");
goto err;
}
- if (SSL_CTX_load_verify_mem(ctx->ssl_ctx,
- ctx->config->ca_mem, ctx->config->ca_len) != 1) {
+ if (SSL_CTX_load_verify_mem(ctx->ssl_ctx, ca_mem,
+ ca_len) != 1) {
tls_set_errorx(ctx, "ssl verify memory setup failure");
goto err;
}
- } else if (SSL_CTX_load_verify_locations(ctx->ssl_ctx,
- ctx->config->ca_file, ctx->config->ca_path) != 1) {
- tls_set_errorx(ctx, "ssl verify setup failure");
+ } else if (SSL_CTX_load_verify_locations(ctx->ssl_ctx, NULL,
+ ctx->config->ca_path) != 1) {
+ tls_set_errorx(ctx, "ssl verify locations failure");
goto err;
}
if (ctx->config->verify_depth >= 0)
SSL_CTX_set_verify_depth(ctx->ssl_ctx,
ctx->config->verify_depth);
+ free(ca_free);
+
return (0);
err:
+ free(ca_free);
+
return (-1);
}
-/* $OpenBSD: tls_config.c,v 1.25 2016/08/12 15:10:59 jsing Exp $ */
+/* $OpenBSD: tls_config.c,v 1.26 2016/08/13 13:05:51 jsing Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/stat.h>
+
#include <ctype.h>
#include <errno.h>
+#include <fcntl.h>
#include <stdlib.h>
+#include <unistd.h>
#include <tls.h>
#include "tls_internal.h"
}
static int
-tls_keypair_set_cert_file(struct tls_keypair *keypair, const char *cert_file)
+tls_keypair_set_cert_file(struct tls_keypair *keypair, struct tls_error *error,
+ const char *cert_file)
{
- return set_string(&keypair->cert_file, cert_file);
+ return tls_config_load_file(error, "certificate", cert_file,
+ &keypair->cert_mem, &keypair->cert_len);
}
static int
}
static int
-tls_keypair_set_key_file(struct tls_keypair *keypair, const char *key_file)
+tls_keypair_set_key_file(struct tls_keypair *keypair, struct tls_error *error,
+ const char *key_file)
{
- return set_string(&keypair->key_file, key_file);
+ if (keypair->key_mem != NULL)
+ explicit_bzero(keypair->key_mem, keypair->key_len);
+ return tls_config_load_file(error, "key", key_file,
+ &keypair->key_mem, &keypair->key_len);
}
static int
tls_keypair_clear(keypair);
- free((char *)keypair->cert_file);
free(keypair->cert_mem);
- free((char *)keypair->key_file);
free(keypair->key_mem);
free(keypair);
}
+int
+tls_config_load_file(struct tls_error *error, const char *filetype,
+ const char *filename, char **buf, size_t *len)
+{
+ struct stat st;
+ int fd = -1;
+
+ free(*buf);
+ *buf = NULL;
+ *len = 0;
+
+ if ((fd = open(filename, O_RDONLY)) == -1) {
+ tls_error_set(error, "failed to open %s file '%s'",
+ filetype, filename);
+ goto fail;
+ }
+ if (fstat(fd, &st) != 0) {
+ tls_error_set(error, "failed to stat %s file '%s'",
+ filetype, filename);
+ goto fail;
+ }
+ *len = (size_t)st.st_size;
+ if ((*buf = malloc(*len)) == NULL) {
+ tls_error_set(error, "failed to allocate buffer for "
+ "%s file", filetype);
+ goto fail;
+ }
+ if (read(fd, *buf, *len) != *len) {
+ tls_error_set(error, "failed to read %s file '%s'",
+ filetype, filename);
+ goto fail;
+ }
+ close(fd);
+ return 0;
+
+ fail:
+ if (fd != -1)
+ close(fd);
+ if (*buf != NULL)
+ explicit_bzero(*buf, *len);
+ free(*buf);
+ *buf = NULL;
+ *len = 0;
+
+ return -1;
+}
+
struct tls_config *
tls_config_new(void)
{
/*
* Default configuration.
*/
- if (tls_config_set_ca_file(config, _PATH_SSL_CA_FILE) != 0)
- goto err;
if (tls_config_set_dheparams(config, "none") != 0)
goto err;
if (tls_config_set_ecdhecurve(config, "auto") != 0)
free(config->error.msg);
free(config->alpn);
- free((char *)config->ca_file);
free((char *)config->ca_mem);
free((char *)config->ca_path);
free((char *)config->ciphers);
int
tls_config_set_ca_file(struct tls_config *config, const char *ca_file)
{
- return set_string(&config->ca_file, ca_file);
+ return tls_config_load_file(&config->error, "CA", ca_file,
+ &config->ca_mem, &config->ca_len);
}
int
int
tls_config_set_cert_file(struct tls_config *config, const char *cert_file)
{
- return tls_keypair_set_cert_file(config->keypair, cert_file);
+ return tls_keypair_set_cert_file(config->keypair, &config->error,
+ cert_file);
}
int
int
tls_config_set_key_file(struct tls_config *config, const char *key_file)
{
- return tls_keypair_set_key_file(config->keypair, key_file);
+ return tls_keypair_set_key_file(config->keypair, &config->error,
+ key_file);
}
int
-/* $OpenBSD: tls_internal.h,v 1.35 2016/08/12 15:10:59 jsing Exp $ */
+/* $OpenBSD: tls_internal.h,v 1.36 2016/08/13 13:05:51 jsing Exp $ */
/*
* Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
struct tls_keypair {
struct tls_keypair *next;
- const char *cert_file;
char *cert_mem;
size_t cert_len;
- const char *key_file;
char *key_mem;
size_t key_len;
};
char *alpn;
size_t alpn_len;
- const char *ca_file;
const char *ca_path;
char *ca_mem;
size_t ca_len;
int tls_configure_server(struct tls *ctx);
int tls_configure_ssl(struct tls *ctx);
int tls_configure_ssl_verify(struct tls *ctx, int verify);
+
int tls_handshake_client(struct tls *ctx);
int tls_handshake_server(struct tls *ctx);
+
+int tls_config_load_file(struct tls_error *error, const char *filetype,
+ const char *filename, char **buf, size_t *len);
int tls_host_port(const char *hostport, char **host, char **port);
int tls_error_set(struct tls_error *error, const char *fmt, ...)