diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libtls/Symbols.list | 1 | ||||
| -rw-r--r-- | src/lib/libtls/tls.c | 67 | ||||
| -rw-r--r-- | src/lib/libtls/tls_config.c | 9 | ||||
| -rw-r--r-- | src/lib/libtls/tls_conninfo.c | 32 | ||||
| -rw-r--r-- | src/lib/libtls/tls_internal.h | 7 |
5 files changed, 87 insertions, 29 deletions
diff --git a/src/lib/libtls/Symbols.list b/src/lib/libtls/Symbols.list index eb704ecbd2..98465dde27 100644 --- a/src/lib/libtls/Symbols.list +++ b/src/lib/libtls/Symbols.list | |||
| @@ -40,6 +40,7 @@ tls_config_set_protocols | |||
| 40 | tls_config_set_session_id | 40 | tls_config_set_session_id |
| 41 | tls_config_set_session_lifetime | 41 | tls_config_set_session_lifetime |
| 42 | tls_config_set_verify_depth | 42 | tls_config_set_verify_depth |
| 43 | tls_config_skip_private_key_check | ||
| 43 | tls_config_verify | 44 | tls_config_verify |
| 44 | tls_config_verify_client | 45 | tls_config_verify_client |
| 45 | tls_config_verify_client_optional | 46 | tls_config_verify_client_optional |
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c index 9b03c2b6f0..419554818c 100644 --- a/src/lib/libtls/tls.c +++ b/src/lib/libtls/tls.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls.c,v 1.59 2017/01/26 12:56:37 jsing Exp $ */ | 1 | /* $OpenBSD: tls.c,v 1.60 2017/04/05 03:13:53 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -252,6 +252,55 @@ tls_configure(struct tls *ctx, struct tls_config *config) | |||
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | int | 254 | int |
| 255 | tls_cert_hash(X509 *cert, char **hash) | ||
| 256 | { | ||
| 257 | char d[EVP_MAX_MD_SIZE], *dhex = NULL; | ||
| 258 | int dlen, rv = -1; | ||
| 259 | |||
| 260 | *hash = NULL; | ||
| 261 | if (X509_digest(cert, EVP_sha256(), d, &dlen) != 1) | ||
| 262 | goto err; | ||
| 263 | |||
| 264 | if (tls_hex_string(d, dlen, &dhex, NULL) != 0) | ||
| 265 | goto err; | ||
| 266 | |||
| 267 | if (asprintf(hash, "SHA256:%s", dhex) == -1) { | ||
| 268 | *hash = NULL; | ||
| 269 | goto err; | ||
| 270 | } | ||
| 271 | |||
| 272 | rv = 0; | ||
| 273 | err: | ||
| 274 | free(dhex); | ||
| 275 | |||
| 276 | return (rv); | ||
| 277 | } | ||
| 278 | |||
| 279 | static int | ||
| 280 | tls_keypair_cert_hash(struct tls_keypair *keypair, char **hash) | ||
| 281 | { | ||
| 282 | BIO *membio = NULL; | ||
| 283 | X509 *cert = NULL; | ||
| 284 | int rv = -1; | ||
| 285 | |||
| 286 | *hash = NULL; | ||
| 287 | |||
| 288 | if ((membio = BIO_new_mem_buf(keypair->cert_mem, keypair->cert_len)) | ||
| 289 | == NULL) | ||
| 290 | goto err; | ||
| 291 | |||
| 292 | if ((cert = PEM_read_bio_X509_AUX(membio, NULL, NULL, NULL)) == NULL) | ||
| 293 | goto err; | ||
| 294 | |||
| 295 | rv = tls_cert_hash(cert, hash); | ||
| 296 | err: | ||
| 297 | BIO_free(membio); | ||
| 298 | |||
| 299 | return (rv); | ||
| 300 | } | ||
| 301 | |||
| 302 | |||
| 303 | int | ||
| 255 | tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | 304 | tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, |
| 256 | struct tls_keypair *keypair, int required) | 305 | struct tls_keypair *keypair, int required) |
| 257 | { | 306 | { |
| @@ -275,8 +324,11 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | |||
| 275 | tls_set_errorx(ctx, "failed to load certificate"); | 324 | tls_set_errorx(ctx, "failed to load certificate"); |
| 276 | goto err; | 325 | goto err; |
| 277 | } | 326 | } |
| 327 | if (tls_keypair_cert_hash(keypair, &keypair->cert_hash) == -1) | ||
| 328 | goto err; | ||
| 278 | cert = NULL; | 329 | cert = NULL; |
| 279 | } | 330 | } |
| 331 | |||
| 280 | if (keypair->key_mem != NULL) { | 332 | if (keypair->key_mem != NULL) { |
| 281 | if (keypair->key_len > INT_MAX) { | 333 | if (keypair->key_len > INT_MAX) { |
| 282 | tls_set_errorx(ctx, "key too long"); | 334 | tls_set_errorx(ctx, "key too long"); |
| @@ -293,6 +345,16 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | |||
| 293 | tls_set_errorx(ctx, "failed to read private key"); | 345 | tls_set_errorx(ctx, "failed to read private key"); |
| 294 | goto err; | 346 | goto err; |
| 295 | } | 347 | } |
| 348 | |||
| 349 | if (keypair->cert_hash != NULL) { | ||
| 350 | RSA *rsa; | ||
| 351 | /* XXX only RSA for now for relayd privsep */ | ||
| 352 | if ((rsa = EVP_PKEY_get1_RSA(pkey)) != NULL) { | ||
| 353 | RSA_set_ex_data(rsa, 0, keypair->cert_hash); | ||
| 354 | RSA_free(rsa); | ||
| 355 | } | ||
| 356 | } | ||
| 357 | |||
| 296 | if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) { | 358 | if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) { |
| 297 | tls_set_errorx(ctx, "failed to load private key"); | 359 | tls_set_errorx(ctx, "failed to load private key"); |
| 298 | goto err; | 360 | goto err; |
| @@ -303,7 +365,8 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | |||
| 303 | pkey = NULL; | 365 | pkey = NULL; |
| 304 | } | 366 | } |
| 305 | 367 | ||
| 306 | if (SSL_CTX_check_private_key(ssl_ctx) != 1) { | 368 | if (!ctx->config->skip_private_key_check && |
| 369 | SSL_CTX_check_private_key(ssl_ctx) != 1) { | ||
| 307 | tls_set_errorx(ctx, "private/public key mismatch"); | 370 | tls_set_errorx(ctx, "private/public key mismatch"); |
| 308 | goto err; | 371 | goto err; |
| 309 | } | 372 | } |
diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c index 87c2166f9e..f5e0bf55e4 100644 --- a/src/lib/libtls/tls_config.c +++ b/src/lib/libtls/tls_config.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls_config.c,v 1.36 2017/01/31 16:18:57 beck Exp $ */ | 1 | /* $OpenBSD: tls_config.c,v 1.37 2017/04/05 03:13:53 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -135,6 +135,7 @@ tls_keypair_free(struct tls_keypair *keypair) | |||
| 135 | free(keypair->cert_mem); | 135 | free(keypair->cert_mem); |
| 136 | free(keypair->key_mem); | 136 | free(keypair->key_mem); |
| 137 | free(keypair->ocsp_staple); | 137 | free(keypair->ocsp_staple); |
| 138 | free(keypair->cert_hash); | ||
| 138 | 139 | ||
| 139 | free(keypair); | 140 | free(keypair); |
| 140 | } | 141 | } |
| @@ -761,6 +762,12 @@ tls_config_verify_client_optional(struct tls_config *config) | |||
| 761 | config->verify_client = 2; | 762 | config->verify_client = 2; |
| 762 | } | 763 | } |
| 763 | 764 | ||
| 765 | void | ||
| 766 | tls_config_skip_private_key_check(struct tls_config *config) | ||
| 767 | { | ||
| 768 | config->skip_private_key_check = 1; | ||
| 769 | } | ||
| 770 | |||
| 764 | int | 771 | int |
| 765 | tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file) | 772 | tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file) |
| 766 | { | 773 | { |
diff --git a/src/lib/libtls/tls_conninfo.c b/src/lib/libtls/tls_conninfo.c index 5cdd0f77c8..c4d23c308b 100644 --- a/src/lib/libtls/tls_conninfo.c +++ b/src/lib/libtls/tls_conninfo.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls_conninfo.c,v 1.13 2017/01/09 15:31:20 jsing Exp $ */ | 1 | /* $OpenBSD: tls_conninfo.c,v 1.14 2017/04/05 03:13:53 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2015 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2015 Joel Sing <jsing@openbsd.org> |
| 4 | * Copyright (c) 2015 Bob Beck <beck@openbsd.org> | 4 | * Copyright (c) 2015 Bob Beck <beck@openbsd.org> |
| @@ -23,7 +23,7 @@ | |||
| 23 | #include <tls.h> | 23 | #include <tls.h> |
| 24 | #include "tls_internal.h" | 24 | #include "tls_internal.h" |
| 25 | 25 | ||
| 26 | static int | 26 | int |
| 27 | tls_hex_string(const unsigned char *in, size_t inlen, char **out, | 27 | tls_hex_string(const unsigned char *in, size_t inlen, char **out, |
| 28 | size_t *outlen) | 28 | size_t *outlen) |
| 29 | { | 29 | { |
| @@ -56,35 +56,16 @@ tls_hex_string(const unsigned char *in, size_t inlen, char **out, | |||
| 56 | static int | 56 | static int |
| 57 | tls_get_peer_cert_hash(struct tls *ctx, char **hash) | 57 | tls_get_peer_cert_hash(struct tls *ctx, char **hash) |
| 58 | { | 58 | { |
| 59 | char d[EVP_MAX_MD_SIZE], *dhex = NULL; | ||
| 60 | int dlen, rv = -1; | ||
| 61 | |||
| 62 | *hash = NULL; | 59 | *hash = NULL; |
| 63 | if (ctx->ssl_peer_cert == NULL) | 60 | if (ctx->ssl_peer_cert == NULL) |
| 64 | return (0); | 61 | return (0); |
| 65 | 62 | ||
| 66 | if (X509_digest(ctx->ssl_peer_cert, EVP_sha256(), d, &dlen) != 1) { | 63 | if (tls_cert_hash(ctx->ssl_peer_cert, hash) == -1) { |
| 67 | tls_set_errorx(ctx, "digest failed"); | 64 | tls_set_errorx(ctx, "unable to compute peer certificate hash - out of memory"); |
| 68 | goto err; | ||
| 69 | } | ||
| 70 | |||
| 71 | if (tls_hex_string(d, dlen, &dhex, NULL) != 0) { | ||
| 72 | tls_set_errorx(ctx, "digest hex string failed"); | ||
| 73 | goto err; | ||
| 74 | } | ||
| 75 | |||
| 76 | if (asprintf(hash, "SHA256:%s", dhex) == -1) { | ||
| 77 | tls_set_errorx(ctx, "out of memory"); | ||
| 78 | *hash = NULL; | 65 | *hash = NULL; |
| 79 | goto err; | 66 | return -1; |
| 80 | } | 67 | } |
| 81 | 68 | return 0; | |
| 82 | rv = 0; | ||
| 83 | |||
| 84 | err: | ||
| 85 | free(dhex); | ||
| 86 | |||
| 87 | return (rv); | ||
| 88 | } | 69 | } |
| 89 | 70 | ||
| 90 | static int | 71 | static int |
| @@ -294,3 +275,4 @@ tls_conn_version(struct tls *ctx) | |||
| 294 | return (NULL); | 275 | return (NULL); |
| 295 | return (ctx->conninfo->version); | 276 | return (ctx->conninfo->version); |
| 296 | } | 277 | } |
| 278 | |||
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h index fbb139c84a..b1d53c8fa3 100644 --- a/src/lib/libtls/tls_internal.h +++ b/src/lib/libtls/tls_internal.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls_internal.h,v 1.53 2017/01/29 17:52:11 beck Exp $ */ | 1 | /* $OpenBSD: tls_internal.h,v 1.54 2017/04/05 03:13:53 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> | 3 | * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> |
| 4 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 4 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
| @@ -53,6 +53,7 @@ struct tls_keypair { | |||
| 53 | size_t key_len; | 53 | size_t key_len; |
| 54 | char *ocsp_staple; | 54 | char *ocsp_staple; |
| 55 | size_t ocsp_staple_len; | 55 | size_t ocsp_staple_len; |
| 56 | char *cert_hash; | ||
| 56 | }; | 57 | }; |
| 57 | 58 | ||
| 58 | #define TLS_MIN_SESSION_TIMEOUT (4) | 59 | #define TLS_MIN_SESSION_TIMEOUT (4) |
| @@ -96,6 +97,7 @@ struct tls_config { | |||
| 96 | int verify_depth; | 97 | int verify_depth; |
| 97 | int verify_name; | 98 | int verify_name; |
| 98 | int verify_time; | 99 | int verify_time; |
| 100 | int skip_private_key_check; | ||
| 99 | }; | 101 | }; |
| 100 | 102 | ||
| 101 | struct tls_conninfo { | 103 | struct tls_conninfo { |
| @@ -232,6 +234,9 @@ int tls_ocsp_verify_cb(SSL *ssl, void *arg); | |||
| 232 | int tls_ocsp_stapling_cb(SSL *ssl, void *arg); | 234 | int tls_ocsp_stapling_cb(SSL *ssl, void *arg); |
| 233 | void tls_ocsp_free(struct tls_ocsp *ctx); | 235 | void tls_ocsp_free(struct tls_ocsp *ctx); |
| 234 | struct tls_ocsp *tls_ocsp_setup_from_peer(struct tls *ctx); | 236 | struct tls_ocsp *tls_ocsp_setup_from_peer(struct tls *ctx); |
| 237 | int tls_hex_string(const unsigned char *_in, size_t _inlen, char **_out, | ||
| 238 | size_t *_outlen); | ||
| 239 | int tls_cert_hash(X509 *_cert, char **_hash); | ||
| 235 | 240 | ||
| 236 | __END_HIDDEN_DECLS | 241 | __END_HIDDEN_DECLS |
| 237 | 242 | ||
