From d148e76c089fa462e9738951a6b1011d3b016dc3 Mon Sep 17 00:00:00 2001 From: raphaelrobert Date: Mon, 8 Apr 2024 21:52:05 +0200 Subject: [PATCH] Align token_key_id/truncated_token_key_id with the base spec --- benches/public.rs | 4 +-- src/auth/authorize.rs | 10 +++---- src/batched_tokens_p384/client.rs | 23 ++++++++------- src/batched_tokens_p384/mod.rs | 12 ++++---- src/batched_tokens_p384/server.rs | 36 +++++++++++++++-------- src/batched_tokens_ristretto255/client.rs | 23 ++++++++------- src/batched_tokens_ristretto255/mod.rs | 12 ++++---- src/batched_tokens_ristretto255/server.rs | 36 +++++++++++++++-------- src/lib.rs | 12 ++++---- src/private_tokens/client.rs | 23 ++++++++------- src/private_tokens/mod.rs | 16 +++++----- src/private_tokens/server.rs | 34 +++++++++++++-------- src/public_tokens/client.rs | 27 +++++++++++------ src/public_tokens/mod.rs | 16 +++++----- src/public_tokens/server.rs | 36 +++++++++++++---------- tests/batched_memory_stores.rs | 36 ++++++++++++++++------- tests/kat_public.rs | 12 ++++++-- tests/private_memory_stores.rs | 19 ++++++++---- tests/public_memory_stores.rs | 22 +++++++------- tests/public_tokens.rs | 7 +++-- 20 files changed, 249 insertions(+), 167 deletions(-) diff --git a/benches/public.rs b/benches/public.rs index 3d63f3c..f351368 100644 --- a/benches/public.rs +++ b/benches/public.rs @@ -1,4 +1,4 @@ -use privacypass::public_tokens::{public_key_to_token_key_id, server::OriginKeyStore}; +use privacypass::public_tokens::{public_key_to_truncated_token_key_id, server::OriginKeyStore}; #[path = "../tests/public_memory_stores.rs"] mod public_memory_stores; @@ -165,7 +165,7 @@ pub fn criterion_public_benchmark(c: &mut Criterion) { .unwrap(); origin_key_store .insert( - public_key_to_token_key_id(&key_pair.pk), + public_key_to_truncated_token_key_id(&key_pair.pk), key_pair.pk.clone(), ) .await; diff --git a/src/auth/authorize.rs b/src/auth/authorize.rs index cf154a5..cb6bdf6 100644 --- a/src/auth/authorize.rs +++ b/src/auth/authorize.rs @@ -13,7 +13,7 @@ use std::io::Write; use thiserror::Error; use tls_codec::{Deserialize, Error, Serialize, Size}; -use crate::{ChallengeDigest, KeyId, Nonce, TokenType}; +use crate::{ChallengeDigest, Nonce, TokenKeyId, TokenType}; use super::{base64_char, key_name, opt_spaces, space}; @@ -34,7 +34,7 @@ pub struct Token> { token_type: TokenType, nonce: Nonce, challenge_digest: ChallengeDigest, - token_key_id: KeyId, + token_key_id: TokenKeyId, authenticator: GenericArray, } @@ -66,7 +66,7 @@ impl> Deserialize for Token { let token_type = TokenType::tls_deserialize(bytes)?; let nonce = Nonce::tls_deserialize(bytes)?; let challenge_digest = ChallengeDigest::tls_deserialize(bytes)?; - let token_key_id = KeyId::tls_deserialize(bytes)?; + let token_key_id = TokenKeyId::tls_deserialize(bytes)?; let mut authenticator = vec![0u8; Nk::to_usize()]; let len = bytes.read(authenticator.as_mut_slice())?; if len != Nk::to_usize() { @@ -88,7 +88,7 @@ impl> Token { token_type: TokenType, nonce: Nonce, challenge_digest: ChallengeDigest, - token_key_id: KeyId, + token_key_id: TokenKeyId, authenticator: GenericArray, ) -> Self { Self { @@ -116,7 +116,7 @@ impl> Token { } /// Returns the token key ID. - pub const fn token_key_id(&self) -> &KeyId { + pub const fn token_key_id(&self) -> &TokenKeyId { &self.token_key_id } diff --git a/src/batched_tokens_p384/client.rs b/src/batched_tokens_p384/client.rs index 0f34cb2..36a19cf 100644 --- a/src/batched_tokens_p384/client.rs +++ b/src/batched_tokens_p384/client.rs @@ -7,12 +7,12 @@ use voprf::{EvaluationElement, Proof, Result, VoprfClient}; use crate::{ auth::{authenticate::TokenChallenge, authorize::Token}, - ChallengeDigest, KeyId, TokenInput, TokenType, + ChallengeDigest, TokenInput, TokenKeyId, TokenType, }; use super::{ - key_id_to_token_key_id, public_key_to_key_id, BatchedToken, Nonce, PublicKey, TokenRequest, - TokenResponse, + public_key_to_token_key_id, truncate_token_key_id, BatchedToken, Nonce, PublicKey, + TokenRequest, TokenResponse, }; /// Client-side state that is kept between the token requests and token responses. @@ -45,7 +45,7 @@ pub enum IssueTokenError { /// The client side of the batched token issuance protocol. #[derive(Debug)] pub struct Client { - key_id: KeyId, + token_key_id: TokenKeyId, public_key: PublicKey, } @@ -53,9 +53,12 @@ impl Client { /// Create a new client from a public key. #[must_use] pub fn new(public_key: PublicKey) -> Self { - let key_id = public_key_to_key_id(&public_key); + let token_key_id = public_key_to_token_key_id(&public_key); - Self { key_id, public_key } + Self { + token_key_id, + public_key, + } } /// Issue a token request. @@ -97,14 +100,14 @@ impl Client { for nonce in nonces { // nonce = random(32) // challenge_digest = SHA256(challenge) - // token_input = concat(0xF901, nonce, challenge_digest, key_id) + // token_input = concat(0xF901, nonce, challenge_digest, token_key_id) // blind, blinded_element = client_context.Blind(token_input) let token_input = TokenInput::new( TokenType::BatchedTokenP384, nonce, challenge_digest, - self.key_id, + self.token_key_id, ); let blinded_element = @@ -138,7 +141,7 @@ impl Client { let token_request = TokenRequest { token_type: TokenType::BatchedTokenP384, - token_key_id: key_id_to_token_key_id(&self.key_id), + truncated_token_key_id: truncate_token_key_id(&self.token_key_id), blinded_elements: blinded_elements.into(), }; @@ -202,7 +205,7 @@ impl Client { TokenType::BatchedTokenP384, token_state.token_input.nonce, token_state.challenge_digest, - token_state.token_input.key_id, + token_state.token_input.token_key_id, *authenticator, ); tokens.push(token); diff --git a/src/batched_tokens_p384/mod.rs b/src/batched_tokens_p384/mod.rs index 2b51fec..93bc082 100644 --- a/src/batched_tokens_p384/mod.rs +++ b/src/batched_tokens_p384/mod.rs @@ -11,7 +11,7 @@ use tls_codec_derive::{TlsDeserialize, TlsSerialize, TlsSize}; use typenum::U48; pub use voprf::*; -use crate::{auth::authorize::Token, KeyId, Nonce, TokenKeyId, TokenType}; +use crate::{auth::authorize::Token, Nonce, TokenKeyId, TokenType, TruncatedTokenKeyId}; use self::server::serialize_public_key; @@ -27,14 +27,14 @@ pub type BatchedToken = Token; /// Public key alias pub type PublicKey = ::Elem; -fn public_key_to_key_id(public_key: &PublicKey) -> KeyId { +fn public_key_to_token_key_id(public_key: &PublicKey) -> TokenKeyId { let public_key = serialize_public_key(*public_key); Sha256::digest(public_key).into() } -fn key_id_to_token_key_id(key_id: &KeyId) -> TokenKeyId { - *key_id.iter().last().unwrap_or(&0) +fn truncate_token_key_id(token_key_id: &TokenKeyId) -> TruncatedTokenKeyId { + *token_key_id.iter().last().unwrap_or(&0) } /// Serialization error @@ -62,14 +62,14 @@ pub struct BlindedElement { /// ```c /// struct { /// uint16_t token_type = 0xF901; -/// uint8_t token_key_id; +/// uint8_t truncated_token_key_id; /// BlindedElement blinded_element[Nr]; /// } TokenRequest; /// ``` #[derive(Debug, TlsDeserialize, TlsSerialize, TlsSize)] pub struct TokenRequest { token_type: TokenType, - token_key_id: TokenKeyId, + truncated_token_key_id: TruncatedTokenKeyId, blinded_elements: TlsVecU16, } diff --git a/src/batched_tokens_p384/server.rs b/src/batched_tokens_p384/server.rs index 116fe14..5a17ead 100644 --- a/src/batched_tokens_p384/server.rs +++ b/src/batched_tokens_p384/server.rs @@ -9,10 +9,10 @@ use voprf::{ BlindedElement, Error, Group, Result, VoprfServer, VoprfServerBatchEvaluateFinishResult, }; -use crate::{NonceStore, TokenInput, TokenKeyId, TokenType}; +use crate::{NonceStore, TokenInput, TokenType, TruncatedTokenKeyId}; use super::{ - key_id_to_token_key_id, public_key_to_key_id, BatchedToken, PublicKey, TokenRequest, + public_key_to_token_key_id, truncate_token_key_id, BatchedToken, PublicKey, TokenRequest, TokenResponse, NK, NS, }; @@ -56,10 +56,17 @@ pub enum RedeemTokenError { /// that the store requires inner mutability. #[async_trait] pub trait BatchedKeyStore: Send + Sync { - /// Inserts a keypair with a given `token_key_id` into the key store. - async fn insert(&self, token_key_id: TokenKeyId, server: VoprfServer); - /// Returns a keypair with a given `token_key_id` from the key store. - async fn get(&self, token_key_id: &TokenKeyId) -> Option>; + /// Inserts a keypair with a given `truncated_token_key_id` into the key store. + async fn insert( + &self, + truncated_token_key_id: TruncatedTokenKeyId, + server: VoprfServer, + ); + /// Returns a keypair with a given `truncated_token_key_id` from the key store. + async fn get( + &self, + truncated_token_key_id: &TruncatedTokenKeyId, + ) -> Option>; } /// Serializes a public key. @@ -111,8 +118,9 @@ impl Server { let server = VoprfServer::::new_from_seed(seed, info) .map_err(|_| CreateKeypairError::SeedError)?; let public_key = server.get_public_key(); - let token_key_id = key_id_to_token_key_id(&public_key_to_key_id(&server.get_public_key())); - key_store.insert(token_key_id, server).await; + let truncated_token_key_id = + truncate_token_key_id(&public_key_to_token_key_id(&server.get_public_key())); + key_store.insert(truncated_token_key_id, server).await; Ok(public_key) } @@ -141,7 +149,7 @@ impl Server { return Err(IssueTokenResponseError::InvalidTokenType); } let server = key_store - .get(&token_request.token_key_id) + .get(&token_request.truncated_token_key_id) .await .ok_or(IssueTokenResponseError::KeyIdNotFound)?; @@ -196,10 +204,10 @@ impl Server { token_type: token.token_type(), nonce: token.nonce(), challenge_digest: *token.challenge_digest(), - key_id: *token.token_key_id(), + token_key_id: *token.token_key_id(), }; let server = key_store - .get(&key_id_to_token_key_id(token.token_key_id())) + .get(&truncate_token_key_id(token.token_key_id())) .await .ok_or(RedeemTokenError::KeyIdNotFound)?; let token_authenticator = server @@ -224,8 +232,10 @@ impl Server { let server = VoprfServer::::new_with_key(private_key) .map_err(|_| CreateKeypairError::SeedError)?; let public_key = server.get_public_key(); - let token_key_id = key_id_to_token_key_id(&public_key_to_key_id(&server.get_public_key())); - key_store.insert(token_key_id, server).await; + let token_key_id = public_key_to_token_key_id(&server.get_public_key()); + key_store + .insert(truncate_token_key_id(&token_key_id), server) + .await; Ok(public_key) } } diff --git a/src/batched_tokens_ristretto255/client.rs b/src/batched_tokens_ristretto255/client.rs index 859f510..0765971 100644 --- a/src/batched_tokens_ristretto255/client.rs +++ b/src/batched_tokens_ristretto255/client.rs @@ -6,12 +6,12 @@ use voprf::{EvaluationElement, Proof, Result, Ristretto255, VoprfClient}; use crate::{ auth::{authenticate::TokenChallenge, authorize::Token}, - ChallengeDigest, KeyId, TokenInput, TokenType, + ChallengeDigest, TokenInput, TokenKeyId, TokenType, }; use super::{ - key_id_to_token_key_id, public_key_to_key_id, BatchedToken, Nonce, PublicKey, TokenRequest, - TokenResponse, + public_key_to_token_key_id, truncate_token_key_id, BatchedToken, Nonce, PublicKey, + TokenRequest, TokenResponse, }; /// Client-side state that is kept between the token requests and token responses. @@ -44,7 +44,7 @@ pub enum IssueTokenError { /// The client side of the batched token issuance protocol. #[derive(Debug)] pub struct Client { - key_id: KeyId, + token_key_id: TokenKeyId, public_key: PublicKey, } @@ -52,9 +52,12 @@ impl Client { /// Create a new client from a public key. #[must_use] pub fn new(public_key: PublicKey) -> Self { - let key_id = public_key_to_key_id(&public_key); + let token_key_id = public_key_to_token_key_id(&public_key); - Self { key_id, public_key } + Self { + token_key_id, + public_key, + } } /// Issue a token request. @@ -96,14 +99,14 @@ impl Client { for nonce in nonces { // nonce = random(32) // challenge_digest = SHA256(challenge) - // token_input = concat(0xF91A, nonce, challenge_digest, key_id) + // token_input = concat(0xF91A, nonce, challenge_digest, token_key_id) // blind, blinded_element = client_context.Blind(token_input) let token_input = TokenInput::new( TokenType::BatchedTokenRistretto255, nonce, challenge_digest, - self.key_id, + self.token_key_id, ); let blinded_element = @@ -137,7 +140,7 @@ impl Client { let token_request = TokenRequest { token_type: TokenType::BatchedTokenRistretto255, - token_key_id: key_id_to_token_key_id(&self.key_id), + truncated_token_key_id: truncate_token_key_id(&self.token_key_id), blinded_elements: blinded_elements.into(), }; @@ -201,7 +204,7 @@ impl Client { TokenType::BatchedTokenRistretto255, token_state.token_input.nonce, token_state.challenge_digest, - token_state.token_input.key_id, + token_state.token_input.token_key_id, *authenticator, ); tokens.push(token); diff --git a/src/batched_tokens_ristretto255/mod.rs b/src/batched_tokens_ristretto255/mod.rs index 46c5b81..9bf7635 100644 --- a/src/batched_tokens_ristretto255/mod.rs +++ b/src/batched_tokens_ristretto255/mod.rs @@ -10,7 +10,7 @@ use tls_codec_derive::{TlsDeserialize, TlsSerialize, TlsSize}; use typenum::U64; pub use voprf::*; -use crate::{auth::authorize::Token, KeyId, Nonce, TokenKeyId, TokenType}; +use crate::{auth::authorize::Token, Nonce, TokenKeyId, TokenType, TruncatedTokenKeyId}; use self::server::serialize_public_key; @@ -26,14 +26,14 @@ pub type BatchedToken = Token; /// Public key alias pub type PublicKey = ::Elem; -fn public_key_to_key_id(public_key: &PublicKey) -> KeyId { +fn public_key_to_token_key_id(public_key: &PublicKey) -> TokenKeyId { let public_key = serialize_public_key(*public_key); Sha256::digest(public_key).into() } -fn key_id_to_token_key_id(key_id: &KeyId) -> TokenKeyId { - *key_id.iter().last().unwrap_or(&0) +fn truncate_token_key_id(token_key_id: &TokenKeyId) -> TruncatedTokenKeyId { + *token_key_id.iter().last().unwrap_or(&0) } /// Serialization error @@ -61,14 +61,14 @@ pub struct BlindedElement { /// ```c /// struct { /// uint16_t token_type = 0xF91A; -/// uint8_t token_key_id; +/// uint8_t truncated_token_key_id; /// BlindedElement blinded_element[Nr]; /// } TokenRequest; /// ``` #[derive(Debug, TlsDeserialize, TlsSerialize, TlsSize)] pub struct TokenRequest { token_type: TokenType, - token_key_id: TokenKeyId, + truncated_token_key_id: TruncatedTokenKeyId, blinded_elements: TlsVecU16, } diff --git a/src/batched_tokens_ristretto255/server.rs b/src/batched_tokens_ristretto255/server.rs index 24f949c..c5661c3 100644 --- a/src/batched_tokens_ristretto255/server.rs +++ b/src/batched_tokens_ristretto255/server.rs @@ -10,11 +10,12 @@ use voprf::{ }; use crate::{ - batched_tokens_ristretto255::EvaluatedElement, NonceStore, TokenInput, TokenKeyId, TokenType, + batched_tokens_ristretto255::EvaluatedElement, NonceStore, TokenInput, TokenType, + TruncatedTokenKeyId, }; use super::{ - key_id_to_token_key_id, public_key_to_key_id, BatchedToken, PublicKey, TokenRequest, + public_key_to_token_key_id, truncate_token_key_id, BatchedToken, PublicKey, TokenRequest, TokenResponse, NK, }; @@ -58,10 +59,17 @@ pub enum RedeemTokenError { /// that the store requires inner mutability. #[async_trait] pub trait BatchedKeyStore: Send + Sync { - /// Inserts a keypair with a given `token_key_id` into the key store. - async fn insert(&self, token_key_id: TokenKeyId, server: VoprfServer); - /// Returns a keypair with a given `token_key_id` from the key store. - async fn get(&self, token_key_id: &TokenKeyId) -> Option>; + /// Inserts a keypair with a given `truncated_token_key_id` into the key store. + async fn insert( + &self, + truncated_token_key_id: TruncatedTokenKeyId, + server: VoprfServer, + ); + /// Returns a keypair with a given `truncated_token_key_id` from the key store. + async fn get( + &self, + truncated_token_key_id: &TruncatedTokenKeyId, + ) -> Option>; } /// Serializes a public key. @@ -113,8 +121,9 @@ impl Server { let server = VoprfServer::::new_from_seed(seed, info) .map_err(|_| CreateKeypairError::SeedError)?; let public_key = server.get_public_key(); - let token_key_id = key_id_to_token_key_id(&public_key_to_key_id(&server.get_public_key())); - key_store.insert(token_key_id, server).await; + let truncated_token_key_id = + truncate_token_key_id(&public_key_to_token_key_id(&server.get_public_key())); + key_store.insert(truncated_token_key_id, server).await; Ok(public_key) } @@ -143,7 +152,7 @@ impl Server { return Err(IssueTokenResponseError::InvalidTokenType); } let server = key_store - .get(&token_request.token_key_id) + .get(&token_request.truncated_token_key_id) .await .ok_or(IssueTokenResponseError::KeyIdNotFound)?; @@ -196,10 +205,10 @@ impl Server { token_type: token.token_type(), nonce: token.nonce(), challenge_digest: *token.challenge_digest(), - key_id: *token.token_key_id(), + token_key_id: *token.token_key_id(), }; let server = key_store - .get(&key_id_to_token_key_id(token.token_key_id())) + .get(&truncate_token_key_id(token.token_key_id())) .await .ok_or(RedeemTokenError::KeyIdNotFound)?; let token_authenticator = server @@ -224,8 +233,9 @@ impl Server { let server = VoprfServer::::new_with_key(private_key) .map_err(|_| CreateKeypairError::SeedError)?; let public_key = server.get_public_key(); - let token_key_id = key_id_to_token_key_id(&public_key_to_key_id(&server.get_public_key())); - key_store.insert(token_key_id, server).await; + let truncated_token_key_id = + truncate_token_key_id(&public_key_to_token_key_id(&server.get_public_key())); + key_store.insert(truncated_token_key_id, server).await; Ok(public_key) } } diff --git a/src/lib.rs b/src/lib.rs index af2aa67..6f21ac4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,9 +43,9 @@ pub enum TokenType { } /// Token key ID -pub type TokenKeyId = u8; +pub type TruncatedTokenKeyId = u8; /// Key ID -pub type KeyId = [u8; 32]; +pub type TokenKeyId = [u8; 32]; /// Nonce pub type Nonce = [u8; 32]; /// Challenge digest @@ -66,7 +66,7 @@ pub(crate) struct TokenInput { token_type: TokenType, nonce: Nonce, challenge_digest: ChallengeDigest, - key_id: KeyId, + token_key_id: TokenKeyId, } impl TokenInput { @@ -74,13 +74,13 @@ impl TokenInput { token_type: TokenType, nonce: Nonce, challenge_digest: ChallengeDigest, - key_id: KeyId, + token_key_id: TokenKeyId, ) -> Self { Self { token_type, nonce, challenge_digest, - key_id, + token_key_id, } } @@ -90,7 +90,7 @@ impl TokenInput { token_input.extend_from_slice((self.token_type as u16).to_be_bytes().as_slice()); token_input.extend_from_slice(self.nonce.as_slice()); token_input.extend_from_slice(self.challenge_digest.as_slice()); - token_input.extend_from_slice(self.key_id.as_slice()); + token_input.extend_from_slice(self.token_key_id.as_slice()); token_input } } diff --git a/src/private_tokens/client.rs b/src/private_tokens/client.rs index fc96db7..2b3e532 100644 --- a/src/private_tokens/client.rs +++ b/src/private_tokens/client.rs @@ -7,12 +7,12 @@ use voprf::{EvaluationElement, Proof, Result, VoprfClient}; use crate::{ auth::{authenticate::TokenChallenge, authorize::Token}, - ChallengeDigest, KeyId, TokenInput, TokenType, + ChallengeDigest, TokenInput, TokenKeyId, TokenType, }; use super::{ - key_id_to_token_key_id, public_key_to_key_id, Nonce, PrivateToken, PublicKey, TokenRequest, - TokenResponse, + public_key_to_token_key_id, truncate_token_key_id, Nonce, PrivateToken, PublicKey, + TokenRequest, TokenResponse, }; /// Client-side state that is kept between the token requests and token responses. @@ -45,7 +45,7 @@ pub enum IssueTokenError { /// The client side of the Privately Verifiable Token protocol. #[derive(Debug)] pub struct Client { - key_id: KeyId, + token_key_id: TokenKeyId, public_key: PublicKey, } @@ -53,9 +53,12 @@ impl Client { /// Create a new client from a public key. #[must_use] pub fn new(public_key: PublicKey) -> Self { - let key_id = public_key_to_key_id(&public_key); + let token_key_id = public_key_to_token_key_id(&public_key); - Self { key_id, public_key } + Self { + token_key_id, + public_key, + } } /// Issue a token request. @@ -84,14 +87,14 @@ impl Client { // nonce = random(32) // challenge_digest = SHA256(challenge) - // token_input = concat(0x0001, nonce, challenge_digest, key_id) + // token_input = concat(0x0001, nonce, challenge_digest, token_key_id) // blind, blinded_element = client_context.Blind(token_input) let token_input = TokenInput::new( TokenType::PrivateToken, nonce, challenge_digest, - self.key_id, + self.token_key_id, ); let blinded_element = VoprfClient::::blind(&token_input.serialize(), &mut OsRng) @@ -107,7 +110,7 @@ impl Client { let token_request = TokenRequest { token_type: TokenType::PrivateToken, - token_key_id: key_id_to_token_key_id(&self.key_id), + truncated_token_key_id: truncate_token_key_id(&self.token_key_id), blinded_msg: blinded_element.message.serialize().into(), }; let token_state = TokenState { @@ -153,7 +156,7 @@ impl Client { TokenType::PrivateToken, token_state.token_input.nonce, token_state.challenge_digest, - token_state.token_input.key_id, + token_state.token_input.token_key_id, authenticator, )) } diff --git a/src/private_tokens/mod.rs b/src/private_tokens/mod.rs index 0c9c8be..4ddd2c3 100644 --- a/src/private_tokens/mod.rs +++ b/src/private_tokens/mod.rs @@ -11,7 +11,7 @@ use tls_codec_derive::{TlsDeserialize, TlsSerialize, TlsSize}; use typenum::U48; pub use voprf::*; -use crate::{auth::authorize::Token, KeyId, Nonce, TokenKeyId, TokenType}; +use crate::{auth::authorize::Token, Nonce, TokenKeyId, TokenType, TruncatedTokenKeyId}; use self::server::serialize_public_key; @@ -28,18 +28,18 @@ pub type PrivateToken = Token; pub type PublicKey = ::Elem; /// Convert a public key to a token key ID. -pub fn public_key_to_token_key_id(public_key: &PublicKey) -> TokenKeyId { - key_id_to_token_key_id(&public_key_to_key_id(public_key)) +pub fn public_key_to_truncated_token_key_id(public_key: &PublicKey) -> TruncatedTokenKeyId { + truncate_token_key_id(&public_key_to_token_key_id(public_key)) } -fn public_key_to_key_id(public_key: &PublicKey) -> KeyId { +fn public_key_to_token_key_id(public_key: &PublicKey) -> TokenKeyId { let public_key = serialize_public_key(*public_key); Sha256::digest(public_key).into() } -fn key_id_to_token_key_id(key_id: &KeyId) -> TokenKeyId { - *key_id.iter().last().unwrap_or(&0) +fn truncate_token_key_id(token_key_id: &TokenKeyId) -> TruncatedTokenKeyId { + *token_key_id.iter().last().unwrap_or(&0) } /// Serialization error @@ -55,14 +55,14 @@ pub enum SerializationError { /// ```c /// struct { /// uint16_t token_type = 0x0001; -/// uint8_t token_key_id; +/// uint8_t truncated_token_key_id; /// uint8_t blinded_msg[Ne]; /// } TokenRequest; /// ``` #[derive(Debug, TlsDeserialize, TlsSerialize, TlsSize)] pub struct TokenRequest { token_type: TokenType, - token_key_id: u8, + truncated_token_key_id: u8, blinded_msg: [u8; NE], } diff --git a/src/private_tokens/server.rs b/src/private_tokens/server.rs index bc6d759..580bbe4 100644 --- a/src/private_tokens/server.rs +++ b/src/private_tokens/server.rs @@ -8,10 +8,11 @@ use rand::{rngs::OsRng, RngCore}; use thiserror::Error; use voprf::{BlindedElement, Error, Group, Result, VoprfServer}; -use crate::{auth::authorize::Token, NonceStore, TokenInput, TokenKeyId, TokenType}; +use crate::{auth::authorize::Token, NonceStore, TokenInput, TokenType, TruncatedTokenKeyId}; use super::{ - key_id_to_token_key_id, public_key_to_key_id, PublicKey, TokenRequest, TokenResponse, NK, NS, + public_key_to_token_key_id, truncate_token_key_id, PublicKey, TokenRequest, TokenResponse, NK, + NS, }; /// Errors that can occur when creating a keypair. @@ -54,10 +55,17 @@ pub enum RedeemTokenError { /// that the store requires inner mutability. #[async_trait] pub trait PrivateKeyStore: Send + Sync { - /// Inserts a keypair with a given `token_key_id` into the key store. - async fn insert(&self, token_key_id: TokenKeyId, server: VoprfServer); - /// Returns a keypair with a given `token_key_id` from the key store. - async fn get(&self, token_key_id: &TokenKeyId) -> Option>; + /// Inserts a keypair with a given `truncated_token_key_id` into the key store. + async fn insert( + &self, + truncated_token_key_id: TruncatedTokenKeyId, + server: VoprfServer, + ); + /// Returns a keypair with a given `truncated_token_key_id` from the key store. + async fn get( + &self, + truncated_token_key_id: &TruncatedTokenKeyId, + ) -> Option>; } /// Serializes a public key. @@ -110,8 +118,9 @@ impl Server { let server = VoprfServer::::new_from_seed(seed, info) .map_err(|_| CreateKeypairError::SeedError)?; let public_key = server.get_public_key(); - let token_key_id = key_id_to_token_key_id(&public_key_to_key_id(&server.get_public_key())); - key_store.insert(token_key_id, server).await; + let truncated_token_key_id = + truncate_token_key_id(&public_key_to_token_key_id(&server.get_public_key())); + key_store.insert(truncated_token_key_id, server).await; Ok(public_key) } @@ -140,7 +149,7 @@ impl Server { return Err(IssueTokenResponseError::InvalidTokenType); } let server = key_store - .get(&token_request.token_key_id) + .get(&token_request.truncated_token_key_id) .await .ok_or(IssueTokenResponseError::KeyIdNotFound)?; let blinded_element = BlindedElement::::deserialize(&token_request.blinded_msg) @@ -181,7 +190,7 @@ impl Server { ); let server = key_store - .get(&key_id_to_token_key_id(token.token_key_id())) + .get(&truncate_token_key_id(token.token_key_id())) .await .ok_or(RedeemTokenError::KeyIdNotFound)?; let token_authenticator = server @@ -206,8 +215,9 @@ impl Server { let server = VoprfServer::::new_with_key(private_key) .map_err(|_| CreateKeypairError::SeedError)?; let public_key = server.get_public_key(); - let token_key_id = key_id_to_token_key_id(&public_key_to_key_id(&server.get_public_key())); - key_store.insert(token_key_id, server).await; + let truncated_token_key_id = + truncate_token_key_id(&public_key_to_token_key_id(&server.get_public_key())); + key_store.insert(truncated_token_key_id, server).await; Ok(public_key) } } diff --git a/src/public_tokens/client.rs b/src/public_tokens/client.rs index 2913f21..cbf5f9e 100644 --- a/src/public_tokens/client.rs +++ b/src/public_tokens/client.rs @@ -7,10 +7,12 @@ use thiserror::Error; use crate::{ auth::{authenticate::TokenChallenge, authorize::Token}, - ChallengeDigest, KeyId, TokenInput, TokenType, + ChallengeDigest, TokenInput, TokenKeyId, TokenType, }; -use super::{key_id_to_token_key_id, public_key_to_key_id, Nonce, TokenRequest, TokenResponse, NK}; +use super::{ + public_key_to_token_key_id, truncate_token_key_id, Nonce, TokenRequest, TokenResponse, NK, +}; /// Client-side state that is kept between the token requests and token responses. #[derive(Debug)] @@ -42,7 +44,7 @@ pub enum IssueTokenError { /// The client side of the Publicly Verifiable Token protocol. #[derive(Debug)] pub struct Client { - key_id: KeyId, + token_key_id: TokenKeyId, public_key: PublicKey, } @@ -50,9 +52,12 @@ impl Client { /// Create a new client from a public key. #[must_use] pub fn new(public_key: PublicKey) -> Self { - let key_id = public_key_to_key_id(&public_key); + let token_key_id = public_key_to_token_key_id(&public_key); - Self { key_id, public_key } + Self { + token_key_id, + public_key, + } } /// Issue a token request. @@ -76,8 +81,12 @@ impl Client { // token_input = concat(0x0002, nonce, challenge_digest, token_key_id) // blinded_msg, blind_inv = rsabssa_blind(pkI, token_input) - let token_input = - TokenInput::new(TokenType::PublicToken, nonce, challenge_digest, self.key_id); + let token_input = TokenInput::new( + TokenType::PublicToken, + nonce, + challenge_digest, + self.token_key_id, + ); let options = Options::default(); let blinding_result = self @@ -91,7 +100,7 @@ impl Client { let token_request = TokenRequest { token_type: TokenType::PublicToken, - token_key_id: key_id_to_token_key_id(&self.key_id), + truncated_token_key_id: truncate_token_key_id(&self.token_key_id), blinded_msg, }; @@ -132,7 +141,7 @@ impl Client { TokenType::PublicToken, token_state.token_input.nonce, token_state.challenge_digest, - token_state.token_input.key_id, + token_state.token_input.token_key_id, authenticator, )) } diff --git a/src/public_tokens/mod.rs b/src/public_tokens/mod.rs index efffc69..b9bbaab 100644 --- a/src/public_tokens/mod.rs +++ b/src/public_tokens/mod.rs @@ -4,7 +4,7 @@ use sha2::{Digest, Sha256}; use tls_codec_derive::{TlsDeserialize, TlsSerialize, TlsSize}; use typenum::U64; -use crate::{auth::authorize::Token, KeyId, Nonce, TokenKeyId, TokenType}; +use crate::{auth::authorize::Token, Nonce, TokenKeyId, TokenType, TruncatedTokenKeyId}; pub mod client; pub mod server; @@ -19,18 +19,18 @@ use self::server::serialize_public_key; pub const NK: usize = 256; /// Converts a public key to a token key ID -pub fn public_key_to_token_key_id(public_key: &PublicKey) -> TokenKeyId { - key_id_to_token_key_id(&public_key_to_key_id(public_key)) +pub fn public_key_to_truncated_token_key_id(public_key: &PublicKey) -> TruncatedTokenKeyId { + truncate_token_key_id(&public_key_to_token_key_id(public_key)) } -fn public_key_to_key_id(public_key: &PublicKey) -> KeyId { +fn public_key_to_token_key_id(public_key: &PublicKey) -> TokenKeyId { let public_key = serialize_public_key(public_key); Sha256::digest(public_key).into() } -fn key_id_to_token_key_id(key_id: &KeyId) -> TokenKeyId { - *key_id.iter().last().unwrap_or(&0) +fn truncate_token_key_id(token_key_id: &TokenKeyId) -> TruncatedTokenKeyId { + *token_key_id.iter().last().unwrap_or(&0) } /// Token request as specified in the spec: @@ -38,14 +38,14 @@ fn key_id_to_token_key_id(key_id: &KeyId) -> TokenKeyId { /// ```c /// struct { /// uint16_t token_type = 0x0002; -/// uint8_t token_key_id; +/// uint8_t truncated_token_key_id; /// uint8_t blinded_msg[Nk]; /// } TokenRequest; /// ``` #[derive(Debug, TlsDeserialize, TlsSerialize, TlsSize)] pub struct TokenRequest { token_type: TokenType, - token_key_id: u8, + truncated_token_key_id: u8, blinded_msg: [u8; NK], } diff --git a/src/public_tokens/server.rs b/src/public_tokens/server.rs index 9f09585..51cd34c 100644 --- a/src/public_tokens/server.rs +++ b/src/public_tokens/server.rs @@ -6,9 +6,9 @@ use generic_array::ArrayLength; use rand::{rngs::OsRng, CryptoRng, RngCore}; use thiserror::Error; -use crate::{auth::authorize::Token, NonceStore, TokenInput, TokenKeyId, TokenType}; +use crate::{auth::authorize::Token, NonceStore, TokenInput, TokenType, TruncatedTokenKeyId}; -use super::{key_id_to_token_key_id, public_key_to_key_id, TokenRequest, TokenResponse, NK}; +use super::{public_key_to_token_key_id, truncate_token_key_id, TokenRequest, TokenResponse, NK}; /// Errors that can occur when creating a keypair. #[derive(Error, Debug, PartialEq, Eq)] @@ -51,20 +51,20 @@ pub enum RedeemTokenError { #[async_trait] pub trait IssuerKeyStore: Send + Sync { - /// Inserts a keypair with a given `token_key_id` into the key store. - async fn insert(&self, token_key_id: TokenKeyId, server: KeyPair); - /// Returns a keypair with a given `token_key_id` from the key store. - async fn get(&self, token_key_id: &TokenKeyId) -> Option; + /// Inserts a keypair with a given `truncated_token_key_id` into the key store. + async fn insert(&self, truncated_token_key_id: TruncatedTokenKeyId, server: KeyPair); + /// Returns a keypair with a given `truncated_token_key_id` from the key store. + async fn get(&self, truncated_token_key_id: &TruncatedTokenKeyId) -> Option; } /// Minimal trait for a key store to store key material on the server-side. Note /// that the store requires inner mutability. #[async_trait] pub trait OriginKeyStore { - /// Inserts a keypair with a given `token_key_id` into the key store. - async fn insert(&self, token_key_id: TokenKeyId, server: PublicKey); - /// Returns a keypair with a given `token_key_id` from the key store. - async fn get(&self, token_key_id: &TokenKeyId) -> Option; + /// Inserts a keypair with a given `truncated_token_key_id` into the key store. + async fn insert(&self, truncated_token_key_id: TruncatedTokenKeyId, server: PublicKey); + /// Returns a keypair with a given `truncated_token_key_id` from the key store. + async fn get(&self, truncated_token_key_id: &TruncatedTokenKeyId) -> Option; } /// Serializes a keypair into a DER-encoded PKCS#8 document. @@ -99,8 +99,11 @@ impl IssuerServer { ) -> Result { let key_pair = KeyPair::generate(rng, KEYSIZE_IN_BITS).map_err(|_| CreateKeypairError::SeedError)?; - let token_key_id = key_id_to_token_key_id(&public_key_to_key_id(&key_pair.pk)); - key_store.insert(token_key_id, key_pair.clone()).await; + let truncated_token_key_id = + truncate_token_key_id(&public_key_to_token_key_id(&key_pair.pk)); + key_store + .insert(truncated_token_key_id, key_pair.clone()) + .await; Ok(key_pair) } @@ -118,7 +121,7 @@ impl IssuerServer { return Err(IssueTokenResponseError::InvalidTokenType); } let key_pair = key_store - .get(&token_request.token_key_id) + .get(&token_request.truncated_token_key_id) .await .ok_or(IssueTokenResponseError::KeyIdNotFound)?; @@ -139,8 +142,9 @@ impl IssuerServer { /// Sets the given keypair. #[cfg(feature = "kat")] pub async fn set_keypair(&self, key_store: &IKS, key_pair: KeyPair) { - let token_key_id = key_id_to_token_key_id(&public_key_to_key_id(&key_pair.pk)); - key_store.insert(token_key_id, key_pair).await; + let truncated_token_key_id = + truncate_token_key_id(&public_key_to_token_key_id(&key_pair.pk)); + key_store.insert(truncated_token_key_id, key_pair).await; } } @@ -182,7 +186,7 @@ impl OriginServer { ); let public_key = key_store - .get(&key_id_to_token_key_id(token.token_key_id())) + .get(&truncate_token_key_id(token.token_key_id())) .await .ok_or(RedeemTokenError::KeyIdNotFound)?; diff --git a/tests/batched_memory_stores.rs b/tests/batched_memory_stores.rs index 120e904..c04cfa1 100644 --- a/tests/batched_memory_stores.rs +++ b/tests/batched_memory_stores.rs @@ -6,7 +6,7 @@ use voprf::*; //use privacypass::batched_tokens::server::BatchedKeyStore; //use privacypass::batched_tokens_2::server; -use privacypass::{Nonce, NonceStore, TokenKeyId}; +use privacypass::{Nonce, NonceStore, TruncatedTokenKeyId}; #[derive(Default)] pub struct MemoryNonceStore { @@ -28,36 +28,50 @@ impl NonceStore for MemoryNonceStore { #[derive(Default)] pub struct MemoryKeyStoreRistretto255 { - keys: Mutex>>, + keys: Mutex>>, } #[async_trait] impl privacypass::batched_tokens_ristretto255::server::BatchedKeyStore for MemoryKeyStoreRistretto255 { - async fn insert(&self, token_key_id: TokenKeyId, server: VoprfServer) { + async fn insert( + &self, + truncated_token_key_id: TruncatedTokenKeyId, + server: VoprfServer, + ) { let mut keys = self.keys.lock().await; - keys.insert(token_key_id, server); + keys.insert(truncated_token_key_id, server); } - async fn get(&self, token_key_id: &TokenKeyId) -> Option> { - self.keys.lock().await.get(token_key_id).cloned() + async fn get( + &self, + truncated_token_key_id: &TruncatedTokenKeyId, + ) -> Option> { + self.keys.lock().await.get(truncated_token_key_id).cloned() } } #[derive(Default)] pub struct MemoryKeyStoreP384 { - keys: Mutex>>, + keys: Mutex>>, } #[async_trait] impl privacypass::batched_tokens_p384::server::BatchedKeyStore for MemoryKeyStoreP384 { - async fn insert(&self, token_key_id: TokenKeyId, server: VoprfServer) { + async fn insert( + &self, + truncated_token_key_id: TruncatedTokenKeyId, + server: VoprfServer, + ) { let mut keys = self.keys.lock().await; - keys.insert(token_key_id, server); + keys.insert(truncated_token_key_id, server); } - async fn get(&self, token_key_id: &TokenKeyId) -> Option> { - self.keys.lock().await.get(token_key_id).cloned() + async fn get( + &self, + truncated_token_key_id: &TruncatedTokenKeyId, + ) -> Option> { + self.keys.lock().await.get(truncated_token_key_id).cloned() } } diff --git a/tests/kat_public.rs b/tests/kat_public.rs index 9579594..f2d489d 100644 --- a/tests/kat_public.rs +++ b/tests/kat_public.rs @@ -12,7 +12,7 @@ use tls_codec::Serialize as TlsSerializeTrait; use privacypass::{ auth::authenticate::TokenChallenge, - public_tokens::{client::*, public_key_to_token_key_id, server::*}, + public_tokens::{client::*, public_key_to_truncated_token_key_id, server::*}, Nonce, }; @@ -80,7 +80,10 @@ async fn evaluate_kat(list: Vec) { // Origin key store: Set the public key origin_key_store - .insert(public_key_to_token_key_id(&pub_key), pub_key.clone()) + .insert( + public_key_to_truncated_token_key_id(&pub_key), + pub_key.clone(), + ) .await; // Client: Create client @@ -162,7 +165,10 @@ async fn write_kat_public_token() { // Origin key store: Set the public key origin_key_store - .insert(public_key_to_token_key_id(&keypair.pk), keypair.pk.clone()) + .insert( + public_key_to_truncated_token_key_id(&keypair.pk), + keypair.pk.clone(), + ) .await; // Client: Create client diff --git a/tests/private_memory_stores.rs b/tests/private_memory_stores.rs index e68a770..8275a68 100644 --- a/tests/private_memory_stores.rs +++ b/tests/private_memory_stores.rs @@ -5,7 +5,7 @@ use tokio::sync::Mutex; use voprf::*; use privacypass::private_tokens::server::*; -use privacypass::{Nonce, NonceStore, TokenKeyId}; +use privacypass::{Nonce, NonceStore, TruncatedTokenKeyId}; #[derive(Default)] pub struct MemoryNonceStore { @@ -27,17 +27,24 @@ impl NonceStore for MemoryNonceStore { #[derive(Default)] pub struct MemoryKeyStore { - keys: Mutex>>, + keys: Mutex>>, } #[async_trait] impl PrivateKeyStore for MemoryKeyStore { - async fn insert(&self, token_key_id: TokenKeyId, server: VoprfServer) { + async fn insert( + &self, + truncated_token_key_id: TruncatedTokenKeyId, + server: VoprfServer, + ) { let mut keys = self.keys.lock().await; - keys.insert(token_key_id, server); + keys.insert(truncated_token_key_id, server); } - async fn get(&self, token_key_id: &TokenKeyId) -> Option> { - self.keys.lock().await.get(token_key_id).cloned() + async fn get( + &self, + truncated_token_key_id: &TruncatedTokenKeyId, + ) -> Option> { + self.keys.lock().await.get(truncated_token_key_id).cloned() } } diff --git a/tests/public_memory_stores.rs b/tests/public_memory_stores.rs index e11a06e..764ee9c 100644 --- a/tests/public_memory_stores.rs +++ b/tests/public_memory_stores.rs @@ -3,7 +3,7 @@ use tokio::sync::Mutex; use async_trait::async_trait; use blind_rsa_signatures::{KeyPair, PublicKey}; -use privacypass::{public_tokens::server::*, Nonce, NonceStore, TokenKeyId}; +use privacypass::{public_tokens::server::*, Nonce, NonceStore, TruncatedTokenKeyId}; #[derive(Default)] pub struct MemoryNonceStore { @@ -25,34 +25,34 @@ impl NonceStore for MemoryNonceStore { #[derive(Default)] pub struct IssuerMemoryKeyStore { - keys: Mutex>, + keys: Mutex>, } #[async_trait] impl IssuerKeyStore for IssuerMemoryKeyStore { - async fn insert(&self, token_key_id: TokenKeyId, key_pair: KeyPair) { + async fn insert(&self, truncated_token_key_id: TruncatedTokenKeyId, key_pair: KeyPair) { let mut keys = self.keys.lock().await; - keys.insert(token_key_id, key_pair); + keys.insert(truncated_token_key_id, key_pair); } - async fn get(&self, token_key_id: &TokenKeyId) -> Option { - self.keys.lock().await.get(token_key_id).cloned() + async fn get(&self, truncated_token_key_id: &TruncatedTokenKeyId) -> Option { + self.keys.lock().await.get(truncated_token_key_id).cloned() } } #[derive(Default)] pub struct OriginMemoryKeyStore { - keys: Mutex>, + keys: Mutex>, } #[async_trait] impl OriginKeyStore for OriginMemoryKeyStore { - async fn insert(&self, token_key_id: TokenKeyId, public_key: PublicKey) { + async fn insert(&self, truncated_token_key_id: TruncatedTokenKeyId, public_key: PublicKey) { let mut keys = self.keys.lock().await; - keys.insert(token_key_id, public_key); + keys.insert(truncated_token_key_id, public_key); } - async fn get(&self, token_key_id: &TokenKeyId) -> Option { - self.keys.lock().await.get(token_key_id).cloned() + async fn get(&self, truncated_token_key_id: &TruncatedTokenKeyId) -> Option { + self.keys.lock().await.get(truncated_token_key_id).cloned() } } diff --git a/tests/public_tokens.rs b/tests/public_tokens.rs index a2fb340..3cc8767 100644 --- a/tests/public_tokens.rs +++ b/tests/public_tokens.rs @@ -4,7 +4,7 @@ use public_memory_stores::*; use privacypass::{ auth::authenticate::TokenChallenge, - public_tokens::{client::*, public_key_to_token_key_id, server::*}, + public_tokens::{client::*, public_key_to_truncated_token_key_id, server::*}, TokenType, }; use rand::thread_rng; @@ -31,7 +31,10 @@ async fn public_tokens_cycle() { let public_key = key_pair.pk; origin_key_store - .insert(public_key_to_token_key_id(&public_key), public_key.clone()) + .insert( + public_key_to_truncated_token_key_id(&public_key), + public_key.clone(), + ) .await; // Client: Create client