Skip to content

Commit

Permalink
use certificate action as the signing data for signature verification…
Browse files Browse the repository at this point in the history
… for certificate actions
  • Loading branch information
vedhavyas committed Apr 2, 2024
1 parent 4863bb8 commit 5de3054
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 15 deletions.
77 changes: 66 additions & 11 deletions domains/pallets/auto-id/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ pub struct X509Certificate {
pub issued_serials: BTreeSet<U256>,
/// Signifies if the certificate is revoked.
pub revoked: bool,
/// Certificate action nonce.
pub nonce: U256,
}

/// Certificate associated with AutoId.
Expand Down Expand Up @@ -109,13 +111,29 @@ impl Certificate {
Certificate::X509(cert) => cert.revoked,
}
}

fn nonce(&self) -> U256 {
match self {
Certificate::X509(cert) => cert.nonce,
}
}

fn inc_nonce<T: Config>(&mut self) -> DispatchResult {
match self {
Certificate::X509(cert) => {
cert.nonce = cert
.nonce
.checked_add(U256::one())
.ok_or(Error::<T>::NonceOverflow)?;
Ok(())
}
}
}
}

/// A representation of AutoId
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
pub struct AutoId {
/// Unique AutoID identifier.
pub identifier: Identifier,
/// Certificate associated with this AutoId.
pub certificate: Certificate,
}
Expand Down Expand Up @@ -149,6 +167,21 @@ pub enum RegisterAutoId {
X509(RegisterAutoIdX509),
}

/// Specific action type taken by the subject of the Certificate.
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
pub enum CertificateActionType {
RevokeCertificate,
DeactivateAutoId,
}

/// Signing data used to verify the certificate action.
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
pub struct CertificateAction {
pub id: Identifier,
pub nonce: U256,
pub action_type: CertificateActionType,
}

#[frame_support::pallet]
mod pallet {
use crate::{AutoId, Identifier, RegisterAutoId, Signature};
Expand Down Expand Up @@ -190,6 +223,8 @@ mod pallet {
ExpiredCertificate,
/// Certificate revoked.
CertificateRevoked,
/// Nonce overflow.
NonceOverflow,
}

#[pallet::event]
Expand Down Expand Up @@ -280,6 +315,7 @@ impl<T: Config> Pallet<T> {
raw: certificate,
issued_serials: BTreeSet::from([tbs_certificate.serial]),
revoked: false,
nonce: U256::zero(),
})
}
RegisterAutoIdX509::Leaf {
Expand Down Expand Up @@ -333,6 +369,7 @@ impl<T: Config> Pallet<T> {
raw: certificate,
issued_serials: BTreeSet::from([tbs_certificate.serial]),
revoked: false,
nonce: U256::zero(),
})
}
},
Expand All @@ -344,27 +381,27 @@ impl<T: Config> Pallet<T> {
.ok_or(Error::<T>::IdentifierOverflow)?;
NextAutoIdIdentifier::<T>::put(next_auto_id_identifier);

let auto_id = AutoId {
identifier: auto_id_identifier,
certificate,
};
let auto_id = AutoId { certificate };

AutoIds::<T>::insert(auto_id_identifier, auto_id);

Self::deposit_event(Event::<T>::NewAutoIdRegistered(auto_id_identifier));
Ok(())
}

