tls: expose peer certificate

Fixes #326.
diff --git a/src/lib.rs b/src/lib.rs
index c944b98..8086d57 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2549,6 +2549,11 @@
         self.handshake.alpn_protocol()
     }
 
+    /// Returns the peer's leaf certificate (if any) as a DER-encoded buffer.
+    pub fn peer_cert(&self) -> Option<Vec<u8>> {
+        self.handshake.peer_cert()
+    }
+
     /// Returns true if the connection handshake is complete.
     pub fn is_established(&self) -> bool {
         self.handshake_completed
@@ -4942,6 +4947,21 @@
             Err(Error::CongestionControl)
         );
     }
+
+    #[test]
+    fn peer_cert() {
+        let mut buf = [0; 65535];
+
+        let mut pipe = testing::Pipe::default().unwrap();
+
+        assert_eq!(pipe.handshake(&mut buf), Ok(()));
+
+        match pipe.client.peer_cert() {
+            Some(c) => assert_eq!(c.len(), 919),
+
+            None => panic!("missing server certificate"),
+        }
+    }
 }
 
 pub use crate::packet::Header;
diff --git a/src/tls.rs b/src/tls.rs
index ab7118c..004b259 100644
--- a/src/tls.rs
+++ b/src/tls.rs
@@ -79,7 +79,6 @@
 
 #[allow(non_camel_case_types)]
 #[repr(transparent)]
-#[cfg(windows)]
 struct X509(c_void);
 
 #[repr(C)]
@@ -446,6 +445,31 @@
         Some(sigalg.to_string())
     }
 
+    pub fn peer_cert(&self) -> Option<Vec<u8>> {
+        let peer_cert = unsafe {
+            let mut out: *mut libc::c_uchar = ptr::null_mut();
+
+            let x509 = SSL_get_peer_certificate(self.as_ptr());
+            if x509.is_null() {
+                return None;
+            }
+
+            let out_len = i2d_X509(x509, &mut out);
+            if out_len <= 0 {
+                return None;
+            }
+
+            let der = slice::from_raw_parts(out, out_len as usize);
+            let der = der.to_vec();
+
+            OPENSSL_free(out as *mut c_void);
+
+            der
+        };
+
+        Some(peer_cert)
+    }
+
     pub fn is_resumed(&self) -> bool {
         unsafe { SSL_session_reused(self.as_ptr()) == 1 }
     }
@@ -866,6 +890,8 @@
         sigalg: u16, include_curve: i32,
     ) -> *const c_char;
 
+    fn SSL_get_peer_certificate(ssl: *mut SSL) -> *const X509;
+
     fn SSL_set_min_proto_version(ssl: *mut SSL, version: u16);
     fn SSL_set_max_proto_version(ssl: *mut SSL, version: u16);
 
@@ -923,8 +949,13 @@
     #[cfg(windows)]
     fn d2i_X509(px: *mut X509, input: *const *const u8, len: c_int) -> *mut X509;
 
+    fn i2d_X509(px: *const X509, out: *mut *mut u8) -> c_int;
+
     // ERR
     fn ERR_peek_error() -> c_uint;
 
     fn ERR_error_string_n(err: c_uint, buf: *const u8, len: usize);
+
+    // OPENSSL
+    fn OPENSSL_free(ptr: *mut c_void);
 }