From b9f0afbd6d19cd263e217cf9f8ec6062b10bd141 Mon Sep 17 00:00:00 2001 From: drakeley Date: Mon, 13 Jan 2020 10:59:25 -0800 Subject: [PATCH] Current MC-Develop --- includegen.sh | 16 +++ mbedtls-sys/Cargo.toml | 6 +- mbedtls-sys/build/bindgen.rs | 131 ++++++++++++++----- mbedtls-sys/build/cmake.rs | 39 +++++- mbedtls-sys/build/config.rs | 6 +- mbedtls-sys/src/lib.rs | 4 + mbedtls-sys/vendor/CMakeLists.txt | 5 + mbedtls/Cargo.toml | 12 +- mbedtls/src/bignum/mod.rs | 3 +- mbedtls/src/cipher/raw/mod.rs | 3 +- mbedtls/src/ecp/mod.rs | 2 +- mbedtls/src/lib.rs | 13 +- mbedtls/src/private.rs | 14 +- mbedtls/src/ssl/context.rs | 25 ++-- mbedtls/src/x509/certificate.rs | 206 ++++++++++++++++++++++-------- mbedtls/src/x509/profile.rs | 29 +++++ 16 files changed, 394 insertions(+), 120 deletions(-) create mode 100755 includegen.sh diff --git a/includegen.sh b/includegen.sh new file mode 100755 index 00000000..20ab009d --- /dev/null +++ b/includegen.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +ls -f1 $( \ + ( \ + grep '^#include' * | \ + grep -v '<' | \ + grep -v MBEDTLS_ | \ + sed 's/:#include//;s/"//g' | \ + grep -v _alt.h; \ + ls *.h | \ + awk '{print $1 " " $1}' \ + ) | \ + tsort | \ + tac | \ + egrep -v '^(compat-1.3.h|certs.h|config.h|check_config.h)$' \ +) diff --git a/mbedtls-sys/Cargo.toml b/mbedtls-sys/Cargo.toml index 1ffdf131..64996b7a 100644 --- a/mbedtls-sys/Cargo.toml +++ b/mbedtls-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mbedtls-sys-auto" -version = "2.18.2" +version = "2.18.1" authors = ["Jethro Beekman "] build = "build/build.rs" license = "Apache-2.0/GPL-2.0+" @@ -21,7 +21,7 @@ libc = { version = "0.2.0", optional = true } libz-sys = { version = "1.0.0", optional = true } [build-dependencies] -bindgen = "0.19.0" +bindgen = "0.43.0" cmake = "0.1.17" [features] @@ -42,7 +42,7 @@ aes_alt = [] custom_threading = ["threading"] pthread = ["libc","threading"] threading = [] -time = [] +time = ["libc"] havege = ["time"] zlib = ["libz-sys"] pkcs11 = [] diff --git a/mbedtls-sys/build/bindgen.rs b/mbedtls-sys/build/bindgen.rs index 7eb3578a..b4293fb0 100644 --- a/mbedtls-sys/build/bindgen.rs +++ b/mbedtls-sys/build/bindgen.rs @@ -7,21 +7,72 @@ * according to those terms. */ use bindgen; +use bindgen::callbacks::IntKind; +use std::env; use std::fs::File; -use std::io::{stderr, Write}; +use std::io::Write; +use std::process::Command; use crate::headers; #[derive(Debug)] -struct StderrLogger; +struct ParseCallbacks {} -impl bindgen::Logger for StderrLogger { - fn error(&self, msg: &str) { - let _ = writeln!(stderr(), "Bindgen ERROR: {}", msg); +impl bindgen::callbacks::ParseCallbacks for ParseCallbacks { + fn int_macro(&self, name: &str, _value: i64) -> Option { + if name.starts_with("MBEDTLS_SSL_IS_") || + name.starts_with("MBEDTLS_SSL_PRESET_") || + name.starts_with("MBEDTLS_SSL_TRANSPORT_") || + name.starts_with("MBEDTLS_SSL_VERIFY_") || + name.starts_with("MBEDTLS_TLS_RSA_WITH_") || + name.starts_with("MBEDTLS_TLS_RSA_PSK_WITH_") || + name.starts_with("MBEDTLS_TLS_ECJPAKE_WITH_") || + name.starts_with("MBEDTLS_TLS_DHE_RSA_WITH_") || + name.starts_with("MBEDTLS_TLS_ECDH_ECDSA_WITH_") || + name.starts_with("MBEDTLS_TLS_ECDHE_ECDSA_WITH_") || + name.starts_with("MBEDTLS_TLS_ECDH_RSA_WITH_") || + name.starts_with("MBEDTLS_TLS_ECDHE_RSA_WITH_") || + name.starts_with("MBEDTLS_TLS_ECDHE_PSK_WITH_") || + name.starts_with("MBEDTLS_TLS_PSK_WITH_") || + name.starts_with("MBEDTLS_TLS_DHE_PSK_WITH_") || + name.starts_with("MBEDTLS_SSL_SESSION_TICKETS_") || + name.starts_with("MBEDTLS_CTR_DRBG_PR_") || + name.starts_with("MBEDTLS_ENTROPY_SOURCE_") || + name.starts_with("MBEDTLS_HMAC_DRBG_PR_") || + name.starts_with("MBEDTLS_RSA_PKCS_") + { + Some(IntKind::Int) + } else { + None + } } - fn warn(&self, msg: &str) { - let _ = writeln!(stderr(), "Bindgen WARNING: {}", msg); + + fn item_name(&self, original_item_name: &str) -> Option { + if original_item_name.starts_with("mbedtls_") { + if original_item_name == "mbedtls_time_t" { + None + } else { + Some(original_item_name.trim_start_matches("mbedtls_").to_string()) + } + } else if original_item_name.starts_with("MBEDTLS_") { + Some(original_item_name.trim_start_matches("MBEDTLS_").to_string()) + } else { + None + } + } + + fn enum_variant_name( + &self, + _enum_name: Option<&str>, + original_variant_name: &str, + _variant_value: bindgen::callbacks::EnumVariantValue + ) -> Option { + if original_variant_name.starts_with("MBEDTLS_") { + Some(original_variant_name.trim_start_matches("MBEDTLS_").to_string()) + } else { + None + } } } @@ -36,38 +87,56 @@ impl super::BuildConfig { }).expect("bindgen-input.h I/O error"); let include = self.mbedtls_src.join("include"); + let target = env::var("TARGET").expect("TARGET environment variable not set"); + + let bindings = (match target.as_str() { + /* iOS */ + "armv7-apple-ios" | "armv7s-apple-ios" | "aarch64-apple-ios" => { + let ios_sdk_path_output = Command::new("xcrun").args(&["--sdk", "iphoneos", "--show-sdk-path"]) + .output().expect("Failed to get xcode iphoneos sdk path"); + let ios_sdk_path = String::from_utf8(ios_sdk_path_output.stdout) + .expect("Command output from xcrun not UTF-8") + .trim().to_string(); - let logger = StderrLogger; - let mut bindgen = bindgen::Builder::new(header.into_os_string().into_string().unwrap()); - let bindings = bindgen - .log(&logger) + (match target.as_str() { + "armv7-apple-ios" | "armv7s-apple-ios" => bindgen::builder() + .clang_args(&["-target", &target]), + "aarch64-apple-ios" => bindgen::builder() + .clang_args(&["-target", "arm64-apple-ios"]), + _ => bindgen::builder() + }).clang_args(&["-isysroot", ios_sdk_path.as_str()]) + }, + /* Android*/ + "i686-linux-andoid" | "armv7-linux-androideabi" | "aarch64-linux-android" => bindgen::builder() + .clang_args(&["-isysroot", &env::var("ISYSROOT").expect("Need ISYSROOT env var for Android compilation")]) + .clang_args(&["-isystem", &env::var("ISYSTEM").expect("Need ISYSTEM env var for Android compilation")]), + /* Everything else */ + _ => bindgen::builder() + }) .clang_arg("-Dmbedtls_t_udbl=mbedtls_t_udbl;") // bindgen can't handle unused uint128 .clang_arg(format!( - "-DMBEDTLS_CONFIG_FILE=<{}>", + "-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) + )).header( + header + .to_str() + .expect("failed to convert header path to string"), + ).use_core() .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() + .disable_name_namespacing() + .prepend_enum_name(false) + .ctypes_prefix("raw_types") + .parse_callbacks(Box::new(ParseCallbacks{})) + // max_align_t is causing bindgen generated tests to fail an alignment check and + // is not needed by the bindings. + .blacklist_type("max_align_t") + // Including the comments breaks the generated code because it contains formatting + // that is interpreted as escaped characters. + .generate_comments(false) + .generate() .expect("bindgen error"); let bindings_rs = self.out_dir.join("bindings.rs"); diff --git a/mbedtls-sys/build/cmake.rs b/mbedtls-sys/build/cmake.rs index 36112045..b9beb974 100644 --- a/mbedtls-sys/build/cmake.rs +++ b/mbedtls-sys/build/cmake.rs @@ -14,17 +14,54 @@ impl super::BuildConfig { pub fn cmake(&self) { let mut cmk = cmake::Config::new(&self.mbedtls_src); cmk.cflag(format!( - r#"-DMBEDTLS_CONFIG_FILE="<{}>""#, + "-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"); + + match ::std::env::var("TARGET").unwrap_or("".to_owned()).as_str() { + "i686-linux-android" => { + cmk.define("TOOLCHAIN_PREFIX", "i686-linux-android") + .target("i686-linux-android26"); + } + "armv7-linux-androideabi" => { + cmk.define("TOOLCHAIN_PREFIX", "arm-linux-androideabi") + .target("armv7a-linux-androideabi26"); + } + "aarch64-linux-android" => { + cmk.define("TOOLCHAIN_PREFIX", "aarch64-linux-android") + .target("aarch64-linux-android26"); + } + _ => {} + }; + + let target_vendor = ::std::env::var("CARGO_CFG_TARGET_VENDOR") + .expect("CARGO_CFG_TARGET_VENDOR is set by cargo."); + + // Workaround for Cmake not setting `-m-version-min` flags properly for asm files + // See https://gitlab.kitware.com/cmake/cmake/issues/19794 + match ::std::env::var("TARGET").unwrap_or("".to_owned()).as_str() { + "aarch64-apple-ios" | "armv7-apple-ios" | "armv7s-apple-ios" => { + cmk.cflag("-miphoneos-version-min=7.0"); + } + "i386-apple-ios" | "x86_64-apple-ios" => { + cmk.cflag("-mios-simulator-version-min=7.0"); + } + _ => {} + }; + if !have_feature("std") || ::std::env::var("TARGET") .map(|s| (s == "x86_64-unknown-none-gnu") || (s == "x86_64-fortanix-unknown-sgx")) == Ok(true) { + if target_vendor != "apple" { + println!("cargo:rustc-link-lib=gcc"); + } + // println!("cargo:rustc-link-lib=gcc"); + cmk.cflag("-fno-builtin") .cflag("-D_FORTIFY_SOURCE=0") .cflag("-fno-stack-protector"); diff --git a/mbedtls-sys/build/config.rs b/mbedtls-sys/build/config.rs index c1c4b577..242b8fa0 100644 --- a/mbedtls-sys/build/config.rs +++ b/mbedtls-sys/build/config.rs @@ -264,7 +264,7 @@ pub const DEFAULT_DEFINES: &'static [CDefine] = &[ ("MBEDTLS_DHM_C", Defined), ("MBEDTLS_ECDH_C", Defined), ("MBEDTLS_ECDSA_C", Defined), - ("MBEDTLS_ECJPAKE_C", Defined), + ("MBEDTLS_ECJPAKE_C", Undefined), ("MBEDTLS_ECP_C", Defined), ("MBEDTLS_ENTROPY_C", Undefined), ("MBEDTLS_ERROR_C", Defined), @@ -274,8 +274,8 @@ pub const DEFAULT_DEFINES: &'static [CDefine] = &[ ("MBEDTLS_HMAC_DRBG_C", Defined), ("MBEDTLS_NIST_KW_C", Defined), ("MBEDTLS_MD_C", Defined), - ("MBEDTLS_MD2_C", Defined), - ("MBEDTLS_MD4_C", Defined), + ("MBEDTLS_MD2_C", Undefined), + ("MBEDTLS_MD4_C", Undefined), ("MBEDTLS_MD5_C", Defined), ("MBEDTLS_MEMORY_BUFFER_ALLOC_C", Undefined), ("MBEDTLS_NET_C", Undefined), diff --git a/mbedtls-sys/src/lib.rs b/mbedtls-sys/src/lib.rs index 11baf644..0f6ca235 100644 --- a/mbedtls-sys/src/lib.rs +++ b/mbedtls-sys/src/lib.rs @@ -6,6 +6,10 @@ * option. This file may not be copied, modified, or distributed except * according to those terms. */ +#![allow(non_snake_case)] +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] +#![allow(clippy::all)] #![cfg_attr(not(feature = "std"), no_std)] #[cfg(feature = "std")] extern crate core; diff --git a/mbedtls-sys/vendor/CMakeLists.txt b/mbedtls-sys/vendor/CMakeLists.txt index 38c80060..bd935f24 100644 --- a/mbedtls-sys/vendor/CMakeLists.txt +++ b/mbedtls-sys/vendor/CMakeLists.txt @@ -5,6 +5,11 @@ else() project("mbed TLS" C) endif() +if(TOOLCHAIN_PREFIX) + set( CMAKE_AR "${TOOLCHAIN_PREFIX}-ar" ) + set( CMAKE_RANLIB "${TOOLCHAIN_PREFIX}-ranlib" ) +endif() + option(USE_PKCS11_HELPER_LIBRARY "Build mbed TLS with the pkcs11-helper library." OFF) option(ENABLE_ZLIB_SUPPORT "Build mbed TLS with zlib library." OFF) diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index 98c5281d..b78a1b79 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -20,18 +20,16 @@ keywords = ["MbedTLS","mbed","TLS","SSL","cryptography"] [dependencies] bitflags = "1" chrono = { version = "0.4", optional = true } -core_io = { version = "0.1", features = ["collections"], optional = true } +# MobileCoin: genio +genio = { version = "0.2.0", default-features = false } spin = { version = "0.4.0", default-features = false, optional = true } serde = { version = "1.0.7", default-features = false } serde_derive = "1.0.7" -byteorder = "1.0.0" +byteorder = { version = "1.0.0", default-features = false } yasna = { version = "0.2", optional = true } block-modes = { version = "0.3", optional = true } rc2 = { version = "0.3", optional = true } -[target.x86_64-fortanix-unknown-sgx.dependencies] -rs-libc = "0.1.0" - [dependencies.mbedtls-sys-auto] version = "2.18.0" default-features = false @@ -40,7 +38,7 @@ path = "../mbedtls-sys" [dev-dependencies] libc = "0.2.0" -rand = "0.4.0" +rand = "0.7" serde_cbor = "0.6" hex = "0.3" @@ -50,7 +48,7 @@ cc = "1.0" [features] # Features are documented in the README default = ["std", "aesni", "time", "padlock", "legacy_protocols", "use_libc"] -std = ["mbedtls-sys-auto/std", "serde/std", "yasna"] +std = ["mbedtls-sys-auto/std", "serde/std", "yasna", "genio/use_std"] threading = [] pthread = ["threading","std","mbedtls-sys-auto/pthread"] spin_threading = ["threading","spin","mbedtls-sys-auto/custom_threading"] diff --git a/mbedtls/src/bignum/mod.rs b/mbedtls/src/bignum/mod.rs index 65e1d3c1..012c18ff 100644 --- a/mbedtls/src/bignum/mod.rs +++ b/mbedtls/src/bignum/mod.rs @@ -8,6 +8,7 @@ use crate::error::{Error, IntoResult, Result}; use mbedtls_sys::*; +use mbedtls_sys::types::raw_types::c_char; #[cfg(not(feature = "std"))] use crate::alloc_prelude::*; @@ -173,7 +174,7 @@ impl Mpi { mpi_write_string( &self.inner, radix, - buf.as_mut_ptr() as *mut i8, + buf.as_mut_ptr() as *mut c_char, buf.len(), &mut olen, ) diff --git a/mbedtls/src/cipher/raw/mod.rs b/mbedtls/src/cipher/raw/mod.rs index 209802e0..fe0d53ab 100644 --- a/mbedtls/src/cipher/raw/mod.rs +++ b/mbedtls/src/cipher/raw/mod.rs @@ -10,6 +10,7 @@ use mbedtls_sys::*; use crate::error::{Error, IntoResult, Result}; +#[cfg(buggy)] mod serde; define!( @@ -403,7 +404,7 @@ impl Cipher { } self.reset()?; unsafe { - cipher_cmac(&*self.inner.cipher_info, key.as_ptr(), (key.len() * 8) as _, data.as_ptr(), data.len(), + cipher_cmac(&*self.inner.cipher_info, key.as_ptr(), (key.len() * 8) as _, data.as_ptr(), data.len(), outdata.as_mut_ptr()).into_result()?; } Ok(()) diff --git a/mbedtls/src/ecp/mod.rs b/mbedtls/src/ecp/mod.rs index 8d28dcac..c8853db3 100644 --- a/mbedtls/src/ecp/mod.rs +++ b/mbedtls/src/ecp/mod.rs @@ -400,7 +400,7 @@ impl EcPoint { ecp_point_write_binary( &group.inner, &self.inner, - format, + format as i32, &mut olen, buf.as_mut_ptr(), buf.len(), diff --git a/mbedtls/src/lib.rs b/mbedtls/src/lib.rs index 3c546f26..40a8a034 100644 --- a/mbedtls/src/lib.rs +++ b/mbedtls/src/lib.rs @@ -6,19 +6,22 @@ * option. This file may not be copied, modified, or distributed except * according to those terms. */ -#![deny(warnings)] +// FIXME: Have to allow warnings to get around the bindgen issues. +// #![deny(warnings)] +#![allow(clippy::all)] +#![cfg_attr(feature = "rdrand", feature(asm))] #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(all(not(feature = "std"), not(feature = "core_io")))] -const ERROR: _MUST_USE_EITHER_STD_OR_CORE_IO_ = (); +// #[cfg(all(not(feature = "std"), not(feature = "core_io")))] +// const ERROR: _MUST_USE_EITHER_STD_OR_CORE_IO_ = (); #[cfg(not(feature = "std"))] #[macro_use] extern crate alloc; #[cfg(feature = "std")] extern crate core; -#[cfg(not(feature = "std"))] -extern crate core_io; + +extern crate genio; #[cfg(feature = "std")] extern crate yasna; diff --git a/mbedtls/src/private.rs b/mbedtls/src/private.rs index 4fbafe36..f37256d1 100644 --- a/mbedtls/src/private.rs +++ b/mbedtls/src/private.rs @@ -88,11 +88,11 @@ pub unsafe fn cstr_to_slice<'a>(ptr: *const c_char) -> &'a [u8] { ::core::slice::from_raw_parts(ptr as *const _, strlen(ptr)) } -#[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}; +// #[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()) -} +// pub fn error_to_io_error(e: Error) -> IoError { +// IoError::new(IoErrorKind::Other, e.to_string()) +// } diff --git a/mbedtls/src/ssl/context.rs b/mbedtls/src/ssl/context.rs index 52925705..41e2c9de 100644 --- a/mbedtls/src/ssl/context.rs +++ b/mbedtls/src/ssl/context.rs @@ -6,10 +6,7 @@ * option. This file may not be copied, modified, or distributed except * according to those terms. */ -#[cfg(not(feature = "std"))] -use core_io::{self as io, Read, Write}; -#[cfg(feature = "std")] -use std::io::{self, Read, Write}; +use genio::{Read, Write}; use mbedtls_sys::types::raw_types::{c_int, c_uchar, c_void}; use mbedtls_sys::types::size_t; @@ -268,27 +265,37 @@ impl<'a> Session<'a> { } impl<'a> Read for Session<'a> { - fn read(&mut self, buf: &mut [u8]) -> io::Result { + type ReadError = Error; + + fn read(&mut self, buf: &mut [u8]) -> StdResult { match unsafe { ssl_read(self.inner, buf.as_mut_ptr(), buf.len()).into_result() } { Err(Error::SslPeerCloseNotify) => Ok(0), - Err(e) => Err(crate::private::error_to_io_error(e)), + Err(e) => Err(e), Ok(i) => Ok(i as usize), } } } impl<'a> Write for Session<'a> { - fn write(&mut self, buf: &[u8]) -> io::Result { + type WriteError = Error; + type FlushError = Error; + + #[inline] + fn write(&mut self, buf: &[u8]) -> StdResult { match unsafe { ssl_write(self.inner, buf.as_ptr(), buf.len()).into_result() } { Err(Error::SslPeerCloseNotify) => Ok(0), - Err(e) => Err(crate::private::error_to_io_error(e)), + Err(e) => Err(e), Ok(i) => Ok(i as usize), } } - fn flush(&mut self) -> io::Result<()> { + #[inline] + fn flush(&mut self) -> StdResult<(), Self::FlushError> { Ok(()) } + + #[inline] + fn size_hint(&mut self, _byte_count: usize) {} } impl<'a> Drop for Session<'a> { diff --git a/mbedtls/src/x509/certificate.rs b/mbedtls/src/x509/certificate.rs index 4f6cbda7..047937d2 100644 --- a/mbedtls/src/x509/certificate.rs +++ b/mbedtls/src/x509/certificate.rs @@ -17,20 +17,27 @@ use crate::alloc_prelude::*; use mbedtls_sys::types::raw_types::c_char; use mbedtls_sys::*; +use crate::x509::{Crl, Profile}; +use core::result::Result as StdResult; +use serde::de::{Deserialize, Deserializer, Error as DeError, Visitor}; +use serde::ser::{Serialize, Serializer}; + #[cfg(feature = "std")] -use yasna::{BERDecodable, BERReader, ASN1Result, ASN1Error, ASN1ErrorKind, models::ObjectIdentifier}; +use yasna::{ + models::ObjectIdentifier, ASN1Error, ASN1ErrorKind, ASN1Result, BERDecodable, BERReader, +}; -use crate::pk::Pk; use crate::error::{Error, IntoResult, Result}; +use crate::hash::Type as MdType; +use crate::pk::Pk; use crate::private::UnsafeFrom; use crate::rng::Random; -use crate::hash::Type as MdType; -#[derive(Debug,Copy,Clone,Eq,PartialEq)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum CertificateVersion { V1, V2, - V3 + V3, } define!( @@ -55,7 +62,11 @@ impl BERDecodable for Extension { let oid = reader.next().read_oid()?; let critical = reader.read_optional(|r| r.read_bool())?.unwrap_or(false); let value = reader.next().read_bytes()?; - Ok(Extension { oid, critical, value }) + Ok(Extension { + oid, + critical, + value, + }) }) } } @@ -139,6 +150,44 @@ impl DerefMut for Certificate { } } +impl Serialize for Certificate { + /// Keys are serialized as DER-encoded byte streams + #[inline] + fn serialize(&self, serializer: S) -> StdResult { + serializer.serialize_bytes(self.as_der()) + } +} + +impl<'de> Deserialize<'de> for Certificate { + #[inline] + fn deserialize>(deserializer: D) -> StdResult { + struct CertVisitor; + + impl<'de> Visitor<'de> for CertVisitor { + type Value = Certificate; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "An public key structure as DER bytes") + } + + #[inline] + fn visit_bytes(self, value: &[u8]) -> StdResult { + Ok(Certificate::from_der(value) + .map_err(|tls_err| E::custom(tls_err.to_string()))? + .into()) + } + } + + deserializer.deserialize_bytes(CertVisitor) + } +} + +impl PartialEq for Certificate { + fn eq(&self, other: &Certificate) -> bool { + (self.as_der() == other.as_der()) + } +} + #[repr(C)] pub struct LinkedCertificate { inner: x509_crt, @@ -159,7 +208,15 @@ fn x509_time_to_time(tm: &x509_time) -> Result { return Err(Error::X509InvalidDate); } - super::Time::new(tm.year as u16, tm.mon as u8, tm.day as u8, tm.hour as u8, tm.min as u8, tm.sec as u8).ok_or(Error::X509InvalidDate) + super::Time::new( + tm.year as u16, + tm.mon as u8, + tm.day as u8, + tm.hour as u8, + tm.min as u8, + tm.sec as u8, + ) + .ok_or(Error::X509InvalidDate) } impl LinkedCertificate { @@ -224,7 +281,7 @@ impl LinkedCertificate { 1 => Ok(CertificateVersion::V1), 2 => Ok(CertificateVersion::V2), 3 => Ok(CertificateVersion::V3), - _ => Err(Error::X509InvalidVersion) + _ => Err(Error::X509InvalidVersion), } } @@ -255,7 +312,8 @@ impl LinkedCertificate { } })?; return Ok(()); - }).map_err(|_| Error::X509InvalidExtensions)?; + }) + .map_err(|_| Error::X509InvalidExtensions)?; Ok(ext) } @@ -268,17 +326,29 @@ impl LinkedCertificate { MdType::from(self.inner.sig_md) } + #[inline] pub fn verify( &mut self, trust_ca: &mut Certificate, err_info: Option<&mut String>, + ) -> Result<()> { + self.verify_with_profile(trust_ca, None, None, err_info) + } + + pub fn verify_with_profile( + &mut self, + trust_ca: &mut Certificate, + crl: Option<&mut Crl>, + profile: Option<&Profile>, + err_info: Option<&mut String>, ) -> Result<()> { let mut flags = 0; let result = unsafe { - x509_crt_verify( + x509_crt_verify_with_profile( &mut self.inner, &mut trust_ca.inner, - ptr::null_mut(), + crl.map_or(ptr::null_mut(), |revlist| revlist.into()), + profile.map_or(ptr::null(), |prof| prof.into()), ptr::null(), &mut flags, None, @@ -496,7 +566,8 @@ define!( impl<'a> Builder<'a> { unsafe fn subject_with_nul_unchecked(&mut self, subject: &[u8]) -> Result<&mut Self> { - x509write_crt_set_subject_name(&mut self.inner, subject.as_ptr() as *const _).into_result()?; + x509write_crt_set_subject_name(&mut self.inner, subject.as_ptr() as *const _) + .into_result()?; Ok(self) } @@ -517,7 +588,8 @@ impl<'a> Builder<'a> { } unsafe fn issuer_with_nul_unchecked(&mut self, issuer: &[u8]) -> Result<&mut Self> { - x509write_crt_set_issuer_name(&mut self.inner, issuer.as_ptr() as *const _).into_result()?; + x509write_crt_set_issuer_name(&mut self.inner, issuer.as_ptr() as *const _) + .into_result()?; Ok(self) } @@ -565,19 +637,18 @@ impl<'a> Builder<'a> { oid.len(), critical as _, val.as_ptr(), - val.len() - ) }.into_result()?; + val.len(), + ) + } + .into_result()?; Ok(self) } pub fn basic_constraints(&mut self, ca: bool, pathlen: Option) -> Result<&mut Self> { unsafe { - x509write_crt_set_basic_constraints( - &mut self.inner, - ca as _, - pathlen.unwrap_or(0) as _ - ) - }.into_result()?; + x509write_crt_set_basic_constraints(&mut self.inner, ca as _, pathlen.unwrap_or(0) as _) + } + .into_result()?; Ok(self) } @@ -590,9 +661,10 @@ impl<'a> Builder<'a> { x509write_crt_set_validity( &mut self.inner, not_before.to_x509_time().as_ptr() as _, - not_after.to_x509_time().as_ptr() as _ + not_after.to_x509_time().as_ptr() as _, ) - }.into_result()?; + } + .into_result()?; Ok(self) } @@ -786,7 +858,8 @@ JS7pkcufTIoN0Yj0SxAWLW711FgB let mut t = Test::new(); let output = t .builder() - .serial(&[5]).unwrap() + .serial(&[5]) + .unwrap() .signature_hash(MdType::Sha256) .write_der_vec(&mut crate::test_support::rand::test_rng()) .unwrap(); @@ -798,7 +871,8 @@ JS7pkcufTIoN0Yj0SxAWLW711FgB let mut t = Test::new(); let output = t .builder() - .serial(&[5]).unwrap() + .serial(&[5]) + .unwrap() .signature_hash(MdType::Sha256) .write_pem_string(&mut crate::test_support::rand::test_rng()) .unwrap(); @@ -838,45 +912,75 @@ cYp0bH/RcPTC0Z+ZaqSWMtfxRrk63MJQF9EXpDCdvQRcTMD9D85DJrMKn8aumq0M ); assert_eq!(cert.digest_type(), MdType::Sha256); - assert_eq!(hex::encode(cert.serial_raw().unwrap()), "00b634492e6963d61bfda207bd202f98eb"); - assert_eq!(hex::encode(cert.issuer_raw().unwrap()), "301f3110300e0603550403130754657374204341310b3009060355040613025553"); - assert_eq!(hex::encode(cert.subject_raw().unwrap()), "30233112301006035504031309546573742043657274310d300b060355040a130454657374"); + assert_eq!( + hex::encode(cert.serial_raw().unwrap()), + "00b634492e6963d61bfda207bd202f98eb" + ); + assert_eq!( + hex::encode(cert.issuer_raw().unwrap()), + "301f3110300e0603550403130754657374204341310b3009060355040613025553" + ); + assert_eq!( + hex::encode(cert.subject_raw().unwrap()), + "30233112301006035504031309546573742043657274310d300b060355040a130454657374" + ); assert_eq!(hex::encode(cert.signature().unwrap()), "4a4b2638e636a0c0121b0334e04b342ac17b178b1a3000d5dc84c0612941519e3ac99da72823809e643f9d1c0ff7ca2734c63974215879f6286532d43b0da6086fb212a96c8f573de4230c9ab3ae09d621719d2e35b3e91963d5e763a273f0e25d6bbc5fcd0cd7ace688821df1724fb3956c96046cd58126f3ae2a66680cccc8aaecbe680fa5fc79684ef33f64153b319713f42ea17aa3fdb99b94d95466ed75e572789d2c7388a49d35a6590429fe9b6959896e8658aee276f3474ff315051e6633be236d2acf552164ea6936122f9d718a746c7fd170f4c2d19f996aa49632d7f146b93adcc25017d117a4309dbd045c4cc0fd0fce4326b30a9fc6ae9aad0c"); assert_eq!(hex::encode(cert.extensions_raw().unwrap()), "30819f30210603551d0e041a04186839fad57e6544121cc6bc421953cc9620655c57cfac060230320603551d11042b302981117465737440666f7274616e69782e636f6d82146578616d706c652e666f7274616e69782e636f6d300c0603551d130101ff0402300030230603551d23041c301a801879076bcc8da0077e4116f84b8e4c9c5c6af7ec4fa000d98730130603551d25040c300a06082b06010505070302"); use crate::x509::Time; - assert_eq!(cert.not_before().unwrap(), Time::new(2019,1,8,0,18,35).unwrap()); - assert_eq!(cert.not_after().unwrap(), Time::new(2029,1,5,0,18,35).unwrap()); + assert_eq!( + cert.not_before().unwrap(), + Time::new(2019, 1, 8, 0, 18, 35).unwrap() + ); + assert_eq!( + cert.not_after().unwrap(), + Time::new(2029, 1, 5, 0, 18, 35).unwrap() + ); - #[cfg(feature = "std")] { + #[cfg(feature = "std")] + { let ext = cert.extensions().unwrap(); assert_eq!(ext.len(), 5); - assert_eq!(ext[0], Extension { - oid: ObjectIdentifier::from_slice(&[2,5,29,14]), - critical: false, - value: hex::decode("04186839FAD57E6544121CC6BC421953CC9620655C57CFAC0602").unwrap(), - }); + assert_eq!( + ext[0], + Extension { + oid: ObjectIdentifier::from_slice(&[2, 5, 29, 14]), + critical: false, + value: hex::decode("04186839FAD57E6544121CC6BC421953CC9620655C57CFAC0602") + .unwrap(), + } + ); assert_eq!(ext[1], Extension { oid: ObjectIdentifier::from_slice(&[2,5,29,17]), critical: false, value: hex::decode("302981117465737440666f7274616e69782e636f6d82146578616d706c652e666f7274616e69782e636f6d").unwrap() }); - assert_eq!(ext[2], Extension { - oid: ObjectIdentifier::from_slice(&[2,5,29,19]), - critical: true, - value: hex::decode("3000").unwrap() - }); - assert_eq!(ext[3], Extension { - oid: ObjectIdentifier::from_slice(&[2,5,29,35]), - critical: false, - value: hex::decode("301a801879076BCC8DA0077E4116F84B8E4C9C5C6AF7EC4FA000D987").unwrap() - }); - assert_eq!(ext[4], Extension { - oid: ObjectIdentifier::from_slice(&[2,5,29,37]), - critical: false, - value: hex::decode("300a06082b06010505070302").unwrap(), - }); + assert_eq!( + ext[2], + Extension { + oid: ObjectIdentifier::from_slice(&[2, 5, 29, 19]), + critical: true, + value: hex::decode("3000").unwrap() + } + ); + assert_eq!( + ext[3], + Extension { + oid: ObjectIdentifier::from_slice(&[2, 5, 29, 35]), + critical: false, + value: hex::decode("301a801879076BCC8DA0077E4116F84B8E4C9C5C6AF7EC4FA000D987") + .unwrap() + } + ); + assert_eq!( + ext[4], + Extension { + oid: ObjectIdentifier::from_slice(&[2, 5, 29, 37]), + critical: false, + value: hex::decode("300a06082b06010505070302").unwrap(), + } + ); } } diff --git a/mbedtls/src/x509/profile.rs b/mbedtls/src/x509/profile.rs index 78cbcb17..6070b4be 100644 --- a/mbedtls/src/x509/profile.rs +++ b/mbedtls/src/x509/profile.rs @@ -7,6 +7,10 @@ * according to those terms. */ use mbedtls_sys::*; +use crate::{hash, pk}; + +#[cfg(not(feature = "std"))] +use crate::alloc_prelude::*; define!( #[c_ty(x509_crt_profile)] @@ -15,6 +19,31 @@ define!( impl<'a> Into {} ); +impl Profile { + pub fn new(hash_types: Vec, pk_types: Vec, curves: Vec, rsa_min_bitlen: u32) -> Self { + let mut allowed_mds = 0u32; + let mut allowed_pks = 0u32; + let mut allowed_curves = 0u32; + for md in hash_types { + allowed_mds |= 1 << (md as u32 - 1); + } + for algo in pk_types { + allowed_pks |= 1 << (algo as u32 - 1); + } + for curve in curves { + allowed_curves |= 1 << (curve as u32 - 1); + } + Profile { + inner: x509_crt_profile { + allowed_mds, + allowed_pks, + allowed_curves, + rsa_min_bitlen, + } + } + } +} + extern "C" { #[link_name = "mbedtls_x509_crt_profile_default"] pub static DEFAULT: Profile;