int tls_keypair_set_cert_mem(struct tls_keypair *keypair, struct tls_error *error, const uint8_t *cert, size_t len) { if (tls_set_mem(&keypair->cert_mem, &keypair->cert_len, cert, len) == -1) return -1; return tls_keypair_pubkey_hash(keypair, error); }
int tls_keypair_set_cert_file(struct tls_keypair *keypair, struct tls_error *error, const char *cert_file) { if (tls_config_load_file(error, "certificate", cert_file, &keypair->cert_mem, &keypair->cert_len) == -1) return -1; return tls_keypair_pubkey_hash(keypair, error); }
int tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, struct tls_keypair *keypair, int required) { EVP_PKEY *pkey = NULL; BIO *bio = NULL; if (!required && keypair->cert_mem == NULL && keypair->key_mem == NULL) return(0); if (keypair->cert_mem != NULL) { if (keypair->cert_len > INT_MAX) { tls_set_errorx(ctx, "certificate too long"); goto err; } if (SSL_CTX_use_certificate_chain_mem(ssl_ctx, keypair->cert_mem, keypair->cert_len) != 1) { tls_set_errorx(ctx, "failed to load certificate"); goto err; } if (tls_keypair_pubkey_hash(keypair, &keypair->pubkey_hash) == -1) goto err; } if (keypair->key_mem != NULL) { if (keypair->key_len > INT_MAX) { tls_set_errorx(ctx, "key too long"); goto err; } if ((bio = BIO_new_mem_buf(keypair->key_mem, keypair->key_len)) == NULL) { tls_set_errorx(ctx, "failed to create buffer"); goto err; } if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb, NULL)) == NULL) { tls_set_errorx(ctx, "failed to read private key"); goto err; } if (keypair->pubkey_hash != NULL) { RSA *rsa; /* XXX only RSA for now for relayd privsep */ if ((rsa = EVP_PKEY_get1_RSA(pkey)) != NULL) { RSA_set_ex_data(rsa, 0, keypair->pubkey_hash); RSA_free(rsa); } } if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) { tls_set_errorx(ctx, "failed to load private key"); goto err; } BIO_free(bio); bio = NULL; EVP_PKEY_free(pkey); pkey = NULL; } if (!ctx->config->skip_private_key_check && SSL_CTX_check_private_key(ssl_ctx) != 1) { tls_set_errorx(ctx, "private/public key mismatch"); goto err; } return (0); err: EVP_PKEY_free(pkey); BIO_free(bio); return (1); }