Skip to content

Commit

Permalink
Merge pull request #3 from ilbertt/tests/verify-signature
Browse files Browse the repository at this point in the history
test: verify canister signature
  • Loading branch information
ilbertt authored Apr 12, 2024
2 parents f569f30 + e8ae4a6 commit d7d17a1
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 326 deletions.
14 changes: 2 additions & 12 deletions Cargo.lock

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

8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,16 +189,18 @@ The [canister_sig_util](https://github.com/dfinity/internet-identity/tree/releas

## Roadmap

- [x] on the canister, periodically fetch the [JSON Web Key Sets (JWKS)](https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets) from Auth0 using the [HTTPS outcalls](https://internetcomputer.org/docs/current/references/https-outcalls-how-it-works/) and [Timers](https://internetcomputer.org/docs/current/developer-docs/smart-contracts/advanced-features/periodic-tasks/) features.
- [x] On the canister, periodically fetch the [JSON Web Key Sets (JWKS)](https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets) from Auth0 using the [HTTPS outcalls](https://internetcomputer.org/docs/current/references/https-outcalls-how-it-works/) and [Timers](https://internetcomputer.org/docs/current/developer-docs/smart-contracts/advanced-features/periodic-tasks/) features.

Right now, the JWKS are fetched at build time by the [build-canister.sh](./scripts/build-canister.sh) script, stored in `data/jwks.json` and imported in the canister as raw bytes at compile time ([source](https://github.com/ilbertt/ic-react-native-jwt-auth/blob/882539addd4e0e35fe1f1756701296f1ff085239/src/ic_backend/src/id_token.rs#L12)).

Fetching the JWKS at runtime is needed because [JWK](https://datatracker.ietf.org/doc/html/rfc7517)s on Auth0 may rotate.

Related issue: https://github.com/ilbertt/ic-react-native-jwt-auth/issues/1.
- [x] tests (integration)
- [x] Integration tests

Related PR: https://github.com/ilbertt/ic-react-native-jwt-auth/pull/2.
Related PRs:
- https://github.com/ilbertt/ic-react-native-jwt-auth/pull/2
- https://github.com/ilbertt/ic-react-native-jwt-auth/pull/3

## License

Expand Down
3 changes: 2 additions & 1 deletion src/ic_backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ candid.workspace = true
ic-cdk = "0.13"
ic-cdk-timers = "0.7"
ic-stable-structures = "0.6"
ic-certified-map = "0.4"
ic-certification = "2.5"
canister_sig_util = { git = "https://github.com/dfinity/internet-identity", tag = "release-2024-04-05" }

serde.workspace = true
Expand All @@ -34,3 +34,4 @@ pocket-ic = "2.2"
jwt-simple = "0.12"
ic-agent = "0.34"
ring = "0.17"
ic-representation-independent-hash = "2.5"
39 changes: 9 additions & 30 deletions src/ic_backend/src/delegation.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::HashMap;

use candid::Principal;
use canister_sig_util::{
delegation_signature_msg, hash_bytes,
signature_map::{SignatureMap, LABEL_SIG},
CanisterSigPublicKey,
};
Expand All @@ -10,10 +9,10 @@ use ic_backend_types::{
UserSub,
};
use ic_cdk::{api::set_certified_data, id};
use ic_certified_map::{labeled_hash, Hash};
use ic_certification::{labeled_hash, Hash};
use serde_bytes::ByteBuf;

use crate::{hash, state};
use crate::state;

pub async fn prepare_delegation(
user_sub: &UserSub,
Expand All @@ -37,11 +36,7 @@ pub fn get_delegation(
expiration: Timestamp,
) -> GetDelegationResponse {
state::signature_map(|sigs| {
let message_hash = delegation_signature_msg_hash(&Delegation {
pubkey: session_key.clone(),
expiration,
targets: None,
});
let message_hash = delegation_signature_msg_hash(&session_key, expiration);
match sigs.get_signature_as_cbor(&calculate_seed(user_sub), message_hash, None) {
Ok(signature) => GetDelegationResponse::SignedDelegation(SignedDelegation {
delegation: Delegation {
Expand Down Expand Up @@ -73,7 +68,7 @@ fn calculate_seed(user_sub: &UserSub) -> Hash {
blob.push(user_sub_blob.len() as u8);
blob.extend(user_sub_blob);

hash::hash_bytes(blob)
hash_bytes(blob)
}

fn update_root_hash() {
Expand All @@ -83,21 +78,9 @@ fn update_root_hash() {
})
}

fn delegation_signature_msg_hash(d: &Delegation) -> Hash {
use hash::Value;

let mut m = HashMap::new();
m.insert("pubkey", Value::Bytes(d.pubkey.as_slice()));
m.insert("expiration", Value::U64(d.expiration));
if let Some(targets) = d.targets.as_ref() {
let mut arr = Vec::with_capacity(targets.len());
for t in targets.iter() {
arr.push(Value::Bytes(t.as_ref()));
}
m.insert("targets", Value::Array(arr));
}
let map_hash = hash::hash_of_map(m);
hash::hash_with_domain(b"ic-request-auth-delegation", &map_hash)
fn delegation_signature_msg_hash(pubkey: &PublicKey, expiration: Timestamp) -> Hash {
let msg = delegation_signature_msg(pubkey, expiration, None);
hash_bytes(msg)
}

fn add_delegation_signature(
Expand All @@ -106,11 +89,7 @@ fn add_delegation_signature(
seed: &[u8],
expiration: Timestamp,
) {
let msg_hash = delegation_signature_msg_hash(&Delegation {
pubkey: pk,
expiration,
targets: None,
});
let msg_hash = delegation_signature_msg_hash(&pk, expiration);
sigs.add_signature(seed, msg_hash);
}

Expand Down
Loading

0 comments on commit d7d17a1

Please sign in to comment.