0
0
Fork 0
mirror of https://git.verdigado.com/NB-Public/simple-wkd.git synced 2024-10-30 03:05:51 +01:00

Check if uploaded key contains secret material

This commit is contained in:
Delta1925 2023-05-20 23:28:17 +02:00
parent 1636a97e15
commit d9b722397c
No known key found for this signature in database
GPG key ID: 1C21ACE44193CB25
4 changed files with 17 additions and 10 deletions

View file

@ -6,7 +6,7 @@ use crate::errors::SpecialErrors;
use crate::management::{delete_key, Action, Pending}; use crate::management::{delete_key, Action, Pending};
use crate::settings::{MAILER, SETTINGS}; use crate::settings::{MAILER, SETTINGS};
use crate::utils::{get_email_from_cert, insert_key, parse_pem, read_file}; use crate::utils::{get_email_from_cert, insert_key, parse_pem, read_file};
use crate::{log_err, pending_path}; use crate::{log_err, pending_path, validate_cert};
use anyhow::Result; use anyhow::Result;
use lettre::{AsyncTransport, Message}; use lettre::{AsyncTransport, Message};
@ -25,8 +25,9 @@ pub fn confirm_action(token: &str) -> Result<(Action, String)> {
let address = match key.action() { let address = match key.action() {
Action::Add => { Action::Add => {
let cert = parse_pem(key.data())?; let cert = parse_pem(key.data())?;
let email = get_email_from_cert(&cert)?; let validcert = validate_cert!(cert)?;
log_err!(insert_key(&cert), warn)?; let email = get_email_from_cert(&validcert)?;
log_err!(insert_key(&validcert), warn)?;
email email
} }
Action::Delete => { Action::Delete => {

View file

@ -36,6 +36,8 @@ macro_rules! log_err {
#[derive(Debug, DeriveError)] #[derive(Debug, DeriveError)]
pub enum SpecialErrors { pub enum SpecialErrors {
#[error("Uploaded certificate contains a secret key!")]
ContainsSecret,
#[error("Could not find any primay user email in the keyblock!")] #[error("Could not find any primay user email in the keyblock!")]
EmailMissing, EmailMissing,
#[error("The request had expired!")] #[error("The request had expired!")]
@ -92,6 +94,7 @@ impl ResponseError for CompatErr {
match self { match self {
Self::AnyhowErr(_) => StatusCode::INTERNAL_SERVER_ERROR, Self::AnyhowErr(_) => StatusCode::INTERNAL_SERVER_ERROR,
Self::SpecialErr(error) => match error { Self::SpecialErr(error) => match error {
SpecialErrors::ContainsSecret => StatusCode::BAD_REQUEST,
SpecialErrors::ExpiredRequest => StatusCode::BAD_REQUEST, SpecialErrors::ExpiredRequest => StatusCode::BAD_REQUEST,
SpecialErrors::InexistingUser => StatusCode::NOT_FOUND, SpecialErrors::InexistingUser => StatusCode::NOT_FOUND,
SpecialErrors::InvalidCert => StatusCode::BAD_REQUEST, SpecialErrors::InvalidCert => StatusCode::BAD_REQUEST,

View file

@ -101,7 +101,11 @@ async fn index(req: HttpRequest) -> Result<HttpResponse, CompatErr> {
#[post("/api/submit")] #[post("/api/submit")]
async fn submit(pem: web::Form<Key>) -> Result<HttpResponse, CompatErr> { async fn submit(pem: web::Form<Key>) -> Result<HttpResponse, CompatErr> {
let cert = parse_pem(&pem.key)?; let cert = parse_pem(&pem.key)?;
let email = get_email_from_cert(&cert)?; let validcert = validate_cert!(cert)?;
if validcert.is_tsk() {
Err(SpecialErrors::ContainsSecret)?
}
let email = get_email_from_cert(&validcert)?;
debug!("Handling user {} request to add a key...", email); debug!("Handling user {} request to add a key...", email);
is_email_allowed(&email)?; is_email_allowed(&email)?;
let token = gen_random_token(); let token = gen_random_token();

View file

@ -15,6 +15,7 @@ use flexi_logger::{style, DeferredNow, FileSpec, FlexiLoggerError, Logger, Logge
use log::debug; use log::debug;
use log::error; use log::error;
use rand::{distributions::Alphanumeric, thread_rng, Rng}; use rand::{distributions::Alphanumeric, thread_rng, Rng};
use sequoia_openpgp::cert::ValidCert;
use sequoia_openpgp::serialize::Marshal; use sequoia_openpgp::serialize::Marshal;
use sequoia_openpgp::types::HashAlgorithm; use sequoia_openpgp::types::HashAlgorithm;
use sequoia_openpgp::{parse::Parse, Cert}; use sequoia_openpgp::{parse::Parse, Cert};
@ -59,13 +60,12 @@ pub fn email_to_file_path(email: &str) -> Result<PathBuf> {
Ok(PathBuf::from(ROOT_FOLDER).join(directory)) Ok(PathBuf::from(ROOT_FOLDER).join(directory))
} }
pub fn insert_key(cert: &Cert) -> Result<()> { pub fn insert_key(cert: &ValidCert) -> Result<()> {
let validcert = validate_cert!(cert)?;
let path = email_to_file_path(&get_email_from_cert(cert)?)?; let path = email_to_file_path(&get_email_from_cert(cert)?)?;
fs::create_dir_all(path.parent().unwrap())?; fs::create_dir_all(path.parent().unwrap())?;
let mut file = fs::File::create(&path)?; let mut file = fs::File::create(&path)?;
validcert.export(&mut file)?; cert.export(&mut file)?;
fs::OpenOptions::new() fs::OpenOptions::new()
.write(true) .write(true)
@ -115,9 +115,8 @@ pub fn gen_random_token() -> String {
(0..10).map(|_| rng.sample(Alphanumeric) as char).collect() (0..10).map(|_| rng.sample(Alphanumeric) as char).collect()
} }
pub fn get_email_from_cert(cert: &Cert) -> Result<String> { pub fn get_email_from_cert(cert: &ValidCert) -> Result<String> {
let validcert = validate_cert!(cert)?; let userid_opt = log_err!(cert.primary_userid(), debug)?;
let userid_opt = log_err!(validcert.primary_userid(), debug)?;
let email_opt = userid_opt.email()?; let email_opt = userid_opt.email()?;
match email_opt { match email_opt {
Some(email) => Ok(email), Some(email) => Ok(email),