about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2019-02-26T16·10+0100
committerVincent Ambo <mail@tazj.in>2019-02-26T16·30+0100
commit37dc54f2bfef14a96aacb8bbedc6c75432b7a825 (patch)
tree87186bd789df08430a5842098a04e16244ba1cec
parent791e2958fc1c5c3f9efe88f84db798fcaea319bb (diff)
feat: Add utility functions for TLS client certificate usage
-rw-r--r--src/lib.rs45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 90c216dc7497..d6d11604a067 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -60,6 +60,7 @@ extern crate curl;
 use curl::easy::{Easy, Form, List, ReadError};
 use std::collections::HashMap;
 use std::io::Write;
+use std::path::Path;
 use std::string::{FromUtf8Error, ToString};
 
 #[cfg(feature = "json")] use serde::Serialize;
@@ -73,6 +74,11 @@ pub enum Method {
     Get, Post, Put, Patch, Delete
 }
 
+/// Certificate types for client-certificate key pairs.
+pub enum CertType {
+    P12, PEM, DER
+}
+
 /// Builder structure for an HTTP request.
 ///
 /// This is the primary API-type in `crimp`. After creating a new
@@ -150,6 +156,45 @@ impl <'a> Request<'a> {
         Ok(self)
     }
 
+    /// Configure a TLS client certificate on the request.
+    ///
+    /// Depending on whether the certificate file contains the private
+    /// key or not, calling `tls_client_key` may be required in
+    /// addition.
+    ///
+    /// Consult the documentation for the `ssl_cert` and `ssl_key`
+    /// functions in `curl::easy::Easy2` for details on supported
+    /// formats and defaults.
+    pub fn tls_client_cert<P: AsRef<Path>>(mut self, cert_type: CertType, cert: P)
+                                           -> Result<Self, curl::Error> {
+        self.handle.ssl_cert(cert)?;
+        self.handle.ssl_cert_type(match cert_type {
+            CertType::P12 => "P12",
+            CertType::PEM => "PEM",
+            CertType::DER => "DER",
+        })?;
+
+        Ok(self)
+    }
+
+    /// Configure a TLS client certificate key on the request with an
+    /// optional key passphrase.
+    ///
+    /// Note that this does **not** need to be called again for
+    /// PKCS12-encoded key pairs which are set via `tls_client_cert`.
+    ///
+    /// Currently only PEM-encoded key files are supported.
+    pub fn tls_client_key<P, S>(mut self, key: P, passphrase: Option<S>)
+                                -> Result<Self, curl::Error>
+    where P: AsRef<Path>, S: AsRef<str> {
+        self.handle.ssl_key(key)?;
+        if let Some(pass) = passphrase {
+            self.handle.key_password(pass.as_ref())?;
+        }
+
+        Ok(self)
+    }
+
     #[cfg(feature = "basic_auth")]
     /// Set the `Authorization` header to a basic authentication value
     /// from the supplied username and password.