Crate sandwich

source ·
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

Enums

  • An error code. An error code holds one of the error described in errors.proto and listed in ErrorKind.

Traits

  • An IO interface that implements both Read and Write traits.

Type Aliases