Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

fix(attestation-origin-validation): added origin validation when subm… #6

Merged
merged 1 commit into from
Sep 28, 2022
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
5 changes: 4 additions & 1 deletion pallets/acurast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ frame-benchmarking = { git = "https://github.com/paritytech/substrate", default-
frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.26" }
frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.26" }
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.26" }
sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.26" }
pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.26" }

# Attestation
Expand All @@ -36,7 +37,8 @@ hex-literal = "0.3"

sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.26" }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.26" }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.26" }

acurast-p256-crypto = { path = "../../p256-crypto" }

[features]
default = ["std"]
Expand All @@ -54,5 +56,6 @@ std = [
"sha2/std",
"num-bigint/std",
"ecdsa-vendored/std",
"sp-io/std",
]
try-runtime = [ "frame-support/try-runtime" ]
15 changes: 8 additions & 7 deletions pallets/acurast/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,19 @@ const RSA_PBK: ObjectIdentifier = oid!(1, 2, 840, 113549, 1, 1, 1);
const ECDSA_PBK: ObjectIdentifier = oid!(1, 2, 840, 10045, 2, 1);

#[derive(Clone)]
enum PublicKey {
pub enum PublicKey {
RSA(RSAPbk),
ECDSA(ECDSACurve),
}

#[derive(Clone)]
struct RSAPbk {
pub struct RSAPbk {
exponent: BigUint,
modulus: BigUint,
}

#[derive(Clone)]
enum ECDSACurve {
pub enum ECDSACurve {
CurveP256(VerifyingKey),
CurveP384(p384::AffinePoint),
}
Expand Down Expand Up @@ -273,7 +273,7 @@ pub fn validate_certificate_chain_root(
/// - the next certificate's public key signs the next one and so on...
pub fn validate_certificate_chain<'a>(
chain: &'a CertificateChainInput,
) -> Result<(Vec<CertificateId>, TBSCertificate<'a>), ValidationError> {
) -> Result<(Vec<CertificateId>, TBSCertificate<'a>, PublicKey), ValidationError> {
let mut cert_ids = Vec::<CertificateId>::new();
let fold_result = chain.iter().try_fold::<_, _, Result<_, ValidationError>>(
(Option::<PublicKey>::None, Option::<Certificate>::None),
Expand All @@ -297,9 +297,10 @@ pub fn validate_certificate_chain<'a>(
)?;

let last_cert = fold_result.1.ok_or(ValidationError::ChainTooShort)?;
let last_cert_pbk = fold_result.0.ok_or(ValidationError::MissingPublicKey)?;

// if the chain is non-empty as ensured above, we know that we always have Some certificate in option
Ok((cert_ids, last_cert.tbs_certificate))
Ok((cert_ids, last_cert.tbs_certificate, last_cert_pbk))
}

/// The list of trusted root certificates, as decoded bytes arrays. [Source](https://developer.android.com/training/articles/security-key-attestation#root_certificate)
Expand Down Expand Up @@ -369,7 +370,7 @@ mod tests {
];
let decoded_chain = decode_certificate_chain(&chain);
validate_certificate_chain_root(&decoded_chain)?;
let (_, cert) = validate_certificate_chain(&decoded_chain)?;
let (_, cert, _) = validate_certificate_chain(&decoded_chain)?;
let key_description = extract_attestation(cert.extensions)?;
match &key_description {
KeyDescription::V100(key_description) => {
Expand All @@ -391,7 +392,7 @@ mod tests {
];
let decoded_chain = decode_certificate_chain(&chain);
validate_certificate_chain_root(&decoded_chain).expect("validating root failed");
let (_, cert) =
let (_, cert, _) =
validate_certificate_chain(&decoded_chain).expect("validating chain failed");
let key_description = extract_attestation(cert.extensions)?;
match &key_description {
Expand Down
1 change: 1 addition & 0 deletions pallets/acurast/src/attestation/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub enum ValidationError {
ParseP256PublicKey,
ParseP384PublicKey,
MissingECDSAAlgorithmTyp,
MissingPublicKey,
InvalidSignatureEncoding,
InvalidSignature,
UnsupportedSignatureAlgorithm,
Expand Down
12 changes: 8 additions & 4 deletions pallets/acurast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,16 @@ pub mod pallet {
CannotGetCertificateId,
/// Failed to convert the attestation to its bounded type.
AttestationToBoundedTypeConversionFailed,
/// Timestamp error
/// Timestamp error.
FailedTimestampConversion,
/// Certificate was revoked
/// Certificate was revoked.
RevokedCertificate,
/// Origin is not allowed to update the certificate revocation list
/// Origin is not allowed to update the certificate revocation list.
CertificateRevocationListUpdateNotAllowed,
/// The attestation was issued for an unsupported public key type.
UnsupportedAttestationPublicKeyType,
/// The submitted attestation public key does not match the source.
AttestationPublicKeyDoesNotMatchSource,
}

#[pallet::hooks]
Expand Down Expand Up @@ -302,7 +306,7 @@ pub mod pallet {
Error::<T>::CertificateChainTooShort,
);

let attestation = validate_and_extract_attestation::<T>(&attestation_chain)?;
let attestation = validate_and_extract_attestation::<T>(&who, &attestation_chain)?;

ensure_not_expired::<T>(&attestation)?;
ensure_not_revoked::<T>(&attestation)?;
Expand Down
32 changes: 28 additions & 4 deletions pallets/acurast/src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use hex_literal::hex;
use sp_io;
use sp_runtime::{testing::Header, traits::IdentityLookup};
use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32};

use crate::{AttestationChain, Fulfillment, JobRegistration, Script, SerialNumber};

type AccountId = u64;
type AccountId = AccountId32;
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
type Block = frame_system::mocking::MockBlock<Test>;

Expand All @@ -31,7 +31,7 @@ impl frame_system::Config for Test {
type Call = Call;
type Hash = sp_core::H256;
type Hashing = ::sp_runtime::traits::BlakeTwo256;
type AccountId = u64;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type Event = Event;
Expand All @@ -50,7 +50,7 @@ impl frame_system::Config for Test {
frame_support::parameter_types! {
pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights::simple_max(1024);
pub const MinimumPeriod: u64 = 6000;
pub AllowedRevocationListUpdate: Vec<AccountId> = vec![1];
pub AllowedRevocationListUpdate: Vec<AccountId> = vec![alice_account_id()];
pub static ExistentialDeposit: u64 = 0;
}

Expand Down Expand Up @@ -223,3 +223,27 @@ pub fn invalid_attestation_chain_3() -> AttestationChain {
pub fn cert_serial_number() -> SerialNumber {
hex!("15905857467176635834").to_vec().try_into().unwrap()
}

pub fn processor_account_id() -> AccountId {
hex!("b8bc25a2b4c0386b8892b43e435b71fe11fa50533935f027949caf04bcce4694").into()
}

pub fn alice_account_id() -> AccountId {
[0; 32].into()
}

pub fn bob_account_id() -> AccountId {
[1; 32].into()
}

pub fn charlie_account_id() -> AccountId {
[2; 32].into()
}

pub fn dave_account_id() -> AccountId {
[3; 32].into()
}

pub fn eve_account_id() -> AccountId {
[4; 32].into()
}
Loading