Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions proxy/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use regex::Regex;
use reqwest::Url;
use rsa::{pkcs1::DecodeRsaPrivateKey, pkcs8::DecodePrivateKey, RsaPrivateKey};
use shared::{errors::SamplyBeamError, jwt_simple::prelude::RS256KeyPair, logger::LogOptions, openssl::x509::X509, reqwest};
use tokio::sync::RwLock;

use std::{
collections::HashMap,
Expand All @@ -11,6 +12,7 @@ use std::{
path::{Path, PathBuf},
process::exit,
str::FromStr,
sync::Arc,
};

use axum::http::HeaderValue;
Expand All @@ -33,10 +35,25 @@ pub struct Config {

#[derive(Debug, Clone)]
pub struct ConfigCrypto {
pub privkey_rs256: RS256KeyPair,
pub privkey_rs256: Arc<RwLock<RS256KeyPair>>,
pub privkey_rsa: RsaPrivateKey,
}

impl ConfigCrypto {
pub async fn reload_public_key_id(&self, config: &Config) -> Result<(), SamplyBeamError> {
let mut key_id = self.privkey_rs256.write().await;
let new = crate::crypto::load_public_crypto_for_proxy(
&*key_id,
self.privkey_rsa.clone(),
&config.proxy_id,
)
.await?
.1;
*key_id = Arc::into_inner(new.privkey_rs256).unwrap().into_inner();
Ok(())
}
}

pub type ApiKey = String;

#[derive(Parser, Debug)]
Expand Down Expand Up @@ -167,7 +184,7 @@ fn load_private_crypto_for_proxy(privkey_file: &PathBuf, proxy_id: &ProxyId) ->
))
})?;
Ok(ConfigCrypto {
privkey_rs256,
privkey_rs256: Arc::new(RwLock::new(privkey_rs256)),
privkey_rsa,
})
}
Expand Down
26 changes: 17 additions & 9 deletions proxy/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use axum::{body::Bytes, http::{header, request, Method, Request, StatusCode, Uri
use beam_lib::{AppOrProxyId, ProxyId};
use rsa::{pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}, pkcs8::DecodePrivateKey, RsaPrivateKey, RsaPublicKey};
use shared::{
async_trait, crypto::{self, asn_str_to_vault_str, get_all_certs_and_clients_by_cname_as_pemstr, get_best_own_certificate, x509_cert_to_x509_public_key, CryptoPublicPortion, GetCerts, ProxyCertInfo}, errors::{CertificateInvalidReason, SamplyBeamError}, http_client::SamplyHttpClient, jwt_simple::prelude::RS256KeyPair, openssl::x509::X509, reqwest, EncryptedMessage, MsgEmpty
EncryptedMessage, MsgEmpty, async_trait, crypto::{self, CryptoPublicPortion, GetCerts, ProxyCertInfo, asn_str_to_vault_str, get_all_certs_and_clients_by_cname_as_pemstr, get_best_own_certificate, x509_cert_to_x509_public_key}, errors::{CertificateInvalidReason, SamplyBeamError}, http_client::SamplyHttpClient, jwt_simple::algorithms::RS256KeyPair, openssl::{pkey::Private, x509::X509}, reqwest
};
use tracing::{debug, info, warn, error};

Expand Down Expand Up @@ -39,7 +39,7 @@ impl GetCertsFromBroker {
.expect("To build request successfully")
.into_parts();

let req = sign_request(body, parts, &self.config)
let req = sign_request(&body, parts, &self.config)
.await
.map_err(|(_, msg)| SamplyBeamError::SignEncryptError(msg.into()))?;
Ok(self.client.execute(req).await?.into())
Expand Down Expand Up @@ -102,30 +102,38 @@ impl GetCerts for GetCertsFromBroker {
pub async fn init_public_crypto_for_proxy(
config: &Config
) -> Result<(ProxyCertInfo, config::ConfigCrypto), SamplyBeamError> {
let (public_info, new_crypto) = load_public_crypto_for_proxy(config).await?;
let (public_info, new_crypto) = load_public_crypto_for_proxy(
&*config.crypto.privkey_rs256.read().await,
config.crypto.privkey_rsa.clone(),
&config.proxy_id
).await?;

let cert_info = ProxyCertInfo::try_from(&public_info.cert)?;
Ok((cert_info, new_crypto))
}

pub async fn load_public_crypto_for_proxy(
config: &Config,
signer: &RS256KeyPair,
privkey_rsa: RsaPrivateKey,
proxy_id: &ProxyId,
) -> Result<(CryptoPublicPortion, config::ConfigCrypto), SamplyBeamError> {
let publics: Vec<CryptoPublicPortion> = get_all_certs_and_clients_by_cname_as_pemstr(&config.proxy_id)
let publics: Vec<CryptoPublicPortion> = get_all_certs_and_clients_by_cname_as_pemstr(proxy_id)
.await
.into_iter()
.filter_map(|r| {
r.map_err(|e| debug!("Unable to parse Certificate: {e}"))
.ok()
})
.collect();
let public = get_best_own_certificate(publics, &config.crypto.privkey_rsa).ok_or(
let public = get_best_own_certificate(publics, &privkey_rsa).ok_or(
SamplyBeamError::SignEncryptError(
"Unable to choose valid, newest certificate for this proxy".into(),
),
)?;
let serial = asn_str_to_vault_str(public.cert.serial_number())?;
let mut crypto_with_kid = config.crypto.clone();
crypto_with_kid.privkey_rs256 = crypto_with_kid.privkey_rs256.with_key_id(&serial);
let crypto_with_kid = config::ConfigCrypto {
privkey_rs256: std::sync::Arc::new(tokio::sync::RwLock::new(signer.clone().with_key_id(&serial))),
privkey_rsa,
};
Ok((public, crypto_with_kid))
}
}
2 changes: 1 addition & 1 deletion proxy/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ fn spawn_controller_polling(client: SamplyHttpClient, config: &'static Config) {
.expect("To build request successfully")
.into_parts();

let req = sign_request(body, parts, &config).await.expect("Unable to sign request; this should always work");
let req = sign_request(&body, parts, &config).await.expect("Unable to sign request; this should always work");
// In the future this will poll actual control related tasks
let res = match client.execute(req).await {
Ok(res) if res.status() == StatusCode::CONFLICT => {
Expand Down
Loading
Loading