From 5042d3d170456183f6acd3815c1ffdadfc22e372 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 13 Aug 2016 12:05:29 -0700 Subject: [PATCH 01/10] Mangle c helper functions We want to make sure that multiple openssl versions can coexist in the same dependency tree. Closes #438 --- .gitignore | 2 ++ openssl/src/c_helpers.c | 20 ++++++++++---------- openssl/src/c_helpers.rs | 14 +++++++------- openssl/src/crypto/hmac.rs | 24 ++++++++++++------------ openssl/src/dh/mod.rs | 2 +- openssl/src/ssl/mod.rs | 2 +- openssl/src/x509/mod.rs | 4 ++-- 7 files changed, 35 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 2c96eb1b..57f4300c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ target/ Cargo.lock +.idea/ +*.iml diff --git a/openssl/src/c_helpers.c b/openssl/src/c_helpers.c index 13041956..5d149553 100644 --- a/openssl/src/c_helpers.c +++ b/openssl/src/c_helpers.c @@ -3,19 +3,19 @@ #include #include -void rust_SSL_CTX_clone(SSL_CTX *ctx) { +void rust_0_8_SSL_CTX_clone(SSL_CTX *ctx) { CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); } -void rust_X509_clone(X509 *x509) { +void rust_0_8_X509_clone(X509 *x509) { CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); } -STACK_OF(X509_EXTENSION) *rust_X509_get_extensions(X509 *x) { +STACK_OF(X509_EXTENSION) *rust_0_8_X509_get_extensions(X509 *x) { return x->cert_info ? x->cert_info->extensions : NULL; } -DH *rust_DH_new_from_params(BIGNUM *p, BIGNUM *g, BIGNUM *q) { +DH *rust_0_8_DH_new_from_params(BIGNUM *p, BIGNUM *g, BIGNUM *q) { DH *dh; if ((dh = DH_new()) == NULL) { @@ -28,32 +28,32 @@ DH *rust_DH_new_from_params(BIGNUM *p, BIGNUM *g, BIGNUM *q) { } #if OPENSSL_VERSION_NUMBER < 0x10000000L -int rust_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) { +int rust_0_8_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) { HMAC_Init_ex(ctx, key, key_len, md, impl); return 1; } -int rust_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len) { +int rust_0_8_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len) { HMAC_Update(ctx, data, len); return 1; } -int rust_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { +int rust_0_8_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { HMAC_Final(ctx, md, len); return 1; } #else -int rust_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) { +int rust_0_8_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) { return HMAC_Init_ex(ctx, key, key_len, md, impl); } -int rust_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len) { +int rust_0_8_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len) { return HMAC_Update(ctx, data, len); } -int rust_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { +int rust_0_8_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { return HMAC_Final(ctx, md, len); } #endif diff --git a/openssl/src/c_helpers.rs b/openssl/src/c_helpers.rs index 90fcf877..74ddb9ac 100644 --- a/openssl/src/c_helpers.rs +++ b/openssl/src/c_helpers.rs @@ -3,12 +3,12 @@ use libc::{c_int, c_void, c_uint, c_uchar}; #[allow(dead_code)] extern "C" { - pub fn rust_SSL_CTX_clone(cxt: *mut ffi::SSL_CTX); - pub fn rust_X509_clone(x509: *mut ffi::X509); - pub fn rust_X509_get_extensions(x: *mut ffi::X509) -> *mut ffi::stack_st_X509_EXTENSION; + pub fn rust_0_8_SSL_CTX_clone(cxt: *mut ffi::SSL_CTX); + pub fn rust_0_8_X509_clone(x509: *mut ffi::X509); + pub fn rust_0_8_X509_get_extensions(x: *mut ffi::X509) -> *mut ffi::stack_st_X509_EXTENSION; - pub fn rust_HMAC_Init_ex(ctx: *mut ffi::HMAC_CTX, key: *const c_void, keylen: c_int, md: *const ffi::EVP_MD, impl_: *mut ffi::ENGINE) -> c_int; - pub fn rust_HMAC_Final(ctx: *mut ffi::HMAC_CTX, output: *mut c_uchar, len: *mut c_uint) -> c_int; - pub fn rust_HMAC_Update(ctx: *mut ffi::HMAC_CTX, input: *const c_uchar, len: c_uint) -> c_int; - pub fn rust_DH_new_from_params(p: *mut ffi::BIGNUM, g: *mut ffi::BIGNUM, q: *mut ffi::BIGNUM) -> *mut ffi::DH; + pub fn rust_0_8_HMAC_Init_ex(ctx: *mut ffi::HMAC_CTX, key: *const c_void, keylen: c_int, md: *const ffi::EVP_MD, impl_: *mut ffi::ENGINE) -> c_int; + pub fn rust_0_8_HMAC_Final(ctx: *mut ffi::HMAC_CTX, output: *mut c_uchar, len: *mut c_uint) -> c_int; + pub fn rust_0_8_HMAC_Update(ctx: *mut ffi::HMAC_CTX, input: *const c_uchar, len: c_uint) -> c_int; + pub fn rust_0_8_DH_new_from_params(p: *mut ffi::BIGNUM, g: *mut ffi::BIGNUM, q: *mut ffi::BIGNUM) -> *mut ffi::DH; } diff --git a/openssl/src/crypto/hmac.rs b/openssl/src/crypto/hmac.rs index 857be339..1847d6b1 100644 --- a/openssl/src/crypto/hmac.rs +++ b/openssl/src/crypto/hmac.rs @@ -92,11 +92,11 @@ impl HMAC { fn init_once(&mut self, md: *const ffi::EVP_MD, key: &[u8]) -> Result<(), ErrorStack> { unsafe { - try_ssl!(c_helpers::rust_HMAC_Init_ex(&mut self.ctx, - key.as_ptr() as *const _, - key.len() as c_int, - md, - 0 as *mut _)); + try_ssl!(c_helpers::rust_0_8_HMAC_Init_ex(&mut self.ctx, + key.as_ptr() as *const _, + key.len() as c_int, + md, + 0 as *mut _)); } self.state = Reset; Ok(()) @@ -113,11 +113,11 @@ impl HMAC { // If the key and/or md is not supplied it's reused from the last time // avoiding redundant initializations unsafe { - try_ssl!(c_helpers::rust_HMAC_Init_ex(&mut self.ctx, - 0 as *const _, - 0, - 0 as *const _, - 0 as *mut _)); + try_ssl!(c_helpers::rust_0_8_HMAC_Init_ex(&mut self.ctx, + 0 as *const _, + 0, + 0 as *const _, + 0 as *mut _)); } self.state = Reset; Ok(()) @@ -130,7 +130,7 @@ impl HMAC { while !data.is_empty() { let len = cmp::min(data.len(), c_uint::max_value() as usize); unsafe { - try_ssl!(c_helpers::rust_HMAC_Update(&mut self.ctx, data.as_ptr(), len as c_uint)); + try_ssl!(c_helpers::rust_0_8_HMAC_Update(&mut self.ctx, data.as_ptr(), len as c_uint)); } data = &data[len..]; } @@ -147,7 +147,7 @@ impl HMAC { unsafe { let mut len = ffi::EVP_MAX_MD_SIZE; let mut res = vec![0; len as usize]; - try_ssl!(c_helpers::rust_HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut len)); + try_ssl!(c_helpers::rust_0_8_HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut len)); res.truncate(len as usize); self.state = Finalized; Ok(res) diff --git a/openssl/src/dh/mod.rs b/openssl/src/dh/mod.rs index 78dcb778..e0cf885a 100644 --- a/openssl/src/dh/mod.rs +++ b/openssl/src/dh/mod.rs @@ -15,7 +15,7 @@ impl DH { #[cfg(feature = "dh_from_params")] pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result { let dh = unsafe { - try_ssl_null!(::c_helpers::rust_DH_new_from_params(p.as_ptr(), g.as_ptr(), q.as_ptr())) + try_ssl_null!(::c_helpers::rust_0_8_DH_new_from_params(p.as_ptr(), g.as_ptr(), q.as_ptr())) }; mem::forget(p); mem::forget(g); diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 82ee3127..1ace24ed 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -662,7 +662,7 @@ impl Clone for SslContext { /// Requires the `ssl_context_clone` feature. fn clone(&self) -> Self { unsafe { - ::c_helpers::rust_SSL_CTX_clone(self.as_ptr()); + ::c_helpers::rust_0_8_SSL_CTX_clone(self.as_ptr()); SslContext::from_ptr(self.as_ptr()) } } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 4cb4458a..9f1c1a79 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -359,7 +359,7 @@ impl X509Generator { let req = ffi::X509_to_X509_REQ(cert.as_ptr(), ptr::null_mut(), ptr::null()); try_ssl_null!(req); - let exts = ::c_helpers::rust_X509_get_extensions(cert.as_ptr()); + let exts = ::c_helpers::rust_0_8_X509_get_extensions(cert.as_ptr()); if exts != ptr::null_mut() { try_ssl!(ffi::X509_REQ_add_extensions(req, exts)); } @@ -481,7 +481,7 @@ impl Clone for X509 { /// Requires the `x509_clone` feature. fn clone(&self) -> X509 { unsafe { - ::c_helpers::rust_X509_clone(self.as_ptr()); + ::c_helpers::rust_0_8_X509_clone(self.as_ptr()); X509::new(self.as_ptr()) } } From 773a6f0735f0a1d5dc92034a6a877bce7272071d Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 14 Aug 2016 10:11:38 -0700 Subject: [PATCH 02/10] Start on PKCS #12 support --- openssl-sys/src/lib.rs | 16 ++++++++++++++ openssl/src/crypto/mod.rs | 1 + openssl/src/crypto/pkcs12.rs | 39 +++++++++++++++++++++++++++++++++++ openssl/src/ssl/tests/mod.rs | 8 +++---- openssl/src/x509/tests.rs | 2 +- openssl/test/cert.pem | 36 +++++++++++++++----------------- openssl/test/identity.p12 | Bin 0 -> 3386 bytes openssl/test/root-ca.key | 27 ++++++++++++++++++++++++ openssl/test/root-ca.pem | 21 +++++++++++++++++++ 9 files changed, 126 insertions(+), 24 deletions(-) create mode 100644 openssl/src/crypto/pkcs12.rs create mode 100644 openssl/test/identity.p12 create mode 100644 openssl/test/root-ca.key create mode 100644 openssl/test/root-ca.pem diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 24d3bf57..a6041a6b 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -37,6 +37,13 @@ pub type X509_NAME_ENTRY = c_void; pub type X509_REQ = c_void; pub type X509_STORE_CTX = c_void; pub type bio_st = c_void; +#[repr(C)] +pub struct PKCS12(c_void); + +#[repr(C)] +pub struct stack_st_X509 { + pub stack: _STACK, +} #[repr(C)] pub struct stack_st_X509_EXTENSION { @@ -1070,6 +1077,15 @@ extern "C" { pub fn i2d_RSAPrivateKey(k: *mut RSA, buf: *const *mut u8) -> c_int; pub fn d2i_RSAPrivateKey(k: *const *mut RSA, buf: *const *const u8, len: c_uint) -> *mut RSA; + pub fn d2i_PKCS12(a: *mut *mut PKCS12, pp: *mut *const u8, length: c_long) -> *mut PKCS12; + pub fn PKCS12_parse(p12: *mut PKCS12, + pass: *const c_char, + pkey: *mut *mut EVP_PKEY, + cert: *mut *mut X509, + ca: *mut *mut stack_st_X509) + -> c_int; + pub fn PKCS12_free(p12: *mut PKCS12); + pub fn SSLeay() -> c_long; pub fn SSLeay_version(key: c_int) -> *const c_char; } diff --git a/openssl/src/crypto/mod.rs b/openssl/src/crypto/mod.rs index 93aba9eb..b8b109a2 100644 --- a/openssl/src/crypto/mod.rs +++ b/openssl/src/crypto/mod.rs @@ -18,6 +18,7 @@ pub mod hash; #[cfg(feature = "hmac")] pub mod hmac; pub mod pkcs5; +pub mod pkcs12; pub mod pkey; pub mod rand; pub mod symm; diff --git a/openssl/src/crypto/pkcs12.rs b/openssl/src/crypto/pkcs12.rs new file mode 100644 index 00000000..dfe30a6c --- /dev/null +++ b/openssl/src/crypto/pkcs12.rs @@ -0,0 +1,39 @@ +//! PKCS #12 archives. + +use ffi; +use libc::{c_long, c_uchar}; +use std::cmp; +use std::ptr; + +use error::ErrorStack; + +/// A PKCS #12 archive. +pub struct Pkcs12(*mut ffi::PKCS12); + +impl Drop for Pkcs12 { + fn drop(&mut self) { + unsafe { ffi::PKCS12_free(self.0); } + } +} + +impl Pkcs12 { + pub fn from_der(der: &[u8]) -> Result { + unsafe { + let mut ptr = der.as_ptr() as *const c_uchar; + let length = cmp::min(der.len(), c_long::max_value() as usize) as c_long; + let p12 = try_ssl_null!(ffi::d2i_PKCS12(ptr::null_mut(), &mut ptr, length)); + Ok(Pkcs12(p12)) + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn from_der() { + let der = include_bytes!("../../test/identity.p12"); + Pkcs12::from_der(der).unwrap(); + } +} diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index bfcaa5e4..dea315ae 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -245,7 +245,7 @@ run_test!(verify_trusted, |method, stream| { let mut ctx = SslContext::new(method).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -314,7 +314,7 @@ run_test!(verify_trusted_get_error_ok, |method, stream| { true }); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -338,7 +338,7 @@ run_test!(verify_callback_data, |method, stream| { // in DER format. // Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256 // Please update if "test/cert.pem" will ever change - let node_hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6"; + let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let node_id = node_hash_str.from_hex().unwrap(); ctx.set_verify_callback(SSL_VERIFY_PEER, move |_preverify_ok, x509_ctx| { let cert = x509_ctx.current_cert(); @@ -367,7 +367,7 @@ run_test!(ssl_verify_callback, |method, stream| { let ctx = SslContext::new(method).unwrap(); let mut ssl = ctx.into_ssl().unwrap(); - let node_hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6"; + let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let node_id = node_hash_str.from_hex().unwrap(); ssl.set_verify_callback(SSL_VERIFY_PEER, move |_, x509| { CHECKED.store(1, Ordering::SeqCst); diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index c09b31cd..43add896 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -86,7 +86,7 @@ fn test_cert_loading() { let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); let fingerprint = cert.fingerprint(SHA1).unwrap(); - let hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6"; + let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let hash_vec = hash_str.from_hex().unwrap(); assert_eq!(fingerprint, hash_vec); diff --git a/openssl/test/cert.pem b/openssl/test/cert.pem index b8c5ce01..032fe60e 100644 --- a/openssl/test/cert.pem +++ b/openssl/test/cert.pem @@ -1,21 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDhzCCAm+gAwIBAgIJAKyxk8nkmAtWMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxEzARBgNVBAMMCmZvb2Jhci5jb20wHhcNMTYwNTE2MDUw -NTAwWhcNMjYwNTE0MDUwNTAwWjBaMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29t -ZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYD -VQQDDApmb29iYXIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -qPQljESzF6NQhf4jkYfQeDYbSRf/LUfT5RvebDb8lrkEP/I33r/vMxK6ZcXy5LdK -SanKImRvIPTVNJFOqOU/v9UIGXJQgKGWktCasZqKNmJP9ULI9eqZzAXNdLkg5Olf -WiUl9bysDjVTUsIhwNTIV/ou1n+/ytJ4qvpO4TpIZXhZFoGbVKuNYF4dVXzroJGu -1JLWJ5PZqwWwDI5mpaGTZ9qTDAEMVYOE4Yi5t877lqr1wEls1GXOyAHdRmzeALQ7 -obNudnqhPROIkx5OxdeMAEtSVqr+uuoUXhh65mSRsdMUEzPbzw9RzebdlNyk34Tv -5k5QFFlcoPbQrTs26CoLNQIDAQABo1AwTjAdBgNVHQ4EFgQUtnMvYaVLoe9ILBWx -n/PcNC+8rDAwHwYDVR0jBBgwFoAUtnMvYaVLoe9ILBWxn/PcNC+8rDAwDAYDVR0T -BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAALVDDD2f25h5ytSkoUqQilybeRDg -bPhTEEC83NWg2snV1yGtwO3zZ+hvX+J/RqOn33ER/RnQCZTB9FGPj566IbLwLSAE -y83GDsbsFEWCL8yN4Q3dQVub7D3HZ5PBtGpBxC7brvJD7OnR3n75QOFC+OaGKUCo -16XulVsB3IQsXdzL4GwoUqWGWaUyf5MkzFruBma16QetK5J10R42skeXssjvqupv -qUQZxzGOzIGuLTBvJrtFxtoTCu+oZV942wGmuyvLwqRfzIODLNcGLS6lGJudXJPT -Vapaj6maldL3qe1X4bxvtglnpdlrOJ65E3YEC1gcD1KUvfO5vItKrP1FbA== +MIIDGzCCAgMCCQCHcfe97pgvpTANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMB4XDTE2MDgxNDE3MDAwM1oXDTI2MDgxMjE3MDAwM1owWjELMAkG +A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 +IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKZm9vYmFyLmNvbTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKj0JYxEsxejUIX+I5GH0Hg2G0kX/y1H0+Ub +3mw2/Ja5BD/yN96/7zMSumXF8uS3SkmpyiJkbyD01TSRTqjlP7/VCBlyUIChlpLQ +mrGaijZiT/VCyPXqmcwFzXS5IOTpX1olJfW8rA41U1LCIcDUyFf6LtZ/v8rSeKr6 +TuE6SGV4WRaBm1SrjWBeHVV866CRrtSS1ieT2asFsAyOZqWhk2fakwwBDFWDhOGI +ubfO+5aq9cBJbNRlzsgB3UZs3gC0O6GzbnZ6oT0TiJMeTsXXjABLUlaq/rrqFF4Y +euZkkbHTFBMz288PUc3m3ZTcpN+E7+ZOUBRZXKD20K07NugqCzUCAwEAATANBgkq +hkiG9w0BAQsFAAOCAQEASvYHuIl5C0NHBELPpVHNuLbQsDQNKVj3a54+9q1JkiMM +6taEJYfw7K1Xjm4RoiFSHpQBh+PWZS3hToToL2Zx8JfMR5MuAirdPAy1Sia/J/qE +wQdJccqmvuLkLTSlsGbEJ/LUUgOAgrgHOZM5lUgIhCneA0/dWJ3PsN0zvn69/faY +oo1iiolWiIHWWBUSdr3jM2AJaVAsTmLh00cKaDNk37JB940xConBGSl98JPrNrf9 +dUAiT0iIBngDBdHnn/yTj+InVEFyZSKrNtiDSObFHxPcxGteHNrCPJdP1e+GqkHp +HJMRZVCQpSMzvHlofHSNgzWV1MX5h1CP4SGZdBDTfA== -----END CERTIFICATE----- diff --git a/openssl/test/identity.p12 b/openssl/test/identity.p12 new file mode 100644 index 0000000000000000000000000000000000000000..d16abb8c70627bd959667495e578fb6f010a7f1d GIT binary patch literal 3386 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 CKSRy{ literal 0 HcmV?d00001 diff --git a/openssl/test/root-ca.key b/openssl/test/root-ca.key new file mode 100644 index 00000000..746ae2a6 --- /dev/null +++ b/openssl/test/root-ca.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEArVHWFn52Lbl1l59exduZntVSZyDYpzDND+S2LUcO6fRBWhV/ +1Kzox+2GZptbuMGmfI3iAnb0CFT4uC3kBkQQlXonGATSVyaFTFR+jq/lc0SP+9Bd +7SBXieIVeIXlY1TvlwIvj3Ntw9zX+scTA4SXxH6M0rKv9gTOub2vCMSHeF16X8DQ +r4XsZuQr7Cp7j1I4aqOJyap5JTl5ijmG8cnu0n+8UcRlBzy99dLWJG0AfI3VRJdW +pGTNVZ92aFff3RpK3F/WI2gp3qV1ynRAKuvmncGC3LDvYfcc2dgsc1N6Ffq8GIrk +gRob6eBcklDHp1d023Lwre+VaVDSo1//Y72UFwIDAQABAoIBAGZrnd/dC2kp11uq +Sg8SHk3GMdPPjTf/lq51sVJAU4fdV2Eso0XCiCzdKDcqR6F+jiu8jHp4YO0riW8N +b1pkjohGjyOaddIaaVsZ80/OkgDz20Ird9XQ7uoEODvopA12+755BDH5PDwqHVeM +nKfPiwAK6Jz6CxGO9bq9ZNoBiSyO1uofaB4Cpp8t74XVeAuPiI/Bb6WJ8TW5K5dt +x0Jihdo46QgZR+z4PnyWIoACkhSoQmtTb9NUrpKceBcxdCrZ/kEmYpnPq/PuSw6g +6HthjYP/H9Xulz69UR5Ez6z+1pU1rKFmQ46qK7X3zVHg233MlGekMzxdmShEjzCP +BMGYpQECgYEA5tqTZsUJwx3HDhkaZ/XOtaQqwOnZm9wPwTjGbV1t4+NUJzsl5gjP +ho+I8ZSGZ6MnNSh+ClpYhUHYBq0rTuAAYL2arcMOuOs1GrMmiZJbXm8zq8M7gYr5 +V99H/7akSx66WV/agPkLIvh/BWxlWgQcoVAIzZibbLUxr7Ye50pCLfECgYEAwDLn +mFz0mFMvGtaSp8RnTDTFCz9czCeDt0GujCxG1epdvtuxlg/S1QH+mGzA/AHkiu7z +uzCwGKWozNTdRkqVwYoJTB+AYHseSkuGP+a1zr39w+xBW/vESb2oP95GIwprXcG2 +b/qdeQVzuLQhYoqWI2u8CBwlHFfpQO4Bp2ea+ocCgYEAurIgLSfCqlpFpiAlG9hN +8NYwgU1d4E+LKj+JMd8yRO+PGh8amjub4X3pST5NqDjpN3Nk42iHWFWUqGmZsbM0 +ewg7tLUgDeqiStKBoxaK8AdMqWc9k5lZ53e6mZISsnHKUQdVBaLjH8gJqdAs8yyK +HudEB0mYwMSUxz6pJXIHrXECgYEAhJkaCpXm8chB8UQj/baUhZDKeI4IWZjRWHbq +Ey7g1+hPMMOk6yCTlf1ARqyRH8u2ftuIL5bRhs+Te21IE5yVYOb4rxn0mZuXNC6S +ujdTKwUMtESkeu9hZnaAQz/4J2ii1hY05WCDj+DhC4bKmY9/MYS8PuQb/kfwVqld +Xr8tvrUCgYEAmslHocXBUFXyRDkEOx/aKo+t9fPBr95PBZzFUt9ejrTP4PXsLa46 +3/PNOCGdrQxh5qHHcvLwR4bPL++Dj+qMUTJXANrArKPDpE2WqH6pqWIC6yaZvzUk +17QbpXR6bHcdJV045pWpw40UCStTocVynY1lBfOw8VqxBIBlpVBBzew= +-----END RSA PRIVATE KEY----- diff --git a/openssl/test/root-ca.pem b/openssl/test/root-ca.pem new file mode 100644 index 00000000..4ec2f538 --- /dev/null +++ b/openssl/test/root-ca.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJAOIvDiVb18eVMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTYwODE0MTY1NjExWhcNMjYwODEyMTY1NjExWjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEArVHWFn52Lbl1l59exduZntVSZyDYpzDND+S2LUcO6fRBWhV/1Kzox+2G +ZptbuMGmfI3iAnb0CFT4uC3kBkQQlXonGATSVyaFTFR+jq/lc0SP+9Bd7SBXieIV +eIXlY1TvlwIvj3Ntw9zX+scTA4SXxH6M0rKv9gTOub2vCMSHeF16X8DQr4XsZuQr +7Cp7j1I4aqOJyap5JTl5ijmG8cnu0n+8UcRlBzy99dLWJG0AfI3VRJdWpGTNVZ92 +aFff3RpK3F/WI2gp3qV1ynRAKuvmncGC3LDvYfcc2dgsc1N6Ffq8GIrkgRob6eBc +klDHp1d023Lwre+VaVDSo1//Y72UFwIDAQABo1AwTjAdBgNVHQ4EFgQUbNOlA6sN +XyzJjYqciKeId7g3/ZowHwYDVR0jBBgwFoAUbNOlA6sNXyzJjYqciKeId7g3/Zow +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAVVaR5QWLZIRR4Dw6TSBn +BQiLpBSXN6oAxdDw6n4PtwW6CzydaA+creiK6LfwEsiifUfQe9f+T+TBSpdIYtMv +Z2H2tjlFX8VrjUFvPrvn5c28CuLI0foBgY8XGSkR2YMYzWw2jPEq3Th/KM5Catn3 +AFm3bGKWMtGPR4v+90chEN0jzaAmJYRrVUh9vea27bOCn31Nse6XXQPmSI6Gyncy +OAPUsvPClF3IjeL1tmBotWqSGn1cYxLo+Lwjk22A9h6vjcNQRyZF2VLVvtwYrNU3 +mwJ6GCLsLHpwW/yjyvn8iEltnJvByM/eeRnfXV6WDObyiZsE/n6DxIRJodQzFqy9 +GA== +-----END CERTIFICATE----- From 3876332734e86334928f2901acdb077aab719fee Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 14 Aug 2016 10:29:55 -0700 Subject: [PATCH 03/10] Fix tests --- openssl/src/ssl/tests/mod.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index dea315ae..4151c23b 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -548,7 +548,7 @@ fn test_connect_with_unilateral_alpn() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -570,7 +570,7 @@ fn test_connect_with_unilateral_npn() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -592,7 +592,7 @@ fn test_connect_with_alpn_successful_multiple_matching() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -614,7 +614,7 @@ fn test_connect_with_npn_successful_multiple_matching() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -637,7 +637,7 @@ fn test_connect_with_alpn_successful_single_match() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -661,7 +661,7 @@ fn test_connect_with_npn_successful_single_match() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -701,7 +701,7 @@ fn test_npn_server_advertise_multiple() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -742,7 +742,7 @@ fn test_alpn_server_advertise_multiple() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -783,7 +783,7 @@ fn test_alpn_server_select_none() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/2"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } From ad4a8cc140e43c48446486ce6fbc59bef45a1ac6 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 14 Aug 2016 11:05:53 -0700 Subject: [PATCH 04/10] More test fixes --- openssl/src/ssl/tests/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index 4151c23b..4e4985e1 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -472,7 +472,7 @@ run_test!(get_peer_certificate, |method, stream| { let stream = SslStream::connect(&SslContext::new(method).unwrap(), stream).unwrap(); let cert = stream.ssl().peer_certificate().unwrap(); let fingerprint = cert.fingerprint(SHA1).unwrap(); - let node_hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6"; + let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let node_id = node_hash_str.from_hex().unwrap(); assert_eq!(node_id, fingerprint) }); From 6b12a0cddea0d4392cf0376c68b36d87cf19b86e Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 14 Aug 2016 11:11:26 -0700 Subject: [PATCH 05/10] PKCS #12 support --- openssl-sys/src/lib.rs | 4 +++ openssl/src/crypto/pkcs12.rs | 55 ++++++++++++++++++++++++++++++++++-- openssl/src/ssl/mod.rs | 2 +- openssl/src/x509/mod.rs | 24 ++++++++++++---- 4 files changed, 76 insertions(+), 9 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index a6041a6b..aa3a0df5 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1086,6 +1086,10 @@ extern "C" { -> c_int; pub fn PKCS12_free(p12: *mut PKCS12); + pub fn sk_free(st: *mut _STACK); + pub fn sk_pop_free(st: *mut _STACK, free: Option); + pub fn sk_pop(st: *mut _STACK) -> *mut c_char; + pub fn SSLeay() -> c_long; pub fn SSLeay_version(key: c_int) -> *const c_char; } diff --git a/openssl/src/crypto/pkcs12.rs b/openssl/src/crypto/pkcs12.rs index dfe30a6c..f35fa2c6 100644 --- a/openssl/src/crypto/pkcs12.rs +++ b/openssl/src/crypto/pkcs12.rs @@ -4,8 +4,11 @@ use ffi; use libc::{c_long, c_uchar}; use std::cmp; use std::ptr; +use std::ffi::CString; +use crypto::pkey::PKey; use error::ErrorStack; +use x509::X509; /// A PKCS #12 archive. pub struct Pkcs12(*mut ffi::PKCS12); @@ -19,21 +22,69 @@ impl Drop for Pkcs12 { impl Pkcs12 { pub fn from_der(der: &[u8]) -> Result { unsafe { + ffi::init(); let mut ptr = der.as_ptr() as *const c_uchar; let length = cmp::min(der.len(), c_long::max_value() as usize) as c_long; let p12 = try_ssl_null!(ffi::d2i_PKCS12(ptr::null_mut(), &mut ptr, length)); Ok(Pkcs12(p12)) } } + + pub fn parse(&self, pass: &str) -> Result { + unsafe { + let pass = CString::new(pass).unwrap(); + + let mut pkey = ptr::null_mut(); + let mut cert = ptr::null_mut(); + let mut chain = ptr::null_mut(); + + try_ssl!(ffi::PKCS12_parse(self.0, pass.as_ptr(), &mut pkey, &mut cert, &mut chain)); + + let pkey = PKey::from_ptr(pkey); + let cert = X509::from_ptr(cert); + + let mut chain_out = vec![]; + for i in 0..(*chain).stack.num { + let x509 = *(*chain).stack.data.offset(i as isize) as *mut _; + chain_out.push(X509::from_ptr(x509)); + } + ffi::sk_free(&mut (*chain).stack); + + Ok(ParsedPkcs12 { + pkey: pkey, + cert: cert, + chain: chain_out, + _p: (), + }) + } + } +} + +pub struct ParsedPkcs12 { + pub pkey: PKey, + pub cert: X509, + pub chain: Vec, + _p: (), } #[cfg(test)] mod test { + use crypto::hash::Type::SHA1; + use serialize::hex::ToHex; + use super::*; #[test] - fn from_der() { + fn parse() { let der = include_bytes!("../../test/identity.p12"); - Pkcs12::from_der(der).unwrap(); + let pkcs12 = Pkcs12::from_der(der).unwrap(); + let parsed = pkcs12.parse("mypass").unwrap(); + + assert_eq!(parsed.cert.fingerprint(SHA1).unwrap().to_hex(), + "59172d9313e84459bcff27f967e79e6e9217e584"); + + assert_eq!(parsed.chain.len(), 1); + assert_eq!(parsed.chain[0].fingerprint(SHA1).unwrap().to_hex(), + "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"); } } diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 1ace24ed..64a2ccaf 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -933,7 +933,7 @@ impl<'a> SslRef<'a> { if ptr.is_null() { None } else { - Some(X509::new(ptr)) + Some(X509::from_ptr(ptr)) } } } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 9f1c1a79..4943f7a9 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -94,7 +94,7 @@ impl X509StoreContext { if ptr.is_null() { None } else { - Some(X509Ref::new(ptr)) + Some(X509Ref::from_ptr(ptr)) } } } @@ -298,7 +298,7 @@ impl X509Generator { unsafe { let x509 = try_ssl_null!(ffi::X509_new()); - let x509 = X509::new(x509); + let x509 = X509::from_ptr(x509); try_ssl!(ffi::X509_set_version(x509.as_ptr(), 2)); try_ssl!(ffi::ASN1_INTEGER_set(ffi::X509_get_serialNumber(x509.as_ptr()), @@ -377,8 +377,14 @@ pub struct X509Ref<'a>(*mut ffi::X509, PhantomData<&'a ()>); impl<'a> X509Ref<'a> { /// Creates a new `X509Ref` wrapping the provided handle. - pub unsafe fn new(handle: *mut ffi::X509) -> X509Ref<'a> { - X509Ref(handle, PhantomData) + pub unsafe fn from_ptr(x509: *mut ffi::X509) -> X509Ref<'a> { + X509Ref(x509, PhantomData) + } + + /// + #[deprecated(note = "renamed to `X509::from_ptr`", since = "0.8.1")] + pub unsafe fn new(x509: *mut ffi::X509) -> X509Ref<'a> { + X509Ref::from_ptr(x509) } pub fn as_ptr(&self) -> *mut ffi::X509 { @@ -451,8 +457,14 @@ pub struct X509(X509Ref<'static>); impl X509 { /// Returns a new `X509`, taking ownership of the handle. + pub unsafe fn from_ptr(x509: *mut ffi::X509) -> X509 { + X509(X509Ref::from_ptr(x509)) + } + + /// + #[deprecated(note = "renamed to `X509::from_ptr`", since = "0.8.1")] pub unsafe fn new(x509: *mut ffi::X509) -> X509 { - X509(X509Ref::new(x509)) + X509::from_ptr(x509) } /// Reads a certificate from PEM. @@ -463,7 +475,7 @@ impl X509 { ptr::null_mut(), None, ptr::null_mut())); - Ok(X509::new(handle)) + Ok(X509::from_ptr(handle)) } } } From e5299fd7c9661579d6de30a5be5b032a90203c95 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 14 Aug 2016 11:16:53 -0700 Subject: [PATCH 06/10] Fix memory leak in general name stack --- openssl-sys/src/lib.rs | 2 ++ openssl/src/x509/mod.rs | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index aa3a0df5..829f6bc1 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1090,6 +1090,8 @@ extern "C" { pub fn sk_pop_free(st: *mut _STACK, free: Option); pub fn sk_pop(st: *mut _STACK) -> *mut c_char; + pub fn GENERAL_NAME_free(name: *mut GENERAL_NAME); + pub fn SSLeay() -> c_long; pub fn SSLeay_version(key: c_int) -> *const c_char; } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 4943f7a9..fb6c2aaa 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -408,7 +408,7 @@ impl<'a> X509Ref<'a> { } Some(GeneralNames { - stack: stack as *const _, + stack: stack as *mut _, m: PhantomData, }) } @@ -735,12 +735,23 @@ make_validation_error!(X509_V_OK, X509ApplicationVerification = X509_V_ERR_APPLICATION_VERIFICATION, ); +// FIXME remove lifetime param for 0.9 /// A collection of OpenSSL `GENERAL_NAME`s. pub struct GeneralNames<'a> { - stack: *const ffi::stack_st_GENERAL_NAME, + stack: *mut ffi::stack_st_GENERAL_NAME, m: PhantomData<&'a ()>, } +impl<'a> Drop for GeneralNames<'a> { + fn drop(&mut self) { + unsafe { + let free: unsafe extern "C" fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; + let free: unsafe extern "C" fn(*mut c_void) = mem::transmute(free); + ffi::sk_pop_free(&mut (*self.stack).stack, Some(free)); + } + } +} + impl<'a> GeneralNames<'a> { /// Returns the number of `GeneralName`s in this structure. pub fn len(&self) -> usize { From e6c4135c53c830a97af4231a02e0f84c18dc720a Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 14 Aug 2016 11:24:18 -0700 Subject: [PATCH 07/10] Docs for pkcs12 --- openssl/src/crypto/pkcs12.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openssl/src/crypto/pkcs12.rs b/openssl/src/crypto/pkcs12.rs index f35fa2c6..89bcbd5c 100644 --- a/openssl/src/crypto/pkcs12.rs +++ b/openssl/src/crypto/pkcs12.rs @@ -20,6 +20,7 @@ impl Drop for Pkcs12 { } impl Pkcs12 { + /// Deserializes a `Pkcs12` structure from DER-encoded data. pub fn from_der(der: &[u8]) -> Result { unsafe { ffi::init(); @@ -30,6 +31,7 @@ impl Pkcs12 { } } + /// Extracts the contents of the `Pkcs12`. pub fn parse(&self, pass: &str) -> Result { unsafe { let pass = CString::new(pass).unwrap(); From 912f7499cdf215f74d84d7c170a52775101d9de9 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 14 Aug 2016 12:51:33 -0700 Subject: [PATCH 08/10] Initialize algorithms in init Required to deserialize PKCS12 on 0.9.8, looks like --- openssl-sys/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 829f6bc1..a5ec7801 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -516,6 +516,7 @@ pub fn init() { unsafe { SSL_library_init(); SSL_load_error_strings(); + OPENSSL_add_all_algorithms_noconf(); let num_locks = CRYPTO_num_locks(); let mut mutexes = Box::new(Vec::new()); @@ -895,8 +896,8 @@ extern "C" { siglen: c_int, dsa: *mut DSA) -> c_int; pub fn SSL_library_init() -> c_int; - pub fn SSL_load_error_strings(); + pub fn OPENSSL_add_all_algorithms_noconf(); #[cfg(feature = "sslv2")] pub fn SSLv2_method() -> *const SSL_METHOD; From 88dcb1c81d6e726bf2e239a4b9f44b9365800b15 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 15 Aug 2016 18:41:18 -0700 Subject: [PATCH 09/10] Add a little comment to sketchy transmute --- openssl/src/x509/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index fb6c2aaa..0cc0eca7 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -745,6 +745,7 @@ pub struct GeneralNames<'a> { impl<'a> Drop for GeneralNames<'a> { fn drop(&mut self) { unsafe { + // This transmute is dubious but it's what openssl itself does... let free: unsafe extern "C" fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; let free: unsafe extern "C" fn(*mut c_void) = mem::transmute(free); ffi::sk_pop_free(&mut (*self.stack).stack, Some(free)); From 629f638f085277c0bf3c27058613b832c5007aa6 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 15 Aug 2016 18:44:57 -0700 Subject: [PATCH 10/10] Release openssl-sys v0.7.16, openssl v0.8.1 --- README.md | 2 +- openssl-sys/Cargo.toml | 4 ++-- openssl-sys/src/lib.rs | 2 +- openssl/Cargo.toml | 6 +++--- openssl/src/lib.rs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ec7eecf1..da4411b2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://travis-ci.org/sfackler/rust-openssl.svg?branch=master)](https://travis-ci.org/sfackler/rust-openssl) -[Documentation](https://sfackler.github.io/rust-openssl/doc/v0.8.0/openssl). +[Documentation](https://sfackler.github.io/rust-openssl/doc/v0.8.1/openssl). ## Building diff --git a/openssl-sys/Cargo.toml b/openssl-sys/Cargo.toml index e09c2020..4b2b6691 100644 --- a/openssl-sys/Cargo.toml +++ b/openssl-sys/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "openssl-sys" -version = "0.7.15" +version = "0.7.16" authors = ["Alex Crichton ", "Steven Fackler "] license = "MIT" description = "FFI bindings to OpenSSL" repository = "https://github.com/sfackler/rust-openssl" -documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.15/openssl_sys" +documentation = "https://sfackler.github.io/rust-openssl/doc/v0.7.16/openssl_sys" links = "openssl" build = "build.rs" diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index a5ec7801..be3ae53e 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1,6 +1,6 @@ #![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)] #![allow(dead_code)] -#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.7.15")] +#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.7.16")] extern crate libc; diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index a5d0de8b..d1d709a3 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "openssl" -version = "0.8.0" +version = "0.8.1" authors = ["Steven Fackler "] license = "Apache-2.0" description = "OpenSSL bindings" repository = "https://github.com/sfackler/rust-openssl" -documentation = "https://sfackler.github.io/rust-openssl/doc/v0.8.0/openssl" +documentation = "https://sfackler.github.io/rust-openssl/doc/v0.8.1/openssl" readme = "../README.md" keywords = ["crypto", "tls", "ssl", "dtls"] build = "build.rs" @@ -38,7 +38,7 @@ dh_from_params = ["c_helpers"] bitflags = "0.7" lazy_static = "0.2" libc = "0.2" -openssl-sys = { version = "0.7.15", path = "../openssl-sys" } +openssl-sys = { version = "0.7.16", path = "../openssl-sys" } [build-dependencies] gcc = { version = "0.3", optional = true } diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index d7e69b0c..f20401f6 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.8.0")] +#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.8.1")] #[macro_use] extern crate bitflags;