use crate::domain::Authentication;
use crate::handle::insert_authentication;
use crate::{domain, program};
use serde::{Deserialize, Serialize};
use alloc::string::String;
pub(crate) type Verifier = [u8; 32 + 33 + 33 + 136 + 16];
pub(crate) type Key = [u8; 33];
pub(crate) type Authenticator = [u8; 32 + 16];
pub(crate) type Proof = [u8; 64];
pub(crate) type Client = [u8; 33 + 64 + 32];
pub(crate) type Randomness = [u8; 32];
pub(crate) type Secret = [u8; 32];
pub(crate) type Mask = [u8; 32];
pub(crate) type Challenge = [u8; 33 + 33];
pub(crate) type Pass = [u8; 33 + 33 + 64 + 33 + 64 + 33 + 32 + 16];
pub(crate) type Digest = [u8; 32];
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub enum Error {
BadRequest,
MissingValue,
InvalidInput,
}
#[derive(Serialize)]
pub(crate) struct ErrorResponse {
pub(crate) error: Error,
}
#[derive(Serialize)]
#[serde(untagged)]
pub(crate) enum Response {
Challenge(ChallengeResponse),
Register(Option<Registration>),
Accept(Acceptance),
Authenticate(AuthenticateResponse2),
Pass(Attempt),
Prove(Option<Transcript>),
Verify(Verification),
Error(ErrorResponse),
}
#[derive(Serialize, Deserialize)]
pub(crate) struct SubscriberState {
#[serde(with = "serde_bytes", default = "Option::default")]
mask: Option<Mask>,
#[serde(with = "serde_bytes", default = "Option::default")]
randomness: Option<Randomness>,
#[serde(with = "serde_bytes", default = "Option::default")]
provider: Option<Key>,
}
impl SubscriberState {
pub(crate) fn handle(&self) -> Option<Option<Registration>> {
Some(
program::subscriber::register(&self.mask?, &self.randomness?, &self.provider?).map(
|(key, verifier)| Registration {
subscriber: Some(key),
verifier: Some(verifier),
},
),
)
}
}
#[derive(Serialize, Deserialize)]
pub(crate) struct Registration {
#[serde(with = "serde_bytes", default = "Option::default")]
subscriber: Option<Key>,
#[serde(with = "serde_bytes", default = "Option::default")]
verifier: Option<Verifier>,
}
#[derive(Serialize, Deserialize)]
pub(crate) struct RegisterResponse {
#[serde(flatten)]
registration: Option<Registration>,
#[serde(default = "Option::default", skip_serializing_if = "Option::is_none")]
error: Option<String>,
}
#[derive(Serialize, Deserialize)]
pub(crate) struct AuthenticateRequest {
#[serde(flatten)]
state: SubscriberState,
#[serde(with = "serde_bytes", default = "Option::default")]
subscriber: Option<Key>,
#[serde(flatten)]
credential: Credential,
#[serde(with = "serde_bytes", default = "Option::default")]
challenge: Option<Challenge>,
#[serde(with = "serde_bytes", default = "Option::default")]
hash: Option<Digest>,
}
#[derive(Serialize)]
pub(crate) struct AuthenticateResponse2 {
#[serde(with = "serde_bytes")]
digest: Digest,
authentication: u64,
}
impl AuthenticateRequest {
pub(crate) fn handle(&self) -> Option<Option<(Authentication, Digest)>> {
Some(program::subscriber::authenticate(
&self.state.mask?,
&self.state.randomness?,
&self.state.provider?,
&self.subscriber?,
&self.credential.verifier?,
&self.challenge?,
&self.hash?,
))
}
pub(crate) fn handle2(&self) -> Option<AuthenticateResponse2> {
match self.handle() {
None => None,
Some(None) => None,
Some(Some((authentication, digest))) => {
let authentication_id = insert_authentication(authentication);
Some(AuthenticateResponse2 {
digest,
authentication: authentication_id,
})
}
}
}
}
#[derive(Serialize, Deserialize)]
pub(crate) struct AuthenticateResponse {
#[serde(
with = "serde_bytes",
default = "Option::default",
skip_serializing_if = "Option::is_none"
)]
digest: Option<Digest>,
#[serde(default = "Option::default", skip_serializing_if = "Option::is_none")]
error: Option<String>,
}
#[derive(Serialize, Deserialize)]
pub(crate) struct PassRequest {
#[serde(with = "serde_bytes", default = "Option::default")]
proof: Option<Proof>,
#[serde(default = "Option::default")]
pub(crate) authentication: Option<u64>,
}
impl PassRequest {
pub(crate) fn handle(&self, authentication: Authentication) -> Option<Option<(Key, Pass)>> {
Some(program::subscriber::pass(authentication, &self.proof?))
}
}
#[derive(Serialize, Deserialize)]
pub(crate) struct Attempt {
#[serde(with = "serde_bytes", default = "Option::default")]
pub(crate) sender: Option<Key>,
#[serde(with = "serde_bytes", default = "Option::default")]
pub(crate) pass: Option<Pass>,
}
#[derive(Serialize, Deserialize)]
struct PassResponse {
#[serde(flatten)]
attempt: Option<Attempt>,
#[serde(default = "Option::default", skip_serializing_if = "Option::is_none")]
error: Option<String>,
}
#[derive(Serialize, Deserialize)]
pub(crate) struct ChallengeRequest {
#[serde(with = "serde_bytes", default = "Option::default")]
randomness: Option<Randomness>,
}
impl ChallengeRequest {
pub(crate) fn handle(&self) -> Option<Challenge> {
Some(program::provider::challenge(&self.randomness?))
}
}
#[derive(Serialize, Deserialize)]
pub(crate) struct ChallengeResponse {
#[serde(
with = "serde_bytes",
default = "Option::default",
skip_serializing_if = "Option::is_none"
)]
pub(crate) challenge: Option<Challenge>,
#[serde(default = "Option::default", skip_serializing_if = "Option::is_none")]
pub(crate) error: Option<String>,
}
#[derive(Serialize, Deserialize, Clone)]
pub(crate) struct ProviderState {
#[serde(with = "serde_bytes", default = "Option::default")]
provider: Option<Key>,
#[serde(
with = "serde_bytes",
default = "Option::default",
rename = "verifierSecret"
)]
secret: Option<Secret>,
#[serde(flatten)]
credential: Credential,
}
impl ProviderState {
pub(crate) fn handle(&self) -> Option<domain::Result> {
Some(program::provider::accept(
&self.provider?,
&self.secret?,
&self.credential.verifier?,
))
}
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub(crate) enum Acceptance {
Accepted,
Rejected,
}
#[derive(Serialize, Deserialize)]
struct AcceptResponse {
#[serde(default = "Option::default", skip_serializing_if = "Option::is_none")]
result: Option<String>,
#[serde(default = "Option::default", skip_serializing_if = "Option::is_none")]
error: Option<String>,
}
#[derive(Serialize, Deserialize)]
pub(crate) struct ProveRequest {
#[serde(with = "serde_bytes", default = "Option::default")]
randomness: Option<Randomness>,
#[serde(flatten)]
state: ProviderState,
#[serde(with = "serde_bytes", default = "Option::default")]
hash: Option<Digest>,
#[serde(
with = "serde_bytes",
default = "Option::default",
rename = "passSecret"
)]
pass_secret: Option<Secret>,
#[serde(with = "serde_bytes", default = "Option::default")]
pass: Option<Pass>,
}
impl ProveRequest {
pub(crate) fn handle(&self) -> Option<Option<(Authenticator, Proof, Client)>> {
Some(program::provider::prove(
&self.randomness?,
&self.state.provider?,
&self.state.secret?,
&self.state.credential.verifier?,
&self.state.credential.device?,
&self.hash?,
&self.pass_secret?,
&self.pass?,
))
}
}
#[derive(Serialize, Deserialize, Debug)]
struct ProveResponse {
#[serde(flatten)]
result: Option<Transcript>,
#[serde(default = "Option::default", skip_serializing_if = "Option::is_none")]
error: Option<String>,
}
#[derive(Serialize, Deserialize, Clone)]
struct Credential {
#[serde(with = "serde_bytes", default = "Option::default")]
verifier: Option<Verifier>,
#[serde(with = "serde_bytes", default = "Option::default")]
device: Option<Key>,
}
#[derive(Serialize, Deserialize, Debug)]
pub(crate) struct Transcript {
#[serde(with = "serde_bytes", default = "Option::default")]
pub(crate) authenticator: Option<Authenticator>,
#[serde(with = "serde_bytes", default = "Option::default")]
pub(crate) proof: Option<Proof>,
#[serde(with = "serde_bytes", default = "Option::default")]
pub(crate) client: Option<Client>,
}
#[derive(Serialize, Deserialize)]
pub(crate) struct VerifyRequest {
#[serde(flatten)]
credential: Credential,
#[serde(with = "serde_bytes", default = "Option::default")]
hash: Option<Digest>,
#[serde(flatten)]
transcript: Transcript,
}
impl VerifyRequest {
pub(crate) fn handle(&self) -> Option<domain::Result> {
Some(program::verify(
&self.credential.verifier?,
&self.credential.device?,
&self.hash?,
&self.transcript.authenticator?,
&self.transcript.proof?,
&self.transcript.client?,
))
}
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub(crate) enum Verification {
Verified,
Rejected,
}
#[derive(Serialize, Deserialize, Debug)]
struct VerifyResponse {
#[serde(default = "Option::default", skip_serializing_if = "Option::is_none")]
result: Option<String>,
#[serde(default = "Option::default", skip_serializing_if = "Option::is_none")]
error: Option<String>,
}