sptp/certificate_request/
mod.rs1use std::str::FromStr;
2
3use argon2::{password_hash::PasswordHashString, Argon2, PasswordHash, PasswordVerifier};
4use rcgen::{Certificate, CertificateParams, CertificateSigningRequest, KeyPair};
5use serde::{Deserialize, Serialize};
6use time::{ext::NumericalDuration, OffsetDateTime};
7
8use crate::{error::{self, FulfillRequest}, message::package::Package};
9
10#[derive(Serialize, Deserialize)]
11pub struct CertificateRequest {
12 certificate_request_pem: String,
13}
14
15impl Package for CertificateRequest {
16 fn pack(self) -> Result<String, error::PackToMessageError> {
17 ron::to_string(&self).expect("This serializes hard coded values, it should always work")[..]
18 .pack()
19 }
20}
21
22impl CertificateRequest {
23 pub fn new(certificate_request_pem: String) -> Self {
24 Self {
25 certificate_request_pem,
26 }
27 }
28
29 pub fn fulfill_request(
30 self,
31 ca_certificate_pem: &String,
32 ca_certificate_private_key_pem: &String,
33 duration: i64,
34 ) -> Result<String, FulfillRequest> {
35 let mut certificate_signing_request =
36 CertificateSigningRequest::from_pem(&self.certificate_request_pem)?;
37
38 let time_now = OffsetDateTime::now_utc();
39
40 certificate_signing_request.params.not_after = time_now.saturating_add(duration.days());
41 certificate_signing_request.params.not_before = time_now;
42
43 let ca_certificate_key = KeyPair::from_pem(&ca_certificate_private_key_pem)?;
44
45 let ca_certificate_params =
46 CertificateParams::from_ca_cert_pem(&ca_certificate_pem, ca_certificate_key)?;
47 let ca_certificate = Certificate::from_params(ca_certificate_params)?;
48
49 let signed_certificate_str =
50 certificate_signing_request.serialize_pem_with_signer(&ca_certificate)?;
51
52 Ok(signed_certificate_str)
53 }
54}
55
56#[derive(Serialize, Deserialize)]
57pub struct PasswordAuthorizationRequest {
58 username: String,
59 password: String,
60}
61
62impl Package for PasswordAuthorizationRequest {
63 fn pack(self) -> Result<String, error::PackToMessageError> {
64 ron::to_string(&self).expect("This serializes hard coded values, it should always work")[..]
65 .pack()
66 }
67}
68
69impl PasswordAuthorizationRequest {
70 pub fn new(username: String, password: String) -> Self {
71 Self { username, password }
72 }
73 pub fn verify_request(&self, allowed_users: &Vec<User>) -> bool {
74 allowed_users.iter().any(|user| {
75 (user.username == self.username)
76 && Argon2::default()
77 .verify_password(
78 self.password.as_bytes(),
79 &user.password_hash.password_hash(),
80 )
81 .is_ok()
82 })
83 }
84}
85
86pub struct User {
87 username: String,
88 password_hash: PasswordHashString,
89}
90
91impl User {
92 pub fn new(username: String, password_hash: PasswordHashString) -> Self {
93 Self {
94 username,
95 password_hash,
96 }
97 }
98}
99impl FromStr for User {
100 type Err = error::UserParsing;
101
102 fn from_str(s: &str) -> Result<Self, Self::Err> {
103 let split_string: Vec<_> = s.split_ascii_whitespace().collect();
104 if split_string.len() != 2 {
105 if split_string.len() < 2 {
106 return Err(error::UserParsing::ToShort());
107 } else {
108 return Err(error::UserParsing::ToLong());
109 }
110 } else {
111 let username = split_string.get(0).expect("We checked the length above");
112 let password_hash_string = split_string.get(1).expect("We checked the length above");
113 let password_hash = PasswordHash::new(password_hash_string)?;
114 Ok(User {
115 username: username.to_string(),
116 password_hash: password_hash.serialize(),
117 })
118 }
119 }
120}
121
122#[cfg(test)]
123mod tests {}