Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract PCK certificate chain from quotes #1209

Merged
merged 35 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f961716
WIP move PCK cert chain verification to attestation pallet
ameba23 Dec 10, 2024
eda5589
Switch things around for PCK cert chain verification happenning as pa…
ameba23 Dec 12, 2024
2884836
Fix error handling in entropy-tss
ameba23 Dec 12, 2024
c7bc598
Use git version of tdx-quote
ameba23 Dec 12, 2024
dac3595
Use git version of tdx-quote
ameba23 Dec 12, 2024
84e0849
Update node/cli/Cargo.toml
ameba23 Dec 13, 2024
92a1397
Fix staking pallet cargo.toml
ameba23 Dec 13, 2024
3fefc22
Taplo
ameba23 Dec 13, 2024
f1fe7bf
Update tdx-quote, rm unwraps
ameba23 Dec 13, 2024
2072ec6
Improve error handling in attestation pallet
ameba23 Dec 13, 2024
dd463c6
Bump tdx-quote again following improvement of error type
ameba23 Dec 13, 2024
9c4bdfd
Update tdx-quote following pck_verify takes reference
ameba23 Dec 13, 2024
3680d62
Revert cargo.lock, fix ensure! macro call
ameba23 Dec 13, 2024
20d57e6
Fix staking pallet config in other pallets mock files
ameba23 Dec 13, 2024
072b411
Update metadata
ameba23 Dec 13, 2024
971052b
Fix client test
ameba23 Dec 13, 2024
4ba9241
Update test-cli
ameba23 Dec 16, 2024
ee23433
Fixes for tests
ameba23 Dec 16, 2024
546b034
Fix staking pallet benchmarking
ameba23 Dec 16, 2024
7a2f36f
Fix staking pallet benchmarking
ameba23 Dec 16, 2024
6f17e5b
Merge master
ameba23 Dec 16, 2024
fe7291a
Fix client following merge master
ameba23 Dec 16, 2024
d1f075f
Typo
ameba23 Dec 17, 2024
02d0a61
Error handling
ameba23 Dec 17, 2024
0456568
Update staking pallet tests
ameba23 Dec 17, 2024
5efd1ae
Comments, changelog
ameba23 Dec 17, 2024
30a522b
VerifyQuoteError implements Debug
ameba23 Dec 17, 2024
a680883
Rm PCK cert chain from JoiningServerInfo
ameba23 Dec 17, 2024
dc2222c
Pull chain metadata
ameba23 Dec 17, 2024
096036e
Clippy
ameba23 Dec 17, 2024
a674da9
Clippy
ameba23 Dec 17, 2024
4c2c586
Add to changelog
ameba23 Dec 18, 2024
f1334e6
Minor changes following review comments
ameba23 Dec 18, 2024
172d2e0
Merge master
ameba23 Dec 18, 2024
0c55178
Use specific commit of tdx-quote rather than branch
ameba23 Dec 18, 2024
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: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ runtime
- In [#1147](https://github.com/entropyxyz/entropy-core/pull/1147) a field is added to the
chainspec: `jump_started_signers` which allows the chain to be started in a pre-jumpstarted state
for testing. If this is not desired it should be set to `None`.
- In [#1209](https://github.com/entropyxyz/entropy-core/pull/1209) the `validate` and `change_threshold_accounts`
extrinsics no longer take a PCK certificate chain. Rather, the certificate chain is extracted from the
provided quote. The test CLI `change-threshold-accounts` command also no longer takes a PCK
certificate chain.

### Added
- Protocol message versioning ([#1140](https://github.com/entropyxyz/entropy-core/pull/1140))
Expand All @@ -46,6 +50,7 @@ runtime
- Update programs to accept multiple oracle data ([#1153](https://github.com/entropyxyz/entropy-core/pull/1153/))
- Use context, not block number in TDX quote input data ([#1179](https://github.com/entropyxyz/entropy-core/pull/1179))
- Allow offchain worker requests to all TSS nodes in entropy-tss test environment ([#1147](https://github.com/entropyxyz/entropy-core/pull/1147))
- Extract PCK certificate chain from quotes ([#1209](https://github.com/entropyxyz/entropy-core/pull/1209))

### Fixed

Expand Down
20 changes: 14 additions & 6 deletions Cargo.lock
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you do a full cargo update here? This seems like a lot of changes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that was an accident. I couldn't update the git version tdx-quote with cargo update tdx-quote because some crates were using the git version and others the release version. So i lazily just did cargo update without thinking of the implications. Im not sure whether to revert it or just see if things still work and leave it in if the do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the end i have reverted the lockfile as there was cargo-deny related license issues popping up

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions crates/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ js-sys={ version="0.3.74", optional=true }
tokio ={ version="1.42", features=["time"] }

[dev-dependencies]
serial_test ="3.2.0"
sp-keyring ="34.0.0"
serial_test="3.2.0"
sp-keyring="34.0.0"
entropy-testing-utils={ path="../testing-utils" }
tdx-quote ={ version="0.0.1", features=["mock"] }
tdx-quote={ git="https://github.com/entropyxyz/tdx-quote.git", branch="peg/cert-chain-parse", features=[
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm planning to re-publish this crate if this PR gets approved. Ideally i would also like to fix entropyxyz/tdx-quote#13 and entropyxyz/tdx-quote#11 before publishing.

"mock",
] }

[features]
default=["native", "full-client-native"]
Expand Down
Binary file modified crates/client/entropy_metadata.scale
Binary file not shown.
4 changes: 0 additions & 4 deletions crates/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,6 @@ pub async fn get_quote_and_change_threshold_accounts(
validator_keypair: sr25519::Pair,
new_tss_account: SubxtAccountId32,
new_x25519_public_key: [u8; 32],
new_pck_certificate_chain: Vec<Vec<u8>>,
) -> Result<ThresholdAccountChanged, ClientError> {
let quote = get_tdx_quote_with_validator_id(
api,
Expand All @@ -387,7 +386,6 @@ pub async fn get_quote_and_change_threshold_accounts(
validator_keypair,
new_tss_account,
new_x25519_public_key,
new_pck_certificate_chain,
quote,
)
.await
Expand All @@ -400,13 +398,11 @@ pub async fn change_threshold_accounts(
validator_keypair: sr25519::Pair,
new_tss_account: SubxtAccountId32,
new_x25519_public_key: [u8; 32],
new_pck_certificate_chain: Vec<Vec<u8>>,
quote: Vec<u8>,
) -> Result<ThresholdAccountChanged, ClientError> {
let change_threshold_accounts = entropy::tx().staking_extension().change_threshold_accounts(
new_tss_account,
new_x25519_public_key,
new_pck_certificate_chain,
quote,
);
let in_block = submit_transaction_with_pair(
Expand Down
19 changes: 11 additions & 8 deletions crates/client/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ async fn test_change_endpoint() {

let mut pck_seeder = StdRng::from_seed(public_key.0);
let pck = tdx_quote::SigningKey::random(&mut pck_seeder);
let pck_encoded = tdx_quote::encode_verifying_key(pck.verifying_key()).unwrap().to_vec();

tdx_quote::Quote::mock(signing_key.clone(), pck, input_data.0).as_bytes().to_vec()
tdx_quote::Quote::mock(signing_key.clone(), pck, input_data.0, pck_encoded)
.as_bytes()
.to_vec()
};

let result =
Expand Down Expand Up @@ -116,14 +119,12 @@ async fn test_change_threshold_accounts() {
let nonce = request_attestation(&api, &rpc, tss_signer_pair.signer()).await.unwrap();
let nonce: [u8; 32] = nonce.try_into().unwrap();

let mut pck_seeder = StdRng::from_seed(tss_public_key.0.clone());
let pck = tdx_quote::SigningKey::random(&mut pck_seeder);
let encoded_pck = encode_verifying_key(&pck.verifying_key()).unwrap().to_vec();

// Our runtime is using the mock `PckCertChainVerifier`, which means that the expected
// "certificate" basically is just our TSS account ID. This account needs to match the one
// used to sign the following `quote`.
let pck_certificate_chain = vec![tss_public_key.0.to_vec()];
let mut pck_seeder = StdRng::from_seed(tss_public_key.0.clone());
let pck = tdx_quote::SigningKey::random(&mut pck_seeder);
let encoded_pck = encode_verifying_key(&pck.verifying_key()).unwrap().to_vec();

let quote = {
let input_data = entropy_shared::QuoteInputData::new(
Expand All @@ -134,7 +135,10 @@ async fn test_change_threshold_accounts() {
);

let signing_key = tdx_quote::SigningKey::random(&mut OsRng);
tdx_quote::Quote::mock(signing_key.clone(), pck.clone(), input_data.0).as_bytes().to_vec()

tdx_quote::Quote::mock(signing_key.clone(), pck.clone(), input_data.0, encoded_pck.clone())
.as_bytes()
.to_vec()
};

let result = change_threshold_accounts(
Expand All @@ -143,7 +147,6 @@ async fn test_change_threshold_accounts() {
one.into(),
tss_public_key.into(),
*x25519_public_key.as_bytes(),
pck_certificate_chain,
quote,
)
.await
Expand Down
34 changes: 29 additions & 5 deletions crates/shared/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,9 @@ pub trait AttestationHandler<AccountId> {
fn verify_quote(
attestee: &AccountId,
x25519_public_key: X25519PublicKey,
provisioning_certification_key: BoundedVecEncodedVerifyingKey,
quote: Vec<u8>,
context: QuoteContext,
) -> Result<(), sp_runtime::DispatchError>;
) -> Result<BoundedVecEncodedVerifyingKey, VerifyQuoteError>;
ameba23 marked this conversation as resolved.
Show resolved Hide resolved

/// Indicate to the attestation handler that a quote is desired.
///
Expand All @@ -183,12 +182,37 @@ impl<AccountId> AttestationHandler<AccountId> for () {
fn verify_quote(
_attestee: &AccountId,
_x25519_public_key: X25519PublicKey,
_provisioning_certification_key: BoundedVecEncodedVerifyingKey,
_quote: Vec<u8>,
_context: QuoteContext,
) -> Result<(), sp_runtime::DispatchError> {
Ok(())
) -> Result<BoundedVecEncodedVerifyingKey, VerifyQuoteError> {
Ok(sp_runtime::BoundedVec::new())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to specify a size of 33 bytes here in case a caller is assuming a "valid"-ish key back

}

fn request_quote(_attestee: &AccountId, _nonce: [u8; 32]) {}
}

/// An error when verifying a quote
#[cfg(not(feature = "wasm"))]
#[derive(Debug, Eq, PartialEq)]
pub enum VerifyQuoteError {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this custom error type because i couldn't figure out how to get the useful information out of a sp_runtime::DispathError without adding a lot of extra code.

/// Quote could not be parsed or verified
BadQuote,
/// Attestation extrinsic submitted when not requested
UnexpectedAttestation,
/// Hashed input data does not match what was expected
IncorrectInputData,
/// Unacceptable VM image running
BadMrtdValue,
/// Cannot encode verifying key (PCK)
CannotEncodeVerifyingKey,
/// Cannot decode verifying key (PCK)
CannotDecodeVerifyingKey,
/// PCK certificate chain cannot be parsed
PckCertificateParse,
/// PCK certificate chain cannot be verified
PckCertificateVerify,
/// PCK certificate chain public key is not well formed
PckCertificateBadPublicKey,
/// Pck certificate could not be extracted from quote
PckCertificateNoCertificate,
}
6 changes: 0 additions & 6 deletions crates/test-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ enum CliCommand {
new_tss_account: String,
/// New x25519 public key
new_x25519_public_key: String,
/// The new Provisioning Certification Key (PCK) certificate chain to be used for the TSS.
new_pck_certificate_chain: Vec<String>,
/// The mnemonic for the validator stash account to use for the call, should be stash address
#[arg(short, long)]
mnemonic_option: Option<String>,
Expand Down Expand Up @@ -482,7 +480,6 @@ pub async fn run_command(
CliCommand::ChangeThresholdAccounts {
new_tss_account,
new_x25519_public_key,
new_pck_certificate_chain,
mnemonic_option,
} => {
let user_keypair = handle_mnemonic(mnemonic_option)?;
Expand All @@ -492,15 +489,12 @@ pub async fn run_command(
let new_x25519_public_key = hex::decode(new_x25519_public_key)?
.try_into()
.map_err(|_| anyhow!("X25519 pub key needs to be 32 bytes"))?;
let new_pck_certificate_chain =
new_pck_certificate_chain.iter().cloned().map(|i| i.into()).collect::<_>();
let result_event = get_quote_and_change_threshold_accounts(
&api,
&rpc,
user_keypair,
new_tss_account,
new_x25519_public_key,
new_pck_certificate_chain,
)
.await?;
cli.log(format!("Event result: {:?}", result_event));
Expand Down
36 changes: 19 additions & 17 deletions crates/testing-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,26 @@ repository ='https://github.com/entropyxyz/entropy-core'
edition ='2021'

[dependencies]
subxt ="0.35.3"
sp-keyring ="34.0.0"
project-root ="0.2.2"
sp-core ={ version="31.0.0", default-features=false }
subxt="0.35.3"
sp-keyring="34.0.0"
project-root="0.2.2"
sp-core={ version="31.0.0", default-features=false }
parity-scale-codec="3.6.12"
lazy_static ="1.5.0"
hex-literal ="0.4.1"
tokio ={ version="1.42", features=["macros", "fs", "rt-multi-thread", "io-util", "process"] }
axum ={ version="0.7.9" }
entropy-shared ={ version="0.3.0", path="../shared" }
entropy-kvdb ={ version="0.3.0", path="../kvdb", default-features=false }
entropy-tss ={ version="0.3.0", path="../threshold-signature-server", features=["test_helpers"] }
entropy-protocol ={ version="0.3.0", path="../protocol" }
synedrion ="0.2.0"
hex ="0.4.3"
rand_core ="0.6.4"
rand ="0.8.5"
tdx-quote ={ version="0.0.1", features=["mock"] }
lazy_static="1.5.0"
hex-literal="0.4.1"
tokio={ version="1.42", features=["macros", "fs", "rt-multi-thread", "io-util", "process"] }
axum={ version="0.7.9" }
entropy-shared={ version="0.3.0", path="../shared" }
entropy-kvdb={ version="0.3.0", path="../kvdb", default-features=false }
entropy-tss={ version="0.3.0", path="../threshold-signature-server", features=["test_helpers"] }
entropy-protocol={ version="0.3.0", path="../protocol" }
synedrion="0.2.0"
hex="0.4.3"
rand_core="0.6.4"
rand="0.8.5"
tdx-quote={ git="https://github.com/entropyxyz/tdx-quote.git", branch="peg/cert-chain-parse", features=[
"mock",
] }

# Logging
tracing ="0.1.41"
Expand Down
54 changes: 29 additions & 25 deletions crates/threshold-signature-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,36 +58,40 @@ uuid ={ version="1.11.0", features=["v4"] }

# Misc
tokio-tungstenite="0.24.0"
bincode ="1.3.3"
bip32 ={ version="0.5.2" }
bip39 ={ version="2.1.0", features=["zeroize"] }
bytes ={ version="1.9", default-features=false, features=["serde"] }
base64 ="0.22.1"
clap ={ version="4.5.23", features=["derive"] }
num ="0.4.3"
snow ="0.9.6"
sha3 ="0.10.8"
hostname ="0.4"
sha1 ="0.10.6"
sha2 ="0.10.8"
hkdf ="0.12.4"
project-root ={ version="0.2.2", optional=true }
tdx-quote ={ version="0.0.1", optional=true, features=["mock"] }
configfs-tsm ={ version="0.0.1", optional=true }
bincode="1.3.3"
bip32={ version="0.5.2" }
bip39={ version="2.1.0", features=["zeroize"] }
bytes={ version="1.9", default-features=false, features=["serde"] }
base64="0.22.1"
clap={ version="4.5.23", features=["derive"] }
num="0.4.3"
snow="0.9.6"
sha3="0.10.8"
hostname="0.4"
sha1="0.10.6"
sha2="0.10.8"
hkdf="0.12.4"
project-root={ version="0.2.2", optional=true }
tdx-quote={ git="https://github.com/entropyxyz/tdx-quote.git", branch="peg/cert-chain-parse", optional=true, features=[
"mock",
] }
configfs-tsm={ version="0.0.1", optional=true }

[dev-dependencies]
serial_test ="3.2.0"
hex-literal ="0.4.1"
serial_test="3.2.0"
hex-literal="0.4.1"
project-root="0.2.2"
sp-keyring ="34.0.0"
sp-keyring="34.0.0"
more-asserts="0.3.1"
lazy_static ="1.5.0"
blake3 ="1.5.5"
ethers-core ="2.0.14"
schnorrkel ={ version="0.11.4", default-features=false, features=["std"] }
schemars ={ version="0.8.21" }
lazy_static="1.5.0"
blake3="1.5.5"
ethers-core="2.0.14"
schnorrkel={ version="0.11.4", default-features=false, features=["std"] }
schemars={ version="0.8.21" }
subxt-signer="0.35.3"
tdx-quote ={ version="0.0.1", features=["mock"] }
tdx-quote={ git="https://github.com/entropyxyz/tdx-quote.git", branch="peg/cert-chain-parse", features=[
"mock",
] }

# Note: We don't specify versions here because otherwise we run into a cyclical dependency between
# `entropy-tss` and `entropy-testing-utils` when we try and publish the `entropy-tss` crate.
Expand Down
5 changes: 4 additions & 1 deletion crates/threshold-signature-server/src/attestation/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ pub async fn create_quote(
let mut pck_seeder = StdRng::from_seed(signer.signer().public().0);
let pck = tdx_quote::SigningKey::random(&mut pck_seeder);

let quote = tdx_quote::Quote::mock(signing_key.clone(), pck, input_data.0).as_bytes().to_vec();
let pck_encoded = tdx_quote::encode_verifying_key(pck.verifying_key())?.to_vec();
let quote = tdx_quote::Quote::mock(signing_key.clone(), pck, input_data.0, pck_encoded)
.as_bytes()
.to_vec();
Ok(quote)
}

Expand Down
3 changes: 3 additions & 0 deletions crates/threshold-signature-server/src/attestation/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ pub enum AttestationErr {
#[cfg(feature = "production")]
#[error("Quote generation: {0}")]
QuoteGeneration(String),
#[cfg(not(feature = "production"))]
#[error("Cannot encode verifying key: {0}")]
EncodeVerifyingKey(#[from] tdx_quote::VerifyingKeyError),
#[error("Vec<u8> Conversion Error: {0}")]
Conversion(&'static str),
#[error("Data is repeated")]
Expand Down
Loading
Loading