use bitcoin_hashes::sha256::Midstate;
use bitcoin_hashes::sha256t::{self, Tag};
use serde::{Serialize, Deserialize};
use serde::ser::Serializer;
use serde::de::Deserializer;
use std::str::FromStr;
use std::hash::Hash;
use std::fmt::Debug;
pub mod secp256k1;
const ORANGEME_NAME: &str = "03273e58dff6f2e5334c526b0dd0100d20e1ac4bfa22dfd904725eef63931e4853";
const ORANGEME_URL: &str = if cfg!(test) {"0.0.0.0:5702"} else {"air.orange.me:5702"};
pub fn now() -> u64 {chrono::Utc::now().timestamp_millis() as u64}
#[derive(Debug)]
pub enum Error {
Secp256k1(secp256k1::E),
InvalidMessage,
MissingPermissions(Vec<Id>),
InvalidSignature
}
impl std::error::Error for Error {}
impl std::fmt::Display for Error {fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {write!(f, "{self:?}")}}
impl From<secp256k1::E> for Error {fn from(e: secp256k1::E) -> Self {Error::Secp256k1(e)}}
struct AirTag;
impl Tag for AirTag {
const MIDSTATE: Midstate = Midstate::hash_tag(b"AIR_NAMES");
}
type AirHash = sha256t::Hash<AirTag>;
#[derive(Default)]
pub struct HashReader(Vec<u8>);
impl core::hash::Hasher for HashReader {
fn finish(&self) -> u64 {panic!("NOOP");}
fn write(&mut self, bytes: &[u8]) {self.0.extend(bytes);}
}
impl HashReader {
pub fn read<H: Hash + ?Sized>(h: &H) -> Vec<u8> {
let mut hasher = HashReader::default();
h.hash(&mut hasher);
hasher.0
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
#[derive(serde_with::SerializeDisplay)]
#[derive(serde_with::DeserializeFromStr)]
pub struct Id([u8; 32]);
impl AsRef<[u8]> for Id {fn as_ref(&self) -> &[u8] {&self.0}}
impl std::ops::Deref for Id {type Target = [u8; 32]; fn deref(&self) -> &Self::Target {&self.0}}
impl std::ops::DerefMut for Id {fn deref_mut(&mut self) -> &mut Self::Target {&mut self.0}}
impl From<[u8; 32]> for Id {fn from(id: [u8; 32]) -> Self {Id(id)}}
impl Id {
pub const MAX: Id = Id([u8::MAX; 32]);
pub const MIN: Id = Id([u8::MIN; 32]);
pub fn hash<H: Hash + ?Sized>(h: &H) -> Self {
Id(*AirHash::hash(&HashReader::read(h)).as_ref())
}
pub fn random() -> Self {Id(secp256k1::rand::random())}
}
impl std::fmt::Display for Id {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", hex::encode(self.0))
}
}
impl std::fmt::Debug for Id {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", hex::encode(self.0))
}
}
impl std::str::FromStr for Id {
type Err = hex::FromHexError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Id(hex::decode(s)?.try_into().map_err(|_| hex::FromHexError::InvalidStringLength)?))
}
}
#[derive(Clone, Copy, Debug, Hash, Ord, Eq, PartialOrd, PartialEq)]
#[derive(serde_with::SerializeDisplay)]
#[derive(serde_with::DeserializeFromStr)]
pub struct Name(secp256k1::PublicKey);
impl Name {
pub fn orange_me() -> Name {Name::from_str(ORANGEME_NAME).unwrap()}
}
impl std::fmt::Display for Name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::str::FromStr for Name {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Name(secp256k1::PublicKey::from_str(s)?))
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct Secret {
name: Name,
path: Vec<Id>,
temporary: secp256k1::SecretKey,
}
impl Secret {
pub fn new() -> Self {
let temporary = secp256k1::SecretKey::new();
Secret{name: Name(temporary.public_key()), path: vec![], temporary}
}
pub fn name(&self) -> Name {self.name}
pub fn path(&self) -> &Vec<Id> {&self.path}
pub fn public(&self) -> Public {Public(self.temporary.public_key())}
pub fn sign(&self, payload: &[u8]) -> Result<Signature, Error> {
Ok(Signature(self.temporary.sign(payload)))
}
pub fn decrypt(&self, _datetime: Option<u64>, path: &[Id], payload: &[u8]) -> Result<Vec<u8>, Error> {
let _path = path.strip_prefix(self.path.as_slice()).ok_or(Error::MissingPermissions(path.to_vec()))?;
self.temporary.decrypt(payload)
}
pub fn derive(&self, path: &[Id]) -> Result<Self, Error> {
Ok(Secret{
name: self.name,
path: [&self.path, path].concat(),
temporary: self.temporary
})
}
}
impl Default for Secret {fn default() -> Self {Self::new()}}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Signature(secp256k1::Signature);
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
pub struct Public(secp256k1::PublicKey);
impl Public {
pub fn verify(&mut self, _path: &[Id], sig: &Signature, payload: &[u8]) -> Result<(), Error> {
self.0.verify(&sig.0, payload).map_err(|_| Error::InvalidSignature)
}
pub fn encrypt(&mut self, _path: &[Id], payload: Vec<u8>) -> Result<Vec<u8>, Error> {
Ok(self.0.encrypt(payload))
}
}
#[derive(Default, Debug)]
pub struct Resolver;
impl Resolver {
pub async fn verify(&mut self, name: &Name, _datetime: Option<u64>, path: &[Id], sig: &Signature, payload: &[u8]) -> Result<(), Error> {
self.public(name).await?.verify(path, sig, payload)
}
pub async fn encrypt(&mut self, name: &Name, path: &[Id], payload: Vec<u8>) -> Result<Vec<u8>, Error> {
self.public(name).await?.encrypt(path, payload)
}
pub async fn public(&mut self, name: &Name) -> Result<Public, Error> {
Ok(Public(name.0))
}
pub async fn url(&mut self, _name: &Name) -> Result<String, Error> {
Ok(ORANGEME_URL.to_string())
}
pub async fn air_servers(&mut self, _name: &Name) -> Result<Vec<Name>, Error> {
Ok(vec![Name::from_str(ORANGEME_NAME).unwrap()])
}
}
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct Signed<H: Hash + Debug>(Name, u64, Vec<Id>, Signature, H);
impl<H: Hash + Debug> Signed<H> {
pub fn new(secret: &Secret, payload: H) -> Result<Self, Error> {
let bytes = HashReader::read(&payload);
Ok(Signed(secret.name, now(), secret.path().to_vec(), secret.sign(&bytes)?, payload))
}
pub async fn verify(&self, resolver: &mut Resolver, signer: Option<&Name>, path: Option<&[Id]>) -> Result<Name, Error> {
let bytes = HashReader::read(&self.4);
if let Some(signer) = signer && &self.0 != signer {Err(Error::InvalidSignature)?}
if let Some(path) = path && self.2 != path {Err(Error::InvalidSignature)?}
resolver.verify(&self.0, Some(self.1), &self.2, &self.3, &bytes).await?;
Ok(self.0)
}
pub fn signer(&self) -> Name {self.0}
pub fn datetime(&self) -> u64 {self.1}
pub fn path(&self) -> &[Id] {&self.2}
pub fn into_inner(self) -> H {self.4}
}
impl<H: Hash + Debug + Clone> Clone for Signed<H> {
fn clone(&self) -> Self {Signed(self.0, self.1, self.2.clone(), self.3.clone(), self.4.clone())}
}
impl<H: Hash + Debug + Serialize> Serialize for Signed<H> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
(&self.0, &self.1, &self.2, &self.3, &self.4).serialize(serializer)
}
}
impl<'de, H: Hash + Debug + Deserialize<'de>> Deserialize<'de> for Signed<H> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
<(Name, u64, Vec<Id>, Signature, H)>::deserialize(deserializer).map(|(a, b, c, d, e)|
Signed(a, b, c, d, e)
)
}
}
impl<H: Hash + Debug> AsRef<H> for Signed<H> {fn as_ref(&self) -> &H {&self.4}}
#[cfg(test)]
mod test {
use super::*;
use std::future::Future;
use std::sync::Arc;
use std::task::{Context, Poll, Wake};
use std::thread::{self, Thread};
use core::pin::pin;
struct ThreadWaker(Thread);
impl Wake for ThreadWaker {
fn wake(self: Arc<Self>) {
self.0.unpark();
}
}
fn block_on<T>(fut: impl Future<Output = T>) -> T {
let mut fut = pin!(fut);
let t = thread::current();
let waker = Arc::new(ThreadWaker(t)).into();
let mut cx = Context::from_waker(&waker);
loop {
match fut.as_mut().poll(&mut cx) {
Poll::Ready(res) => return res,
Poll::Pending => thread::park(),
}
}
}
#[test]
pub fn encryption() {
let secret = Secret::new();
let name = secret.name();
let id = Id::random();
let m = vec![1, 2, 3];
let c = block_on(Resolver.encrypt(&name, &[id], m.clone())).unwrap();
assert_eq!(m, secret.decrypt(None, &[id], &c).unwrap())
}
#[test]
pub fn signature() {
let secret = Secret::new();
let name = secret.name();
let id = Id::random();
let m = vec![1, 2, 3];
let s = secret.derive(&[id]).unwrap().sign(&m).unwrap();
block_on(Resolver.verify(&name, None, &[id], &s, &m)).unwrap();
}
}