gmarche-rs/src/utils.rs

49 lines
1.3 KiB
Rust
Raw Normal View History

2020-12-08 19:53:30 +01:00
use sha2::{Digest, Sha256};
pub enum PubkeyDecodeError {
BadChecksum,
BadFormat,
}
/// Decode pubkey from base 58
/// Verify checksum if provided
/// Accepts any checksum length >=3
pub fn format_pubkey(raw: &str) -> Result<String, PubkeyDecodeError> {
let mut iter = raw.splitn(2, ':');
2020-12-08 21:12:02 +01:00
let raw_pubkey = iter.next().ok_or(PubkeyDecodeError::BadFormat)?;
if raw_pubkey.len() < 43 || raw_pubkey.len() > 44 {
return Err(PubkeyDecodeError::BadFormat);
}
2020-12-08 19:53:30 +01:00
let mut pubkey = [0u8; 32];
2020-12-08 21:12:02 +01:00
bs58::decode(raw_pubkey)
2020-12-08 19:53:30 +01:00
.into(&mut pubkey)
.map_err(|_| PubkeyDecodeError::BadFormat)?;
let mut hasher1 = Sha256::new();
hasher1.update(&pubkey.as_ref()[..32]);
let mut hasher2 = Sha256::new();
hasher2.update(hasher1.finalize());
let checksum = bs58::encode(hasher2.finalize()).into_string();
if let Some(given_checksum) = iter.next() {
if given_checksum.len() < 3 {
return Err(PubkeyDecodeError::BadFormat);
}
if !checksum.starts_with(given_checksum) {
return Err(PubkeyDecodeError::BadChecksum);
}
}
Ok(format!(
"{}:{}",
bs58::encode(pubkey).into_string(),
&checksum[..3]
))
}
2020-12-08 22:39:02 +01:00
pub fn redirect_302(url: &str) -> warp::reply::WithStatus<warp::reply::WithHeader<&str>> {
warp::reply::with_status(
warp::reply::with_header("", "Location", url),
http::status::StatusCode::FOUND,
)
}