diff --git a/mbedtls-sys/build/bindgen.rs b/mbedtls-sys/build/bindgen.rs index b506eed69..c6dfd6ab0 100644 --- a/mbedtls-sys/build/bindgen.rs +++ b/mbedtls-sys/build/bindgen.rs @@ -1,15 +1,15 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use bindgen; use std::fs::File; -use std::io::{stderr,Write}; +use std::io::{stderr, Write}; use headers; @@ -17,48 +17,69 @@ use headers; struct StderrLogger; impl bindgen::Logger for StderrLogger { - fn error(&self, msg: &str) { let _=writeln!(stderr(),"Bindgen ERROR: {}",msg); } - fn warn(&self, msg: &str) { let _=writeln!(stderr(),"Bindgen WARNING: {}",msg); } + fn error(&self, msg: &str) { + let _ = writeln!(stderr(), "Bindgen ERROR: {}", msg); + } + fn warn(&self, msg: &str) { + let _ = writeln!(stderr(), "Bindgen WARNING: {}", msg); + } } impl super::BuildConfig { - pub fn bindgen(&self) { - let header=self.out_dir.join("bindgen-input.h"); - File::create(&header).and_then(|mut f|Ok( - for h in headers::enabled_ordered() { - try!(writeln!(f,"#include ",h)); - } - )).expect("bindgen-input.h I/O error"); + pub fn bindgen(&self) { + let header = self.out_dir.join("bindgen-input.h"); + File::create(&header) + .and_then(|mut f| { + Ok(for h in headers::enabled_ordered() { + try!(writeln!(f, "#include ", h)); + }) + }).expect("bindgen-input.h I/O error"); - let include=self.mbedtls_src.join("include"); - - let logger=StderrLogger; - let mut bindgen=bindgen::Builder::new(header.into_os_string().into_string().unwrap()); - let bindings=bindgen - .log(&logger) - .clang_arg("-Dmbedtls_t_udbl=mbedtls_t_udbl;") // bindgen can't handle unused uint128 - .clang_arg(format!("-DMBEDTLS_CONFIG_FILE=<{}>",self.config_h.to_str().expect("config.h UTF-8 error"))) - .clang_arg(format!("-I{}",include.to_str().expect("include/ UTF-8 error"))) - .match_pat(include.to_str().expect("include/ UTF-8 error")) - .match_pat(self.config_h.to_str().expect("config.h UTF-8 error")) - .use_core(true) - .derive_debug(false) // buggy :( - .ctypes_prefix(vec!["types".to_owned(),"raw_types".to_owned()]) - .remove_prefix("mbedtls_") - .rust_enums(false) - .convert_macros(true) - .macro_int_types(vec!["sint","sint","sint","slonglong","sint","sint","sint","slonglong"].into_iter()) - .generate().expect("bindgen error"); + let include = self.mbedtls_src.join("include"); - let bindings_rs=self.out_dir.join("bindings.rs"); - File::create(&bindings_rs).and_then(|mut f|{ - try!(bindings.write(Box::new(&mut f))); - f.write_all(b"use ::types::*;\n") // for FILE, time_t, etc. - }).expect("bindings.rs I/O error"); + let logger = StderrLogger; + let mut bindgen = bindgen::Builder::new(header.into_os_string().into_string().unwrap()); + let bindings = bindgen + .log(&logger) + .clang_arg("-Dmbedtls_t_udbl=mbedtls_t_udbl;") // bindgen can't handle unused uint128 + .clang_arg(format!( + "-DMBEDTLS_CONFIG_FILE=<{}>", + self.config_h.to_str().expect("config.h UTF-8 error") + )).clang_arg(format!( + "-I{}", + include.to_str().expect("include/ UTF-8 error") + )).match_pat(include.to_str().expect("include/ UTF-8 error")) + .match_pat(self.config_h.to_str().expect("config.h UTF-8 error")) + .use_core(true) + .derive_debug(false) // buggy :( + .ctypes_prefix(vec!["types".to_owned(), "raw_types".to_owned()]) + .remove_prefix("mbedtls_") + .rust_enums(false) + .convert_macros(true) + .macro_int_types( + vec![ + "sint", + "sint", + "sint", + "slonglong", + "sint", + "sint", + "sint", + "slonglong", + ].into_iter(), + ).generate() + .expect("bindgen error"); - let mod_bindings=self.out_dir.join("mod-bindings.rs"); - File::create(&mod_bindings).and_then(|mut f| - f.write_all(b"mod bindings;\n") - ).expect("mod-bindings.rs I/O error"); - } + let bindings_rs = self.out_dir.join("bindings.rs"); + File::create(&bindings_rs) + .and_then(|mut f| { + try!(bindings.write(Box::new(&mut f))); + f.write_all(b"use ::types::*;\n") // for FILE, time_t, etc. + }).expect("bindings.rs I/O error"); + + let mod_bindings = self.out_dir.join("mod-bindings.rs"); + File::create(&mod_bindings) + .and_then(|mut f| f.write_all(b"mod bindings;\n")) + .expect("mod-bindings.rs I/O error"); + } } diff --git a/mbedtls-sys/build/build.rs b/mbedtls-sys/build/build.rs index 5dd030849..facf0cada 100644 --- a/mbedtls-sys/build/build.rs +++ b/mbedtls-sys/build/build.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ extern crate bindgen; @@ -11,79 +11,104 @@ extern crate cmake; mod config; mod headers; -#[path="cmake.rs"] -mod mod_cmake; -#[path="bindgen.rs"] +#[path = "bindgen.rs"] mod mod_bindgen; +#[path = "cmake.rs"] +mod mod_cmake; use std::collections::HashMap; -use std::path::{Path,PathBuf}; use std::env; use std::fs::File; use std::io::Write; +use std::path::{Path, PathBuf}; pub fn have_feature(feature: &'static str) -> bool { - env::var_os(format!("CARGO_FEATURE_{}",feature).to_uppercase().replace("-","_")).is_some() + env::var_os( + format!("CARGO_FEATURE_{}", feature) + .to_uppercase() + .replace("-", "_"), + ).is_some() } struct BuildConfig { - out_dir: PathBuf, - mbedtls_src: PathBuf, - config_h: PathBuf, + out_dir: PathBuf, + mbedtls_src: PathBuf, + config_h: PathBuf, } impl BuildConfig { - fn create_config_h(&self) { - let mut defines=config::DEFAULT_DEFINES.iter().cloned().collect::>(); - for &(feat,def) in config::FEATURE_DEFINES { - if have_feature(feat) { - defines.insert(def.0,def.1); - } - } - - File::create(&self.config_h).and_then(|mut f|{ - try!(f.write_all(config::PREFIX.as_bytes())); - for (name,def) in defines { - try!(f.write_all(def.define(name).as_bytes())); - } - if have_feature("custom_printf") { - try!(writeln!(f,"int mbedtls_printf(const char *format, ...);")); - } - if have_feature("custom_has_support") { - try!(writeln!(f,"int mbedtls_aesni_has_support( unsigned int what ) __attribute__((weak));")); - try!(writeln!(f,"int mbedtls_padlock_has_support( int feature ) __attribute__((weak));")); - } - if have_feature("custom_threading") { - try!(writeln!(f,"typedef void* mbedtls_threading_mutex_t;")); - } - f.write_all(config::SUFFIX.as_bytes()) - }).expect("config.h I/O error"); - } + fn create_config_h(&self) { + let mut defines = config::DEFAULT_DEFINES + .iter() + .cloned() + .collect::>(); + for &(feat, def) in config::FEATURE_DEFINES { + if have_feature(feat) { + defines.insert(def.0, def.1); + } + } + + File::create(&self.config_h) + .and_then(|mut f| { + try!(f.write_all(config::PREFIX.as_bytes())); + for (name, def) in defines { + try!(f.write_all(def.define(name).as_bytes())); + } + if have_feature("custom_printf") { + try!(writeln!(f, "int mbedtls_printf(const char *format, ...);")); + } + if have_feature("custom_has_support") { + try!(writeln!( + f, + "int mbedtls_aesni_has_support( unsigned int what ) __attribute__((weak));" + )); + try!(writeln!( + f, + "int mbedtls_padlock_has_support( int feature ) __attribute__((weak));" + )); + } + if have_feature("custom_threading") { + try!(writeln!(f, "typedef void* mbedtls_threading_mutex_t;")); + } + f.write_all(config::SUFFIX.as_bytes()) + }).expect("config.h I/O error"); + } - fn print_rerun_files(&self) { + fn print_rerun_files(&self) { println!("cargo:rerun-if-env-changed=RUST_MBEDTLS_SYS_SOURCE"); - println!("cargo:rerun-if-changed={}",self.mbedtls_src.join("CMakeLists.txt").display()); - let include=self.mbedtls_src.join(Path::new("include").join("mbedtls")); + println!( + "cargo:rerun-if-changed={}", + self.mbedtls_src.join("CMakeLists.txt").display() + ); + let include = self.mbedtls_src.join(Path::new("include").join("mbedtls")); for h in headers::enabled_ordered() { - println!("cargo:rerun-if-changed={}",include.join(h).display()); - } - for f in self.mbedtls_src.join("library").read_dir().expect("read_dir failed") { - println!("cargo:rerun-if-changed={}",f.expect("DirEntry failed").path().display()); - } - } + println!("cargo:rerun-if-changed={}", include.join(h).display()); + } + for f in self + .mbedtls_src + .join("library") + .read_dir() + .expect("read_dir failed") + { + println!( + "cargo:rerun-if-changed={}", + f.expect("DirEntry failed").path().display() + ); + } + } } fn main() { - let out_dir=PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR environment not set?")); - let src=PathBuf::from(env::var("RUST_MBEDTLS_SYS_SOURCE").unwrap_or("vendor".to_owned())); - let cfg=BuildConfig { - config_h: out_dir.join("config.h"), - out_dir: out_dir, - mbedtls_src: src, - }; + let out_dir = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR environment not set?")); + let src = PathBuf::from(env::var("RUST_MBEDTLS_SYS_SOURCE").unwrap_or("vendor".to_owned())); + let cfg = BuildConfig { + config_h: out_dir.join("config.h"), + out_dir: out_dir, + mbedtls_src: src, + }; - cfg.create_config_h(); - cfg.print_rerun_files(); - cfg.cmake(); - cfg.bindgen(); + cfg.create_config_h(); + cfg.print_rerun_files(); + cfg.cmake(); + cfg.bindgen(); } diff --git a/mbedtls-sys/build/cmake.rs b/mbedtls-sys/build/cmake.rs index 34cb6455b..9118d69e6 100644 --- a/mbedtls-sys/build/cmake.rs +++ b/mbedtls-sys/build/cmake.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use cmake; @@ -11,23 +11,31 @@ use cmake; use have_feature; impl super::BuildConfig { - pub fn cmake(&self) { - let mut cmk=cmake::Config::new(&self.mbedtls_src); - cmk - .cflag(format!(r#"-DMBEDTLS_CONFIG_FILE="<{}>""#,self.config_h.to_str().expect("config.h UTF-8 error"))) - .define("ENABLE_PROGRAMS","OFF") - .define("ENABLE_TESTING","OFF") - .build_target("lib"); - if !have_feature("std") || ::std::env::var("TARGET").map(|s|s=="x86_64-unknown-none-gnu")==Ok(true) { - println!("cargo:rustc-link-lib=gcc"); - cmk.cflag("-fno-builtin").cflag("-D_FORTIFY_SOURCE=0").cflag("-fno-stack-protector"); - } - let mut dst=cmk.build(); - dst.push("build"); - dst.push("library"); - println!("cargo:rustc-link-search=native={}",dst.to_str().expect("link-search UTF-8 error")); + pub fn cmake(&self) { + let mut cmk = cmake::Config::new(&self.mbedtls_src); + cmk.cflag(format!( + r#"-DMBEDTLS_CONFIG_FILE="<{}>""#, + self.config_h.to_str().expect("config.h UTF-8 error") + )).define("ENABLE_PROGRAMS", "OFF") + .define("ENABLE_TESTING", "OFF") + .build_target("lib"); + if !have_feature("std") + || ::std::env::var("TARGET").map(|s| s == "x86_64-unknown-none-gnu") == Ok(true) + { + println!("cargo:rustc-link-lib=gcc"); + cmk.cflag("-fno-builtin") + .cflag("-D_FORTIFY_SOURCE=0") + .cflag("-fno-stack-protector"); + } + let mut dst = cmk.build(); + dst.push("build"); + dst.push("library"); + println!( + "cargo:rustc-link-search=native={}", + dst.to_str().expect("link-search UTF-8 error") + ); println!("cargo:rustc-link-lib=mbedtls"); - println!("cargo:rustc-link-lib=mbedx509"); + println!("cargo:rustc-link-lib=mbedx509"); println!("cargo:rustc-link-lib=mbedcrypto"); - } + } } diff --git a/mbedtls-sys/build/config.rs b/mbedtls-sys/build/config.rs index 5c7cd5838..963a9a3be 100644 --- a/mbedtls-sys/build/config.rs +++ b/mbedtls-sys/build/config.rs @@ -1,33 +1,33 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ -#[derive(Copy,Clone,PartialEq,Eq)] +#[derive(Copy, Clone, PartialEq, Eq)] pub enum Macro { - Undefined, - Defined, - #[allow(dead_code)] - DefinedAs(&'static str), + Undefined, + Defined, + #[allow(dead_code)] + DefinedAs(&'static str), } use self::Macro::*; impl Macro { - pub fn define(self, name: &'static str) -> String { - match self { - Undefined => String::new(), - Defined => format!("#define {}\n",name), - DefinedAs(v) => format!("#define {} {}\n",name,v), - } - } + pub fn define(self, name: &'static str) -> String { + match self { + Undefined => String::new(), + Defined => format!("#define {}\n", name), + DefinedAs(v) => format!("#define {} {}\n", name, v), + } + } } -pub type CDefine=(&'static str,Macro); +pub type CDefine = (&'static str, Macro); -pub const PREFIX: &'static str=r#" +pub const PREFIX: &'static str = r#" #ifndef MBEDTLS_CONFIG_H #define MBEDTLS_CONFIG_H @@ -36,309 +36,311 @@ pub const PREFIX: &'static str=r#" #endif "#; -pub const DEFAULT_DEFINES: &'static [CDefine]=&[ - ("MBEDTLS_HAVE_ASM", Defined), - ("MBEDTLS_NO_64BIT_MULTIPLICATION", Undefined), - ("MBEDTLS_NO_UDBL_DIVISION", Undefined), - ("MBEDTLS_HAVE_SSE2", Undefined), - ("MBEDTLS_HAVE_TIME", Undefined), - ("MBEDTLS_HAVE_TIME_DATE", Undefined), - ("MBEDTLS_PLATFORM_MEMORY", Undefined), - ("MBEDTLS_PLATFORM_NO_STD_FUNCTIONS", Undefined), - ("MBEDTLS_PLATFORM_EXIT_ALT", Undefined), - ("MBEDTLS_PLATFORM_FPRINTF_ALT", Undefined), - ("MBEDTLS_PLATFORM_PRINTF_ALT", Undefined), - ("MBEDTLS_PLATFORM_SNPRINTF_ALT", Undefined), - ("MBEDTLS_PLATFORM_NV_SEED_ALT", Undefined), - ("MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT", Undefined), - ("MBEDTLS_DEPRECATED_WARNING", Undefined), - ("MBEDTLS_DEPRECATED_REMOVED", Undefined), - ("MBEDTLS_TIMING_ALT", Undefined), - ("MBEDTLS_AES_ALT", Undefined), - ("MBEDTLS_ARC4_ALT", Undefined), - ("MBEDTLS_ARIA_ALT", Undefined), - ("MBEDTLS_BLOWFISH_ALT", Undefined), - ("MBEDTLS_CAMELLIA_ALT", Undefined), - ("MBEDTLS_CCM_ALT", Undefined), - ("MBEDTLS_CHACHA20_ALT", Undefined), - ("MBEDTLS_CHACHAPOLY_ALT", Undefined), - ("MBEDTLS_CMAC_ALT", Undefined), - ("MBEDTLS_DES_ALT", Undefined), - ("MBEDTLS_DHM_ALT", Undefined), - ("MBEDTLS_ECJPAKE_ALT", Undefined), - ("MBEDTLS_GCM_ALT", Undefined), - ("MBEDTLS_NIST_KW_ALT", Undefined), - ("MBEDTLS_MD2_ALT", Undefined), - ("MBEDTLS_MD4_ALT", Undefined), - ("MBEDTLS_MD5_ALT", Undefined), - ("MBEDTLS_POLY1305_ALT", Undefined), - ("MBEDTLS_RIPEMD160_ALT", Undefined), - ("MBEDTLS_RSA_ALT", Undefined), - ("MBEDTLS_SHA1_ALT", Undefined), - ("MBEDTLS_SHA256_ALT", Undefined), - ("MBEDTLS_SHA512_ALT", Undefined), - ("MBEDTLS_XTEA_ALT", Undefined), - ("MBEDTLS_ECP_ALT", Undefined), - ("MBEDTLS_MD2_PROCESS_ALT", Undefined), - ("MBEDTLS_MD4_PROCESS_ALT", Undefined), - ("MBEDTLS_MD5_PROCESS_ALT", Undefined), - ("MBEDTLS_RIPEMD160_PROCESS_ALT", Undefined), - ("MBEDTLS_SHA1_PROCESS_ALT", Undefined), - ("MBEDTLS_SHA256_PROCESS_ALT", Undefined), - ("MBEDTLS_SHA512_PROCESS_ALT", Undefined), - ("MBEDTLS_DES_SETKEY_ALT", Undefined), - ("MBEDTLS_DES_CRYPT_ECB_ALT", Undefined), - ("MBEDTLS_DES3_CRYPT_ECB_ALT", Undefined), - ("MBEDTLS_AES_SETKEY_ENC_ALT", Undefined), - ("MBEDTLS_AES_SETKEY_DEC_ALT", Undefined), - ("MBEDTLS_AES_ENCRYPT_ALT", Undefined), - ("MBEDTLS_AES_DECRYPT_ALT", Undefined), - ("MBEDTLS_ECDH_GEN_PUBLIC_ALT", Undefined), - ("MBEDTLS_ECDH_COMPUTE_SHARED_ALT", Undefined), - ("MBEDTLS_ECDSA_VERIFY_ALT", Undefined), - ("MBEDTLS_ECDSA_SIGN_ALT", Undefined), - ("MBEDTLS_ECDSA_GENKEY_ALT", Undefined), - ("MBEDTLS_ECP_INTERNAL_ALT", Undefined), - ("MBEDTLS_ECP_RANDOMIZE_JAC_ALT", Undefined), - ("MBEDTLS_ECP_ADD_MIXED_ALT", Undefined), - ("MBEDTLS_ECP_DOUBLE_JAC_ALT", Undefined), - ("MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT", Undefined), - ("MBEDTLS_ECP_NORMALIZE_JAC_ALT", Undefined), - ("MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT", Undefined), - ("MBEDTLS_ECP_RANDOMIZE_MXZ_ALT", Undefined), - ("MBEDTLS_ECP_NORMALIZE_MXZ_ALT", Undefined), - ("MBEDTLS_TEST_NULL_ENTROPY", Undefined), - ("MBEDTLS_ENTROPY_HARDWARE_ALT", Undefined), - ("MBEDTLS_AES_ROM_TABLES", Undefined), - ("MBEDTLS_AES_FEWER_TABLES", Undefined), - ("MBEDTLS_CAMELLIA_SMALL_MEMORY", Undefined), - ("MBEDTLS_CIPHER_MODE_CBC", Defined), - ("MBEDTLS_CIPHER_MODE_CFB", Defined), - ("MBEDTLS_CIPHER_MODE_CTR", Defined), - ("MBEDTLS_CIPHER_MODE_OFB", Defined), - ("MBEDTLS_CIPHER_MODE_XTS", Defined), - ("MBEDTLS_CIPHER_NULL_CIPHER", Undefined), - ("MBEDTLS_CIPHER_PADDING_PKCS7", Defined), - ("MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS", Defined), - ("MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN", Defined), - ("MBEDTLS_CIPHER_PADDING_ZEROS", Defined), - ("MBEDTLS_ENABLE_WEAK_CIPHERSUITES", Undefined), - ("MBEDTLS_REMOVE_ARC4_CIPHERSUITES", Defined), - ("MBEDTLS_ECP_DP_SECP192R1_ENABLED", Defined), - ("MBEDTLS_ECP_DP_SECP224R1_ENABLED", Defined), - ("MBEDTLS_ECP_DP_SECP256R1_ENABLED", Defined), - ("MBEDTLS_ECP_DP_SECP384R1_ENABLED", Defined), - ("MBEDTLS_ECP_DP_SECP521R1_ENABLED", Defined), - ("MBEDTLS_ECP_DP_SECP192K1_ENABLED", Defined), - ("MBEDTLS_ECP_DP_SECP224K1_ENABLED", Defined), - ("MBEDTLS_ECP_DP_SECP256K1_ENABLED", Defined), - ("MBEDTLS_ECP_DP_BP256R1_ENABLED", Defined), - ("MBEDTLS_ECP_DP_BP384R1_ENABLED", Defined), - ("MBEDTLS_ECP_DP_BP512R1_ENABLED", Defined), - ("MBEDTLS_ECP_DP_CURVE25519_ENABLED", Defined), - ("MBEDTLS_ECP_DP_CURVE448_ENABLED", Defined), - ("MBEDTLS_ECP_NIST_OPTIM", Defined), - ("MBEDTLS_ECDSA_DETERMINISTIC", Defined), - ("MBEDTLS_KEY_EXCHANGE_PSK_ENABLED", Defined), - ("MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED", Defined), - ("MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED", Defined), - ("MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED", Defined), - ("MBEDTLS_KEY_EXCHANGE_RSA_ENABLED", Defined), - ("MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED", Defined), - ("MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED", Defined), - ("MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED", Defined), - ("MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED", Defined), - ("MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED", Defined), - ("MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED", Undefined), - ("MBEDTLS_PK_PARSE_EC_EXTENDED", Defined), - ("MBEDTLS_ERROR_STRERROR_DUMMY", Defined), - ("MBEDTLS_GENPRIME", Defined), - ("MBEDTLS_FS_IO", Undefined), - ("MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES", Undefined), - ("MBEDTLS_NO_PLATFORM_ENTROPY", Defined), - ("MBEDTLS_ENTROPY_FORCE_SHA256", Undefined), - ("MBEDTLS_MEMORY_DEBUG", Undefined), - ("MBEDTLS_MEMORY_BACKTRACE", Undefined), - ("MBEDTLS_PK_RSA_ALT_SUPPORT", Defined), - ("MBEDTLS_PKCS1_V15", Defined), - ("MBEDTLS_PKCS1_V21", Defined), - ("MBEDTLS_RSA_NO_CRT", Undefined), - ("MBEDTLS_SELF_TEST", Defined), - ("MBEDTLS_SHA256_SMALLER", Undefined), - ("MBEDTLS_SSL_ALL_ALERT_MESSAGES", Defined), - ("MBEDTLS_SSL_ASYNC_PRIVATE", Undefined), - ("MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT", Undefined), - ("MBEDTLS_SSL_DEBUG_ALL", Undefined), - ("MBEDTLS_SSL_ENCRYPT_THEN_MAC", Defined), - ("MBEDTLS_SSL_EXTENDED_MASTER_SECRET", Defined), - ("MBEDTLS_SSL_FALLBACK_SCSV", Defined), - ("MBEDTLS_SSL_HW_RECORD_ACCEL", Undefined), - ("MBEDTLS_SSL_CBC_RECORD_SPLITTING", Defined), - ("MBEDTLS_SSL_RENEGOTIATION", Defined), - ("MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO", Undefined), - ("MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE", Undefined), - ("MBEDTLS_SSL_MAX_FRAGMENT_LENGTH", Defined), - ("MBEDTLS_SSL_PROTO_SSL3", Defined), - ("MBEDTLS_SSL_PROTO_TLS1", Defined), - ("MBEDTLS_SSL_PROTO_TLS1_1", Defined), - ("MBEDTLS_SSL_PROTO_TLS1_2", Defined), - ("MBEDTLS_SSL_PROTO_DTLS", Defined), - ("MBEDTLS_SSL_ALPN", Defined), - ("MBEDTLS_SSL_DTLS_ANTI_REPLAY", Defined), - ("MBEDTLS_SSL_DTLS_HELLO_VERIFY", Defined), - ("MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", Defined), - ("MBEDTLS_SSL_DTLS_BADMAC_LIMIT", Defined), - ("MBEDTLS_SSL_SESSION_TICKETS", Defined), - ("MBEDTLS_SSL_EXPORT_KEYS", Defined), - ("MBEDTLS_SSL_SERVER_NAME_INDICATION", Defined), - ("MBEDTLS_SSL_TRUNCATED_HMAC", Defined), - ("MBEDTLS_THREADING_ALT", Undefined), - ("MBEDTLS_THREADING_PTHREAD", Undefined), - ("MBEDTLS_VERSION_FEATURES", Defined), - ("MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3", Undefined), - ("MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION", Undefined), - ("MBEDTLS_X509_CHECK_KEY_USAGE", Defined), - ("MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE", Defined), - ("MBEDTLS_X509_RSASSA_PSS_SUPPORT", Defined), - ("MBEDTLS_ZLIB_SUPPORT", Undefined), - ("MBEDTLS_AES_C", Defined), - ("MBEDTLS_ARC4_C", Defined), - ("MBEDTLS_ASN1_PARSE_C", Defined), - ("MBEDTLS_ASN1_WRITE_C", Defined), - ("MBEDTLS_BASE64_C", Defined), - ("MBEDTLS_BIGNUM_C", Defined), - ("MBEDTLS_BLOWFISH_C", Defined), - ("MBEDTLS_CAMELLIA_C", Defined), - ("MBEDTLS_ARIA_C", Undefined), - ("MBEDTLS_CCM_C", Defined), - ("MBEDTLS_CERTS_C", Defined), - ("MBEDTLS_CHACHA20_C", Defined), - ("MBEDTLS_CHACHAPOLY_C", Defined), - ("MBEDTLS_CIPHER_C", Defined), - ("MBEDTLS_CTR_DRBG_C", Defined), - ("MBEDTLS_CMAC_C", Undefined), - ("MBEDTLS_DEBUG_C", Undefined), - ("MBEDTLS_DES_C", Defined), - ("MBEDTLS_DHM_C", Defined), - ("MBEDTLS_ECDH_C", Defined), - ("MBEDTLS_ECDSA_C", Defined), - ("MBEDTLS_ECJPAKE_C", Defined), - ("MBEDTLS_ECP_C", Defined), - ("MBEDTLS_ENTROPY_C", Undefined), - ("MBEDTLS_ERROR_C", Defined), - ("MBEDTLS_GCM_C", Defined), - ("MBEDTLS_HAVEGE_C", Undefined), - ("MBEDTLS_HKDF_C", Defined), - ("MBEDTLS_HMAC_DRBG_C", Defined), - ("MBEDTLS_NIST_KW_C", Undefined), - ("MBEDTLS_MD_C", Defined), - ("MBEDTLS_MD2_C", Defined), - ("MBEDTLS_MD4_C", Defined), - ("MBEDTLS_MD5_C", Defined), - ("MBEDTLS_MEMORY_BUFFER_ALLOC_C", Undefined), - ("MBEDTLS_NET_C", Undefined), - ("MBEDTLS_OID_C", Defined), - ("MBEDTLS_PADLOCK_C", Defined), - ("MBEDTLS_PEM_PARSE_C", Defined), - ("MBEDTLS_PEM_WRITE_C", Defined), - ("MBEDTLS_PK_C", Defined), - ("MBEDTLS_PK_PARSE_C", Defined), - ("MBEDTLS_PK_WRITE_C", Defined), - ("MBEDTLS_PKCS5_C", Defined), - ("MBEDTLS_PKCS11_C", Undefined), - ("MBEDTLS_PKCS12_C", Defined), - ("MBEDTLS_PLATFORM_C", Undefined), - ("MBEDTLS_POLY1305_C", Defined), - ("MBEDTLS_RIPEMD160_C", Defined), - ("MBEDTLS_RSA_C", Defined), - ("MBEDTLS_SHA1_C", Defined), - ("MBEDTLS_SHA256_C", Defined), - ("MBEDTLS_SHA512_C", Defined), - ("MBEDTLS_SSL_CACHE_C", Defined), - ("MBEDTLS_SSL_COOKIE_C", Defined), - ("MBEDTLS_SSL_TICKET_C", Defined), - ("MBEDTLS_SSL_CLI_C", Defined), - ("MBEDTLS_SSL_SRV_C", Defined), - ("MBEDTLS_SSL_TLS_C", Defined), - ("MBEDTLS_THREADING_C", Undefined), - ("MBEDTLS_TIMING_C", Undefined), - ("MBEDTLS_VERSION_C", Defined), - ("MBEDTLS_X509_USE_C", Defined), - ("MBEDTLS_X509_CRT_PARSE_C", Defined), - ("MBEDTLS_X509_CRL_PARSE_C", Defined), - ("MBEDTLS_X509_CSR_PARSE_C", Defined), - ("MBEDTLS_X509_CREATE_C", Defined), - ("MBEDTLS_X509_CRT_WRITE_C", Defined), - ("MBEDTLS_X509_CSR_WRITE_C", Defined), - ("MBEDTLS_XTEA_C", Defined), - ("MBEDTLS_MPI_WINDOW_SIZE", Undefined), // default: 6 - ("MBEDTLS_MPI_MAX_SIZE", Undefined), // default: 1024 - ("MBEDTLS_CTR_DRBG_ENTROPY_LEN", Undefined), // default: 48 - ("MBEDTLS_CTR_DRBG_RESEED_INTERVAL", Undefined), // default: 10000 - ("MBEDTLS_CTR_DRBG_MAX_INPUT", Undefined), // default: 256 - ("MBEDTLS_CTR_DRBG_MAX_REQUEST", Undefined), // default: 1024 - ("MBEDTLS_CTR_DRBG_MAX_SEED_INPUT", Undefined), // default: 384 - ("MBEDTLS_HMAC_DRBG_RESEED_INTERVAL", Undefined), // default: 10000 - ("MBEDTLS_HMAC_DRBG_MAX_INPUT", Undefined), // default: 256 - ("MBEDTLS_HMAC_DRBG_MAX_REQUEST", Undefined), // default: 1024 - ("MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT", Undefined), // default: 384 - ("MBEDTLS_ECP_MAX_BITS", Undefined), // default: 521 - ("MBEDTLS_ECP_WINDOW_SIZE", Undefined), // default: 6 - ("MBEDTLS_ECP_FIXED_POINT_OPTIM", Undefined), // default: 1 - ("MBEDTLS_ENTROPY_MAX_SOURCES", Undefined), // default: 20 - ("MBEDTLS_ENTROPY_MAX_GATHER", Undefined), // default: 128 - ("MBEDTLS_ENTROPY_MIN_HARDWARE", Undefined), // default: 32 - ("MBEDTLS_MEMORY_ALIGN_MULTIPLE", Undefined), // default: 4 - ("MBEDTLS_PLATFORM_STD_MEM_HDR", Undefined), // default: - ("MBEDTLS_PLATFORM_STD_CALLOC", Undefined), // default: calloc - ("MBEDTLS_PLATFORM_STD_FREE", Undefined), // default: free - ("MBEDTLS_PLATFORM_STD_EXIT", Undefined), // default: exit - ("MBEDTLS_PLATFORM_STD_FPRINTF", Undefined), // default: fprintf - ("MBEDTLS_PLATFORM_STD_PRINTF", Undefined), // default: printf - ("MBEDTLS_PLATFORM_STD_SNPRINTF", Undefined), // default: snprintf - ("MBEDTLS_PLATFORM_CALLOC_MACRO", Undefined), // default: calloc - ("MBEDTLS_PLATFORM_FREE_MACRO", Undefined), // default: free - ("MBEDTLS_PLATFORM_EXIT_MACRO", Undefined), // default: exit - ("MBEDTLS_PLATFORM_FPRINTF_MACRO", Undefined), // default: fprintf - ("MBEDTLS_PLATFORM_PRINTF_MACRO", Undefined), // default: printf - ("MBEDTLS_PLATFORM_SNPRINTF_MACRO", Undefined), // default: snprintf - ("MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT", Undefined), // default: 86400 - ("MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES", Undefined), // default: 50 - ("MBEDTLS_SSL_MAX_CONTENT_LEN", Undefined), // default: 16384 - ("MBEDTLS_SSL_IN_CONTENT_LEN", Undefined), // default: 16384 - ("MBEDTLS_SSL_OUT_CONTENT_LEN", Undefined), // default: 16384 - ("MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME", Undefined), // default: 86400 - ("MBEDTLS_PSK_MAX_LEN", Undefined), // default: 32 - ("MBEDTLS_SSL_COOKIE_TIMEOUT", Undefined), // default: 60 - ("MBEDTLS_SSL_CIPHERSUITES", Undefined), // no default - ("MBEDTLS_X509_MAX_INTERMEDIATE_CA", Undefined), // default: 8 - ("MBEDTLS_X509_MAX_FILE_PATH_LEN", Undefined), // default: 512 - ("MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES", Undefined), - ("MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE", Defined), - ("MBEDTLS_PLATFORM_ZEROIZE_ALT", Undefined), +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const DEFAULT_DEFINES: &'static [CDefine] = &[ + ("MBEDTLS_HAVE_ASM", Defined), + ("MBEDTLS_NO_64BIT_MULTIPLICATION", Undefined), + ("MBEDTLS_NO_UDBL_DIVISION", Undefined), + ("MBEDTLS_HAVE_SSE2", Undefined), + ("MBEDTLS_HAVE_TIME", Undefined), + ("MBEDTLS_HAVE_TIME_DATE", Undefined), + ("MBEDTLS_PLATFORM_MEMORY", Undefined), + ("MBEDTLS_PLATFORM_NO_STD_FUNCTIONS", Undefined), + ("MBEDTLS_PLATFORM_EXIT_ALT", Undefined), + ("MBEDTLS_PLATFORM_FPRINTF_ALT", Undefined), + ("MBEDTLS_PLATFORM_PRINTF_ALT", Undefined), + ("MBEDTLS_PLATFORM_SNPRINTF_ALT", Undefined), + ("MBEDTLS_PLATFORM_NV_SEED_ALT", Undefined), + ("MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT", Undefined), + ("MBEDTLS_DEPRECATED_WARNING", Undefined), + ("MBEDTLS_DEPRECATED_REMOVED", Undefined), + ("MBEDTLS_TIMING_ALT", Undefined), + ("MBEDTLS_AES_ALT", Undefined), + ("MBEDTLS_ARC4_ALT", Undefined), + ("MBEDTLS_ARIA_ALT", Undefined), + ("MBEDTLS_BLOWFISH_ALT", Undefined), + ("MBEDTLS_CAMELLIA_ALT", Undefined), + ("MBEDTLS_CCM_ALT", Undefined), + ("MBEDTLS_CHACHA20_ALT", Undefined), + ("MBEDTLS_CHACHAPOLY_ALT", Undefined), + ("MBEDTLS_CMAC_ALT", Undefined), + ("MBEDTLS_DES_ALT", Undefined), + ("MBEDTLS_DHM_ALT", Undefined), + ("MBEDTLS_ECJPAKE_ALT", Undefined), + ("MBEDTLS_GCM_ALT", Undefined), + ("MBEDTLS_NIST_KW_ALT", Undefined), + ("MBEDTLS_MD2_ALT", Undefined), + ("MBEDTLS_MD4_ALT", Undefined), + ("MBEDTLS_MD5_ALT", Undefined), + ("MBEDTLS_POLY1305_ALT", Undefined), + ("MBEDTLS_RIPEMD160_ALT", Undefined), + ("MBEDTLS_RSA_ALT", Undefined), + ("MBEDTLS_SHA1_ALT", Undefined), + ("MBEDTLS_SHA256_ALT", Undefined), + ("MBEDTLS_SHA512_ALT", Undefined), + ("MBEDTLS_XTEA_ALT", Undefined), + ("MBEDTLS_ECP_ALT", Undefined), + ("MBEDTLS_MD2_PROCESS_ALT", Undefined), + ("MBEDTLS_MD4_PROCESS_ALT", Undefined), + ("MBEDTLS_MD5_PROCESS_ALT", Undefined), + ("MBEDTLS_RIPEMD160_PROCESS_ALT", Undefined), + ("MBEDTLS_SHA1_PROCESS_ALT", Undefined), + ("MBEDTLS_SHA256_PROCESS_ALT", Undefined), + ("MBEDTLS_SHA512_PROCESS_ALT", Undefined), + ("MBEDTLS_DES_SETKEY_ALT", Undefined), + ("MBEDTLS_DES_CRYPT_ECB_ALT", Undefined), + ("MBEDTLS_DES3_CRYPT_ECB_ALT", Undefined), + ("MBEDTLS_AES_SETKEY_ENC_ALT", Undefined), + ("MBEDTLS_AES_SETKEY_DEC_ALT", Undefined), + ("MBEDTLS_AES_ENCRYPT_ALT", Undefined), + ("MBEDTLS_AES_DECRYPT_ALT", Undefined), + ("MBEDTLS_ECDH_GEN_PUBLIC_ALT", Undefined), + ("MBEDTLS_ECDH_COMPUTE_SHARED_ALT", Undefined), + ("MBEDTLS_ECDSA_VERIFY_ALT", Undefined), + ("MBEDTLS_ECDSA_SIGN_ALT", Undefined), + ("MBEDTLS_ECDSA_GENKEY_ALT", Undefined), + ("MBEDTLS_ECP_INTERNAL_ALT", Undefined), + ("MBEDTLS_ECP_RANDOMIZE_JAC_ALT", Undefined), + ("MBEDTLS_ECP_ADD_MIXED_ALT", Undefined), + ("MBEDTLS_ECP_DOUBLE_JAC_ALT", Undefined), + ("MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT", Undefined), + ("MBEDTLS_ECP_NORMALIZE_JAC_ALT", Undefined), + ("MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT", Undefined), + ("MBEDTLS_ECP_RANDOMIZE_MXZ_ALT", Undefined), + ("MBEDTLS_ECP_NORMALIZE_MXZ_ALT", Undefined), + ("MBEDTLS_TEST_NULL_ENTROPY", Undefined), + ("MBEDTLS_ENTROPY_HARDWARE_ALT", Undefined), + ("MBEDTLS_AES_ROM_TABLES", Undefined), + ("MBEDTLS_AES_FEWER_TABLES", Undefined), + ("MBEDTLS_CAMELLIA_SMALL_MEMORY", Undefined), + ("MBEDTLS_CIPHER_MODE_CBC", Defined), + ("MBEDTLS_CIPHER_MODE_CFB", Defined), + ("MBEDTLS_CIPHER_MODE_CTR", Defined), + ("MBEDTLS_CIPHER_MODE_OFB", Defined), + ("MBEDTLS_CIPHER_MODE_XTS", Defined), + ("MBEDTLS_CIPHER_NULL_CIPHER", Undefined), + ("MBEDTLS_CIPHER_PADDING_PKCS7", Defined), + ("MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS", Defined), + ("MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN", Defined), + ("MBEDTLS_CIPHER_PADDING_ZEROS", Defined), + ("MBEDTLS_ENABLE_WEAK_CIPHERSUITES", Undefined), + ("MBEDTLS_REMOVE_ARC4_CIPHERSUITES", Defined), + ("MBEDTLS_ECP_DP_SECP192R1_ENABLED", Defined), + ("MBEDTLS_ECP_DP_SECP224R1_ENABLED", Defined), + ("MBEDTLS_ECP_DP_SECP256R1_ENABLED", Defined), + ("MBEDTLS_ECP_DP_SECP384R1_ENABLED", Defined), + ("MBEDTLS_ECP_DP_SECP521R1_ENABLED", Defined), + ("MBEDTLS_ECP_DP_SECP192K1_ENABLED", Defined), + ("MBEDTLS_ECP_DP_SECP224K1_ENABLED", Defined), + ("MBEDTLS_ECP_DP_SECP256K1_ENABLED", Defined), + ("MBEDTLS_ECP_DP_BP256R1_ENABLED", Defined), + ("MBEDTLS_ECP_DP_BP384R1_ENABLED", Defined), + ("MBEDTLS_ECP_DP_BP512R1_ENABLED", Defined), + ("MBEDTLS_ECP_DP_CURVE25519_ENABLED", Defined), + ("MBEDTLS_ECP_DP_CURVE448_ENABLED", Defined), + ("MBEDTLS_ECP_NIST_OPTIM", Defined), + ("MBEDTLS_ECDSA_DETERMINISTIC", Defined), + ("MBEDTLS_KEY_EXCHANGE_PSK_ENABLED", Defined), + ("MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED", Defined), + ("MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED", Defined), + ("MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED", Defined), + ("MBEDTLS_KEY_EXCHANGE_RSA_ENABLED", Defined), + ("MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED", Defined), + ("MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED", Defined), + ("MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED", Defined), + ("MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED", Defined), + ("MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED", Defined), + ("MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED", Undefined), + ("MBEDTLS_PK_PARSE_EC_EXTENDED", Defined), + ("MBEDTLS_ERROR_STRERROR_DUMMY", Defined), + ("MBEDTLS_GENPRIME", Defined), + ("MBEDTLS_FS_IO", Undefined), + ("MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES", Undefined), + ("MBEDTLS_NO_PLATFORM_ENTROPY", Defined), + ("MBEDTLS_ENTROPY_FORCE_SHA256", Undefined), + ("MBEDTLS_MEMORY_DEBUG", Undefined), + ("MBEDTLS_MEMORY_BACKTRACE", Undefined), + ("MBEDTLS_PK_RSA_ALT_SUPPORT", Defined), + ("MBEDTLS_PKCS1_V15", Defined), + ("MBEDTLS_PKCS1_V21", Defined), + ("MBEDTLS_RSA_NO_CRT", Undefined), + ("MBEDTLS_SELF_TEST", Defined), + ("MBEDTLS_SHA256_SMALLER", Undefined), + ("MBEDTLS_SSL_ALL_ALERT_MESSAGES", Defined), + ("MBEDTLS_SSL_ASYNC_PRIVATE", Undefined), + ("MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT", Undefined), + ("MBEDTLS_SSL_DEBUG_ALL", Undefined), + ("MBEDTLS_SSL_ENCRYPT_THEN_MAC", Defined), + ("MBEDTLS_SSL_EXTENDED_MASTER_SECRET", Defined), + ("MBEDTLS_SSL_FALLBACK_SCSV", Defined), + ("MBEDTLS_SSL_HW_RECORD_ACCEL", Undefined), + ("MBEDTLS_SSL_CBC_RECORD_SPLITTING", Defined), + ("MBEDTLS_SSL_RENEGOTIATION", Defined), + ("MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO", Undefined), + ("MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE", Undefined), + ("MBEDTLS_SSL_MAX_FRAGMENT_LENGTH", Defined), + ("MBEDTLS_SSL_PROTO_SSL3", Defined), + ("MBEDTLS_SSL_PROTO_TLS1", Defined), + ("MBEDTLS_SSL_PROTO_TLS1_1", Defined), + ("MBEDTLS_SSL_PROTO_TLS1_2", Defined), + ("MBEDTLS_SSL_PROTO_DTLS", Defined), + ("MBEDTLS_SSL_ALPN", Defined), + ("MBEDTLS_SSL_DTLS_ANTI_REPLAY", Defined), + ("MBEDTLS_SSL_DTLS_HELLO_VERIFY", Defined), + ("MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", Defined), + ("MBEDTLS_SSL_DTLS_BADMAC_LIMIT", Defined), + ("MBEDTLS_SSL_SESSION_TICKETS", Defined), + ("MBEDTLS_SSL_EXPORT_KEYS", Defined), + ("MBEDTLS_SSL_SERVER_NAME_INDICATION", Defined), + ("MBEDTLS_SSL_TRUNCATED_HMAC", Defined), + ("MBEDTLS_THREADING_ALT", Undefined), + ("MBEDTLS_THREADING_PTHREAD", Undefined), + ("MBEDTLS_VERSION_FEATURES", Defined), + ("MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3", Undefined), + ("MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION", Undefined), + ("MBEDTLS_X509_CHECK_KEY_USAGE", Defined), + ("MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE", Defined), + ("MBEDTLS_X509_RSASSA_PSS_SUPPORT", Defined), + ("MBEDTLS_ZLIB_SUPPORT", Undefined), + ("MBEDTLS_AES_C", Defined), + ("MBEDTLS_ARC4_C", Defined), + ("MBEDTLS_ASN1_PARSE_C", Defined), + ("MBEDTLS_ASN1_WRITE_C", Defined), + ("MBEDTLS_BASE64_C", Defined), + ("MBEDTLS_BIGNUM_C", Defined), + ("MBEDTLS_BLOWFISH_C", Defined), + ("MBEDTLS_CAMELLIA_C", Defined), + ("MBEDTLS_ARIA_C", Undefined), + ("MBEDTLS_CCM_C", Defined), + ("MBEDTLS_CERTS_C", Defined), + ("MBEDTLS_CHACHA20_C", Defined), + ("MBEDTLS_CHACHAPOLY_C", Defined), + ("MBEDTLS_CIPHER_C", Defined), + ("MBEDTLS_CTR_DRBG_C", Defined), + ("MBEDTLS_CMAC_C", Undefined), + ("MBEDTLS_DEBUG_C", Undefined), + ("MBEDTLS_DES_C", Defined), + ("MBEDTLS_DHM_C", Defined), + ("MBEDTLS_ECDH_C", Defined), + ("MBEDTLS_ECDSA_C", Defined), + ("MBEDTLS_ECJPAKE_C", Defined), + ("MBEDTLS_ECP_C", Defined), + ("MBEDTLS_ENTROPY_C", Undefined), + ("MBEDTLS_ERROR_C", Defined), + ("MBEDTLS_GCM_C", Defined), + ("MBEDTLS_HAVEGE_C", Undefined), + ("MBEDTLS_HKDF_C", Defined), + ("MBEDTLS_HMAC_DRBG_C", Defined), + ("MBEDTLS_NIST_KW_C", Undefined), + ("MBEDTLS_MD_C", Defined), + ("MBEDTLS_MD2_C", Defined), + ("MBEDTLS_MD4_C", Defined), + ("MBEDTLS_MD5_C", Defined), + ("MBEDTLS_MEMORY_BUFFER_ALLOC_C", Undefined), + ("MBEDTLS_NET_C", Undefined), + ("MBEDTLS_OID_C", Defined), + ("MBEDTLS_PADLOCK_C", Defined), + ("MBEDTLS_PEM_PARSE_C", Defined), + ("MBEDTLS_PEM_WRITE_C", Defined), + ("MBEDTLS_PK_C", Defined), + ("MBEDTLS_PK_PARSE_C", Defined), + ("MBEDTLS_PK_WRITE_C", Defined), + ("MBEDTLS_PKCS5_C", Defined), + ("MBEDTLS_PKCS11_C", Undefined), + ("MBEDTLS_PKCS12_C", Defined), + ("MBEDTLS_PLATFORM_C", Undefined), + ("MBEDTLS_POLY1305_C", Defined), + ("MBEDTLS_RIPEMD160_C", Defined), + ("MBEDTLS_RSA_C", Defined), + ("MBEDTLS_SHA1_C", Defined), + ("MBEDTLS_SHA256_C", Defined), + ("MBEDTLS_SHA512_C", Defined), + ("MBEDTLS_SSL_CACHE_C", Defined), + ("MBEDTLS_SSL_COOKIE_C", Defined), + ("MBEDTLS_SSL_TICKET_C", Defined), + ("MBEDTLS_SSL_CLI_C", Defined), + ("MBEDTLS_SSL_SRV_C", Defined), + ("MBEDTLS_SSL_TLS_C", Defined), + ("MBEDTLS_THREADING_C", Undefined), + ("MBEDTLS_TIMING_C", Undefined), + ("MBEDTLS_VERSION_C", Defined), + ("MBEDTLS_X509_USE_C", Defined), + ("MBEDTLS_X509_CRT_PARSE_C", Defined), + ("MBEDTLS_X509_CRL_PARSE_C", Defined), + ("MBEDTLS_X509_CSR_PARSE_C", Defined), + ("MBEDTLS_X509_CREATE_C", Defined), + ("MBEDTLS_X509_CRT_WRITE_C", Defined), + ("MBEDTLS_X509_CSR_WRITE_C", Defined), + ("MBEDTLS_XTEA_C", Defined), + ("MBEDTLS_MPI_WINDOW_SIZE", Undefined), // default: 6 + ("MBEDTLS_MPI_MAX_SIZE", Undefined), // default: 1024 + ("MBEDTLS_CTR_DRBG_ENTROPY_LEN", Undefined), // default: 48 + ("MBEDTLS_CTR_DRBG_RESEED_INTERVAL", Undefined), // default: 10000 + ("MBEDTLS_CTR_DRBG_MAX_INPUT", Undefined), // default: 256 + ("MBEDTLS_CTR_DRBG_MAX_REQUEST", Undefined), // default: 1024 + ("MBEDTLS_CTR_DRBG_MAX_SEED_INPUT", Undefined), // default: 384 + ("MBEDTLS_HMAC_DRBG_RESEED_INTERVAL", Undefined), // default: 10000 + ("MBEDTLS_HMAC_DRBG_MAX_INPUT", Undefined), // default: 256 + ("MBEDTLS_HMAC_DRBG_MAX_REQUEST", Undefined), // default: 1024 + ("MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT", Undefined), // default: 384 + ("MBEDTLS_ECP_MAX_BITS", Undefined), // default: 521 + ("MBEDTLS_ECP_WINDOW_SIZE", Undefined), // default: 6 + ("MBEDTLS_ECP_FIXED_POINT_OPTIM", Undefined), // default: 1 + ("MBEDTLS_ENTROPY_MAX_SOURCES", Undefined), // default: 20 + ("MBEDTLS_ENTROPY_MAX_GATHER", Undefined), // default: 128 + ("MBEDTLS_ENTROPY_MIN_HARDWARE", Undefined), // default: 32 + ("MBEDTLS_MEMORY_ALIGN_MULTIPLE", Undefined), // default: 4 + ("MBEDTLS_PLATFORM_STD_MEM_HDR", Undefined), // default: + ("MBEDTLS_PLATFORM_STD_CALLOC", Undefined), // default: calloc + ("MBEDTLS_PLATFORM_STD_FREE", Undefined), // default: free + ("MBEDTLS_PLATFORM_STD_EXIT", Undefined), // default: exit + ("MBEDTLS_PLATFORM_STD_FPRINTF", Undefined), // default: fprintf + ("MBEDTLS_PLATFORM_STD_PRINTF", Undefined), // default: printf + ("MBEDTLS_PLATFORM_STD_SNPRINTF", Undefined), // default: snprintf + ("MBEDTLS_PLATFORM_CALLOC_MACRO", Undefined), // default: calloc + ("MBEDTLS_PLATFORM_FREE_MACRO", Undefined), // default: free + ("MBEDTLS_PLATFORM_EXIT_MACRO", Undefined), // default: exit + ("MBEDTLS_PLATFORM_FPRINTF_MACRO", Undefined), // default: fprintf + ("MBEDTLS_PLATFORM_PRINTF_MACRO", Undefined), // default: printf + ("MBEDTLS_PLATFORM_SNPRINTF_MACRO", Undefined), // default: snprintf + ("MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT", Undefined), // default: 86400 + ("MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES", Undefined), // default: 50 + ("MBEDTLS_SSL_MAX_CONTENT_LEN", Undefined), // default: 16384 + ("MBEDTLS_SSL_IN_CONTENT_LEN", Undefined), // default: 16384 + ("MBEDTLS_SSL_OUT_CONTENT_LEN", Undefined), // default: 16384 + ("MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME", Undefined), // default: 86400 + ("MBEDTLS_PSK_MAX_LEN", Undefined), // default: 32 + ("MBEDTLS_SSL_COOKIE_TIMEOUT", Undefined), // default: 60 + ("MBEDTLS_SSL_CIPHERSUITES", Undefined), // no default + ("MBEDTLS_X509_MAX_INTERMEDIATE_CA", Undefined), // default: 8 + ("MBEDTLS_X509_MAX_FILE_PATH_LEN", Undefined), // default: 512 + ("MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES", Undefined), + ("MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE", Defined), + ("MBEDTLS_PLATFORM_ZEROIZE_ALT", Undefined), ]; -pub const FEATURE_DEFINES: &'static [(&'static str,CDefine)]=&[ - ("time", ("MBEDTLS_HAVE_TIME", Defined)), - ("time", ("MBEDTLS_HAVE_TIME_DATE", Defined)), - ("time", ("MBEDTLS_TIMING_C", Defined)), - ("havege", ("MBEDTLS_HAVEGE_C", Defined)), - ("threading", ("MBEDTLS_THREADING_C", Defined)), - ("pthread", ("MBEDTLS_THREADING_PTHREAD", Defined)), - ("custom_threading",("MBEDTLS_THREADING_IMPL", Defined)), - ("pkcs11", ("MBEDTLS_PKCS11_C", Defined)), - ("zlib", ("MBEDTLS_ZLIB_SUPPORT", Defined)), - ("std", ("MBEDTLS_NET_C", Defined)), - ("std", ("MBEDTLS_FS_IO", Defined)), - ("std", ("MBEDTLS_NO_PLATFORM_ENTROPY", Undefined)), - ("std", ("MBEDTLS_DEBUG_C", Defined)), - ("std", ("MBEDTLS_ENTROPY_C", Defined)), - ("custom_printf", ("MBEDTLS_PLATFORM_C", Defined)), - ("custom_printf", ("MBEDTLS_PLATFORM_PRINTF_MACRO", DefinedAs("mbedtls_printf"))), - ("aesni", ("MBEDTLS_AESNI_C", Defined)), +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const FEATURE_DEFINES: &'static [(&'static str, CDefine)] = &[ + ("time", ("MBEDTLS_HAVE_TIME", Defined)), + ("time", ("MBEDTLS_HAVE_TIME_DATE", Defined)), + ("time", ("MBEDTLS_TIMING_C", Defined)), + ("havege", ("MBEDTLS_HAVEGE_C", Defined)), + ("threading", ("MBEDTLS_THREADING_C", Defined)), + ("pthread", ("MBEDTLS_THREADING_PTHREAD", Defined)), + ("custom_threading",("MBEDTLS_THREADING_IMPL", Defined)), + ("pkcs11", ("MBEDTLS_PKCS11_C", Defined)), + ("zlib", ("MBEDTLS_ZLIB_SUPPORT", Defined)), + ("std", ("MBEDTLS_NET_C", Defined)), + ("std", ("MBEDTLS_FS_IO", Defined)), + ("std", ("MBEDTLS_NO_PLATFORM_ENTROPY", Undefined)), + ("std", ("MBEDTLS_DEBUG_C", Defined)), + ("std", ("MBEDTLS_ENTROPY_C", Defined)), + ("custom_printf", ("MBEDTLS_PLATFORM_C", Defined)), + ("custom_printf", ("MBEDTLS_PLATFORM_PRINTF_MACRO", DefinedAs("mbedtls_printf"))), + ("aesni", ("MBEDTLS_AESNI_C", Defined)), ]; -pub const SUFFIX: &'static str=r#" +pub const SUFFIX: &'static str = r#" #if defined(TARGET_LIKE_MBED) #include "mbedtls/target_config.h" #endif diff --git a/mbedtls-sys/build/headers.rs b/mbedtls-sys/build/headers.rs index f9dedbc4f..276551acf 100644 --- a/mbedtls-sys/build/headers.rs +++ b/mbedtls-sys/build/headers.rs @@ -1,19 +1,19 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ /* This list has been generated from a include/mbedtls/ directory as follows: - * + * * 1. Find all occurences of #include "", but skip MBEDTLS macros and *_alt.h * 2. Add a list all files in the current directory * 3. Reverse topological sort * 4. Exclude certain files * 5. Show only files that exist in cmdline order - * + * * ls -f1 $( \ * ( \ * grep '^#include' *|grep -v '<'|grep -v MBEDTLS_|sed 's/:#include//;s/"//g'|grep -v _alt.h; \ @@ -23,89 +23,90 @@ * ) */ -pub const ORDERED: &'static [(Option<&'static str>,&'static str)]=&[ - (None, "bignum.h"), - (None, "md.h"), - (Some("threading"), "threading.h"), - (None, "ecp.h"), - (None, "rsa.h"), - (None, "ecdsa.h"), - (None, "asn1.h"), - (None, "pk.h"), - (None, "x509.h"), - (None, "cipher.h"), - (None, "x509_crl.h"), - (None, "ssl_ciphersuites.h"), - (None, "x509_crt.h"), - (None, "dhm.h"), - (None, "ecdh.h"), - (None, "platform_time.h"), - (None, "ssl.h"), - (None, "md5.h"), - (None, "sha1.h"), - (None, "sha256.h"), - (None, "sha512.h"), - (None, "ecjpake.h"), - (None, "aes.h"), - (None, "net_sockets.h"), - (None, "havege.h"), - (None, "xtea.h"), - (None, "poly1305.h"), - (None, "chacha20.h"), - (None, "x509_csr.h"), - (None, "version.h"), - (None, "timing.h"), - (None, "ssl_ticket.h"), - (None, "ssl_internal.h"), - (None, "ssl_cookie.h"), - (None, "ssl_cache.h"), - (None, "rsa_internal.h"), - (None, "ripemd160.h"), - (None, "platform_util.h"), - (None, "platform.h"), - (None, "pkcs5.h"), - (None, "pkcs12.h"), - (Some("pkcs11"), "pkcs11.h"), - (None, "pk_internal.h"), - (None, "pem.h"), - (None, "padlock.h"), - (None, "oid.h"), - (None, "nist_kw.h"), - (None, "net.h"), - (None, "memory_buffer_alloc.h"), - (None, "md_internal.h"), - (None, "md4.h"), - (None, "md2.h"), - (None, "hmac_drbg.h"), - (None, "hkdf.h"), - (None, "gcm.h"), - (None, "error.h"), - (None, "entropy_poll.h"), - (None, "entropy.h"), - (None, "ecp_internal.h"), - (None, "des.h"), - (None, "debug.h"), - (None, "ctr_drbg.h"), - (None, "cmac.h"), - (None, "cipher_internal.h"), - (None, "chachapoly.h"), - (None, "ccm.h"), - (None, "camellia.h"), - (None, "bn_mul.h"), - (None, "blowfish.h"), - (None, "base64.h"), - (None, "asn1write.h"), - (None, "aria.h"), - (None, "arc4.h"), - (None, "aesni.h"), +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const ORDERED: &'static [(Option<&'static str>, &'static str)] = &[ + (None, "bignum.h"), + (None, "md.h"), + (Some("threading"), "threading.h"), + (None, "ecp.h"), + (None, "rsa.h"), + (None, "ecdsa.h"), + (None, "asn1.h"), + (None, "pk.h"), + (None, "x509.h"), + (None, "cipher.h"), + (None, "x509_crl.h"), + (None, "ssl_ciphersuites.h"), + (None, "x509_crt.h"), + (None, "dhm.h"), + (None, "ecdh.h"), + (None, "platform_time.h"), + (None, "ssl.h"), + (None, "md5.h"), + (None, "sha1.h"), + (None, "sha256.h"), + (None, "sha512.h"), + (None, "ecjpake.h"), + (None, "aes.h"), + (None, "net_sockets.h"), + (None, "havege.h"), + (None, "xtea.h"), + (None, "poly1305.h"), + (None, "chacha20.h"), + (None, "x509_csr.h"), + (None, "version.h"), + (None, "timing.h"), + (None, "ssl_ticket.h"), + (None, "ssl_internal.h"), + (None, "ssl_cookie.h"), + (None, "ssl_cache.h"), + (None, "rsa_internal.h"), + (None, "ripemd160.h"), + (None, "platform_util.h"), + (None, "platform.h"), + (None, "pkcs5.h"), + (None, "pkcs12.h"), + (Some("pkcs11"), "pkcs11.h"), + (None, "pk_internal.h"), + (None, "pem.h"), + (None, "padlock.h"), + (None, "oid.h"), + (None, "nist_kw.h"), + (None, "net.h"), + (None, "memory_buffer_alloc.h"), + (None, "md_internal.h"), + (None, "md4.h"), + (None, "md2.h"), + (None, "hmac_drbg.h"), + (None, "hkdf.h"), + (None, "gcm.h"), + (None, "error.h"), + (None, "entropy_poll.h"), + (None, "entropy.h"), + (None, "ecp_internal.h"), + (None, "des.h"), + (None, "debug.h"), + (None, "ctr_drbg.h"), + (None, "cmac.h"), + (None, "cipher_internal.h"), + (None, "chachapoly.h"), + (None, "ccm.h"), + (None, "camellia.h"), + (None, "bn_mul.h"), + (None, "blowfish.h"), + (None, "base64.h"), + (None, "asn1write.h"), + (None, "aria.h"), + (None, "arc4.h"), + (None, "aesni.h"), ]; -pub fn enabled_ordered() -> Box> { - Box::new(ORDERED.iter().filter_map(|&(feat,h)| - if feat.map(::have_feature).unwrap_or(true) { - Some(h) - } else { - None - } - )) +pub fn enabled_ordered() -> Box> { + Box::new(ORDERED.iter().filter_map(|&(feat, h)| { + if feat.map(::have_feature).unwrap_or(true) { + Some(h) + } else { + None + } + })) } diff --git a/mbedtls-sys/src/lib.rs b/mbedtls-sys/src/lib.rs index 62bb6bc2e..190392fdc 100644 --- a/mbedtls-sys/src/lib.rs +++ b/mbedtls-sys/src/lib.rs @@ -1,13 +1,13 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ -#![cfg_attr(not(feature="std"),no_std)] -#[cfg(feature="std")] +#![cfg_attr(not(feature = "std"), no_std)] +#[cfg(feature = "std")] extern crate core; pub mod types; diff --git a/mbedtls-sys/src/types.rs b/mbedtls-sys/src/types.rs index abf1a7b76..a3a137fb2 100644 --- a/mbedtls-sys/src/types.rs +++ b/mbedtls-sys/src/types.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ #![allow(non_camel_case_types)] @@ -22,76 +22,92 @@ pub type intptr_t = isize; pub type uintptr_t = usize; pub type ptrdiff_t = isize; -#[cfg(feature="std")] +#[cfg(feature = "std")] pub use std::os::raw as raw_types; -#[cfg(not(feature="std"))] +#[cfg(not(feature = "std"))] pub mod raw_types { - // From libstd/os/raw.rs - #[cfg(any(target_os = "android", - target_os = "emscripten", - all(target_os = "linux", any(target_arch = "aarch64", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "powerpc64"))))] - pub type c_char = u8; - #[cfg(not(any(target_os = "android", - target_os = "emscripten", - all(target_os = "linux", any(target_arch = "aarch64", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "powerpc64")))))] - pub type c_char = i8; - pub type c_schar = i8; - pub type c_uchar = u8; - pub type c_short = i16; - pub type c_ushort = u16; - pub type c_int = i32; - pub type c_uint = u32; - #[cfg(any(target_pointer_width = "32", windows))] - pub type c_long = i32; - #[cfg(any(target_pointer_width = "32", windows))] - pub type c_ulong = u32; - #[cfg(all(target_pointer_width = "64", not(windows)))] - pub type c_long = i64; - #[cfg(all(target_pointer_width = "64", not(windows)))] - pub type c_ulong = u64; - pub type c_longlong = i64; - pub type c_ulonglong = u64; - pub type c_float = f32; - pub type c_double = f64; + // From libstd/os/raw.rs + #[cfg(any( + target_os = "android", + target_os = "emscripten", + all( + target_os = "linux", + any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "powerpc64" + ) + ) + ))] + pub type c_char = u8; + #[cfg(not(any( + target_os = "android", + target_os = "emscripten", + all( + target_os = "linux", + any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "powerpc64" + ) + ) + )))] + pub type c_char = i8; + pub type c_schar = i8; + pub type c_uchar = u8; + pub type c_short = i16; + pub type c_ushort = u16; + pub type c_int = i32; + pub type c_uint = u32; + #[cfg(any(target_pointer_width = "32", windows))] + pub type c_long = i32; + #[cfg(any(target_pointer_width = "32", windows))] + pub type c_ulong = u32; + #[cfg(all(target_pointer_width = "64", not(windows)))] + pub type c_long = i64; + #[cfg(all(target_pointer_width = "64", not(windows)))] + pub type c_ulong = u64; + pub type c_longlong = i64; + pub type c_ulonglong = u64; + pub type c_float = f32; + pub type c_double = f64; - #[repr(u8)] - pub enum c_void { - #[doc(hidden)] __variant1, - #[doc(hidden)] __variant2, - } + #[repr(u8)] + pub enum c_void { + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } } -#[cfg(feature="libc")] +#[cfg(feature = "libc")] extern crate libc; -#[cfg(feature="libc")] +#[cfg(feature = "libc")] mod libc_types { - pub use super::libc::FILE; + pub use super::libc::FILE; } -#[cfg(not(feature="libc"))] +#[cfg(not(feature = "libc"))] mod libc_types { - pub enum FILE {} + pub enum FILE {} } pub use self::libc_types::*; -#[cfg(feature="pthread")] +#[cfg(feature = "pthread")] pub use self::libc::pthread_mutex_t; -#[cfg(feature="time")] +#[cfg(feature = "time")] pub use self::libc::time_t; -#[cfg(feature="zlib")] +#[cfg(feature = "zlib")] extern crate libz_sys; -#[cfg(feature="zlib")] +#[cfg(feature = "zlib")] pub use self::libz_sys::z_stream; -#[cfg(feature="pkcs11")] +#[cfg(feature = "pkcs11")] const ERROR: _PKCS11_NOT_SUPPORTED_ = (); diff --git a/mbedtls/build.rs b/mbedtls/build.rs index 414a6b9d9..ec5694e6e 100644 --- a/mbedtls/build.rs +++ b/mbedtls/build.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ extern crate gcc; @@ -11,16 +11,18 @@ extern crate gcc; use std::env; fn main() { - let mut c = gcc::Config::new(); - c.file("src/rust_printf.c"); - if env::var_os("CARGO_FEATURE_STD").is_none() || env::var("TARGET").map(|s|s=="x86_64-unknown-none-gnu")==Ok(true) { - c.flag("-U_FORTIFY_SOURCE") - .define("_FORTIFY_SOURCE",Some("0")) - .flag("-ffreestanding"); - } - c.compile("librust-mbedtls.a"); - // Force correct link order for mbedtls_printf - println!("cargo:rustc-link-lib=static=mbedtls"); - println!("cargo:rustc-link-lib=static=mbedx509"); - println!("cargo:rustc-link-lib=static=mbedcrypto"); + let mut c = gcc::Config::new(); + c.file("src/rust_printf.c"); + if env::var_os("CARGO_FEATURE_STD").is_none() + || env::var("TARGET").map(|s| s == "x86_64-unknown-none-gnu") == Ok(true) + { + c.flag("-U_FORTIFY_SOURCE") + .define("_FORTIFY_SOURCE", Some("0")) + .flag("-ffreestanding"); + } + c.compile("librust-mbedtls.a"); + // Force correct link order for mbedtls_printf + println!("cargo:rustc-link-lib=static=mbedtls"); + println!("cargo:rustc-link-lib=static=mbedx509"); + println!("cargo:rustc-link-lib=static=mbedcrypto"); } diff --git a/mbedtls/examples/client.rs b/mbedtls/examples/client.rs index e724ba33c..9690269cd 100644 --- a/mbedtls/examples/client.rs +++ b/mbedtls/examples/client.rs @@ -1,48 +1,52 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ extern crate mbedtls; -use std::net::TcpStream; use std::io::{self, stdin, stdout, Write}; +use std::net::TcpStream; -use mbedtls::Result as TlsResult; use mbedtls::rng::CtrDrbg; -use mbedtls::x509::Certificate; -use mbedtls::ssl::config::{Endpoint, Transport, Preset}; +use mbedtls::ssl::config::{Endpoint, Preset, Transport}; use mbedtls::ssl::{Config, Context}; +use mbedtls::x509::Certificate; +use mbedtls::Result as TlsResult; -#[path="../tests/support/mod.rs"] +#[path = "../tests/support/mod.rs"] mod support; -use support::keys; use support::entropy::entropy_new; +use support::keys; fn result_main(addr: &str) -> TlsResult<()> { - let mut entropy = entropy_new(); - let mut rng = try!(CtrDrbg::new(&mut entropy, None)); - let mut cert = try!(Certificate::from_pem(keys::PEM_CERT)); - let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default); - config.set_rng(Some(&mut rng)); - config.set_ca_list(Some(&mut *cert), None); - let mut ctx = try!(Context::new(&config)); - - let mut conn = TcpStream::connect(addr).unwrap(); - let mut session = try!(ctx.establish(&mut conn, None)); - - let mut line = String::new(); - stdin().read_line(&mut line).unwrap(); - session.write_all(line.as_bytes()).unwrap(); - io::copy(&mut session, &mut stdout()).unwrap(); - Ok(()) + let mut entropy = entropy_new(); + let mut rng = try!(CtrDrbg::new(&mut entropy, None)); + let mut cert = try!(Certificate::from_pem(keys::PEM_CERT)); + let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default); + config.set_rng(Some(&mut rng)); + config.set_ca_list(Some(&mut *cert), None); + let mut ctx = try!(Context::new(&config)); + + let mut conn = TcpStream::connect(addr).unwrap(); + let mut session = try!(ctx.establish(&mut conn, None)); + + let mut line = String::new(); + stdin().read_line(&mut line).unwrap(); + session.write_all(line.as_bytes()).unwrap(); + io::copy(&mut session, &mut stdout()).unwrap(); + Ok(()) } fn main() { - let mut args = std::env::args(); - args.next(); - result_main(&args.next().expect("supply destination in command-line argument")).unwrap(); + let mut args = std::env::args(); + args.next(); + result_main( + &args + .next() + .expect("supply destination in command-line argument"), + ).unwrap(); } diff --git a/mbedtls/examples/server.rs b/mbedtls/examples/server.rs index 49a895a82..7bb327f6d 100644 --- a/mbedtls/examples/server.rs +++ b/mbedtls/examples/server.rs @@ -1,56 +1,56 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ extern crate mbedtls; +use std::io::{BufRead, BufReader, Write}; use std::net::{TcpListener, TcpStream}; -use std::io::{BufReader, BufRead, Write}; -use mbedtls::Result as TlsResult; -use mbedtls::rng::CtrDrbg; -use mbedtls::x509::Certificate; use mbedtls::pk::Pk; -use mbedtls::ssl::config::{Endpoint, Transport, Preset}; +use mbedtls::rng::CtrDrbg; +use mbedtls::ssl::config::{Endpoint, Preset, Transport}; use mbedtls::ssl::{Config, Context}; +use mbedtls::x509::Certificate; +use mbedtls::Result as TlsResult; -#[path="../tests/support/mod.rs"] +#[path = "../tests/support/mod.rs"] mod support; -use support::keys; use support::entropy::entropy_new; +use support::keys; fn listen Result<(), E>>(mut handle_client: F) -> Result<(), E> { - let sock = TcpListener::bind("127.0.0.1:8080").unwrap(); - for conn in sock.incoming().map(Result::unwrap) { - println!("Connection from {}", conn.peer_addr().unwrap()); - try!(handle_client(conn)); - } - Ok(()) + let sock = TcpListener::bind("127.0.0.1:8080").unwrap(); + for conn in sock.incoming().map(Result::unwrap) { + println!("Connection from {}", conn.peer_addr().unwrap()); + try!(handle_client(conn)); + } + Ok(()) } fn result_main() -> TlsResult<()> { - let mut entropy = entropy_new(); - let mut rng = try!(CtrDrbg::new(&mut entropy, None)); - let mut cert = try!(Certificate::from_pem(keys::PEM_CERT)); - let mut key = try!(Pk::from_private_key(keys::PEM_KEY, None)); - let mut config = Config::new(Endpoint::Server, Transport::Stream, Preset::Default); - config.set_rng(Some(&mut rng)); - try!(config.push_cert(&mut *cert, &mut key)); - let mut ctx = try!(Context::new(&config)); - - listen(|mut conn| { - let mut session = BufReader::new(try!(ctx.establish(&mut conn, None))); - let mut line = Vec::new(); - session.read_until(b'\n', &mut line).unwrap(); - session.get_mut().write_all(&line).unwrap(); - Ok(()) - }) + let mut entropy = entropy_new(); + let mut rng = try!(CtrDrbg::new(&mut entropy, None)); + let mut cert = try!(Certificate::from_pem(keys::PEM_CERT)); + let mut key = try!(Pk::from_private_key(keys::PEM_KEY, None)); + let mut config = Config::new(Endpoint::Server, Transport::Stream, Preset::Default); + config.set_rng(Some(&mut rng)); + try!(config.push_cert(&mut *cert, &mut key)); + let mut ctx = try!(Context::new(&config)); + + listen(|mut conn| { + let mut session = BufReader::new(try!(ctx.establish(&mut conn, None))); + let mut line = Vec::new(); + session.read_until(b'\n', &mut line).unwrap(); + session.get_mut().write_all(&line).unwrap(); + Ok(()) + }) } fn main() { - result_main().unwrap(); + result_main().unwrap(); } diff --git a/mbedtls/src/bignum/mod.rs b/mbedtls/src/bignum/mod.rs index b56248bbc..bd710158f 100644 --- a/mbedtls/src/bignum/mod.rs +++ b/mbedtls/src/bignum/mod.rs @@ -1,13 +1,13 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use error::IntoResult; -use ::mbedtls_sys::*; +use mbedtls_sys::*; define!(struct Mpi(mpi) { fn init=mpi_init; @@ -16,18 +16,18 @@ define!(struct Mpi(mpi) { }); impl Mpi { - pub fn new(value: mpi_sint) -> ::Result { - let mut ret = Self::init(); - try!(unsafe{mpi_lset(&mut ret.inner,value).into_result()}); - Ok(ret) - } + pub fn new(value: mpi_sint) -> ::Result { + let mut ret = Self::init(); + try!(unsafe { mpi_lset(&mut ret.inner, value).into_result() }); + Ok(ret) + } - /// Initialize an MPI number from big endian binary data - pub fn from_binary(num: &[u8]) -> ::Result { - let mut ret = Self::init(); - try!(unsafe{mpi_read_binary(&mut ret.inner,num.as_ptr(),num.len()).into_result()}); - Ok(ret) - } + /// Initialize an MPI number from big endian binary data + pub fn from_binary(num: &[u8]) -> ::Result { + let mut ret = Self::init(); + try!(unsafe { mpi_read_binary(&mut ret.inner, num.as_ptr(), num.len()).into_result() }); + Ok(ret) + } } // TODO diff --git a/mbedtls/src/cipher/mod.rs b/mbedtls/src/cipher/mod.rs index 5c7c196cd..6e9a92c8d 100644 --- a/mbedtls/src/cipher/mod.rs +++ b/mbedtls/src/cipher/mod.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use core::marker::PhantomData; @@ -17,12 +17,16 @@ pub trait Operation: Sized { pub enum Encryption {} impl Operation for Encryption { - fn is_encrypt() -> bool { true } + fn is_encrypt() -> bool { + true + } } pub enum Decryption {} impl Operation for Decryption { - fn is_encrypt() -> bool { false } + fn is_encrypt() -> bool { + false + } } // Type-level cipher types @@ -34,7 +38,7 @@ pub enum TraditionalNoIv {} impl Type for TraditionalNoIv { fn is_valid_mode(mode: raw::CipherMode) -> bool { match mode { - raw::CipherMode::ECB => true, + raw::CipherMode::ECB => true, _ => false, } } @@ -44,7 +48,10 @@ pub enum Traditional {} impl Type for Traditional { fn is_valid_mode(mode: raw::CipherMode) -> bool { match mode { - raw::CipherMode::CBC | raw::CipherMode::CFB | raw::CipherMode::OFB | raw::CipherMode::CTR => true, + raw::CipherMode::CBC + | raw::CipherMode::CFB + | raw::CipherMode::OFB + | raw::CipherMode::CTR => true, _ => false, } } @@ -54,7 +61,7 @@ pub enum Authenticated {} impl Type for Authenticated { fn is_valid_mode(mode: raw::CipherMode) -> bool { match mode { - raw::CipherMode::GCM | raw::CipherMode::CCM => true, + raw::CipherMode::GCM | raw::CipherMode::CCM => true, _ => false, } } @@ -76,204 +83,249 @@ pub enum Finished {} impl State for Finished {} pub struct Cipher { - raw_cipher: raw::Cipher, + raw_cipher: raw::Cipher, - // mbedtls only stores the padding as function pointers, so we remember this here - padding: raw::CipherPadding, - _op: PhantomData, - _type: PhantomData, - _state: PhantomData, + // mbedtls only stores the padding as function pointers, so we remember this here + padding: raw::CipherPadding, + _op: PhantomData, + _type: PhantomData, + _state: PhantomData, } impl Cipher { - fn change_state(self) -> Cipher { - self.change_type_and_state() - } - - fn change_type_and_state(self) -> Cipher { - Cipher { - raw_cipher: self.raw_cipher, - padding: self.padding, - _op: PhantomData, - _type: PhantomData, - _state: PhantomData, - } - } - - pub fn block_size(&self) -> usize { - self.raw_cipher.block_size() - } - - pub fn iv_size(&self) -> usize { - self.raw_cipher.iv_size() - } - - pub fn tag_size(&self) -> Option> { - if self.raw_cipher.is_authenticated() { - Some(32..129) - } else { - None - } - } + fn change_state(self) -> Cipher { + self.change_type_and_state() + } + + fn change_type_and_state(self) -> Cipher { + Cipher { + raw_cipher: self.raw_cipher, + padding: self.padding, + _op: PhantomData, + _type: PhantomData, + _state: PhantomData, + } + } + + pub fn block_size(&self) -> usize { + self.raw_cipher.block_size() + } + + pub fn iv_size(&self) -> usize { + self.raw_cipher.iv_size() + } + + pub fn tag_size(&self) -> Option> { + if self.raw_cipher.is_authenticated() { + Some(32..129) + } else { + None + } + } } impl Cipher { - pub fn new(cipher_id: raw::CipherId, cipher_mode: raw::CipherMode, key_bit_len: u32) -> ::Result> { - assert!(T::is_valid_mode(cipher_mode)); - - // Create raw cipher object - let raw_cipher = try!(raw::Cipher::setup(cipher_id, cipher_mode, key_bit_len)); - - // Put together the structure to return - Ok(Cipher { - raw_cipher: raw_cipher, - padding: raw::CipherPadding::Pkcs7, - _op: PhantomData, - _type: PhantomData, - _state: PhantomData, - }) - } - - pub fn set_parity(key: &mut [u8]) -> ::Result<()> { - raw::Cipher::set_parity(key) - } + pub fn new( + cipher_id: raw::CipherId, + cipher_mode: raw::CipherMode, + key_bit_len: u32, + ) -> ::Result> { + assert!(T::is_valid_mode(cipher_mode)); + + // Create raw cipher object + let raw_cipher = try!(raw::Cipher::setup(cipher_id, cipher_mode, key_bit_len)); + + // Put together the structure to return + Ok(Cipher { + raw_cipher: raw_cipher, + padding: raw::CipherPadding::Pkcs7, + _op: PhantomData, + _type: PhantomData, + _state: PhantomData, + }) + } + + pub fn set_parity(key: &mut [u8]) -> ::Result<()> { + raw::Cipher::set_parity(key) + } } impl Cipher { - fn set_key_and_maybe_iv(&mut self, key: &[u8], iv: Option<&[u8]>) -> ::Result<()> { - let cipher_op = if Op::is_encrypt() { raw::Operation::Encrypt } else { raw::Operation::Decrypt }; - - // Set key - self.raw_cipher.set_key(cipher_op, key)?; - - // Set IV - if let Some(iv) = iv { - self.raw_cipher.set_iv(iv)?; - } + fn set_key_and_maybe_iv(&mut self, key: &[u8], iv: Option<&[u8]>) -> ::Result<()> { + let cipher_op = if Op::is_encrypt() { + raw::Operation::Encrypt + } else { + raw::Operation::Decrypt + }; + + // Set key + self.raw_cipher.set_key(cipher_op, key)?; + + // Set IV + if let Some(iv) = iv { + self.raw_cipher.set_iv(iv)?; + } - // Also do a reset right here so the user can start the crypto operation right away in "CipherData" - self.raw_cipher.reset() - } + // Also do a reset right here so the user can start the crypto operation right away in "CipherData" + self.raw_cipher.reset() + } - pub fn set_padding(&mut self, padding: raw::CipherPadding) -> ::Result<()> { - self.padding = padding; - self.raw_cipher.set_padding(padding) - } + pub fn set_padding(&mut self, padding: raw::CipherPadding) -> ::Result<()> { + self.padding = padding; + self.raw_cipher.set_padding(padding) + } } impl Cipher { - pub fn set_key(mut self, key: &[u8]) -> ::Result> { - self.set_key_and_maybe_iv(key, None)?; + pub fn set_key(mut self, key: &[u8]) -> ::Result> { + self.set_key_and_maybe_iv(key, None)?; - // Put together the structure to return - Ok(self.change_type_and_state()) - } + // Put together the structure to return + Ok(self.change_type_and_state()) + } } impl Cipher { - pub fn set_key_iv(mut self, key: &[u8], iv: &[u8]) -> ::Result> { - self.set_key_and_maybe_iv(key, Some(iv))?; - - // Put together the structure to return - Ok(self.change_state()) - } + pub fn set_key_iv( + mut self, + key: &[u8], + iv: &[u8], + ) -> ::Result> { + self.set_key_and_maybe_iv(key, Some(iv))?; + + // Put together the structure to return + Ok(self.change_state()) + } } impl Cipher { - pub fn set_key_iv(mut self, key: &[u8], iv: &[u8]) -> ::Result> { - self.set_key_and_maybe_iv(key, Some(iv))?; - - // Put together the structure to return - Ok(self.change_state()) - } + pub fn set_key_iv( + mut self, + key: &[u8], + iv: &[u8], + ) -> ::Result> { + self.set_key_and_maybe_iv(key, Some(iv))?; + + // Put together the structure to return + Ok(self.change_state()) + } } impl Cipher { - pub fn encrypt(mut self, - plain_text: &[u8], - cipher_text: &mut [u8]) - -> ::Result<(usize, Cipher)> { - // Call the wrapper function to encrypt all - let len = try!(self.raw_cipher.encrypt(plain_text, cipher_text)); - - // Put together the structure to return - Ok((len, self.change_state())) - } + pub fn encrypt( + mut self, + plain_text: &[u8], + cipher_text: &mut [u8], + ) -> ::Result<(usize, Cipher)> { + // Call the wrapper function to encrypt all + let len = try!(self.raw_cipher.encrypt(plain_text, cipher_text)); + + // Put together the structure to return + Ok((len, self.change_state())) + } } impl Cipher { - pub fn decrypt(mut self, - cipher_text: &[u8], - plain_text: &mut [u8]) - -> ::Result<(usize, Cipher)> { - // Call the wrapper function to decrypt all - let len = try!(self.raw_cipher.decrypt(cipher_text, plain_text)); - - // Put together the structure to return - Ok((len, self.change_state())) - } + pub fn decrypt( + mut self, + cipher_text: &[u8], + plain_text: &mut [u8], + ) -> ::Result<(usize, Cipher)> { + // Call the wrapper function to decrypt all + let len = try!(self.raw_cipher.decrypt(cipher_text, plain_text)); + + // Put together the structure to return + Ok((len, self.change_state())) + } } impl Cipher { - pub fn encrypt_auth(mut self, - ad: &[u8], - plain_text: &[u8], - cipher_text: &mut [u8], - tag: &mut [u8]) - -> ::Result<(usize, Cipher)> { - Ok((self.raw_cipher.encrypt_auth(ad, plain_text, cipher_text, tag)?, self.change_state())) - } + pub fn encrypt_auth( + mut self, + ad: &[u8], + plain_text: &[u8], + cipher_text: &mut [u8], + tag: &mut [u8], + ) -> ::Result<(usize, Cipher)> { + Ok(( + self.raw_cipher + .encrypt_auth(ad, plain_text, cipher_text, tag)?, + self.change_state(), + )) + } } impl Cipher { - pub fn decrypt_auth(mut self, - ad: &[u8], - cipher_text: &[u8], - plain_text: &mut [u8], - tag: &[u8]) - -> ::Result<(usize, Cipher)> { - Ok((self.raw_cipher.decrypt_auth(ad, cipher_text, plain_text, tag)?, self.change_state())) - } + pub fn decrypt_auth( + mut self, + ad: &[u8], + cipher_text: &[u8], + plain_text: &mut [u8], + tag: &[u8], + ) -> ::Result<(usize, Cipher)> { + Ok(( + self.raw_cipher + .decrypt_auth(ad, cipher_text, plain_text, tag)?, + self.change_state(), + )) + } } impl Cipher { - pub fn update(mut self, in_data: &[u8], out_data: &mut [u8]) -> ::Result<(usize, Cipher)> { - // Call the wrapper function to do update operation (multi part) - let len = try!(self.raw_cipher.update(in_data, out_data)); - - // Put together the structure to return - Ok((len, self.change_state())) - } + pub fn update( + mut self, + in_data: &[u8], + out_data: &mut [u8], + ) -> ::Result<(usize, Cipher)> { + // Call the wrapper function to do update operation (multi part) + let len = try!(self.raw_cipher.update(in_data, out_data)); + + // Put together the structure to return + Ok((len, self.change_state())) + } - pub fn finish(mut self, out_data: &mut [u8]) -> ::Result<(usize, Cipher)> { - // Call the wrapper function to finish operation (multi part) - let len = try!(self.raw_cipher.finish(out_data)); + pub fn finish(mut self, out_data: &mut [u8]) -> ::Result<(usize, Cipher)> { + // Call the wrapper function to finish operation (multi part) + let len = try!(self.raw_cipher.finish(out_data)); - // Put together the structure to return - Ok((len, self.change_state())) - } + // Put together the structure to return + Ok((len, self.change_state())) + } } #[test] fn ccm() { - // Example vector C.1 - let k = [0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f]; - let iv = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16]; - let ad = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]; - let p = [0x20, 0x21, 0x22, 0x23]; - let mut p_out = [0u8; 4]; - let c = [0x71, 0x62, 0x01, 0x5b]; - let mut c_out = [0u8; 4]; - let t = [0x4d, 0xac, 0x25, 0x5d]; - let mut t_out = [0u8; 4]; - - let cipher = Cipher::<_, Authenticated, _>::new(raw::CipherId::Aes, raw::CipherMode::CCM, (k.len() * 8) as _).unwrap(); - let cipher = cipher.set_key_iv(&k, &iv).unwrap(); - cipher.encrypt_auth(&ad, &p, &mut c_out, &mut t_out).unwrap(); - assert_eq!(c, c_out); - assert_eq!(t, t_out); - let cipher = Cipher::<_, Authenticated, _>::new(raw::CipherId::Aes, raw::CipherMode::CCM, (k.len() * 8) as _).unwrap(); - let cipher = cipher.set_key_iv(&k, &iv).unwrap(); - cipher.decrypt_auth(&ad, &c, &mut p_out, &t).unwrap(); - assert_eq!(p, p_out); + // Example vector C.1 + let k = [ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, + 0x4f, + ]; + let iv = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16]; + let ad = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]; + let p = [0x20, 0x21, 0x22, 0x23]; + let mut p_out = [0u8; 4]; + let c = [0x71, 0x62, 0x01, 0x5b]; + let mut c_out = [0u8; 4]; + let t = [0x4d, 0xac, 0x25, 0x5d]; + let mut t_out = [0u8; 4]; + + let cipher = Cipher::<_, Authenticated, _>::new( + raw::CipherId::Aes, + raw::CipherMode::CCM, + (k.len() * 8) as _, + ).unwrap(); + let cipher = cipher.set_key_iv(&k, &iv).unwrap(); + cipher + .encrypt_auth(&ad, &p, &mut c_out, &mut t_out) + .unwrap(); + assert_eq!(c, c_out); + assert_eq!(t, t_out); + let cipher = Cipher::<_, Authenticated, _>::new( + raw::CipherId::Aes, + raw::CipherMode::CCM, + (k.len() * 8) as _, + ).unwrap(); + let cipher = cipher.set_key_iv(&k, &iv).unwrap(); + cipher.decrypt_auth(&ad, &c, &mut p_out, &t).unwrap(); + assert_eq!(p, p_out); } diff --git a/mbedtls/src/cipher/raw/mod.rs b/mbedtls/src/cipher/raw/mod.rs index 30905487c..d312b306d 100644 --- a/mbedtls/src/cipher/raw/mod.rs +++ b/mbedtls/src/cipher/raw/mod.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use mbedtls_sys::*; @@ -24,20 +24,20 @@ define!(enum CipherId -> cipher_id_t { }); impl From for CipherId { - fn from(inner: cipher_id_t) -> Self { - match inner { - CIPHER_ID_NONE => CipherId::None, - CIPHER_ID_NULL => CipherId::Null, - CIPHER_ID_AES => CipherId::Aes, - CIPHER_ID_DES => CipherId::Des, - CIPHER_ID_3DES => CipherId::Des3, - CIPHER_ID_CAMELLIA => CipherId::Camellia, - CIPHER_ID_BLOWFISH => CipherId::Blowfish, - CIPHER_ID_ARC4 => CipherId::Arc4, - // This should be replaced with TryFrom once it is stable. - _ => panic!("Invalid cipher_id_t"), - } - } + fn from(inner: cipher_id_t) -> Self { + match inner { + CIPHER_ID_NONE => CipherId::None, + CIPHER_ID_NULL => CipherId::Null, + CIPHER_ID_AES => CipherId::Aes, + CIPHER_ID_DES => CipherId::Des, + CIPHER_ID_3DES => CipherId::Des3, + CIPHER_ID_CAMELLIA => CipherId::Camellia, + CIPHER_ID_BLOWFISH => CipherId::Blowfish, + CIPHER_ID_ARC4 => CipherId::Arc4, + // This should be replaced with TryFrom once it is stable. + _ => panic!("Invalid cipher_id_t"), + } + } } define!(#[derive(Copy, Clone, Eq, PartialEq)] enum CipherMode -> cipher_mode_t { @@ -53,21 +53,21 @@ define!(#[derive(Copy, Clone, Eq, PartialEq)] enum CipherMode -> cipher_mode_t { }); impl From for CipherMode { - fn from(inner: cipher_mode_t) -> Self { - match inner { - MODE_NONE => CipherMode::None, - MODE_ECB => CipherMode::ECB, - MODE_CBC => CipherMode::CBC, - MODE_CFB => CipherMode::CFB, - MODE_OFB => CipherMode::OFB, - MODE_CTR => CipherMode::CTR, - MODE_GCM => CipherMode::GCM, - MODE_STREAM => CipherMode::STREAM, - MODE_CCM => CipherMode::CCM, - // This should be replaced with TryFrom once it is stable. - _ => panic!("Invalid cipher_mode_t"), - } - } + fn from(inner: cipher_mode_t) -> Self { + match inner { + MODE_NONE => CipherMode::None, + MODE_ECB => CipherMode::ECB, + MODE_CBC => CipherMode::CBC, + MODE_CFB => CipherMode::CFB, + MODE_OFB => CipherMode::OFB, + MODE_CTR => CipherMode::CTR, + MODE_GCM => CipherMode::GCM, + MODE_STREAM => CipherMode::STREAM, + MODE_CCM => CipherMode::CCM, + // This should be replaced with TryFrom once it is stable. + _ => panic!("Invalid cipher_mode_t"), + } + } } define!(enum CipherType -> cipher_type_t { @@ -146,217 +146,252 @@ struct Cipher(cipher_context_t) { }); impl Cipher { - // Setup routine - this should be the first function called - // it combines several steps into one call here, they are - // Cipher init, Cipher setup - pub fn setup(cipher_id: CipherId, cipher_mode: CipherMode, key_bit_len: u32) -> ::Result { - let mut ret = Self::init(); - unsafe { - // Do setup with proper cipher_info based on algorithm, key length and mode - try!(cipher_setup(&mut ret.inner, - cipher_info_from_values(cipher_id.into(), - key_bit_len as i32, - cipher_mode.into()) - ).into_result()); - } - Ok(ret) - } - - // Cipher set key - should be called after setup - pub fn set_key(&mut self, op: Operation, key: &[u8]) -> ::Result<()> { - unsafe { - cipher_setkey(&mut self.inner, key.as_ptr(), (key.len() * 8) as _, op.into()).into_result_discard() - } - } - - pub fn set_padding(&mut self, padding: CipherPadding) -> ::Result<()> { - unsafe { - cipher_set_padding_mode(&mut self.inner, padding.into()).into_result_discard() - } - } - - // Cipher set IV - should be called after setup - pub fn set_iv(&mut self, iv: &[u8]) -> ::Result<()> { - unsafe { - cipher_set_iv(&mut self.inner, iv.as_ptr(), iv.len()).into_result_discard() - } - } - - pub fn reset(&mut self) -> ::Result<()> { - unsafe { - cipher_reset(&mut self.inner).into_result_discard() - } - } - - pub fn update(&mut self, indata: &[u8], outdata: &mut [u8]) -> ::Result { - // Check that minimum required space is available in outdata buffer - let reqd_size = if unsafe{*self.inner.cipher_info}.mode == MODE_ECB { - self.block_size() - } else { - indata.len() + self.block_size() - }; - - if outdata.len() < reqd_size { - return Err(::Error::CipherFullBlockExpected); - } - - let mut olen = 0; - unsafe { - try!(cipher_update(&mut self.inner, - indata.as_ptr(), - indata.len(), - outdata.as_mut_ptr(), - &mut olen - ).into_result()); - } - Ok(olen) - } - - pub fn finish(&mut self, outdata: &mut [u8]) -> ::Result { - // Check that minimum required space is available in outdata buffer - if outdata.len() < self.block_size() { - return Err(::Error::CipherFullBlockExpected); - } - - let mut olen = 0; - unsafe { - try!(cipher_finish(&mut self.inner, - outdata.as_mut_ptr(), - &mut olen - ).into_result()); - } - Ok(olen) - } - - pub fn write_tag(&mut self, tag: &mut [u8]) -> ::Result<()> { - unsafe { - cipher_write_tag(&mut self.inner, tag.as_mut_ptr(), tag.len()).into_result_discard() - } - } - - pub fn check_tag(&mut self, tag: &[u8]) -> ::Result<()> { - unsafe { - cipher_check_tag(&mut self.inner, tag.as_ptr(), tag.len()).into_result_discard() - } - } - - // Utility function to get block size for the selected / setup cipher_info - pub fn block_size(&self) -> usize { - unsafe { (*self.inner.cipher_info).block_size as usize } - } - - // Utility function to get IV size for the selected / setup cipher_info - pub fn iv_size(&self) -> usize { - unsafe { (*self.inner.cipher_info).iv_size as usize } - } - - // Utility function to get mdoe for the selected / setup cipher_info - pub fn is_authenticated(&self) -> bool { - unsafe { - if (*self.inner.cipher_info).mode == MODE_GCM || (*self.inner.cipher_info).mode == MODE_CCM { - return true; - } else { - return false; - } - } - } - - // Utility function to set odd parity - used for DES keys - pub fn set_parity(key: &mut [u8]) -> ::Result<()> { - unsafe { - des_key_set_parity(key.as_mut_ptr()) - } - Ok(()) - } - - pub fn encrypt(&mut self, plain: &[u8], cipher: &mut [u8]) -> ::Result { - self.do_crypto(plain, cipher) - } - - pub fn decrypt(&mut self, cipher: &[u8], plain: &mut [u8]) -> ::Result { - self.do_crypto(cipher, plain) - } - - pub fn encrypt_auth(&mut self, ad: &[u8], plain: &[u8], cipher: &mut [u8], tag: &mut [u8]) -> ::Result { - if plain.len() > cipher.len() { - return Err(::Error::CipherBadInputData); - } - - let iv = self.inner.iv; - let iv_len = self.inner.iv_size; - let mut cipher_len = cipher.len(); - unsafe { cipher_auth_encrypt( - &mut self.inner, - iv.as_ptr(), iv_len, - ad.as_ptr(), ad.len(), - plain.as_ptr(), plain.len(), - cipher.as_mut_ptr(), &mut cipher_len, - tag.as_mut_ptr(), tag.len() - ).into_result()? }; - - Ok(cipher_len) - } - - pub fn decrypt_auth(&mut self, ad: &[u8], cipher: &[u8], plain: &mut [u8], tag: &[u8]) -> ::Result { - if cipher.len() > plain.len() { - return Err(::Error::CipherBadInputData); - } - - let iv = self.inner.iv; - let iv_len = self.inner.iv_size; - let mut plain_len = plain.len(); - unsafe { cipher_auth_decrypt( - &mut self.inner, - iv.as_ptr(), iv_len, - ad.as_ptr(), ad.len(), - cipher.as_ptr(), cipher.len(), - plain.as_mut_ptr(), &mut plain_len, - tag.as_ptr(), tag.len() - ).into_result()? }; - - Ok(plain_len) - } - - fn do_crypto(&mut self, indata: &[u8], outdata: &mut [u8]) -> ::Result { - self.reset()?; - - // The total number of bytes writte to outdata so far. It's safe to - // use this as a start index for slicing: &slice[slice.len()..] will - // return an empty slice, it doesn't panic. - let mut total_len = 0; - - if unsafe{*self.inner.cipher_info}.mode == MODE_ECB { - // ECB mode requires single-block updates - for chunk in indata.chunks(self.block_size()) { - let len = self.update(chunk, &mut outdata[total_len..])?; - total_len += len; - } - } else { - total_len = self.update(indata, outdata)?; - total_len += self.finish(&mut outdata[total_len..])?; - } - - Ok(total_len) - } + // Setup routine - this should be the first function called + // it combines several steps into one call here, they are + // Cipher init, Cipher setup + pub fn setup( + cipher_id: CipherId, + cipher_mode: CipherMode, + key_bit_len: u32, + ) -> ::Result { + let mut ret = Self::init(); + unsafe { + // Do setup with proper cipher_info based on algorithm, key length and mode + try!( + cipher_setup( + &mut ret.inner, + cipher_info_from_values( + cipher_id.into(), + key_bit_len as i32, + cipher_mode.into() + ) + ).into_result() + ); + } + Ok(ret) + } + + // Cipher set key - should be called after setup + pub fn set_key(&mut self, op: Operation, key: &[u8]) -> ::Result<()> { + unsafe { + cipher_setkey( + &mut self.inner, + key.as_ptr(), + (key.len() * 8) as _, + op.into(), + ).into_result_discard() + } + } + + pub fn set_padding(&mut self, padding: CipherPadding) -> ::Result<()> { + unsafe { cipher_set_padding_mode(&mut self.inner, padding.into()).into_result_discard() } + } + + // Cipher set IV - should be called after setup + pub fn set_iv(&mut self, iv: &[u8]) -> ::Result<()> { + unsafe { cipher_set_iv(&mut self.inner, iv.as_ptr(), iv.len()).into_result_discard() } + } + + pub fn reset(&mut self) -> ::Result<()> { + unsafe { cipher_reset(&mut self.inner).into_result_discard() } + } + + pub fn update(&mut self, indata: &[u8], outdata: &mut [u8]) -> ::Result { + // Check that minimum required space is available in outdata buffer + let reqd_size = if unsafe { *self.inner.cipher_info }.mode == MODE_ECB { + self.block_size() + } else { + indata.len() + self.block_size() + }; + + if outdata.len() < reqd_size { + return Err(::Error::CipherFullBlockExpected); + } + + let mut olen = 0; + unsafe { + try!( + cipher_update( + &mut self.inner, + indata.as_ptr(), + indata.len(), + outdata.as_mut_ptr(), + &mut olen + ).into_result() + ); + } + Ok(olen) + } + + pub fn finish(&mut self, outdata: &mut [u8]) -> ::Result { + // Check that minimum required space is available in outdata buffer + if outdata.len() < self.block_size() { + return Err(::Error::CipherFullBlockExpected); + } + + let mut olen = 0; + unsafe { + try!(cipher_finish(&mut self.inner, outdata.as_mut_ptr(), &mut olen).into_result()); + } + Ok(olen) + } + + pub fn write_tag(&mut self, tag: &mut [u8]) -> ::Result<()> { + unsafe { + cipher_write_tag(&mut self.inner, tag.as_mut_ptr(), tag.len()).into_result_discard() + } + } + + pub fn check_tag(&mut self, tag: &[u8]) -> ::Result<()> { + unsafe { cipher_check_tag(&mut self.inner, tag.as_ptr(), tag.len()).into_result_discard() } + } + + // Utility function to get block size for the selected / setup cipher_info + pub fn block_size(&self) -> usize { + unsafe { (*self.inner.cipher_info).block_size as usize } + } + + // Utility function to get IV size for the selected / setup cipher_info + pub fn iv_size(&self) -> usize { + unsafe { (*self.inner.cipher_info).iv_size as usize } + } + + // Utility function to get mdoe for the selected / setup cipher_info + pub fn is_authenticated(&self) -> bool { + unsafe { + if (*self.inner.cipher_info).mode == MODE_GCM + || (*self.inner.cipher_info).mode == MODE_CCM + { + return true; + } else { + return false; + } + } + } + + // Utility function to set odd parity - used for DES keys + pub fn set_parity(key: &mut [u8]) -> ::Result<()> { + unsafe { des_key_set_parity(key.as_mut_ptr()) } + Ok(()) + } + + pub fn encrypt(&mut self, plain: &[u8], cipher: &mut [u8]) -> ::Result { + self.do_crypto(plain, cipher) + } + + pub fn decrypt(&mut self, cipher: &[u8], plain: &mut [u8]) -> ::Result { + self.do_crypto(cipher, plain) + } + + pub fn encrypt_auth( + &mut self, + ad: &[u8], + plain: &[u8], + cipher: &mut [u8], + tag: &mut [u8], + ) -> ::Result { + if plain.len() > cipher.len() { + return Err(::Error::CipherBadInputData); + } + + let iv = self.inner.iv; + let iv_len = self.inner.iv_size; + let mut cipher_len = cipher.len(); + unsafe { + cipher_auth_encrypt( + &mut self.inner, + iv.as_ptr(), + iv_len, + ad.as_ptr(), + ad.len(), + plain.as_ptr(), + plain.len(), + cipher.as_mut_ptr(), + &mut cipher_len, + tag.as_mut_ptr(), + tag.len(), + ).into_result()? + }; + + Ok(cipher_len) + } + + pub fn decrypt_auth( + &mut self, + ad: &[u8], + cipher: &[u8], + plain: &mut [u8], + tag: &[u8], + ) -> ::Result { + if cipher.len() > plain.len() { + return Err(::Error::CipherBadInputData); + } + + let iv = self.inner.iv; + let iv_len = self.inner.iv_size; + let mut plain_len = plain.len(); + unsafe { + cipher_auth_decrypt( + &mut self.inner, + iv.as_ptr(), + iv_len, + ad.as_ptr(), + ad.len(), + cipher.as_ptr(), + cipher.len(), + plain.as_mut_ptr(), + &mut plain_len, + tag.as_ptr(), + tag.len(), + ).into_result()? + }; + + Ok(plain_len) + } + + fn do_crypto(&mut self, indata: &[u8], outdata: &mut [u8]) -> ::Result { + self.reset()?; + + // The total number of bytes writte to outdata so far. It's safe to + // use this as a start index for slicing: &slice[slice.len()..] will + // return an empty slice, it doesn't panic. + let mut total_len = 0; + + if unsafe { *self.inner.cipher_info }.mode == MODE_ECB { + // ECB mode requires single-block updates + for chunk in indata.chunks(self.block_size()) { + let len = self.update(chunk, &mut outdata[total_len..])?; + total_len += len; + } + } else { + total_len = self.update(indata, outdata)?; + total_len += self.finish(&mut outdata[total_len..])?; + } + + Ok(total_len) + } } #[test] fn no_overflow() { - let mut c = Cipher::setup(CipherId::Aes, CipherMode::CBC, 128).unwrap(); - c.set_key(Operation::Encrypt, &[0u8;16]).unwrap(); - c.set_iv(&[0u8;16]).unwrap(); - let mut out = [0u8; 48]; - let encrypt_result = c.encrypt(&[0u8; 16][..], &mut out[..16]); - assert_eq!(out[16..], [0u8; 32]); - encrypt_result.expect_err("Returned OK with too small buffer"); + let mut c = Cipher::setup(CipherId::Aes, CipherMode::CBC, 128).unwrap(); + c.set_key(Operation::Encrypt, &[0u8; 16]).unwrap(); + c.set_iv(&[0u8; 16]).unwrap(); + let mut out = [0u8; 48]; + let encrypt_result = c.encrypt(&[0u8; 16][..], &mut out[..16]); + assert_eq!(out[16..], [0u8; 32]); + encrypt_result.expect_err("Returned OK with too small buffer"); } #[test] fn one_part_ecb() { - let mut c = Cipher::setup(CipherId::Aes, CipherMode::ECB, 128).unwrap(); - c.set_key(Operation::Encrypt, b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f").unwrap(); - let mut out = [0u8; 48]; - let len = c.encrypt(b"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff", &mut out).unwrap(); - assert_eq!(len, 32); - assert_eq!(&out[..len], b"\x69\xc4\xe0\xd8\x6a\x7b\x04\x30\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a\x69\xc4\xe0\xd8\x6a\x7b\x04\x30\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a"); + let mut c = Cipher::setup(CipherId::Aes, CipherMode::ECB, 128).unwrap(); + c.set_key( + Operation::Encrypt, + b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + ).unwrap(); + let mut out = [0u8; 48]; + let len = c.encrypt(b"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff", &mut out).unwrap(); + assert_eq!(len, 32); + assert_eq!(&out[..len], b"\x69\xc4\xe0\xd8\x6a\x7b\x04\x30\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a\x69\xc4\xe0\xd8\x6a\x7b\x04\x30\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a"); } diff --git a/mbedtls/src/cipher/raw/serde.rs b/mbedtls/src/cipher/raw/serde.rs index a8133c1b0..8af735c6e 100644 --- a/mbedtls/src/cipher/raw/serde.rs +++ b/mbedtls/src/cipher/raw/serde.rs @@ -1,193 +1,231 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ +#[cfg(not(feature = "std"))] +use alloc_prelude::*; use cipher::*; +use core::fmt; use core::marker::PhantomData; use core::mem::size_of; use core::ptr; -use core::str; use core::slice::from_raw_parts; -use core::fmt; -#[cfg(not(feature="std"))] -use alloc_prelude::*; +use core::str; use mbedtls_sys::*; -use serde::{Serialize, Serializer, Deserialize, Deserializer}; -use serde::ser::SerializeSeq; -use serde::de::Unexpected; -use serde::{ser, de}; use serde; +use serde::de::Unexpected; +use serde::ser::SerializeSeq; +use serde::{de, ser}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; struct Bytes(T); #[derive(Serialize, Deserialize)] enum SavedCipher { - Encryption(SavedRawCipher, raw::CipherPadding), - Decryption(SavedRawCipher, raw::CipherPadding), + Encryption(SavedRawCipher, raw::CipherPadding), + Decryption(SavedRawCipher, raw::CipherPadding), } // Custom serialization in serde.rs to force encoding as sequence. #[derive(Deserialize)] pub struct SavedRawCipher { - cipher_id: cipher_id_t, - cipher_mode: cipher_mode_t, - key_bit_len: u32, - context: Bytes, - algorithm_ctx: AlgorithmContext, + cipher_id: cipher_id_t, + cipher_mode: cipher_mode_t, + key_bit_len: u32, + context: Bytes, + algorithm_ctx: AlgorithmContext, } -#[derive(Serialize,Deserialize)] +#[derive(Serialize, Deserialize)] enum AlgorithmContext { - Aes(Bytes), - Des(Bytes), - Des3(Bytes), + Aes(Bytes), + Des(Bytes), + Des3(Bytes), } // Serialization support for cipher structs. We only support serialization for traditional (not // AEAD) ciphers, and only in the "data" state. impl Serialize for Cipher { - fn serialize(&self, s: S) -> Result - where S: Serializer - { - let saved_raw_cipher = unsafe { - let mut cipher_context = self.raw_cipher.inner; - - let cipher_id = (*(*cipher_context.cipher_info).base).cipher; - let cipher_mode = (*cipher_context.cipher_info).mode; - let key_bit_len = (*cipher_context.cipher_info).key_bitlen; - - // Null the cipher info now that we've extracted the important bits. - cipher_context.cipher_info = ::core::ptr::null(); - - // We only allow certain modes that we know have serialization-safe context - // structures. If adding GCM/CCM support, be aware that they don't use the same - // context types as the conventional modes. - let algorithm_ctx = match (cipher_id, cipher_mode) { - (CIPHER_ID_AES, MODE_CBC) | - (CIPHER_ID_AES, MODE_CTR) | - (CIPHER_ID_AES, MODE_CFB) => { - let mut aes_context = *(cipher_context.cipher_ctx as *const aes_context); - aes_context.rk = ::core::ptr::null_mut(); - AlgorithmContext::Aes(Bytes(aes_context)) - } - (CIPHER_ID_DES, MODE_CBC) | - (CIPHER_ID_DES, MODE_CTR) | - (CIPHER_ID_DES, MODE_CFB) => AlgorithmContext::Des(Bytes(*(cipher_context.cipher_ctx as *const des_context))), - (CIPHER_ID_3DES, MODE_CBC) | - (CIPHER_ID_3DES, MODE_CTR) | - (CIPHER_ID_3DES, MODE_CFB) => AlgorithmContext::Des3(Bytes(*(cipher_context.cipher_ctx as *const des3_context))), - _ => return Err(ser::Error::custom("unsupported algorithm for serialization")), - }; - - // Null the algorithm context - cipher_context.cipher_ctx = ::core::ptr::null_mut(); - - // Null function pointers - cipher_context.add_padding = None; - cipher_context.get_padding = None; - - SavedRawCipher { - cipher_id: cipher_id, - cipher_mode: cipher_mode, - key_bit_len: key_bit_len, - context: Bytes(cipher_context), - algorithm_ctx: algorithm_ctx, - } - }; - - match Op::is_encrypt() { - true => SavedCipher::Encryption(saved_raw_cipher, self.padding).serialize(s), - false => SavedCipher::Decryption(saved_raw_cipher, self.padding).serialize(s), - } - } + fn serialize(&self, s: S) -> Result + where + S: Serializer, + { + let saved_raw_cipher = unsafe { + let mut cipher_context = self.raw_cipher.inner; + + let cipher_id = (*(*cipher_context.cipher_info).base).cipher; + let cipher_mode = (*cipher_context.cipher_info).mode; + let key_bit_len = (*cipher_context.cipher_info).key_bitlen; + + // Null the cipher info now that we've extracted the important bits. + cipher_context.cipher_info = ::core::ptr::null(); + + // We only allow certain modes that we know have serialization-safe context + // structures. If adding GCM/CCM support, be aware that they don't use the same + // context types as the conventional modes. + let algorithm_ctx = match (cipher_id, cipher_mode) { + (CIPHER_ID_AES, MODE_CBC) + | (CIPHER_ID_AES, MODE_CTR) + | (CIPHER_ID_AES, MODE_CFB) => { + let mut aes_context = *(cipher_context.cipher_ctx as *const aes_context); + aes_context.rk = ::core::ptr::null_mut(); + AlgorithmContext::Aes(Bytes(aes_context)) + } + (CIPHER_ID_DES, MODE_CBC) + | (CIPHER_ID_DES, MODE_CTR) + | (CIPHER_ID_DES, MODE_CFB) => { + AlgorithmContext::Des(Bytes(*(cipher_context.cipher_ctx as *const des_context))) + } + (CIPHER_ID_3DES, MODE_CBC) + | (CIPHER_ID_3DES, MODE_CTR) + | (CIPHER_ID_3DES, MODE_CFB) => AlgorithmContext::Des3(Bytes( + *(cipher_context.cipher_ctx as *const des3_context), + )), + _ => { + return Err(ser::Error::custom( + "unsupported algorithm for serialization", + )) + } + }; + + // Null the algorithm context + cipher_context.cipher_ctx = ::core::ptr::null_mut(); + + // Null function pointers + cipher_context.add_padding = None; + cipher_context.get_padding = None; + + SavedRawCipher { + cipher_id: cipher_id, + cipher_mode: cipher_mode, + key_bit_len: key_bit_len, + context: Bytes(cipher_context), + algorithm_ctx: algorithm_ctx, + } + }; + + match Op::is_encrypt() { + true => SavedCipher::Encryption(saved_raw_cipher, self.padding).serialize(s), + false => SavedCipher::Decryption(saved_raw_cipher, self.padding).serialize(s), + } + } } impl<'de, Op: Operation> Deserialize<'de> for Cipher { - fn deserialize(d: D) -> Result, D::Error> - where D: Deserializer<'de> - { - let saved_cipher: SavedCipher = try!(SavedCipher::deserialize(d)); - - let (raw, padding) = match saved_cipher { - SavedCipher::Encryption(..) if !Op::is_encrypt() => { - return Err(de::Error::invalid_value(Unexpected::Other("incorrect cipher operation"), &"encryption")); - } - SavedCipher::Decryption(..) if Op::is_encrypt() => { - return Err(de::Error::invalid_value(Unexpected::Other("incorrect cipher operation"), &"decryption")); - } - SavedCipher::Encryption(raw, padding) | SavedCipher::Decryption(raw, padding) => (raw, padding), - }; - - let mut raw_cipher = match raw::Cipher::setup(raw.cipher_id.into(), raw.cipher_mode.into(), raw.key_bit_len) { - Ok(raw) => raw, - Err(_) => return Err(de::Error::invalid_value(Unexpected::Other("bad cipher parameters"), &"valid parameters")), - }; - - if raw.cipher_mode == MODE_CBC { - try!(raw_cipher.set_padding(padding).map_err(|_| de::Error::invalid_value(Unexpected::Other("bad padding mode"), &"valid mode"))); - } - - unsafe { - let cipher_context = &mut raw_cipher.inner; - - match (raw.cipher_id, raw.algorithm_ctx) { - (CIPHER_ID_AES, AlgorithmContext::Aes(Bytes(aes_ctx))) => { - let ret_aes_ctx = cipher_context.cipher_ctx as *mut aes_context; - *ret_aes_ctx = aes_ctx; - // aes_ctx.rk needs to be a pointer to aes_ctx.buf, which holds the round keys. - // We don't adjust for the padding needed on VIA Padlock (see definition of - // mbedtls_aes_context in the mbedTLS source). - (*ret_aes_ctx).rk = &mut (*ret_aes_ctx).buf[0]; - } - (CIPHER_ID_DES, AlgorithmContext::Des(Bytes(des_ctx))) => { - *(cipher_context.cipher_ctx as *mut des_context) = des_ctx - } - (CIPHER_ID_3DES, AlgorithmContext::Des3(Bytes(des3_ctx))) => { - *(cipher_context.cipher_ctx as *mut des3_context) = des3_ctx - } - _ => { - return Err(de::Error::invalid_value(Unexpected::Other("bad algorithm"), &"valid algorithm")); - } - }; - - cipher_context.key_bitlen = raw.context.0.key_bitlen; - cipher_context.operation = raw.context.0.operation; - cipher_context.unprocessed_data = raw.context.0.unprocessed_data; - cipher_context.unprocessed_len = raw.context.0.unprocessed_len; - cipher_context.iv = raw.context.0.iv; - cipher_context.iv_size = raw.context.0.iv_size; - } - - Ok(Cipher { - raw_cipher: raw_cipher, - padding: padding, - _op: PhantomData, - _type: PhantomData, - _state: PhantomData, - }) - } + fn deserialize(d: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let saved_cipher: SavedCipher = try!(SavedCipher::deserialize(d)); + + let (raw, padding) = match saved_cipher { + SavedCipher::Encryption(..) if !Op::is_encrypt() => { + return Err(de::Error::invalid_value( + Unexpected::Other("incorrect cipher operation"), + &"encryption", + )); + } + SavedCipher::Decryption(..) if Op::is_encrypt() => { + return Err(de::Error::invalid_value( + Unexpected::Other("incorrect cipher operation"), + &"decryption", + )); + } + SavedCipher::Encryption(raw, padding) | SavedCipher::Decryption(raw, padding) => { + (raw, padding) + } + }; + + let mut raw_cipher = match raw::Cipher::setup( + raw.cipher_id.into(), + raw.cipher_mode.into(), + raw.key_bit_len, + ) { + Ok(raw) => raw, + Err(_) => { + return Err(de::Error::invalid_value( + Unexpected::Other("bad cipher parameters"), + &"valid parameters", + )) + } + }; + + if raw.cipher_mode == MODE_CBC { + try!( + raw_cipher + .set_padding(padding) + .map_err(|_| de::Error::invalid_value( + Unexpected::Other("bad padding mode"), + &"valid mode" + )) + ); + } + + unsafe { + let cipher_context = &mut raw_cipher.inner; + + match (raw.cipher_id, raw.algorithm_ctx) { + (CIPHER_ID_AES, AlgorithmContext::Aes(Bytes(aes_ctx))) => { + let ret_aes_ctx = cipher_context.cipher_ctx as *mut aes_context; + *ret_aes_ctx = aes_ctx; + // aes_ctx.rk needs to be a pointer to aes_ctx.buf, which holds the round keys. + // We don't adjust for the padding needed on VIA Padlock (see definition of + // mbedtls_aes_context in the mbedTLS source). + (*ret_aes_ctx).rk = &mut (*ret_aes_ctx).buf[0]; + } + (CIPHER_ID_DES, AlgorithmContext::Des(Bytes(des_ctx))) => { + *(cipher_context.cipher_ctx as *mut des_context) = des_ctx + } + (CIPHER_ID_3DES, AlgorithmContext::Des3(Bytes(des3_ctx))) => { + *(cipher_context.cipher_ctx as *mut des3_context) = des3_ctx + } + _ => { + return Err(de::Error::invalid_value( + Unexpected::Other("bad algorithm"), + &"valid algorithm", + )); + } + }; + + cipher_context.key_bitlen = raw.context.0.key_bitlen; + cipher_context.operation = raw.context.0.operation; + cipher_context.unprocessed_data = raw.context.0.unprocessed_data; + cipher_context.unprocessed_len = raw.context.0.unprocessed_len; + cipher_context.iv = raw.context.0.iv; + cipher_context.iv_size = raw.context.0.iv_size; + } + + Ok(Cipher { + raw_cipher: raw_cipher, + padding: padding, + _op: PhantomData, + _type: PhantomData, + _state: PhantomData, + }) + } } // Serialization support for raw cipher structs. Custom serialization as a sequence to save the // space of encoding all the member names. impl Serialize for SavedRawCipher { - fn serialize(&self, s: S) -> Result - where S: Serializer - { - let mut seq = try!(s.serialize_seq(Some(5))); - try!(seq.serialize_element(&self.cipher_id)); - try!(seq.serialize_element(&self.cipher_mode)); - try!(seq.serialize_element(&self.key_bit_len)); - try!(seq.serialize_element(&self.context)); - try!(seq.serialize_element(&self.algorithm_ctx)); - seq.end() - } + fn serialize(&self, s: S) -> Result + where + S: Serializer, + { + let mut seq = try!(s.serialize_seq(Some(5))); + try!(seq.serialize_element(&self.cipher_id)); + try!(seq.serialize_element(&self.cipher_mode)); + try!(seq.serialize_element(&self.key_bit_len)); + try!(seq.serialize_element(&self.context)); + try!(seq.serialize_element(&self.algorithm_ctx)); + seq.end() + } } // Byte block serialization support @@ -195,57 +233,62 @@ impl Serialize for SavedRawCipher { // integer, which uses two bytes except for most values.) unsafe trait BytesSerde: Sized { - fn read_slice(s: &[u8]) -> Option { - unsafe { - if s.len() == size_of::() { - Some(ptr::read(s.as_ptr() as *const Self)) - } else { - None - } - } - } - - fn as_slice(&self) -> &[u8] { - unsafe { from_raw_parts(self as *const Self as *const u8, size_of::()) } - } + fn read_slice(s: &[u8]) -> Option { + unsafe { + if s.len() == size_of::() { + Some(ptr::read(s.as_ptr() as *const Self)) + } else { + None + } + } + } + + fn as_slice(&self) -> &[u8] { + unsafe { from_raw_parts(self as *const Self as *const u8, size_of::()) } + } } impl Serialize for Bytes { - fn serialize(&self, s: S) -> Result - where S: Serializer - { - s.serialize_bytes(self.0.as_slice()) - } + fn serialize(&self, s: S) -> Result + where + S: Serializer, + { + s.serialize_bytes(self.0.as_slice()) + } } - impl<'de, T: BytesSerde> Deserialize<'de> for Bytes { - fn deserialize(d: D) -> Result, D::Error> - where D: Deserializer<'de> - { - struct BytesVisitor(PhantomData); - impl<'de, T: BytesSerde> de::Visitor<'de> for BytesVisitor { - type Value = Bytes; - - fn visit_bytes(self, v: &[u8]) -> Result - where E: serde::de::Error - { - T::read_slice(v).map(Bytes).ok_or_else(|| E::invalid_length(v.len(), &self)) - } - - fn visit_byte_buf(self, v: Vec) -> Result - where E: serde::de::Error - { - self.visit_bytes(&v) - } - - fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", size_of::()) - } - } - - d.deserialize_bytes(BytesVisitor(PhantomData)) - } + fn deserialize(d: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + struct BytesVisitor(PhantomData); + impl<'de, T: BytesSerde> de::Visitor<'de> for BytesVisitor { + type Value = Bytes; + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: serde::de::Error, + { + T::read_slice(v) + .map(Bytes) + .ok_or_else(|| E::invalid_length(v.len(), &self)) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where + E: serde::de::Error, + { + self.visit_bytes(&v) + } + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", size_of::()) + } + } + + d.deserialize_bytes(BytesVisitor(PhantomData)) + } } unsafe impl BytesSerde for cipher_context_t {} @@ -256,17 +299,17 @@ unsafe impl BytesSerde for des3_context {} // If the C API changes, the serde implementation needs to be reviewed for correctness. unsafe fn _check_cipher_context_t_size(ctx: cipher_context_t) -> [u8; 88] { - ::core::mem::transmute(ctx) + ::core::mem::transmute(ctx) } unsafe fn _check_aes_context_size(ctx: aes_context) -> [u8; 288] { - ::core::mem::transmute(ctx) + ::core::mem::transmute(ctx) } unsafe fn _check_des_context_size(ctx: des_context) -> [u8; 128] { - ::core::mem::transmute(ctx) + ::core::mem::transmute(ctx) } unsafe fn _check_des3_context_size(ctx: des3_context) -> [u8; 384] { - ::core::mem::transmute(ctx) + ::core::mem::transmute(ctx) } diff --git a/mbedtls/src/error.rs b/mbedtls/src/error.rs index 1d3934f26..b9d4ac426 100644 --- a/mbedtls/src/error.rs +++ b/mbedtls/src/error.rs @@ -1,14 +1,14 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ -use core::str::Utf8Error; use core::fmt; -#[cfg(feature="std")] +use core::str::Utf8Error; +#[cfg(feature = "std")] use std::error::Error as StdError; use mbedtls_sys::types::raw_types::c_int; @@ -16,10 +16,10 @@ use mbedtls_sys::types::raw_types::c_int; pub type Result = ::core::result::Result; pub trait IntoResult: Sized { - fn into_result(self) -> Result; - fn into_result_discard(self) -> Result<()> { - self.into_result().map(|_|()) - } + fn into_result(self) -> Result; + fn into_result_discard(self) -> Result<()> { + self.into_result().map(|_| ()) + } } // This is intended not to overlap with mbedtls error codes. Utf8Error is @@ -48,7 +48,7 @@ macro_rules! error_enum { Err($n::from_mbedtls_code(if high_level_code > 0 { -high_level_code } else { -low_level_code })) } } - + impl $n { pub fn from_mbedtls_code(code: c_int) -> Self { match code { @@ -77,27 +77,29 @@ macro_rules! error_enum { } impl From for Error { - fn from(e: Utf8Error) -> Error { - Error::Utf8Error(Some(e)) - } + fn from(e: Utf8Error) -> Error { + Error::Utf8Error(Some(e)) + } } impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - &Error::Utf8Error(Some(ref e)) => f.write_fmt(format_args!("Error converting to UTF-8: {}",e)), - &Error::Utf8Error(None) => f.write_fmt(format_args!("Error converting to UTF-8")), - &Error::Other(i) => f.write_fmt(format_args!("mbedTLS unknown error ({})",i)), - e @ _ => f.write_fmt(format_args!("mbedTLS error {:?}",e)), - } - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + &Error::Utf8Error(Some(ref e)) => { + f.write_fmt(format_args!("Error converting to UTF-8: {}", e)) + } + &Error::Utf8Error(None) => f.write_fmt(format_args!("Error converting to UTF-8")), + &Error::Other(i) => f.write_fmt(format_args!("mbedTLS unknown error ({})", i)), + e @ _ => f.write_fmt(format_args!("mbedTLS error {:?}", e)), + } + } } -#[cfg(feature="std")] +#[cfg(feature = "std")] impl StdError for Error { - fn description(&self) -> &str { - self.as_str() - } + fn description(&self) -> &str { + self.as_str() + } } error_enum!(Error { diff --git a/mbedtls/src/hash/mod.rs b/mbedtls/src/hash/mod.rs index cd1523952..ca36cd7ac 100644 --- a/mbedtls/src/hash/mod.rs +++ b/mbedtls/src/hash/mod.rs @@ -1,13 +1,13 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ -use mbedtls_sys::*; use error::IntoResult; +use mbedtls_sys::*; define!(enum Type -> md_type_t { None => MD_NONE, @@ -23,38 +23,38 @@ define!(enum Type -> md_type_t { }); impl From for Type { - fn from(inner: md_type_t) -> Type { - match inner { - MD_NONE => Type::None, - MD_MD2 => Type::Md2, - MD_MD4 => Type::Md4, - MD_MD5 => Type::Md5, - MD_SHA1 => Type::Sha1, - MD_SHA224 => Type::Sha224, - MD_SHA256 => Type::Sha256, - MD_SHA384 => Type::Sha384, - MD_SHA512 => Type::Sha512, - MD_RIPEMD160 => Type::Ripemd, - _ => panic!("Invalid Md type"), - } - } + fn from(inner: md_type_t) -> Type { + match inner { + MD_NONE => Type::None, + MD_MD2 => Type::Md2, + MD_MD4 => Type::Md4, + MD_MD5 => Type::Md5, + MD_SHA1 => Type::Sha1, + MD_SHA224 => Type::Sha224, + MD_SHA256 => Type::Sha256, + MD_SHA384 => Type::Sha384, + MD_SHA512 => Type::Sha512, + MD_RIPEMD160 => Type::Ripemd, + _ => panic!("Invalid Md type"), + } + } } -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] pub struct MdInfo { - inner: &'static md_info_t, + inner: &'static md_info_t, } impl Into> for Type { - fn into(self) -> Option { - unsafe { md_info_from_type(self.into()).as_ref() }.map(|r| MdInfo { inner: r }) - } + fn into(self) -> Option { + unsafe { md_info_from_type(self.into()).as_ref() }.map(|r| MdInfo { inner: r }) + } } impl Into<*const md_info_t> for MdInfo { - fn into(self) -> *const md_info_t { - self.inner - } + fn into(self) -> *const md_info_t { + self.inner + } } define!(struct Md(md_context_t) { @@ -64,90 +64,121 @@ define!(struct Md(md_context_t) { }); impl MdInfo { - pub fn size(&self) -> usize { - unsafe { ::mbedtls_sys::md_get_size(self.inner).into() } - } - pub fn get_type(&self) -> Type { - unsafe { ::mbedtls_sys::md_get_type(self.inner).into() } - } + pub fn size(&self) -> usize { + unsafe { ::mbedtls_sys::md_get_size(self.inner).into() } + } + pub fn get_type(&self) -> Type { + unsafe { ::mbedtls_sys::md_get_type(self.inner).into() } + } } impl Md { - pub fn new(md: Type) -> ::Result { - let md: MdInfo = match md.into() { - Some(md) => md, - None => return Err(::Error::MdBadInputData), - }; - - let mut ctx = Md::init(); - unsafe { - try!(md_setup(&mut ctx.inner,md.into(),0).into_result()); - try!(md_starts(&mut ctx.inner).into_result()); - } - Ok(ctx) - } - - pub fn update(&mut self, data: &[u8]) -> ::Result<()> { - unsafe { - try!(::mbedtls_sys::md_update(&mut self.inner,data.as_ptr(),data.len()).into_result()); - } - Ok(()) - } - - pub fn finish(mut self, out: &mut [u8]) -> ::Result { - unsafe { - let olen = (*self.inner.md_info).size as usize; - if out.len() < olen { - return Err(::Error::MdBadInputData); - } - try!(::mbedtls_sys::md_finish(&mut self.inner,out.as_mut_ptr()).into_result()); - Ok(olen) - } - } - - pub fn hash(md: Type, data: &[u8], out: &mut [u8]) -> ::Result { - let md: MdInfo = match md.into() { - Some(md) => md, - None => return Err(::Error::MdBadInputData), - }; - - unsafe { - let olen = md.inner.size as usize; - if out.len() < olen { - return Err(::Error::MdBadInputData); - } - try!(::mbedtls_sys::md(md.inner,data.as_ptr(),data.len(),out.as_mut_ptr()).into_result()); - Ok(olen) - } - } - - pub fn hmac(md: Type, key: &[u8], data: &[u8], out: &mut [u8]) -> ::Result { - let md: MdInfo = match md.into() { - Some(md) => md, - None => return Err(::Error::MdBadInputData), - }; - - unsafe { - let olen = md.inner.size as usize; - if out.len() < olen { - return Err(::Error::MdBadInputData); - } - try!(::mbedtls_sys::md_hmac(md.inner,key.as_ptr(),key.len(),data.as_ptr(),data.len(),out.as_mut_ptr()).into_result()); - Ok(olen) - } - } + pub fn new(md: Type) -> ::Result { + let md: MdInfo = match md.into() { + Some(md) => md, + None => return Err(::Error::MdBadInputData), + }; + + let mut ctx = Md::init(); + unsafe { + try!(md_setup(&mut ctx.inner, md.into(), 0).into_result()); + try!(md_starts(&mut ctx.inner).into_result()); + } + Ok(ctx) + } + + pub fn update(&mut self, data: &[u8]) -> ::Result<()> { + unsafe { + try!( + ::mbedtls_sys::md_update(&mut self.inner, data.as_ptr(), data.len()).into_result() + ); + } + Ok(()) + } + + pub fn finish(mut self, out: &mut [u8]) -> ::Result { + unsafe { + let olen = (*self.inner.md_info).size as usize; + if out.len() < olen { + return Err(::Error::MdBadInputData); + } + try!(::mbedtls_sys::md_finish(&mut self.inner, out.as_mut_ptr()).into_result()); + Ok(olen) + } + } + + pub fn hash(md: Type, data: &[u8], out: &mut [u8]) -> ::Result { + let md: MdInfo = match md.into() { + Some(md) => md, + None => return Err(::Error::MdBadInputData), + }; + + unsafe { + let olen = md.inner.size as usize; + if out.len() < olen { + return Err(::Error::MdBadInputData); + } + try!( + ::mbedtls_sys::md(md.inner, data.as_ptr(), data.len(), out.as_mut_ptr()) + .into_result() + ); + Ok(olen) + } + } + + pub fn hmac(md: Type, key: &[u8], data: &[u8], out: &mut [u8]) -> ::Result { + let md: MdInfo = match md.into() { + Some(md) => md, + None => return Err(::Error::MdBadInputData), + }; + + unsafe { + let olen = md.inner.size as usize; + if out.len() < olen { + return Err(::Error::MdBadInputData); + } + try!( + ::mbedtls_sys::md_hmac( + md.inner, + key.as_ptr(), + key.len(), + data.as_ptr(), + data.len(), + out.as_mut_ptr() + ).into_result() + ); + Ok(olen) + } + } } -pub fn pbkdf2_hmac(md: Type, password: &[u8], salt: &[u8], iterations: u32, key: &mut [u8]) -> ::Result<()> { - let md: MdInfo = match md.into() { - Some(md) => md, - None => return Err(::Error::MdBadInputData), - }; - - unsafe { - let mut ctx = Md::init(); - try!(md_setup((&mut ctx).into(),md.into(),1).into_result()); - try!(pkcs5_pbkdf2_hmac((&mut ctx).into(),password.as_ptr(),password.len(),salt.as_ptr(),salt.len(),iterations,key.len() as u32,key.as_mut_ptr()).into_result()); - Ok(()) - } +pub fn pbkdf2_hmac( + md: Type, + password: &[u8], + salt: &[u8], + iterations: u32, + key: &mut [u8], +) -> ::Result<()> { + let md: MdInfo = match md.into() { + Some(md) => md, + None => return Err(::Error::MdBadInputData), + }; + + unsafe { + let mut ctx = Md::init(); + try!(md_setup((&mut ctx).into(), md.into(), 1).into_result()); + try!( + pkcs5_pbkdf2_hmac( + (&mut ctx).into(), + password.as_ptr(), + password.len(), + salt.as_ptr(), + salt.len(), + iterations, + key.len() as u32, + key.as_mut_ptr() + ).into_result() + ); + Ok(()) + } } diff --git a/mbedtls/src/lib.rs b/mbedtls/src/lib.rs index d22deb842..a6930c4e0 100644 --- a/mbedtls/src/lib.rs +++ b/mbedtls/src/lib.rs @@ -1,25 +1,25 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ #![deny(warnings)] -#![cfg_attr(feature="rdrand",feature(asm))] -#![cfg_attr(not(feature="std"),feature(alloc))] -#![cfg_attr(not(feature="std"),no_std)] +#![cfg_attr(feature = "rdrand", feature(asm))] +#![cfg_attr(not(feature = "std"), feature(alloc))] +#![cfg_attr(not(feature = "std"), no_std)] -#[cfg(all(not(feature="std"),not(feature="core_io")))] +#[cfg(all(not(feature = "std"), not(feature = "core_io")))] const ERROR: _MUST_USE_EITHER_STD_OR_CORE_IO_ = (); -#[cfg(feature="std")] +#[cfg(not(feature = "std"))] +extern crate alloc; +#[cfg(feature = "std")] extern crate core; -#[cfg(not(feature="std"))] +#[cfg(not(feature = "std"))] extern crate core_io; -#[cfg(not(feature="std"))] -extern crate alloc; #[macro_use] extern crate bitflags; @@ -39,13 +39,13 @@ mod wrapper_macros; mod bignum; mod error; pub use error::{Error, Result}; +pub mod cipher; pub mod hash; pub mod pk; pub mod rng; +pub mod self_test; pub mod ssl; pub mod x509; -pub mod cipher; -pub mod self_test; // ============== // Utility @@ -53,40 +53,40 @@ pub mod self_test; mod private; // needs to be pub for global visiblity -#[cfg(feature="spin_threading")] +#[cfg(feature = "spin_threading")] #[doc(hidden)] pub mod threading; // needs to be pub for global visiblity -#[cfg(all(feature="std",not(target_os="none")))] +#[cfg(all(feature = "std", not(target_os = "none")))] #[doc(hidden)] #[no_mangle] pub unsafe extern "C" fn mbedtls_log(msg: *const std::os::raw::c_char) { - print!("{}",std::ffi::CStr::from_ptr(msg).to_string_lossy()); + print!("{}", std::ffi::CStr::from_ptr(msg).to_string_lossy()); } // needs to be pub for global visiblity -#[cfg(feature="force_aesni_support")] +#[cfg(feature = "force_aesni_support")] #[doc(hidden)] #[no_mangle] pub extern "C" fn mbedtls_aesni_has_support(_what: u32) -> i32 { - return 1; + return 1; } #[cfg(test)] -#[path="../tests/support/mod.rs"] +#[path = "../tests/support/mod.rs"] mod test_support; #[cfg(test)] mod mbedtls { - pub use super::*; + pub use super::*; } -#[cfg(not(feature="std"))] +#[cfg(not(feature = "std"))] mod alloc_prelude { - #![allow(unused)] - pub(crate) use alloc::borrow::ToOwned; - pub(crate) use alloc::boxed::Box; - pub(crate) use alloc::string::String; - pub(crate) use alloc::string::ToString; - pub(crate) use alloc::vec::Vec; + #![allow(unused)] + pub(crate) use alloc::borrow::ToOwned; + pub(crate) use alloc::boxed::Box; + pub(crate) use alloc::string::String; + pub(crate) use alloc::string::ToString; + pub(crate) use alloc::vec::Vec; } diff --git a/mbedtls/src/pk/dhparam.rs b/mbedtls/src/pk/dhparam.rs index f2fa12a4a..18d75875f 100644 --- a/mbedtls/src/pk/dhparam.rs +++ b/mbedtls/src/pk/dhparam.rs @@ -1,13 +1,13 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ -use mbedtls_sys::*; use error::IntoResult; +use mbedtls_sys::*; define!(#[repr(C)] struct Dhm(dhm_context) { @@ -17,12 +17,12 @@ struct Dhm(dhm_context) { }); impl Dhm { - /// Takes both DER and PEM forms of FFDH parameters in `DHParams` format. - /// - /// When calling on PEM-encoded data, `params` must be NULL-terminated - pub(crate) fn from_params(params: &[u8]) -> ::Result { - let mut ret = Self::init(); - unsafe { try!(dhm_parse_dhm(&mut ret.inner,params.as_ptr(),params.len()).into_result()) }; - Ok(ret) - } + /// Takes both DER and PEM forms of FFDH parameters in `DHParams` format. + /// + /// When calling on PEM-encoded data, `params` must be NULL-terminated + pub(crate) fn from_params(params: &[u8]) -> ::Result { + let mut ret = Self::init(); + unsafe { try!(dhm_parse_dhm(&mut ret.inner, params.as_ptr(), params.len()).into_result()) }; + Ok(ret) + } } diff --git a/mbedtls/src/pk/ec.rs b/mbedtls/src/pk/ec.rs index 4ec8d980e..8e865c22d 100644 --- a/mbedtls/src/pk/ec.rs +++ b/mbedtls/src/pk/ec.rs @@ -1,13 +1,13 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ -use mbedtls_sys::*; use mbedtls_sys::ECDSA_MAX_LEN as MBEDTLS_ECDSA_MAX_LEN; +use mbedtls_sys::*; use error::IntoResult; @@ -28,24 +28,24 @@ define!(enum EcGroupId -> ecp_group_id { }); impl From for EcGroupId { - fn from(inner: ecp_group_id) -> EcGroupId { - match inner { - ECP_DP_NONE => EcGroupId::None, - ECP_DP_SECP192R1 => EcGroupId::SecP192R1, - ECP_DP_SECP224R1 => EcGroupId::SecP224R1, - ECP_DP_SECP256R1 => EcGroupId::SecP256R1, - ECP_DP_SECP384R1 => EcGroupId::SecP384R1, - ECP_DP_SECP521R1 => EcGroupId::SecP521R1, - ECP_DP_BP256R1 => EcGroupId::Bp256R1, - ECP_DP_BP384R1 => EcGroupId::Bp384R1, - ECP_DP_BP512R1 => EcGroupId::Bp512R1, - ECP_DP_CURVE25519 => EcGroupId::Curve25519, - ECP_DP_SECP192K1 => EcGroupId::SecP192K1, - ECP_DP_SECP224K1 => EcGroupId::SecP224K1, - ECP_DP_SECP256K1 => EcGroupId::SecP256K1, - _ => panic!("Invalid EC group ID"), - } - } + fn from(inner: ecp_group_id) -> EcGroupId { + match inner { + ECP_DP_NONE => EcGroupId::None, + ECP_DP_SECP192R1 => EcGroupId::SecP192R1, + ECP_DP_SECP224R1 => EcGroupId::SecP224R1, + ECP_DP_SECP256R1 => EcGroupId::SecP256R1, + ECP_DP_SECP384R1 => EcGroupId::SecP384R1, + ECP_DP_SECP521R1 => EcGroupId::SecP521R1, + ECP_DP_BP256R1 => EcGroupId::Bp256R1, + ECP_DP_BP384R1 => EcGroupId::Bp384R1, + ECP_DP_BP512R1 => EcGroupId::Bp512R1, + ECP_DP_CURVE25519 => EcGroupId::Curve25519, + ECP_DP_SECP192K1 => EcGroupId::SecP192K1, + ECP_DP_SECP224K1 => EcGroupId::SecP224K1, + ECP_DP_SECP256K1 => EcGroupId::SecP256K1, + _ => panic!("Invalid EC group ID"), + } + } } /// Maximum size of an elliptic curve signature generated by `sign`, and the minimum @@ -68,56 +68,72 @@ struct Ecdh(ecdh_context) { }); impl Ecdh { - pub fn from_keys(private: &EcpKeypair, public: &EcpKeypair) -> ::Result { - if public.inner.grp.id == ECP_DP_NONE || public.inner.grp.id != private.inner.grp.id { - return Err(::Error::EcpBadInputData); - } + pub fn from_keys(private: &EcpKeypair, public: &EcpKeypair) -> ::Result { + if public.inner.grp.id == ECP_DP_NONE || public.inner.grp.id != private.inner.grp.id { + return Err(::Error::EcpBadInputData); + } - let mut ret = Self::init(); - unsafe { - ecp_group_copy(&mut ret.inner.grp, &private.inner.grp).into_result()?; - mpi_copy(&mut ret.inner.d, &private.inner.d).into_result()?; - ecp_copy(&mut ret.inner.Qp, &public.inner.Q).into_result()?; - } - Ok(ret) - } + let mut ret = Self::init(); + unsafe { + ecp_group_copy(&mut ret.inner.grp, &private.inner.grp).into_result()?; + mpi_copy(&mut ret.inner.d, &private.inner.d).into_result()?; + ecp_copy(&mut ret.inner.Qp, &public.inner.Q).into_result()?; + } + Ok(ret) + } - pub fn calc_secret(&mut self, shared: &mut [u8], rng: &mut F) -> ::Result { - let mut olen = 0; - unsafe { ecdh_calc_secret(&mut self.inner, &mut olen, shared.as_mut_ptr(), shared.len(), Some(F::call), rng.data_ptr()).into_result()? }; - Ok(olen) - } + pub fn calc_secret( + &mut self, + shared: &mut [u8], + rng: &mut F, + ) -> ::Result { + let mut olen = 0; + unsafe { + ecdh_calc_secret( + &mut self.inner, + &mut olen, + shared.as_mut_ptr(), + shared.len(), + Some(F::call), + rng.data_ptr(), + ).into_result()? + }; + Ok(olen) + } } #[cfg(test)] mod tests { - use pk::Pk; + use pk::Pk; - #[test] - fn p192_dh() { - // From NIST CAVS 14.1, ECC CDH Primitive (SP800-56A Section 5.7.1.2), - // Generated on Mon Nov 19 10:52:17 2012. Curve P-192, test vector - // number 0. - const PRIVATE_P192: &'static [u8] = b"-----BEGIN PRIVATE KEY----- + #[test] + fn p192_dh() { + // From NIST CAVS 14.1, ECC CDH Primitive (SP800-56A Section 5.7.1.2), + // Generated on Mon Nov 19 10:52:17 2012. Curve P-192, test vector + // number 0. + const PRIVATE_P192: &'static [u8] = b"-----BEGIN PRIVATE KEY----- MG8CAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQEEVTBTAgEBBBjxfT/qNnt000CFHKQn DcskwnH0Rb7Z1SehNAMyAASxUFNAH1coVjfsMkwc0hOeOmfeNzkjSzfyacFYY3SC qtZEzWkt0dPvLIp8SeOJ9/Y= -----END PRIVATE KEY-----\0"; - const PUBLIC_P192: &'static [u8] = b"-----BEGIN PUBLIC KEY----- + const PUBLIC_P192: &'static [u8] = b"-----BEGIN PUBLIC KEY----- MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEQupt2Zad0qYf6hqsf46Y7cyJbG5V hXzA375dfGH6yIsRgRveMo6KDRK/AanSBLUj -----END PUBLIC KEY-----\0"; - const DH_P192: &'static [u8] = &[0x80, 0x3d, 0x8a, 0xb2, 0xe5, 0xb6, - 0xe6, 0xfc, 0xa7, 0x15, 0x73, 0x7c, 0x3a, 0x82, 0xf7, 0xce, 0x3c, - 0x78, 0x31, 0x24, 0xf6, 0xd5, 0x1c, 0xd0]; + const DH_P192: &'static [u8] = &[ + 0x80, 0x3d, 0x8a, 0xb2, 0xe5, 0xb6, 0xe6, 0xfc, 0xa7, 0x15, 0x73, 0x7c, 0x3a, 0x82, + 0xf7, 0xce, 0x3c, 0x78, 0x31, 0x24, 0xf6, 0xd5, 0x1c, 0xd0, + ]; - let mut k_pr = Pk::from_private_key(PRIVATE_P192, None).unwrap(); - let k_pb = Pk::from_public_key(PUBLIC_P192).unwrap(); - let mut out = [0; 192/8]; - let len = k_pr.agree(&k_pb, &mut out, &mut ::test_support::rand::test_rng()).unwrap(); - assert_eq!(len, DH_P192.len()); - assert_eq!(out, DH_P192); - } + let mut k_pr = Pk::from_private_key(PRIVATE_P192, None).unwrap(); + let k_pb = Pk::from_public_key(PUBLIC_P192).unwrap(); + let mut out = [0; 192 / 8]; + let len = k_pr + .agree(&k_pb, &mut out, &mut ::test_support::rand::test_rng()) + .unwrap(); + assert_eq!(len, DH_P192.len()); + assert_eq!(out, DH_P192); + } } diff --git a/mbedtls/src/pk/mod.rs b/mbedtls/src/pk/mod.rs index ceb5797b7..c2939b494 100644 --- a/mbedtls/src/pk/mod.rs +++ b/mbedtls/src/pk/mod.rs @@ -1,20 +1,20 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ -#[cfg(not(feature="std"))] +#[cfg(not(feature = "std"))] use alloc_prelude::*; use mbedtls_sys::*; use error::IntoResult; use private::UnsafeFrom; -mod ec; pub(crate) mod dhparam; +mod ec; #[doc(inline)] pub use self::ec::{EcGroupId, ECDSA_MAX_LEN}; @@ -31,33 +31,31 @@ define!(enum Type -> pk_type_t { }); impl From for Type { - fn from(inner: pk_type_t) -> Type { - match inner { - PK_NONE => Type::None, - PK_RSA => Type::Rsa, - PK_ECKEY => Type::Eckey, - PK_ECKEY_DH => Type::EckeyDh, - PK_ECDSA => Type::Ecdsa, - PK_RSA_ALT => Type::RsaAlt, - PK_RSASSA_PSS => Type::RsassaPss, - _ => panic!("Invalid PK type"), - } - } + fn from(inner: pk_type_t) -> Type { + match inner { + PK_NONE => Type::None, + PK_RSA => Type::Rsa, + PK_ECKEY => Type::Eckey, + PK_ECKEY_DH => Type::EckeyDh, + PK_ECDSA => Type::Ecdsa, + PK_RSA_ALT => Type::RsaAlt, + PK_RSASSA_PSS => Type::RsassaPss, + _ => panic!("Invalid PK type"), + } + } } pub enum RsaPadding { - Pkcs1V15, - /// Use OAEP for encryption, or PSS for signing. - Pkcs1V21 { - /// The Mask Generating Function (MGF) to use. - mgf: ::hash::Type - } + Pkcs1V15, + /// Use OAEP for encryption, or PSS for signing. + Pkcs1V21 { + /// The Mask Generating Function (MGF) to use. + mgf: ::hash::Type, + }, } pub enum Options { - Rsa { - padding: RsaPadding - } + Rsa { padding: RsaPadding }, } define!(#[repr(C)] @@ -69,134 +67,165 @@ struct Pk(pk_context) { }); impl Pk { - /// Takes both DER and PEM forms of PKCS#1 or PKCS#8 encoded keys. - /// - /// When calling on PEM-encoded data, `key` must be NULL-terminated - pub fn from_private_key(key: &[u8], password: Option<&[u8]>) -> ::Result { - let mut ret = Self::init(); - unsafe { - try!(pk_parse_key( - &mut ret.inner, - key.as_ptr(), - key.len(), - password.map(<[_]>::as_ptr).unwrap_or(::core::ptr::null()), - password.map(<[_]>::len).unwrap_or(0) - ).into_result()) - }; - Ok(ret) - } - - /// Takes both DER and PEM encoded SubjectPublicKeyInfo keys. - /// - /// When calling on PEM-encoded data, `key` must be NULL-terminated - pub fn from_public_key(key: &[u8]) -> ::Result { - let mut ret = Self::init(); - unsafe { try!(pk_parse_public_key(&mut ret.inner,key.as_ptr(),key.len()).into_result()) }; - Ok(ret) - } - - pub fn generate_rsa(rng: &mut F, bits: u32, exponent: u32) -> ::Result { - let mut ret = Self::init(); - unsafe { - try!(pk_setup(&mut ret.inner,pk_info_from_type(Type::Rsa.into())).into_result()); - try!(rsa_gen_key(ret.inner.pk_ctx as *mut _,Some(F::call),rng.data_ptr(),bits,exponent as _).into_result()); - } - Ok(ret) - } - - pub fn generate_ec(rng: &mut F, curve: EcGroupId) -> ::Result { - let mut ret = Self::init(); - unsafe { - try!(pk_setup(&mut ret.inner, pk_info_from_type(Type::Eckey.into())).into_result()); - try!(ecp_gen_key(curve.into(), ret.inner.pk_ctx as *mut _, Some(F::call), rng.data_ptr()).into_result()); - } - Ok(ret) - } - - /// Panics if the options are not valid for this key type. - pub fn set_options(&mut self, options: Options) { - unsafe { - match (Type::from(pk_get_type(&self.inner)), options) { - (Type::Rsa, Options::Rsa { padding }) | - (Type::RsassaPss, Options::Rsa { padding }) => { - let (padding, hash_id) = match padding { - RsaPadding::Pkcs1V15 => (RSA_PKCS_V15, 0), - RsaPadding::Pkcs1V21 { mgf } => (RSA_PKCS_V21, mgf.into()), - }; - rsa_set_padding(self.inner.pk_ctx as *mut rsa_context, padding, hash_id as _); - }, - _ => panic!("Invalid options for this key type") - } - } - } - - pub fn can_do(&self, t: Type) -> bool { - if unsafe { pk_can_do(&self.inner, t.into()) } == 0 { - false - } else { - true - } - } - - pub fn check_pair(public: &Self, private: &Self) -> bool { - unsafe { pk_check_pair(&public.inner, &private.inner) }.into_result().is_ok() - } - - /// Key length in bits - getter!(len() -> usize = fn pk_get_bitlen); - getter!(pk_type() -> Type = fn pk_get_type); - - pub fn curve(&self) -> ::Result { - match self.pk_type() { - Type::Eckey | Type::EckeyDh | Type::Ecdsa => {}, - _ => return Err(::Error::PkTypeMismatch) - } - - unsafe { - Ok((*(self.inner.pk_ctx as *const ecp_keypair)).grp.id.into()) - } - } - - pub fn name(&self) -> ::Result<&str> { - let s = unsafe { ::private::cstr_to_slice(pk_get_name(&self.inner)) }; - Ok(try!(::core::str::from_utf8(s))) - } - - pub fn decrypt(&mut self, cipher: &[u8], plain: &mut [u8], rng: &mut F) -> ::Result { - let mut ret; - unsafe { - ret = ::core::mem::uninitialized(); - try!(pk_decrypt( - &mut self.inner, - cipher.as_ptr(), - cipher.len(), - plain.as_mut_ptr(), - &mut ret, - plain.len(), - Some(F::call), - rng.data_ptr() - ).into_result()); - } - Ok(ret) - } - - pub fn encrypt(&mut self, plain: &[u8], cipher: &mut [u8], rng: &mut F) -> ::Result { - let mut ret; - unsafe { - ret = ::core::mem::uninitialized(); - try!(pk_encrypt( - &mut self.inner, - plain.as_ptr(), - plain.len(), - cipher.as_mut_ptr(), - &mut ret, - cipher.len(), - Some(F::call), - rng.data_ptr() - ).into_result()); - } - Ok(ret) - } + /// Takes both DER and PEM forms of PKCS#1 or PKCS#8 encoded keys. + /// + /// When calling on PEM-encoded data, `key` must be NULL-terminated + pub fn from_private_key(key: &[u8], password: Option<&[u8]>) -> ::Result { + let mut ret = Self::init(); + unsafe { + try!( + pk_parse_key( + &mut ret.inner, + key.as_ptr(), + key.len(), + password.map(<[_]>::as_ptr).unwrap_or(::core::ptr::null()), + password.map(<[_]>::len).unwrap_or(0) + ).into_result() + ) + }; + Ok(ret) + } + + /// Takes both DER and PEM encoded SubjectPublicKeyInfo keys. + /// + /// When calling on PEM-encoded data, `key` must be NULL-terminated + pub fn from_public_key(key: &[u8]) -> ::Result { + let mut ret = Self::init(); + unsafe { try!(pk_parse_public_key(&mut ret.inner, key.as_ptr(), key.len()).into_result()) }; + Ok(ret) + } + + pub fn generate_rsa(rng: &mut F, bits: u32, exponent: u32) -> ::Result { + let mut ret = Self::init(); + unsafe { + try!(pk_setup(&mut ret.inner, pk_info_from_type(Type::Rsa.into())).into_result()); + try!( + rsa_gen_key( + ret.inner.pk_ctx as *mut _, + Some(F::call), + rng.data_ptr(), + bits, + exponent as _ + ).into_result() + ); + } + Ok(ret) + } + + pub fn generate_ec(rng: &mut F, curve: EcGroupId) -> ::Result { + let mut ret = Self::init(); + unsafe { + try!(pk_setup(&mut ret.inner, pk_info_from_type(Type::Eckey.into())).into_result()); + try!( + ecp_gen_key( + curve.into(), + ret.inner.pk_ctx as *mut _, + Some(F::call), + rng.data_ptr() + ).into_result() + ); + } + Ok(ret) + } + + /// Panics if the options are not valid for this key type. + pub fn set_options(&mut self, options: Options) { + unsafe { + match (Type::from(pk_get_type(&self.inner)), options) { + (Type::Rsa, Options::Rsa { padding }) + | (Type::RsassaPss, Options::Rsa { padding }) => { + let (padding, hash_id) = match padding { + RsaPadding::Pkcs1V15 => (RSA_PKCS_V15, 0), + RsaPadding::Pkcs1V21 { mgf } => (RSA_PKCS_V21, mgf.into()), + }; + rsa_set_padding(self.inner.pk_ctx as *mut rsa_context, padding, hash_id as _); + } + _ => panic!("Invalid options for this key type"), + } + } + } + + pub fn can_do(&self, t: Type) -> bool { + if unsafe { pk_can_do(&self.inner, t.into()) } == 0 { + false + } else { + true + } + } + + pub fn check_pair(public: &Self, private: &Self) -> bool { + unsafe { pk_check_pair(&public.inner, &private.inner) } + .into_result() + .is_ok() + } + + /// Key length in bits + getter!(len() -> usize = fn pk_get_bitlen); + getter!(pk_type() -> Type = fn pk_get_type); + + pub fn curve(&self) -> ::Result { + match self.pk_type() { + Type::Eckey | Type::EckeyDh | Type::Ecdsa => {} + _ => return Err(::Error::PkTypeMismatch), + } + + unsafe { Ok((*(self.inner.pk_ctx as *const ecp_keypair)).grp.id.into()) } + } + + pub fn name(&self) -> ::Result<&str> { + let s = unsafe { ::private::cstr_to_slice(pk_get_name(&self.inner)) }; + Ok(try!(::core::str::from_utf8(s))) + } + + pub fn decrypt( + &mut self, + cipher: &[u8], + plain: &mut [u8], + rng: &mut F, + ) -> ::Result { + let mut ret; + unsafe { + ret = ::core::mem::uninitialized(); + try!( + pk_decrypt( + &mut self.inner, + cipher.as_ptr(), + cipher.len(), + plain.as_mut_ptr(), + &mut ret, + plain.len(), + Some(F::call), + rng.data_ptr() + ).into_result() + ); + } + Ok(ret) + } + + pub fn encrypt( + &mut self, + plain: &[u8], + cipher: &mut [u8], + rng: &mut F, + ) -> ::Result { + let mut ret; + unsafe { + ret = ::core::mem::uninitialized(); + try!( + pk_encrypt( + &mut self.inner, + plain.as_ptr(), + plain.len(), + cipher.as_mut_ptr(), + &mut ret, + cipher.len(), + Some(F::call), + rng.data_ptr() + ).into_result() + ); + } + Ok(ret) + } /// Sign the hash `hash` of type `md`, placing the signature in `sig`. `rng` must be a /// cryptographically secure RNG. @@ -208,118 +237,152 @@ impl Pk { /// otherwise `sign()` fails with `Error::PkSigLenMismatch`. /// /// On success, returns the actual number of bytes written to `sig`. - pub fn sign(&mut self, md: ::hash::Type, hash: &[u8], sig: &mut [u8], rng: &mut F) -> ::Result { - let mut ret; - match self.pk_type() { - Type::Rsa | Type::RsaAlt | Type::RsassaPss => { - if sig.len() < (self.len() / 8) { - return Err(::Error::PkSigLenMismatch); - } - }, - Type::Eckey | Type::Ecdsa => { - if sig.len() < ECDSA_MAX_LEN { - return Err(::Error::PkSigLenMismatch); - } - }, - _ => return Err(::Error::PkSigLenMismatch), - } - unsafe { - ret = ::core::mem::uninitialized(); - try!(pk_sign( - &mut self.inner, - md.into(), - hash.as_ptr(), - hash.len(), - sig.as_mut_ptr(), - &mut ret, - Some(F::call), - rng.data_ptr() - ).into_result()); - } - Ok(ret) - } - - pub fn verify(&mut self, md: ::hash::Type, hash: &[u8], sig: &[u8]) -> ::Result<()> { - unsafe { - pk_verify(&mut self.inner, md.into(), hash.as_ptr(), hash.len(), sig.as_ptr(), sig.len()) - .into_result() - .map(|_| ()) - } - } - - /// Agree on a shared secret with another public key. - pub fn agree(&mut self, other: &Pk, shared: &mut [u8], rng: &mut F) -> ::Result { - match (self.pk_type(), other.pk_type()) { - (Type::Eckey, Type::Eckey) | - (Type::EckeyDh, Type::Eckey) | - (Type::Eckey, Type::EckeyDh) | - (Type::EckeyDh, Type::EckeyDh) => { - unsafe { - let mut ecdh = ec::Ecdh::from_keys(UnsafeFrom::from(self.inner.pk_ctx as *const _).unwrap(), UnsafeFrom::from(other.inner.pk_ctx as *const _).unwrap())?; - ecdh.calc_secret(shared, rng) - } - } - _ => return Err(::Error::PkTypeMismatch) - } - } - - pub fn write_private_der<'buf>(&mut self, buf: &'buf mut [u8]) -> ::Result> { - match unsafe { pk_write_key_der(&mut self.inner, buf.as_mut_ptr(), buf.len()).into_result() } { - Err(::Error::Asn1BufTooSmall) => Ok(None), - Err(e) => Err(e), - Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), - } - } - - pub fn write_private_der_vec(&mut self) -> ::Result> { - ::private::alloc_vec_repeat(|buf, size| unsafe { pk_write_key_der(&mut self.inner, buf, size) }, true) - } - - pub fn write_private_pem<'buf>(&mut self, buf: &'buf mut [u8]) -> ::Result> { - match unsafe { pk_write_key_pem(&mut self.inner, buf.as_mut_ptr(), buf.len()).into_result() } { - Err(::Error::Base64BufferTooSmall) => Ok(None), - Err(e) => Err(e), - Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), - } - } - - pub fn write_private_pem_string(&mut self) -> ::Result { - ::private::alloc_string_repeat(|buf, size| unsafe { - match pk_write_key_pem(&mut self.inner, buf as _, size) { - 0 => ::private::cstr_to_slice(buf as _).len() as _, - r => r, - } - }) - } - - pub fn write_public_der<'buf>(&mut self, buf: &'buf mut [u8]) -> ::Result> { - match unsafe { pk_write_pubkey_der(&mut self.inner, buf.as_mut_ptr(), buf.len()).into_result() } { - Err(::Error::Asn1BufTooSmall) => Ok(None), - Err(e) => Err(e), - Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), - } - } - - pub fn write_public_der_vec(&mut self) -> ::Result> { - ::private::alloc_vec_repeat(|buf, size| unsafe { pk_write_pubkey_der(&mut self.inner, buf, size) }, true) - } - - pub fn write_public_pem<'buf>(&mut self, buf: &'buf mut [u8]) -> ::Result> { - match unsafe { pk_write_pubkey_pem(&mut self.inner, buf.as_mut_ptr(), buf.len()).into_result() } { - Err(::Error::Base64BufferTooSmall) => Ok(None), - Err(e) => Err(e), - Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), - } - } - - pub fn write_public_pem_string(&mut self) -> ::Result { - ::private::alloc_string_repeat(|buf, size| unsafe { - match pk_write_pubkey_pem(&mut self.inner, buf as _, size) { - 0 => ::private::cstr_to_slice(buf as _).len() as _, - r => r, - } - }) - } + pub fn sign( + &mut self, + md: ::hash::Type, + hash: &[u8], + sig: &mut [u8], + rng: &mut F, + ) -> ::Result { + let mut ret; + match self.pk_type() { + Type::Rsa | Type::RsaAlt | Type::RsassaPss => { + if sig.len() < (self.len() / 8) { + return Err(::Error::PkSigLenMismatch); + } + } + Type::Eckey | Type::Ecdsa => { + if sig.len() < ECDSA_MAX_LEN { + return Err(::Error::PkSigLenMismatch); + } + } + _ => return Err(::Error::PkSigLenMismatch), + } + unsafe { + ret = ::core::mem::uninitialized(); + try!( + pk_sign( + &mut self.inner, + md.into(), + hash.as_ptr(), + hash.len(), + sig.as_mut_ptr(), + &mut ret, + Some(F::call), + rng.data_ptr() + ).into_result() + ); + } + Ok(ret) + } + + pub fn verify(&mut self, md: ::hash::Type, hash: &[u8], sig: &[u8]) -> ::Result<()> { + unsafe { + pk_verify( + &mut self.inner, + md.into(), + hash.as_ptr(), + hash.len(), + sig.as_ptr(), + sig.len(), + ).into_result() + .map(|_| ()) + } + } + + /// Agree on a shared secret with another public key. + pub fn agree( + &mut self, + other: &Pk, + shared: &mut [u8], + rng: &mut F, + ) -> ::Result { + match (self.pk_type(), other.pk_type()) { + (Type::Eckey, Type::Eckey) + | (Type::EckeyDh, Type::Eckey) + | (Type::Eckey, Type::EckeyDh) + | (Type::EckeyDh, Type::EckeyDh) => unsafe { + let mut ecdh = ec::Ecdh::from_keys( + UnsafeFrom::from(self.inner.pk_ctx as *const _).unwrap(), + UnsafeFrom::from(other.inner.pk_ctx as *const _).unwrap(), + )?; + ecdh.calc_secret(shared, rng) + }, + _ => return Err(::Error::PkTypeMismatch), + } + } + + pub fn write_private_der<'buf>(&mut self, buf: &'buf mut [u8]) -> ::Result> { + match unsafe { + pk_write_key_der(&mut self.inner, buf.as_mut_ptr(), buf.len()).into_result() + } { + Err(::Error::Asn1BufTooSmall) => Ok(None), + Err(e) => Err(e), + Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), + } + } + + pub fn write_private_der_vec(&mut self) -> ::Result> { + ::private::alloc_vec_repeat( + |buf, size| unsafe { pk_write_key_der(&mut self.inner, buf, size) }, + true, + ) + } + + pub fn write_private_pem<'buf>(&mut self, buf: &'buf mut [u8]) -> ::Result> { + match unsafe { + pk_write_key_pem(&mut self.inner, buf.as_mut_ptr(), buf.len()).into_result() + } { + Err(::Error::Base64BufferTooSmall) => Ok(None), + Err(e) => Err(e), + Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), + } + } + + pub fn write_private_pem_string(&mut self) -> ::Result { + ::private::alloc_string_repeat(|buf, size| unsafe { + match pk_write_key_pem(&mut self.inner, buf as _, size) { + 0 => ::private::cstr_to_slice(buf as _).len() as _, + r => r, + } + }) + } + + pub fn write_public_der<'buf>(&mut self, buf: &'buf mut [u8]) -> ::Result> { + match unsafe { + pk_write_pubkey_der(&mut self.inner, buf.as_mut_ptr(), buf.len()).into_result() + } { + Err(::Error::Asn1BufTooSmall) => Ok(None), + Err(e) => Err(e), + Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), + } + } + + pub fn write_public_der_vec(&mut self) -> ::Result> { + ::private::alloc_vec_repeat( + |buf, size| unsafe { pk_write_pubkey_der(&mut self.inner, buf, size) }, + true, + ) + } + + pub fn write_public_pem<'buf>(&mut self, buf: &'buf mut [u8]) -> ::Result> { + match unsafe { + pk_write_pubkey_pem(&mut self.inner, buf.as_mut_ptr(), buf.len()).into_result() + } { + Err(::Error::Base64BufferTooSmall) => Ok(None), + Err(e) => Err(e), + Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), + } + } + + pub fn write_public_pem_string(&mut self) -> ::Result { + ::private::alloc_string_repeat(|buf, size| unsafe { + match pk_write_pubkey_pem(&mut self.inner, buf as _, size) { + 0 => ::private::cstr_to_slice(buf as _).len() as _, + r => r, + } + }) + } } // pk_verify_ext @@ -339,9 +402,9 @@ impl Pk { #[cfg(test)] mod tests { - use super::*; + use super::*; -#[cfg_attr(rustfmt,rustfmt_skip)] + #[cfg_attr(rustfmt,rustfmt_skip)] // This is test data that must match library output *exactly* const TEST_PEM: &'static str = "-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAh1aoz6wFwVHaCVDISSy+dZ8rOsJmfYBCrgzUjX+VNb2RwdT8 @@ -372,134 +435,170 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi -----END RSA PRIVATE KEY----- \0"; - const TEST_DER: &'static [u8] = - &[0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0x8d, 0x76, 0xa1, 0x2e, 0xb6, 0xc0, 0xe5, - 0x1e, 0x1a, 0x06, 0x74, 0x13, 0x57, 0x6a, 0xc2, 0x6c, 0x02, 0x9d, 0x82, 0x91, 0x5b, 0xb0, 0xe5, 0xa9, 0x7f, 0xe0, - 0x6d, 0x3f, 0xc0, 0x94, 0x88, 0x8e, 0x72, 0xd4, 0x4a, 0xc1, 0xf5, 0x54, 0x71, 0x63, 0x10, 0xaa, 0xef, 0x9d, 0xa5, - 0x1a, 0xdc, 0x00, 0x82, 0x2d, 0xea, 0x5f, 0x5b, 0xe8, 0x73, 0x6e, 0x03, 0xf8, 0x07, 0x90, 0x8c, 0xd5, 0x52, 0xf5, - 0x6d, 0xfc, 0x4d, 0xe5, 0x6a, 0x87, 0x5a, 0x85, 0xf7, 0x34, 0x85, 0x9a, 0x19, 0x3a, 0x74, 0x46, 0x1e, 0xcb, 0x30, - 0x77, 0x8d, 0x68, 0x8a, 0xb8, 0xfd, 0x6e, 0xbc, 0xee, 0xd2, 0xd0, 0xb3, 0xd0, 0x1c, 0x44, 0x29, 0xd0, 0xd6, 0x91, - 0xb5, 0xa8, 0xc1, 0xe3, 0x88, 0x64, 0x40, 0x16, 0x31, 0x6c, 0xdc, 0x4b, 0xba, 0x69, 0xc3, 0xcd, 0x8d, 0x4a, 0xd8, - 0x7d, 0xf4, 0xa7, 0xe2, 0xe8, 0xc5, 0x01, 0x6f, 0xcc, 0x91, 0x22, 0x81, 0x52, 0x83, 0x11, 0x28, 0xb3, 0x97, 0x1d, - 0x57, 0xa2, 0x2a, 0x01, 0x77, 0x65, 0x87, 0x3e, 0xdc, 0x6c, 0x7f, 0x0a, 0xca, 0x95, 0x04, 0x6a, 0x4e, 0x47, 0xa4, - 0xfb, 0xa1, 0x42, 0x19, 0x0f, 0x80, 0x14, 0xed, 0xf9, 0x4a, 0x42, 0x9c, 0x6f, 0xef, 0x0f, 0x82, 0x51, 0xbb, 0x46, - 0x66, 0xc6, 0xfd, 0xd9, 0x01, 0x93, 0x6d, 0xda, 0x36, 0xc7, 0x58, 0x37, 0x4b, 0xa7, 0xdb, 0xbd, 0xb2, 0x6f, 0x5b, - 0x33, 0x4b, 0x78, 0x70, 0x7e, 0xe8, 0x02, 0xdd, 0x5f, 0xa4, 0x2f, 0xea, 0x3c, 0x6b, 0xfb, 0x51, 0xe1, 0x19, 0x21, - 0x9f, 0x52, 0xd6, 0x29, 0x53, 0x09, 0x98, 0xbc, 0x3e, 0x3b, 0xb3, 0xdc, 0x25, 0x13, 0x36, 0x1b, 0x24, 0xf4, 0x33, - 0xdd, 0xdf, 0xa8, 0xd6, 0xe8, 0x97, 0x11, 0x2f, 0x9a, 0x81, 0xc1, 0xb6, 0xf1, 0x7b, 0xa5, 0xa4, 0x2c, 0xda, 0x41, - 0xb6, 0x11, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x38, 0x98, 0xb9, 0xab, 0xe2, 0xda, 0x11, 0xd0, - 0x95, 0x40, 0xf7, 0xb7, 0xb5, 0x45, 0xb5, 0x3b, 0x59, 0x60, 0x83, 0x18, 0x7c, 0xc2, 0xad, 0x5f, 0xbf, 0x15, 0x9f, - 0x1f, 0xde, 0x80, 0x8e, 0x91, 0xcf, 0x47, 0x38, 0x11, 0x99, 0x81, 0x8b, 0x4b, 0xc3, 0x23, 0x60, 0x72, 0x85, 0xd7, - 0xd5, 0x25, 0x2e, 0xf0, 0x07, 0xd0, 0xd7, 0x08, 0x8d, 0x05, 0xfa, 0xf8, 0x84, 0xae, 0x44, 0x6a, 0x24, 0xa2, 0xa4, - 0xba, 0x48, 0xbf, 0xfc, 0x7a, 0xe2, 0xb0, 0xae, 0x52, 0x89, 0x11, 0x39, 0xfe, 0xb4, 0xfe, 0x48, 0xdb, 0xaa, 0x2c, - 0x6a, 0x9a, 0xe4, 0xc5, 0x56, 0x3f, 0xb3, 0xbf, 0x29, 0x00, 0xee, 0xaf, 0xd8, 0x5f, 0x3d, 0x0b, 0x9c, 0x8c, 0xf7, - 0x4c, 0xe9, 0x25, 0x8b, 0x2f, 0xf0, 0xa3, 0xf0, 0x6a, 0x49, 0x48, 0xd2, 0xef, 0xf5, 0xb2, 0x8b, 0x50, 0xe2, 0x84, - 0xa2, 0x19, 0x79, 0x22, 0xff, 0x8e, 0x16, 0xbe, 0x00, 0x70, 0xc4, 0x6d, 0xd0, 0x29, 0x54, 0x28, 0x99, 0x97, 0x84, - 0xc9, 0xaf, 0xd8, 0xb6, 0xb1, 0x44, 0x6d, 0x4a, 0x74, 0x82, 0x4e, 0xde, 0x44, 0x1c, 0x47, 0x11, 0x52, 0x86, 0x48, - 0xd7, 0x78, 0x52, 0xa9, 0x98, 0x20, 0x9d, 0x83, 0x39, 0x3d, 0xe5, 0xd6, 0xed, 0x94, 0x6a, 0x67, 0xd0, 0x65, 0x23, - 0xf6, 0xdd, 0xe1, 0xe3, 0xed, 0xe9, 0x6b, 0x85, 0xcb, 0x91, 0x0b, 0xcd, 0xc4, 0x6b, 0xe4, 0x90, 0xd4, 0xeb, 0x7b, - 0x80, 0x0b, 0x67, 0x9d, 0xb5, 0x37, 0x0b, 0x83, 0x7d, 0x79, 0x45, 0x6b, 0x60, 0x7d, 0x6f, 0xe3, 0xe0, 0x5e, 0x92, - 0xf6, 0x13, 0x67, 0xd2, 0xd4, 0xdc, 0x43, 0x5f, 0xd8, 0xee, 0xf5, 0x28, 0x05, 0x64, 0x78, 0x6a, 0x6f, 0xaf, 0xef, - 0x64, 0x52, 0x93, 0x70, 0x4f, 0x9a, 0xab, 0xce, 0x4a, 0x51, 0x63, 0x2a, 0xf1, 0x33, 0xfd, 0xd8, 0x1e, 0xf9, 0xef, - 0xf1, 0x02, 0x81, 0x81, 0x00, 0xcf, 0xa7, 0x89, 0x75, 0xdd, 0x09, 0x66, 0x8b, 0x4e, 0xda, 0x52, 0x38, 0x4a, 0xc3, - 0x7c, 0xca, 0x90, 0x68, 0x4a, 0xbb, 0x78, 0x14, 0xc1, 0x83, 0x24, 0xb2, 0x2e, 0x39, 0x20, 0x8a, 0x00, 0x97, 0x8d, - 0xf3, 0x21, 0x5a, 0xad, 0x03, 0xc7, 0xb2, 0xe9, 0x17, 0x10, 0x85, 0x63, 0x23, 0xe3, 0xc9, 0x73, 0x91, 0xa8, 0x5a, - 0x8d, 0xb6, 0x40, 0x0f, 0x98, 0xb8, 0x2a, 0x8f, 0x7e, 0x59, 0x80, 0x8a, 0xee, 0xb9, 0xe9, 0x9b, 0x2e, 0x83, 0xd4, - 0x85, 0xc1, 0xdc, 0x1e, 0xc9, 0x44, 0x48, 0x2a, 0x13, 0x06, 0x09, 0x02, 0x3e, 0x3f, 0xfb, 0xf2, 0xe8, 0x1a, 0x2d, - 0xec, 0x40, 0xea, 0x0e, 0x2b, 0x7f, 0xf3, 0x79, 0xdc, 0x11, 0x3b, 0x0d, 0xb8, 0x3f, 0x4f, 0x06, 0x02, 0x17, 0x7c, - 0x79, 0xa7, 0x36, 0x56, 0xef, 0xcd, 0x1a, 0x41, 0x00, 0x2c, 0xe8, 0x2e, 0x55, 0x9b, 0x10, 0xea, 0x19, 0xb2, 0xe3, - 0x02, 0x81, 0x81, 0x00, 0xae, 0x66, 0x06, 0x29, 0xcd, 0x44, 0x6b, 0x4d, 0xb0, 0x1e, 0xba, 0xb8, 0x4f, 0x5e, 0x06, - 0xaa, 0x02, 0x58, 0xc9, 0xb5, 0x46, 0x68, 0xe0, 0xaf, 0x48, 0x48, 0x82, 0x45, 0xd2, 0x9c, 0xa5, 0x2d, 0x9d, 0xe6, - 0x7a, 0x16, 0xe6, 0xba, 0x8c, 0xe9, 0x2b, 0x61, 0xaf, 0x40, 0x8c, 0xab, 0x38, 0x17, 0x4e, 0xe1, 0xf7, 0x0d, 0x52, - 0xb8, 0x78, 0xcc, 0x4d, 0xcb, 0xdc, 0xe4, 0xb7, 0x4f, 0x41, 0xdf, 0xde, 0x34, 0x20, 0x5f, 0xac, 0x45, 0x6f, 0xed, - 0xcd, 0xc0, 0x4d, 0x88, 0x7a, 0xf4, 0xc9, 0x8a, 0xa4, 0xf7, 0x40, 0x41, 0x4d, 0xb6, 0x98, 0x1f, 0x2a, 0x42, 0x42, - 0x62, 0xd2, 0xb1, 0xef, 0x84, 0x94, 0x87, 0x09, 0xfe, 0xf1, 0xba, 0xb2, 0xb8, 0x6c, 0x99, 0xb2, 0x77, 0xa6, 0xd8, - 0x91, 0x07, 0xb5, 0xd9, 0x7d, 0xe8, 0x59, 0xc0, 0xfa, 0x5a, 0x55, 0xf4, 0x3a, 0x82, 0xf4, 0x78, 0xa1, 0x7b, 0x02, - 0x81, 0x80, 0x3f, 0x6e, 0xfa, 0x7a, 0xda, 0xce, 0xe8, 0x58, 0x5d, 0xfa, 0x2b, 0x6b, 0xae, 0xcb, 0x10, 0xf0, 0x00, - 0x35, 0x1b, 0xbf, 0x30, 0xeb, 0x86, 0x41, 0xbd, 0x90, 0x00, 0xb6, 0xca, 0xcd, 0xdd, 0x68, 0x6e, 0xa0, 0x7a, 0xeb, - 0xec, 0x36, 0x5f, 0x66, 0xb3, 0xf5, 0xab, 0xc2, 0x53, 0x8a, 0xbf, 0x26, 0xe6, 0xfa, 0xf3, 0xe6, 0xd5, 0xab, 0x7a, - 0xde, 0x48, 0xd4, 0xd9, 0x8b, 0x84, 0x19, 0x6b, 0x3f, 0x05, 0xb6, 0x1d, 0x3a, 0x9e, 0x76, 0xff, 0x10, 0xed, 0x2b, - 0x84, 0xec, 0x0e, 0xc3, 0xcc, 0xb6, 0x8a, 0xfd, 0x6d, 0x85, 0xfe, 0x9d, 0xc4, 0x92, 0x4a, 0x8d, 0x04, 0xc2, 0xbf, - 0xbd, 0x1c, 0x64, 0xb5, 0xc7, 0xe0, 0x06, 0x13, 0x78, 0x19, 0x74, 0x9d, 0x7b, 0x44, 0x60, 0x50, 0x52, 0x09, 0x56, - 0x7c, 0x30, 0x3d, 0x03, 0x6c, 0x1f, 0xd5, 0x98, 0x07, 0xaf, 0x76, 0xf3, 0x2f, 0xd0, 0x31, 0xe9, 0x02, 0x81, 0x81, - 0x00, 0xa6, 0x61, 0x77, 0x67, 0xd2, 0x09, 0x80, 0x45, 0xb1, 0xcc, 0xdf, 0x5e, 0x8f, 0x79, 0xa8, 0xe9, 0xf1, 0x2b, - 0x3b, 0xe4, 0xd1, 0xb3, 0xa5, 0x08, 0x14, 0xf1, 0xf8, 0x37, 0x1c, 0xe3, 0x8d, 0x42, 0xa3, 0xee, 0x0a, 0x74, 0x66, - 0xd3, 0x7b, 0x33, 0xc8, 0xcb, 0x7d, 0x23, 0x1c, 0x11, 0x0d, 0x86, 0x4f, 0x1f, 0x8d, 0x4f, 0x0c, 0xa8, 0x29, 0xb6, - 0xe0, 0x51, 0xaa, 0x00, 0x1a, 0x52, 0x67, 0x0a, 0x69, 0x37, 0x59, 0xdb, 0x6c, 0xc3, 0x22, 0x31, 0xc1, 0xa5, 0xc1, - 0x52, 0x7f, 0xdb, 0xa1, 0x9b, 0xc0, 0x1e, 0x93, 0x12, 0xba, 0x4d, 0x85, 0x7b, 0xd6, 0x19, 0x38, 0xb4, 0x87, 0x46, - 0x72, 0xb8, 0x0d, 0xeb, 0x77, 0x41, 0xde, 0xe4, 0xbb, 0x34, 0xef, 0x87, 0x02, 0x98, 0xdc, 0x78, 0xa8, 0x84, 0xae, - 0x9d, 0x3c, 0x5d, 0xbb, 0xa3, 0x3c, 0x35, 0x8a, 0xe3, 0x62, 0x1f, 0x25, 0x95, 0x20, 0x99, 0x02, 0x81, 0x80, 0x5b, - 0xfb, 0x99, 0x65, 0xaa, 0x0d, 0x55, 0xf5, 0x66, 0x27, 0x95, 0xc8, 0xb2, 0x68, 0x7f, 0x8b, 0xd3, 0x26, 0xd1, 0x51, - 0x68, 0xe3, 0x5f, 0x84, 0x1b, 0x13, 0xbf, 0xec, 0xb4, 0x92, 0x09, 0xa8, 0x0c, 0xac, 0x5f, 0x99, 0x3a, 0xd5, 0xda, - 0xdd, 0xee, 0xba, 0x1c, 0xce, 0x92, 0x7c, 0x54, 0xd4, 0xf8, 0x6a, 0xc3, 0xb3, 0x07, 0xea, 0xce, 0x18, 0xad, 0x8e, - 0x26, 0x5e, 0x54, 0xa1, 0x87, 0x77, 0x6a, 0x7b, 0x23, 0x2e, 0x76, 0xb6, 0x3a, 0xe7, 0xd9, 0x67, 0x0d, 0x7e, 0x19, - 0xd9, 0x6e, 0x2c, 0xe0, 0x00, 0xd6, 0x8e, 0xd2, 0x5a, 0xc9, 0x59, 0x44, 0x58, 0xd8, 0x73, 0x15, 0x0f, 0x17, 0x63, - 0x3e, 0xef, 0x74, 0x2f, 0xfe, 0xbd, 0x50, 0x07, 0x5f, 0x7d, 0x15, 0x23, 0xab, 0xc2, 0x77, 0x6d, 0xc9, 0x3d, 0x08, - 0x1a, 0x88, 0xdd, 0x45, 0x26, 0xd9, 0x2d, 0xe9, 0xde, 0xb9, 0x58, 0x36, 0x5f]; - - #[test] - fn generate_rsa() { - let generated = Pk::generate_rsa(&mut ::test_support::rand::test_rng(), 2048, 0x10001) - .unwrap() - .write_private_pem_string() - .unwrap(); - assert_eq!(generated,TEST_PEM[..TEST_PEM.len()-1]); - } - - #[test] - fn generate_ec_curve25519() { - let _generated = Pk::generate_ec(&mut ::test_support::rand::test_rng(), EcGroupId::Curve25519) - .unwrap(); - // mbedtls does not have an OID for Curve25519, so can't write it as PEM - } - - #[test] - fn generate_ec_secp192r1() { - let _generated = Pk::generate_ec(&mut ::test_support::rand::test_rng(), EcGroupId::SecP192R1) - .unwrap() - .write_private_pem_string() - .unwrap(); - } - - #[test] - fn generate_ec_secp256r1() { - let mut _generated = Pk::generate_ec(&mut ::test_support::rand::test_rng(), EcGroupId::SecP256R1) - .unwrap() - .write_private_pem_string() - .unwrap(); - } - - #[test] - fn generate_ec_secp256k1() { - let _generated = Pk::generate_ec(&mut ::test_support::rand::test_rng(), EcGroupId::SecP256K1) - .unwrap() - .write_private_pem_string() - .unwrap(); - } - - #[test] - fn parse_write_pem() { - let parsed = Pk::from_private_key(TEST_PEM.as_bytes(), None) - .unwrap() - .write_private_pem_string() - .unwrap(); - assert_eq!(parsed,TEST_PEM[..TEST_PEM.len()-1]); - } - - #[test] - fn parse_write_der() { - let parsed = Pk::from_private_key(TEST_DER, None).unwrap().write_private_der_vec().unwrap(); - assert!(parsed==TEST_DER); - } - - #[test] - fn encrypt_v15_oaep() { - let mut pk = Pk::from_private_key(TEST_DER, None).unwrap(); - let mut cipher1 = [0u8; 2048/8]; - let mut cipher2 = [0u8; 2048/8]; - assert_eq!(pk.encrypt(b"test", &mut cipher1, &mut ::test_support::rand::test_rng()).unwrap(), cipher1.len()); - pk.set_options(Options::Rsa { padding: RsaPadding::Pkcs1V21 { mgf: ::hash::Type::Sha256 } }); - assert_eq!(pk.encrypt(b"test", &mut cipher2, &mut ::test_support::rand::test_rng()).unwrap(), cipher2.len()); - assert_ne!(&cipher1[..], &cipher2[..]); - } + const TEST_DER: &'static [u8] = &[ + 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0x8d, 0x76, 0xa1, + 0x2e, 0xb6, 0xc0, 0xe5, 0x1e, 0x1a, 0x06, 0x74, 0x13, 0x57, 0x6a, 0xc2, 0x6c, 0x02, 0x9d, + 0x82, 0x91, 0x5b, 0xb0, 0xe5, 0xa9, 0x7f, 0xe0, 0x6d, 0x3f, 0xc0, 0x94, 0x88, 0x8e, 0x72, + 0xd4, 0x4a, 0xc1, 0xf5, 0x54, 0x71, 0x63, 0x10, 0xaa, 0xef, 0x9d, 0xa5, 0x1a, 0xdc, 0x00, + 0x82, 0x2d, 0xea, 0x5f, 0x5b, 0xe8, 0x73, 0x6e, 0x03, 0xf8, 0x07, 0x90, 0x8c, 0xd5, 0x52, + 0xf5, 0x6d, 0xfc, 0x4d, 0xe5, 0x6a, 0x87, 0x5a, 0x85, 0xf7, 0x34, 0x85, 0x9a, 0x19, 0x3a, + 0x74, 0x46, 0x1e, 0xcb, 0x30, 0x77, 0x8d, 0x68, 0x8a, 0xb8, 0xfd, 0x6e, 0xbc, 0xee, 0xd2, + 0xd0, 0xb3, 0xd0, 0x1c, 0x44, 0x29, 0xd0, 0xd6, 0x91, 0xb5, 0xa8, 0xc1, 0xe3, 0x88, 0x64, + 0x40, 0x16, 0x31, 0x6c, 0xdc, 0x4b, 0xba, 0x69, 0xc3, 0xcd, 0x8d, 0x4a, 0xd8, 0x7d, 0xf4, + 0xa7, 0xe2, 0xe8, 0xc5, 0x01, 0x6f, 0xcc, 0x91, 0x22, 0x81, 0x52, 0x83, 0x11, 0x28, 0xb3, + 0x97, 0x1d, 0x57, 0xa2, 0x2a, 0x01, 0x77, 0x65, 0x87, 0x3e, 0xdc, 0x6c, 0x7f, 0x0a, 0xca, + 0x95, 0x04, 0x6a, 0x4e, 0x47, 0xa4, 0xfb, 0xa1, 0x42, 0x19, 0x0f, 0x80, 0x14, 0xed, 0xf9, + 0x4a, 0x42, 0x9c, 0x6f, 0xef, 0x0f, 0x82, 0x51, 0xbb, 0x46, 0x66, 0xc6, 0xfd, 0xd9, 0x01, + 0x93, 0x6d, 0xda, 0x36, 0xc7, 0x58, 0x37, 0x4b, 0xa7, 0xdb, 0xbd, 0xb2, 0x6f, 0x5b, 0x33, + 0x4b, 0x78, 0x70, 0x7e, 0xe8, 0x02, 0xdd, 0x5f, 0xa4, 0x2f, 0xea, 0x3c, 0x6b, 0xfb, 0x51, + 0xe1, 0x19, 0x21, 0x9f, 0x52, 0xd6, 0x29, 0x53, 0x09, 0x98, 0xbc, 0x3e, 0x3b, 0xb3, 0xdc, + 0x25, 0x13, 0x36, 0x1b, 0x24, 0xf4, 0x33, 0xdd, 0xdf, 0xa8, 0xd6, 0xe8, 0x97, 0x11, 0x2f, + 0x9a, 0x81, 0xc1, 0xb6, 0xf1, 0x7b, 0xa5, 0xa4, 0x2c, 0xda, 0x41, 0xb6, 0x11, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x38, 0x98, 0xb9, 0xab, 0xe2, 0xda, 0x11, 0xd0, + 0x95, 0x40, 0xf7, 0xb7, 0xb5, 0x45, 0xb5, 0x3b, 0x59, 0x60, 0x83, 0x18, 0x7c, 0xc2, 0xad, + 0x5f, 0xbf, 0x15, 0x9f, 0x1f, 0xde, 0x80, 0x8e, 0x91, 0xcf, 0x47, 0x38, 0x11, 0x99, 0x81, + 0x8b, 0x4b, 0xc3, 0x23, 0x60, 0x72, 0x85, 0xd7, 0xd5, 0x25, 0x2e, 0xf0, 0x07, 0xd0, 0xd7, + 0x08, 0x8d, 0x05, 0xfa, 0xf8, 0x84, 0xae, 0x44, 0x6a, 0x24, 0xa2, 0xa4, 0xba, 0x48, 0xbf, + 0xfc, 0x7a, 0xe2, 0xb0, 0xae, 0x52, 0x89, 0x11, 0x39, 0xfe, 0xb4, 0xfe, 0x48, 0xdb, 0xaa, + 0x2c, 0x6a, 0x9a, 0xe4, 0xc5, 0x56, 0x3f, 0xb3, 0xbf, 0x29, 0x00, 0xee, 0xaf, 0xd8, 0x5f, + 0x3d, 0x0b, 0x9c, 0x8c, 0xf7, 0x4c, 0xe9, 0x25, 0x8b, 0x2f, 0xf0, 0xa3, 0xf0, 0x6a, 0x49, + 0x48, 0xd2, 0xef, 0xf5, 0xb2, 0x8b, 0x50, 0xe2, 0x84, 0xa2, 0x19, 0x79, 0x22, 0xff, 0x8e, + 0x16, 0xbe, 0x00, 0x70, 0xc4, 0x6d, 0xd0, 0x29, 0x54, 0x28, 0x99, 0x97, 0x84, 0xc9, 0xaf, + 0xd8, 0xb6, 0xb1, 0x44, 0x6d, 0x4a, 0x74, 0x82, 0x4e, 0xde, 0x44, 0x1c, 0x47, 0x11, 0x52, + 0x86, 0x48, 0xd7, 0x78, 0x52, 0xa9, 0x98, 0x20, 0x9d, 0x83, 0x39, 0x3d, 0xe5, 0xd6, 0xed, + 0x94, 0x6a, 0x67, 0xd0, 0x65, 0x23, 0xf6, 0xdd, 0xe1, 0xe3, 0xed, 0xe9, 0x6b, 0x85, 0xcb, + 0x91, 0x0b, 0xcd, 0xc4, 0x6b, 0xe4, 0x90, 0xd4, 0xeb, 0x7b, 0x80, 0x0b, 0x67, 0x9d, 0xb5, + 0x37, 0x0b, 0x83, 0x7d, 0x79, 0x45, 0x6b, 0x60, 0x7d, 0x6f, 0xe3, 0xe0, 0x5e, 0x92, 0xf6, + 0x13, 0x67, 0xd2, 0xd4, 0xdc, 0x43, 0x5f, 0xd8, 0xee, 0xf5, 0x28, 0x05, 0x64, 0x78, 0x6a, + 0x6f, 0xaf, 0xef, 0x64, 0x52, 0x93, 0x70, 0x4f, 0x9a, 0xab, 0xce, 0x4a, 0x51, 0x63, 0x2a, + 0xf1, 0x33, 0xfd, 0xd8, 0x1e, 0xf9, 0xef, 0xf1, 0x02, 0x81, 0x81, 0x00, 0xcf, 0xa7, 0x89, + 0x75, 0xdd, 0x09, 0x66, 0x8b, 0x4e, 0xda, 0x52, 0x38, 0x4a, 0xc3, 0x7c, 0xca, 0x90, 0x68, + 0x4a, 0xbb, 0x78, 0x14, 0xc1, 0x83, 0x24, 0xb2, 0x2e, 0x39, 0x20, 0x8a, 0x00, 0x97, 0x8d, + 0xf3, 0x21, 0x5a, 0xad, 0x03, 0xc7, 0xb2, 0xe9, 0x17, 0x10, 0x85, 0x63, 0x23, 0xe3, 0xc9, + 0x73, 0x91, 0xa8, 0x5a, 0x8d, 0xb6, 0x40, 0x0f, 0x98, 0xb8, 0x2a, 0x8f, 0x7e, 0x59, 0x80, + 0x8a, 0xee, 0xb9, 0xe9, 0x9b, 0x2e, 0x83, 0xd4, 0x85, 0xc1, 0xdc, 0x1e, 0xc9, 0x44, 0x48, + 0x2a, 0x13, 0x06, 0x09, 0x02, 0x3e, 0x3f, 0xfb, 0xf2, 0xe8, 0x1a, 0x2d, 0xec, 0x40, 0xea, + 0x0e, 0x2b, 0x7f, 0xf3, 0x79, 0xdc, 0x11, 0x3b, 0x0d, 0xb8, 0x3f, 0x4f, 0x06, 0x02, 0x17, + 0x7c, 0x79, 0xa7, 0x36, 0x56, 0xef, 0xcd, 0x1a, 0x41, 0x00, 0x2c, 0xe8, 0x2e, 0x55, 0x9b, + 0x10, 0xea, 0x19, 0xb2, 0xe3, 0x02, 0x81, 0x81, 0x00, 0xae, 0x66, 0x06, 0x29, 0xcd, 0x44, + 0x6b, 0x4d, 0xb0, 0x1e, 0xba, 0xb8, 0x4f, 0x5e, 0x06, 0xaa, 0x02, 0x58, 0xc9, 0xb5, 0x46, + 0x68, 0xe0, 0xaf, 0x48, 0x48, 0x82, 0x45, 0xd2, 0x9c, 0xa5, 0x2d, 0x9d, 0xe6, 0x7a, 0x16, + 0xe6, 0xba, 0x8c, 0xe9, 0x2b, 0x61, 0xaf, 0x40, 0x8c, 0xab, 0x38, 0x17, 0x4e, 0xe1, 0xf7, + 0x0d, 0x52, 0xb8, 0x78, 0xcc, 0x4d, 0xcb, 0xdc, 0xe4, 0xb7, 0x4f, 0x41, 0xdf, 0xde, 0x34, + 0x20, 0x5f, 0xac, 0x45, 0x6f, 0xed, 0xcd, 0xc0, 0x4d, 0x88, 0x7a, 0xf4, 0xc9, 0x8a, 0xa4, + 0xf7, 0x40, 0x41, 0x4d, 0xb6, 0x98, 0x1f, 0x2a, 0x42, 0x42, 0x62, 0xd2, 0xb1, 0xef, 0x84, + 0x94, 0x87, 0x09, 0xfe, 0xf1, 0xba, 0xb2, 0xb8, 0x6c, 0x99, 0xb2, 0x77, 0xa6, 0xd8, 0x91, + 0x07, 0xb5, 0xd9, 0x7d, 0xe8, 0x59, 0xc0, 0xfa, 0x5a, 0x55, 0xf4, 0x3a, 0x82, 0xf4, 0x78, + 0xa1, 0x7b, 0x02, 0x81, 0x80, 0x3f, 0x6e, 0xfa, 0x7a, 0xda, 0xce, 0xe8, 0x58, 0x5d, 0xfa, + 0x2b, 0x6b, 0xae, 0xcb, 0x10, 0xf0, 0x00, 0x35, 0x1b, 0xbf, 0x30, 0xeb, 0x86, 0x41, 0xbd, + 0x90, 0x00, 0xb6, 0xca, 0xcd, 0xdd, 0x68, 0x6e, 0xa0, 0x7a, 0xeb, 0xec, 0x36, 0x5f, 0x66, + 0xb3, 0xf5, 0xab, 0xc2, 0x53, 0x8a, 0xbf, 0x26, 0xe6, 0xfa, 0xf3, 0xe6, 0xd5, 0xab, 0x7a, + 0xde, 0x48, 0xd4, 0xd9, 0x8b, 0x84, 0x19, 0x6b, 0x3f, 0x05, 0xb6, 0x1d, 0x3a, 0x9e, 0x76, + 0xff, 0x10, 0xed, 0x2b, 0x84, 0xec, 0x0e, 0xc3, 0xcc, 0xb6, 0x8a, 0xfd, 0x6d, 0x85, 0xfe, + 0x9d, 0xc4, 0x92, 0x4a, 0x8d, 0x04, 0xc2, 0xbf, 0xbd, 0x1c, 0x64, 0xb5, 0xc7, 0xe0, 0x06, + 0x13, 0x78, 0x19, 0x74, 0x9d, 0x7b, 0x44, 0x60, 0x50, 0x52, 0x09, 0x56, 0x7c, 0x30, 0x3d, + 0x03, 0x6c, 0x1f, 0xd5, 0x98, 0x07, 0xaf, 0x76, 0xf3, 0x2f, 0xd0, 0x31, 0xe9, 0x02, 0x81, + 0x81, 0x00, 0xa6, 0x61, 0x77, 0x67, 0xd2, 0x09, 0x80, 0x45, 0xb1, 0xcc, 0xdf, 0x5e, 0x8f, + 0x79, 0xa8, 0xe9, 0xf1, 0x2b, 0x3b, 0xe4, 0xd1, 0xb3, 0xa5, 0x08, 0x14, 0xf1, 0xf8, 0x37, + 0x1c, 0xe3, 0x8d, 0x42, 0xa3, 0xee, 0x0a, 0x74, 0x66, 0xd3, 0x7b, 0x33, 0xc8, 0xcb, 0x7d, + 0x23, 0x1c, 0x11, 0x0d, 0x86, 0x4f, 0x1f, 0x8d, 0x4f, 0x0c, 0xa8, 0x29, 0xb6, 0xe0, 0x51, + 0xaa, 0x00, 0x1a, 0x52, 0x67, 0x0a, 0x69, 0x37, 0x59, 0xdb, 0x6c, 0xc3, 0x22, 0x31, 0xc1, + 0xa5, 0xc1, 0x52, 0x7f, 0xdb, 0xa1, 0x9b, 0xc0, 0x1e, 0x93, 0x12, 0xba, 0x4d, 0x85, 0x7b, + 0xd6, 0x19, 0x38, 0xb4, 0x87, 0x46, 0x72, 0xb8, 0x0d, 0xeb, 0x77, 0x41, 0xde, 0xe4, 0xbb, + 0x34, 0xef, 0x87, 0x02, 0x98, 0xdc, 0x78, 0xa8, 0x84, 0xae, 0x9d, 0x3c, 0x5d, 0xbb, 0xa3, + 0x3c, 0x35, 0x8a, 0xe3, 0x62, 0x1f, 0x25, 0x95, 0x20, 0x99, 0x02, 0x81, 0x80, 0x5b, 0xfb, + 0x99, 0x65, 0xaa, 0x0d, 0x55, 0xf5, 0x66, 0x27, 0x95, 0xc8, 0xb2, 0x68, 0x7f, 0x8b, 0xd3, + 0x26, 0xd1, 0x51, 0x68, 0xe3, 0x5f, 0x84, 0x1b, 0x13, 0xbf, 0xec, 0xb4, 0x92, 0x09, 0xa8, + 0x0c, 0xac, 0x5f, 0x99, 0x3a, 0xd5, 0xda, 0xdd, 0xee, 0xba, 0x1c, 0xce, 0x92, 0x7c, 0x54, + 0xd4, 0xf8, 0x6a, 0xc3, 0xb3, 0x07, 0xea, 0xce, 0x18, 0xad, 0x8e, 0x26, 0x5e, 0x54, 0xa1, + 0x87, 0x77, 0x6a, 0x7b, 0x23, 0x2e, 0x76, 0xb6, 0x3a, 0xe7, 0xd9, 0x67, 0x0d, 0x7e, 0x19, + 0xd9, 0x6e, 0x2c, 0xe0, 0x00, 0xd6, 0x8e, 0xd2, 0x5a, 0xc9, 0x59, 0x44, 0x58, 0xd8, 0x73, + 0x15, 0x0f, 0x17, 0x63, 0x3e, 0xef, 0x74, 0x2f, 0xfe, 0xbd, 0x50, 0x07, 0x5f, 0x7d, 0x15, + 0x23, 0xab, 0xc2, 0x77, 0x6d, 0xc9, 0x3d, 0x08, 0x1a, 0x88, 0xdd, 0x45, 0x26, 0xd9, 0x2d, + 0xe9, 0xde, 0xb9, 0x58, 0x36, 0x5f, + ]; + + #[test] + fn generate_rsa() { + let generated = Pk::generate_rsa(&mut ::test_support::rand::test_rng(), 2048, 0x10001) + .unwrap() + .write_private_pem_string() + .unwrap(); + assert_eq!(generated, TEST_PEM[..TEST_PEM.len() - 1]); + } + + #[test] + fn generate_ec_curve25519() { + let _generated = + Pk::generate_ec(&mut ::test_support::rand::test_rng(), EcGroupId::Curve25519).unwrap(); + // mbedtls does not have an OID for Curve25519, so can't write it as PEM + } + + #[test] + fn generate_ec_secp192r1() { + let _generated = + Pk::generate_ec(&mut ::test_support::rand::test_rng(), EcGroupId::SecP192R1) + .unwrap() + .write_private_pem_string() + .unwrap(); + } + + #[test] + fn generate_ec_secp256r1() { + let mut _generated = + Pk::generate_ec(&mut ::test_support::rand::test_rng(), EcGroupId::SecP256R1) + .unwrap() + .write_private_pem_string() + .unwrap(); + } + + #[test] + fn generate_ec_secp256k1() { + let _generated = + Pk::generate_ec(&mut ::test_support::rand::test_rng(), EcGroupId::SecP256K1) + .unwrap() + .write_private_pem_string() + .unwrap(); + } + + #[test] + fn parse_write_pem() { + let parsed = Pk::from_private_key(TEST_PEM.as_bytes(), None) + .unwrap() + .write_private_pem_string() + .unwrap(); + assert_eq!(parsed, TEST_PEM[..TEST_PEM.len() - 1]); + } + + #[test] + fn parse_write_der() { + let parsed = Pk::from_private_key(TEST_DER, None) + .unwrap() + .write_private_der_vec() + .unwrap(); + assert!(parsed == TEST_DER); + } + + #[test] + fn encrypt_v15_oaep() { + let mut pk = Pk::from_private_key(TEST_DER, None).unwrap(); + let mut cipher1 = [0u8; 2048 / 8]; + let mut cipher2 = [0u8; 2048 / 8]; + assert_eq!( + pk.encrypt(b"test", &mut cipher1, &mut ::test_support::rand::test_rng()) + .unwrap(), + cipher1.len() + ); + pk.set_options(Options::Rsa { + padding: RsaPadding::Pkcs1V21 { + mgf: ::hash::Type::Sha256, + }, + }); + assert_eq!( + pk.encrypt(b"test", &mut cipher2, &mut ::test_support::rand::test_rng()) + .unwrap(), + cipher2.len() + ); + assert_ne!(&cipher1[..], &cipher2[..]); + } } diff --git a/mbedtls/src/private.rs b/mbedtls/src/private.rs index 924bba9de..86d848f78 100644 --- a/mbedtls/src/private.rs +++ b/mbedtls/src/private.rs @@ -1,86 +1,89 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ -#[cfg(not(feature="std"))] +#[cfg(not(feature = "std"))] use alloc_prelude::*; -use mbedtls_sys::types::raw_types::{c_int, c_uchar}; use mbedtls_sys::types::raw_types::c_char; +use mbedtls_sys::types::raw_types::{c_int, c_uchar}; use mbedtls_sys::types::size_t; use error::IntoResult; pub trait UnsafeFrom - where Self: Sized +where + Self: Sized, { - unsafe fn from(T) -> Option; + unsafe fn from(T) -> Option; } pub fn alloc_vec_repeat(mut f: F, data_at_end: bool) -> ::Result> - where F: FnMut(*mut c_uchar, size_t) -> c_int +where + F: FnMut(*mut c_uchar, size_t) -> c_int, { - let mut vec = Vec::with_capacity(2048 /* big because of bug in x509write */); - loop { - match f(vec.as_mut_ptr(), vec.capacity()).into_result() { - Err(::Error::Asn1BufTooSmall) | - Err(::Error::Base64BufferTooSmall) | - Err(::Error::EcpBufferTooSmall) | - Err(::Error::MpiBufferTooSmall) | - Err(::Error::NetBufferTooSmall) | - Err(::Error::OidBufTooSmall) | - Err(::Error::SslBufferTooSmall) | - Err(::Error::X509BufferTooSmall) => { - let cap = vec.capacity(); - vec.reserve(cap * 2) - } - Err(e) => return Err(e), - Ok(n) => { - if data_at_end { - let len = vec.capacity(); - unsafe { vec.set_len(len) }; - drop(vec.drain(..len - (n as usize))); - } else { - unsafe { vec.set_len(n as usize) }; - } - break; - } - } - } - vec.shrink_to_fit(); - Ok(vec) + let mut vec = Vec::with_capacity(2048 /* big because of bug in x509write */); + loop { + match f(vec.as_mut_ptr(), vec.capacity()).into_result() { + Err(::Error::Asn1BufTooSmall) + | Err(::Error::Base64BufferTooSmall) + | Err(::Error::EcpBufferTooSmall) + | Err(::Error::MpiBufferTooSmall) + | Err(::Error::NetBufferTooSmall) + | Err(::Error::OidBufTooSmall) + | Err(::Error::SslBufferTooSmall) + | Err(::Error::X509BufferTooSmall) => { + let cap = vec.capacity(); + vec.reserve(cap * 2) + } + Err(e) => return Err(e), + Ok(n) => { + if data_at_end { + let len = vec.capacity(); + unsafe { vec.set_len(len) }; + drop(vec.drain(..len - (n as usize))); + } else { + unsafe { vec.set_len(n as usize) }; + } + break; + } + } + } + vec.shrink_to_fit(); + Ok(vec) } pub fn alloc_string_repeat(mut f: F) -> ::Result - where F: FnMut(*mut c_char, size_t) -> c_int +where + F: FnMut(*mut c_char, size_t) -> c_int, { - let vec = try!(alloc_vec_repeat(|b,s|f(b as _,s),false)); - String::from_utf8(vec).map_err(|e| e.utf8_error().into()) + let vec = try!(alloc_vec_repeat(|b, s| f(b as _, s), false)); + String::from_utf8(vec).map_err(|e| e.utf8_error().into()) } -#[cfg(feature="std")] +#[cfg(feature = "std")] pub unsafe fn cstr_to_slice<'a>(ptr: *const c_char) -> &'a [u8] { - ::std::ffi::CStr::from_ptr(ptr).to_bytes() + ::std::ffi::CStr::from_ptr(ptr).to_bytes() } -#[cfg(not(feature="std"))] +#[cfg(not(feature = "std"))] pub unsafe fn cstr_to_slice<'a>(ptr: *const c_char) -> &'a [u8] { - extern "C" { - // this function is coming from the mbedtls C support lib - fn strlen(s: *const c_char) -> size_t; - } - ::core::slice::from_raw_parts(ptr as *const _, strlen(ptr)) + extern "C" { + // this function is coming from the mbedtls C support lib + fn strlen(s: *const c_char) -> size_t; + } + ::core::slice::from_raw_parts(ptr as *const _, strlen(ptr)) } -#[cfg(feature="std")] -use std::io::{Error as IoError, ErrorKind as IoErrorKind}; -#[cfg(not(feature="std"))] +#[cfg(not(feature = "std"))] use core_io::{Error as IoError, ErrorKind as IoErrorKind}; +#[cfg(feature = "std")] +use std::io::{Error as IoError, ErrorKind as IoErrorKind}; pub fn error_to_io_error(e: ::Error) -> IoError { - IoError::new(IoErrorKind::Other, e.to_string()) + IoError::new(IoErrorKind::Other, e.to_string()) } diff --git a/mbedtls/src/rng/ctr_drbg.rs b/mbedtls/src/rng/ctr_drbg.rs index ef25f00f9..ce9534cfe 100644 --- a/mbedtls/src/rng/ctr_drbg.rs +++ b/mbedtls/src/rng/ctr_drbg.rs @@ -1,16 +1,18 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use mbedtls_sys::types::raw_types::{c_int, c_uchar, c_void}; use mbedtls_sys::types::size_t; -use mbedtls_sys::{ctr_drbg_seed, ctr_drbg_set_prediction_resistance, ctr_drbg_reseed, ctr_drbg_update, ctr_drbg_random, - CTR_DRBG_PR_OFF, CTR_DRBG_PR_ON}; pub use mbedtls_sys::CTR_DRBG_RESEED_INTERVAL as RESEED_INTERVAL; +use mbedtls_sys::{ + ctr_drbg_random, ctr_drbg_reseed, ctr_drbg_seed, ctr_drbg_set_prediction_resistance, + ctr_drbg_update, CTR_DRBG_PR_OFF, CTR_DRBG_PR_ON, +}; use super::{EntropyCallback, RngCallback}; use error::IntoResult; @@ -30,133 +32,151 @@ use error::IntoResult; // }); // ``` -#[cfg(not(feature="std"))] -use alloc_prelude::*; use self::private::CtrDrbgInner; +#[cfg(not(feature = "std"))] +use alloc_prelude::*; use core::ops::{Deref, DerefMut}; mod private { - use core::marker::PhantomData; - use mbedtls_sys::{ctr_drbg_context, ctr_drbg_init, ctr_drbg_free}; - - pub struct CtrDrbgInner<'entropy> { - pub(super) inner: ctr_drbg_context, - r: PhantomData<&'entropy ()>, - } - - impl<'entropy> CtrDrbgInner<'entropy> { - pub(super) fn init() -> Self { - let mut inner; - unsafe { - inner = ::core::mem::uninitialized(); - ctr_drbg_init(&mut inner) - }; - CtrDrbgInner{ - inner, - r: PhantomData - } - } - } - - impl<'entropy> Drop for CtrDrbgInner<'entropy> { - fn drop(&mut self) { - unsafe{ctr_drbg_free(&mut self.inner)}; - } - } + use core::marker::PhantomData; + use mbedtls_sys::{ctr_drbg_context, ctr_drbg_free, ctr_drbg_init}; + + pub struct CtrDrbgInner<'entropy> { + pub(super) inner: ctr_drbg_context, + r: PhantomData<&'entropy ()>, + } + + impl<'entropy> CtrDrbgInner<'entropy> { + pub(super) fn init() -> Self { + let mut inner; + unsafe { + inner = ::core::mem::uninitialized(); + ctr_drbg_init(&mut inner) + }; + CtrDrbgInner { + inner, + r: PhantomData, + } + } + } + + impl<'entropy> Drop for CtrDrbgInner<'entropy> { + fn drop(&mut self) { + unsafe { ctr_drbg_free(&mut self.inner) }; + } + } } pub struct CtrDrbg<'entropy> { - boxed: Box>, + boxed: Box>, } impl<'entropy> CtrDrbg<'entropy> { - fn init() -> Self { - CtrDrbg { boxed: Box::new(CtrDrbgInner::init()) } - } + fn init() -> Self { + CtrDrbg { + boxed: Box::new(CtrDrbgInner::init()), + } + } } #[doc(hidden)] impl<'entropy> Deref for CtrDrbg<'entropy> { - type Target = CtrDrbgInner<'entropy>; - fn deref(&self) -> &Self::Target { - &self.boxed - } + type Target = CtrDrbgInner<'entropy>; + fn deref(&self) -> &Self::Target { + &self.boxed + } } #[doc(hidden)] impl<'entropy> DerefMut for CtrDrbg<'entropy> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.boxed - } + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.boxed + } } // ==== END IMMOVABLE TYPE KLUDGE ==== -#[cfg(feature="threading")] +#[cfg(feature = "threading")] unsafe impl<'entropy> Sync for CtrDrbg<'entropy> {} impl<'entropy> CtrDrbg<'entropy> { - pub fn new(source: &'entropy mut F, additional_entropy: Option<&[u8]>) -> ::Result> { - let mut ret = Self::init(); - unsafe { - try!(ctr_drbg_seed( - &mut ret.inner, - Some(F::call), - source.data_ptr(), - additional_entropy.map(<[_]>::as_ptr).unwrap_or(::core::ptr::null()), - additional_entropy.map(<[_]>::len).unwrap_or(0) - ).into_result()) - }; - Ok(ret) - } - - pub fn prediction_resistance(&self) -> bool { - if self.inner.prediction_resistance == CTR_DRBG_PR_OFF { - false - } else { - true - } - } - - pub fn set_prediction_resistance(&mut self, pr: bool) { - unsafe { ctr_drbg_set_prediction_resistance(&mut self.inner, if pr { CTR_DRBG_PR_ON } else { CTR_DRBG_PR_OFF }) } - } - - getter!(entropy_len() -> size_t = .entropy_len); - setter!(set_entropy_len(len: size_t) = ctr_drbg_set_entropy_len); - getter!(reseed_interval() -> c_int = .reseed_interval); - setter!(set_reseed_interval(i: c_int) = ctr_drbg_set_reseed_interval); - - pub fn reseed(&mut self, additional_entropy: Option<&[u8]>) -> ::Result<()> { - unsafe { - try!(ctr_drbg_reseed( - &mut self.inner, - additional_entropy.map(<[_]>::as_ptr).unwrap_or(::core::ptr::null()), - additional_entropy.map(<[_]>::len).unwrap_or(0) - ).into_result()) - }; - Ok(()) - } - - pub fn update(&mut self, entropy: &[u8]) { - unsafe { ctr_drbg_update(&mut self.inner, entropy.as_ptr(), entropy.len()) }; - } - - // TODO: - // - // ctr_drbg_random_with_add - // ctr_drbg_write_seed_file - // ctr_drbg_update_seed_file - // + pub fn new( + source: &'entropy mut F, + additional_entropy: Option<&[u8]>, + ) -> ::Result> { + let mut ret = Self::init(); + unsafe { + try!( + ctr_drbg_seed( + &mut ret.inner, + Some(F::call), + source.data_ptr(), + additional_entropy + .map(<[_]>::as_ptr) + .unwrap_or(::core::ptr::null()), + additional_entropy.map(<[_]>::len).unwrap_or(0) + ).into_result() + ) + }; + Ok(ret) + } + + pub fn prediction_resistance(&self) -> bool { + if self.inner.prediction_resistance == CTR_DRBG_PR_OFF { + false + } else { + true + } + } + + pub fn set_prediction_resistance(&mut self, pr: bool) { + unsafe { + ctr_drbg_set_prediction_resistance( + &mut self.inner, + if pr { CTR_DRBG_PR_ON } else { CTR_DRBG_PR_OFF }, + ) + } + } + + getter!(entropy_len() -> size_t = .entropy_len); + setter!(set_entropy_len(len: size_t) = ctr_drbg_set_entropy_len); + getter!(reseed_interval() -> c_int = .reseed_interval); + setter!(set_reseed_interval(i: c_int) = ctr_drbg_set_reseed_interval); + + pub fn reseed(&mut self, additional_entropy: Option<&[u8]>) -> ::Result<()> { + unsafe { + try!( + ctr_drbg_reseed( + &mut self.inner, + additional_entropy + .map(<[_]>::as_ptr) + .unwrap_or(::core::ptr::null()), + additional_entropy.map(<[_]>::len).unwrap_or(0) + ).into_result() + ) + }; + Ok(()) + } + + pub fn update(&mut self, entropy: &[u8]) { + unsafe { ctr_drbg_update(&mut self.inner, entropy.as_ptr(), entropy.len()) }; + } + + // TODO: + // + // ctr_drbg_random_with_add + // ctr_drbg_write_seed_file + // ctr_drbg_update_seed_file + // } impl<'entropy> RngCallback for CtrDrbg<'entropy> { - #[inline(always)] - unsafe extern "C" fn call(user_data: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { - ctr_drbg_random(user_data, data, len) - } - - fn data_ptr(&mut self) -> *mut c_void { - &mut self.inner as *mut _ as *mut _ - } + #[inline(always)] + unsafe extern "C" fn call(user_data: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { + ctr_drbg_random(user_data, data, len) + } + + fn data_ptr(&mut self) -> *mut c_void { + &mut self.inner as *mut _ as *mut _ + } } diff --git a/mbedtls/src/rng/hmac_drbg.rs b/mbedtls/src/rng/hmac_drbg.rs index 49fc80d07..9aafb8f84 100644 --- a/mbedtls/src/rng/hmac_drbg.rs +++ b/mbedtls/src/rng/hmac_drbg.rs @@ -1,16 +1,18 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use mbedtls_sys::types::raw_types::{c_int, c_uchar, c_void}; use mbedtls_sys::types::size_t; -use mbedtls_sys::{hmac_drbg_seed, hmac_drbg_seed_buf, hmac_drbg_set_prediction_resistance, hmac_drbg_reseed, hmac_drbg_update, - hmac_drbg_random, HMAC_DRBG_PR_OFF, HMAC_DRBG_PR_ON}; pub use mbedtls_sys::HMAC_DRBG_RESEED_INTERVAL as RESEED_INTERVAL; +use mbedtls_sys::{ + hmac_drbg_random, hmac_drbg_reseed, hmac_drbg_seed, hmac_drbg_seed_buf, + hmac_drbg_set_prediction_resistance, hmac_drbg_update, HMAC_DRBG_PR_OFF, HMAC_DRBG_PR_ON, +}; use super::{EntropyCallback, RngCallback}; use error::IntoResult; @@ -20,88 +22,108 @@ define!(struct HmacDrbg<'entropy>(hmac_drbg_context) { fn drop=hmac_drbg_free; }); -#[cfg(feature="threading")] +#[cfg(feature = "threading")] unsafe impl<'entropy> Sync for HmacDrbg<'entropy> {} impl<'entropy> HmacDrbg<'entropy> { - pub fn new(md_info: ::hash::MdInfo, - source: &'entropy mut F, - additional_entropy: Option<&[u8]>) - -> ::Result> { - let mut ret = Self::init(); - unsafe { - try!(hmac_drbg_seed( - &mut ret.inner, - md_info.into(), - Some(F::call), - source.data_ptr(), - additional_entropy.map(<[_]>::as_ptr).unwrap_or(::core::ptr::null()), - additional_entropy.map(<[_]>::len).unwrap_or(0) - ).into_result()) - }; - Ok(ret) - } + pub fn new( + md_info: ::hash::MdInfo, + source: &'entropy mut F, + additional_entropy: Option<&[u8]>, + ) -> ::Result> { + let mut ret = Self::init(); + unsafe { + try!( + hmac_drbg_seed( + &mut ret.inner, + md_info.into(), + Some(F::call), + source.data_ptr(), + additional_entropy + .map(<[_]>::as_ptr) + .unwrap_or(::core::ptr::null()), + additional_entropy.map(<[_]>::len).unwrap_or(0) + ).into_result() + ) + }; + Ok(ret) + } - pub fn from_buf(md_info: ::hash::MdInfo, entropy: &[u8]) -> ::Result> { - let mut ret = Self::init(); - unsafe { try!(hmac_drbg_seed_buf(&mut ret.inner,md_info.into(),entropy.as_ptr(),entropy.len()).into_result()) }; - Ok(ret) - } + pub fn from_buf(md_info: ::hash::MdInfo, entropy: &[u8]) -> ::Result> { + let mut ret = Self::init(); + unsafe { + try!( + hmac_drbg_seed_buf( + &mut ret.inner, + md_info.into(), + entropy.as_ptr(), + entropy.len() + ).into_result() + ) + }; + Ok(ret) + } - pub fn prediction_resistance(&self) -> bool { - if self.inner.prediction_resistance == HMAC_DRBG_PR_OFF { - false - } else { - true - } - } + pub fn prediction_resistance(&self) -> bool { + if self.inner.prediction_resistance == HMAC_DRBG_PR_OFF { + false + } else { + true + } + } - pub fn set_prediction_resistance(&mut self, pr: bool) { - unsafe { - hmac_drbg_set_prediction_resistance(&mut self.inner, - if pr { - HMAC_DRBG_PR_ON - } else { - HMAC_DRBG_PR_OFF - }) - } - } + pub fn set_prediction_resistance(&mut self, pr: bool) { + unsafe { + hmac_drbg_set_prediction_resistance( + &mut self.inner, + if pr { + HMAC_DRBG_PR_ON + } else { + HMAC_DRBG_PR_OFF + }, + ) + } + } - getter!(entropy_len() -> size_t = .entropy_len); - setter!(set_entropy_len(len: size_t) = hmac_drbg_set_entropy_len); - getter!(reseed_interval() -> c_int = .reseed_interval); - setter!(set_reseed_interval(i: c_int) = hmac_drbg_set_reseed_interval); + getter!(entropy_len() -> size_t = .entropy_len); + setter!(set_entropy_len(len: size_t) = hmac_drbg_set_entropy_len); + getter!(reseed_interval() -> c_int = .reseed_interval); + setter!(set_reseed_interval(i: c_int) = hmac_drbg_set_reseed_interval); - pub fn reseed(&mut self, additional_entropy: Option<&[u8]>) -> ::Result<()> { - unsafe { - try!(hmac_drbg_reseed( - &mut self.inner, - additional_entropy.map(<[_]>::as_ptr).unwrap_or(::core::ptr::null()), - additional_entropy.map(<[_]>::len).unwrap_or(0) - ).into_result()) - }; - Ok(()) - } + pub fn reseed(&mut self, additional_entropy: Option<&[u8]>) -> ::Result<()> { + unsafe { + try!( + hmac_drbg_reseed( + &mut self.inner, + additional_entropy + .map(<[_]>::as_ptr) + .unwrap_or(::core::ptr::null()), + additional_entropy.map(<[_]>::len).unwrap_or(0) + ).into_result() + ) + }; + Ok(()) + } - pub fn update(&mut self, entropy: &[u8]) { - unsafe { hmac_drbg_update(&mut self.inner, entropy.as_ptr(), entropy.len()) }; - } + pub fn update(&mut self, entropy: &[u8]) { + unsafe { hmac_drbg_update(&mut self.inner, entropy.as_ptr(), entropy.len()) }; + } - // TODO: - // - // hmac_drbg_random_with_add - // hmac_drbg_write_seed_file - // hmac_drbg_update_seed_file - // + // TODO: + // + // hmac_drbg_random_with_add + // hmac_drbg_write_seed_file + // hmac_drbg_update_seed_file + // } impl<'entropy> RngCallback for HmacDrbg<'entropy> { - #[inline(always)] - unsafe extern "C" fn call(user_data: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { - hmac_drbg_random(user_data, data, len) - } + #[inline(always)] + unsafe extern "C" fn call(user_data: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { + hmac_drbg_random(user_data, data, len) + } - fn data_ptr(&mut self) -> *mut c_void { - &mut self.inner as *mut _ as *mut _ - } + fn data_ptr(&mut self) -> *mut c_void { + &mut self.inner as *mut _ as *mut _ + } } diff --git a/mbedtls/src/rng/mod.rs b/mbedtls/src/rng/mod.rs index 7b77ad681..baed8146a 100644 --- a/mbedtls/src/rng/mod.rs +++ b/mbedtls/src/rng/mod.rs @@ -1,40 +1,40 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ pub mod ctr_drbg; pub mod hmac_drbg; -#[cfg(feature="std")] +#[cfg(feature = "std")] pub mod os_entropy; -#[cfg(feature="rdrand")] +#[cfg(feature = "rdrand")] mod rdrand; #[doc(inline)] pub use self::ctr_drbg::CtrDrbg; #[doc(inline)] pub use self::hmac_drbg::HmacDrbg; -#[cfg(feature="std")] +#[cfg(feature = "std")] #[doc(inline)] pub use self::os_entropy::OsEntropy; -#[cfg(feature="rdrand")] +#[cfg(feature = "rdrand")] pub use self::rdrand::{Entropy as Rdseed, Nrbg as Rdrand}; +use error::IntoResult; use mbedtls_sys::types::raw_types::{c_int, c_uchar}; use mbedtls_sys::types::size_t; -use error::IntoResult; callback!(EntropyCallback:Sync(data: *mut c_uchar, len: size_t) -> c_int); callback!(RngCallback:Sync(data: *mut c_uchar, len: size_t) -> c_int); pub trait Random: RngCallback { - fn random(&mut self, data: &mut [u8]) -> ::Result<()> { - try!(unsafe{Self::call(self.data_ptr(),data.as_mut_ptr(),data.len())}.into_result()); - Ok(()) - } + fn random(&mut self, data: &mut [u8]) -> ::Result<()> { + try!(unsafe { Self::call(self.data_ptr(), data.as_mut_ptr(), data.len()) }.into_result()); + Ok(()) + } } impl<'r, F: RngCallback> Random for F {} diff --git a/mbedtls/src/rng/os_entropy.rs b/mbedtls/src/rng/os_entropy.rs index 0a7f1cfe0..46ef6146e 100644 --- a/mbedtls/src/rng/os_entropy.rs +++ b/mbedtls/src/rng/os_entropy.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use mbedtls_sys::types::raw_types::{c_int, c_uchar, c_void}; @@ -19,49 +19,59 @@ define!(struct OsEntropy<'source>(entropy_context) { fn drop=entropy_free; }); -#[cfg(feature="threading")] +#[cfg(feature = "threading")] unsafe impl<'source> Sync for OsEntropy<'source> {} impl<'source> OsEntropy<'source> { - pub fn add_source(&mut self, - source: &'source mut F, - threshold: size_t, - strong: bool) - -> ::Result<()> { - unsafe { - try!(entropy_add_source( - &mut self.inner, - Some(F::call), - source.data_ptr(), - threshold, - if strong { ENTROPY_SOURCE_STRONG } else { ENTROPY_SOURCE_WEAK }).into_result()) - }; - Ok(()) - } + pub fn add_source( + &mut self, + source: &'source mut F, + threshold: size_t, + strong: bool, + ) -> ::Result<()> { + unsafe { + try!( + entropy_add_source( + &mut self.inner, + Some(F::call), + source.data_ptr(), + threshold, + if strong { + ENTROPY_SOURCE_STRONG + } else { + ENTROPY_SOURCE_WEAK + } + ).into_result() + ) + }; + Ok(()) + } - pub fn gather(&mut self) -> ::Result<()> { - unsafe { try!(entropy_gather(&mut self.inner).into_result()) }; - Ok(()) - } + pub fn gather(&mut self) -> ::Result<()> { + unsafe { try!(entropy_gather(&mut self.inner).into_result()) }; + Ok(()) + } - pub fn update_manual(&mut self, data: &[u8]) -> ::Result<()> { - unsafe { try!(entropy_update_manual(&mut self.inner,data.as_ptr(),data.len()).into_result()) }; - Ok(()) - } + pub fn update_manual(&mut self, data: &[u8]) -> ::Result<()> { + unsafe { + try!(entropy_update_manual(&mut self.inner, data.as_ptr(), data.len()).into_result()) + }; + Ok(()) + } - // TODO - // entropy_write_seed_file - // entropy_update_seed_file - // + // TODO + // entropy_write_seed_file + // entropy_update_seed_file + // } impl<'source> super::EntropyCallback for OsEntropy<'source> { - #[inline(always)] - unsafe extern "C" fn call(user_data: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { - entropy_func(user_data, data, len) - } + #[inline(always)] + unsafe extern "C" fn call(user_data: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { + entropy_func(user_data, data, len) + } - fn data_ptr(&mut self) -> *mut c_void { - &mut self.inner as *mut _ as *mut _ - } + fn data_ptr(&mut self) -> *mut c_void { + &mut self.inner as *mut _ as *mut _ + } } diff --git a/mbedtls/src/rng/rdrand.rs b/mbedtls/src/rng/rdrand.rs index 62d7b199f..dc9bf35bb 100644 --- a/mbedtls/src/rng/rdrand.rs +++ b/mbedtls/src/rng/rdrand.rs @@ -1,26 +1,26 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use core::slice::from_raw_parts_mut; -use mbedtls_sys::types::size_t; use mbedtls_sys::types::raw_types::{c_int, c_uchar, c_void}; +use mbedtls_sys::types::size_t; use super::{EntropyCallback, RngCallback}; pub struct Entropy; impl EntropyCallback for Entropy { - unsafe extern "C" fn call(_: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { - let outbuf = from_raw_parts_mut(data, len); - for chunk in outbuf.chunks_mut(8) { - let ret; - let mut retry = 10; - asm!(" + unsafe extern "C" fn call(_: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { + let outbuf = from_raw_parts_mut(data, len); + for chunk in outbuf.chunks_mut(8) { + let ret; + let mut retry = 10; + asm!(" 1: rdseed $0 jc 2f @@ -28,30 +28,30 @@ impl EntropyCallback for Entropy { jnz 1b 2: ":"=r"(ret),"=r"(retry):"1"(retry)::"volatile"); - if retry == 0 { - return ::mbedtls_sys::ERR_ENTROPY_SOURCE_FAILED; - } - let rand = ::core::mem::transmute::(ret); - let ptr = &rand[..chunk.len()]; - chunk.copy_from_slice(ptr); - } - 0 - } + if retry == 0 { + return ::mbedtls_sys::ERR_ENTROPY_SOURCE_FAILED; + } + let rand = ::core::mem::transmute::(ret); + let ptr = &rand[..chunk.len()]; + chunk.copy_from_slice(ptr); + } + 0 + } - fn data_ptr(&mut self) -> *mut c_void { - ::core::ptr::null_mut() - } + fn data_ptr(&mut self) -> *mut c_void { + ::core::ptr::null_mut() + } } pub struct Nrbg; impl RngCallback for Nrbg { - unsafe extern "C" fn call(_: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { - let outbuf = from_raw_parts_mut(data, len); - for chunk in outbuf.chunks_mut(8) { - let ret; - let mut retry = 10; - asm!(" + unsafe extern "C" fn call(_: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { + let outbuf = from_raw_parts_mut(data, len); + for chunk in outbuf.chunks_mut(8) { + let ret; + let mut retry = 10; + asm!(" 1: rdrand $0 jc 2f @@ -59,17 +59,17 @@ impl RngCallback for Nrbg { jnz 1b 2: ":"=r"(ret),"=r"(retry):"1"(retry)::"volatile"); - if retry == 0 { - return ::mbedtls_sys::ERR_ENTROPY_SOURCE_FAILED; - } - let rand = ::core::mem::transmute::(ret); - let ptr = &rand[..chunk.len()]; - chunk.copy_from_slice(ptr); - } - 0 - } + if retry == 0 { + return ::mbedtls_sys::ERR_ENTROPY_SOURCE_FAILED; + } + let rand = ::core::mem::transmute::(ret); + let ptr = &rand[..chunk.len()]; + chunk.copy_from_slice(ptr); + } + 0 + } - fn data_ptr(&mut self) -> *mut c_void { - ::core::ptr::null_mut() - } + fn data_ptr(&mut self) -> *mut c_void { + ::core::ptr::null_mut() + } } diff --git a/mbedtls/src/self_test.rs b/mbedtls/src/self_test.rs index 80dc66885..6148192f1 100644 --- a/mbedtls/src/self_test.rs +++ b/mbedtls/src/self_test.rs @@ -1,80 +1,62 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ //! Helper functions to enable mbedTLS self tests in no_std. //! //! Calling mbedTLS self-test functions before they're enabled using the //! `enable()` function here will result in a panic. -#[cfg(any(target_os="none",not(feature="std")))] -use mbedtls_sys::types::raw_types::{c_int, c_char}; +#[cfg(any(target_os = "none", not(feature = "std")))] +use mbedtls_sys::types::raw_types::{c_char, c_int}; -#[cfg(any(target_os="none",not(feature="std")))] +#[cfg(any(target_os = "none", not(feature = "std")))] #[allow(non_upper_case_globals)] static mut rand_f: Option c_int> = None; -#[cfg(any(target_os="none",not(feature="std")))] +#[cfg(any(target_os = "none", not(feature = "std")))] #[allow(non_upper_case_globals)] static mut log_f: Option = None; // needs to be pub for global visiblity -#[cfg(any(target_os="none",not(feature="std")))] +#[cfg(any(target_os = "none", not(feature = "std")))] #[doc(hidden)] #[no_mangle] pub unsafe extern "C" fn rand() -> c_int { - rand_f.expect("Called self-test rand without enabling self-test")() + rand_f.expect("Called self-test rand without enabling self-test")() } // needs to be pub for global visiblity -#[cfg(any(target_os="none",not(feature="std")))] +#[cfg(any(target_os = "none", not(feature = "std")))] #[doc(hidden)] #[no_mangle] pub unsafe extern "C" fn mbedtls_log(msg: *const c_char) { - log_f.expect("Called self-test log without enabling self-test")(msg) + log_f.expect("Called self-test log without enabling self-test")(msg) } // unsafe since unsynchronized -#[cfg(any(target_os="none",not(feature="std")))] +#[cfg(any(target_os = "none", not(feature = "std")))] pub unsafe fn enable(rand: fn() -> c_int, log: unsafe fn(*const c_char)) { - rand_f = Some(rand); - log_f = Some(log); + rand_f = Some(rand); + log_f = Some(log); } // unsafe since unsynchronized -#[cfg(any(target_os="none",not(feature="std")))] +#[cfg(any(target_os = "none", not(feature = "std")))] pub unsafe fn disable() { - rand_f = None; - log_f = None; + rand_f = None; + log_f = None; } pub use mbedtls_sys::{ - aes_self_test as aes, - arc4_self_test as arc4, - base64_self_test as base64, - camellia_self_test as camellia, - ccm_self_test as ccm, - des_self_test as des, - dhm_self_test as dhm, - gcm_self_test as gcm, - hmac_drbg_self_test as hmac_drbg, - rsa_self_test as rsa, - sha1_self_test as sha1, - sha256_self_test as sha256, - sha512_self_test as sha512, - ecp_self_test as ecp, - ecjpake_self_test as ecjpake, - ctr_drbg_self_test as ctr_drbg, - entropy_self_test as entropy, - md2_self_test as md2, - md4_self_test as md4, - md5_self_test as md5, - mpi_self_test as mpi, - pkcs5_self_test as pkcs5, - ripemd160_self_test as ripemd160, - x509_self_test as x509, - xtea_self_test as xtea + aes_self_test as aes, arc4_self_test as arc4, base64_self_test as base64, + camellia_self_test as camellia, ccm_self_test as ccm, ctr_drbg_self_test as ctr_drbg, + des_self_test as des, dhm_self_test as dhm, ecjpake_self_test as ecjpake, ecp_self_test as ecp, + entropy_self_test as entropy, gcm_self_test as gcm, hmac_drbg_self_test as hmac_drbg, + md2_self_test as md2, md4_self_test as md4, md5_self_test as md5, mpi_self_test as mpi, + pkcs5_self_test as pkcs5, ripemd160_self_test as ripemd160, rsa_self_test as rsa, + sha1_self_test as sha1, sha256_self_test as sha256, sha512_self_test as sha512, + x509_self_test as x509, xtea_self_test as xtea, }; - diff --git a/mbedtls/src/ssl/ciphersuites.rs b/mbedtls/src/ssl/ciphersuites.rs index 1b4d57cfa..31b44a987 100644 --- a/mbedtls/src/ssl/ciphersuites.rs +++ b/mbedtls/src/ssl/ciphersuites.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use mbedtls_sys::types::raw_types::c_int; diff --git a/mbedtls/src/ssl/config.rs b/mbedtls/src/ssl/config.rs index 756af1ee5..3ad22433e 100644 --- a/mbedtls/src/ssl/config.rs +++ b/mbedtls/src/ssl/config.rs @@ -1,23 +1,23 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use core::slice::from_raw_parts; -use mbedtls_sys::types::raw_types::{c_char, c_uchar, c_int, c_uint, c_void}; +use mbedtls_sys::types::raw_types::{c_char, c_int, c_uchar, c_uint, c_void}; use mbedtls_sys::types::size_t; use mbedtls_sys::*; use error::IntoResult; -use x509::{LinkedCertificate, Crl, Profile, VerifyError, certificate}; -use ssl::ticket::TicketCallback; -use ssl::context::HandshakeContext; use pk::dhparam::Dhm; use private::UnsafeFrom; +use ssl::context::HandshakeContext; +use ssl::ticket::TicketCallback; +use x509::{certificate, Crl, LinkedCertificate, Profile, VerifyError}; define!(enum Endpoint -> c_int { Client => SSL_IS_CLIENT, @@ -59,138 +59,179 @@ define!(struct Config<'c>(ssl_config) { impl<'q> UnsafeFrom<*>; }); -#[cfg(feature="threading")] +#[cfg(feature = "threading")] unsafe impl<'c> Sync for Config<'c> {} impl<'c> Config<'c> { - pub fn new(e: Endpoint, t: Transport, p: Preset) -> Self { - let mut c = Config::init(); - unsafe { - ssl_config_defaults(&mut c.inner, e.into(), t.into(), p.into()); - } - c - } - - // need bitfield support getter!(endpoint() -> Endpoint = field endpoint); - setter!(set_endpoint(e: Endpoint) = ssl_conf_endpoint); - // need bitfield support getter!(transport() -> Transport = field transport); - setter!(set_transport(t: Transport) = ssl_conf_transport); - // need bitfield support getter!(authmode() -> AuthMode = field authmode); - setter!(set_authmode(am: AuthMode) = ssl_conf_authmode); - getter!(read_timeout() -> u32 = .read_timeout); - setter!(set_read_timeout(t: u32) = ssl_conf_read_timeout); - - fn check_c_list(list: &[T]) { - assert!(list.last()==Some(&T::default())); - } - - pub fn set_ciphersuites(&mut self, list: &'c [c_int]) { - Self::check_c_list(list); - unsafe { ssl_conf_ciphersuites(&mut self.inner, list.as_ptr()) } - } - - pub fn set_ciphersuites_for_version(&mut self, list: &'c [c_int], major: c_int, minor: c_int) { - Self::check_c_list(list); - unsafe { ssl_conf_ciphersuites_for_version(&mut self.inner, list.as_ptr(), major, minor) } - } - - pub fn set_curves(&mut self, list: &'c [ecp_group_id]) { - Self::check_c_list(list); - unsafe { ssl_conf_curves(&mut self.inner, list.as_ptr()) } - } - - setter!(set_cert_profile(p: &'c Profile) = ssl_conf_cert_profile); - - /// Takes both DER and PEM forms of FFDH parameters in `DHParams` format. - /// - /// When calling on PEM-encoded data, `params` must be NULL-terminated - pub fn set_dh_params(&mut self, params: &[u8]) -> ::Result<()> { - let mut ctx = Dhm::from_params(params)?; - unsafe { ssl_conf_dh_param_ctx(&mut self.inner, (&mut ctx).into()).into_result().map(|_| ()) } - } - - pub fn set_ca_list>(&mut self, list: Option, crl: Option<&'c mut Crl>) { - unsafe { - ssl_conf_ca_chain(&mut self.inner, - list.map(Into::into) - .map(Into::into) - .unwrap_or(::core::ptr::null_mut()), - crl.map(Into::into).unwrap_or(::core::ptr::null_mut())) - } - } - - pub fn push_cert>(&mut self, chain: C, key: &'c mut ::pk::Pk) -> ::Result<()> { - unsafe { - ssl_conf_own_cert(&mut self.inner, chain.into().into(), key.into()) - .into_result() - .map(|_| ()) - } - } - - pub fn certs(&'c self) -> KeyCertIter<'c> { - KeyCertIter { - key_cert: unsafe { UnsafeFrom::from(self.inner.key_cert as *const _) } - } - } - - /// Server only: configure callback to use for generating/interpreting session tickets. - pub fn set_session_tickets_callback(&mut self, cb: &'c mut F) { - unsafe{ssl_conf_session_tickets_cb(&mut self.inner, Some(F::call_write), Some(F::call_parse), cb.data_ptr())}; - } - - /// Client only: whether to remember and use session tickets - setter!(set_session_tickets(u: UseSessionTickets) = ssl_conf_session_tickets); - - /// Client only: minimal FFDH group size - setter!(set_ffdh_min_bitlen(bitlen: c_uint) = ssl_conf_dhm_min_bitlen); - - // TODO: The lifetime restrictions on HandshakeContext here are too strict. - // Once we need something else, we might fix it. - pub fn set_sni_callback Result<(),()>>(&mut self, cb: &'c mut F) { - unsafe extern "C" fn sni_callback Result<(),()>>(closure: *mut c_void, ctx: *mut ssl_context, name: *const c_uchar, name_len: size_t) -> c_int { - let cb = &mut*(closure as *mut F); - let mut ctx = ::private::UnsafeFrom::from(ctx).expect("valid context"); - let name = from_raw_parts(name, name_len); - match cb(&mut ctx, name) { - Ok(()) => 0, - Err(()) => -1, - } - } - - unsafe { ssl_conf_sni(&mut self.inner, Some(sni_callback::), cb as *mut F as _) } - } - - // The docs for mbedtls_x509_crt_verify say "The [callback] should return 0 for anything but a - // fatal error.", so verify callbacks should return Ok(()) for anything but a fatal error. - // Report verification errors by updating the flags in VerifyError. - pub fn set_verify_callback(&mut self, cb: &'c mut F) - where F: FnMut(&mut LinkedCertificate, i32, &mut VerifyError) -> ::Result<()> - { - unsafe extern "C" fn verify_callback(closure: *mut c_void, - crt: *mut x509_crt, - depth: c_int, - flags: *mut u32) - -> c_int - where F: FnMut(&mut LinkedCertificate, i32, &mut VerifyError) -> ::Result<()> - { - let cb = &mut *(closure as *mut F); - let crt: &mut LinkedCertificate = ::private::UnsafeFrom::from(crt).expect("valid certificate"); - let mut verify_error = match VerifyError::from_bits(*flags) { - Some(ve) => ve, - // This can only happen if mbedtls is setting flags in VerifyError that are - // missing from our definition. - None => return ::mbedtls_sys::ERR_X509_BAD_INPUT_DATA, - }; - let res = cb(crt, depth, &mut verify_error); - *flags = verify_error.bits(); - match res { - Ok(()) => 0, - Err(e) => e.to_int(), - } - } - - unsafe { ssl_conf_verify(&mut self.inner, Some(verify_callback::), cb as *mut F as _) } - } + pub fn new(e: Endpoint, t: Transport, p: Preset) -> Self { + let mut c = Config::init(); + unsafe { + ssl_config_defaults(&mut c.inner, e.into(), t.into(), p.into()); + } + c + } + + // need bitfield support getter!(endpoint() -> Endpoint = field endpoint); + setter!(set_endpoint(e: Endpoint) = ssl_conf_endpoint); + // need bitfield support getter!(transport() -> Transport = field transport); + setter!(set_transport(t: Transport) = ssl_conf_transport); + // need bitfield support getter!(authmode() -> AuthMode = field authmode); + setter!(set_authmode(am: AuthMode) = ssl_conf_authmode); + getter!(read_timeout() -> u32 = .read_timeout); + setter!(set_read_timeout(t: u32) = ssl_conf_read_timeout); + + fn check_c_list(list: &[T]) { + assert!(list.last() == Some(&T::default())); + } + + pub fn set_ciphersuites(&mut self, list: &'c [c_int]) { + Self::check_c_list(list); + unsafe { ssl_conf_ciphersuites(&mut self.inner, list.as_ptr()) } + } + + pub fn set_ciphersuites_for_version(&mut self, list: &'c [c_int], major: c_int, minor: c_int) { + Self::check_c_list(list); + unsafe { ssl_conf_ciphersuites_for_version(&mut self.inner, list.as_ptr(), major, minor) } + } + + pub fn set_curves(&mut self, list: &'c [ecp_group_id]) { + Self::check_c_list(list); + unsafe { ssl_conf_curves(&mut self.inner, list.as_ptr()) } + } + + setter!(set_cert_profile(p: &'c Profile) = ssl_conf_cert_profile); + + /// Takes both DER and PEM forms of FFDH parameters in `DHParams` format. + /// + /// When calling on PEM-encoded data, `params` must be NULL-terminated + pub fn set_dh_params(&mut self, params: &[u8]) -> ::Result<()> { + let mut ctx = Dhm::from_params(params)?; + unsafe { + ssl_conf_dh_param_ctx(&mut self.inner, (&mut ctx).into()) + .into_result() + .map(|_| ()) + } + } + + pub fn set_ca_list>( + &mut self, + list: Option, + crl: Option<&'c mut Crl>, + ) { + unsafe { + ssl_conf_ca_chain( + &mut self.inner, + list.map(Into::into) + .map(Into::into) + .unwrap_or(::core::ptr::null_mut()), + crl.map(Into::into).unwrap_or(::core::ptr::null_mut()), + ) + } + } + + pub fn push_cert>( + &mut self, + chain: C, + key: &'c mut ::pk::Pk, + ) -> ::Result<()> { + unsafe { + ssl_conf_own_cert(&mut self.inner, chain.into().into(), key.into()) + .into_result() + .map(|_| ()) + } + } + + pub fn certs(&'c self) -> KeyCertIter<'c> { + KeyCertIter { + key_cert: unsafe { UnsafeFrom::from(self.inner.key_cert as *const _) }, + } + } + + /// Server only: configure callback to use for generating/interpreting session tickets. + pub fn set_session_tickets_callback(&mut self, cb: &'c mut F) { + unsafe { + ssl_conf_session_tickets_cb( + &mut self.inner, + Some(F::call_write), + Some(F::call_parse), + cb.data_ptr(), + ) + }; + } + + /// Client only: whether to remember and use session tickets + setter!(set_session_tickets(u: UseSessionTickets) = ssl_conf_session_tickets); + + /// Client only: minimal FFDH group size + setter!(set_ffdh_min_bitlen(bitlen: c_uint) = ssl_conf_dhm_min_bitlen); + + // TODO: The lifetime restrictions on HandshakeContext here are too strict. + // Once we need something else, we might fix it. + pub fn set_sni_callback Result<(), ()>>( + &mut self, + cb: &'c mut F, + ) { + unsafe extern "C" fn sni_callback< + F: FnMut(&mut HandshakeContext, &[u8]) -> Result<(), ()>, + >( + closure: *mut c_void, + ctx: *mut ssl_context, + name: *const c_uchar, + name_len: size_t, + ) -> c_int { + let cb = &mut *(closure as *mut F); + let mut ctx = ::private::UnsafeFrom::from(ctx).expect("valid context"); + let name = from_raw_parts(name, name_len); + match cb(&mut ctx, name) { + Ok(()) => 0, + Err(()) => -1, + } + } + + unsafe { ssl_conf_sni(&mut self.inner, Some(sni_callback::), cb as *mut F as _) } + } + + // The docs for mbedtls_x509_crt_verify say "The [callback] should return 0 for anything but a + // fatal error.", so verify callbacks should return Ok(()) for anything but a fatal error. + // Report verification errors by updating the flags in VerifyError. + pub fn set_verify_callback(&mut self, cb: &'c mut F) + where + F: FnMut(&mut LinkedCertificate, i32, &mut VerifyError) -> ::Result<()>, + { + unsafe extern "C" fn verify_callback( + closure: *mut c_void, + crt: *mut x509_crt, + depth: c_int, + flags: *mut u32, + ) -> c_int + where + F: FnMut(&mut LinkedCertificate, i32, &mut VerifyError) -> ::Result<()>, + { + let cb = &mut *(closure as *mut F); + let crt: &mut LinkedCertificate = + ::private::UnsafeFrom::from(crt).expect("valid certificate"); + let mut verify_error = match VerifyError::from_bits(*flags) { + Some(ve) => ve, + // This can only happen if mbedtls is setting flags in VerifyError that are + // missing from our definition. + None => return ::mbedtls_sys::ERR_X509_BAD_INPUT_DATA, + }; + let res = cb(crt, depth, &mut verify_error); + *flags = verify_error.bits(); + match res { + Ok(()) => 0, + Err(e) => e.to_int(), + } + } + + unsafe { + ssl_conf_verify( + &mut self.inner, + Some(verify_callback::), + cb as *mut F as _, + ) + } + } } setter_callback!(Config<'c>::set_rng(f: ::rng::Random) = ssl_conf_rng); @@ -201,19 +242,21 @@ define!(struct KeyCert(ssl_key_cert) { }); pub struct KeyCertIter<'a> { - key_cert: Option<&'a KeyCert> + key_cert: Option<&'a KeyCert>, } impl<'a> Iterator for KeyCertIter<'a> { - type Item = (certificate::Iter<'a>, &'a ::pk::Pk); - - fn next(&mut self) -> Option { - self.key_cert.take().map(|key_cert| unsafe { - self.key_cert = UnsafeFrom::from(key_cert.inner.next as *const _ ); - (UnsafeFrom::from(key_cert.inner.cert as *const _).expect("not null"), - UnsafeFrom::from(key_cert.inner.key as *const _).expect("not null")) - }) - } + type Item = (certificate::Iter<'a>, &'a ::pk::Pk); + + fn next(&mut self) -> Option { + self.key_cert.take().map(|key_cert| unsafe { + self.key_cert = UnsafeFrom::from(key_cert.inner.next as *const _); + ( + UnsafeFrom::from(key_cert.inner.cert as *const _).expect("not null"), + UnsafeFrom::from(key_cert.inner.key as *const _).expect("not null"), + ) + }) + } } // TODO diff --git a/mbedtls/src/ssl/context.rs b/mbedtls/src/ssl/context.rs index 7dc67f3d4..32760c0ed 100644 --- a/mbedtls/src/ssl/context.rs +++ b/mbedtls/src/ssl/context.rs @@ -1,60 +1,76 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ -#[cfg(feature="std")] +#[cfg(not(feature = "std"))] +use core_io::{self as io, Read, Write}; +#[cfg(feature = "std")] use std::io::{self, Read, Write}; -#[cfg(not(feature="std"))] -use core_io::{Read, Write, self as io}; use mbedtls_sys::types::raw_types::{c_int, c_uchar, c_void}; use mbedtls_sys::types::size_t; use mbedtls_sys::*; use error::IntoResult; -use ssl::config::{Config, AuthMode}; -use x509::{LinkedCertificate, Crl, VerifyError}; use private::UnsafeFrom; +use ssl::config::{AuthMode, Config}; +use x509::{Crl, LinkedCertificate, VerifyError}; pub trait IoCallback { - unsafe extern "C" fn call_recv(user_data: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int; - unsafe extern "C" fn call_send(user_data: *mut c_void, data: *const c_uchar, len: size_t) -> c_int; + unsafe extern "C" fn call_recv( + user_data: *mut c_void, + data: *mut c_uchar, + len: size_t, + ) -> c_int; + unsafe extern "C" fn call_send( + user_data: *mut c_void, + data: *const c_uchar, + len: size_t, + ) -> c_int; - fn data_ptr(&mut self) -> *mut c_void; + fn data_ptr(&mut self) -> *mut c_void; } impl IoCallback for IO { - unsafe extern "C" fn call_recv(user_data: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { - let len = if len > (c_int::max_value() as size_t) { - c_int::max_value() as size_t - } else { - len - }; - match (&mut *(user_data as *mut IO)).read(::core::slice::from_raw_parts_mut(data, len)) { - Ok(i) => i as c_int, - Err(_) => ::mbedtls_sys::ERR_NET_RECV_FAILED, - } - } + unsafe extern "C" fn call_recv( + user_data: *mut c_void, + data: *mut c_uchar, + len: size_t, + ) -> c_int { + let len = if len > (c_int::max_value() as size_t) { + c_int::max_value() as size_t + } else { + len + }; + match (&mut *(user_data as *mut IO)).read(::core::slice::from_raw_parts_mut(data, len)) { + Ok(i) => i as c_int, + Err(_) => ::mbedtls_sys::ERR_NET_RECV_FAILED, + } + } - unsafe extern "C" fn call_send(user_data: *mut c_void, data: *const c_uchar, len: size_t) -> c_int { - let len = if len > (c_int::max_value() as size_t) { - c_int::max_value() as size_t - } else { - len - }; - match (&mut *(user_data as *mut IO)).write(::core::slice::from_raw_parts(data, len)) { - Ok(i) => i as c_int, - Err(_) => ::mbedtls_sys::ERR_NET_SEND_FAILED, - } - } + unsafe extern "C" fn call_send( + user_data: *mut c_void, + data: *const c_uchar, + len: size_t, + ) -> c_int { + let len = if len > (c_int::max_value() as size_t) { + c_int::max_value() as size_t + } else { + len + }; + match (&mut *(user_data as *mut IO)).write(::core::slice::from_raw_parts(data, len)) { + Ok(i) => i as c_int, + Err(_) => ::mbedtls_sys::ERR_NET_SEND_FAILED, + } + } - fn data_ptr(&mut self) -> *mut c_void { - self as *mut IO as *mut _ - } + fn data_ptr(&mut self) -> *mut c_void { + self as *mut IO as *mut _ + } } define!(struct Context<'config>(ssl_context) { @@ -65,158 +81,180 @@ define!(struct Context<'config>(ssl_context) { }); pub struct Session<'ctx> { - inner: &'ctx mut ssl_context, + inner: &'ctx mut ssl_context, } -#[cfg(feature="threading")] +#[cfg(feature = "threading")] unsafe impl<'ctx> Send for Session<'ctx> {} pub struct HandshakeContext<'ctx> { - inner: &'ctx mut ssl_context, + inner: &'ctx mut ssl_context, } impl<'config> Context<'config> { - pub fn new(config: &'config Config) -> ::Result> { - let mut ret = Self::init(); - unsafe { ssl_setup(&mut ret.inner, config.into()) }.into_result().map(|_| ret) - } + pub fn new(config: &'config Config) -> ::Result> { + let mut ret = Self::init(); + unsafe { ssl_setup(&mut ret.inner, config.into()) } + .into_result() + .map(|_| ret) + } - pub fn establish<'c, F: IoCallback>(&'c mut self, io: &'c mut F, hostname: Option<&str>) -> ::Result> { - unsafe { - try!(ssl_session_reset(&mut self.inner).into_result()); - try!(self.set_hostname(hostname)); + pub fn establish<'c, F: IoCallback>( + &'c mut self, + io: &'c mut F, + hostname: Option<&str>, + ) -> ::Result> { + unsafe { + try!(ssl_session_reset(&mut self.inner).into_result()); + try!(self.set_hostname(hostname)); - ssl_set_bio(&mut self.inner, io.data_ptr(), Some(F::call_send), Some(F::call_recv), None); - match ssl_handshake(&mut self.inner).into_result() { - Err(e) => { - // safely end borrow of io - ssl_set_bio(&mut self.inner, ::core::ptr::null_mut(), None, None, None); - Err(e) - } - Ok(_) => Ok(Session { inner: &mut self.inner }), - } - } - } + ssl_set_bio( + &mut self.inner, + io.data_ptr(), + Some(F::call_send), + Some(F::call_recv), + None, + ); + match ssl_handshake(&mut self.inner).into_result() { + Err(e) => { + // safely end borrow of io + ssl_set_bio(&mut self.inner, ::core::ptr::null_mut(), None, None, None); + Err(e) + } + Ok(_) => Ok(Session { + inner: &mut self.inner, + }), + } + } + } - #[cfg(not(feature="std"))] - fn set_hostname(&mut self, hostname: Option<&str>) -> ::Result<()> { - match hostname { - Some(_) => Err(::Error::SslBadInputData), - None => Ok(()), - } - } + #[cfg(not(feature = "std"))] + fn set_hostname(&mut self, hostname: Option<&str>) -> ::Result<()> { + match hostname { + Some(_) => Err(::Error::SslBadInputData), + None => Ok(()), + } + } - #[cfg(feature="std")] - fn set_hostname(&mut self, hostname: Option<&str>) -> ::Result<()> { - if self.inner.hostname != ::core::ptr::null_mut() { - // potential MEMORY LEAK! See https://github.com/ARMmbed/mbedtls/issues/836 - self.inner.hostname = ::core::ptr::null_mut(); - } - if let Some(s) = hostname { - let cstr = try!(::std::ffi::CString::new(s).map_err(|_|::Error::SslBadInputData)); - unsafe {ssl_set_hostname(&mut self.inner, cstr.as_ptr()).into_result().map(|_|())} - } else { - Ok(()) - } - } + #[cfg(feature = "std")] + fn set_hostname(&mut self, hostname: Option<&str>) -> ::Result<()> { + if self.inner.hostname != ::core::ptr::null_mut() { + // potential MEMORY LEAK! See https://github.com/ARMmbed/mbedtls/issues/836 + self.inner.hostname = ::core::ptr::null_mut(); + } + if let Some(s) = hostname { + let cstr = try!(::std::ffi::CString::new(s).map_err(|_| ::Error::SslBadInputData)); + unsafe { + ssl_set_hostname(&mut self.inner, cstr.as_ptr()) + .into_result() + .map(|_| ()) + } + } else { + Ok(()) + } + } - pub fn config(&self) -> &'config Config { - unsafe { - UnsafeFrom::from(self.inner.conf).expect("not null") - } - } + pub fn config(&self) -> &'config Config { + unsafe { UnsafeFrom::from(self.inner.conf).expect("not null") } + } } impl<'ctx> HandshakeContext<'ctx> { - pub fn set_authmode(&mut self, am: AuthMode) { - unsafe { - ssl_set_hs_authmode(self.inner, am.into()) - } - } + pub fn set_authmode(&mut self, am: AuthMode) { + unsafe { ssl_set_hs_authmode(self.inner, am.into()) } + } - pub fn set_ca_list>(&mut self, list: Option, crl: Option<&'ctx mut Crl>) { - unsafe { - ssl_set_hs_ca_chain(self.inner, - list.map(Into::into) - .map(Into::into) - .unwrap_or(::core::ptr::null_mut()), - crl.map(Into::into).unwrap_or(::core::ptr::null_mut())) - } - } + pub fn set_ca_list>( + &mut self, + list: Option, + crl: Option<&'ctx mut Crl>, + ) { + unsafe { + ssl_set_hs_ca_chain( + self.inner, + list.map(Into::into) + .map(Into::into) + .unwrap_or(::core::ptr::null_mut()), + crl.map(Into::into).unwrap_or(::core::ptr::null_mut()), + ) + } + } - /// If this is never called, will use the set of private keys and - /// certificates configured in the `Config` associated with this `Context`. - /// If this is called at least once, all those are ignored and the set - /// specified using this function is used. - pub fn push_cert>(&mut self, chain: C, key: &'ctx mut ::pk::Pk) -> ::Result<()> { - unsafe { - ssl_set_hs_own_cert(self.inner, chain.into().into(), key.into()) - .into_result() - .map(|_| ()) - } - } + /// If this is never called, will use the set of private keys and + /// certificates configured in the `Config` associated with this `Context`. + /// If this is called at least once, all those are ignored and the set + /// specified using this function is used. + pub fn push_cert>( + &mut self, + chain: C, + key: &'ctx mut ::pk::Pk, + ) -> ::Result<()> { + unsafe { + ssl_set_hs_own_cert(self.inner, chain.into().into(), key.into()) + .into_result() + .map(|_| ()) + } + } } impl<'ctx> ::core::ops::Deref for HandshakeContext<'ctx> { - type Target = Context<'ctx>; + type Target = Context<'ctx>; - fn deref(&self) -> &Context<'ctx> { - unsafe { - UnsafeFrom::from(&*self.inner as *const _).expect("not null") - } - } + fn deref(&self) -> &Context<'ctx> { + unsafe { UnsafeFrom::from(&*self.inner as *const _).expect("not null") } + } } impl<'ctx> ::private::UnsafeFrom<*mut ssl_context> for HandshakeContext<'ctx> { - unsafe fn from(ctx: *mut ssl_context) -> Option> { - ctx.as_mut().map(|ctx|HandshakeContext{inner:ctx}) - } + unsafe fn from(ctx: *mut ssl_context) -> Option> { + ctx.as_mut().map(|ctx| HandshakeContext { inner: ctx }) + } } impl<'a> Session<'a> { - pub fn peer_cert(&self) -> Option<::x509::certificate::Iter> { - unsafe { ::private::UnsafeFrom::from(ssl_get_peer_cert(self.inner)) } - } + pub fn peer_cert(&self) -> Option<::x509::certificate::Iter> { + unsafe { ::private::UnsafeFrom::from(ssl_get_peer_cert(self.inner)) } + } - pub fn verify_result(&self) -> Result<(), VerifyError> { - match unsafe { ssl_get_verify_result(self.inner) } { - 0 => Ok(()), - flags => Err(VerifyError::from_bits_truncate(flags)), - } - } + pub fn verify_result(&self) -> Result<(), VerifyError> { + match unsafe { ssl_get_verify_result(self.inner) } { + 0 => Ok(()), + flags => Err(VerifyError::from_bits_truncate(flags)), + } + } } impl<'a> Read for Session<'a> { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - match unsafe { ssl_read(self.inner, buf.as_mut_ptr(), buf.len()).into_result() } { - Err(::Error::SslPeerCloseNotify) => Ok(0), - Err(e) => Err(::private::error_to_io_error(e)), - Ok(i) => Ok(i as usize), - } - } + fn read(&mut self, buf: &mut [u8]) -> io::Result { + match unsafe { ssl_read(self.inner, buf.as_mut_ptr(), buf.len()).into_result() } { + Err(::Error::SslPeerCloseNotify) => Ok(0), + Err(e) => Err(::private::error_to_io_error(e)), + Ok(i) => Ok(i as usize), + } + } } impl<'a> Write for Session<'a> { - fn write(&mut self, buf: &[u8]) -> io::Result { - match unsafe { ssl_write(self.inner, buf.as_ptr(), buf.len()).into_result() } { - Err(::Error::SslPeerCloseNotify) => Ok(0), - Err(e) => Err(::private::error_to_io_error(e)), - Ok(i) => Ok(i as usize), - } - } + fn write(&mut self, buf: &[u8]) -> io::Result { + match unsafe { ssl_write(self.inner, buf.as_ptr(), buf.len()).into_result() } { + Err(::Error::SslPeerCloseNotify) => Ok(0), + Err(e) => Err(::private::error_to_io_error(e)), + Ok(i) => Ok(i as usize), + } + } - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } } impl<'a> Drop for Session<'a> { - fn drop(&mut self) { - unsafe { - ssl_close_notify(self.inner); - ssl_set_bio(self.inner, ::core::ptr::null_mut(), None, None, None); - } - } + fn drop(&mut self) { + unsafe { + ssl_close_notify(self.inner); + ssl_set_bio(self.inner, ::core::ptr::null_mut(), None, None, None); + } + } } // ssl_get_alpn_protocol diff --git a/mbedtls/src/ssl/mod.rs b/mbedtls/src/ssl/mod.rs index 1a3ae1f3e..d819bdf98 100644 --- a/mbedtls/src/ssl/mod.rs +++ b/mbedtls/src/ssl/mod.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ pub mod ciphersuites; @@ -11,11 +11,11 @@ pub mod config; pub mod context; pub mod ticket; +#[doc(inline)] +pub use self::ciphersuites::CipherSuite; #[doc(inline)] pub use self::config::Config; #[doc(inline)] pub use self::context::{Context, HandshakeContext, Session}; #[doc(inline)] pub use self::ticket::TicketContext; -#[doc(inline)] -pub use self::ciphersuites::CipherSuite; diff --git a/mbedtls/src/ssl/ticket.rs b/mbedtls/src/ssl/ticket.rs index 56f44e96d..59a0154e7 100644 --- a/mbedtls/src/ssl/ticket.rs +++ b/mbedtls/src/ssl/ticket.rs @@ -1,22 +1,34 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ +use cipher::raw::CipherType; +use error::IntoResult; use mbedtls_sys::types::raw_types::{c_int, c_uchar, c_void}; use mbedtls_sys::types::size_t; use mbedtls_sys::*; -use cipher::raw::CipherType; -use error::IntoResult; pub trait TicketCallback { - unsafe extern "C" fn call_write(p_ticket: *mut c_void, session: *const ssl_session, start: *mut c_uchar, end: *const c_uchar, tlen: *mut size_t, lifetime: *mut u32) -> c_int; - unsafe extern "C" fn call_parse(p_ticket: *mut c_void, session: *mut ssl_session, buf: *mut c_uchar, len: size_t) -> c_int; + unsafe extern "C" fn call_write( + p_ticket: *mut c_void, + session: *const ssl_session, + start: *mut c_uchar, + end: *const c_uchar, + tlen: *mut size_t, + lifetime: *mut u32, + ) -> c_int; + unsafe extern "C" fn call_parse( + p_ticket: *mut c_void, + session: *mut ssl_session, + buf: *mut c_uchar, + len: size_t, + ) -> c_int; - fn data_ptr(&mut self) -> *mut c_void; + fn data_ptr(&mut self) -> *mut c_void; } define!(struct TicketContext<'rng>(ssl_ticket_context) { @@ -25,22 +37,47 @@ define!(struct TicketContext<'rng>(ssl_ticket_context) { }); impl<'rng> TicketContext<'rng> { - pub fn new(rng: &'rng mut F, cipher: CipherType, lifetime: u32) -> ::Result> { - let mut ret = Self::init(); - unsafe { ssl_ticket_setup(&mut ret.inner, Some(F::call), rng.data_ptr(), cipher.into(), lifetime) }.into_result().map(|_| ret) - } + pub fn new( + rng: &'rng mut F, + cipher: CipherType, + lifetime: u32, + ) -> ::Result> { + let mut ret = Self::init(); + unsafe { + ssl_ticket_setup( + &mut ret.inner, + Some(F::call), + rng.data_ptr(), + cipher.into(), + lifetime, + ) + }.into_result() + .map(|_| ret) + } } impl<'rng> TicketCallback for TicketContext<'rng> { - unsafe extern "C" fn call_write(p_ticket: *mut c_void, session: *const ssl_session, start: *mut c_uchar, end: *const c_uchar, tlen: *mut size_t, lifetime: *mut u32) -> c_int { - ssl_ticket_write(p_ticket, session, start, end, tlen, lifetime) - } + unsafe extern "C" fn call_write( + p_ticket: *mut c_void, + session: *const ssl_session, + start: *mut c_uchar, + end: *const c_uchar, + tlen: *mut size_t, + lifetime: *mut u32, + ) -> c_int { + ssl_ticket_write(p_ticket, session, start, end, tlen, lifetime) + } - unsafe extern "C" fn call_parse(p_ticket: *mut c_void, session: *mut ssl_session, buf: *mut c_uchar, len: size_t) -> c_int { - ssl_ticket_parse(p_ticket, session, buf, len) - } + unsafe extern "C" fn call_parse( + p_ticket: *mut c_void, + session: *mut ssl_session, + buf: *mut c_uchar, + len: size_t, + ) -> c_int { + ssl_ticket_parse(p_ticket, session, buf, len) + } - fn data_ptr(&mut self) -> *mut c_void { - &mut self.inner as *mut _ as *mut _ - } + fn data_ptr(&mut self) -> *mut c_void { + &mut self.inner as *mut _ as *mut _ + } } diff --git a/mbedtls/src/threading.rs b/mbedtls/src/threading.rs index 28dd79503..0f4d6b9a1 100644 --- a/mbedtls/src/threading.rs +++ b/mbedtls/src/threading.rs @@ -1,12 +1,12 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ -#[cfg(not(feature="std"))] +#[cfg(not(feature = "std"))] use alloc_prelude::*; extern crate spin; @@ -16,71 +16,78 @@ use core::ptr; use mbedtls_sys::types::raw_types::c_int; pub struct StaticMutex { - guard: Option>, - mutex: Mutex<()>, + guard: Option>, + mutex: Mutex<()>, } #[no_mangle] #[allow(non_upper_case_globals)] -pub static mut mbedtls_mutex_init: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) = StaticMutex::init; +pub static mut mbedtls_mutex_init: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) = + StaticMutex::init; #[no_mangle] #[allow(non_upper_case_globals)] -pub static mut mbedtls_mutex_free: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) = StaticMutex::free; +pub static mut mbedtls_mutex_free: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) = + StaticMutex::free; #[no_mangle] #[allow(non_upper_case_globals)] -pub static mut mbedtls_mutex_lock: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) -> c_int = StaticMutex::lock; +pub static mut mbedtls_mutex_lock: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) -> c_int = + StaticMutex::lock; #[no_mangle] #[allow(non_upper_case_globals)] -pub static mut mbedtls_mutex_unlock: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) -> c_int = StaticMutex::unlock; +pub static mut mbedtls_mutex_unlock: unsafe extern "C" fn(mutex: *mut *mut StaticMutex) -> c_int = + StaticMutex::unlock; impl StaticMutex { - unsafe extern "C" fn init(mutex: *mut *mut StaticMutex) { - if let Some(m) = mutex.as_mut() { - *m = Box::into_raw(Box::new(StaticMutex { guard: None, mutex: Mutex::new(()) })); - } - } + unsafe extern "C" fn init(mutex: *mut *mut StaticMutex) { + if let Some(m) = mutex.as_mut() { + *m = Box::into_raw(Box::new(StaticMutex { + guard: None, + mutex: Mutex::new(()), + })); + } + } - unsafe extern "C" fn free(mutex: *mut *mut StaticMutex) { - if let Some(m) = mutex.as_mut() { - if *m != ptr::null_mut() { - let mut mutex = Box::from_raw(*m); - mutex.guard.take(); - *m = ptr::null_mut(); - } - } - } + unsafe extern "C" fn free(mutex: *mut *mut StaticMutex) { + if let Some(m) = mutex.as_mut() { + if *m != ptr::null_mut() { + let mut mutex = Box::from_raw(*m); + mutex.guard.take(); + *m = ptr::null_mut(); + } + } + } - unsafe extern "C" fn lock(mutex: *mut *mut StaticMutex) -> c_int { - if let Some(m) = mutex.as_mut().and_then(|p| p.as_mut()) { - let guard = m.mutex.lock(); - m.guard = Some(guard); - 0 - } else { - ::mbedtls_sys::ERR_THREADING_BAD_INPUT_DATA - } - } + unsafe extern "C" fn lock(mutex: *mut *mut StaticMutex) -> c_int { + if let Some(m) = mutex.as_mut().and_then(|p| p.as_mut()) { + let guard = m.mutex.lock(); + m.guard = Some(guard); + 0 + } else { + ::mbedtls_sys::ERR_THREADING_BAD_INPUT_DATA + } + } - unsafe extern "C" fn unlock(mutex: *mut *mut StaticMutex) -> c_int { - if let Some(m) = mutex.as_mut().and_then(|p| p.as_mut()) { - m.guard.take(); - 0 - } else { - ::mbedtls_sys::ERR_THREADING_BAD_INPUT_DATA - } - } + unsafe extern "C" fn unlock(mutex: *mut *mut StaticMutex) -> c_int { + if let Some(m) = mutex.as_mut().and_then(|p| p.as_mut()) { + m.guard.take(); + 0 + } else { + ::mbedtls_sys::ERR_THREADING_BAD_INPUT_DATA + } + } } #[cfg(test)] mod tests { - use super::*; + use super::*; - #[test] - fn double_free() { - unsafe { - let mut mutex: *mut StaticMutex = ptr::null_mut(); - mbedtls_mutex_init(&mut mutex); - mbedtls_mutex_free(&mut mutex); - mbedtls_mutex_free(&mut mutex); - } - } + #[test] + fn double_free() { + unsafe { + let mut mutex: *mut StaticMutex = ptr::null_mut(); + mbedtls_mutex_init(&mut mutex); + mbedtls_mutex_free(&mut mutex); + mbedtls_mutex_free(&mut mutex); + } + } } diff --git a/mbedtls/src/wrapper_macros.rs b/mbedtls/src/wrapper_macros.rs index c9c7503a5..69f27a413 100644 --- a/mbedtls/src/wrapper_macros.rs +++ b/mbedtls/src/wrapper_macros.rs @@ -1,12 +1,16 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ -macro_rules! as_item { ($i:item) => {$i} } +macro_rules! as_item { + ($i:item) => { + $i + }; +} macro_rules! callback { //{ ($($arg:ident: $ty:ty),*) -> $ret:ty } => { @@ -15,14 +19,14 @@ macro_rules! callback { #[cfg(not(feature="threading"))] pub trait $n { unsafe extern "C" fn call(user_data: *mut ::mbedtls_sys::types::raw_types::c_void, $($arg:$ty),*) -> $ret; - + fn data_ptr(&mut self) -> *mut ::mbedtls_sys::types::raw_types::c_void; } #[cfg(feature="threading")] pub trait $n $( : $sync )* { unsafe extern "C" fn call(user_data: *mut ::mbedtls_sys::types::raw_types::c_void, $($arg:$ty),*) -> $ret; - + fn data_ptr(&mut self) -> *mut ::mbedtls_sys::types::raw_types::c_void; } @@ -86,7 +90,7 @@ macro_rules! define_struct { $(r: ::core::marker::PhantomData<&$l ()>,)* } ); - + as_item!( #[cfg(feature="threading")] unsafe impl<$($l)*> Send for $name<$($l)*> {} diff --git a/mbedtls/src/x509/certificate.rs b/mbedtls/src/x509/certificate.rs index bc50ef7ca..d9bb58900 100644 --- a/mbedtls/src/x509/certificate.rs +++ b/mbedtls/src/x509/certificate.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use core::fmt; @@ -11,7 +11,7 @@ use core::marker::PhantomData; use core::ops::{Deref, DerefMut}; use core::ptr; -#[cfg(not(feature="std"))] +#[cfg(not(feature = "std"))] use alloc_prelude::*; use mbedtls_sys::types::raw_types::c_char; @@ -26,132 +26,161 @@ define!(struct Certificate(x509_crt) { }); impl Certificate { - pub fn from_der(der: &[u8]) -> ::Result { - let mut ret = Self::init(); - unsafe { try!(x509_crt_parse_der(&mut ret.inner,der.as_ptr(),der.len()).into_result()) }; - Ok(ret) - } - - /// Input must be NULL-terminated - pub fn from_pem(pem: &[u8]) -> ::Result { - let mut ret = Self::init(); - unsafe { try!(x509_crt_parse(&mut ret.inner,pem.as_ptr(),pem.len()).into_result()) }; - let mut fake = Self::init(); - ::core::mem::swap(&mut fake.inner.next, &mut ret.inner.next); - Ok(ret) - } - - /// Input must be NULL-terminated - #[cfg(buggy)] - pub fn from_pem_multiple(pem: &[u8]) -> ::Result> { - let mut vec; - unsafe { - // first, find out how many certificates we're parsing - let mut dummy = Certificate::init(); - try!(x509_crt_parse(&mut dummy.inner,pem.as_ptr(),pem.len()).into_result()); - - // then allocate enough certs with our allocator - vec = Vec::new(); - let mut cur: *mut _ = &mut dummy.inner; - while cur != ::core::ptr::null_mut() { - vec.push(Certificate::init()); - cur = (*cur).next; - } - - // link them together, they will become unlinked again when List drops - let list = List::from_vec(&mut vec).unwrap(); - - // load the data again but into our allocated list - try!(x509_crt_parse(&mut list.head.inner,pem.as_ptr(),pem.len()).into_result()); - }; - Ok(vec) - } + pub fn from_der(der: &[u8]) -> ::Result { + let mut ret = Self::init(); + unsafe { try!(x509_crt_parse_der(&mut ret.inner, der.as_ptr(), der.len()).into_result()) }; + Ok(ret) + } + + /// Input must be NULL-terminated + pub fn from_pem(pem: &[u8]) -> ::Result { + let mut ret = Self::init(); + unsafe { try!(x509_crt_parse(&mut ret.inner, pem.as_ptr(), pem.len()).into_result()) }; + let mut fake = Self::init(); + ::core::mem::swap(&mut fake.inner.next, &mut ret.inner.next); + Ok(ret) + } + + /// Input must be NULL-terminated + #[cfg(buggy)] + pub fn from_pem_multiple(pem: &[u8]) -> ::Result> { + let mut vec; + unsafe { + // first, find out how many certificates we're parsing + let mut dummy = Certificate::init(); + try!(x509_crt_parse(&mut dummy.inner, pem.as_ptr(), pem.len()).into_result()); + + // then allocate enough certs with our allocator + vec = Vec::new(); + let mut cur: *mut _ = &mut dummy.inner; + while cur != ::core::ptr::null_mut() { + vec.push(Certificate::init()); + cur = (*cur).next; + } + + // link them together, they will become unlinked again when List drops + let list = List::from_vec(&mut vec).unwrap(); + + // load the data again but into our allocated list + try!(x509_crt_parse(&mut list.head.inner, pem.as_ptr(), pem.len()).into_result()); + }; + Ok(vec) + } } impl Deref for Certificate { - type Target = LinkedCertificate; - fn deref(&self) -> &LinkedCertificate { - unsafe { UnsafeFrom::from(&self.inner as *const _).unwrap() } - } + type Target = LinkedCertificate; + fn deref(&self) -> &LinkedCertificate { + unsafe { UnsafeFrom::from(&self.inner as *const _).unwrap() } + } } impl DerefMut for Certificate { - fn deref_mut(&mut self) -> &mut LinkedCertificate { - unsafe { UnsafeFrom::from(&mut self.inner as *mut _).unwrap() } - } + fn deref_mut(&mut self) -> &mut LinkedCertificate { + unsafe { UnsafeFrom::from(&mut self.inner as *mut _).unwrap() } + } } #[repr(C)] pub struct LinkedCertificate { - inner: x509_crt, + inner: x509_crt, } impl LinkedCertificate { - pub fn check_key_usage(&self, usage: super::KeyUsage) -> bool { - unsafe { x509_crt_check_key_usage(&self.inner, usage.bits()) }.into_result().is_ok() - } - - pub fn check_extended_key_usage(&self, usage_oid: &[c_char]) -> bool { - unsafe { x509_crt_check_extended_key_usage(&self.inner, usage_oid.as_ptr(), usage_oid.len()) } - .into_result() - .is_ok() - } - - pub fn issuer(&self) -> ::Result { - ::private::alloc_string_repeat(|buf, size| unsafe { x509_dn_gets(buf, size, &self.inner.issuer) }) - } - - pub fn issuer_raw(&self) -> ::Result> { - ::private::alloc_vec_repeat(|buf, size| unsafe { x509_dn_gets(buf as _, size, &self.inner.issuer) }, false) - } - - pub fn subject(&self) -> ::Result { - ::private::alloc_string_repeat(|buf, size| unsafe { x509_dn_gets(buf, size, &self.inner.subject) }) - } - - pub fn subject_raw(&self) -> ::Result> { - ::private::alloc_vec_repeat(|buf, size| unsafe { x509_dn_gets(buf as _, size, &self.inner.subject) }, false) - } - - pub fn serial(&self) -> ::Result { - ::private::alloc_string_repeat(|buf, size| unsafe { x509_serial_gets(buf, size, &self.inner.serial) }) - } - - pub fn serial_raw(&self) -> ::Result> { - ::private::alloc_vec_repeat(|buf, size| unsafe { x509_serial_gets(buf as _, size, &self.inner.serial) }, false) - } - - pub fn public_key(&self) -> &::pk::Pk { - unsafe { &*(&self.inner.pk as *const _ as *const _) } - } - - pub fn public_key_mut(&mut self) -> &mut ::pk::Pk { - unsafe { &mut *(&mut self.inner.pk as *mut _ as *mut _) } - } - - pub fn as_der(&self) -> &[u8] { - unsafe { ::core::slice::from_raw_parts(self.inner.raw.p, self.inner.raw.len) } - } - - pub fn verify(&mut self, trust_ca: &mut Certificate, err_info: Option<&mut String>) -> ::Result<()> { - let mut flags = 0; - let result = unsafe { - x509_crt_verify(&mut self.inner, &mut trust_ca.inner, ptr::null_mut(), ptr::null(), - &mut flags, None, ptr::null_mut()) - }.into_result(); - - if result.is_err() { - if let Some(err_info) = err_info { - let verify_info = ::private::alloc_string_repeat(|buf, size| unsafe { - x509_crt_verify_info(buf, size, ptr::null_mut(), flags) - }); - if let Ok(error_str) = verify_info { - *err_info = error_str; - } - } - } - result.map(|_| ()) - } + pub fn check_key_usage(&self, usage: super::KeyUsage) -> bool { + unsafe { x509_crt_check_key_usage(&self.inner, usage.bits()) } + .into_result() + .is_ok() + } + + pub fn check_extended_key_usage(&self, usage_oid: &[c_char]) -> bool { + unsafe { + x509_crt_check_extended_key_usage(&self.inner, usage_oid.as_ptr(), usage_oid.len()) + }.into_result() + .is_ok() + } + + pub fn issuer(&self) -> ::Result { + ::private::alloc_string_repeat(|buf, size| unsafe { + x509_dn_gets(buf, size, &self.inner.issuer) + }) + } + + pub fn issuer_raw(&self) -> ::Result> { + ::private::alloc_vec_repeat( + |buf, size| unsafe { x509_dn_gets(buf as _, size, &self.inner.issuer) }, + false, + ) + } + + pub fn subject(&self) -> ::Result { + ::private::alloc_string_repeat(|buf, size| unsafe { + x509_dn_gets(buf, size, &self.inner.subject) + }) + } + + pub fn subject_raw(&self) -> ::Result> { + ::private::alloc_vec_repeat( + |buf, size| unsafe { x509_dn_gets(buf as _, size, &self.inner.subject) }, + false, + ) + } + + pub fn serial(&self) -> ::Result { + ::private::alloc_string_repeat(|buf, size| unsafe { + x509_serial_gets(buf, size, &self.inner.serial) + }) + } + + pub fn serial_raw(&self) -> ::Result> { + ::private::alloc_vec_repeat( + |buf, size| unsafe { x509_serial_gets(buf as _, size, &self.inner.serial) }, + false, + ) + } + + pub fn public_key(&self) -> &::pk::Pk { + unsafe { &*(&self.inner.pk as *const _ as *const _) } + } + + pub fn public_key_mut(&mut self) -> &mut ::pk::Pk { + unsafe { &mut *(&mut self.inner.pk as *mut _ as *mut _) } + } + + pub fn as_der(&self) -> &[u8] { + unsafe { ::core::slice::from_raw_parts(self.inner.raw.p, self.inner.raw.len) } + } + + pub fn verify( + &mut self, + trust_ca: &mut Certificate, + err_info: Option<&mut String>, + ) -> ::Result<()> { + let mut flags = 0; + let result = unsafe { + x509_crt_verify( + &mut self.inner, + &mut trust_ca.inner, + ptr::null_mut(), + ptr::null(), + &mut flags, + None, + ptr::null_mut(), + ) + }.into_result(); + + if result.is_err() { + if let Some(err_info) = err_info { + let verify_info = ::private::alloc_string_repeat(|buf, size| unsafe { + x509_crt_verify_info(buf, size, ptr::null_mut(), flags) + }); + if let Ok(error_str) = verify_info { + *err_info = error_str; + } + } + } + result.map(|_| ()) + } } // TODO @@ -164,173 +193,179 @@ impl LinkedCertificate { // impl fmt::Debug for LinkedCertificate { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match ::private::alloc_string_repeat(|buf, size| unsafe { - x509_crt_info(buf, size, b"\0".as_ptr() as *const _, &self.inner) - }) { - Err(_) => Err(fmt::Error), - Ok(s) => f.write_str(&s), - } - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match ::private::alloc_string_repeat(|buf, size| unsafe { + x509_crt_info(buf, size, b"\0".as_ptr() as *const _, &self.inner) + }) { + Err(_) => Err(fmt::Error), + Ok(s) => f.write_str(&s), + } + } } impl<'r> Into<*const x509_crt> for &'r LinkedCertificate { - fn into(self) -> *const x509_crt { - &self.inner - } + fn into(self) -> *const x509_crt { + &self.inner + } } impl<'r> Into<*mut x509_crt> for &'r mut LinkedCertificate { - fn into(self) -> *mut x509_crt { - &mut self.inner - } + fn into(self) -> *mut x509_crt { + &mut self.inner + } } impl<'r> UnsafeFrom<*const x509_crt> for &'r LinkedCertificate { - unsafe fn from(ptr: *const x509_crt) -> Option<&'r LinkedCertificate> { - (ptr as *const LinkedCertificate).as_ref() - } + unsafe fn from(ptr: *const x509_crt) -> Option<&'r LinkedCertificate> { + (ptr as *const LinkedCertificate).as_ref() + } } impl<'r> UnsafeFrom<*mut x509_crt> for &'r mut LinkedCertificate { - unsafe fn from(ptr: *mut x509_crt) -> Option<&'r mut LinkedCertificate> { - (ptr as *mut LinkedCertificate).as_mut() - } + unsafe fn from(ptr: *mut x509_crt) -> Option<&'r mut LinkedCertificate> { + (ptr as *mut LinkedCertificate).as_mut() + } } pub struct Iter<'a> { - next: *const x509_crt, - r: PhantomData<&'a x509_crt>, + next: *const x509_crt, + r: PhantomData<&'a x509_crt>, } impl<'a> Iterator for Iter<'a> { - type Item = &'a LinkedCertificate; - - fn next(&mut self) -> Option<&'a LinkedCertificate> { - unsafe { - match self.next { - p if p == ::core::ptr::null() => None, - p => { - self.next = (*p).next as *const _; - Some(UnsafeFrom::from(p).unwrap()) - } - } - } - } + type Item = &'a LinkedCertificate; + + fn next(&mut self) -> Option<&'a LinkedCertificate> { + unsafe { + match self.next { + p if p == ::core::ptr::null() => None, + p => { + self.next = (*p).next as *const _; + Some(UnsafeFrom::from(p).unwrap()) + } + } + } + } } impl<'r> UnsafeFrom<*const x509_crt> for Iter<'r> { - unsafe fn from(ptr: *const x509_crt) -> Option> { - if ptr.is_null() { - None - } else { - Some(Iter { next: ptr, r: PhantomData }) - } - } + unsafe fn from(ptr: *const x509_crt) -> Option> { + if ptr.is_null() { + None + } else { + Some(Iter { + next: ptr, + r: PhantomData, + }) + } + } } pub struct IterMut<'a> { - next: *mut x509_crt, - r: PhantomData<&'a mut x509_crt>, + next: *mut x509_crt, + r: PhantomData<&'a mut x509_crt>, } impl<'a> Iterator for IterMut<'a> { - type Item = &'a mut LinkedCertificate; - - fn next(&mut self) -> Option<&'a mut LinkedCertificate> { - unsafe { - match self.next { - p if p == ::core::ptr::null_mut() => None, - p => { - self.next = (*p).next; - Some(UnsafeFrom::from(p).unwrap()) - } - } - } - } + type Item = &'a mut LinkedCertificate; + + fn next(&mut self) -> Option<&'a mut LinkedCertificate> { + unsafe { + match self.next { + p if p == ::core::ptr::null_mut() => None, + p => { + self.next = (*p).next; + Some(UnsafeFrom::from(p).unwrap()) + } + } + } + } } impl<'r> UnsafeFrom<*mut x509_crt> for IterMut<'r> { - unsafe fn from(ptr: *mut x509_crt) -> Option> { - if ptr.is_null() { - None - } else { - Some(IterMut { next: ptr, r: PhantomData }) - } - } + unsafe fn from(ptr: *mut x509_crt) -> Option> { + if ptr.is_null() { + None + } else { + Some(IterMut { + next: ptr, + r: PhantomData, + }) + } + } } pub struct List<'c> { - head: &'c mut Certificate, + head: &'c mut Certificate, } impl<'c> List<'c> { - pub fn iter<'i>(&'i self) -> Iter<'i> { - unsafe { UnsafeFrom::from(&self.head.inner as *const _).expect("not null") } - } - - pub fn iter_mut<'i>(&'i mut self) -> IterMut<'i> { - unsafe { UnsafeFrom::from(&mut self.head.inner as *mut _).expect("not null") } - } - - pub fn push_front(&mut self, cert: &'c mut Certificate) { - assert!(cert.inner.next==::core::ptr::null_mut()); - cert.inner.next = &mut self.head.inner; - self.head = cert; - } - - pub fn push_back(&mut self, cert: &'c mut Certificate) { - assert!(cert.inner.next==::core::ptr::null_mut()); - for c in self.iter_mut() { - if c.inner.next == ::core::ptr::null_mut() { - c.inner.next = &mut cert.inner; - break; - } - } - } - - pub fn append(&mut self, list: List<'c>) { - assert!(list.head.inner.next==::core::ptr::null_mut()); - for c in self.iter_mut() { - if c.inner.next == ::core::ptr::null_mut() { - c.inner.next = &mut list.head.inner; - break; - } - } - ::core::mem::forget(list); - } - - pub fn from_vec(vec: &'c mut Vec) -> Option> { - vec.split_first_mut().map(|(first, rest)| { - let mut list = List::from(first); - for c in rest { - list.push_back(c); - } - list - }) - } + pub fn iter<'i>(&'i self) -> Iter<'i> { + unsafe { UnsafeFrom::from(&self.head.inner as *const _).expect("not null") } + } + + pub fn iter_mut<'i>(&'i mut self) -> IterMut<'i> { + unsafe { UnsafeFrom::from(&mut self.head.inner as *mut _).expect("not null") } + } + + pub fn push_front(&mut self, cert: &'c mut Certificate) { + assert!(cert.inner.next == ::core::ptr::null_mut()); + cert.inner.next = &mut self.head.inner; + self.head = cert; + } + + pub fn push_back(&mut self, cert: &'c mut Certificate) { + assert!(cert.inner.next == ::core::ptr::null_mut()); + for c in self.iter_mut() { + if c.inner.next == ::core::ptr::null_mut() { + c.inner.next = &mut cert.inner; + break; + } + } + } + + pub fn append(&mut self, list: List<'c>) { + assert!(list.head.inner.next == ::core::ptr::null_mut()); + for c in self.iter_mut() { + if c.inner.next == ::core::ptr::null_mut() { + c.inner.next = &mut list.head.inner; + break; + } + } + ::core::mem::forget(list); + } + + pub fn from_vec(vec: &'c mut Vec) -> Option> { + vec.split_first_mut().map(|(first, rest)| { + let mut list = List::from(first); + for c in rest { + list.push_back(c); + } + list + }) + } } impl<'c> Drop for List<'c> { - fn drop(&mut self) { - // we don't own the certificates, we just need to make sure that - // x509_crt_free isn't going to try to deallocate our linked certs - for c in self.iter_mut() { - c.inner.next = ::core::ptr::null_mut(); - } - } + fn drop(&mut self) { + // we don't own the certificates, we just need to make sure that + // x509_crt_free isn't going to try to deallocate our linked certs + for c in self.iter_mut() { + c.inner.next = ::core::ptr::null_mut(); + } + } } impl<'c> From<&'c mut Certificate> for List<'c> { - fn from(cert: &'c mut Certificate) -> List<'c> { - List { head: cert } - } + fn from(cert: &'c mut Certificate) -> List<'c> { + List { head: cert } + } } impl<'c, 'r> From<&'c mut List<'r>> for &'c mut LinkedCertificate { - fn from(list: &'c mut List<'r>) -> &'c mut LinkedCertificate { - list.head - } + fn from(list: &'c mut List<'r>) -> &'c mut LinkedCertificate { + list.head + } } define!(struct Builder<'a>(x509write_cert) { @@ -339,124 +374,189 @@ define!(struct Builder<'a>(x509write_cert) { }); impl<'a> Builder<'a> { - unsafe fn subject_with_nul_unchecked(&mut self, subject: &[u8]) -> ::Result<&mut Self> { - try!(x509write_crt_set_subject_name(&mut self.inner,subject.as_ptr() as *const _).into_result()); - Ok(self) - } - - #[cfg(feature="std")] - pub fn subject(&mut self, subject: &str) -> ::Result<&mut Self> { - match ::std::ffi::CString::new(subject) { - Err(_) => Err(::Error::X509InvalidName), - Ok(s) => unsafe { self.subject_with_nul_unchecked(s.as_bytes_with_nul()) }, - } - } - - pub fn subject_with_nul(&mut self, subject: &str) -> ::Result<&mut Self> { - if subject.as_bytes().iter().any(|&c| c == 0) { - unsafe { self.subject_with_nul_unchecked(subject.as_bytes()) } - } else { - Err(::Error::X509InvalidName) - } - } - - unsafe fn issuer_with_nul_unchecked(&mut self, issuer: &[u8]) -> ::Result<&mut Self> { - try!(x509write_crt_set_issuer_name(&mut self.inner,issuer.as_ptr() as *const _).into_result()); - Ok(self) - } - - #[cfg(feature="std")] - pub fn issuer(&mut self, issuer: &str) -> ::Result<&mut Self> { - match ::std::ffi::CString::new(issuer) { - Err(_) => Err(::Error::X509InvalidName), - Ok(s) => unsafe { self.issuer_with_nul_unchecked(s.as_bytes_with_nul()) }, - } - } - - pub fn issuer_with_nul(&mut self, issuer: &str) -> ::Result<&mut Self> { - if issuer.as_bytes().iter().any(|&c| c == 0) { - unsafe { self.issuer_with_nul_unchecked(issuer.as_bytes()) } - } else { - Err(::Error::X509InvalidName) - } - } - - pub fn subject_key(&mut self, key: &'a mut ::pk::Pk) -> &mut Self { - unsafe { x509write_crt_set_subject_key(&mut self.inner, key.into()) }; - self - } - - pub fn issuer_key(&mut self, key: &'a mut ::pk::Pk) -> &mut Self { - unsafe { x509write_crt_set_issuer_key(&mut self.inner, key.into()) }; - self - } - - pub fn signature_hash(&mut self, md: ::hash::Type) -> &mut Self { - unsafe { x509write_crt_set_md_alg(&mut self.inner, md.into()) }; - self - } - - pub fn key_usage(&mut self, usage: ::x509::KeyUsage) -> ::Result<&mut Self> { - unsafe { try!(x509write_crt_set_key_usage(&mut self.inner,usage.bits()).into_result()) }; - Ok(self) - } - - pub fn extension(&mut self, oid: &[u8], val: &[u8], critical: bool) -> ::Result<&mut Self> { - unsafe{try!(x509write_crt_set_extension(&mut self.inner,oid.as_ptr() as *const _,oid.len(),critical as _,val.as_ptr(),val.len()).into_result())}; - Ok(self) - } - - pub fn basic_constraints(&mut self, ca: bool, pathlen: Option) -> ::Result<&mut Self> { - unsafe { try!(x509write_crt_set_basic_constraints(&mut self.inner,ca as _,pathlen.unwrap_or(0) as _).into_result()) }; - Ok(self) - } - - pub fn validity(&mut self, not_before: super::Time, not_after: super::Time) -> ::Result<&mut Self> { - unsafe{try!(x509write_crt_set_validity(&mut self.inner,not_before.to_x509_time().as_ptr() as _,not_after.to_x509_time().as_ptr() as _).into_result())}; - Ok(self) - } - - pub fn serial(&mut self, serial: &[u8]) -> ::Result<&mut Self> { - let serial = try!(::bignum::Mpi::from_binary(serial)); - unsafe { try!(x509write_crt_set_serial(&mut self.inner,(&serial).into()).into_result()) }; - Ok(self) - } - - pub fn write_der<'buf, F: ::rng::Random>(&mut self, buf: &'buf mut [u8], rng: &mut F) -> ::Result> { - match unsafe { - x509write_crt_der(&mut self.inner, buf.as_mut_ptr(), buf.len(), Some(F::call), rng.data_ptr()).into_result() - } { - Err(::Error::Asn1BufTooSmall) => Ok(None), - Err(e) => Err(e), - Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), - } - } - - pub fn write_der_vec(&mut self, rng: &mut F) -> ::Result> { - ::private::alloc_vec_repeat(|buf, size| unsafe { - x509write_crt_der(&mut self.inner, buf, size, Some(F::call), rng.data_ptr()) - }, - true) - } - - pub fn write_pem<'buf, F: ::rng::Random>(&mut self, buf: &'buf mut [u8], rng: &mut F) -> ::Result> { - match unsafe { - x509write_crt_der(&mut self.inner, buf.as_mut_ptr(), buf.len(), Some(F::call), rng.data_ptr()).into_result() - } { - Err(::Error::Base64BufferTooSmall) => Ok(None), - Err(e) => Err(e), - Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), - } - } - - pub fn write_pem_string(&mut self, rng: &mut F) -> ::Result { - ::private::alloc_string_repeat(|buf, size| unsafe { - match x509write_crt_pem(&mut self.inner, buf as _, size, Some(F::call), rng.data_ptr()) { - 0 => ::private::cstr_to_slice(buf as _).len() as _, - r => r, - } - }) - } + unsafe fn subject_with_nul_unchecked(&mut self, subject: &[u8]) -> ::Result<&mut Self> { + try!( + x509write_crt_set_subject_name(&mut self.inner, subject.as_ptr() as *const _) + .into_result() + ); + Ok(self) + } + + #[cfg(feature = "std")] + pub fn subject(&mut self, subject: &str) -> ::Result<&mut Self> { + match ::std::ffi::CString::new(subject) { + Err(_) => Err(::Error::X509InvalidName), + Ok(s) => unsafe { self.subject_with_nul_unchecked(s.as_bytes_with_nul()) }, + } + } + + pub fn subject_with_nul(&mut self, subject: &str) -> ::Result<&mut Self> { + if subject.as_bytes().iter().any(|&c| c == 0) { + unsafe { self.subject_with_nul_unchecked(subject.as_bytes()) } + } else { + Err(::Error::X509InvalidName) + } + } + + unsafe fn issuer_with_nul_unchecked(&mut self, issuer: &[u8]) -> ::Result<&mut Self> { + try!( + x509write_crt_set_issuer_name(&mut self.inner, issuer.as_ptr() as *const _) + .into_result() + ); + Ok(self) + } + + #[cfg(feature = "std")] + pub fn issuer(&mut self, issuer: &str) -> ::Result<&mut Self> { + match ::std::ffi::CString::new(issuer) { + Err(_) => Err(::Error::X509InvalidName), + Ok(s) => unsafe { self.issuer_with_nul_unchecked(s.as_bytes_with_nul()) }, + } + } + + pub fn issuer_with_nul(&mut self, issuer: &str) -> ::Result<&mut Self> { + if issuer.as_bytes().iter().any(|&c| c == 0) { + unsafe { self.issuer_with_nul_unchecked(issuer.as_bytes()) } + } else { + Err(::Error::X509InvalidName) + } + } + + pub fn subject_key(&mut self, key: &'a mut ::pk::Pk) -> &mut Self { + unsafe { x509write_crt_set_subject_key(&mut self.inner, key.into()) }; + self + } + + pub fn issuer_key(&mut self, key: &'a mut ::pk::Pk) -> &mut Self { + unsafe { x509write_crt_set_issuer_key(&mut self.inner, key.into()) }; + self + } + + pub fn signature_hash(&mut self, md: ::hash::Type) -> &mut Self { + unsafe { x509write_crt_set_md_alg(&mut self.inner, md.into()) }; + self + } + + pub fn key_usage(&mut self, usage: ::x509::KeyUsage) -> ::Result<&mut Self> { + unsafe { try!(x509write_crt_set_key_usage(&mut self.inner, usage.bits()).into_result()) }; + Ok(self) + } + + pub fn extension(&mut self, oid: &[u8], val: &[u8], critical: bool) -> ::Result<&mut Self> { + unsafe { + try!( + x509write_crt_set_extension( + &mut self.inner, + oid.as_ptr() as *const _, + oid.len(), + critical as _, + val.as_ptr(), + val.len() + ).into_result() + ) + }; + Ok(self) + } + + pub fn basic_constraints(&mut self, ca: bool, pathlen: Option) -> ::Result<&mut Self> { + unsafe { + try!( + x509write_crt_set_basic_constraints( + &mut self.inner, + ca as _, + pathlen.unwrap_or(0) as _ + ).into_result() + ) + }; + Ok(self) + } + + pub fn validity( + &mut self, + not_before: super::Time, + not_after: super::Time, + ) -> ::Result<&mut Self> { + unsafe { + try!( + x509write_crt_set_validity( + &mut self.inner, + not_before.to_x509_time().as_ptr() as _, + not_after.to_x509_time().as_ptr() as _ + ).into_result() + ) + }; + Ok(self) + } + + pub fn serial(&mut self, serial: &[u8]) -> ::Result<&mut Self> { + let serial = try!(::bignum::Mpi::from_binary(serial)); + unsafe { try!(x509write_crt_set_serial(&mut self.inner, (&serial).into()).into_result()) }; + Ok(self) + } + + pub fn write_der<'buf, F: ::rng::Random>( + &mut self, + buf: &'buf mut [u8], + rng: &mut F, + ) -> ::Result> { + match unsafe { + x509write_crt_der( + &mut self.inner, + buf.as_mut_ptr(), + buf.len(), + Some(F::call), + rng.data_ptr(), + ).into_result() + } { + Err(::Error::Asn1BufTooSmall) => Ok(None), + Err(e) => Err(e), + Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), + } + } + + pub fn write_der_vec(&mut self, rng: &mut F) -> ::Result> { + ::private::alloc_vec_repeat( + |buf, size| unsafe { + x509write_crt_der(&mut self.inner, buf, size, Some(F::call), rng.data_ptr()) + }, + true, + ) + } + + pub fn write_pem<'buf, F: ::rng::Random>( + &mut self, + buf: &'buf mut [u8], + rng: &mut F, + ) -> ::Result> { + match unsafe { + x509write_crt_der( + &mut self.inner, + buf.as_mut_ptr(), + buf.len(), + Some(F::call), + rng.data_ptr(), + ).into_result() + } { + Err(::Error::Base64BufferTooSmall) => Ok(None), + Err(e) => Err(e), + Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), + } + } + + pub fn write_pem_string(&mut self, rng: &mut F) -> ::Result { + ::private::alloc_string_repeat(|buf, size| unsafe { + match x509write_crt_pem( + &mut self.inner, + buf as _, + size, + Some(F::call), + rng.data_ptr(), + ) { + 0 => ::private::cstr_to_slice(buf as _).len() as _, + r => r, + } + }) + } } // TODO @@ -468,40 +568,41 @@ impl<'a> Builder<'a> { #[cfg(test)] mod tests { - use super::*; - use pk::Pk; - - struct Test { - key1: Pk, - key2: Pk, - } - - impl Test { - fn new() -> Self { - Test { - key1: Pk::from_private_key(::test_support::keys::PEM_KEY, None).unwrap(), - key2: Pk::from_private_key(::test_support::keys::PEM_KEY, None).unwrap(), - } - } - - fn builder<'a>(&'a mut self) -> Builder<'a> { - use x509::Time; - - let mut b = Builder::new(); - b.subject_key(&mut self.key1) - .subject_with_nul("CN=mbedtls.example\0") - .unwrap() - .issuer_key(&mut self.key2) - .issuer_with_nul("CN=mbedtls.example\0") - .unwrap() - .validity(Time::new(2000, 1, 1, 0, 0, 0).unwrap(), - Time::new(2009, 12, 31, 23, 59, 59).unwrap()) - .unwrap(); - b - } - } - - const TEST_PEM: &'static str = r"-----BEGIN CERTIFICATE----- + use super::*; + use pk::Pk; + + struct Test { + key1: Pk, + key2: Pk, + } + + impl Test { + fn new() -> Self { + Test { + key1: Pk::from_private_key(::test_support::keys::PEM_KEY, None).unwrap(), + key2: Pk::from_private_key(::test_support::keys::PEM_KEY, None).unwrap(), + } + } + + fn builder<'a>(&'a mut self) -> Builder<'a> { + use x509::Time; + + let mut b = Builder::new(); + b.subject_key(&mut self.key1) + .subject_with_nul("CN=mbedtls.example\0") + .unwrap() + .issuer_key(&mut self.key2) + .issuer_with_nul("CN=mbedtls.example\0") + .unwrap() + .validity( + Time::new(2000, 1, 1, 0, 0, 0).unwrap(), + Time::new(2009, 12, 31, 23, 59, 59).unwrap(), + ).unwrap(); + b + } + } + + const TEST_PEM: &'static str = r"-----BEGIN CERTIFICATE----- MIICsDCCAZigAwIBAgIAMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNVBAMTD21iZWR0 bHMuZXhhbXBsZTAeFw0wMDAxMDEwMDAwMDBaFw0wOTEyMzEyMzU5NTlaMBoxGDAW BgNVBAMTD21iZWR0bHMuZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC @@ -520,62 +621,75 @@ yj9wo3CnzOvVa5Yt1HWfKWYX3RVeSDvOaN2rrKauiVQ/KPSD9gWrySCt7Kqp+Ruk -----END CERTIFICATE----- "; - const TEST_DER: &'static [u8] = - &[0x30, 0x82, 0x02, 0xb0, 0x30, 0x82, 0x01, 0x98, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x00, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1a, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x0f, 0x6d, 0x62, 0x65, 0x64, 0x74, 0x6c, 0x73, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, - 0x0d, 0x30, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x1a, 0x31, 0x18, 0x30, - 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x6d, 0x62, 0x65, 0x64, 0x74, 0x6c, 0x73, 0x2e, 0x65, 0x78, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc5, - 0x8c, 0x08, 0x26, 0x08, 0x95, 0x26, 0x28, 0x04, 0x3f, 0x38, 0x08, 0x34, 0x30, 0x18, 0x77, 0x13, 0x6f, 0xa5, 0xe5, - 0xab, 0x12, 0x1d, 0xd0, 0x4d, 0x99, 0x39, 0xb4, 0x82, 0xbd, 0xef, 0x9a, 0x79, 0x85, 0x71, 0x4a, 0xa5, 0x22, 0x95, - 0x06, 0xdc, 0x11, 0x9d, 0xf3, 0x9a, 0x34, 0x73, 0xd5, 0xf9, 0xaa, 0x7c, 0x41, 0x28, 0x96, 0x9f, 0x4c, 0x92, 0xee, - 0xdb, 0x14, 0x6a, 0x8f, 0x1d, 0x53, 0x32, 0x50, 0x5d, 0xb5, 0x5a, 0x4f, 0xd0, 0x25, 0xf2, 0xe6, 0xa3, 0xd8, 0xc2, - 0xf3, 0xbc, 0x51, 0x62, 0x06, 0xca, 0xbb, 0x27, 0x8b, 0x2f, 0x06, 0x7e, 0x90, 0xe3, 0x5c, 0x69, 0x14, 0x15, 0xb9, - 0xbd, 0xd4, 0x2c, 0x35, 0x73, 0xf9, 0x42, 0x0f, 0xb4, 0x75, 0xea, 0x52, 0xc7, 0x2b, 0xee, 0xcd, 0xa6, 0xaf, 0x68, - 0xc6, 0x99, 0x37, 0x29, 0xf3, 0x07, 0x8a, 0xf4, 0x28, 0xac, 0x57, 0x77, 0xd5, 0xbc, 0xa8, 0xd1, 0x5c, 0x59, 0xbf, - 0xfb, 0x05, 0x61, 0x58, 0x82, 0x6c, 0x3b, 0x4e, 0x62, 0x63, 0x22, 0x7d, 0x05, 0xff, 0xaa, 0x4a, 0xac, 0x6e, 0xf9, - 0x31, 0x4a, 0xe3, 0xe4, 0x97, 0x3a, 0x71, 0x03, 0x11, 0x7c, 0xdb, 0x89, 0xad, 0x28, 0xc4, 0x62, 0x9b, 0x01, 0x90, - 0x6d, 0x9e, 0x2d, 0x6c, 0xb9, 0x40, 0x14, 0xdb, 0xa0, 0x3b, 0x4d, 0x9e, 0x57, 0x41, 0xea, 0xf3, 0x11, 0xf1, 0x7d, - 0xb9, 0x8d, 0xad, 0xb9, 0x52, 0xa8, 0x8c, 0xba, 0xf3, 0xf5, 0x1d, 0x8e, 0x0e, 0x18, 0xf5, 0xf7, 0x85, 0x8b, 0xc3, - 0x55, 0x7d, 0x88, 0x3f, 0xae, 0xc1, 0x63, 0xb8, 0xbf, 0x85, 0xbf, 0xfd, 0xdd, 0x2c, 0x10, 0x61, 0x68, 0xc7, 0xdf, - 0xc9, 0x5f, 0x49, 0xd1, 0xe5, 0x0b, 0x5e, 0x05, 0x70, 0xe5, 0x95, 0xcd, 0x69, 0x08, 0x0a, 0x6f, 0xab, 0x12, 0x05, - 0x0a, 0xa2, 0x53, 0x72, 0xdf, 0xb4, 0x70, 0xd3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x02, 0x30, 0x00, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x73, - 0xef, 0x7e, 0x60, 0xaa, 0x15, 0x1a, 0x32, 0x40, 0x04, 0xcf, 0xa3, 0xc6, 0x95, 0xd7, 0xa4, 0x02, 0xdb, 0x6a, 0xe9, - 0x1e, 0x23, 0x0b, 0xf7, 0xa4, 0x20, 0x8c, 0x73, 0xfe, 0x0b, 0x5d, 0x94, 0xfc, 0x0e, 0x1c, 0x56, 0x7e, 0x50, 0xbb, - 0x81, 0xa1, 0x06, 0x6b, 0x5e, 0x49, 0xb3, 0x2b, 0xff, 0x90, 0xb7, 0x11, 0x7b, 0x46, 0xaf, 0x71, 0xec, 0x72, 0xa2, - 0xe4, 0x99, 0xc5, 0x6e, 0xf8, 0x85, 0x1d, 0xf4, 0x28, 0xf5, 0xae, 0x10, 0x1c, 0xc9, 0x1e, 0x87, 0x03, 0x73, 0x8c, - 0x1c, 0xbd, 0x7b, 0x5d, 0xae, 0xa6, 0x85, 0xbf, 0x2a, 0x6d, 0x4d, 0x6a, 0xd4, 0x95, 0x41, 0xca, 0x3f, 0x70, 0xa3, - 0x70, 0xa7, 0xcc, 0xeb, 0xd5, 0x6b, 0x96, 0x2d, 0xd4, 0x75, 0x9f, 0x29, 0x66, 0x17, 0xdd, 0x15, 0x5e, 0x48, 0x3b, - 0xce, 0x68, 0xdd, 0xab, 0xac, 0xa6, 0xae, 0x89, 0x54, 0x3f, 0x28, 0xf4, 0x83, 0xf6, 0x05, 0xab, 0xc9, 0x20, 0xad, - 0xec, 0xaa, 0xa9, 0xf9, 0x1b, 0xa4, 0xd4, 0x86, 0xf7, 0x36, 0x2d, 0x6b, 0xa5, 0x66, 0x54, 0x8f, 0x30, 0x11, 0x4d, - 0x14, 0xc7, 0x7c, 0x89, 0x46, 0x61, 0x6b, 0x03, 0xf3, 0x4f, 0x27, 0x8c, 0xed, 0x0a, 0xb5, 0x5a, 0x2b, 0xa6, 0xbb, - 0x28, 0x54, 0x54, 0x6b, 0xe2, 0x39, 0x9b, 0x17, 0x6a, 0xc8, 0x4e, 0xaa, 0x02, 0x59, 0x71, 0x2c, 0xda, 0xf8, 0x01, - 0xf0, 0x35, 0x68, 0x5b, 0x2e, 0x7b, 0xff, 0x28, 0x32, 0x5e, 0xa1, 0x58, 0x4d, 0x0d, 0x9f, 0xd2, 0x3a, 0x9c, 0x57, - 0x54, 0x8c, 0x37, 0x09, 0xf9, 0x89, 0x69, 0x48, 0xf4, 0x9b, 0xce, 0xac, 0xb7, 0x7d, 0x96, 0x39, 0xa6, 0xa2, 0x74, - 0x76, 0x1a, 0x27, 0x96, 0x4c, 0x70, 0xfe, 0xe4, 0xfc, 0x97, 0xae, 0xab, 0x61, 0xe4, 0x9f, 0x60, 0x50, 0xaf, 0xa4, - 0x84, 0x7f, 0x2b, 0x09, 0xec, 0xb2, 0xd4, 0xc9]; - - #[test] - fn write_der() { - let mut t = Test::new(); - let output = t.builder() - .signature_hash(::hash::Type::Sha256) - .write_der_vec(&mut ::test_support::rand::test_rng()) - .unwrap(); - assert!(output==TEST_DER); - } - - #[test] - fn write_pem() { - let mut t = Test::new(); - let output = t.builder() - .signature_hash(::hash::Type::Sha256) - .write_pem_string(&mut ::test_support::rand::test_rng()) - .unwrap(); - assert_eq!(output,TEST_PEM); - } + const TEST_DER: &'static [u8] = &[ + 0x30, 0x82, 0x02, 0xb0, 0x30, 0x82, 0x01, 0x98, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x00, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x30, 0x1a, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x6d, 0x62, + 0x65, 0x64, 0x74, 0x6c, 0x73, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x30, 0x1e, + 0x17, 0x0d, 0x30, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, + 0x17, 0x0d, 0x30, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, + 0x30, 0x1a, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x6d, 0x62, + 0x65, 0x64, 0x74, 0x6c, 0x73, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x30, 0x82, + 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, + 0x00, 0xc5, 0x8c, 0x08, 0x26, 0x08, 0x95, 0x26, 0x28, 0x04, 0x3f, 0x38, 0x08, 0x34, 0x30, + 0x18, 0x77, 0x13, 0x6f, 0xa5, 0xe5, 0xab, 0x12, 0x1d, 0xd0, 0x4d, 0x99, 0x39, 0xb4, 0x82, + 0xbd, 0xef, 0x9a, 0x79, 0x85, 0x71, 0x4a, 0xa5, 0x22, 0x95, 0x06, 0xdc, 0x11, 0x9d, 0xf3, + 0x9a, 0x34, 0x73, 0xd5, 0xf9, 0xaa, 0x7c, 0x41, 0x28, 0x96, 0x9f, 0x4c, 0x92, 0xee, 0xdb, + 0x14, 0x6a, 0x8f, 0x1d, 0x53, 0x32, 0x50, 0x5d, 0xb5, 0x5a, 0x4f, 0xd0, 0x25, 0xf2, 0xe6, + 0xa3, 0xd8, 0xc2, 0xf3, 0xbc, 0x51, 0x62, 0x06, 0xca, 0xbb, 0x27, 0x8b, 0x2f, 0x06, 0x7e, + 0x90, 0xe3, 0x5c, 0x69, 0x14, 0x15, 0xb9, 0xbd, 0xd4, 0x2c, 0x35, 0x73, 0xf9, 0x42, 0x0f, + 0xb4, 0x75, 0xea, 0x52, 0xc7, 0x2b, 0xee, 0xcd, 0xa6, 0xaf, 0x68, 0xc6, 0x99, 0x37, 0x29, + 0xf3, 0x07, 0x8a, 0xf4, 0x28, 0xac, 0x57, 0x77, 0xd5, 0xbc, 0xa8, 0xd1, 0x5c, 0x59, 0xbf, + 0xfb, 0x05, 0x61, 0x58, 0x82, 0x6c, 0x3b, 0x4e, 0x62, 0x63, 0x22, 0x7d, 0x05, 0xff, 0xaa, + 0x4a, 0xac, 0x6e, 0xf9, 0x31, 0x4a, 0xe3, 0xe4, 0x97, 0x3a, 0x71, 0x03, 0x11, 0x7c, 0xdb, + 0x89, 0xad, 0x28, 0xc4, 0x62, 0x9b, 0x01, 0x90, 0x6d, 0x9e, 0x2d, 0x6c, 0xb9, 0x40, 0x14, + 0xdb, 0xa0, 0x3b, 0x4d, 0x9e, 0x57, 0x41, 0xea, 0xf3, 0x11, 0xf1, 0x7d, 0xb9, 0x8d, 0xad, + 0xb9, 0x52, 0xa8, 0x8c, 0xba, 0xf3, 0xf5, 0x1d, 0x8e, 0x0e, 0x18, 0xf5, 0xf7, 0x85, 0x8b, + 0xc3, 0x55, 0x7d, 0x88, 0x3f, 0xae, 0xc1, 0x63, 0xb8, 0xbf, 0x85, 0xbf, 0xfd, 0xdd, 0x2c, + 0x10, 0x61, 0x68, 0xc7, 0xdf, 0xc9, 0x5f, 0x49, 0xd1, 0xe5, 0x0b, 0x5e, 0x05, 0x70, 0xe5, + 0x95, 0xcd, 0x69, 0x08, 0x0a, 0x6f, 0xab, 0x12, 0x05, 0x0a, 0xa2, 0x53, 0x72, 0xdf, 0xb4, + 0x70, 0xd3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x02, 0x30, 0x00, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x73, 0xef, 0x7e, 0x60, 0xaa, 0x15, 0x1a, 0x32, 0x40, 0x04, 0xcf, 0xa3, 0xc6, 0x95, + 0xd7, 0xa4, 0x02, 0xdb, 0x6a, 0xe9, 0x1e, 0x23, 0x0b, 0xf7, 0xa4, 0x20, 0x8c, 0x73, 0xfe, + 0x0b, 0x5d, 0x94, 0xfc, 0x0e, 0x1c, 0x56, 0x7e, 0x50, 0xbb, 0x81, 0xa1, 0x06, 0x6b, 0x5e, + 0x49, 0xb3, 0x2b, 0xff, 0x90, 0xb7, 0x11, 0x7b, 0x46, 0xaf, 0x71, 0xec, 0x72, 0xa2, 0xe4, + 0x99, 0xc5, 0x6e, 0xf8, 0x85, 0x1d, 0xf4, 0x28, 0xf5, 0xae, 0x10, 0x1c, 0xc9, 0x1e, 0x87, + 0x03, 0x73, 0x8c, 0x1c, 0xbd, 0x7b, 0x5d, 0xae, 0xa6, 0x85, 0xbf, 0x2a, 0x6d, 0x4d, 0x6a, + 0xd4, 0x95, 0x41, 0xca, 0x3f, 0x70, 0xa3, 0x70, 0xa7, 0xcc, 0xeb, 0xd5, 0x6b, 0x96, 0x2d, + 0xd4, 0x75, 0x9f, 0x29, 0x66, 0x17, 0xdd, 0x15, 0x5e, 0x48, 0x3b, 0xce, 0x68, 0xdd, 0xab, + 0xac, 0xa6, 0xae, 0x89, 0x54, 0x3f, 0x28, 0xf4, 0x83, 0xf6, 0x05, 0xab, 0xc9, 0x20, 0xad, + 0xec, 0xaa, 0xa9, 0xf9, 0x1b, 0xa4, 0xd4, 0x86, 0xf7, 0x36, 0x2d, 0x6b, 0xa5, 0x66, 0x54, + 0x8f, 0x30, 0x11, 0x4d, 0x14, 0xc7, 0x7c, 0x89, 0x46, 0x61, 0x6b, 0x03, 0xf3, 0x4f, 0x27, + 0x8c, 0xed, 0x0a, 0xb5, 0x5a, 0x2b, 0xa6, 0xbb, 0x28, 0x54, 0x54, 0x6b, 0xe2, 0x39, 0x9b, + 0x17, 0x6a, 0xc8, 0x4e, 0xaa, 0x02, 0x59, 0x71, 0x2c, 0xda, 0xf8, 0x01, 0xf0, 0x35, 0x68, + 0x5b, 0x2e, 0x7b, 0xff, 0x28, 0x32, 0x5e, 0xa1, 0x58, 0x4d, 0x0d, 0x9f, 0xd2, 0x3a, 0x9c, + 0x57, 0x54, 0x8c, 0x37, 0x09, 0xf9, 0x89, 0x69, 0x48, 0xf4, 0x9b, 0xce, 0xac, 0xb7, 0x7d, + 0x96, 0x39, 0xa6, 0xa2, 0x74, 0x76, 0x1a, 0x27, 0x96, 0x4c, 0x70, 0xfe, 0xe4, 0xfc, 0x97, + 0xae, 0xab, 0x61, 0xe4, 0x9f, 0x60, 0x50, 0xaf, 0xa4, 0x84, 0x7f, 0x2b, 0x09, 0xec, 0xb2, + 0xd4, 0xc9, + ]; + + #[test] + fn write_der() { + let mut t = Test::new(); + let output = t + .builder() + .signature_hash(::hash::Type::Sha256) + .write_der_vec(&mut ::test_support::rand::test_rng()) + .unwrap(); + assert!(output == TEST_DER); + } + + #[test] + fn write_pem() { + let mut t = Test::new(); + let output = t + .builder() + .signature_hash(::hash::Type::Sha256) + .write_pem_string(&mut ::test_support::rand::test_rng()) + .unwrap(); + assert_eq!(output, TEST_PEM); + } } diff --git a/mbedtls/src/x509/crl.rs b/mbedtls/src/x509/crl.rs index f4935b4da..1d53e438e 100644 --- a/mbedtls/src/x509/crl.rs +++ b/mbedtls/src/x509/crl.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use core::fmt; @@ -21,24 +21,32 @@ struct Crl(x509_crl) { }); impl Crl { - pub fn push_from_der(&mut self, der: &[u8]) -> ::Result<()> { - unsafe { x509_crl_parse_der(&mut self.inner, der.as_ptr(), der.len()).into_result().map(|_| ()) } - } - - pub fn push_from_pem(&mut self, pem: &[u8]) -> ::Result<()> { - unsafe { x509_crl_parse(&mut self.inner, pem.as_ptr(), pem.len()).into_result().map(|_| ()) } - } + pub fn push_from_der(&mut self, der: &[u8]) -> ::Result<()> { + unsafe { + x509_crl_parse_der(&mut self.inner, der.as_ptr(), der.len()) + .into_result() + .map(|_| ()) + } + } + + pub fn push_from_pem(&mut self, pem: &[u8]) -> ::Result<()> { + unsafe { + x509_crl_parse(&mut self.inner, pem.as_ptr(), pem.len()) + .into_result() + .map(|_| ()) + } + } } impl fmt::Debug for Crl { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match ::private::alloc_string_repeat(|buf, size| unsafe { - x509_crl_info(buf, size, b"\0".as_ptr() as *const _, &self.inner) - }) { - Err(_) => Err(fmt::Error), - Ok(s) => f.write_str(&s), - } - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match ::private::alloc_string_repeat(|buf, size| unsafe { + x509_crl_info(buf, size, b"\0".as_ptr() as *const _, &self.inner) + }) { + Err(_) => Err(fmt::Error), + Ok(s) => f.write_str(&s), + } + } } // TODO diff --git a/mbedtls/src/x509/csr.rs b/mbedtls/src/x509/csr.rs index 6d71ad8ae..e29a3f429 100644 --- a/mbedtls/src/x509/csr.rs +++ b/mbedtls/src/x509/csr.rs @@ -1,14 +1,14 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ use core::fmt; -#[cfg(not(feature="std"))] +#[cfg(not(feature = "std"))] use alloc_prelude::*; use mbedtls_sys::*; @@ -23,44 +23,49 @@ struct Csr(x509_csr) { }); impl Csr { - pub fn from_der(der: &[u8]) -> ::Result { - let mut ret = Self::init(); - unsafe { try!(x509_csr_parse_der(&mut ret.inner,der.as_ptr(),der.len()).into_result()) }; - Ok(ret) - } - - pub fn from_pem(pem: &[u8]) -> ::Result { - let mut ret = Self::init(); - unsafe { try!(x509_csr_parse(&mut ret.inner,pem.as_ptr(),pem.len()).into_result()) }; - Ok(ret) - } - - pub fn subject(&self) -> ::Result { - ::private::alloc_string_repeat(|buf, size| unsafe { x509_dn_gets(buf, size, &self.inner.subject) }) - } - - pub fn subject_raw(&self) -> ::Result> { - ::private::alloc_vec_repeat(|buf, size| unsafe { x509_dn_gets(buf as _, size, &self.inner.subject) }, false) - } - - pub fn public_key(&self) -> &::pk::Pk { - unsafe { &*(&self.inner.pk as *const _ as *const _) } - } - - pub fn as_der(&self) -> &[u8] { - unsafe { ::core::slice::from_raw_parts(self.inner.raw.p, self.inner.raw.len) } - } + pub fn from_der(der: &[u8]) -> ::Result { + let mut ret = Self::init(); + unsafe { try!(x509_csr_parse_der(&mut ret.inner, der.as_ptr(), der.len()).into_result()) }; + Ok(ret) + } + + pub fn from_pem(pem: &[u8]) -> ::Result { + let mut ret = Self::init(); + unsafe { try!(x509_csr_parse(&mut ret.inner, pem.as_ptr(), pem.len()).into_result()) }; + Ok(ret) + } + + pub fn subject(&self) -> ::Result { + ::private::alloc_string_repeat(|buf, size| unsafe { + x509_dn_gets(buf, size, &self.inner.subject) + }) + } + + pub fn subject_raw(&self) -> ::Result> { + ::private::alloc_vec_repeat( + |buf, size| unsafe { x509_dn_gets(buf as _, size, &self.inner.subject) }, + false, + ) + } + + pub fn public_key(&self) -> &::pk::Pk { + unsafe { &*(&self.inner.pk as *const _ as *const _) } + } + + pub fn as_der(&self) -> &[u8] { + unsafe { ::core::slice::from_raw_parts(self.inner.raw.p, self.inner.raw.len) } + } } impl fmt::Debug for Csr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match ::private::alloc_string_repeat(|buf, size| unsafe { - x509_csr_info(buf, size, b"\0".as_ptr() as *const _, &self.inner) - }) { - Err(_) => Err(fmt::Error), - Ok(s) => f.write_str(&s), - } - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match ::private::alloc_string_repeat(|buf, size| unsafe { + x509_csr_info(buf, size, b"\0".as_ptr() as *const _, &self.inner) + }) { + Err(_) => Err(fmt::Error), + Ok(s) => f.write_str(&s), + } + } } define!(struct Builder<'a>(x509write_csr) { @@ -69,88 +74,131 @@ define!(struct Builder<'a>(x509write_csr) { }); impl<'a> Builder<'a> { - unsafe fn subject_with_nul_unchecked(&mut self, subject: &[u8]) -> ::Result<&mut Self> { - try!(x509write_csr_set_subject_name(&mut self.inner,subject.as_ptr() as *const _).into_result()); - Ok(self) - } - - #[cfg(feature="std")] - pub fn subject(&mut self, subject: &str) -> ::Result<&mut Self> { - match ::std::ffi::CString::new(subject) { - Err(_) => Err(::Error::X509InvalidName), - Ok(s) => unsafe { self.subject_with_nul_unchecked(s.as_bytes_with_nul()) }, - } - } - - pub fn subject_with_nul(&mut self, subject: &str) -> ::Result<&mut Self> { - if subject.as_bytes().iter().any(|&c| c == 0) { - unsafe { self.subject_with_nul_unchecked(subject.as_bytes()) } - } else { - Err(::Error::X509InvalidName) - } - } - - pub fn key(&mut self, key: &'a mut ::pk::Pk) -> &mut Self { - unsafe { x509write_csr_set_key(&mut self.inner, key.into()) }; - self - } - - pub fn signature_hash(&mut self, md: ::hash::Type) -> &mut Self { - unsafe { x509write_csr_set_md_alg(&mut self.inner, md.into()) }; - self - } - - pub fn key_usage(&mut self, usage: ::x509::KeyUsage) -> ::Result<&mut Self> { - let usage = usage.bits(); - if (usage & !0xfe) != 0 { - // according to x509write_**crt**_set_key_usage - return Err(::Error::X509FeatureUnavailable); - } - - unsafe { try!(x509write_csr_set_key_usage(&mut self.inner,(usage&0xfe) as u8).into_result()) }; - Ok(self) - } - - pub fn extension(&mut self, oid: &[u8], val: &[u8]) -> ::Result<&mut Self> { - unsafe{try!(x509write_csr_set_extension(&mut self.inner,oid.as_ptr() as *const _,oid.len(),val.as_ptr(),val.len()).into_result())}; - Ok(self) - } - - pub fn write_der<'buf, F: ::rng::Random>(&mut self, buf: &'buf mut [u8], rng: &mut F) -> ::Result> { - match unsafe { - x509write_csr_der(&mut self.inner, buf.as_mut_ptr(), buf.len(), Some(F::call), rng.data_ptr()).into_result() - } { - Err(::Error::Asn1BufTooSmall) => Ok(None), - Err(e) => Err(e), - Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), - } - } - - pub fn write_der_vec(&mut self, rng: &mut F) -> ::Result> { - ::private::alloc_vec_repeat(|buf, size| unsafe { - x509write_csr_der(&mut self.inner, buf, size, Some(F::call), rng.data_ptr()) - }, - true) - } - - pub fn write_pem<'buf, F: ::rng::Random>(&mut self, buf: &'buf mut [u8], rng: &mut F) -> ::Result> { - match unsafe { - x509write_csr_der(&mut self.inner, buf.as_mut_ptr(), buf.len(), Some(F::call), rng.data_ptr()).into_result() - } { - Err(::Error::Base64BufferTooSmall) => Ok(None), - Err(e) => Err(e), - Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), - } - } - - pub fn write_pem_string(&mut self, rng: &mut F) -> ::Result { - ::private::alloc_string_repeat(|buf, size| unsafe { - match x509write_csr_pem(&mut self.inner, buf as _, size, Some(F::call), rng.data_ptr()) { - 0 => ::private::cstr_to_slice(buf as _).len() as _, - r => r, - } - }) - } + unsafe fn subject_with_nul_unchecked(&mut self, subject: &[u8]) -> ::Result<&mut Self> { + try!( + x509write_csr_set_subject_name(&mut self.inner, subject.as_ptr() as *const _) + .into_result() + ); + Ok(self) + } + + #[cfg(feature = "std")] + pub fn subject(&mut self, subject: &str) -> ::Result<&mut Self> { + match ::std::ffi::CString::new(subject) { + Err(_) => Err(::Error::X509InvalidName), + Ok(s) => unsafe { self.subject_with_nul_unchecked(s.as_bytes_with_nul()) }, + } + } + + pub fn subject_with_nul(&mut self, subject: &str) -> ::Result<&mut Self> { + if subject.as_bytes().iter().any(|&c| c == 0) { + unsafe { self.subject_with_nul_unchecked(subject.as_bytes()) } + } else { + Err(::Error::X509InvalidName) + } + } + + pub fn key(&mut self, key: &'a mut ::pk::Pk) -> &mut Self { + unsafe { x509write_csr_set_key(&mut self.inner, key.into()) }; + self + } + + pub fn signature_hash(&mut self, md: ::hash::Type) -> &mut Self { + unsafe { x509write_csr_set_md_alg(&mut self.inner, md.into()) }; + self + } + + pub fn key_usage(&mut self, usage: ::x509::KeyUsage) -> ::Result<&mut Self> { + let usage = usage.bits(); + if (usage & !0xfe) != 0 { + // according to x509write_**crt**_set_key_usage + return Err(::Error::X509FeatureUnavailable); + } + + unsafe { + try!(x509write_csr_set_key_usage(&mut self.inner, (usage & 0xfe) as u8).into_result()) + }; + Ok(self) + } + + pub fn extension(&mut self, oid: &[u8], val: &[u8]) -> ::Result<&mut Self> { + unsafe { + try!( + x509write_csr_set_extension( + &mut self.inner, + oid.as_ptr() as *const _, + oid.len(), + val.as_ptr(), + val.len() + ).into_result() + ) + }; + Ok(self) + } + + pub fn write_der<'buf, F: ::rng::Random>( + &mut self, + buf: &'buf mut [u8], + rng: &mut F, + ) -> ::Result> { + match unsafe { + x509write_csr_der( + &mut self.inner, + buf.as_mut_ptr(), + buf.len(), + Some(F::call), + rng.data_ptr(), + ).into_result() + } { + Err(::Error::Asn1BufTooSmall) => Ok(None), + Err(e) => Err(e), + Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), + } + } + + pub fn write_der_vec(&mut self, rng: &mut F) -> ::Result> { + ::private::alloc_vec_repeat( + |buf, size| unsafe { + x509write_csr_der(&mut self.inner, buf, size, Some(F::call), rng.data_ptr()) + }, + true, + ) + } + + pub fn write_pem<'buf, F: ::rng::Random>( + &mut self, + buf: &'buf mut [u8], + rng: &mut F, + ) -> ::Result> { + match unsafe { + x509write_csr_der( + &mut self.inner, + buf.as_mut_ptr(), + buf.len(), + Some(F::call), + rng.data_ptr(), + ).into_result() + } { + Err(::Error::Base64BufferTooSmall) => Ok(None), + Err(e) => Err(e), + Ok(n) => Ok(Some(&buf[buf.len() - (n as usize)..])), + } + } + + pub fn write_pem_string(&mut self, rng: &mut F) -> ::Result { + ::private::alloc_string_repeat(|buf, size| unsafe { + match x509write_csr_pem( + &mut self.inner, + buf as _, + size, + Some(F::call), + rng.data_ptr(), + ) { + 0 => ::private::cstr_to_slice(buf as _).len() as _, + r => r, + } + }) + } } // TODO @@ -159,27 +207,29 @@ impl<'a> Builder<'a> { #[cfg(test)] mod tests { - use super::*; - use pk::Pk; - - struct Test { - key: Pk, - } - - impl Test { - fn new() -> Self { - Test { key: Pk::from_private_key(::test_support::keys::PEM_KEY, None).unwrap() } - } - - fn builder<'a>(&'a mut self) -> Builder<'a> { - let mut b = Builder::new(); - b.key(&mut self.key); - b.subject_with_nul("CN=mbedtls.example\0").unwrap(); - b - } - } - - const TEST_PEM: &'static str = r"-----BEGIN CERTIFICATE REQUEST----- + use super::*; + use pk::Pk; + + struct Test { + key: Pk, + } + + impl Test { + fn new() -> Self { + Test { + key: Pk::from_private_key(::test_support::keys::PEM_KEY, None).unwrap(), + } + } + + fn builder<'a>(&'a mut self) -> Builder<'a> { + let mut b = Builder::new(); + b.key(&mut self.key); + b.subject_with_nul("CN=mbedtls.example\0").unwrap(); + b + } + } + + const TEST_PEM: &'static str = r"-----BEGIN CERTIFICATE REQUEST----- MIICXzCCAUcCAQAwGjEYMBYGA1UEAxMPbWJlZHRscy5leGFtcGxlMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxYwIJgiVJigEPzgINDAYdxNvpeWrEh3Q TZk5tIK975p5hXFKpSKVBtwRnfOaNHPV+ap8QSiWn0yS7tsUao8dUzJQXbVaT9Al @@ -196,58 +246,69 @@ L9kiqglOzjFqAjAjIbzmQfeyu+vYrTglvjfskf0V+vgvCMs= -----END CERTIFICATE REQUEST----- "; - const TEST_DER: &'static [u8] = - &[0x30, 0x82, 0x02, 0x5f, 0x30, 0x82, 0x01, 0x47, 0x02, 0x01, 0x00, 0x30, 0x1a, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x0f, 0x6d, 0x62, 0x65, 0x64, 0x74, 0x6c, 0x73, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, - 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc5, 0x8c, 0x08, 0x26, - 0x08, 0x95, 0x26, 0x28, 0x04, 0x3f, 0x38, 0x08, 0x34, 0x30, 0x18, 0x77, 0x13, 0x6f, 0xa5, 0xe5, 0xab, 0x12, 0x1d, - 0xd0, 0x4d, 0x99, 0x39, 0xb4, 0x82, 0xbd, 0xef, 0x9a, 0x79, 0x85, 0x71, 0x4a, 0xa5, 0x22, 0x95, 0x06, 0xdc, 0x11, - 0x9d, 0xf3, 0x9a, 0x34, 0x73, 0xd5, 0xf9, 0xaa, 0x7c, 0x41, 0x28, 0x96, 0x9f, 0x4c, 0x92, 0xee, 0xdb, 0x14, 0x6a, - 0x8f, 0x1d, 0x53, 0x32, 0x50, 0x5d, 0xb5, 0x5a, 0x4f, 0xd0, 0x25, 0xf2, 0xe6, 0xa3, 0xd8, 0xc2, 0xf3, 0xbc, 0x51, - 0x62, 0x06, 0xca, 0xbb, 0x27, 0x8b, 0x2f, 0x06, 0x7e, 0x90, 0xe3, 0x5c, 0x69, 0x14, 0x15, 0xb9, 0xbd, 0xd4, 0x2c, - 0x35, 0x73, 0xf9, 0x42, 0x0f, 0xb4, 0x75, 0xea, 0x52, 0xc7, 0x2b, 0xee, 0xcd, 0xa6, 0xaf, 0x68, 0xc6, 0x99, 0x37, - 0x29, 0xf3, 0x07, 0x8a, 0xf4, 0x28, 0xac, 0x57, 0x77, 0xd5, 0xbc, 0xa8, 0xd1, 0x5c, 0x59, 0xbf, 0xfb, 0x05, 0x61, - 0x58, 0x82, 0x6c, 0x3b, 0x4e, 0x62, 0x63, 0x22, 0x7d, 0x05, 0xff, 0xaa, 0x4a, 0xac, 0x6e, 0xf9, 0x31, 0x4a, 0xe3, - 0xe4, 0x97, 0x3a, 0x71, 0x03, 0x11, 0x7c, 0xdb, 0x89, 0xad, 0x28, 0xc4, 0x62, 0x9b, 0x01, 0x90, 0x6d, 0x9e, 0x2d, - 0x6c, 0xb9, 0x40, 0x14, 0xdb, 0xa0, 0x3b, 0x4d, 0x9e, 0x57, 0x41, 0xea, 0xf3, 0x11, 0xf1, 0x7d, 0xb9, 0x8d, 0xad, - 0xb9, 0x52, 0xa8, 0x8c, 0xba, 0xf3, 0xf5, 0x1d, 0x8e, 0x0e, 0x18, 0xf5, 0xf7, 0x85, 0x8b, 0xc3, 0x55, 0x7d, 0x88, - 0x3f, 0xae, 0xc1, 0x63, 0xb8, 0xbf, 0x85, 0xbf, 0xfd, 0xdd, 0x2c, 0x10, 0x61, 0x68, 0xc7, 0xdf, 0xc9, 0x5f, 0x49, - 0xd1, 0xe5, 0x0b, 0x5e, 0x05, 0x70, 0xe5, 0x95, 0xcd, 0x69, 0x08, 0x0a, 0x6f, 0xab, 0x12, 0x05, 0x0a, 0xa2, 0x53, - 0x72, 0xdf, 0xb4, 0x70, 0xd3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa0, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x6e, 0x7c, 0x8c, 0xe6, 0x36, 0xa8, - 0x84, 0x2a, 0x23, 0xe7, 0xb8, 0x36, 0xd1, 0x94, 0x17, 0x18, 0x19, 0x18, 0xda, 0x40, 0xcc, 0xdf, 0x63, 0xbb, 0xbf, - 0x4e, 0x36, 0xec, 0x54, 0x07, 0x6f, 0xc6, 0x6b, 0xd7, 0x91, 0x6a, 0x6d, 0x3c, 0xfc, 0x44, 0x86, 0x7f, 0x8a, 0xc5, - 0x52, 0x2a, 0xef, 0x51, 0x63, 0x84, 0xaf, 0x84, 0xac, 0xc8, 0xf0, 0x97, 0x48, 0x6a, 0x8d, 0x57, 0x15, 0xa7, 0x54, - 0xd6, 0xf1, 0x52, 0x56, 0x5c, 0xcf, 0x19, 0x09, 0x93, 0x20, 0xf1, 0x9c, 0x76, 0x0f, 0xec, 0x9f, 0x91, 0x96, 0xcc, - 0x46, 0x5c, 0x2d, 0x80, 0xb6, 0x2e, 0xb6, 0x9e, 0x82, 0x9e, 0x79, 0x55, 0xfd, 0x6c, 0x52, 0x64, 0x00, 0x13, 0x43, - 0x29, 0x34, 0x64, 0xec, 0x3c, 0x50, 0x4e, 0xcf, 0x1d, 0x90, 0xf1, 0xc7, 0x5a, 0x8f, 0x01, 0xa6, 0xa2, 0x2e, 0xb3, - 0xf1, 0x6e, 0x1b, 0x4f, 0x39, 0x05, 0x1f, 0xb5, 0x0f, 0x06, 0x26, 0x2f, 0xb6, 0x8f, 0xf1, 0x77, 0x1c, 0x99, 0xc5, - 0xec, 0x6c, 0xfc, 0x7f, 0x6a, 0x56, 0xe9, 0x67, 0x07, 0x37, 0xe7, 0x22, 0x88, 0x10, 0x1f, 0x81, 0xa2, 0xe6, 0x9a, - 0x9b, 0xc6, 0xcb, 0x0c, 0x4a, 0x25, 0x8c, 0xe2, 0x97, 0xc2, 0xda, 0x6c, 0x14, 0x7b, 0xe6, 0x26, 0x1d, 0x51, 0xba, - 0x34, 0x40, 0x83, 0xa3, 0x0a, 0xe8, 0x0b, 0x18, 0x6a, 0x76, 0x4f, 0xfa, 0xc0, 0x12, 0xf1, 0xf6, 0x8a, 0xe0, 0xfd, - 0x5f, 0xa2, 0x7c, 0x1c, 0x05, 0xf9, 0xd9, 0x83, 0xb1, 0xfe, 0xa1, 0xb0, 0x2d, 0x9f, 0xf0, 0x67, 0x42, 0x6e, 0xd1, - 0xcd, 0xce, 0xb6, 0x19, 0x96, 0x8e, 0x2f, 0xd9, 0x22, 0xaa, 0x09, 0x4e, 0xce, 0x31, 0x6a, 0x02, 0x30, 0x23, 0x21, - 0xbc, 0xe6, 0x41, 0xf7, 0xb2, 0xbb, 0xeb, 0xd8, 0xad, 0x38, 0x25, 0xbe, 0x37, 0xec, 0x91, 0xfd, 0x15, 0xfa, 0xf8, - 0x2f, 0x08, 0xcb]; - - #[test] - fn write_der() { - let mut t = Test::new(); - let output = t.builder() - .signature_hash(::hash::Type::Sha256) - .write_der_vec(&mut ::test_support::rand::test_rng()) - .unwrap(); - assert!(output==TEST_DER); - } - - #[test] - fn write_pem() { - let mut t = Test::new(); - let output = t.builder() - .signature_hash(::hash::Type::Sha256) - .write_pem_string(&mut ::test_support::rand::test_rng()) - .unwrap(); - assert_eq!(output,TEST_PEM); - } + const TEST_DER: &'static [u8] = &[ + 0x30, 0x82, 0x02, 0x5f, 0x30, 0x82, 0x01, 0x47, 0x02, 0x01, 0x00, 0x30, 0x1a, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x6d, 0x62, 0x65, 0x64, 0x74, 0x6c, + 0x73, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc5, 0x8c, 0x08, + 0x26, 0x08, 0x95, 0x26, 0x28, 0x04, 0x3f, 0x38, 0x08, 0x34, 0x30, 0x18, 0x77, 0x13, 0x6f, + 0xa5, 0xe5, 0xab, 0x12, 0x1d, 0xd0, 0x4d, 0x99, 0x39, 0xb4, 0x82, 0xbd, 0xef, 0x9a, 0x79, + 0x85, 0x71, 0x4a, 0xa5, 0x22, 0x95, 0x06, 0xdc, 0x11, 0x9d, 0xf3, 0x9a, 0x34, 0x73, 0xd5, + 0xf9, 0xaa, 0x7c, 0x41, 0x28, 0x96, 0x9f, 0x4c, 0x92, 0xee, 0xdb, 0x14, 0x6a, 0x8f, 0x1d, + 0x53, 0x32, 0x50, 0x5d, 0xb5, 0x5a, 0x4f, 0xd0, 0x25, 0xf2, 0xe6, 0xa3, 0xd8, 0xc2, 0xf3, + 0xbc, 0x51, 0x62, 0x06, 0xca, 0xbb, 0x27, 0x8b, 0x2f, 0x06, 0x7e, 0x90, 0xe3, 0x5c, 0x69, + 0x14, 0x15, 0xb9, 0xbd, 0xd4, 0x2c, 0x35, 0x73, 0xf9, 0x42, 0x0f, 0xb4, 0x75, 0xea, 0x52, + 0xc7, 0x2b, 0xee, 0xcd, 0xa6, 0xaf, 0x68, 0xc6, 0x99, 0x37, 0x29, 0xf3, 0x07, 0x8a, 0xf4, + 0x28, 0xac, 0x57, 0x77, 0xd5, 0xbc, 0xa8, 0xd1, 0x5c, 0x59, 0xbf, 0xfb, 0x05, 0x61, 0x58, + 0x82, 0x6c, 0x3b, 0x4e, 0x62, 0x63, 0x22, 0x7d, 0x05, 0xff, 0xaa, 0x4a, 0xac, 0x6e, 0xf9, + 0x31, 0x4a, 0xe3, 0xe4, 0x97, 0x3a, 0x71, 0x03, 0x11, 0x7c, 0xdb, 0x89, 0xad, 0x28, 0xc4, + 0x62, 0x9b, 0x01, 0x90, 0x6d, 0x9e, 0x2d, 0x6c, 0xb9, 0x40, 0x14, 0xdb, 0xa0, 0x3b, 0x4d, + 0x9e, 0x57, 0x41, 0xea, 0xf3, 0x11, 0xf1, 0x7d, 0xb9, 0x8d, 0xad, 0xb9, 0x52, 0xa8, 0x8c, + 0xba, 0xf3, 0xf5, 0x1d, 0x8e, 0x0e, 0x18, 0xf5, 0xf7, 0x85, 0x8b, 0xc3, 0x55, 0x7d, 0x88, + 0x3f, 0xae, 0xc1, 0x63, 0xb8, 0xbf, 0x85, 0xbf, 0xfd, 0xdd, 0x2c, 0x10, 0x61, 0x68, 0xc7, + 0xdf, 0xc9, 0x5f, 0x49, 0xd1, 0xe5, 0x0b, 0x5e, 0x05, 0x70, 0xe5, 0x95, 0xcd, 0x69, 0x08, + 0x0a, 0x6f, 0xab, 0x12, 0x05, 0x0a, 0xa2, 0x53, 0x72, 0xdf, 0xb4, 0x70, 0xd3, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa0, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x6e, 0x7c, 0x8c, 0xe6, 0x36, + 0xa8, 0x84, 0x2a, 0x23, 0xe7, 0xb8, 0x36, 0xd1, 0x94, 0x17, 0x18, 0x19, 0x18, 0xda, 0x40, + 0xcc, 0xdf, 0x63, 0xbb, 0xbf, 0x4e, 0x36, 0xec, 0x54, 0x07, 0x6f, 0xc6, 0x6b, 0xd7, 0x91, + 0x6a, 0x6d, 0x3c, 0xfc, 0x44, 0x86, 0x7f, 0x8a, 0xc5, 0x52, 0x2a, 0xef, 0x51, 0x63, 0x84, + 0xaf, 0x84, 0xac, 0xc8, 0xf0, 0x97, 0x48, 0x6a, 0x8d, 0x57, 0x15, 0xa7, 0x54, 0xd6, 0xf1, + 0x52, 0x56, 0x5c, 0xcf, 0x19, 0x09, 0x93, 0x20, 0xf1, 0x9c, 0x76, 0x0f, 0xec, 0x9f, 0x91, + 0x96, 0xcc, 0x46, 0x5c, 0x2d, 0x80, 0xb6, 0x2e, 0xb6, 0x9e, 0x82, 0x9e, 0x79, 0x55, 0xfd, + 0x6c, 0x52, 0x64, 0x00, 0x13, 0x43, 0x29, 0x34, 0x64, 0xec, 0x3c, 0x50, 0x4e, 0xcf, 0x1d, + 0x90, 0xf1, 0xc7, 0x5a, 0x8f, 0x01, 0xa6, 0xa2, 0x2e, 0xb3, 0xf1, 0x6e, 0x1b, 0x4f, 0x39, + 0x05, 0x1f, 0xb5, 0x0f, 0x06, 0x26, 0x2f, 0xb6, 0x8f, 0xf1, 0x77, 0x1c, 0x99, 0xc5, 0xec, + 0x6c, 0xfc, 0x7f, 0x6a, 0x56, 0xe9, 0x67, 0x07, 0x37, 0xe7, 0x22, 0x88, 0x10, 0x1f, 0x81, + 0xa2, 0xe6, 0x9a, 0x9b, 0xc6, 0xcb, 0x0c, 0x4a, 0x25, 0x8c, 0xe2, 0x97, 0xc2, 0xda, 0x6c, + 0x14, 0x7b, 0xe6, 0x26, 0x1d, 0x51, 0xba, 0x34, 0x40, 0x83, 0xa3, 0x0a, 0xe8, 0x0b, 0x18, + 0x6a, 0x76, 0x4f, 0xfa, 0xc0, 0x12, 0xf1, 0xf6, 0x8a, 0xe0, 0xfd, 0x5f, 0xa2, 0x7c, 0x1c, + 0x05, 0xf9, 0xd9, 0x83, 0xb1, 0xfe, 0xa1, 0xb0, 0x2d, 0x9f, 0xf0, 0x67, 0x42, 0x6e, 0xd1, + 0xcd, 0xce, 0xb6, 0x19, 0x96, 0x8e, 0x2f, 0xd9, 0x22, 0xaa, 0x09, 0x4e, 0xce, 0x31, 0x6a, + 0x02, 0x30, 0x23, 0x21, 0xbc, 0xe6, 0x41, 0xf7, 0xb2, 0xbb, 0xeb, 0xd8, 0xad, 0x38, 0x25, + 0xbe, 0x37, 0xec, 0x91, 0xfd, 0x15, 0xfa, 0xf8, 0x2f, 0x08, 0xcb, + ]; + + #[test] + fn write_der() { + let mut t = Test::new(); + let output = t + .builder() + .signature_hash(::hash::Type::Sha256) + .write_der_vec(&mut ::test_support::rand::test_rng()) + .unwrap(); + assert!(output == TEST_DER); + } + + #[test] + fn write_pem() { + let mut t = Test::new(); + let output = t + .builder() + .signature_hash(::hash::Type::Sha256) + .write_pem_string(&mut ::test_support::rand::test_rng()) + .unwrap(); + assert_eq!(output, TEST_PEM); + } } diff --git a/mbedtls/src/x509/mod.rs b/mbedtls/src/x509/mod.rs index e6b76b5b9..9e9332e3c 100644 --- a/mbedtls/src/x509/mod.rs +++ b/mbedtls/src/x509/mod.rs @@ -1,9 +1,9 @@ /* Copyright (c) Fortanix, Inc. * - * Licensed under the GNU General Public License, version 2 or the Apache License, Version - * 2.0 , at your - * option. This file may not be copied, modified, or distributed except + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except * according to those terms. */ pub mod certificate; @@ -23,128 +23,142 @@ pub use self::csr::Csr; pub use self::profile::Profile; pub mod key_usage { - use mbedtls_sys::types::raw_types::c_uint; - use mbedtls_sys::*; + use mbedtls_sys::types::raw_types::c_uint; + use mbedtls_sys::*; - bitflags! { - pub flags KeyUsage: c_uint { - const DIGITAL_SIGNATURE = X509_KU_DIGITAL_SIGNATURE as c_uint, - const NON_REPUDIATION = X509_KU_NON_REPUDIATION as c_uint, - const KEY_ENCIPHERMENT = X509_KU_KEY_ENCIPHERMENT as c_uint, - const DATA_ENCIPHERMENT = X509_KU_DATA_ENCIPHERMENT as c_uint, - const KEY_AGREEMENT = X509_KU_KEY_AGREEMENT as c_uint, - const KEY_CERT_SIGN = X509_KU_KEY_CERT_SIGN as c_uint, - const CRL_SIGN = X509_KU_CRL_SIGN as c_uint, - const ENCIPHER_ONLY = X509_KU_ENCIPHER_ONLY as c_uint, - const DECIPHER_ONLY = X509_KU_DECIPHER_ONLY as c_uint, - } - } + bitflags! { + pub flags KeyUsage: c_uint { + const DIGITAL_SIGNATURE = X509_KU_DIGITAL_SIGNATURE as c_uint, + const NON_REPUDIATION = X509_KU_NON_REPUDIATION as c_uint, + const KEY_ENCIPHERMENT = X509_KU_KEY_ENCIPHERMENT as c_uint, + const DATA_ENCIPHERMENT = X509_KU_DATA_ENCIPHERMENT as c_uint, + const KEY_AGREEMENT = X509_KU_KEY_AGREEMENT as c_uint, + const KEY_CERT_SIGN = X509_KU_KEY_CERT_SIGN as c_uint, + const CRL_SIGN = X509_KU_CRL_SIGN as c_uint, + const ENCIPHER_ONLY = X509_KU_ENCIPHER_ONLY as c_uint, + const DECIPHER_ONLY = X509_KU_DECIPHER_ONLY as c_uint, + } + } } #[doc(inline)] pub use self::key_usage::KeyUsage; pub mod verify_error { - use mbedtls_sys::*; + use mbedtls_sys::*; - bitflags! { - pub flags VerifyError: u32 { - const CERT_BAD_KEY = X509_BADCERT_BAD_KEY as u32, - const CERT_BAD_MD = X509_BADCERT_BAD_MD as u32, - const CERT_BAD_PK = X509_BADCERT_BAD_PK as u32, - const CERT_CN_MISMATCH = X509_BADCERT_CN_MISMATCH as u32, - const CERT_EXPIRED = X509_BADCERT_EXPIRED as u32, - const CERT_EXT_KEY_USAGE = X509_BADCERT_EXT_KEY_USAGE as u32, - const CERT_FUTURE = X509_BADCERT_FUTURE as u32, - const CERT_KEY_USAGE = X509_BADCERT_KEY_USAGE as u32, - const CERT_MISSING = X509_BADCERT_MISSING as u32, - const CERT_NOT_TRUSTED = X509_BADCERT_NOT_TRUSTED as u32, - const CERT_NS_CERT_TYPE = X509_BADCERT_NS_CERT_TYPE as u32, - const CERT_OTHER = X509_BADCERT_OTHER as u32, - const CERT_REVOKED = X509_BADCERT_REVOKED as u32, - const CERT_SKIP_VERIFY = X509_BADCERT_SKIP_VERIFY as u32, - const CRL_BAD_KEY = X509_BADCRL_BAD_KEY as u32, - const CRL_BAD_MD = X509_BADCRL_BAD_MD as u32, - const CRL_BAD_PK = X509_BADCRL_BAD_PK as u32, - const CRL_EXPIRED = X509_BADCRL_EXPIRED as u32, - const CRL_FUTURE = X509_BADCRL_FUTURE as u32, - const CRL_NOT_TRUSTED = X509_BADCRL_NOT_TRUSTED as u32, - const CUSTOM_BIT_20 = 0x10_0000, - const CUSTOM_BIT_21 = 0x20_0000, - const CUSTOM_BIT_22 = 0x40_0000, - const CUSTOM_BIT_23 = 0x80_0000, - const CUSTOM_BIT_24 = 0x100_0000, - const CUSTOM_BIT_25 = 0x200_0000, - const CUSTOM_BIT_26 = 0x400_0000, - const CUSTOM_BIT_27 = 0x800_0000, - const CUSTOM_BIT_28 = 0x1000_0000, - const CUSTOM_BIT_29 = 0x2000_0000, - const CUSTOM_BIT_30 = 0x4000_0000, - const CUSTOM_BIT_31 = 0x8000_0000, - } - } + bitflags! { + pub flags VerifyError: u32 { + const CERT_BAD_KEY = X509_BADCERT_BAD_KEY as u32, + const CERT_BAD_MD = X509_BADCERT_BAD_MD as u32, + const CERT_BAD_PK = X509_BADCERT_BAD_PK as u32, + const CERT_CN_MISMATCH = X509_BADCERT_CN_MISMATCH as u32, + const CERT_EXPIRED = X509_BADCERT_EXPIRED as u32, + const CERT_EXT_KEY_USAGE = X509_BADCERT_EXT_KEY_USAGE as u32, + const CERT_FUTURE = X509_BADCERT_FUTURE as u32, + const CERT_KEY_USAGE = X509_BADCERT_KEY_USAGE as u32, + const CERT_MISSING = X509_BADCERT_MISSING as u32, + const CERT_NOT_TRUSTED = X509_BADCERT_NOT_TRUSTED as u32, + const CERT_NS_CERT_TYPE = X509_BADCERT_NS_CERT_TYPE as u32, + const CERT_OTHER = X509_BADCERT_OTHER as u32, + const CERT_REVOKED = X509_BADCERT_REVOKED as u32, + const CERT_SKIP_VERIFY = X509_BADCERT_SKIP_VERIFY as u32, + const CRL_BAD_KEY = X509_BADCRL_BAD_KEY as u32, + const CRL_BAD_MD = X509_BADCRL_BAD_MD as u32, + const CRL_BAD_PK = X509_BADCRL_BAD_PK as u32, + const CRL_EXPIRED = X509_BADCRL_EXPIRED as u32, + const CRL_FUTURE = X509_BADCRL_FUTURE as u32, + const CRL_NOT_TRUSTED = X509_BADCRL_NOT_TRUSTED as u32, + const CUSTOM_BIT_20 = 0x10_0000, + const CUSTOM_BIT_21 = 0x20_0000, + const CUSTOM_BIT_22 = 0x40_0000, + const CUSTOM_BIT_23 = 0x80_0000, + const CUSTOM_BIT_24 = 0x100_0000, + const CUSTOM_BIT_25 = 0x200_0000, + const CUSTOM_BIT_26 = 0x400_0000, + const CUSTOM_BIT_27 = 0x800_0000, + const CUSTOM_BIT_28 = 0x1000_0000, + const CUSTOM_BIT_29 = 0x2000_0000, + const CUSTOM_BIT_30 = 0x4000_0000, + const CUSTOM_BIT_31 = 0x8000_0000, + } + } } #[doc(inline)] pub use self::verify_error::VerifyError; /// A specific moment in time in UTC pub struct Time { - year: u16, - month: u8, - day: u8, - hour: u8, - minute: u8, - second: u8, + year: u16, + month: u8, + day: u8, + hour: u8, + minute: u8, + second: u8, } use core::fmt::{self, Write as FmtWrite}; struct TimeWriter { - buf: [u8; 15], - idx: usize, + buf: [u8; 15], + idx: usize, } impl fmt::Write for TimeWriter { - fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { - for (dst, src) in self.buf.iter_mut().skip(self.idx).zip(s.as_bytes().iter()) { - *dst = *src - } - self.idx += s.len(); - Ok(()) - } + fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { + for (dst, src) in self.buf.iter_mut().skip(self.idx).zip(s.as_bytes().iter()) { + *dst = *src + } + self.idx += s.len(); + Ok(()) + } - fn write_char(&mut self, c: char) -> Result<(), fmt::Error> { - if c >= '0' || c <= '9' { - if let Some(dst) = self.buf.get_mut(self.idx) { - *dst = c as u8; - self.idx += 1; - return Ok(()); - } - } - Err(fmt::Error) - } + fn write_char(&mut self, c: char) -> Result<(), fmt::Error> { + if c >= '0' || c <= '9' { + if let Some(dst) = self.buf.get_mut(self.idx) { + *dst = c as u8; + self.idx += 1; + return Ok(()); + } + } + Err(fmt::Error) + } } impl Time { - pub fn new(year: u16, month: u8, day: u8, hour: u8, minute: u8, second: u8) -> Option