diff options
Diffstat (limited to 'src/lib')
-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 | ||