Skip to content

Commit c8c69b7

Browse files
committed
docs: add docs for packages
1 parent 8e3059d commit c8c69b7

File tree

15 files changed

+187
-4
lines changed

15 files changed

+187
-4
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,63 @@
11
# Response Verification
2+
3+
Response verification on the [Internet Computer](https://dfinity.org) is the process of
4+
verifying that a canister response from a replica has gone through consensus with other replicas
5+
hosting the same canister.
6+
7+
This package encapsulates the protocol for such verification. It is used by the
8+
[Service Worker](https://github.com/dfinity/ic/tree/master/typescript/service-worker) and
9+
[ICX Proxy](https://github.com/dfinity/ic/tree/master/rs/boundary_node/icx_proxy) and may be
10+
used by other implementations of the
11+
[HTTP Gateway Protocol](https://internetcomputer.org/docs/current/references/ic-interface-spec/#http-gateway)
12+
in the future. These implementations can also be reviewed to see working integrations.
13+
14+
## Usage
15+
16+
```javascript
17+
import initResponseVerification, {
18+
verifyRequestResponsePair,
19+
ResponseVerificationError,
20+
ResponseVerificationErrorCode,
21+
} from "@dfinity/response-verification";
22+
23+
// this is necessary for web, but not for NodeJS consumers
24+
await initResponseVerification();
25+
26+
try {
27+
const result = verifyRequestResponsePair(
28+
request,
29+
response,
30+
canister_id,
31+
current_time_ns,
32+
max_cert_time_offset_ns,
33+
fromHex(IC_ROOT_KEY)
34+
);
35+
36+
// do something with the result
37+
// `result.passed` will be true if verification succeeds, false otherwise, and
38+
// `result.response` will contain the certified response object if verification was successful.
39+
} catch (error) {
40+
if (error instanceof ResponseVerificationError) {
41+
switch (error.code) {
42+
case ResponseVerificationErrorCode.MalformedCbor:
43+
// the cbor returned from the replica was malformed.
44+
// ...
45+
break;
46+
47+
case ResponseVerificationErrorCode.MalformedCertificate:
48+
// the certificate returned from the replica was malformed.
49+
// ...
50+
break;
51+
52+
// Other error cases...
53+
}
54+
}
55+
}
56+
```
57+
58+
See the following for working examples:
59+
- [Web](https://github.com/dfinity/response-verification/tree/main/examples/web)
60+
- [Service Worker](https://github.com/dfinity/response-verification/tree/main/examples/service-worker)
61+
- [NodeJS](https://github.com/dfinity/response-verification/tree/main/examples/nodejs)
62+
63+
Note that when bundling for a service worker with Webpack. The `target` property must be set to `webworker`.

packages/ic-response-verification/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,9 @@ Format rust files.
4545
```shell
4646
cargo fmt -p ic-response-verification
4747
```
48+
49+
## Build docs
50+
51+
```shell
52+
cargo doc -p ic-response-verification --no-deps --open
53+
```

packages/ic-response-verification/src/cel.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Utilities for parsing CEL expressions into Rust consumable types.
2+
13
mod error;
24
pub use error::*;
35

@@ -9,6 +11,7 @@ use crate::cel::error::CelParserResult;
911
use crate::cel::parser::parse_cel_expression;
1012
use crate::types::Certification;
1113

14+
/// Parses a CEL expression string into a [Certification] object.
1215
pub fn cel_to_certification(cel: &str) -> CelParserResult<Option<Certification>> {
1316
parse_cel_expression(cel).and_then(map_cel_ast)
1417
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,96 @@
11
pub type CelParserResult<T = ()> = Result<T, CelParserError>;
22

3+
/// CEL expression parsing error.
34
#[derive(thiserror::Error, Debug)]
45
pub enum CelParserError {
6+
/// The CEL parser encountered an unsupported CEL function.
57
#[error(r#""{0}" is not a supported CEL function, only default_certification is currently supported"#)]
68
UnrecognizedFunction(String),
79

10+
/// The CEL parser expected a parameter at a position, but none was found.
811
#[error(r#"Parameter at position {parameter_position:?} for function {function_name:?} is missing, expected {parameter_name:?} with type {parameter_type:?}"#)]
912
MissingFunctionParameter {
13+
/// The name of the function with a missing parameter.
1014
function_name: String,
15+
/// The expected type of the missing parameter.
1116
parameter_type: String,
17+
/// The expected name of the missing parameter.
1218
parameter_name: String,
19+
/// The expected position of the missing parameter.
1320
parameter_position: u8,
1421
},
1522

23+
/// The CEL parser expected a parameter to have a different type than the one it found.
1624
#[error(r#"Parameter at position {parameter_position:?} for function {function_name:?} has the wrong type, expected {parameter_name:?} {expected_parameter_type:?} found {found_parameter_type:?}"#)]
1725
IncorrectFunctionParameterType {
26+
/// The name of the function with an unexpected parameter type.
1827
function_name: String,
28+
/// The name of the parameter with the unexpected type.
1929
parameter_name: String,
30+
/// The expected type of the parameter.
2031
expected_parameter_type: String,
32+
/// The actual type of the parameter.
2133
found_parameter_type: String,
34+
/// The position of the parameter.
2235
parameter_position: u8,
2336
},
2437

38+
/// The CEL parser expected a node to have a different type than the one it found.
2539
#[error(r#"Expected node with name {node_name:?} to have type {expected_type:?}, found {found_type:?}"#)]
2640
UnexpectedNodeType {
41+
/// The name of the node with an unexpected type.
2742
node_name: String,
43+
/// The expected type of the node.
2844
expected_type: String,
45+
/// The actual type of the node.
2946
found_type: String,
3047
},
3148

49+
/// The CEL parser expected a node to have a different name than the one it found.
3250
#[error(r#"Expected node with type {node_type:?} to have name {expected_name:?}, found {found_name:?}"#)]
3351
UnexpectedNodeName {
52+
/// The type of the node with an unexpected name.
3453
node_type: String,
54+
/// The expected name of the node.
3555
expected_name: String,
56+
/// The actual name of hte node.
3657
found_name: String,
3758
},
3859

60+
/// The CEL parser expected an object to have a property with a particular name, but none was found.
3961
#[error(r#"Expected object {object_name:?} to have property {expected_property_name:?}"#)]
4062
MissingObjectProperty {
63+
/// The name of the object with a missing property.
4164
object_name: String,
65+
/// The expected property name.
4266
expected_property_name: String,
4367
},
4468

69+
/// The CEL parser encountered an extraneous property on the request certification's CEL object.
4570
#[error(r#"The request_certification object must only specify one of the no_request_certification or request_certification properties, not both"#)]
4671
ExtraneousRequestCertificationProperty,
4772

73+
/// The CEL parser expected to find a property on the request certification's CEL object, but none was found.
4874
#[error(r#"The request_certification object must specify at least one of the no_request_certification or request_certification properties"#)]
4975
MissingRequestCertificationProperty,
5076

77+
/// The CEL parser encountered an extraneous property on the response certification's CEL object.
5178
#[error(r#"The response_certification object must only specify one of the certified_response_headers or response_header_exclusions properties, not both"#)]
5279
ExtraneousResponseCertificationProperty,
5380

81+
/// The CEL parser expected to find a property on the response certification's CEL object, but none was found.
5482
#[error(r#"The response_certification object must specify at least one of the certified_response_headers or response_header_exclusions properties"#)]
5583
MissingResponseCertificationProperty,
5684

85+
/// The CEL parser encountered an extraneous property on the certification's CEL object.
5786
#[error(r#"The ValidationArgs parameter must only specify one of the no_certification or certification properties, not both"#)]
5887
ExtraneousValidationArgsProperty,
5988

89+
/// The CEL parser expected to find a property on the certification's CEL object, but none was found.
6090
#[error(r#"The ValidationArgs parameter must specify at least one of the no_certification or certification properties"#)]
6191
MissingValidationArgsProperty,
6292

93+
/// The CEL parser encountered a syntax error while parsing the CEL expression. Using the "debug" feature flag can help to debug these syntax errors.
6394
#[error(r#"Cel Syntax Expception: {0}"#)]
6495
CelSyntaxException(String),
6596
}

packages/ic-response-verification/src/hash.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
//! Utilities for calculating
2+
//! [Representation Independent Hashes](https://internetcomputer.org/docs/current/references/ic-interface-spec/#hash-of-map)
3+
//! of [crate::Request] and [crate::Response] objects.
4+
15
mod hash;
26
pub(crate) use hash::*;
37

packages/ic-response-verification/src/hash/representation_independent_hash.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ use crate::hash::hash;
22
use ic_certification::hash_tree::Sha256Digest;
33
use sha2::{Digest, Sha256};
44

5+
/// Represents a value to be hashed. Only UTF-8 strings and numbers are currently supported.
6+
#[derive(Debug)]
57
pub enum Value {
8+
/// An UTF-8 string to be hashed.
69
String(String),
10+
/// A number to be hashed.
711
Number(u64),
812
}
913

packages/ic-response-verification/src/hash/request_hash.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ use crate::hash::representation_independent_hash::{representation_independent_ha
33
use crate::types::{Request, RequestCertification};
44
use ic_certification::hash_tree::Sha256Digest;
55

6+
/// Calculates the
7+
/// [Representation Independent Hash](https://internetcomputer.org/docs/current/references/ic-interface-spec/#hash-of-map)
8+
/// of [crate::types::Request] according to [crate::types::RequestCertification] returned from
9+
/// [crate::cel::cel_to_certification].
610
pub fn request_hash(
711
request: &Request,
812
request_certification: &RequestCertification,

packages/ic-response-verification/src/hash/response_hash.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@ const CERTIFICATE_HEADER_NAME: &str = "IC-Certificate";
77
const CERTIFICATE_EXPRESSION_HEADER_NAME: &str = "IC-Certificate-Expression";
88
const RESPONSE_STATUS_PSEUDO_HEADER_NAME: &str = ":ic-cert-status";
99

10+
/// Representation of response headers filtered by [filter_response_headers].
11+
#[derive(Debug)]
1012
pub struct ResponseHeaders {
13+
/// Filtered headers
1114
pub headers: Vec<(String, String)>,
15+
/// IC-Certificate header
1216
pub certificate: Option<String>,
17+
/// IC-Certificate-Expression header
1318
pub certificate_expression: Option<String>,
1419
}
1520

21+
/// Filters headers of [crate::types::Response] according to [crate::types::ResponseCertification]
22+
/// returned from [crate::cel::cel_to_certification].
1623
pub fn filter_response_headers(
1724
response: &Response,
1825
response_certification: &ResponseCertification,
@@ -74,6 +81,9 @@ pub fn filter_response_headers(
7481
response_headers
7582
}
7683

84+
/// Calculates the
85+
/// [Representation Independent Hash](https://internetcomputer.org/docs/current/references/ic-interface-spec/#hash-of-map)
86+
/// of [ResponseHeaders] that have been filtered with [filter_response_headers].
7787
pub fn response_headers_hash(
7888
status_code: &u64,
7989
response_headers: &ResponseHeaders,
@@ -103,7 +113,10 @@ pub fn response_headers_hash(
103113

104114
representation_independent_hash(&headers_to_verify)
105115
}
106-
116+
/// Calculates the
117+
/// [Representation Independent Hash](https://internetcomputer.org/docs/current/references/ic-interface-spec/#hash-of-map)
118+
/// of a [crate::types::Response] according to [crate::types::ResponseCertification] returned from
119+
/// [crate::cel::cel_to_certification].
107120
pub fn response_hash(
108121
response: &Response,
109122
response_certification: &ResponseCertification,

packages/ic-response-verification/src/lib.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
//! # Response Verification
2+
//!
3+
//! Response verification on the [Internet Computer](https://dfinity.org) is the process of
4+
//! verifying that a canister response from a replica has gone through consensus with other replicas
5+
//! hosting the same canister.
6+
//!
7+
//! This package encapsulates the protocol for such verification. It is used by the
8+
//! [Service Worker](https://github.com/dfinity/ic/tree/master/typescript/service-worker) and
9+
//! [ICX Proxy](https://github.com/dfinity/ic/tree/master/rs/boundary_node/icx_proxy) and may be
10+
//! used by other implementations of the
11+
//! [HTTP Gateway Protocol](https://internetcomputer.org/docs/current/references/ic-interface-spec/#http-gateway)
12+
//! in the future.
13+
14+
#![deny(
15+
missing_docs,
16+
missing_debug_implementations,
17+
rustdoc::broken_intra_doc_links,
18+
rustdoc::private_intra_doc_links
19+
)]
20+
121
#[cfg(target_arch = "wasm32")]
222
use wasm_bindgen::prelude::*;
323

@@ -37,7 +57,9 @@ mod logger;
3757
mod test_utils;
3858
mod validation;
3959

60+
/// The minimum verification version supported by this package.
4061
pub const MIN_VERIFICATION_VERSION: u8 = 1;
62+
/// The maximum verification version supported by this package.
4163
pub const MAX_VERIFICATION_VERSION: u8 = 2;
4264

4365
#[cfg(target_arch = "wasm32")]
@@ -86,6 +108,8 @@ pub fn verify_request_response_pair(
86108
#[cfg(not(target_arch = "wasm32"))]
87109
pub use verify_request_response_pair_impl as verify_request_response_pair;
88110

111+
/// The primary entry point for verifying a request and response pair. This will verify the response
112+
/// with respect to the request, according the [Response Verification Spec]().
89113
pub fn verify_request_response_pair_impl(
90114
request: Request,
91115
response: Response,

packages/ic-response-verification/src/logger.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ macro_rules! error {
5353
)
5454
}
5555

56+
/// Logs a message to the console
5657
#[macro_export]
5758
#[cfg(not(target_arch = "wasm32"))]
5859
macro_rules! log {
@@ -61,6 +62,7 @@ macro_rules! log {
6162
}};
6263
}
6364

65+
/// Logs a warning to the console
6466
#[macro_export]
6567
#[cfg(not(target_arch = "wasm32"))]
6668
macro_rules! warn {
@@ -69,6 +71,7 @@ macro_rules! warn {
6971
}};
7072
}
7173

74+
/// Logs a trace to the console
7275
#[macro_export]
7376
#[cfg(not(target_arch = "wasm32"))]
7477
macro_rules! trace {
@@ -77,6 +80,7 @@ macro_rules! trace {
7780
}};
7881
}
7982

83+
/// Logs an error to the console
8084
#[macro_export]
8185
#[cfg(not(target_arch = "wasm32"))]
8286
macro_rules! error {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1+
//! Public types used for response verification.
2+
3+
/// Types to represent parsed CEL expressions.
14
pub mod certification;
25
pub use certification::*;
36

7+
/// Types to represent response objects used for certification.
48
pub mod request;
59
pub use request::*;
610

11+
/// Types to represent request objects used for certification.
712
pub mod response;
813
pub use response::*;
914

15+
/// Types to represent the result of verifying a request/response pair's certification.
1016
pub mod certification_result;
1117
pub use certification_result::*;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
1+
/// Parsed request certification CEL expression parameters.
12
#[derive(Debug, Eq, PartialEq)]
23
pub struct RequestCertification {
4+
/// Request headers to include in certification.
35
pub certified_request_headers: Vec<String>,
6+
/// Request query parameters to include in certification.
47
pub certified_query_parameters: Vec<String>,
58
}
69

10+
/// Parsed response certification CEL expression parameters. Can either include headers using
11+
/// [ResponseCertification::CertifiedHeaders] or exclude them using
12+
/// [ResponseCertification::HeaderExclusions].
713
#[derive(Debug, Eq, PartialEq)]
814
pub enum ResponseCertification {
15+
/// Response headers to exclude from certification.
916
HeaderExclusions(Vec<String>),
17+
/// Response headers to include in certification.
1018
CertifiedHeaders(Vec<String>),
1119
}
1220

21+
/// Parsed request/response pair certification CEL expression.
1322
#[derive(Debug, Eq, PartialEq)]
1423
pub struct Certification {
24+
/// Optional rust representation of the request certification CEL expression parameters.
1525
pub request_certification: Option<RequestCertification>,
26+
/// Rust representation of the response certification CEL expression parameters.
1627
pub response_certification: ResponseCertification,
1728
}

packages/ic-response-verification/src/types/certification_result.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,14 @@ interface CertificationResult {
1111
}
1212
"#;
1313

14+
/// Result of verifying the provided request/response pair's certification.
1415
#[derive(Debug, Eq, PartialEq)]
1516
pub struct CertificationResult {
17+
/// True if verification was successful, false otherwise.
1618
pub passed: bool,
19+
/// Response object including the status code, body and headers that were included in the
20+
/// certification and passed verification. If verification failed then this object will be
21+
/// empty.
1722
pub response: Option<Response>,
1823
}
1924

0 commit comments

Comments
 (0)