freepass issuance API side

This commit is contained in:
Simon Wicky
2024-05-07 10:55:09 +02:00
parent 7247e11b9e
commit 24d75e10cf
3 changed files with 30 additions and 60 deletions
+9 -12
View File
@@ -135,7 +135,7 @@ pub struct FreePassRequest {
// secp256k1 key associated with the admin account
pub cosmos_pubkey: cosmrs::crypto::PublicKey,
pub inner_sign_request: BlindSignRequest,
pub inner_sign_request: WithdrawalRequest,
// we need to include a nonce here to prevent replay attacks
// (and not making the nym-api store the serial numbers of all issued credential)
@@ -145,36 +145,33 @@ pub struct FreePassRequest {
/// to prove the possession of the cosmos key/address
pub nonce_signature: cosmrs::crypto::secp256k1::Signature,
pub public_attributes_plain: Vec<String>,
pub ecash_pubkey: PublicKeyUser,
pub expiration_date: u64,
}
impl FreePassRequest {
pub fn new(
cosmos_pubkey: cosmrs::crypto::PublicKey,
inner_sign_request: BlindSignRequest,
inner_sign_request: WithdrawalRequest,
used_nonce: [u8; 16],
nonce_signature: cosmrs::crypto::secp256k1::Signature,
public_attributes_plain: Vec<String>,
ecash_pubkey: PublicKeyUser,
expiration_date: u64,
) -> Self {
FreePassRequest {
cosmos_pubkey,
inner_sign_request,
used_nonce,
nonce_signature,
public_attributes_plain,
ecash_pubkey,
expiration_date,
}
}
pub fn tendermint_pubkey(&self) -> tendermint::PublicKey {
self.cosmos_pubkey.into()
}
pub fn public_attributes_hashed(&self) -> Vec<Attribute> {
self.public_attributes_plain
.iter()
.map(hash_to_scalar)
.collect()
}
}
#[derive(Serialize, Deserialize)]
+14 -45
View File
@@ -30,48 +30,6 @@ use time::OffsetDateTime;
mod helpers;
fn validate_freepass_public_attributes(res: &FreePassRequest) -> Result<()> {
let public_attributes = &res.public_attributes_plain;
if public_attributes.len() != IssuanceBandwidthCredential::PUBLIC_ATTRIBUTES as usize {
return Err(CoconutError::InvalidFreePassAttributes {
got: public_attributes.len(),
expected: IssuanceBandwidthCredential::PUBLIC_ATTRIBUTES as usize,
});
}
// SAFETY: we just ensured correct number of attributes
let expiry_raw = public_attributes.first().unwrap();
let type_raw = public_attributes.get(1).unwrap();
let parsed_type = type_raw.parse::<CredentialType>()?;
if parsed_type != CredentialType::FreePass {
return Err(CoconutError::InvalidFreePassTypeAttribute { got: parsed_type });
}
let expiry_timestamp: i64 = expiry_raw
.parse()
.map_err(|source| CoconutError::ExpiryDateParsingFailure { source })?;
let expiry_date = OffsetDateTime::from_unix_timestamp(expiry_timestamp).map_err(|source| {
CoconutError::InvalidExpiryDate {
unix_timestamp: expiry_timestamp,
source,
}
})?;
let now = OffsetDateTime::now_utc();
if expiry_date > now + MAX_FREE_PASS_VALIDITY {
return Err(CoconutError::TooLongFreePass { expiry_date });
}
if expiry_date < now {
return Err(CoconutError::FreePassExpiryInThePast { expiry_date });
}
Ok(())
}
#[get("/free-pass-nonce")]
pub async fn get_current_free_pass_nonce(
state: &RocketState<State>,
@@ -94,7 +52,16 @@ pub async fn post_free_pass(
debug!("Received free pass sign request");
trace!("body: {:?}", freepass_request_body);
validate_freepass_public_attributes(&freepass_request_body)?;
//check expiration date validity
if freepass_request_body.expiration_date > freepass_exp_date_timestamp() {
return Err(CoconutError::TooLongFreePass {
expiry_date: OffsetDateTime::from_unix_timestamp(
//safety : expiration date is a unix timestamp so these unwraps will not fail for 290 million years
freepass_request_body.expiration_date.try_into().unwrap(),
)
.unwrap(),
});
}
// grab the admin of the bandwidth contract
let Some(authorised_admin) = state.get_bandwidth_contract_admin().await? else {
@@ -161,8 +128,10 @@ pub async fn post_free_pass(
// produce the partial signature
debug!("producing the partial credential");
let blinded_signature =
blind_sign(freepass_request_body.deref(), signing_key.keys.secret_key())?;
let blinded_signature = blind_sign(
freepass_request_body.deref(),
&signing_key.keys.secret_key(),
)?;
// update the number of issued free passes
state.storage.increment_issued_freepasses().await?;
+7 -3
View File
@@ -51,12 +51,16 @@ impl CredentialRequest for BlindSignRequestBody {
}
impl CredentialRequest for FreePassRequest {
fn blind_sign_request(&self) -> &BlindSignRequest {
fn withdrawal_request(&self) -> &WithdrawalRequest {
&self.inner_sign_request
}
fn public_attributes(&self) -> Vec<Attribute> {
self.public_attributes_hashed()
fn expiration_date(&self) -> u64 {
self.expiration_date
}
fn ecash_pubkey(&self) -> PublicKeyUser {
self.ecash_pubkey.clone()
}
}