Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/amortized_tokens/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl<CS: PrivateCipherSuite> AmortizedBatchTokenRequest<CS> {
) -> Result<(AmortizedBatchTokenRequest<CS>, TokenState<CS>), IssueTokenRequestError> {
let challenge_digest = challenge
.digest()
.map_err(|_| IssueTokenRequestError::InvalidTokenChallenge)?;
.map_err(|source| IssueTokenRequestError::InvalidTokenChallenge { source })?;

let token_key_id = public_key_to_token_key_id::<CS>(&public_key);

Expand All @@ -125,16 +125,21 @@ impl<CS: PrivateCipherSuite> AmortizedBatchTokenRequest<CS> {
token_key_id,
);

let blind = VoprfClient::<CS>::blind(&token_input.serialize(), &mut OsRng)
.map_err(|_| IssueTokenRequestError::BlindingError)?;
let blind = VoprfClient::<CS>::blind(&token_input.serialize(), &mut OsRng).map_err(
|source| IssueTokenRequestError::BlindingError {
source: source.into(),
},
)?;

#[cfg(feature = "kat")]
let blind = if _blinds.is_some() {
VoprfClient::<CS>::deterministic_blind_unchecked(
&token_input.serialize(),
*blinds_iter.next().unwrap(),
)
.map_err(|_| IssueTokenRequestError::BlindingError)?
.map_err(|source| IssueTokenRequestError::BlindingError {
source: source.into(),
})?
} else {
blind
};
Expand Down
40 changes: 31 additions & 9 deletions src/amortized_tokens/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ impl<CS: PrivateCipherSuite> AmortizedBatchTokenResponse<CS> {
/// valid `TokenResponse`.
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, SerializationError> {
let mut bytes = bytes;
Self::tls_deserialize(&mut bytes).map_err(|_| SerializationError::InvalidData)
Self::tls_deserialize(&mut bytes)
.map_err(|source| SerializationError::InvalidData { source })
}

/// Issue a token.
Expand All @@ -64,15 +65,30 @@ impl<CS: PrivateCipherSuite> AmortizedBatchTokenResponse<CS> {
token_state: &TokenState<CS>,
) -> Result<Vec<AmortizedToken<CS>>, IssueTokenError> {
let mut evaluated_elements = Vec::new();
for element in self.evaluated_elements.iter() {
let evaluated_element =
EvaluationElement::<CS>::deserialize(&element.evaluated_element)
.map_err(|_| IssueTokenError::InvalidTokenResponse)?;
let default_token_type = token_state
.token_inputs
.first()
.map(|token_input| token_input.token_type)
.unwrap_or_else(CS::token_type);
for (index, element) in self.evaluated_elements.iter().enumerate() {
let token_type = token_state
.token_inputs
.get(index)
.map(|token_input| token_input.token_type)
.unwrap_or(default_token_type);
let evaluated_element = EvaluationElement::<CS>::deserialize(
&element.evaluated_element,
)
.map_err(|source| IssueTokenError::InvalidEvaluationElement { token_type, source })?;
evaluated_elements.push(evaluated_element);
}

let proof = Proof::deserialize(&self.evaluated_proof)
.map_err(|_| IssueTokenError::InvalidTokenResponse)?;
let proof = Proof::deserialize(&self.evaluated_proof).map_err(|source| {
IssueTokenError::InvalidProof {
token_type: default_token_type,
source,
}
})?;

let client_batch_finalize_result = VoprfClient::batch_finalize(
&token_state
Expand All @@ -85,9 +101,15 @@ impl<CS: PrivateCipherSuite> AmortizedBatchTokenResponse<CS> {
&proof,
token_state.public_key,
)
.map_err(|_| IssueTokenError::InvalidTokenResponse)?
.map_err(|source| IssueTokenError::BatchFinalizationFailed {
token_type: default_token_type,
source,
})?
.collect::<Result<Vec<_>>>()
.map_err(|_| IssueTokenError::InvalidTokenResponse)?;
.map_err(|source| IssueTokenError::BatchFinalizationFailed {
token_type: default_token_type,
source,
})?;

let mut tokens = Vec::new();

Expand Down
39 changes: 27 additions & 12 deletions src/amortized_tokens/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ impl<CS: PrivateCipherSuite> Server<CS> {
<CS::Group as Group>::Scalar: Send + Sync,
<CS::Group as Group>::Elem: Send + Sync,
{
VoprfServer::<CS>::new_from_seed(seed, info).map_err(|_| CreateKeypairError::SeedError)
VoprfServer::<CS>::new_from_seed(seed, info)
.map_err(|source| CreateKeypairError::SeedError { source })
}

/// Create a new server. The new server does not contain any key material.
Expand Down Expand Up @@ -103,7 +104,10 @@ impl<CS: PrivateCipherSuite> Server<CS> {
token_request: AmortizedBatchTokenRequest<CS>,
) -> Result<AmortizedBatchTokenResponse<CS>, IssueTokenResponseError> {
if token_request.token_type != CS::token_type() {
return Err(IssueTokenResponseError::InvalidTokenType);
return Err(IssueTokenResponseError::InvalidTokenType {
expected: CS::token_type(),
found: token_request.token_type,
});
}
let server = key_store
.get(&token_request.truncated_token_key_id)
Expand All @@ -113,7 +117,7 @@ impl<CS: PrivateCipherSuite> Server<CS> {
let mut blinded_elements = Vec::new();
for element in token_request.blinded_elements.iter() {
let blinded_element = BlindedElement::<CS>::deserialize(&element.blinded_element)
.map_err(|_| IssueTokenResponseError::InvalidTokenRequest)?;
.map_err(|source| IssueTokenResponseError::InvalidBlindedMessage { source })?;
blinded_elements.push(blinded_element);
}

Expand All @@ -122,7 +126,7 @@ impl<CS: PrivateCipherSuite> Server<CS> {
.collect::<Vec<_>>();
let VoprfServerBatchEvaluateFinishResult { messages, proof } = server
.batch_blind_evaluate_finish(&mut OsRng, blinded_elements.iter(), &prepared_elements)
.map_err(|_| IssueTokenResponseError::InvalidTokenRequest)?;
.map_err(|source| IssueTokenResponseError::BlindEvaluationFailed { source })?;

let evaluated_elements = messages
.map(|m| super::EvaluatedElement {
Expand All @@ -149,18 +153,26 @@ impl<CS: PrivateCipherSuite> Server<CS> {
nonce_store: &NS,
token: AmortizedToken<CS>,
) -> Result<(), RedeemTokenError> {
if token.token_type() != CS::token_type() {
return Err(RedeemTokenError::InvalidToken);
let token_type = token.token_type();
if token_type != CS::token_type() {
return Err(RedeemTokenError::TokenTypeMismatch {
expected: CS::token_type(),
found: token_type,
});
}
let auth_len = <<CS::Hash as OutputSizeUser>::OutputSize as Unsigned>::USIZE;
if token.authenticator().len() != auth_len {
return Err(RedeemTokenError::InvalidToken);
let authenticator_len = token.authenticator().len();
if authenticator_len != auth_len {
return Err(RedeemTokenError::InvalidAuthenticatorLength {
expected: auth_len,
found: authenticator_len,
});
}
if nonce_store.exists(&token.nonce()).await {
return Err(RedeemTokenError::DoubleSpending);
}
let token_input = TokenInput {
token_type: token.token_type(),
token_type,
nonce: token.nonce(),
challenge_digest: *token.challenge_digest(),
token_key_id: *token.token_key_id(),
Expand All @@ -171,13 +183,16 @@ impl<CS: PrivateCipherSuite> Server<CS> {
.ok_or(RedeemTokenError::KeyIdNotFound)?;
let token_authenticator = server
.evaluate(&token_input.serialize())
.map_err(|_| RedeemTokenError::InvalidToken)?
.map_err(|source| RedeemTokenError::AuthenticatorDerivationFailed {
token_type,
source,
})?
.to_vec();
if token.authenticator() == token_authenticator {
nonce_store.insert(token.nonce()).await;
Ok(())
} else {
Err(RedeemTokenError::InvalidToken)
Err(RedeemTokenError::AuthenticatorMismatch { token_type })
}
}

Expand All @@ -193,7 +208,7 @@ impl<CS: PrivateCipherSuite> Server<CS> {
<CS::Group as Group>::Elem: Send + Sync,
{
let server = VoprfServer::<CS>::new_with_key(private_key)
.map_err(|_| CreateKeypairError::SeedError)?;
.map_err(|source| CreateKeypairError::SeedError { source })?;
let public_key = server.get_public_key();
let token_key_id = public_key_to_token_key_id::<CS>(&server.get_public_key());
key_store
Expand Down
4 changes: 2 additions & 2 deletions src/auth/authenticate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ impl TokenChallenge {
}

/// An error that occurred during serialization or deserialization.
#[derive(Error, Debug)]
#[derive(PartialEq, Eq, Error, Debug)]
pub enum SerializationError {
#[error("Invalid TokenChallenge")]
/// Invalid TokenChallenge
Expand Down Expand Up @@ -174,7 +174,7 @@ pub fn build_www_authenticate_header(
}

/// Building error for the `Authorization` header values
#[derive(Error, Debug)]
#[derive(PartialEq, Eq, Error, Debug)]
pub enum BuildError {
#[error("Invalid TokenChallenge")]
/// Invalid TokenChallenge
Expand Down
4 changes: 2 additions & 2 deletions src/auth/authorize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ pub fn build_authorization_header<Nk: ArrayLength>(
}

/// Building error for the `Authorization` header values
#[derive(Error, Debug)]
#[derive(PartialEq, Eq, Error, Debug)]
pub enum BuildError {
#[error("Invalid token")]
/// Invalid token
Expand All @@ -172,7 +172,7 @@ pub fn parse_authorization_header<Nk: ArrayLength>(
}

/// Parsing error for the `WWW-Authenticate` header values
#[derive(Error, Debug)]
#[derive(PartialEq, Eq, Error, Debug)]
pub enum ParseError {
#[error("Invalid token")]
/// Invalid token
Expand Down
Loading