Skip to content

Commit

Permalink
Support signatures produced by Polkadot JS signRaw
Browse files Browse the repository at this point in the history
This function wraps the raw bytes with `<Bytes>` and `</Bytes>` before signing it. The `verify()` functions for `SignedVoteRequest` and `SignedRemoveVoteRequest` will try to verify with and without this wrapping to support both cases.
  • Loading branch information
shamsasari committed Jul 31, 2024
1 parent 431a022 commit 3ffaf76
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 51 deletions.
15 changes: 6 additions & 9 deletions Cargo.lock

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

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ resolver = "2"
[workspace.package]
homepage = "https://projectglove.io/"
repository = "https://github.com/projectglove/glove-monorepo/"
version = "0.0.6"
version = "0.0.7"

[workspace.dependencies]
anyhow = "1.0.86"
Expand Down Expand Up @@ -40,7 +40,6 @@ cfg-if = "1.0.0"
aws-nitro-enclaves-nsm-api = "0.4.0"
aws-nitro-enclaves-cose = "0.5.2"
openssl = "0.10.66"
hex = "0.4.3"
sha2 = "0.10.8"
flate2 = "1.0.30"
aws-config = "1.5.4"
Expand Down
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Enclave Image successfully created.
{
"Measurements": {
"HashAlgorithm": "Sha384 { ... }",
"PCR0": "2c655d5ba7f35e9e5208aff0670b9bee257cd9994cb957100fd8c9b4aa693a1d1c67f430d28c4f62a5372fe96d417d29",
"PCR0": "34b6ef3d11a1bb37e6987af685803959e834805d13fada834f49dce15634926a3fa7c1fbc181665cc89de6d6dccd369d",
...
}
}
Expand All @@ -45,7 +45,7 @@ instructions on how to audit and verify the enclave code.

> [!NOTE]
> The enclave measurement for the latest build is
> `2c655d5ba7f35e9e5208aff0670b9bee257cd9994cb957100fd8c9b4aa693a1d1c67f430d28c4f62a5372fe96d417d29`.
> `34b6ef3d11a1bb37e6987af685803959e834805d13fada834f49dce15634926a3fa7c1fbc181665cc89de6d6dccd369d`.
# Glove mixing

Expand Down Expand Up @@ -153,8 +153,8 @@ it points to the same network.

#### `attestation_bundle`

