1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use crate::;
use ;
use HashTree;
use Serialize;
/// Adds the [`IC-Certificate` header](https://internetcomputer.org/docs/references/http-gateway-protocol-spec/#the-certificate-header)
/// to a given [`HttpResponse`]. This header is used by the HTTP Gateway to verify the authenticity of query call responses made to the
/// `http_request` method of the target canister.
///
/// # Arguments
///
/// * `data_certificate` - A certificate used by the HTTP Gateway to verify a response.
/// Retrieved using `ic_cdk::api::data_certificate`. This value is not validated by this function
/// and is expected to be a valid certificate. The function will not fail if the certificate is invalid,
/// but verification of the certificate by the HTTP Gateway will fail.
/// * `response` - The [`HttpResponse`] to add the certificate header to.
/// Created using [`HttpResponse::builder()`](crate::HttpResponse::builder).
/// * `witness` - A pruned merkle tree revealing the relevant certification for the current response.
/// Created using [`HttpCertificationTree::witness()`](crate::HttpCertificationTree::witness).
/// The witness is not validated to be correct for the given response, and the function will not fail
/// if the witness is invalid. The HTTP Gateway will fail to verify the response if the witness is invalid.
/// * `expr_path` - An expression path for the current response informing the HTTP Gateway where the
/// relevant certification is present in the merkle tree. Created using
/// [`HttpCertificationPath::to_expr_path()`](crate::HttpCertificationPath::to_expr_path). The expression path
/// is not validated to be correct for the given response, and the function will not fail if the expression path is invalid.
///
/// # Examples
///
/// ```
/// use ic_http_certification::{HttpCertification, HttpRequest, HttpResponse, DefaultCelBuilder, DefaultResponseCertification, HttpCertificationTree, HttpCertificationTreeEntry, HttpCertificationPath, CERTIFICATE_EXPRESSION_HEADER_NAME, CERTIFICATE_HEADER_NAME, utils::add_v2_certificate_header};
///
/// let cel_expr = DefaultCelBuilder::full_certification().build();
///
/// let request = HttpRequest::get("/index.html?foo=a&bar=b&baz=c").build();
///
/// let mut response = HttpResponse::builder()
/// .with_headers(vec![(CERTIFICATE_EXPRESSION_HEADER_NAME.to_string(), cel_expr.to_string())])
/// .build();
///
/// let request_url = "/example.json";
/// let path = HttpCertificationPath::exact(request_url);
/// let expr_path = path.to_expr_path();
///
/// let certification = HttpCertification::full(&cel_expr, &request, &response, None).unwrap();
/// let entry = HttpCertificationTreeEntry::new(&path, &certification);
///
/// let mut http_certification_tree = HttpCertificationTree::default();
/// http_certification_tree.insert(&entry);
///
/// // this should normally be retrieved using `ic_cdk::api::data_certificate()`.
/// let data_certificate = vec![1, 2, 3];
///
/// let witness = http_certification_tree.witness(&entry, request_url).unwrap();
/// add_v2_certificate_header(
/// &data_certificate,
/// &mut response,
/// &witness,
/// &expr_path
/// );
///
/// assert_eq!(
/// response.headers(),
/// vec![
/// (CERTIFICATE_EXPRESSION_HEADER_NAME.to_string(), cel_expr.to_string()),
/// (
/// CERTIFICATE_HEADER_NAME.to_string(),
/// "certificate=:AQID:, tree=:2dn3gwJJaHR0cF9leHBygwJMZXhhbXBsZS5qc29ugwJDPCQ+gwJYIFJ2k+R/YYbgGPADidRdRwDurH06HXACVHlTIVrv1q4WgwJYIGvHTtoVXrGXb4aD1BvH+OW26d0CtLUdA43LP+42N6xpgwJYIM7zUx3VibIaHEUF14Kx813l3Xlilg43Y5uGaABAA/i9ggNA:, expr_path=:2dn3g2lodHRwX2V4cHJsZXhhbXBsZS5qc29uYzwkPg==:, version=2".to_string(),
/// ),
/// ]
/// );
/// ```
/// Serializes a value as self-describing CBOR and returns its base64 (standard alphabet) encoding.
///
/// This is useful for encoding `expr_path` and witness trees in the IC-Certificate header format.
/// Builds the value portion of the `IC-Certificate` response header.
///
/// Returns the full header value string in the format:
/// `certificate=:…:, tree=:…:, expr_path=:…:, version=2`
///
/// Unlike [`add_v2_certificate_header`], this function returns the header value as a [`String`]
/// rather than mutating an [`HttpResponse`]. The `expr_path_b64` argument is expected to already
/// be a base64-encoded self-describing CBOR value (e.g. produced by [`cbor_encode_to_base64`]).