diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml
index d1893fe840a3584eab94bf76cf3a8cbd75da39ce..5d9aab92840b6e47595e2677a1ff9ee5bb8a451c 100644
--- a/openssl/Cargo.toml
+++ b/openssl/Cargo.toml
@@ -19,6 +19,7 @@ v110 = []
 
 [dependencies]
 bitflags = "0.7"
+foreign-types = "0.1"
 lazy_static = "0.2"
 libc = "0.2"
 openssl-sys = { version = "0.9.6", path = "../openssl-sys" }
diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs
index d177885efc8ea372f3af6c82c4d4f80f014e27eb..fd9327236576fe71110aa9974bb087f4bda1da46 100644
--- a/openssl/src/asn1.rs
+++ b/openssl/src/asn1.rs
@@ -1,4 +1,5 @@
 use ffi;
+use foreign_types::{ForeignType, ForeignTypeRef};
 use libc::{c_long, c_char};
 use std::fmt;
 use std::ptr;
@@ -8,10 +9,15 @@ use std::str;
 use {cvt, cvt_p};
 use bio::MemBio;
 use error::ErrorStack;
-use types::{OpenSslType, OpenSslTypeRef};
 use string::OpensslString;
 
-type_!(Asn1GeneralizedTime, Asn1GeneralizedTimeRef, ffi::ASN1_GENERALIZEDTIME, ffi::ASN1_GENERALIZEDTIME_free);
+foreign_type! {
+    type CType = ffi::ASN1_GENERALIZEDTIME;
+    fn drop = ffi::ASN1_GENERALIZEDTIME_free;
+
+    pub struct Asn1GeneralizedTime;
+    pub struct Asn1GeneralizedTimeRef;
+}
 
 impl fmt::Display for Asn1GeneralizedTimeRef {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -23,7 +29,13 @@ impl fmt::Display for Asn1GeneralizedTimeRef {
     }
 }
 
-type_!(Asn1Time, Asn1TimeRef, ffi::ASN1_TIME, ffi::ASN1_TIME_free);
+foreign_type! {
+    type CType = ffi::ASN1_TIME;
+    fn drop = ffi::ASN1_TIME_free;
+
+    pub struct Asn1Time;
+    pub struct Asn1TimeRef;
+}
 
 impl fmt::Display for Asn1TimeRef {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -51,7 +63,13 @@ impl Asn1Time {
     }
 }
 
