diff options
author | Steven Fackler <sfackler@gmail.com> | 2015-11-10 21:32:19 -0800 |
---|---|---|
committer | Steven Fackler <sfackler@gmail.com> | 2015-11-16 20:16:01 -0800 |
commit | a8a10e64ad21fe900dbeef220493cc31cbeda48e (patch) | |
tree | 22677ed06cdb8956fac3a017639ee52e8baf07a5 /openssl-sys-extras | |
parent | 8139fadbff0c74b5a93c0257eed268f51d516c68 (diff) | |
download | rust-openssl-a8a10e64ad21fe900dbeef220493cc31cbeda48e.zip |
Split stuff requiring a shim out to a separate crate
Diffstat (limited to 'openssl-sys-extras')
-rw-r--r-- | openssl-sys-extras/Cargo.toml | 16 | ||||
-rw-r--r-- | openssl-sys-extras/build.rs | 77 | ||||
-rw-r--r-- | openssl-sys-extras/src/lib.rs | 64 | ||||
-rw-r--r-- | openssl-sys-extras/src/openssl_shim.c | 142 | ||||
-rw-r--r-- | openssl-sys-extras/src/ssl_options.rs | 46 |
5 files changed, 345 insertions, 0 deletions
diff --git a/openssl-sys-extras/Cargo.toml b/openssl-sys-extras/Cargo.toml new file mode 100644 index 00000000..031b2124 --- /dev/null +++ b/openssl-sys-extras/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "openssl-sys-extras" +version = "0.6.7" +authors = ["Steven Fackler <sfackler@gmail.com>"] +links = "openssl_shim" +build = "build.rs" + +[features] +ecdh_auto = [] + +[dependencies] +libc = "0.2" +openssl-sys = { version = "0.6.7", path = "../openssl-sys" } + +[build-dependencies] +gcc = "0.3" diff --git a/openssl-sys-extras/build.rs b/openssl-sys-extras/build.rs new file mode 100644 index 00000000..e3c695b1 --- /dev/null +++ b/openssl-sys-extras/build.rs @@ -0,0 +1,77 @@ +extern crate gcc; + +use std::env; +use std::path::PathBuf; +use std::fs::File; +use std::io::Write as IoWrite; +use std::fmt::Write; + +fn main() { + let options_shim_file = generate_options_shim(); + let mut config = gcc::Config::new(); + + if let Some(paths) = env::var_os("DEP_OPENSSL_INCLUDE") { + for path in env::split_paths(&paths) { + config.include(PathBuf::from(path)); + } + } + + config.file("src/openssl_shim.c") + .file(options_shim_file) + .compile("libopenssl_shim.a"); +} + +macro_rules! import_options { + ( $( $name:ident $val:expr )* ) => { + &[ $( (stringify!($name),$val), )* ] + }; +} + +fn generate_options_shim() -> PathBuf { + let options: &[(&'static str,u64)]=include!("src/ssl_options.rs"); + let mut shim = String::new(); + writeln!(shim,"#include <stdint.h>").unwrap(); + writeln!(shim,"#include <openssl/ssl.h>").unwrap(); + + for &(name,value) in options { + writeln!(shim,"#define RUST_{} UINT64_C({})",name,value).unwrap(); + writeln!(shim,"#ifndef {}",name).unwrap(); + writeln!(shim,"# define {} 0",name).unwrap(); + writeln!(shim,"#endif").unwrap(); + } + + writeln!(shim,"#define COPY_MASK ( \\").unwrap(); + + let mut it=options.iter().peekable(); + while let Some(&(name,_))=it.next() { + let eol=match it.peek() { + Some(_) => " | \\", + None => " )" + }; + writeln!(shim," ((RUST_{0}==(uint64_t)(uint32_t){0})?RUST_{0}:UINT64_C(0)){1}",name,eol).unwrap(); + } + + writeln!(shim,"long rust_openssl_ssl_ctx_options_rust_to_c(uint64_t rustval) {{").unwrap(); + writeln!(shim," long cval=rustval©_MASK;").unwrap(); + for &(name,_) in options { + writeln!(shim," if (rustval&RUST_{0}) cval|={0};",name).unwrap(); + } + writeln!(shim," return cval;").unwrap(); + writeln!(shim,"}}").unwrap(); + + writeln!(shim,"uint64_t rust_openssl_ssl_ctx_options_c_to_rust(long cval) {{").unwrap(); + writeln!(shim," uint64_t rustval=cval©_MASK;").unwrap(); + for &(name,_) in options { + writeln!(shim," if (cval&{0}) rustval|=RUST_{0};",name).unwrap(); + } + writeln!(shim," return rustval;").unwrap(); + writeln!(shim,"}}").unwrap(); + + let out_dir = env::var("OUT_DIR").unwrap(); + let dest_file = PathBuf::from(&out_dir).join("ssl_ctx_options_shim.c"); + let mut f = File::create(&dest_file).unwrap(); + + f.write_all(shim.as_bytes()).unwrap(); + + dest_file +} diff --git a/openssl-sys-extras/src/lib.rs b/openssl-sys-extras/src/lib.rs new file mode 100644 index 00000000..c602c514 --- /dev/null +++ b/openssl-sys-extras/src/lib.rs @@ -0,0 +1,64 @@ +#![allow(non_upper_case_globals, non_snake_case)] + +extern crate openssl_sys; +extern crate libc; + +use libc::{c_int, c_uint, c_long, c_char}; +use openssl_sys::{HMAC_CTX, EVP_MD, ENGINE, SSL_CTX, BIO, X509, stack_st_X509_EXTENSION, SSL, DH}; + +macro_rules! import_options { + ( $( $name:ident $val:expr )* ) => { + $( pub const $name: u64 = $val; )* + }; +} + +include!("ssl_options.rs"); + +pub unsafe fn SSL_CTX_set_options(ssl: *mut SSL_CTX, op: u64) -> u64 { + rust_openssl_ssl_ctx_options_c_to_rust(SSL_CTX_set_options_shim(ssl, rust_openssl_ssl_ctx_options_rust_to_c(op))) +} + +pub unsafe fn SSL_CTX_get_options(ssl: *mut SSL_CTX) -> u64 { + rust_openssl_ssl_ctx_options_c_to_rust(SSL_CTX_get_options_shim(ssl)) +} + +pub unsafe fn SSL_CTX_clear_options(ssl: *mut SSL_CTX, op: u64) -> u64 { + rust_openssl_ssl_ctx_options_c_to_rust(SSL_CTX_clear_options_shim(ssl, rust_openssl_ssl_ctx_options_rust_to_c(op))) +} + +extern { + fn rust_openssl_ssl_ctx_options_rust_to_c(rustval: u64) -> c_long; + fn rust_openssl_ssl_ctx_options_c_to_rust(cval: c_long) -> u64; + + // Pre-1.0 versions of these didn't return anything, so the shims bridge that gap + #[cfg_attr(not(target_os = "nacl"), link_name = "HMAC_Init_ex_shim")] + pub fn HMAC_Init_ex(ctx: *mut HMAC_CTX, key: *const u8, keylen: c_int, md: *const EVP_MD, imple: *const ENGINE) -> c_int; + #[cfg_attr(not(target_os = "nacl"), link_name = "HMAC_Final_shim")] + pub fn HMAC_Final(ctx: *mut HMAC_CTX, output: *mut u8, len: *mut c_uint) -> c_int; + #[cfg_attr(not(target_os = "nacl"), link_name = "HMAC_Update_shim")] + pub fn HMAC_Update(ctx: *mut HMAC_CTX, input: *const u8, len: c_uint) -> c_int; + + // These functions are defined in OpenSSL as macros, so we shim them + #[link_name = "BIO_eof_shim"] + pub fn BIO_eof(b: *mut BIO) -> c_int; + #[link_name = "BIO_set_nbio_shim"] + pub fn BIO_set_nbio(b: *mut BIO, enabled: c_long) -> c_long; + #[link_name = "BIO_set_mem_eof_return_shim"] + pub fn BIO_set_mem_eof_return(b: *mut BIO, v: c_int); + pub fn SSL_CTX_set_options_shim(ctx: *mut SSL_CTX, options: c_long) -> c_long; + pub fn SSL_CTX_get_options_shim(ctx: *mut SSL_CTX) -> c_long; + pub fn SSL_CTX_clear_options_shim(ctx: *mut SSL_CTX, options: c_long) -> c_long; + #[link_name = "SSL_CTX_add_extra_chain_cert_shim"] + pub fn SSL_CTX_add_extra_chain_cert(ctx: *mut SSL_CTX, x509: *mut X509) -> c_long; + #[link_name = "SSL_CTX_set_read_ahead_shim"] + pub fn SSL_CTX_set_read_ahead(ctx: *mut SSL_CTX, m: c_long) -> c_long; + #[cfg(feature = "ecdh_auto")] + #[link_name = "SSL_CTX_set_ecdh_auto_shim"] + pub fn SSL_CTX_set_ecdh_auto(ssl: *mut SSL_CTX, onoff: c_int) -> c_int; + #[link_name = "SSL_set_tlsext_host_name_shim"] + pub fn SSL_set_tlsext_host_name(s: *mut SSL, name: *const c_char) -> c_long; + #[link_name = "SSL_CTX_set_tmp_dh_shim"] + pub fn SSL_CTX_set_tmp_dh(s: *mut SSL, dh: *const DH) -> c_long; + #[link_name = "X509_get_extensions_shim"] + pub fn X509_get_extensions(x: *mut X509) -> *mut stack_st_X509_EXTENSION; +} diff --git a/openssl-sys-extras/src/openssl_shim.c b/openssl-sys-extras/src/openssl_shim.c new file mode 100644 index 00000000..84adb47b --- /dev/null +++ b/openssl-sys-extras/src/openssl_shim.c @@ -0,0 +1,142 @@ +#include <openssl/hmac.h> +#include <openssl/ssl.h> +#include <openssl/dh.h> +#include <openssl/bn.h> + +#if defined(__APPLE__) || defined(__linux) + +#include<pthread.h> +#include<openssl/crypto.h> + +unsigned long thread_id() +{ + return (unsigned long) pthread_self(); +} + +void rust_openssl_set_id_callback() { + CRYPTO_set_id_callback(thread_id); +} + +#else +// Openssl already handles Windows directly, so we don't +// need to explicitly set it + +void rust_openssl_set_id_callback() { + // We don't know how to set the callback for arbitrary OSes + // Let openssl use its defaults and hope they work. +} + +#endif + + +#if OPENSSL_VERSION_NUMBER < 0x10000000L +// Copied from openssl crypto/hmac/hmac.c +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx) + { + if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx)) + goto err; + if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx)) + goto err; + if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx)) + goto err; + memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK); + dctx->key_length = sctx->key_length; + dctx->md = sctx->md; + return 1; + err: + return 0; + } + +int HMAC_Init_ex_shim(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 HMAC_Update_shim(HMAC_CTX *ctx, const unsigned char *data, int len) { + HMAC_Update(ctx, data, len); + return 1; +} + +int HMAC_Final_shim(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { + HMAC_Final(ctx, md, len); + return 1; +} + +#else + +int HMAC_Init_ex_shim(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 HMAC_Update_shim(HMAC_CTX *ctx, const unsigned char *data, int len) { + return HMAC_Update(ctx, data, len); +} + +int HMAC_Final_shim(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { + return HMAC_Final(ctx, md, len); +} +#endif + +// shims for OpenSSL macros + +int BIO_eof_shim(BIO *b) { + return BIO_eof(b); +} + +long BIO_set_nbio_shim(BIO *b, long enabled) { + return BIO_set_nbio(b, enabled); +} + +void BIO_set_mem_eof_return_shim(BIO *b, int v) { + BIO_set_mem_eof_return(b, v); +} + +long SSL_CTX_set_options_shim(SSL_CTX *ctx, long options) { + return SSL_CTX_set_options(ctx, options); +} + +long SSL_CTX_get_options_shim(SSL_CTX *ctx) { + return SSL_CTX_get_options(ctx); +} + +long SSL_CTX_clear_options_shim(SSL_CTX *ctx, long options) { + return SSL_CTX_clear_options(ctx, options); +} + +long SSL_CTX_add_extra_chain_cert_shim(SSL_CTX *ctx, X509 *x509) { + return SSL_CTX_add_extra_chain_cert(ctx, x509); +} + +long SSL_CTX_set_read_ahead_shim(SSL_CTX *ctx, long m) { + return SSL_CTX_set_read_ahead(ctx, m); +} + +long SSL_CTX_set_tmp_dh_shim(SSL_CTX *ctx, DH *dh) { + return SSL_CTX_set_tmp_dh(ctx, dh); +} + +#if OPENSSL_VERSION_NUMBER >= 0x10002000L +int SSL_CTX_set_ecdh_auto_shim(SSL_CTX *ctx, int onoff) { + return SSL_CTX_set_ecdh_auto(ctx, onoff); +} +#endif + +DH *DH_new_from_params(BIGNUM *p, BIGNUM *g, BIGNUM *q) { + DH *dh; + + if ((dh = DH_new()) == NULL) { + return NULL; + } + dh->p = p; + dh->g = g; + dh->q = q; + return dh; +} + +long SSL_set_tlsext_host_name_shim(SSL *s, char *name) { + return SSL_set_tlsext_host_name(s, name); +} + +STACK_OF(X509_EXTENSION) *X509_get_extensions_shim(X509 *x) { + return x->cert_info ? x->cert_info->extensions : NULL; +} diff --git a/openssl-sys-extras/src/ssl_options.rs b/openssl-sys-extras/src/ssl_options.rs new file mode 100644 index 00000000..a1c778ac --- /dev/null +++ b/openssl-sys-extras/src/ssl_options.rs @@ -0,0 +1,46 @@ +import_options!{ +// The following values are directly from recent OpenSSL +SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001 +SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002 +SSL_OP_LEGACY_SERVER_CONNECT 0x00000004 +SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008 +SSL_OP_TLSEXT_PADDING 0x00000010 +SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020 +SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040 +SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x00000080 +SSL_OP_TLS_D5_BUG 0x00000100 +SSL_OP_TLS_BLOCK_PADDING_BUG 0x00000200 +// unused: 0x00000400 +SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800 +SSL_OP_NO_QUERY_MTU 0x00001000 +SSL_OP_COOKIE_EXCHANGE 0x00002000 +SSL_OP_NO_TICKET 0x00004000 +SSL_OP_CISCO_ANYCONNECT 0x00008000 +SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000 +SSL_OP_NO_COMPRESSION 0x00020000 +SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000 +SSL_OP_SINGLE_ECDH_USE 0x00080000 +SSL_OP_SINGLE_DH_USE 0x00100000 +// unused: 0x00200000 +SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000 +SSL_OP_TLS_ROLLBACK_BUG 0x00800000 +SSL_OP_NO_SSLv2 0x01000000 +SSL_OP_NO_SSLv3 0x02000000 +SSL_OP_NO_DTLSv1 0x04000000 +SSL_OP_NO_TLSv1 0x04000000 +SSL_OP_NO_DTLSv1_2 0x08000000 +SSL_OP_NO_TLSv1_2 0x08000000 +SSL_OP_NO_TLSv1_1 0x10000000 +SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000 +SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x40000000 +SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000 + +// The following values were in 32-bit range in old OpenSSL +SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x100000000 +SSL_OP_MSIE_SSLV2_RSA_PADDING 0x200000000 +SSL_OP_PKCS1_CHECK_1 0x400000000 +SSL_OP_PKCS1_CHECK_2 0x800000000 + +// The following values were redefined to 0 for security reasons +SSL_OP_EPHEMERAL_RSA 0x0 +} |