The attestation bundle of the enclave the service is using. This is a hex-encoded string (without the `0x` prefix),
representing the [`AttestationBundle`](common/src/attestation.rs#L45) struct in
The attestation bundle of the enclave the service is using. This is a hex string representing the
[`AttestationBundle`](common/src/attestation.rs#L38) struct in
[SCALE](https://docs.substrate.io/reference/scale-codec/) encoding.

The attestation bundle is primarily used in Glove proofs when the enclave submits its mixed votes on-chain. It's
Expand All @@ -171,8 +171,8 @@ The version of the Glove service.
"proxy_account": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
"network_name": "rococo",
"node_endpoint": "wss://rococo-rpc.polkadot.io",
"attestation_bundle": "6408de7737c59c238890533af25896a2c20608d8b380bb01029acb3927...",
"version": "0.0.4"
"attestation_bundle": "0x6408de7737c59c238890533af25896a2c20608d8b380bb01029acb3927...",
"version": "0.0.7"
}
```

Expand All @@ -189,15 +189,15 @@ A JSON object with the following fields:

#### `request`

[SCALE-encoded](https://docs.substrate.io/reference/scale-codec/) [`VoteRequest`](common/src/lib.rs#L36) struct as a
hex string (without the `0x` prefix).
[SCALE-encoded](https://docs.substrate.io/reference/scale-codec/) [`VoteRequest`](common/src/lib.rs#L57) as a
hex string.

#### `signature`

[SCALE-encoded](https://docs.substrate.io/reference/scale-codec/)
[`MultiSignature`](https://docs.rs/sp-runtime/latest/sp_runtime/enum.MultiSignature.html) as a hex string (without the
`0x` prefix). Signed by`VoteRequest.account`, the signature is of the `VoteRequest` in SCALE-encoded bytes, i.e. the
`request` field without the hex-encoding.
[`MultiSignature`](https://docs.rs/sp-runtime/latest/sp_runtime/enum.MultiSignature.html) as a hex string. The
signature is of the `VoteRequest` in SCALE-encoded bytes, i.e. the `request` field without the hex-encoding, signed by
`VoteRequest.account`.

#### Example

Expand All @@ -224,15 +224,15 @@ A JSON object with the following fields:

#### `request`

[SCALE-encoded](https://docs.substrate.io/reference/scale-codec/) [`RemoveVoteRequest`](client-interface/src/lib.rs#L374)
struct as a hex string (without the `0x` prefix).
[SCALE-encoded](https://docs.substrate.io/reference/scale-codec/) [`RemoveVoteRequest`](client-interface/src/lib.rs#L416)
as a hex string.

#### `signature`

[SCALE-encoded](https://docs.substrate.io/reference/scale-codec/)
[`MultiSignature`](https://docs.rs/sp-runtime/latest/sp_runtime/enum.MultiSignature.html) as a hex string (without the
`0x` prefix). Signed by`RemoveVoteRequest.account`, the signature is of the `RemoveVoteRequest` in SCALE-encoded bytes,
i.e. the `request` field without the hex-encoding.
[`MultiSignature`](https://docs.rs/sp-runtime/latest/sp_runtime/enum.MultiSignature.html) as a hex string. The
signature is of the `RemoveVoteRequest` in SCALE-encoded bytes, i.e. the `request` field without the hex-encoding,
signed by `RemoveVoteRequest.account`,

### Response

Expand Down
1 change: 0 additions & 1 deletion client-interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,4 @@ reqwest.workspace = true

[dev-dependencies]
serde_json.workspace = true
hex.workspace = true
rand.workspace = true
8 changes: 4 additions & 4 deletions client-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use serde::{Deserialize, Serialize};
use sp_core::crypto::AccountId32;
use sp_runtime::{MultiAddress, MultiSignature};
use sp_runtime::traits::Verify;
use ss58_registry::{Ss58AddressFormat, Ss58AddressFormatRegistry, Token};
use subxt::Error as SubxtError;
use subxt::ext::scale_decode::DecodeAsType;
Expand All @@ -23,8 +22,8 @@ use subxt_signer::SecretUri;
use subxt_signer::sr25519;
use tokio::sync::Mutex;

use common::{ExtrinsicLocation, verify_js_payload};
use common::attestation::AttestationBundle;
use common::ExtrinsicLocation;
use metadata::proxy::events::ProxyExecuted;
use metadata::referenda::storage::types::referendum_info_for::ReferendumInfoFor;
use metadata::runtime_types::frame_support::traits::preimages::Bounded;
Expand Down Expand Up @@ -408,7 +407,7 @@ pub struct SignedRemoveVoteRequest {

impl SignedRemoveVoteRequest {
pub fn verify(&self) -> bool {
self.signature.verify(&*self.request.encode(), &self.request.account)
verify_js_payload(&self.signature, &self.request, &self.request.account)
}
}

Expand All @@ -428,6 +427,7 @@ mod tests {
use rand::random;
use serde_json::{json, Value};
use sp_core::{ed25519, Pair};
use subxt_core::utils::to_hex;
use subxt_signer::sr25519::dev;

use common::attestation::{Attestation, AttestedData};
Expand Down Expand Up @@ -460,7 +460,7 @@ mod tests {
"proxy_account": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
"network_name": "polkadot",
"node_endpoint": "wss://polkadot.api.onfinality.io/public-ws",
"attestation_bundle": hex::encode(&service_info.attestation_bundle.encode()),
"attestation_bundle": to_hex(&service_info.attestation_bundle.encode()),
"version": "1.0.0"
})
);
Expand Down
1 change: 0 additions & 1 deletion client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,4 @@ strum.workspace = true
sp-core.workspace = true
sp-runtime.workspace = true
thiserror.workspace = true
hex.workspace = true
ss58-registry.workspace = true
14 changes: 8 additions & 6 deletions client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use sp_runtime::MultiSignature;
use strum::Display;
use subxt::error::DispatchError;
use subxt::Error::Runtime;
use subxt_core::ext::sp_core::bytes::from_hex;
use subxt_core::utils::to_hex;
use subxt_signer::sr25519::Keypair;

use client::{Error, try_verify_glove_result};
Expand Down Expand Up @@ -234,18 +236,18 @@ async fn verify_vote(
if !cmd.enclave_measurement.is_empty() {
let enclave_match = cmd.enclave_measurement
.iter()
.any(|str| hex::decode(str).ok() == Some(image_measurement.clone()));
.any(|str| from_hex(str).ok() == Some(image_measurement.clone()));
if !enclave_match {
bail!("Unknown enclave encountered in Glove proof ({})",
hex::encode(&image_measurement))
to_hex(&image_measurement))
}
println!("Vote mixed by VERIFIED Glove enclave: {:?} with {} and conviction {:?}",
verified_glove_proof.result.direction,
network.token.amount(assigned_balance.balance),
assigned_balance.conviction);
} else {
println!("Vote mixed by POSSIBLE Glove enclave ({}): {:?} with {} and conviction {:?}",
hex::encode(&image_measurement),
to_hex(&image_measurement),
verified_glove_proof.result.direction,
network.token.amount(assigned_balance.balance),
assigned_balance.conviction);
Expand All @@ -255,7 +257,7 @@ async fn verify_vote(
verified_glove_proof.attested_data.version,
env!("CARGO_PKG_REPOSITORY"));
println!();
println!("And then verify 'PCR0' output is '{}':", hex::encode(&image_measurement));
println!("And then verify 'PCR0' output is '{}':", to_hex(&image_measurement));
println!("./build.sh");
}

Expand Down Expand Up @@ -289,7 +291,7 @@ fn info(service_info: ServiceInfo) -> Result<SuccessOutput> {
let ab = &service_info.attestation_bundle;
let enclave_info = match ab.verify() {
Ok(EnclaveInfo::Nitro(enclave_info)) => {
&format!("AWS Nitro Enclave ({})", hex::encode(enclave_info.image_measurement))
&format!("AWS Nitro Enclave ({})", to_hex(enclave_info.image_measurement))
},
Err(attestation::Error::InsecureMode) => match ab.attestation {
Attestation::Nitro(_) => "Debug AWS Nitro Enclave (INSECURE)",
Expand All @@ -301,7 +303,7 @@ fn info(service_info: ServiceInfo) -> Result<SuccessOutput> {
println!("Glove proxy account: {}", service_info.proxy_account);
println!("Enclave: {}", enclave_info);
println!("Substrate Network: {}", service_info.network_name);
println!("Genesis hash: {}", hex::encode(ab.attested_data.genesis_hash));
println!("Genesis hash: {}", to_hex(ab.attested_data.genesis_hash));

Ok(SuccessOutput::None)
}
Expand Down
1 change: 0 additions & 1 deletion common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ sha2.workspace = true
thiserror.workspace = true
flate2.workspace = true
subxt.workspace = true
hex.workspace = true

[dev-dependencies]
serde_json.workspace = true
Expand Down
Loading

0 comments on commit 3ffaf76

Please sign in to comment.