add more specific error handeling to certs
All checks were successful
Build and Test / account (push) Successful in 6m7s
All checks were successful
Build and Test / account (push) Successful in 6m7s
This commit is contained in:
parent
893bcecc9e
commit
6b96e1db51
1 changed files with 52 additions and 16 deletions
|
|
@ -15,6 +15,7 @@ use bytemuck::bytes_of;
|
|||
use chrono::{NaiveDate, NaiveDateTime, Utc};
|
||||
use openssl::bn::BigNum;
|
||||
use openssl::ecdsa::EcdsaSig;
|
||||
use openssl::error::ErrorStack;
|
||||
use rand::Rng;
|
||||
use rocket::http::Status;
|
||||
use rocket::request::{FromRequest, Outcome};
|
||||
|
|
@ -262,7 +263,7 @@ pub async fn link_certificate_to_pid(
|
|||
sqlx::query(
|
||||
"INSERT INTO certificate_pids (cert_hash, pid)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT DO NOTHING"
|
||||
ON CONFLICT DO NOTHING",
|
||||
)
|
||||
.bind(&hash[..])
|
||||
.bind(pid)
|
||||
|
|
@ -330,14 +331,17 @@ impl<'r> FromRequest<'r> for DeviceCert {
|
|||
};
|
||||
|
||||
let cert = match Certificate::new(cert_header) {
|
||||
Some(c) => c,
|
||||
None => return Outcome::Error((Status::BadGateway, INVALID_TOKEN_ERRORS)),
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
println!("error occurred whilest getting cert data: {}", e);
|
||||
return Outcome::Error((Status::BadGateway, INVALID_TOKEN_ERRORS));
|
||||
}
|
||||
};
|
||||
|
||||
let hash = cert.hash();
|
||||
|
||||
let existing = sqlx::query_as::<_, CertificateRecord>(
|
||||
"SELECT hash, banned FROM certificates WHERE hash = $1"
|
||||
"SELECT hash, banned FROM certificates WHERE hash = $1",
|
||||
)
|
||||
.bind(&hash[..])
|
||||
.fetch_optional(pool)
|
||||
|
|
@ -359,7 +363,7 @@ impl<'r> FromRequest<'r> for DeviceCert {
|
|||
} else {
|
||||
sqlx::query(
|
||||
"INSERT INTO certificates (hash, banned)
|
||||
VALUES ($1, false)"
|
||||
VALUES ($1, false)",
|
||||
)
|
||||
.bind(&hash[..])
|
||||
.execute(pool)
|
||||
|
|
@ -396,19 +400,36 @@ MFIwEAYHKoZIzj0CAQYFK4EEABsDPgAEAP1WBBgs8XUJIQDDCK5IOZEbb5+h1TqV
|
|||
rwgzSUcrAAFxMWm1kf/TDL9z2nZkuo0N+VtNEQREZDXA7aQv
|
||||
-----END PUBLIC KEY-----"#;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
enum CertError {
|
||||
#[error("unable to decode base64: {0}")]
|
||||
Base64(#[from] base64::DecodeError),
|
||||
#[error("unable to decode outer cert: {0}")]
|
||||
OuterBinError(binrw::Error),
|
||||
#[error("unable to decode inner cert: {0}")]
|
||||
BinError(binrw::Error),
|
||||
#[error("unable to create openssl ecdsa sig: {0}")]
|
||||
EcdsaSig(ErrorStack),
|
||||
#[error("error whilest validating signature: {0}")]
|
||||
CryptoVerifError(ErrorStack),
|
||||
#[error("certificate is not valid")]
|
||||
ValidationError,
|
||||
}
|
||||
|
||||
impl Certificate {
|
||||
fn new(data: &str) -> Option<Self> {
|
||||
let data = BASE64_STANDARD.decode(data).unwrap();
|
||||
fn new(data: &str) -> Result<Self, CertError> {
|
||||
let data = BASE64_STANDARD.decode(data)?;
|
||||
|
||||
let cert = OuterCertificate::read(&mut Cursor::new(&data)).ok()?;
|
||||
let cert =
|
||||
OuterCertificate::read(&mut Cursor::new(&data)).map_err(CertError::OuterBinError)?;
|
||||
|
||||
println!("key");
|
||||
let key = openssl::ec::EcKey::public_key_from_pem(PUB_PEM).expect("invalid pem file");
|
||||
|
||||
let key = openssl::ec::EcKey::public_key_from_pem(PUB_PEM).ok()?;
|
||||
let sig_components = read_p1363(&cert.signature)
|
||||
.expect("unable to read signature despite fixed size signature");
|
||||
|
||||
let sig_components = read_p1363(&cert.signature)?;
|
||||
|
||||
let sig = EcdsaSig::from_private_components(sig_components.0, sig_components.1).unwrap();
|
||||
let sig = EcdsaSig::from_private_components(sig_components.0, sig_components.1)
|
||||
.map_err(CertError::EcdsaSig)?;
|
||||
|
||||
let mut hasher = openssl::sha::Sha256::new();
|
||||
|
||||
|
|
@ -416,11 +437,14 @@ impl Certificate {
|
|||
|
||||
let hash = hasher.finish();
|
||||
|
||||
if !sig.verify(&hash[..], &key).ok()? {
|
||||
return None;
|
||||
if !sig
|
||||
.verify(&hash[..], &key)
|
||||
.map_err(CertError::CryptoVerifError)?
|
||||
{
|
||||
return Err(CertError::ValidationError);
|
||||
}
|
||||
|
||||
Certificate::read(&mut Cursor::new(cert.data)).ok()
|
||||
Certificate::read(&mut Cursor::new(cert.data)).map_err(CertError::BinError)
|
||||
}
|
||||
|
||||
pub fn hash(&self) -> [u8; 32] {
|
||||
|
|
@ -446,3 +470,15 @@ fn read_p1363(data: &[u8]) -> Option<(BigNum, BigNum)> {
|
|||
BigNum::from_slice(&data[half_len..]).ok()?,
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::account::account::Certificate;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
const CERT: &str = "AAEABQAsTGvAP1XNwh6JO+z47AkwVvqPYHRDO9X11BdhYwCIEipUJne32JSWMAYsFe1LqWT+0AkSnaDCkMWK1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSb290LUNBMDAwMDAwMDMtTVMwMDAwMDAxMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk5HNDQ0Y2FiZmMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1/THZAcTyFksveCuIl5fOM7Fb6ebi6mUqcVJlQQDqvsgMAW12aEaECJWV+Y6wXOL+E7yP5WJ/9VAd4jlgrvZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
|
||||
Certificate::new(CERT).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue