-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathattested_get.rs
More file actions
131 lines (114 loc) · 4.22 KB
/
attested_get.rs
File metadata and controls
131 lines (114 loc) · 4.22 KB
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
131
//! A one-shot attested TLS proxy client which sends a single GET request and returns the response
use crate::{
http_version::HttpVersion, AttestationGenerator, AttestationVerifier, ProxyClient, ProxyError,
};
use tokio_rustls::rustls::pki_types::CertificateDer;
/// Start a proxy-client, send a single HTTP GET request to the given path and return the
/// [reqwest::Response]
pub async fn attested_get(
target_addr: String,
url_path: &str,
attestation_verifier: AttestationVerifier,
remote_certificate: Option<CertificateDer<'static>>,
) -> Result<reqwest::Response, ProxyError> {
let proxy_client = ProxyClient::new(
None,
"127.0.0.1:0".to_string(),
target_addr,
AttestationGenerator::with_no_attestation(),
attestation_verifier,
remote_certificate,
HttpVersion::Http2,
)
.await?;
attested_get_with_client(proxy_client, url_path).await
}
/// Given a configured [ProxyClient], make a GET request to the given path and return the
/// [reqwest::Response]
async fn attested_get_with_client(
proxy_client: ProxyClient,
url_path: &str,
) -> Result<reqwest::Response, ProxyError> {
let proxy_client_addr = proxy_client.local_addr().unwrap();
// Accept a single connection in a separate task
tokio::spawn(async move {
if let Err(err) = proxy_client.accept().await {
tracing::warn!("Atttested get - failed to accept connection: {err}");
}
});
// Remove leading '/' if present
let url_path = url_path.strip_prefix("/").unwrap_or(url_path);
// Make a GET request
let request = reqwest::Request::new(
reqwest::Method::GET,
reqwest::Url::parse(&format!("http://{proxy_client_addr}/{url_path}")).unwrap(),
);
let client = reqwest::Client::new();
let response = client.execute(request).await.unwrap();
Ok(response)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
attestation::AttestationType,
file_server::static_file_server,
test_helpers::{generate_certificate_chain, generate_tls_config},
ProxyServer,
};
use tempfile::tempdir;
#[tokio::test]
async fn test_attested_get() {
// Create a temporary directory with a file to serve
let dir = tempdir().unwrap();
let file_path = dir.path().join("foo.txt");
tokio::fs::write(file_path, b"bar").await.unwrap();
// Start a static file server
let target_addr = static_file_server(dir.path().to_path_buf()).await.unwrap();
// Create TLS configuration
let (cert_chain, private_key) = generate_certificate_chain("127.0.0.1".parse().unwrap());
let (server_config, client_config) = generate_tls_config(cert_chain.clone(), private_key);
// Setup a proxy server targetting the static file server
let proxy_server = ProxyServer::new_with_tls_config(
cert_chain,
server_config,
"127.0.0.1:0",
target_addr.to_string(),
AttestationGenerator::new(AttestationType::DcapTdx, None).unwrap(),
AttestationVerifier::expect_none(),
)
.await
.unwrap();
let proxy_addr = proxy_server.local_addr().unwrap();
// Accept a single connction
tokio::spawn(async move {
proxy_server.accept().await.unwrap();
});
// Setup a proxy client
let proxy_client = ProxyClient::new_with_tls_config(
client_config,
"127.0.0.1:0".to_string(),
proxy_addr.to_string(),
AttestationGenerator::with_no_attestation(),
AttestationVerifier::mock(),
None,
HttpVersion::Http2,
)
.await
.unwrap();
// Make a GET request
let response = attested_get_with_client(proxy_client, "foo.txt")
.await
.unwrap();
// Check the response
let content_type = response
.headers()
.get(reqwest::header::CONTENT_TYPE)
.and_then(|h| h.to_str().ok())
.unwrap()
.to_string();
let body = response.bytes().await.unwrap();
assert_eq!(content_type, "text/plain");
assert_eq!(&body.to_vec(), b"bar");
}
}