-type_!(Asn1String, Asn1StringRef, ffi::ASN1_STRING, ffi::ASN1_STRING_free);
+foreign_type! {
+    type CType = ffi::ASN1_STRING;
+    fn drop = ffi::ASN1_STRING_free;
+
+    pub struct Asn1String;
+    pub struct Asn1StringRef;
+}
 
 impl Asn1StringRef {
     pub fn as_utf8(&self) -> Result<OpensslString, ErrorStack> {
diff --git a/openssl/src/bn.rs b/openssl/src/bn.rs
index 01c0b428323860e17aee0e4b1b880423a8725d4c..7d288eee528592edce4fe0182ba579cbb6d224c4 100644
--- a/openssl/src/bn.rs
+++ b/openssl/src/bn.rs
@@ -1,4 +1,5 @@
 use ffi;
+use foreign_types::{ForeignType, ForeignTypeRef};
 use libc::c_int;
 use std::cmp::Ordering;
 use std::ffi::CString;
@@ -8,7 +9,6 @@ use std::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub, Deref};
 use {cvt, cvt_p, cvt_n};
 use error::ErrorStack;
 use string::OpensslString;
-use types::{OpenSslType, OpenSslTypeRef};
 
 #[cfg(ossl10x)]
 use ffi::{get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
@@ -40,7 +40,13 @@ pub const MSB_ONE: MsbOption = MsbOption(0);
 /// of bits in the original numbers.
 pub const TWO_MSB_ONE: MsbOption = MsbOption(1);
 
-type_!(BigNumContext, BigNumContextRef, ffi::BN_CTX, ffi::BN_CTX_free);
+foreign_type! {
+    type CType = ffi::BN_CTX;
+    fn drop = ffi::BN_CTX_free;
+
+    pub struct BigNumContext;
+    pub struct BigNumContextRef;
+}
 
 impl BigNumContext {
     /// Returns a new `BigNumContext`.
@@ -509,7 +515,13 @@ impl BigNumRef {
     }
 }
 
-type_!(BigNum, BigNumRef, ffi::BIGNUM, ffi::BN_free);
+foreign_type! {
+    type CType = ffi::BIGNUM;
+    fn drop = ffi::BN_free;
+
+    pub struct BigNum;
+    pub struct BigNumRef;
+}
 
 impl BigNum {
     /// Creates a new `BigNum` with the value 0.
diff --git a/openssl/src/dh.rs b/openssl/src/dh.rs
index 64494f959e88ce6b216bbaae08b76f0fe1f59e3e..a7454150ee2ac1f3b845f7b66ec2858eea527d78 100644
--- a/openssl/src/dh.rs
+++ b/openssl/src/dh.rs
@@ -1,13 +1,20 @@
 use error::ErrorStack;
 use ffi;
+use foreign_types::ForeignTypeRef;
 use std::mem;
 use std::ptr;
 
 use {cvt, cvt_p, init};
 use bn::BigNum;
-use types::OpenSslTypeRef;
 
-type_!(Dh, DhRef, ffi::DH, ffi::DH_free);
+foreign_type! {
+    type CType = ffi::DH;
+    fn drop = ffi::DH_free;
+
+    pub struct Dh;
+
+    pub struct DhRef;
+}
 
 impl DhRef {
     to_pem!(ffi::PEM_write_bio_DHparams);
diff --git a/openssl/src/dsa.rs b/openssl/src/dsa.rs
index a4a8bf30089d1a8b4c3e39ead7c5c223aa2254d2..60a1afdeb78bbf26b689138db64313ca92b61f8c 100644
--- a/openssl/src/dsa.rs
+++ b/openssl/src/dsa.rs
@@ -1,16 +1,22 @@
-use error::ErrorStack;
 use ffi;
+use foreign_types::ForeignTypeRef;
 use libc::{c_int, c_char, c_void};
 use std::fmt;
 use std::ptr;
 
+use {cvt, cvt_p};
 use bio::MemBioSlice;
 use bn::BigNumRef;
-use {cvt, cvt_p};
-use types::OpenSslTypeRef;
+use error::ErrorStack;
 use util::{CallbackState, invoke_passwd_cb_old};
 
-type_!(Dsa, DsaRef, ffi::DSA, ffi::DSA_free);
+foreign_type! {
+    type CType = ffi::DSA;
+    fn drop = ffi::DSA_free;
+
+    pub struct Dsa;
+    pub struct DsaRef;
+}
 
 impl DsaRef {
     private_key_to_pem!(ffi::PEM_write_bio_DSAPrivateKey);
diff --git a/openssl/src/ec.rs b/openssl/src/ec.rs
index ebb631e8b04708764810785cd4d273f3a2a9b087..378150212041b484de28848e7d846cfff65b4743 100644
--- a/openssl/src/ec.rs
+++ b/openssl/src/ec.rs
@@ -1,4 +1,5 @@
 use ffi;
+use foreign_types::{ForeignType, ForeignTypeRef};
 use std::ptr;
 use std::mem;
 use libc::c_int;
@@ -7,7 +8,6 @@ use {cvt, cvt_n, cvt_p, init};
 use bn::{BigNumRef, BigNumContextRef};
 use error::ErrorStack;
 use nid::Nid;
-use types::{OpenSslType, OpenSslTypeRef};
 
 pub const POINT_CONVERSION_COMPRESSED: PointConversionForm =
     PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_COMPRESSED);
@@ -29,7 +29,13 @@ pub struct PointConversionForm(ffi::point_conversion_form_t);
 #[derive(Copy, Clone)]
 pub struct Asn1Flag(c_int);
 
-type_!(EcGroup, EcGroupRef, ffi::EC_GROUP, ffi::EC_GROUP_free);
+foreign_type! {
+    type CType = ffi::EC_GROUP;
+    fn drop = ffi::EC_GROUP_free;
+
+    pub struct EcGroup;
+    pub struct EcGroupRef;
+}
 
 impl EcGroup {
     /// Returns the group of a standard named curve.
@@ -103,7 +109,13 @@ impl EcGroupRef {
     }
 }
 
-type_!(EcPoint, EcPointRef, ffi::EC_POINT, ffi::EC_POINT_free);
+foreign_type! {
+    type CType = ffi::EC_POINT;
+    fn drop = ffi::EC_POINT_free;
+
+    pub struct EcPoint;
+    pub struct EcPointRef;
+}
 
 impl EcPointRef {
     /// Computes `a + b`, storing the result in `self`.
@@ -253,7 +265,13 @@ impl EcPoint {
     }
 }
 
-type_!(EcKey, EcKeyRef, ffi::EC_KEY, ffi::EC_KEY_free);
+foreign_type! {
+    type CType = ffi::EC_KEY;
+    fn drop = ffi::EC_KEY_free;
+
+    pub struct EcKey;
+    pub struct EcKeyRef;
+}
 
 impl EcKeyRef {
     private_key_to_pem!(ffi::PEM_write_bio_ECPrivateKey);
@@ -355,7 +373,14 @@ impl EcKey {
     private_key_from_der!(EcKey, ffi::d2i_ECPrivateKey);
 }
 
-type_!(EcKeyBuilder, EcKeyBuilderRef, ffi::EC_KEY, ffi::EC_KEY_free);
+
+foreign_type! {
+    type CType = ffi::EC_KEY;
+    fn drop = ffi::EC_KEY_free;
+
+    pub struct EcKeyBuilder;
+    pub struct EcKeyBuilderRef;
+}
 
 impl EcKeyBuilder {
     pub fn new() -> Result<EcKeyBuilder, ErrorStack> {
diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs
index ea71a2697ccbff8e3452da64070be482c7c55042..507af1d4c61b59764043db328783ad4fcf251193 100644
--- a/openssl/src/lib.rs
+++ b/openssl/src/lib.rs
@@ -2,6 +2,8 @@
 
 #[macro_use]
 extern crate bitflags;
+#[macro_use]
+extern crate foreign_types;
 extern crate libc;
 #[macro_use]
 extern crate lazy_static;
diff --git a/openssl/src/macros.rs b/openssl/src/macros.rs
index b36e83198d0dcd825f1374e124eca9ba56270ff8..b2fe0c18a9e4715ae906b13fb934f5279c7de485 100644
--- a/openssl/src/macros.rs
+++ b/openssl/src/macros.rs
@@ -1,45 +1,4 @@
 
-macro_rules! type_ {
-    ($n:ident, $r:ident, $c:path, $d:path) => {
-        pub struct $n(*mut $c);
-
-        impl ::types::OpenSslType for $n {
-            type CType = $c;
-            type Ref = $r;
-
-            unsafe fn from_ptr(ptr: *mut $c) -> $n {
-                $n(ptr)
-            }
-        }
-
-        impl Drop for $n {
-            fn drop(&mut self) {
-                unsafe { $d(self.0) }
-            }
-        }
-
-        impl ::std::ops::Deref for $n {
-            type Target = $r;
-
-            fn deref(&self) -> &$r {
-                unsafe { ::types::OpenSslTypeRef::from_ptr(self.0) }
-            }
-        }
-
-        impl ::std::ops::DerefMut for $n {
-            fn deref_mut(&mut self) -> &mut $r {
-                unsafe { ::types::OpenSslTypeRef::from_ptr_mut(self.0) }
-            }
-        }
-
-        pub struct $r(::util::Opaque);
-
-        impl ::types::OpenSslTypeRef for $r {
-            type CType = $c;
-        }
-    }
-}
-
 macro_rules! private_key_from_pem {
     ($t:ident, $f:path) => {
         from_pem_inner!(/// Deserializes a PEM-formatted private key.
@@ -161,9 +120,11 @@ macro_rules! to_der_inner {
         #[$m]
         pub fn $n(&self) -> Result<Vec<u8>, ::error::ErrorStack> {
             unsafe {
-                let len = try!(::cvt($f(::types::OpenSslTypeRef::as_ptr(self), ptr::null_mut())));
+                let len = try!(::cvt($f(::foreign_types::ForeignTypeRef::as_ptr(self),
+                                        ptr::null_mut())));
                 let mut buf = vec![0; len as usize];
-                try!(::cvt($f(::types::OpenSslTypeRef::as_ptr(self), &mut buf.as_mut_ptr())));
+                try!(::cvt($f(::foreign_types::ForeignTypeRef::as_ptr(self),
+                              &mut buf.as_mut_ptr())));
                 Ok(buf)
             }
         }
diff --git a/openssl/src/ocsp.rs b/openssl/src/ocsp.rs
index 708c3561ea67967d9d7f163f57463704c1517d78..67d518384970e878e85ac48c37c73023493e143f 100644
--- a/openssl/src/ocsp.rs
+++ b/openssl/src/ocsp.rs
@@ -1,4 +1,5 @@
 use ffi;
+use foreign_types::ForeignTypeRef;
 use libc::{c_int, c_long, c_ulong};
 use std::ptr;
 use std::mem;
@@ -8,7 +9,6 @@ use asn1::Asn1GeneralizedTimeRef;
 use error::ErrorStack;
 use hash::MessageDigest;
 use stack::StackRef;
-use types::OpenSslTypeRef;
 use x509::store::X509StoreRef;
 use x509::{X509, X509Ref};
 
@@ -135,7 +135,13 @@ impl<'a> Status<'a> {
     }
 }
 
-type_!(OcspBasicResponse, OcspBasicResponseRef, ffi::OCSP_BASICRESP, ffi::OCSP_BASICRESP_free);
+foreign_type! {
+    type CType = ffi::OCSP_BASICRESP;
+    fn drop = ffi::OCSP_BASICRESP_free;
+
+    pub struct OcspBasicResponse;
+    pub struct OcspBasicResponseRef;
+}
 
 impl OcspBasicResponseRef {
     /// Verifies the validity of the response.
@@ -189,7 +195,13 @@ impl OcspBasicResponseRef {
     }
 }
 
-type_!(OcspCertId, OcspCertIdRef, ffi::OCSP_CERTID, ffi::OCSP_CERTID_free);
+foreign_type! {
+    type CType = ffi::OCSP_CERTID;
+    fn drop = ffi::OCSP_CERTID_free;
+
+    pub struct OcspCertId;
+    pub struct OcspCertIdRef;
+}
 
 impl OcspCertId {
     /// Constructs a certificate ID for certificate `subject`.
@@ -204,7 +216,13 @@ impl OcspCertId {
     }
 }
 
-type_!(OcspResponse, OcspResponseRef, ffi::OCSP_RESPONSE, ffi::OCSP_RESPONSE_free);
+foreign_type! {
+    type CType = ffi::OCSP_RESPONSE;
+    fn drop = ffi::OCSP_RESPONSE_free;
+
+    pub struct OcspResponse;
+    pub struct OcspResponseRef;
+}
 
 impl OcspResponse {
     /// Creates an OCSP response from the status and optional body.
@@ -245,7 +263,13 @@ impl OcspResponseRef {
     }
 }
 
-type_!(OcspRequest, OcspRequestRef, ffi::OCSP_REQUEST, ffi::OCSP_REQUEST_free);
+foreign_type! {
+    type CType = ffi::OCSP_REQUEST;
+    fn drop = ffi::OCSP_REQUEST_free;
+
+    pub struct OcspRequest;
+    pub struct OcspRequestRef;
+}
 
 impl OcspRequest {
     pub fn new() -> Result<OcspRequest, ErrorStack> {
@@ -271,4 +295,10 @@ impl OcspRequestRef {
     }
 }
 
-type_!(OcspOneReq, OcspOneReqRef, ffi::OCSP_ONEREQ, ffi::OCSP_ONEREQ_free);
+foreign_type! {
+    type CType = ffi::OCSP_ONEREQ;
+    fn drop = ffi::OCSP_ONEREQ_free;
+
+    pub struct OcspOneReq;
+    pub struct OcspOneReqRef;
+}
diff --git a/openssl/src/pkcs12.rs b/openssl/src/pkcs12.rs
index 44a67af0bd0cdd387d295598396dd8eb8432de6c..1e23668e444a4f5e0163830ba6bdf32a7acacaea 100644
--- a/openssl/src/pkcs12.rs
+++ b/openssl/src/pkcs12.rs
@@ -1,6 +1,7 @@
 //! PKCS #12 archives.
 
 use ffi;
+use foreign_types::{ForeignType, ForeignTypeRef};
 use libc::c_int;
 use std::ptr;
 use std::ffi::CString;
@@ -9,11 +10,16 @@ use {cvt, cvt_p};
 use pkey::{PKey, PKeyRef};
 use error::ErrorStack;
 use x509::X509;
-use types::{OpenSslType, OpenSslTypeRef};
 use stack::Stack;
 use nid;
 
-type_!(Pkcs12, Pkcs12Ref, ffi::PKCS12, ffi::PKCS12_free);
+foreign_type! {
+    type CType = ffi::PKCS12;
+    fn drop = ffi::PKCS12_free;
+
+    pub struct Pkcs12;
+    pub struct Pkcs12Ref;
+}
 
 impl Pkcs12Ref {
     to_der!(ffi::i2d_PKCS12);
diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs
index c9f5ec1b24d3143bceecc4f66ea1e8f9159de3f8..5608dd51fccb0f40d9281ca7427be123fc1aeada 100644
--- a/openssl/src/pkey.rs
+++ b/openssl/src/pkey.rs
@@ -2,6 +2,7 @@ use libc::{c_void, c_char, c_int};
 use std::ptr;
 use std::mem;
 use ffi;
+use foreign_types::{Opaque, ForeignType, ForeignTypeRef};
 
 use {cvt, cvt_p};
 use bio::MemBioSlice;
@@ -11,9 +12,14 @@ use ec::EcKey;
 use rsa::{Rsa, Padding};
 use error::ErrorStack;
 use util::{CallbackState, invoke_passwd_cb_old};
-use types::{OpenSslType, OpenSslTypeRef};
 
-type_!(PKey, PKeyRef, ffi::EVP_PKEY, ffi::EVP_PKEY_free);
+foreign_type! {
+    type CType = ffi::EVP_PKEY;
+    fn drop = ffi::EVP_PKEY_free;
+
+    pub struct PKey;
+    pub struct PKeyRef;
+}
 
 impl PKeyRef {
     /// Returns a copy of the internal RSA key.
@@ -151,7 +157,7 @@ impl PKey {
     }
 }
 
-pub struct PKeyCtxRef(::util::Opaque);
+pub struct PKeyCtxRef(Opaque);
 
 impl PKeyCtxRef {
     pub fn set_rsa_padding(&mut self, pad: Padding) -> Result<(), ErrorStack> {
@@ -170,7 +176,7 @@ impl PKeyCtxRef {
     }
 }
 
-impl ::types::OpenSslTypeRef for PKeyCtxRef {
+impl ForeignTypeRef for PKeyCtxRef {
     type CType = ffi::EVP_PKEY_CTX;
 }
 
diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs
index dc760f7ac399cf0e819163d068cfc90a43d73018..792f70709f7344992bd09a663960d472f2959862 100644
--- a/openssl/src/rsa.rs
+++ b/openssl/src/rsa.rs
@@ -3,13 +3,13 @@ use std::fmt;
 use std::ptr;
 use std::mem;
 use libc::{c_int, c_void, c_char};
+use foreign_types::ForeignTypeRef;
 
 use {cvt, cvt_p, cvt_n};
 use bn::{BigNum, BigNumRef};
 use bio::MemBioSlice;
 use error::ErrorStack;
 use util::{CallbackState, invoke_passwd_cb_old};
-use types::OpenSslTypeRef;
 
 /// Type of encryption padding to use.
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -29,7 +29,13 @@ pub const NO_PADDING: Padding = Padding(ffi::RSA_NO_PADDING);
 pub const PKCS1_PADDING: Padding = Padding(ffi::RSA_PKCS1_PADDING);
 pub const PKCS1_OAEP_PADDING: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING);
 
-type_!(Rsa, RsaRef, ffi::RSA, ffi::RSA_free);
+foreign_type! {
+    type CType = ffi::RSA;
+    fn drop = ffi::RSA_free;
+
+    pub struct Rsa;
+    pub struct RsaRef;
+}
 
 impl RsaRef {
     private_key_to_pem!(ffi::PEM_write_bio_RSAPrivateKey);
diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs
index ac33bd07cbe58d50a64f399a7f0c7af82c91ffba..279f294d1e17a1768402a24f854524221d62589f 100644
--- a/openssl/src/sign.rs
+++ b/openssl/src/sign.rs
@@ -62,6 +62,7 @@
 //! assert!(memcmp::eq(&hmac, &target));
 //! ```
 use ffi;
+use foreign_types::ForeignTypeRef;
 use std::io::{self, Write};
 use std::marker::PhantomData;
 use std::ptr;
@@ -70,7 +71,6 @@ use {cvt, cvt_p};
 use hash::MessageDigest;
 use pkey::{PKeyRef, PKeyCtxRef};
 use error::ErrorStack;
-use types::OpenSslTypeRef;
 
 #[cfg(ossl110)]
 use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free};
@@ -120,11 +120,11 @@ impl<'a> Signer<'a> {
     }
 
     pub fn pkey_ctx(&self) -> &PKeyCtxRef {
-        unsafe { ::types::OpenSslTypeRef::from_ptr(self.pkey_ctx) }
+        unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
     }
 
     pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef {
-        unsafe { ::types::OpenSslTypeRef::from_ptr_mut(self.pkey_ctx) }
+        unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
     }
 
     pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
@@ -200,11 +200,11 @@ impl<'a> Verifier<'a> {
     }
 
     pub fn pkey_ctx(&self) -> &PKeyCtxRef {
-        unsafe { ::types::OpenSslTypeRef::from_ptr(self.pkey_ctx) }
+        unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
     }
 
     pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef {
-        unsafe { ::types::OpenSslTypeRef::from_ptr_mut(self.pkey_ctx) }
+        unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
     }
 
     pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index dd7f72cc5e6c64a8b174ec7969acd3fae9ad6f01..860e2e0086fa95c2504442780f59088fbedfefe6 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -71,6 +71,7 @@
 //! }
 //! ```
 use ffi;
+use foreign_types::{ForeignType, ForeignTypeRef};
 use libc::{c_int, c_void, c_long, c_ulong};
 use libc::{c_uchar, c_uint};
 use std::any::Any;
@@ -102,7 +103,6 @@ use x509::store::{X509StoreBuilderRef, X509StoreRef};
 use verify::X509VerifyParamRef;
 use pkey::PKeyRef;
 use error::ErrorStack;
-use types::{OpenSslType, OpenSslTypeRef};
 use util::Opaque;
 use stack::{Stack, StackRef};
 
@@ -966,7 +966,13 @@ impl SslContextBuilder {
     }
 }
 
-type_!(SslContext, SslContextRef, ffi::SSL_CTX, ffi::SSL_CTX_free);
+foreign_type! {
+    type CType = ffi::SSL_CTX;
+    fn drop = ffi::SSL_CTX_free;
+
+    pub struct SslContext;
+    pub struct SslContextRef;
+}
 
 unsafe impl Send for SslContext {}
 unsafe impl Sync for SslContext {}
@@ -1051,7 +1057,7 @@ pub struct CipherBits {
 
 pub struct SslCipher(*mut ffi::SSL_CIPHER);
 
-impl OpenSslType for SslCipher {
+impl ForeignType for SslCipher {
     type CType = ffi::SSL_CIPHER;
     type Ref = SslCipherRef;
 
@@ -1076,7 +1082,7 @@ impl DerefMut for SslCipher {
 
 pub struct SslCipherRef(Opaque);
 
-impl OpenSslTypeRef for SslCipherRef {
+impl ForeignTypeRef for SslCipherRef {
     type CType = ffi::SSL_CIPHER;
 }
 
@@ -1124,7 +1130,13 @@ impl SslCipherRef {
     }
 }
 
-type_!(SslSession, SslSessionRef, ffi::SSL_SESSION, ffi::SSL_SESSION_free);
+foreign_type! {
+    type CType = ffi::SSL_SESSION;
+    fn drop = ffi::SSL_SESSION_free;
+
+    pub struct SslSession;
+    pub struct SslSessionRef;
+}
 
 impl SslSessionRef {
     /// Returns the SSL session ID.
@@ -1149,7 +1161,13 @@ impl SslSessionRef {
     }
 }
 
-type_!(Ssl, SslRef, ffi::SSL, ffi::SSL_free);
+foreign_type! {
+    type CType = ffi::SSL;
+    fn drop = ffi::SSL_free;
+
+    pub struct Ssl;
+    pub struct SslRef;
+}
 
 impl fmt::Debug for SslRef {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs
index 536088abc9c1fe20d9b71251e85a8a6fc156df0b..9c00e3eda493512683d896b0b94ce1cfc2df928b 100644
--- a/openssl/src/ssl/tests/mod.rs
+++ b/openssl/src/ssl/tests/mod.rs
@@ -174,7 +174,7 @@ macro_rules! run_test(
             use hash::MessageDigest;
             use x509::X509StoreContext;
             use hex::FromHex;
-            use types::OpenSslTypeRef;
+            use foreign_types::ForeignTypeRef;
             use super::Server;
 
             #[test]
diff --git a/openssl/src/stack.rs b/openssl/src/stack.rs
index dae42ca862ce5f3e7891f08241c8026577ecd281..372040aa76ca0bf6008cabaf791a0154738afbf8 100644
--- a/openssl/src/stack.rs
+++ b/openssl/src/stack.rs
@@ -1,12 +1,12 @@
-use std::ops::{Deref, DerefMut, Index, IndexMut};
-use std::iter;
+use foreign_types::{ForeignTypeRef, ForeignType};
+use libc::c_int;
 use std::borrow::Borrow;
 use std::convert::AsRef;
+use std::iter;
 use std::marker::PhantomData;
-use libc::c_int;
 use std::mem;
+use std::ops::{Deref, DerefMut, Index, IndexMut};
 
-use types::{OpenSslType, OpenSslTypeRef};
 use util::Opaque;
 
 #[cfg(ossl10x)]
@@ -17,9 +17,8 @@ use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPE
 
 /// Trait implemented by types which can be placed in a stack.
 ///
-/// Like `OpenSslType`, it should not be implemented for any type outside
-/// of this crate.
-pub trait Stackable: OpenSslType {
+/// It should not be implemented for any type outside of this crate.
+pub trait Stackable: ForeignType {
     /// The C stack type for this element.
     ///
     /// Generally called `stack_st_{ELEMENT_TYPE}`, normally hidden by the
@@ -72,7 +71,7 @@ impl<T: Stackable> Borrow<StackRef<T>> for Stack<T> {
     }
 }
 
-impl<T: Stackable> OpenSslType for Stack<T> {
+impl<T: Stackable> ForeignType for Stack<T> {
     type CType = T::StackType;
     type Ref = StackRef<T>;
 
@@ -140,7 +139,7 @@ impl<T: Stackable> ExactSizeIterator for IntoIter<T> {}
 
 pub struct StackRef<T: Stackable>(Opaque, PhantomData<T>);
 
-impl<T: Stackable> OpenSslTypeRef for StackRef<T> {
+impl<T: Stackable> ForeignTypeRef for StackRef<T> {
     type CType = T::StackType;
 }
 
diff --git a/openssl/src/string.rs b/openssl/src/string.rs
index 37d44d16b2017a2192fcd4ebac7e23ab7e40734d..4a1d3479593d0b48f97d3a01b0058ede14e39517 100644
--- a/openssl/src/string.rs
+++ b/openssl/src/string.rs
@@ -1,14 +1,20 @@
 use ffi;
+use foreign_types::{ForeignType, ForeignTypeRef};
 use libc::{c_char, c_void};
 use std::fmt;
 use std::ffi::CStr;
 use std::ops::Deref;
 use std::str;
 
-use types::{OpenSslType, OpenSslTypeRef};
 use stack::Stackable;
 
-type_!(OpensslString, OpensslStringRef, c_char, free);
+foreign_type! {
+    type CType = c_char;
+    fn drop = free;
+
+    pub struct OpensslString;
+    pub struct OpensslStringRef;
+}
 
 impl OpensslString {
     #[deprecated(note = "use from_ptr", since = "0.9.7")]
diff --git a/openssl/src/types.rs b/openssl/src/types.rs
index 2fadfd42c8017f937748ed9f6839a685f686b7c9..25ffe501bfb7870eb5bcffd18698ed4df6497ef1 100644
--- a/openssl/src/types.rs
+++ b/openssl/src/types.rs
@@ -1,40 +1,5 @@
-//! Items used by other types.
+#[deprecated(note = "use foreign_types instead", since = "0.9.7")]
+pub use foreign_types::ForeignType as OpenSslType;
 
-/// A type implemented by wrappers over OpenSSL types.
-///
-/// This should not be implemented by anything outside of this crate; new methods may be added at
-/// any time.
-pub trait OpenSslType: Sized {
-    /// The raw C type.
-    type CType;
-
-    /// The type representing a reference to this type.
-    type Ref: OpenSslTypeRef<CType = Self::CType>;
-
-    /// Constructs an instance of this type from its raw type.
-    unsafe fn from_ptr(ptr: *mut Self::CType) -> Self;
-}
-
-/// A trait implemented by types which reference borrowed OpenSSL types.
-///
-/// This should not be implemented by anything outside of this crate; new methods may be added at
-/// any time.
-pub trait OpenSslTypeRef: Sized {
-    /// The raw C type.
-    type CType;
-
-    /// Constructs a shared instance of this type from its raw type.
-    unsafe fn from_ptr<'a>(ptr: *mut Self::CType) -> &'a Self {
-        &*(ptr as *mut _)
-    }
-
-    /// Constructs a mutable reference of this type from its raw type.
-    unsafe fn from_ptr_mut<'a>(ptr: *mut Self::CType) -> &'a mut Self {
-        &mut *(ptr as *mut _)
-    }
-
-    /// Returns a raw pointer to the wrapped value.
-    fn as_ptr(&self) -> *mut Self::CType {
-        self as *const _ as *mut _
-    }
-}
+#[deprecated(note = "use foreign_types instead", since = "0.9.7")]
+pub use foreign_types::ForeignTypeRef as OpenSslTypeRef;
diff --git a/openssl/src/verify.rs b/openssl/src/verify.rs
index 2f070fe5f2e59c805b77e29986d33ae1c79f10a2..f554127af209c4125cfe477845a64ca1e7c54f36 100644
--- a/openssl/src/verify.rs
+++ b/openssl/src/verify.rs
@@ -1,9 +1,9 @@
 use libc::c_uint;
 use ffi;
+use foreign_types::ForeignTypeRef;
 
 use cvt;
 use error::ErrorStack;
-use types::OpenSslTypeRef;
 
 bitflags! {
     pub flags X509CheckFlags: c_uint {
@@ -19,7 +19,13 @@ bitflags! {
     }
 }
 
-type_!(X509VerifyParam, X509VerifyParamRef, ffi::X509_VERIFY_PARAM, ffi::X509_VERIFY_PARAM_free);
+foreign_type! {
+    type CType = ffi::X509_VERIFY_PARAM;
+    fn drop = ffi::X509_VERIFY_PARAM_free;
+
+    pub struct X509VerifyParam;
+    pub struct X509VerifyParamRef;
+}
 
 impl X509VerifyParamRef {
     pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) {
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs
index e75dcf5d872f58fd781f89e1eca9969d9445e00e..a0b76fef4b3cfe3b7cbfaa35b78f774093683202 100644
--- a/openssl/src/x509/mod.rs
+++ b/openssl/src/x509/mod.rs
@@ -1,3 +1,5 @@
+use ffi;
+use foreign_types::{ForeignType, ForeignTypeRef};
 use libc::{c_char, c_int, c_long, c_ulong};
 use std::borrow::Borrow;
 use std::collections::HashMap;
@@ -17,9 +19,7 @@ use hash::MessageDigest;
 use pkey::{PKey, PKeyRef};
 use rand::rand_bytes;
 use error::ErrorStack;
-use ffi;
 use nid::Nid;
-use types::{OpenSslType, OpenSslTypeRef};
 use string::OpensslString;
 use stack::{Stack, StackRef, Stackable};
 
@@ -53,7 +53,13 @@ pub const X509_FILETYPE_PEM: X509FileType = X509FileType(ffi::X509_FILETYPE_PEM)
 pub const X509_FILETYPE_ASN1: X509FileType = X509FileType(ffi::X509_FILETYPE_ASN1);
 pub const X509_FILETYPE_DEFAULT: X509FileType = X509FileType(ffi::X509_FILETYPE_DEFAULT);
 
-type_!(X509StoreContext, X509StoreContextRef, ffi::X509_STORE_CTX, ffi::X509_STORE_CTX_free);
+foreign_type! {
+    type CType = ffi::X509_STORE_CTX;
+    fn drop = ffi::X509_STORE_CTX_free;
+
+    pub struct X509StoreContext;
+    pub struct X509StoreContextRef;
+}
 
 impl X509StoreContextRef {
     pub fn error(&self) -> Option<X509VerifyError> {
@@ -354,7 +360,13 @@ impl X509Generator {
     }
 }
 
-type_!(X509, X509Ref, ffi::X509, ffi::X509_free);
+foreign_type! {
+    type CType = ffi::X509;
+    fn drop = ffi::X509_free;
+
+    pub struct X509;
+    pub struct X509Ref;
+}
 
 impl X509Ref {
     pub fn subject_name(&self) -> &X509NameRef {
@@ -513,7 +525,13 @@ impl Stackable for X509 {
     type StackType = ffi::stack_st_X509;
 }
 
-type_!(X509Name, X509NameRef, ffi::X509_NAME, ffi::X509_NAME_free);
+foreign_type! {
+    type CType = ffi::X509_NAME;
+    fn drop = ffi::X509_NAME_free;
+
+    pub struct X509Name;
+    pub struct X509NameRef;
+}
 
 impl X509Name {
     /// Loads subject names from a file containing PEM-formatted certificates.
@@ -567,7 +585,13 @@ impl<'a> Iterator for X509NameEntries<'a> {
     }
 }
 
-type_!(X509NameEntry, X509NameEntryRef, ffi::X509_NAME_ENTRY, ffi::X509_NAME_ENTRY_free);
+foreign_type! {
+    type CType = ffi::X509_NAME_ENTRY;
+    fn drop = ffi::X509_NAME_ENTRY_free;
+
+    pub struct X509NameEntry;
+    pub struct X509NameEntryRef;
+}
 
 impl X509NameEntryRef {
     pub fn data(&self) -> &Asn1StringRef {
@@ -578,7 +602,13 @@ impl X509NameEntryRef {
     }
 }
 
-type_!(X509Req, X509ReqRef, ffi::X509_REQ, ffi::X509_REQ_free);
+foreign_type! {
+    type CType = ffi::X509_REQ;
+    fn drop = ffi::X509_REQ_free;
+
+    pub struct X509Req;
+    pub struct X509ReqRef;
+}
 
 impl X509Req {
     /// Reads CSR from PEM
@@ -724,7 +754,13 @@ impl X509VerifyError {
     }
 }
 
-type_!(GeneralName, GeneralNameRef, ffi::GENERAL_NAME, ffi::GENERAL_NAME_free);
+foreign_type! {
+    type CType = ffi::GENERAL_NAME;
+    fn drop = ffi::GENERAL_NAME_free;
+
+    pub struct GeneralName;
+    pub struct GeneralNameRef;
+}
 
 impl GeneralNameRef {
     /// Returns the contents of this `GeneralName` if it is a `dNSName`.
diff --git a/openssl/src/x509/store.rs b/openssl/src/x509/store.rs
index dd08a49b235b6ecff219c62fc9766d60be01f68b..8b7a084bed4e0ae97b6c686f1327ec181a250950 100644
--- a/openssl/src/x509/store.rs
+++ b/openssl/src/x509/store.rs
@@ -1,12 +1,18 @@
 use ffi;
+use foreign_types::ForeignTypeRef;
 use std::mem;
 
 use {cvt, cvt_p};
 use error::ErrorStack;
-use types::OpenSslTypeRef;
 use x509::X509;
 
-type_!(X509StoreBuilder, X509StoreBuilderRef, ffi::X509_STORE, ffi::X509_STORE_free);
+foreign_type! {
+    type CType = ffi::X509_STORE;
+    fn drop = ffi::X509_STORE_free;
+
+    pub struct X509StoreBuilder;
+    pub struct X509StoreBuilderRef;
+}
 
 impl X509StoreBuilder {
     /// Returns a builder for a certificate store.
@@ -50,4 +56,10 @@ impl X509StoreBuilderRef {
     }
 }
 
-type_!(X509Store, X509StoreRef, ffi::X509_STORE, ffi::X509_STORE_free);
+foreign_type! {
+    type CType = ffi::X509_STORE;
+    fn drop = ffi::X509_STORE_free;
+
+    pub struct X509Store;
+    pub struct X509StoreRef;
+}