Expand description
Sandwich is a simple, unified and hard to misue API for developers to use cryptographic algorithms and protocols.
Installation
Sandwich can be added to an existing Cargo.toml
configuration file:
[dependencies]
sandwich = { git = "https://github.com/sandbox-quantum/sandwich.git" }
Alternatively, cargo add
can also be used:
$ cargo add --git 'https://github.com/sandbox-quantum/sandwich.git' sandwich
From source
Sandwich can also be built from source:
$ cargo build --release
$ cargo test --release
Protobuf API
Sandwich uses a protobuf based configuration. Definitions of this configuration are available in the git repository: https://github.com/sandbox-quantum/sandwich/tree/main/proto/api/v1.
For convenience reasons, the Rust protobuf API is re-exposed in Sandwich
as sandwich::pb_api
.
Examples
In the following example, we create a [tunnel::Context
] from a configuration,
then we instantiate a [tunnel::Tunnel
] to establish a TLS connection to google.com
.
extern crate protobuf;
use sandwich::pb;
use sandwich::pb_api;
use sandwich::tunnel::{Context, Tunnel};
let configuration = protobuf::text_format::parse_from_str::<pb_api::Configuration>(r#"
implementation: IMPL_OPENSSL1_1_1_OQS
client <
tls <
common_options <
kem: "X25519"
x509_verifier <
trusted_cas <
static <
data <
filename: "/etc/ssl/cert.pem"
>
format: ENCODING_FORMAT_PEM
>
>
>
alpn_protocol: "h2"
alpn_protocol: "http/1.1"
>
>
>
"#).expect("invalid protobuf message");
let sw = sandwich::Context::new();
let context = Context::try_from(&sw, &configuration).expect("invalid configuration");
let io = new_tcp_connection(); // This returns a `Box<dyn sandwich::IO>`.
let tunnel_verifier = protobuf::text_format::parse_from_str::<pb_api::TunnelVerifier>(r#"
verifier <
san_verifier <
alt_names <
dns: "google.com"
>
alt_names <
dns: "www.google.com"
>
>
>
"#).expect("invalid protobuf message");
let tunnel = context.new_tunnel(io, tunnel_verifier).expect("cannot instantiate a tunnel");
loop {
tunnel.handshake().expect("an error occurred during the handshake");
match tunnel.state() {
pb::STATE_HANDSHAKE_DONE => break,
pb::STATE_BEING_SHUTDOWN |
pb::STATE_DISCONNECTED => panic!("tunnel is closed"),
pb::STATE_ERROR => panic!("an error occurred"),
_ => {},
}
}
tunnel.write(b"GET / HTTP/1.1\r\nHostname: google.com\r\n\r\n").expect("failed to write the HTTP GET request");
let mut buf = vec![0u8; 1024];
tunnel.read(&mut buf).expect("failed to read the HTTP response");
tunnel.close();
Modules
- Module experimental features, protocols, etc.
- This module provides the definition of I/O interfaces.
- Common definitions.
- The Sandwich API.
Structs
- Top-level context.
- An error. An
Error
holds a chain ofProtoBasedErrorCode
. - An error code. An error code consists of an error code based on a protobuf enum -
ProtoBasedErrorCode
and an arbitrary string.
Enums
- An error code. An error code holds one of the error described in
errors.proto
and listed inErrorKind
.