fn do_verify_signature(auto_id: &AutoId, signature: Signature) -> DispatchResult {
fn do_verify_signature(
auto_id: &AutoId,
signing_data: CertificateAction,
signature: Signature,
) -> DispatchResult {
let Signature {
signature_algorithm,
value: signature,
} = signature;
let req = SignatureVerificationRequest {
public_key_info: auto_id.certificate.subject_public_key_info(),
signature_algorithm,
// uses auto_id identifier as the message to sign
data: auto_id.identifier.encode(),
data: signing_data.encode(),
signature,
};

Expand All @@ -377,13 +414,23 @@ impl<T: Config> Pallet<T> {
signature: Signature,
) -> DispatchResult {
let mut auto_id = AutoIds::<T>::get(auto_id_identifier).ok_or(Error::<T>::UnknownIssuer)?;
Self::do_verify_signature(&auto_id, signature)?;
Self::do_verify_signature(
&auto_id,
CertificateAction {
id: auto_id_identifier,
nonce: auto_id.certificate.nonce(),
action_type: CertificateActionType::RevokeCertificate,
},
signature,
)?;
ensure!(
!auto_id.certificate.is_revoked(),
Error::<T>::CertificateRevoked
);

auto_id.certificate.revoke();
auto_id.certificate.inc_nonce::<T>()?;

// TODO: revoke all the issued leaf certificates if this is an issuer certificate.
AutoIds::<T>::insert(auto_id_identifier, auto_id);

Expand All @@ -396,7 +443,15 @@ impl<T: Config> Pallet<T> {
signature: Signature,
) -> DispatchResult {
let auto_id = AutoIds::<T>::get(auto_id_identifier).ok_or(Error::<T>::UnknownIssuer)?;
Self::do_verify_signature(&auto_id, signature)?;
Self::do_verify_signature(
&auto_id,
CertificateAction {
id: auto_id_identifier,
nonce: auto_id.certificate.nonce(),
action_type: CertificateActionType::DeactivateAutoId,
},
signature,
)?;

// TODO: remove all the AutoIds registered using leaf certificates if this is the issuer.
AutoIds::<T>::remove(auto_id_identifier);
Expand Down
21 changes: 17 additions & 4 deletions domains/pallets/auto-id/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::pallet::{AutoIds, NextAutoIdIdentifier};
use crate::{
self as pallet_auto_id, Identifier, Pallet, RegisterAutoId, RegisterAutoIdX509, Signature,
self as pallet_auto_id, CertificateAction, CertificateActionType, Identifier, Pallet,
RegisterAutoId, RegisterAutoIdX509, Signature,
};
use codec::Encode;
use frame_support::dispatch::RawOrigin;
Expand All @@ -9,7 +10,7 @@ use pem::parse;
use ring::rand::SystemRandom;
use ring::signature::RsaKeyPair;
use sp_auto_id::DerVec;
use sp_core::H256;
use sp_core::{H256, U256};
use sp_runtime::traits::{BlakeTwo256, IdentityLookup};
use sp_runtime::BuildStorage;
use std::sync::Arc;
Expand Down Expand Up @@ -198,7 +199,12 @@ fn test_revoke_certificate() {
let auto_id_identifier = register_issuer_auto_id();
let auto_id = AutoIds::<Test>::get(auto_id_identifier).unwrap();
assert!(!auto_id.certificate.is_revoked());
let signature = sign_preimage(auto_id_identifier.encode());
let signing_data = CertificateAction {
id: auto_id_identifier,
nonce: auto_id.certificate.nonce(),
action_type: CertificateActionType::RevokeCertificate,
};
let signature = sign_preimage(signing_data.encode());
Pallet::<Test>::revoke_certificate(
RawOrigin::Signed(1).into(),
auto_id_identifier,
Expand All @@ -207,14 +213,21 @@ fn test_revoke_certificate() {
.unwrap();
let auto_id = AutoIds::<Test>::get(auto_id_identifier).unwrap();
assert!(auto_id.certificate.is_revoked());
assert_eq!(auto_id.certificate.nonce(), U256::one());
})
}

#[test]
fn test_deactivate_auto_id() {
new_test_ext().execute_with(|| {
let auto_id_identifier = register_issuer_auto_id();
let signature = sign_preimage(auto_id_identifier.encode());
let auto_id = AutoIds::<Test>::get(auto_id_identifier).unwrap();
let signing_data = CertificateAction {
id: auto_id_identifier,
nonce: auto_id.certificate.nonce(),
action_type: CertificateActionType::DeactivateAutoId,
};
let signature = sign_preimage(signing_data.encode());
Pallet::<Test>::deactivate_auto_id(
RawOrigin::Signed(1).into(),
auto_id_identifier,
Expand Down

0 comments on commit 5de3054

Please sign in to comment.