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/tls.c | |
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/tls.c')
-rw-r--r-- | src/lib/libtls/tls.c | 84 |
1 files changed, 62 insertions, 22 deletions
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 | } |