diff --git a/spec/_attachments/interface-spec-changelog.md b/spec/_attachments/interface-spec-changelog.md index 722ce910e..e8db713d4 100644 --- a/spec/_attachments/interface-spec-changelog.md +++ b/spec/_attachments/interface-spec-changelog.md @@ -10,6 +10,7 @@ * Add per-call context performance counter. * Update the computation of the representation-independent hash for the case of maps with nested maps. * Remove `senders` field from user delegations. +* The maximum length of a nonce in an ingress message is 32 bytes. ### 0.21.0 (2023-09-18) {#0_21_0} * Canister cycle balance cannot decrease below the freezing limit after executing `install_code` on the management canister. diff --git a/spec/index.md b/spec/index.md index d5c8e6a29..aff3c8198 100644 --- a/spec/index.md +++ b/spec/index.md @@ -858,7 +858,7 @@ In development instances of the Internet Computer Protocol (e.g. testnets), the All requests coming in via the HTTPS interface need to be either *anonymous* or *authenticated* using a cryptographic signature. To that end, the following fields are present in the `content` map in all cases: -- `nonce` (`blob`, optional): Arbitrary user-provided data, typically randomly generated. This can be used to create distinct requests with otherwise identical fields. +- `nonce` (`blob`, optional): Arbitrary user-provided data of length at most 32 bytes, typically randomly generated. This can be used to create distinct requests with otherwise identical fields. - `ingress_expiry` (`nat`, required): An upper limit on the validity of the request, expressed in nanoseconds since 1970-01-01 (like [ic0.time()](#system-api-time)). This avoids replay attacks: The IC will not accept requests, or transition requests from status `received` to status `processing`, if their expiry date is in the past. The IC may refuse to accept requests with an ingress expiry date too far in the future. This applies to synchronous and asynchronous requests alike (and could have been called `request_expiry`). @@ -3097,6 +3097,7 @@ Conditions ```html E.content.canister_id ∈ verify_envelope(E, E.content.sender, S.system_time) +|E.content.nonce| <= 32 E.content ∉ dom(S.requests) S.system_time <= E.content.ingress_expiry is_effective_canister_id(E.content, ECID) @@ -5213,6 +5214,7 @@ Conditions E.content = CanisterQuery Q Q.canister_id ∈ verify_envelope(E, Q.sender, S.system_time) +|Q.nonce| <= 32 is_effective_canister_id(E.content, ECID) S.system_time <= Q.ingress_expiry @@ -5257,6 +5259,7 @@ Conditions E.content = ReadState RS TS = verify_envelope(E, RS.sender, S.system_time) +|E.content.nonce| <= 32 S.system_time <= RS.ingress_expiry ∀ path ∈ RS.paths. may_read_path_for_canister(S, R.sender, path) ∀ (["request_status", Rid] · _) ∈ RS.paths. ∀ R ∈ dom(S.requests). hash_of_map(R) = Rid => R.canister_id ∈ TS @@ -5307,6 +5310,7 @@ Conditions E.content = ReadState RS TS = verify_envelope(E, RS.sender, S.system_time) +|E.content.nonce| <= 32 S.system_time <= RS.ingress_expiry ∀ path ∈ RS.paths. may_read_path_for_subnet(S, RS.sender, path)