diff options
author | eric <> | 2021-01-21 19:09:10 +0000 |
---|---|---|
committer | eric <> | 2021-01-21 19:09:10 +0000 |
commit | b6080b52f179de6a4d935e9b00d1daefb76f3f83 (patch) | |
tree | cef0da52413de065f06dfb4111338c722b5d63c9 /src/lib/libtls | |
parent | 56cb8632a04478fa825a640e148efb0caaea8105 (diff) | |
download | openbsd-b6080b52f179de6a4d935e9b00d1daefb76f3f83.tar.gz openbsd-b6080b52f179de6a4d935e9b00d1daefb76f3f83.tar.bz2 openbsd-b6080b52f179de6a4d935e9b00d1daefb76f3f83.zip |
Allow setting a keypair on a tls context without specifying the private
key, and fake it internally with the certificate public key instead.
It makes it easier for privsep engines like relayd that don't have to
use bogus keys anymore.
ok beck@ tb@ jsing@
Diffstat (limited to 'src/lib/libtls')
-rw-r--r-- | src/lib/libtls/Symbols.list | 1 | ||||
-rw-r--r-- | src/lib/libtls/tls.c | 84 | ||||
-rw-r--r-- | src/lib/libtls/tls_config.c | 14 | ||||
-rw-r--r-- | src/lib/libtls/tls_internal.h | 4 |
4 files changed, 77 insertions, 26 deletions
diff --git a/src/lib/libtls/Symbols.list b/src/lib/libtls/Symbols.list index e3fcb67fb3..42c039d294 100644 --- a/src/lib/libtls/Symbols.list +++ b/src/lib/libtls/Symbols.list | |||
@@ -45,6 +45,7 @@ tls_config_set_session_lifetime | |||
45 | tls_config_set_session_fd | 45 | tls_config_set_session_fd |
46 | tls_config_set_verify_depth | 46 | tls_config_set_verify_depth |
47 | tls_config_skip_private_key_check | 47 | tls_config_skip_private_key_check |
48 | tls_config_use_fake_private_key | ||
48 | tls_config_verify | 49 | tls_config_verify |
49 | tls_config_verify_client | 50 | tls_config_verify_client |
50 | tls_config_verify_client_optional | 51 | tls_config_verify_client_optional |
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c index 3d6723bbd9..02ddf447fb 100644 --- a/src/lib/libtls/tls.c +++ b/src/lib/libtls/tls.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls.c,v 1.85 2020/05/24 15:12:54 jsing Exp $ */ | 1 | /* $OpenBSD: tls.c,v 1.86 2021/01/21 19:09:10 eric Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -326,12 +326,69 @@ tls_cert_pubkey_hash(X509 *cert, char **hash) | |||
326 | return (rv); | 326 | return (rv); |
327 | } | 327 | } |
328 | 328 | ||
329 | static int | ||
330 | tls_keypair_to_pkey(struct tls *ctx, struct tls_keypair *keypair, EVP_PKEY **pkey) | ||
331 | { | ||
332 | BIO *bio = NULL; | ||
333 | X509 *x509 = NULL; | ||
334 | char *mem; | ||
335 | size_t len; | ||
336 | int ret = -1; | ||
337 | |||
338 | *pkey = NULL; | ||
339 | |||
340 | if (ctx->config->use_fake_private_key) { | ||
341 | mem = keypair->cert_mem; | ||
342 | len = keypair->cert_len; | ||
343 | } else { | ||
344 | mem = keypair->key_mem; | ||
345 | len = keypair->key_len; | ||
346 | } | ||
347 | |||
348 | if (mem == NULL) | ||
349 | return (0); | ||
350 | |||
351 | if (len > INT_MAX) { | ||
352 | tls_set_errorx(ctx, ctx->config->use_fake_private_key ? | ||
353 | "cert too long" : "key too long"); | ||
354 | goto err; | ||
355 | } | ||
356 | |||
357 | if ((bio = BIO_new_mem_buf(mem, len)) == NULL) { | ||
358 | tls_set_errorx(ctx, "failed to create buffer"); | ||
359 | goto err; | ||
360 | } | ||
361 | |||
362 | if (ctx->config->use_fake_private_key) { | ||
363 | if ((x509 = PEM_read_bio_X509(bio, NULL, tls_password_cb, | ||
364 | NULL)) == NULL) { | ||
365 | tls_set_errorx(ctx, "failed to read X509 certificate"); | ||
366 | goto err; | ||
367 | } | ||
368 | if ((*pkey = X509_get_pubkey(x509)) == NULL) { | ||
369 | tls_set_errorx(ctx, "failed to retrieve pubkey"); | ||
370 | goto err; | ||
371 | } | ||
372 | } else { | ||
373 | if ((*pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb, | ||
374 | NULL)) == NULL) { | ||
375 | tls_set_errorx(ctx, "failed to read private key"); | ||
376 | goto err; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | ret = 0; | ||
381 | err: | ||
382 | BIO_free(bio); | ||
383 | X509_free(x509); | ||
384 | return (ret); | ||
385 | } | ||
386 | |||
329 | int | 387 | int |
330 | tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | 388 | tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, |
331 | struct tls_keypair *keypair, int required) | 389 | struct tls_keypair *keypair, int required) |
332 | { | 390 | { |
333 | EVP_PKEY *pkey = NULL; | 391 | EVP_PKEY *pkey = NULL; |
334 | BIO *bio = NULL; | ||
335 | 392 | ||
336 | if (!required && | 393 | if (!required && |
337 | keypair->cert_mem == NULL && | 394 | keypair->cert_mem == NULL && |
@@ -351,23 +408,9 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | |||
351 | } | 408 | } |
352 | } | 409 | } |
353 | 410 | ||
354 | if (keypair->key_mem != NULL) { | 411 | if (tls_keypair_to_pkey(ctx, keypair, &pkey) == -1) |
355 | if (keypair->key_len > INT_MAX) { | 412 | goto err; |
356 | tls_set_errorx(ctx, "key too long"); | 413 | if (pkey != NULL) { |
357 | goto err; | ||
358 | } | ||
359 | |||
360 | if ((bio = BIO_new_mem_buf(keypair->key_mem, | ||
361 | keypair->key_len)) == NULL) { | ||
362 | tls_set_errorx(ctx, "failed to create buffer"); | ||
363 | goto err; | ||
364 | } | ||
365 | if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb, | ||
366 | NULL)) == NULL) { | ||
367 | tls_set_errorx(ctx, "failed to read private key"); | ||
368 | goto err; | ||
369 | } | ||
370 | |||
371 | if (keypair->pubkey_hash != NULL) { | 414 | if (keypair->pubkey_hash != NULL) { |
372 | RSA *rsa; | 415 | RSA *rsa; |
373 | /* XXX only RSA for now for relayd privsep */ | 416 | /* XXX only RSA for now for relayd privsep */ |
@@ -381,8 +424,6 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | |||
381 | tls_set_errorx(ctx, "failed to load private key"); | 424 | tls_set_errorx(ctx, "failed to load private key"); |
382 | goto err; | 425 | goto err; |
383 | } | 426 | } |
384 | BIO_free(bio); | ||
385 | bio = NULL; | ||
386 | EVP_PKEY_free(pkey); | 427 | EVP_PKEY_free(pkey); |
387 | pkey = NULL; | 428 | pkey = NULL; |
388 | } | 429 | } |
@@ -397,7 +438,6 @@ tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, | |||
397 | 438 | ||
398 | err: | 439 | err: |
399 | EVP_PKEY_free(pkey); | 440 | EVP_PKEY_free(pkey); |
400 | BIO_free(bio); | ||
401 | 441 | ||
402 | return (1); | 442 | return (1); |
403 | } | 443 | } |
diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c index 7a0d6d8adf..e3e90aaa00 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.61 2020/12/22 13:07:54 bcook Exp $ */ | 1 | /* $OpenBSD: tls_config.c,v 1.62 2021/01/21 19:09:10 eric Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -353,7 +353,8 @@ tls_config_add_keypair_file_internal(struct tls_config *config, | |||
353 | return (-1); | 353 | return (-1); |
354 | if (tls_keypair_set_cert_file(keypair, &config->error, cert_file) != 0) | 354 | if (tls_keypair_set_cert_file(keypair, &config->error, cert_file) != 0) |
355 | goto err; | 355 | goto err; |
356 | if (tls_keypair_set_key_file(keypair, &config->error, key_file) != 0) | 356 | if (key_file != NULL && |
357 | tls_keypair_set_key_file(keypair, &config->error, key_file) != 0) | ||
357 | goto err; | 358 | goto err; |
358 | if (ocsp_file != NULL && | 359 | if (ocsp_file != NULL && |
359 | tls_keypair_set_ocsp_staple_file(keypair, &config->error, | 360 | tls_keypair_set_ocsp_staple_file(keypair, &config->error, |
@@ -380,7 +381,8 @@ tls_config_add_keypair_mem_internal(struct tls_config *config, const uint8_t *ce | |||
380 | return (-1); | 381 | return (-1); |
381 | if (tls_keypair_set_cert_mem(keypair, &config->error, cert, cert_len) != 0) | 382 | if (tls_keypair_set_cert_mem(keypair, &config->error, cert, cert_len) != 0) |
382 | goto err; | 383 | goto err; |
383 | if (tls_keypair_set_key_mem(keypair, &config->error, key, key_len) != 0) | 384 | if (key != NULL && |
385 | tls_keypair_set_key_mem(keypair, &config->error, key, key_len) != 0) | ||
384 | goto err; | 386 | goto err; |
385 | if (staple != NULL && | 387 | if (staple != NULL && |
386 | tls_keypair_set_ocsp_staple_mem(keypair, &config->error, staple, | 388 | tls_keypair_set_ocsp_staple_mem(keypair, &config->error, staple, |
@@ -805,6 +807,12 @@ tls_config_skip_private_key_check(struct tls_config *config) | |||
805 | config->skip_private_key_check = 1; | 807 | config->skip_private_key_check = 1; |
806 | } | 808 | } |
807 | 809 | ||
810 | void | ||
811 | tls_config_use_fake_private_key(struct tls_config *config) | ||
812 | { | ||
813 | config->use_fake_private_key = 1; | ||
814 | } | ||
815 | |||
808 | int | 816 | int |
809 | tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file) | 817 | tls_config_set_ocsp_staple_file(struct tls_config *config, const char *staple_file) |
810 | { | 818 | { |
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h index 1dd5f45ddd..5487b123ec 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.77 2019/11/16 21:39:52 beck Exp $ */ | 1 | /* $OpenBSD: tls_internal.h,v 1.78 2021/01/21 19:09:10 eric 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> |
@@ -111,6 +111,7 @@ struct tls_config { | |||
111 | int verify_name; | 111 | int verify_name; |
112 | int verify_time; | 112 | int verify_time; |
113 | int skip_private_key_check; | 113 | int skip_private_key_check; |
114 | int use_fake_private_key; | ||
114 | }; | 115 | }; |
115 | 116 | ||
116 | struct tls_conninfo { | 117 | struct tls_conninfo { |
@@ -294,5 +295,6 @@ __END_HIDDEN_DECLS | |||
294 | 295 | ||
295 | /* XXX this function is not fully hidden so relayd can use it */ | 296 | /* XXX this function is not fully hidden so relayd can use it */ |
296 | void tls_config_skip_private_key_check(struct tls_config *config); | 297 | void tls_config_skip_private_key_check(struct tls_config *config); |
298 | void tls_config_use_fake_private_key(struct tls_config *config); | ||
297 | 299 | ||
298 | #endif /* HEADER_TLS_INTERNAL_H */ | 300 | #endif /* HEADER_TLS_INTERNAL_H */ |