diff options
Diffstat (limited to 'src/lib/libtls/tls.c')
| -rw-r--r-- | src/lib/libtls/tls.c | 67 |
1 files changed, 65 insertions, 2 deletions
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 | } |
