Skip to content

Commit

Permalink
Merge branch 'master' into SDK-1245-asset-canister-setting-etag-as-cu…
Browse files Browse the repository at this point in the history
…stom-header-breaks-certification
  • Loading branch information
sesi200 committed Nov 2, 2023
2 parents 10ee585 + 5f25685 commit 3e9fc80
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 46 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ Updated Motoko to [0.10.1](https://github.com/dfinity/motoko/releases/tag/0.10.1

Defining a custom `etag` header no longer breaks certification.

- Module hash: 517d5117bb43236e1673627aacec3955a68072dcd95f0b0218e6155f75a4bb54
Fixed a certification issue where under certain conditions the fallback file (`/index.html`) was served with an incomplete certificate tree, not proving sufficiently that the fallback file may be used as a replacement.

- Module hash: 965c8899f0a033593dc9b1634b2ab4e0f3fd28c1cfa06993069be2040a2f700e
- https://github.com/dfinity/sdk/pull/3429
- https://github.com/dfinity/sdk/pull/3428
- https://github.com/dfinity/sdk/pull/3421

### Replica
Expand Down
40 changes: 20 additions & 20 deletions Cargo.lock

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

Original file line number Diff line number Diff line change
Expand Up @@ -184,25 +184,18 @@ impl CertifiedResponses {
WitnessResult::PathFound,
)
} else {
let fallback_path = HashTreePath::not_found_base_path_v2();

let absence_proof = self.witness(hash_tree_path_root.as_vec());
let fallback_trailing_slash_path = HashTreePath::not_found_trailing_slash_path_v2();
let not_found_trailing_slash_proof =
self.witness(fallback_trailing_slash_path.as_vec());
let mut combined_proof =
merge_hash_trees(absence_proof, not_found_trailing_slash_proof);

let mut partial_path = hash_tree_path_root.0;
while partial_path.pop().is_some() && !partial_path.is_empty() {
partial_path.push(NestedTreeKey::String("<*>".into()));
let fallback_paths = hash_tree_path_root.fallback_paths_v2();

let proof = self.witness(HashTreePath::from(partial_path.clone()).as_vec());
combined_proof = merge_hash_trees(combined_proof, proof);

partial_path.pop(); // remove <*>
}
let combined_proof =
fallback_paths
.into_iter()
.fold(absence_proof, |accumulator, path| {
let new_proof = self.witness(path.as_vec());
merge_hash_trees(accumulator, new_proof)
});

let fallback_path = HashTreePath::not_found_base_path_v2();
if self.contains_path(fallback_path.as_vec()) {
(combined_proof, WitnessResult::FallbackFound)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,28 @@ impl HashTreePath {
base64::encode(cbor)
}

/// Produces all `HashTreePath`s required to prove
/// - whether or not fallback file exists and
/// - that there is no fallback file with higher priority
/// in the hash tree.
pub fn fallback_paths_v2(&self) -> Vec<Self> {
let mut paths = Vec::new();

// starting at 1 because "http_expr" is always the starting element
for i in 1..self.0.len() {
let mut without_trailing_slash: Vec<NestedTreeKey> = self.0.as_slice()[0..i].into();
let mut with_trailing_slash = without_trailing_slash.clone();
without_trailing_slash.push("<*>".into());
with_trailing_slash.push("".into());
with_trailing_slash.push("<*>".into());

paths.push(without_trailing_slash.into());
paths.push(with_trailing_slash.into());
}

paths
}

pub fn new(
asset: &str,
status_code: u16,
Expand Down Expand Up @@ -182,14 +204,6 @@ impl HashTreePath {
]))
}

pub fn not_found_trailing_slash_path_v2() -> Self {
HashTreePath::from(Vec::from([
NestedTreeKey::String("http_expr".into()),
NestedTreeKey::String("".into()),
NestedTreeKey::String("<*>".into()),
]))
}

pub fn not_found_base_path_v1() -> Self {
let not_found_path = AssetPath::from(FALLBACK_FILE);
not_found_path.asset_hash_path_v1()
Expand Down
14 changes: 13 additions & 1 deletion src/canisters/frontend/ic-certified-assets/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,17 @@ pub fn verify_response(

fn certified_http_request(state: &State, request: HttpRequest) -> HttpResponse {
let response = state.http_request(request.clone(), &[], unused_callback());
assert!(verify_response(state, &request, &response).expect("Certificate validation failed."));
match verify_response(state, &request, &response) {
Err(err) => panic!(
"Response verification failed with error {:?}. Response: {:#?}",
err, response
),
Ok(success) => {
if !success {
panic!("Response verification failed. Response: {:?}", response)
}
}
}
response
}

Expand Down Expand Up @@ -510,6 +520,8 @@ fn serve_fallback_v2() {
vec![
AssetBuilder::new("/index.html", "text/html")
.with_encoding("identity", vec![INDEX_BODY]),
AssetBuilder::new("/deep/nested/folder/index.html", "text/html")
.with_encoding("identity", vec![OTHER_BODY]),
AssetBuilder::new("/deep/nested/folder/a_file.html", "text/html")
.with_encoding("identity", vec![OTHER_BODY]),
AssetBuilder::new("/deep/nested/sibling/another_file.html", "text/html")
Expand Down
Binary file modified src/distributed/assetstorage.wasm.gz
Binary file not shown.

0 comments on commit 3e9fc80

Please sign in to comment.