Refactored certificate generation

This commit is contained in:
Thorsten Sommer 2024-11-05 20:57:03 +01:00
parent e0a2906655
commit d96b168ee6
Signed by: tsommer
GPG Key ID: 371BBA77A02C0108
4 changed files with 42 additions and 19 deletions

View File

@ -0,0 +1,32 @@
use std::sync::OnceLock;
use log::info;
use rcgen::generate_simple_self_signed;
use sha2::{Sha256, Digest};
pub static CERTIFICATE: OnceLock<Vec<u8>> = OnceLock::new();
pub static CERTIFICATE_PRIVATE_KEY: OnceLock<Vec<u8>> = OnceLock::new();
pub static CERTIFICATE_FINGERPRINT: OnceLock<String> = OnceLock::new();
pub fn generate_certificate() {
info!("Try to generate a TLS certificate for the runtime API server...");
let subject_alt_names = vec!["localhost".to_string()];
let certificate_data = generate_simple_self_signed(subject_alt_names).unwrap();
let certificate_binary_data = certificate_data.cert.der().to_vec();
let certificate_fingerprint = Sha256::digest(certificate_binary_data).to_vec();
let certificate_fingerprint = certificate_fingerprint.iter().fold(String::new(), |mut result, byte| {
result.push_str(&format!("{:02x}", byte));
result
});
let certificate_fingerprint = certificate_fingerprint.to_uppercase();
CERTIFICATE_FINGERPRINT.set(certificate_fingerprint.clone()).expect("Could not set the certificate fingerprint.");
CERTIFICATE.set(certificate_data.cert.pem().as_bytes().to_vec()).expect("Could not set the certificate.");
CERTIFICATE_PRIVATE_KEY.set(certificate_data.key_pair.serialize_pem().as_bytes().to_vec()).expect("Could not set the private key.");
info!("Certificate fingerprint: '{certificate_fingerprint}'.");
info!("Done generating certificate for the runtime API server.");
}

View File

@ -9,6 +9,7 @@ use tauri::api::process::{Command, CommandChild, CommandEvent};
use tauri::Url;
use crate::api_token::{APIToken, API_TOKEN};
use crate::app_window::change_location_to;
use crate::certificate::CERTIFICATE_FINGERPRINT;
use crate::encryption::ENCRYPTION;
use crate::environment::is_dev;
use crate::network::get_available_port;
@ -30,7 +31,7 @@ pub fn dotnet_port(_token: APIToken) -> String {
format!("{dotnet_server_port}")
}
pub fn start_dotnet_server(api_server_port: u16, certificate_fingerprint: String) {
pub fn start_dotnet_server(api_server_port: u16) {
// Get the secret password & salt and convert it to a base64 string:
let secret_password = BASE64_STANDARD.encode(ENCRYPTION.secret_password);
@ -39,7 +40,7 @@ pub fn start_dotnet_server(api_server_port: u16, certificate_fingerprint: String
let dotnet_server_environment = HashMap::from_iter([
(String::from("AI_STUDIO_SECRET_PASSWORD"), secret_password),
(String::from("AI_STUDIO_SECRET_KEY_SALT"), secret_key_salt),
(String::from("AI_STUDIO_CERTIFICATE_FINGERPRINT"), certificate_fingerprint),
(String::from("AI_STUDIO_CERTIFICATE_FINGERPRINT"), CERTIFICATE_FINGERPRINT.get().unwrap().to_string()),
(String::from("AI_STUDIO_API_TOKEN"), API_TOKEN.to_hex_text().to_string()),
]);

View File

@ -6,4 +6,5 @@ pub mod network;
pub mod api_token;
pub mod app_window;
pub mod secret;
pub mod clipboard;
pub mod clipboard;
pub mod certificate;

View File

@ -14,6 +14,7 @@ use rocket::routes;
use rocket::config::{Shutdown};
use sha2::{Sha256, Digest};
use mindwork_ai_studio::app_window::start_tauri;
use mindwork_ai_studio::certificate::{generate_certificate, CERTIFICATE, CERTIFICATE_PRIVATE_KEY};
use mindwork_ai_studio::dotnet::start_dotnet_server;
use mindwork_ai_studio::environment::is_dev;
use mindwork_ai_studio::log::init_logging;
@ -66,19 +67,7 @@ async fn main() {
info!("Running in production mode.");
}
info!("Try to generate a TLS certificate for the runtime API server...");
let subject_alt_names = vec!["localhost".to_string()];
let certificate_data = generate_simple_self_signed(subject_alt_names).unwrap();
let certificate_binary_data = certificate_data.cert.der().to_vec();
let certificate_fingerprint = Sha256::digest(certificate_binary_data).to_vec();
let certificate_fingerprint = certificate_fingerprint.iter().fold(String::new(), |mut result, byte| {
result.push_str(&format!("{:02x}", byte));
result
});
let certificate_fingerprint = certificate_fingerprint.to_uppercase();
info!("Certificate fingerprint: '{certificate_fingerprint}'.");
info!("Done generating certificate for the runtime API server.");
generate_certificate();
let api_port = *API_SERVER_PORT;
info!("Try to start the API server on 'http://localhost:{api_port}'...");
@ -122,8 +111,8 @@ async fn main() {
.merge(("cli_colors", false))
// Read the TLS certificate and key from the generated certificate data in-memory:
.merge(("tls.certs", certificate_data.cert.pem().as_bytes()))
.merge(("tls.key", certificate_data.key_pair.serialize_pem().as_bytes()))
.merge(("tls.certs", CERTIFICATE.get().unwrap()))
.merge(("tls.key", CERTIFICATE_PRIVATE_KEY.get().unwrap()))
// Set the shutdown configuration:
.merge(("shutdown", shutdown));
@ -152,6 +141,6 @@ async fn main() {
});
info!("Secret password for the IPC channel was generated successfully.");
start_dotnet_server(*API_SERVER_PORT, certificate_fingerprint);
start_dotnet_server(*API_SERVER_PORT);
start_tauri();
}