Skip to content

Commit

Permalink
Configure TlsConnector with the CA cert.
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmycuadra committed May 2, 2017
1 parent 73ed38c commit 49c1ba2
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 35 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/Cargo.lock
/target
/tests/ssl/*.der
/tests/ssl/*.p12
/tests/ssl/*.pem
/tests/ssl/*.srl
11 changes: 7 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ repository = "https://github.com/jimmycuadra/rust-etcd"
version = "0.5.5"

[dependencies]
hyper = "0.10.4"
hyper = "0.10.9"
hyper-native-tls = "0.2.2"
serde = "0.9.5"
serde_derive = "0.9.5"
serde_json = "0.9.4"
serde = "1.0.2"
serde_derive = "1.0.2"
serde_json = "1.0.1"
url = "1.4.0"

[dev-dependencies]
native-tls = "0.1.2"
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ ci: ssl
docker-compose run --rm rust cargo test --verbose

.PHONY: ssl
ssl: tests/ssl/client.pem tests/ssl/client.p12 tests/ssl/server.pem
ssl: tests/ssl/ca.der tests/ssl/client.pem tests/ssl/client.p12 tests/ssl/server.pem

.PHONY: clean-ssl
clean-ssl:
rm -f tests/ssl/*.pem tests/ssl/*.srl tests/ssl/*.p12
rm -f tests/ssl/*.der tests/ssl/*.pem tests/ssl/*.srl tests/ssl/*.p12

tests/ssl/ca.der: tests/ssl/ca.pem
openssl x509 -in tests/ssl/ca.pem -out tests/ssl/ca.der -outform der

tests/ssl/ca.pem: tests/ssl/ca-key.pem
openssl req -x509 -new -nodes -key tests/ssl/ca-key.pem -days 10000 -out tests/ssl/ca.pem -subj "/CN=rust-etcd-test-ca"
Expand Down
5 changes: 5 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,8 @@ services:
- etcdsecure
volumes:
- .:/source
- cargo_git:/root/.cargo/git
- cargo_registry:/root/.cargo/registry
volumes:
cargo_git: {}
cargo_registry: {}
8 changes: 3 additions & 5 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use std::collections::HashMap;
use std::default::Default;
use std::io::Read;

pub use hyper_native_tls::native_tls::Pkcs12;

use hyper::status::StatusCode;
use hyper_native_tls::native_tls::TlsConnector;
use serde_json::from_str;
use url::Url;
use url::form_urlencoded::Serializer;
Expand All @@ -28,9 +27,8 @@ pub struct Client {
/// Options for configuring the behavior of a `Client`.
#[derive(Default)]
pub struct ClientOptions {
/// A PKCS #12 archive containing a client certificate, private key, and any intermediate
/// certificates needed to authenticate with the server.
pub pkcs12: Option<Pkcs12>,
/// A `native_tls::TlsConnector` configured as desired for HTTPS connections.
pub tls_connector: Option<TlsConnector>,
/// The username and password to use for authentication.
pub username_and_password: Option<(String, String)>,
}
Expand Down
19 changes: 9 additions & 10 deletions src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use hyper::header::{Authorization, Basic, ContentType};
use hyper::method::Method;
use hyper::net::HttpsConnector;
use hyper_native_tls::NativeTlsClient;
use hyper_native_tls::native_tls::TlsConnector;

use client::ClientOptions;
use error::Error;
Expand All @@ -17,18 +16,18 @@ pub struct HttpClient {
impl HttpClient {
/// Constructs a new `HttpClient`.
pub fn new(options: ClientOptions) -> Result<Self, Error> {
let mut tls_connector_builder = TlsConnector::builder()?;
let hyper = match options.tls_connector {
Some(tls_connector) => {
let native_tls_client = NativeTlsClient::from(tls_connector);
let connector = HttpsConnector::new(native_tls_client);

if let Some(pkcs12) = options.pkcs12 {
tls_connector_builder.identity(pkcs12)?;
}

let tls_connector = tls_connector_builder.build()?;
let native_tls_client = NativeTlsClient::from(tls_connector);
let connector = HttpsConnector::new(native_tls_client);
Client::with_connector(connector)
}
None => Client::new(),
};

Ok(HttpClient {
hyper: Client::with_connector(connector),
hyper: hyper,
username_and_password: options.username_and_password,
})
}
Expand Down
25 changes: 19 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,32 @@
//!
//! ```no_run
//! extern crate etcd;
//! extern crate native_tls;
//!
//! use std::fs::File;
//! use std::io::Read;
//!
//! use etcd::{Client, ClientOptions, Pkcs12};
//! use native_tls::{Certificate, Pkcs12, TlsConnector};
//!
//! use etcd::{Client, ClientOptions};
//!
//! fn main() {
//! let mut file = File::open("client.p12").unwrap();
//! let mut buffer = Vec::new();
//! file.read_to_end(&mut buffer).unwrap();
//! let mut ca_cert_file = File::open("ca.der").unwrap();
//! let mut ca_cert_buffer = Vec::new();
//! ca_cert_file.read_to_end(&mut ca_cert_buffer).unwrap();
//!
//! let mut pkcs12_file = File::open("/source/tests/ssl/client.p12").unwrap();
//! let mut pkcs12_buffer = Vec::new();
//! pkcs12_file.read_to_end(&mut pkcs12_buffer).unwrap();
//!
//! let mut builder = TlsConnector::builder().unwrap();
//! builder.add_root_certificate(Certificate::from_der(&ca_cert_buffer).unwrap()).unwrap();
//! builder.identity(Pkcs12::from_der(&pkcs12_buffer, "secret").unwrap()).unwrap();
//!
//! let tls_connector = builder.build().unwrap();
//!
//! let client = Client::with_options(&["https://example.com:2379"], ClientOptions {
//! pkcs12: Some(Pkcs12::from_der(&buffer, "secret").unwrap()),
//! tls_connector: Some(tls_connector),
//! username_and_password: Some(("jimmy".to_owned(), "secret".to_owned())),
//! }).unwrap();
//!
Expand All @@ -70,7 +83,7 @@ extern crate serde_derive;
extern crate serde_json;
extern crate url;

pub use client::{Client, ClientOptions, Pkcs12};
pub use client::{Client, ClientOptions};
pub use error::{ApiError, EtcdResult, Error};
pub use keys::{KeySpaceInfo, KeySpaceResult, Node};

Expand Down
26 changes: 18 additions & 8 deletions tests/client_test.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
extern crate etcd;
extern crate native_tls;

use std::fs::File;
use std::io::Read;
use std::ops::Deref;
use std::thread::{sleep, spawn};
use std::time::Duration;

use etcd::{Client, ClientOptions, Error, Pkcs12};
use native_tls::{Certificate, Pkcs12, TlsConnector};

use etcd::{Client, ClientOptions, Error};

/// Wrapper around Client that automatically cleans up etcd after each test.
struct TestClient {
Expand All @@ -23,15 +26,25 @@ impl TestClient {

/// Creates a new HTTPS client for a test.
fn https() -> TestClient {
let mut file = File::open("/source/tests/ssl/client.p12").unwrap();
let mut buffer = Vec::new();
file.read_to_end(&mut buffer).unwrap();
let mut ca_cert_file = File::open("/source/tests/ssl/ca.der").unwrap();
let mut ca_cert_buffer = Vec::new();
ca_cert_file.read_to_end(&mut ca_cert_buffer).unwrap();

let mut pkcs12_file = File::open("/source/tests/ssl/client.p12").unwrap();
let mut pkcs12_buffer = Vec::new();
pkcs12_file.read_to_end(&mut pkcs12_buffer).unwrap();

let mut builder = TlsConnector::builder().unwrap();
builder.add_root_certificate(Certificate::from_der(&ca_cert_buffer).unwrap()).unwrap();
builder.identity(Pkcs12::from_der(&pkcs12_buffer, "secret").unwrap()).unwrap();

let tls_connector = builder.build().unwrap();

TestClient {
c: Client::with_options(
&["https://etcdsecure:2379"],
ClientOptions {
pkcs12: Some(Pkcs12::from_der(&buffer, "secret").unwrap()),
tls_connector: Some(tls_connector),
username_and_password: None,
},
).unwrap(),
Expand Down Expand Up @@ -306,9 +319,6 @@ fn get_recursive() {
fn https() {
let client = TestClient::https();

// TODO: Why is this failing? The error printed is:
//
// ERROR: The OpenSSL library reported an error: The OpenSSL library reported an error: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
if let Err(errors) = client.create("/test/foo", "bar", Some(60)) {
for error in errors {
println!("ERROR: {}", error);
Expand Down

0 comments on commit 49c1ba2

Please sign in to comment.