rust-openssl版本升级到0.10.56

Signed-off-by: 薛磊 <xuelei3@huawei.com>
This commit is contained in:
薛磊
2024-02-27 16:21:13 +08:00
parent 7495bd5a0e
commit ad581c5d4b
68 changed files with 2650 additions and 344 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
"Name": "openssl",
"License": "Apache License V2.0",
"License File": "THIRD_PARTY",
"Version Number": "0.10.48",
"Version Number": "0.10.56",
"Owner": "xuelei3@huawei.com",
"Upstream URL": "https://github.com/sfackler/rust-openssl",
"Description": "OpenSSL bindings."
+1 -1
View File
@@ -3,7 +3,7 @@ name = "openssl-errors"
version = "0.2.0"
authors = ["Steven Fackler <sfackler@gmail.com>"]
edition = "2018"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
description = "Custom error library support for the openssl crate."
repository = "https://github.com/sfackler/rust-openssl"
readme = "README.md"
+1 -1
View File
@@ -20,7 +20,7 @@ ohos_cargo_crate("lib") {
sources = [ "src/lib.rs" ]
edition = "2018"
cargo_pkg_version = "0.1.0"
cargo_pkg_version = "0.1.1"
cargo_pkg_name = "openssl-macros"
cargo_pkg_description = "Internal macros used by the openssl crate."
deps = [
+3 -3
View File
@@ -1,8 +1,8 @@
[package]
name = "openssl-macros"
version = "0.1.0"
version = "0.1.1"
edition = "2018"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
description = "Internal macros used by the openssl crate."
[lib]
@@ -11,4 +11,4 @@ proc-macro = true
[dependencies]
proc-macro2 = "1"
quote = "1"
syn = { version = "1", features = ["full"] }
syn = { version = "2", features = ["full"] }
+1 -1
View File
@@ -20,7 +20,7 @@ ohos_cargo_crate("lib") {
sources = [ "src/lib.rs" ]
edition = "2018"
cargo_pkg_version = "0.9.82"
cargo_pkg_version = "0.9.91"
cargo_pkg_authors = "Alex Crichton <alex@alexcrichton.com>, Steven Fackler <sfackler@gmail.com>"
cargo_pkg_name = "openssl-sys"
cargo_pkg_description = "FFI bindings to OpenSSL"
+89 -1
View File
@@ -2,6 +2,86 @@
## [Unreleased]
## [v0.9.91] - 2023-08-06
### Added
* Expose `poly1305_state`, `CRYPTO_poly1305_init`, `CRYPTO_poly1305_update`, and `CRYPTO_poly1305_finish` on BoringSSL and LibreSSL.
* Fix detection of libraries on OpenBSD.
* Added `EC_POINT_point2hex` and `EC_POINT_hex2point`.
* Added `EVP_PKEY_verify_recover_init`, `EVP_PKEY_verify_recover`, and `EVP_PKEY_CTX_set_signature_md`.
* Added `EVP_CIPHER_CTX_FLAG_WRAP_ALLOW` and `EVP_CTX_set_flags`.
* Added `BN_mod_sqrt`.
## [v0.9.90] - 2023-06-20
### Fixed
* Fixed compilation with BoringSSL when building with the bindgen CLI.
## [v0.9.89] - 2023-06-20
### Fixed
* Fixed compilation with recent versions of BoringSSL.
### Added
* Added support for detecting OpenSSL compiled with `OPENSSL_NO_OCB`.
* Added `EVP_PKEY_SM2` and `NID_sm2`.
* Added `EVP_PKEY_assign_RSA`, `EVP_PKEY_assign_DSA`, `EVP_PKEY_assign_DH`, and `EVP_PKEY_assign_EC_KEY`.
* Added `EC_GROUP_get_asn1_flag`.
* Expose `EC_POINT_get_affine_coordinates` on BoringSSL and LibreSSL.
* Added `EVP_PKEY_derive_set_peer_ex`.
## [v0.9.88] - 2023-05-30
### Added
* Added support for the LibreSSL 3.8.0.
* Added support for detecting `OPENSSL_NO_RC4`.
* Added `OBJ_dup`.
* Added `ASN1_TYPE_new`, `ASN1_TYPE_set`, `d2i_ASN1_TYPE`, and `i2d_ASN1_TYPE`.
* Added `SSL_bytes_to_cipher_list`, `SSL_CTX_get_num_tickets`, and `SSL_get_num_tickets`.
* Added `GENERAL_NAME_set0_othername`.
* Added `X509_get_pathlen`.
## [v0.9.87] - 2023-04-24
### Added
* Added `DH_CHECK`.
* Added `CMAC_CTX_new`, `CMAC_CTX_free`, `CMAC_Init`, `CMAC_Update`, `CMAC_Final`, and `CMAC_CTX_copy`.
* Added `EVP_default_properties_is_fips_enabled`.
* Added `X509_get0_subject_key_id`, `X509_get0_authority_key_id`, `X509_get0_authority_issuer`, and `X509_get0_authority_serial`.
* Added `NID_poly1305`.
## [v0.9.86] - 2023-04-20
### Fixed
* Fixed BoringSSL support with the latest bindgen release.
### Added
* Added bindings for PKCS#7 functions and more X.509 functions.
## [v0.9.85] - 2023-04-09
### Added
* Added support for LibreSSL 3.7.x.
## [v0.9.84] - 2023-04-01
### Added
* Added `ASN1_INTEGER_dup` and `ASN1_INTEGER_cmp`.
* Added `stack_st_X509_NAME_ENTRY`.
* Added `DIST_POINT_NAME`, `DIST_POINT`, `stack_st_DIST_POINT`, `DIST_POINT_free`, and `DIST_POINT_NAME_free`.
## [v0.9.83] - 2023-03-23
### Fixed
@@ -410,7 +490,15 @@ Fixed builds against OpenSSL built with `no-cast`.
* Added `X509_verify` and `X509_REQ_verify`.
* Added `EVP_MD_type` and `EVP_GROUP_get_curve_name`.
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.83..master
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.91..master
[v0.9.91]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.90...openssl-sys-v0.9.91
[v0.9.90]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.89...openssl-sys-v0.9.90
[v0.9.89]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.88...openssl-sys-v0.9.89
[v0.9.88]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.87...openssl-sys-v0.9.88
[v0.9.87]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.86...openssl-sys-v0.9.87
[v0.9.86]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.85...openssl-sys-v0.9.86
[v0.9.85]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.84...openssl-sys-v0.9.85
[v0.9.84]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.83...openssl-sys-v0.9.84
[v0.9.83]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.82...openssl-sys-v0.9.83
[v0.9.82]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.81...openssl-sys-v0.9.82
[v0.9.81]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.80...openssl-sys-v0.9.81
+2 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "openssl-sys"
version = "0.9.83"
version = "0.9.91"
authors = [
"Alex Crichton <alex@alexcrichton.com>",
"Steven Fackler <sfackler@gmail.com>",
@@ -24,12 +24,9 @@ bssl-sys = { version = "0.1.0", optional = true }
[build-dependencies]
bindgen = { version = "0.64.0", optional = true, features = ["experimental"] }
cc = "1.0"
cc = "1.0.61"
openssl-src = { version = "111", optional = true }
pkg-config = "0.3.9"
autocfg = "1.0"
[target.'cfg(target_env = "msvc")'.build-dependencies]
vcpkg = "0.2.8"
# We don't actually use metadeps for annoying reasons but this is still here for tooling
+4
View File
@@ -1,3 +1,4 @@
#[allow(clippy::unusual_byte_groupings)]
pub fn get(openssl_version: Option<u64>, libressl_version: Option<u64>) -> Vec<&'static str> {
let mut cfgs = vec![];
@@ -91,6 +92,9 @@ pub fn get(openssl_version: Option<u64>, libressl_version: Option<u64>) -> Vec<&
if openssl_version >= 0x1_01_01_03_0 {
cfgs.push("ossl111c");
}
if openssl_version >= 0x1_01_01_04_0 {
cfgs.push("ossl111d");
}
}
cfgs
+12
View File
@@ -75,10 +75,18 @@ RUST_CONF_OPENSSL_NO_NEXTPROTONEG
RUST_CONF_OPENSSL_NO_OCSP
#endif
#ifdef OPENSSL_NO_OCB
RUST_CONF_OPENSSL_NO_OCB
#endif
#ifdef OPENSSL_NO_PSK
RUST_CONF_OPENSSL_NO_PSK
#endif
#ifdef OPENSSL_NO_RC4
RUST_CONF_OPENSSL_NO_RC4
#endif
#ifdef OPENSSL_NO_RFC3779
RUST_CONF_OPENSSL_NO_RFC3779
#endif
@@ -103,6 +111,10 @@ RUST_CONF_OPENSSL_NO_SSL3_METHOD
RUST_CONF_OPENSSL_NO_TLSEXT
#endif
#ifdef OPENSSL_NO_SOCK
RUST_CONF_OPENSSL_NO_SOCK
#endif
#ifdef OPENSSL_NO_STDIO
RUST_CONF_OPENSSL_NO_STDIO
#endif
+10 -11
View File
@@ -92,8 +92,8 @@ fn find_openssl_dir(target: &str) -> OsString {
try_pkg_config();
try_vcpkg();
// FreeBSD ships with OpenSSL but doesn't include a pkg-config file :(
if host == target && target.contains("freebsd") {
// FreeBSD and OpenBSD ship with Libre|OpenSSL but don't include a pkg-config file
if host == target && (target.contains("freebsd") || target.contains("openbsd")) {
return OsString::from("/usr");
}
@@ -198,13 +198,11 @@ fn try_pkg_config() {
let target = env::var("TARGET").unwrap();
let host = env::var("HOST").unwrap();
// If we're going to windows-gnu we can use pkg-config, but only so long as
// we're coming from a windows host.
//
// Otherwise if we're going to windows we probably can't use pkg-config.
// FIXME we really shouldn't be automatically enabling this
if target.contains("windows-gnu") && host.contains("windows") {
env::set_var("PKG_CONFIG_ALLOW_CROSS", "1");
} else if target.contains("windows") {
} else if target.contains("windows-msvc") {
// MSVC targets use vcpkg instead.
return;
}
@@ -232,8 +230,12 @@ fn try_pkg_config() {
///
/// Note that if this succeeds then the function does not return as vcpkg
/// should emit all of the cargo metadata that we need.
#[cfg(target_env = "msvc")]
fn try_vcpkg() {
let target = env::var("TARGET").unwrap();
if !target.contains("windows") {
return;
}
// vcpkg will not emit any metadata if it can not find libraries
// appropriate for the target triple with the desired linkage.
@@ -257,9 +259,6 @@ fn try_vcpkg() {
process::exit(0);
}
#[cfg(not(target_env = "msvc"))]
fn try_vcpkg() {}
fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option<String> {
let out = Command::new(cmd).args(args).output();
if let Ok(ref r1) = out {
+11 -38
View File
@@ -1,17 +1,9 @@
#![allow(
clippy::inconsistent_digit_grouping,
clippy::uninlined_format_args,
clippy::unusual_byte_groupings
)]
extern crate autocfg;
#[cfg(feature = "bindgen")]
extern crate bindgen;
extern crate cc;
#[cfg(feature = "vendored")]
extern crate openssl_src;
extern crate pkg_config;
#[cfg(target_env = "msvc")]
extern crate vcpkg;
use std::collections::HashSet;
@@ -74,8 +66,6 @@ fn check_ssl_kind() {
}
fn main() {
check_rustc_versions();
check_ssl_kind();
let target = env::var("TARGET").unwrap();
@@ -134,15 +124,6 @@ fn main() {
}
}
fn check_rustc_versions() {
let cfg = autocfg::new();
if cfg.probe_rustc_version(1, 31) {
println!("cargo:rustc-cfg=const_fn");
}
}
#[allow(clippy::let_and_return)]
fn postprocess(include_dirs: &[PathBuf]) -> Version {
let version = validate_headers(include_dirs);
@@ -157,7 +138,7 @@ fn postprocess(include_dirs: &[PathBuf]) -> Version {
/// Validates the header files found in `include_dir` and then returns the
/// version string of OpenSSL.
#[allow(clippy::manual_strip)] // we need to support pre-1.45.0
#[allow(clippy::unusual_byte_groupings)]
fn validate_headers(include_dirs: &[PathBuf]) -> Version {
// This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, 1.1.0, 1.1.1 and 3.0.0.
// To correctly expose the right API from this crate, take a look at
@@ -173,9 +154,7 @@ fn validate_headers(include_dirs: &[PathBuf]) -> Version {
// account for compile differences and such.
println!("cargo:rerun-if-changed=build/expando.c");
let mut gcc = cc::Build::new();
for include_dir in include_dirs {
gcc.include(include_dir);
}
gcc.includes(include_dirs);
let expanded = match gcc.file("build/expando.c").try_expand() {
Ok(expanded) => expanded,
Err(e) => {
@@ -221,17 +200,14 @@ See rust-openssl documentation for more information:
let libressl_prefix = "RUST_VERSION_LIBRESSL_";
let boringsl_prefix = "RUST_OPENSSL_IS_BORINGSSL";
let conf_prefix = "RUST_CONF_";
if line.starts_with(openssl_prefix) {
let version = &line[openssl_prefix.len()..];
if let Some(version) = line.strip_prefix(openssl_prefix) {
openssl_version = Some(parse_version(version));
} else if line.starts_with(new_openssl_prefix) {
let version = &line[new_openssl_prefix.len()..];
} else if let Some(version) = line.strip_prefix(new_openssl_prefix) {
openssl_version = Some(parse_new_version(version));
} else if line.starts_with(libressl_prefix) {
let version = &line[libressl_prefix.len()..];
} else if let Some(version) = line.strip_prefix(libressl_prefix) {
libressl_version = Some(parse_version(version));
} else if line.starts_with(conf_prefix) {
enabled.push(&line[conf_prefix.len()..]);
} else if let Some(conf) = line.strip_prefix(conf_prefix) {
enabled.push(conf);
} else if line.starts_with(boringsl_prefix) {
is_boringssl = true;
}
@@ -295,6 +271,8 @@ See rust-openssl documentation for more information:
(3, 6, _) => ('3', '6', 'x'),
(3, 7, 0) => ('3', '7', '0'),
(3, 7, 1) => ('3', '7', '1'),
(3, 7, _) => ('3', '7', 'x'),
(3, 8, 0) => ('3', '8', '0'),
_ => version_error(),
};
@@ -337,7 +315,7 @@ fn version_error() -> ! {
"
This crate is only compatible with OpenSSL (version 1.0.1 through 1.1.1, or 3.0.0), or LibreSSL 2.5
through 3.7.1, but a different version of OpenSSL was found. The build is now aborting
through 3.8.0, but a different version of OpenSSL was found. The build is now aborting
due to this version mismatch.
"
@@ -345,18 +323,13 @@ due to this version mismatch.
}
// parses a string that looks like "0x100020cfL"
#[allow(deprecated)] // trim_right_matches is now trim_end_matches
#[allow(clippy::match_like_matches_macro)] // matches macro requires rust 1.42.0
fn parse_version(version: &str) -> u64 {
// cut off the 0x prefix
assert!(version.starts_with("0x"));
let version = &version[2..];
// and the type specifier suffix
let version = version.trim_right_matches(|c: char| match c {
'0'..='9' | 'a'..='f' | 'A'..='F' => false,
_ => true,
});
let version = version.trim_end_matches(|c: char| !c.is_ascii_hexdigit());
u64::from_str_radix(version, 16).unwrap()
}
+15 -2
View File
@@ -12,6 +12,7 @@ const INCLUDES: &str = "
#include <openssl/aes.h>
#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/cmac.h>
#include <openssl/conf.h>
#include <openssl/crypto.h>
#include <openssl/dh.h>
@@ -54,6 +55,10 @@ const INCLUDES: &str = "
#if OPENSSL_VERSION_NUMBER >= 0x30000000
#include <openssl/provider.h>
#endif
#if defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_BORINGSSL)
#include <openssl/poly1305.h>
#endif
";
#[cfg(feature = "bindgen")]
@@ -109,12 +114,15 @@ pub fn run_boringssl(include_dirs: &[PathBuf]) {
let mut builder = bindgen::builder()
.rust_target(RustTarget::Stable_1_47)
.ctypes_prefix("::libc")
.raw_line("use libc::*;")
.derive_default(false)
.enable_function_attribute_detection()
.size_t_is_usize(true)
.default_macro_constant_type(MacroTypeVariation::Signed)
.rustified_enum("point_conversion_form_t")
.allowlist_file(".*/openssl/[^/]+\\.h")
.allowlist_recursively(false)
.blocklist_function("BIO_vsnprintf")
.blocklist_function("OPENSSL_vasprintf")
.wrap_static_fns(true)
.wrap_static_fns_path(out_dir.join("boring_static_wrapper").display().to_string())
.layout_tests(false)
@@ -163,14 +171,19 @@ pub fn run_boringssl(include_dirs: &[PathBuf]) {
bindgen_cmd
.arg("-o")
.arg(out_dir.join("bindgen.rs"))
// Must be a valid version from
// https://docs.rs/bindgen/latest/bindgen/enum.RustTarget.html
.arg("--rust-target=1.47")
.arg("--ctypes-prefix=::libc")
.arg("--raw-line=use libc::*;")
.arg("--no-derive-default")
.arg("--enable-function-attribute-detection")
.arg("--size_t-is-usize")
.arg("--default-macro-constant-type=signed")
.arg("--rustified-enum=point_conversion_form_t")
.arg("--allowlist-file=.*/openssl/[^/]+\\.h")
.arg("--no-recursive-allowlist")
.arg("--blocklist-function=BIO_vsnprintf")
.arg("--blocklist-function=OPENSSL_vasprintf")
.arg("--experimental")
.arg("--wrap-static-fns")
.arg("--wrap-static-fns-path")
+32 -36
View File
@@ -20,51 +20,47 @@ cfg_if! {
pub const ERR_RFLAG_FATAL: c_ulong = 0x1 << ERR_RFLAGS_OFFSET;
const_fn! {
pub const fn ERR_SYSTEM_ERROR(errcode: c_ulong) -> bool {
errcode & ERR_SYSTEM_FLAG != 0
}
pub const fn ERR_SYSTEM_ERROR(errcode: c_ulong) -> bool {
errcode & ERR_SYSTEM_FLAG != 0
}
pub const fn ERR_GET_LIB(errcode: c_ulong) -> c_int {
// hacks since `if` isn't yet stable in const functions :(
((ERR_LIB_SYS as c_ulong * (ERR_SYSTEM_ERROR(errcode) as c_ulong)) |
(((errcode >> ERR_LIB_OFFSET) & ERR_LIB_MASK) * (!ERR_SYSTEM_ERROR(errcode) as c_ulong))) as c_int
}
pub const fn ERR_GET_LIB(errcode: c_ulong) -> c_int {
// hacks since `if` isn't yet stable in const functions :(
((ERR_LIB_SYS as c_ulong * (ERR_SYSTEM_ERROR(errcode) as c_ulong)) |
(((errcode >> ERR_LIB_OFFSET) & ERR_LIB_MASK) * (!ERR_SYSTEM_ERROR(errcode) as c_ulong))) as c_int
}
pub const fn ERR_GET_FUNC(_errcode: c_ulong) -> c_int {
0
}
pub const fn ERR_GET_FUNC(_errcode: c_ulong) -> c_int {
0
}
pub const fn ERR_GET_REASON(errcode: c_ulong) -> c_int {
// hacks since `if` isn't yet stable in const functions :(
((ERR_LIB_SYS as c_ulong * (ERR_SYSTEM_ERROR(errcode) as c_ulong)) |
((errcode & ERR_REASON_MASK) * (!ERR_SYSTEM_ERROR(errcode) as c_ulong))) as c_int
}
pub const fn ERR_GET_REASON(errcode: c_ulong) -> c_int {
// hacks since `if` isn't yet stable in const functions :(
((ERR_LIB_SYS as c_ulong * (ERR_SYSTEM_ERROR(errcode) as c_ulong)) |
((errcode & ERR_REASON_MASK) * (!ERR_SYSTEM_ERROR(errcode) as c_ulong))) as c_int
}
pub const fn ERR_PACK(lib: c_int, _func: c_int, reason: c_int) -> c_ulong {
((lib as c_ulong & ERR_LIB_MASK) << ERR_LIB_OFFSET) |
(reason as c_ulong & ERR_REASON_MASK)
}
pub const fn ERR_PACK(lib: c_int, _func: c_int, reason: c_int) -> c_ulong {
((lib as c_ulong & ERR_LIB_MASK) << ERR_LIB_OFFSET) |
(reason as c_ulong & ERR_REASON_MASK)
}
} else {
const_fn! {
pub const fn ERR_PACK(l: c_int, f: c_int, r: c_int) -> c_ulong {
((l as c_ulong & 0x0FF) << 24) |
((f as c_ulong & 0xFFF) << 12) |
(r as c_ulong & 0xFFF)
}
pub const fn ERR_PACK(l: c_int, f: c_int, r: c_int) -> c_ulong {
((l as c_ulong & 0x0FF) << 24) |
((f as c_ulong & 0xFFF) << 12) |
(r as c_ulong & 0xFFF)
}
pub const fn ERR_GET_LIB(l: c_ulong) -> c_int {
((l >> 24) & 0x0FF) as c_int
}
pub const fn ERR_GET_LIB(l: c_ulong) -> c_int {
((l >> 24) & 0x0FF) as c_int
}
pub const fn ERR_GET_FUNC(l: c_ulong) -> c_int {
((l >> 12) & 0xFFF) as c_int
}
pub const fn ERR_GET_FUNC(l: c_ulong) -> c_int {
((l >> 12) & 0xFFF) as c_int
}
pub const fn ERR_GET_REASON(l: c_ulong) -> c_int {
(l & 0xFFF) as c_int
}
pub const fn ERR_GET_REASON(l: c_ulong) -> c_int {
(l & 0xFFF) as c_int
}
}
}
+37
View File
@@ -10,6 +10,8 @@ pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption;
pub const EVP_PKEY_DSA: c_int = NID_dsa;
pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement;
pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey;
#[cfg(ossl111)]
pub const EVP_PKEY_SM2: c_int = NID_sm2;
#[cfg(any(ossl111, libressl370))]
pub const EVP_PKEY_X25519: c_int = NID_X25519;
#[cfg(any(ossl111, libressl370))]
@@ -20,9 +22,14 @@ pub const EVP_PKEY_X448: c_int = NID_X448;
pub const EVP_PKEY_ED448: c_int = NID_ED448;
pub const EVP_PKEY_HMAC: c_int = NID_hmac;
pub const EVP_PKEY_CMAC: c_int = NID_cmac;
#[cfg(ossl111)]
pub const EVP_PKEY_POLY1305: c_int = NID_poly1305;
#[cfg(ossl110)]
pub const EVP_PKEY_HKDF: c_int = NID_hkdf;
#[cfg(ossl102)]
pub const EVP_CIPHER_CTX_FLAG_WRAP_ALLOW: c_int = 0x1;
pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9;
pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10;
pub const EVP_CTRL_GCM_SET_TAG: c_int = 0x11;
@@ -182,6 +189,8 @@ pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN
pub const EVP_PKEY_OP_TYPE_CRYPT: c_int = EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT;
pub const EVP_PKEY_CTRL_MD: c_int = 1;
pub const EVP_PKEY_CTRL_SET_MAC_KEY: c_int = 6;
pub const EVP_PKEY_CTRL_CIPHER: c_int = 12;
@@ -283,3 +292,31 @@ pub unsafe fn EVP_PKEY_CTX_add1_hkdf_info(
info as *mut c_void,
)
}
#[cfg(all(not(ossl300), not(boringssl)))]
pub unsafe fn EVP_PKEY_CTX_set_signature_md(cxt: *mut EVP_PKEY_CTX, md: *mut EVP_MD) -> c_int {
EVP_PKEY_CTX_ctrl(
cxt,
-1,
EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_MD,
0,
md as *mut c_void,
)
}
pub unsafe fn EVP_PKEY_assign_RSA(pkey: *mut EVP_PKEY, rsa: *mut RSA) -> c_int {
EVP_PKEY_assign(pkey, EVP_PKEY_RSA, rsa as *mut c_void)
}
pub unsafe fn EVP_PKEY_assign_DSA(pkey: *mut EVP_PKEY, dsa: *mut DSA) -> c_int {
EVP_PKEY_assign(pkey, EVP_PKEY_DSA, dsa as *mut c_void)
}
pub unsafe fn EVP_PKEY_assign_DH(pkey: *mut EVP_PKEY, dh: *mut DH) -> c_int {
EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh as *mut c_void)
}
pub unsafe fn EVP_PKEY_assign_EC_KEY(pkey: *mut EVP_PKEY, ec_key: *mut EC_KEY) -> c_int {
EVP_PKEY_assign(pkey, EVP_PKEY_EC, ec_key as *mut c_void)
}
+59 -4
View File
@@ -10,23 +10,60 @@ pub struct ASN1_ENCODING {
extern "C" {
pub fn ASN1_OBJECT_free(x: *mut ASN1_OBJECT);
pub fn OBJ_dup(x: *const ASN1_OBJECT) -> *mut ASN1_OBJECT;
}
stack!(stack_st_ASN1_OBJECT);
#[repr(C)]
pub struct ASN1_TYPE {
pub type_: c_int,
pub value: ASN1_TYPE_value,
}
#[repr(C)]
pub union ASN1_TYPE_value {
pub ptr: *mut c_char,
pub boolean: ASN1_BOOLEAN,
pub asn1_string: *mut ASN1_STRING,
pub object: *mut ASN1_OBJECT,
pub integer: *mut ASN1_INTEGER,
pub enumerated: *mut ASN1_ENUMERATED,
pub bit_string: *mut ASN1_BIT_STRING,
pub octet_string: *mut ASN1_OCTET_STRING,
pub printablestring: *mut ASN1_PRINTABLESTRING,
pub t61string: *mut ASN1_T61STRING,
pub ia5string: *mut ASN1_IA5STRING,
pub generalstring: *mut ASN1_GENERALSTRING,
pub bmpstring: *mut ASN1_BMPSTRING,
pub universalstring: *mut ASN1_UNIVERSALSTRING,
pub utctime: *mut ASN1_UTCTIME,
pub generalizedtime: *mut ASN1_GENERALIZEDTIME,
pub visiblestring: *mut ASN1_VISIBLESTRING,
pub utf8string: *mut ASN1_UTF8STRING,
pub set: *mut ASN1_STRING,
pub sequence: *mut ASN1_STRING,
pub asn1_value: *mut ASN1_VALUE,
}
extern "C" {
pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING;
#[cfg(any(ossl110, libressl273))]
pub fn ASN1_STRING_get0_data(x: *const ASN1_STRING) -> *const c_uchar;
#[cfg(any(all(ossl101, not(ossl110)), libressl))]
pub fn ASN1_STRING_data(x: *mut ASN1_STRING) -> *mut c_uchar;
pub fn ASN1_BIT_STRING_free(x: *mut ASN1_BIT_STRING);
pub fn ASN1_STRING_new() -> *mut ASN1_STRING;
pub fn ASN1_OCTET_STRING_new() -> *mut ASN1_OCTET_STRING;
pub fn ASN1_STRING_free(x: *mut ASN1_STRING);
pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int;
pub fn ASN1_STRING_set(x: *mut ASN1_STRING, data: *const c_void, len_in: c_int) -> c_int;
pub fn ASN1_OCTET_STRING_set(
x: *mut ASN1_OCTET_STRING,
data: *const c_uchar,
len_in: c_int,
) -> c_int;
pub fn ASN1_STRING_set(x: *mut ASN1_STRING, data: *const c_void, len: c_int) -> c_int;
pub fn ASN1_BIT_STRING_free(x: *mut ASN1_BIT_STRING);
pub fn ASN1_OCTET_STRING_free(x: *mut ASN1_OCTET_STRING);
pub fn ASN1_GENERALIZEDTIME_free(tm: *mut ASN1_GENERALIZEDTIME);
pub fn ASN1_GENERALIZEDTIME_print(b: *mut BIO, tm: *const ASN1_GENERALIZEDTIME) -> c_int;
@@ -43,18 +80,36 @@ extern "C" {
pub fn ASN1_TIME_set(from: *mut ASN1_TIME, to: time_t) -> *mut ASN1_TIME;
pub fn ASN1_INTEGER_free(x: *mut ASN1_INTEGER);
pub fn ASN1_INTEGER_dup(a: *const ASN1_INTEGER) -> *mut ASN1_INTEGER;
pub fn ASN1_INTEGER_get(dest: *const ASN1_INTEGER) -> c_long;
pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int;
pub fn ASN1_INTEGER_cmp(a: *const ASN1_INTEGER, b: *const ASN1_INTEGER) -> c_int;
pub fn BN_to_ASN1_INTEGER(bn: *const BIGNUM, ai: *mut ASN1_INTEGER) -> *mut ASN1_INTEGER;
pub fn ASN1_INTEGER_to_BN(ai: *const ASN1_INTEGER, bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn ASN1_TIME_set_string(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
#[cfg(ossl111)]
pub fn ASN1_TIME_set_string_X509(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
pub fn ASN1_ENUMERATED_free(a: *mut ASN1_ENUMERATED);
#[cfg(ossl110)]
pub fn ASN1_ENUMERATED_get_int64(pr: *mut i64, a: *const ASN1_ENUMERATED) -> c_int;
pub fn ASN1_TYPE_new() -> *mut ASN1_TYPE;
pub fn ASN1_TYPE_set(a: *mut ASN1_TYPE, type_: c_int, value: *mut c_void);
pub fn ASN1_TYPE_free(x: *mut ASN1_TYPE);
pub fn d2i_ASN1_TYPE(
k: *mut *mut ASN1_TYPE,
buf: *mut *const u8,
len: c_long,
) -> *mut ASN1_TYPE;
}
const_ptr_api! {
extern "C" {
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: #[const_ptr_if(any(ossl110, libressl280))] ASN1_STRING) -> c_int;
pub fn ASN1_STRING_type(x: #[const_ptr_if(any(ossl110, libressl280))] ASN1_STRING) -> c_int;
pub fn ASN1_generate_v3(str: #[const_ptr_if(any(ossl110, libressl280))] c_char, cnf: *mut X509V3_CTX) -> *mut ASN1_TYPE;
pub fn i2d_ASN1_TYPE(a: #[const_ptr_if(ossl300)] ASN1_TYPE, pp: *mut *mut c_uchar) -> c_int;
}
}
+1
View File
@@ -58,6 +58,7 @@ const_ptr_api! {
}
extern "C" {
#[cfg(not(osslconf = "OPENSSL_NO_SOCK"))]
pub fn BIO_new_socket(sock: c_int, close_flag: c_int) -> *mut BIO;
#[cfg(any(ossl110, libressl273))]
+10 -1
View File
@@ -23,7 +23,7 @@ extern "C" {
pub fn BN_clear_free(bn: *mut BIGNUM);
pub fn BN_bin2bn(s: *const u8, size: c_int, ret: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_bn2bin(a: *const BIGNUM, to: *mut u8) -> c_int;
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl340))]
pub fn BN_bn2binpad(a: *const BIGNUM, to: *mut u8, tolen: c_int) -> c_int;
pub fn BN_sub(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;
pub fn BN_add(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;
@@ -32,6 +32,8 @@ extern "C" {
pub fn BN_set_negative(bn: *mut BIGNUM, n: c_int);
#[cfg(any(ossl110, libressl350))]
pub fn BN_is_negative(b: *const BIGNUM) -> c_int;
#[cfg(any(ossl110, libressl350))]
pub fn BN_is_odd(b: *const BIGNUM) -> c_int;
pub fn BN_div(
dv: *mut BIGNUM,
@@ -73,6 +75,13 @@ extern "C" {
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
#[cfg(ossl110)]
pub fn BN_mod_sqrt(
ret: *mut BIGNUM,
a: *const BIGNUM,
p: *const BIGNUM,
ctx: *mut BN_CTX,
) -> *mut BIGNUM;
pub fn BN_mod_word(r: *const BIGNUM, w: BN_ULONG) -> BN_ULONG;
pub fn BN_div_word(r: *mut BIGNUM, w: BN_ULONG) -> BN_ULONG;
+18
View File
@@ -0,0 +1,18 @@
use libc::*;
use super::super::*;
extern "C" {
pub fn CMAC_CTX_new() -> *mut CMAC_CTX;
pub fn CMAC_CTX_free(ctx: *mut CMAC_CTX);
pub fn CMAC_Init(
ctx: *mut CMAC_CTX,
key: *const c_void,
len: size_t,
cipher: *const EVP_CIPHER,
impl_: *mut ENGINE,
) -> c_int;
pub fn CMAC_Update(ctx: *mut CMAC_CTX, data: *const c_void, len: size_t) -> c_int;
pub fn CMAC_Final(ctx: *mut CMAC_CTX, out: *mut c_uchar, len: *mut size_t) -> c_int;
pub fn CMAC_CTX_copy(dst: *mut CMAC_CTX, src: *const CMAC_CTX) -> c_int;
}
+1
View File
@@ -3,6 +3,7 @@ use super::super::*;
extern "C" {
pub fn DH_new() -> *mut DH;
pub fn DH_free(dh: *mut DH);
pub fn DH_check(dh: *const DH, codes: *mut c_int) -> c_int;
pub fn DH_generate_parameters(
prime_len: c_int,
+17 -1
View File
@@ -46,6 +46,8 @@ extern "C" {
pub fn EC_GROUP_set_asn1_flag(key: *mut EC_GROUP, flag: c_int);
pub fn EC_GROUP_get_asn1_flag(group: *const EC_GROUP) -> c_int;
pub fn EC_GROUP_get_curve_GFp(
group: *const EC_GROUP,
p: *mut BIGNUM,
@@ -99,7 +101,7 @@ extern "C" {
pub fn EC_POINT_dup(p: *const EC_POINT, group: *const EC_GROUP) -> *mut EC_POINT;
#[cfg(ossl111)]
#[cfg(any(ossl111, boringssl, libressl350))]
pub fn EC_POINT_get_affine_coordinates(
group: *const EC_GROUP,
p: *const EC_POINT,
@@ -150,6 +152,20 @@ extern "C" {
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_point2hex(
group: *const EC_GROUP,
p: *const EC_POINT,
form: point_conversion_form_t,
ctx: *mut BN_CTX,
) -> *mut c_char;
pub fn EC_POINT_hex2point(
group: *const EC_GROUP,
s: *const c_char,
p: *mut EC_POINT,
ctx: *mut BN_CTX,
) -> *mut EC_POINT;
pub fn EC_POINT_add(
group: *const EC_GROUP,
r: *mut EC_POINT,
+39 -16
View File
@@ -65,6 +65,14 @@ cfg_if! {
}
}
cfg_if! {
if #[cfg(ossl300)] {
extern "C" {
pub fn EVP_default_properties_is_fips_enabled(libctx: *mut OSSL_LIB_CTX) -> c_int;
}
}
}
extern "C" {
pub fn EVP_DigestInit_ex(ctx: *mut EVP_MD_CTX, typ: *const EVP_MD, imple: *mut ENGINE)
-> c_int;
@@ -275,6 +283,7 @@ extern "C" {
ptr: *mut c_void,
) -> c_int;
pub fn EVP_CIPHER_CTX_rand_key(ctx: *mut EVP_CIPHER_CTX, key: *mut c_uchar) -> c_int;
pub fn EVP_CIPHER_CTX_set_flags(ctx: *mut EVP_CIPHER_CTX, flags: c_int);
pub fn EVP_md_null() -> *const EVP_MD;
pub fn EVP_md5() -> *const EVP_MD;
@@ -303,6 +312,7 @@ extern "C" {
pub fn EVP_des_ede3_cbc() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_cfb64() -> *const EVP_CIPHER;
pub fn EVP_des_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
pub fn EVP_rc4() -> *const EVP_CIPHER;
pub fn EVP_bf_ecb() -> *const EVP_CIPHER;
pub fn EVP_bf_cbc() -> *const EVP_CIPHER;
@@ -320,6 +330,10 @@ extern "C" {
pub fn EVP_aes_128_ofb() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_128_ocb() -> *const EVP_CIPHER;
#[cfg(ossl102)]
pub fn EVP_aes_128_wrap() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_128_wrap_pad() -> *const EVP_CIPHER;
pub fn EVP_aes_192_ecb() -> *const EVP_CIPHER;
pub fn EVP_aes_192_cbc() -> *const EVP_CIPHER;
pub fn EVP_aes_192_cfb1() -> *const EVP_CIPHER;
@@ -331,6 +345,10 @@ extern "C" {
pub fn EVP_aes_192_ofb() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_192_ocb() -> *const EVP_CIPHER;
#[cfg(ossl102)]
pub fn EVP_aes_192_wrap() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_192_wrap_pad() -> *const EVP_CIPHER;
pub fn EVP_aes_256_ecb() -> *const EVP_CIPHER;
pub fn EVP_aes_256_cbc() -> *const EVP_CIPHER;
pub fn EVP_aes_256_cfb1() -> *const EVP_CIPHER;
@@ -343,6 +361,10 @@ extern "C" {
pub fn EVP_aes_256_ofb() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_256_ocb() -> *const EVP_CIPHER;
#[cfg(ossl102)]
pub fn EVP_aes_256_wrap() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_256_wrap_pad() -> *const EVP_CIPHER;
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
pub fn EVP_chacha20() -> *const EVP_CIPHER;
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
@@ -404,22 +426,6 @@ cfg_if! {
pub fn EVP_PKEY_get_bits(key: *const EVP_PKEY) -> c_int;
pub fn EVP_PKEY_get_security_bits(key: *const EVP_PKEY) -> c_int;
}
#[inline]
pub unsafe fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int {
EVP_PKEY_get_id(pkey)
}
#[inline]
pub unsafe fn EVP_PKEY_bits(pkey: *const EVP_PKEY) -> c_int {
EVP_PKEY_get_bits(pkey)
}
#[inline]
pub unsafe fn EVP_PKEY_security_bits(pkey: *const EVP_PKEY) -> c_int {
EVP_PKEY_get_security_bits(pkey)
}
} else {
extern "C" {
pub fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int;
@@ -504,6 +510,9 @@ extern "C" {
p2: *mut c_void,
) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_CTX_set_signature_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD) -> c_int;
pub fn EVP_PKEY_new_mac_key(
type_: c_int,
e: *mut ENGINE,
@@ -513,6 +522,12 @@ extern "C" {
pub fn EVP_PKEY_derive_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
pub fn EVP_PKEY_derive_set_peer(ctx: *mut EVP_PKEY_CTX, peer: *mut EVP_PKEY) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_derive_set_peer_ex(
ctx: *mut EVP_PKEY_CTX,
peer: *mut EVP_PKEY,
validate_peer: c_int,
) -> c_int;
pub fn EVP_PKEY_derive(ctx: *mut EVP_PKEY_CTX, key: *mut c_uchar, size: *mut size_t) -> c_int;
#[cfg(ossl300)]
@@ -557,6 +572,14 @@ extern "C" {
pin: *const c_uchar,
pinlen: size_t,
) -> c_int;
pub fn EVP_PKEY_verify_recover_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
pub fn EVP_PKEY_verify_recover(
ctx: *mut EVP_PKEY_CTX,
rout: *mut c_uchar,
routlen: *mut size_t,
sig: *const c_uchar,
siglen: size_t,
) -> c_int;
}
const_ptr_api! {
+6
View File
@@ -2,6 +2,7 @@ pub use self::aes::*;
pub use self::asn1::*;
pub use self::bio::*;
pub use self::bn::*;
pub use self::cmac::*;
pub use self::cms::*;
pub use self::conf::*;
pub use self::crypto::*;
@@ -17,6 +18,8 @@ pub use self::ocsp::*;
pub use self::pem::*;
pub use self::pkcs12::*;
pub use self::pkcs7::*;
#[cfg(libressl)]
pub use self::poly1305::*;
pub use self::provider::*;
pub use self::rand::*;
pub use self::rsa::*;
@@ -35,6 +38,7 @@ mod aes;
mod asn1;
mod bio;
mod bn;
mod cmac;
mod cms;
mod conf;
mod crypto;
@@ -50,6 +54,8 @@ mod ocsp;
mod pem;
mod pkcs12;
mod pkcs7;
#[cfg(libressl)]
mod poly1305;
mod provider;
mod rand;
mod rsa;
+1
View File
@@ -27,4 +27,5 @@ extern "C" {
pub fn OBJ_length(obj: *const ASN1_OBJECT) -> libc::size_t;
#[cfg(ossl111)]
pub fn OBJ_get0_data(obj: *const ASN1_OBJECT) -> *const c_uchar;
pub fn OBJ_cmp(a: *const ASN1_OBJECT, b: *const ASN1_OBJECT) -> c_int;
}
+193 -6
View File
@@ -1,12 +1,149 @@
use super::super::*;
use libc::*;
pub enum PKCS7_SIGNED {}
pub enum PKCS7_ENVELOPE {}
pub enum PKCS7_SIGN_ENVELOPE {}
pub enum PKCS7_DIGEST {}
pub enum PKCS7_ENCRYPT {}
pub enum PKCS7 {}
#[cfg(ossl300)]
#[repr(C)]
pub struct PKCS7_CTX {
libctx: *mut OSSL_LIB_CTX,
propq: *mut c_char,
}
#[repr(C)]
pub struct PKCS7_SIGNED {
pub version: *mut ASN1_INTEGER, /* version 1 */
pub md_algs: *mut stack_st_X509_ALGOR, /* md used */
pub cert: *mut stack_st_X509, /* [ 0 ] */
pub crl: *mut stack_st_X509_CRL, /* [ 1 ] */
pub signer_info: *mut stack_st_PKCS7_SIGNER_INFO,
pub contents: *mut PKCS7,
}
#[repr(C)]
pub struct PKCS7_ENC_CONTENT {
pub content_type: *mut ASN1_OBJECT,
pub algorithm: *mut X509_ALGOR,
pub enc_data: *mut ASN1_OCTET_STRING, /* [ 0 ] */
pub cipher: *const EVP_CIPHER,
#[cfg(ossl300)]
pub ctx: *const PKCS7_CTX,
}
#[repr(C)]
pub struct PKCS7_ENVELOPE {
pub version: *mut ASN1_INTEGER, /* version 0 */
pub recipientinfo: *mut stack_st_PKCS7_RECIP_INFO,
pub enc_data: *mut PKCS7_ENC_CONTENT,
}
#[repr(C)]
pub struct PKCS7_SIGN_ENVELOPE {
pub version: *mut ASN1_INTEGER, /* version 1 */
pub md_algs: *mut stack_st_X509_ALGOR, /* md used */
pub cert: *mut stack_st_X509, /* [ 0 ] */
pub crl: *mut stack_st_X509_CRL, /* [ 1 ] */
pub signer_info: *mut stack_st_PKCS7_SIGNER_INFO,
pub enc_data: *mut PKCS7_ENC_CONTENT,
pub recipientinfo: *mut stack_st_PKCS7_RECIP_INFO,
}
#[repr(C)]
pub struct PKCS7_DIGEST {
pub version: *mut ASN1_INTEGER, /* version 0 */
pub md: *mut X509_ALGOR, /* md used */
pub contents: *mut PKCS7,
pub digest: *mut ASN1_OCTET_STRING,
}
#[repr(C)]
pub struct PKCS7_ENCRYPT {
pub version: *mut ASN1_INTEGER, /* version 0 */
pub enc_data: *mut PKCS7_ENC_CONTENT,
}
extern "C" {
pub fn PKCS7_SIGNED_free(info: *mut PKCS7_SIGNED);
pub fn PKCS7_ENC_CONTENT_free(info: *mut PKCS7_ENC_CONTENT);
pub fn PKCS7_ENVELOPE_free(info: *mut PKCS7_ENVELOPE);
pub fn PKCS7_SIGN_ENVELOPE_free(info: *mut PKCS7_SIGN_ENVELOPE);
pub fn PKCS7_DIGEST_free(info: *mut PKCS7_DIGEST);
pub fn PKCS7_SIGNER_INFO_free(info: *mut PKCS7_SIGNER_INFO);
pub fn PKCS7_ENCRYPT_free(enc: *mut PKCS7_ENCRYPT);
pub fn PKCS7_ISSUER_AND_SERIAL_free(ias: *mut PKCS7_ISSUER_AND_SERIAL);
pub fn PKCS7_RECIP_INFO_free(info: *mut PKCS7_RECIP_INFO);
}
#[repr(C)]
pub struct PKCS7 {
/*
* The following is non NULL if it contains ASN1 encoding of this
* structure
*/
pub asn1: *mut c_uchar,
pub length: c_long,
// # define PKCS7_S_HEADER 0
// # define PKCS7_S_BODY 1
// # define PKCS7_S_TAIL 2
pub state: c_int, /* used during processing */
pub detached: c_int,
pub type_: *mut ASN1_OBJECT,
/* content as defined by the type */
/*
* all encryption/message digests are applied to the 'contents', leaving
* out the 'type' field.
*/
pub d: PKCS7_data,
#[cfg(ossl300)]
pub ctx: PKCS7_CTX,
}
#[repr(C)]
pub union PKCS7_data {
pub ptr: *mut c_char,
/* NID_pkcs7_data */
pub data: *mut ASN1_OCTET_STRING,
/* NID_pkcs7_signed */
pub sign: *mut PKCS7_SIGNED,
/* NID_pkcs7_enveloped */
pub enveloped: *mut PKCS7_ENVELOPE,
/* NID_pkcs7_signedAndEnveloped */
pub signed_and_enveloped: *mut PKCS7_SIGN_ENVELOPE,
/* NID_pkcs7_digest */
pub digest: *mut PKCS7_DIGEST,
/* NID_pkcs7_encrypted */
pub encrypted: *mut PKCS7_ENCRYPT,
/* Anything else */
pub other: *mut ASN1_TYPE,
}
#[repr(C)]
pub struct PKCS7_ISSUER_AND_SERIAL {
pub issuer: *mut X509_NAME,
pub serial: *mut ASN1_INTEGER,
}
#[repr(C)]
pub struct PKCS7_SIGNER_INFO {
pub version: *mut ASN1_INTEGER, /* version 1 */
pub issuer_and_serial: *mut PKCS7_ISSUER_AND_SERIAL,
pub digest_alg: *mut X509_ALGOR,
pub auth_attr: *mut stack_st_X509_ATTRIBUTE, /* [ 0 ] */
pub digest_enc_alg: *mut X509_ALGOR,
pub enc_digest: *mut ASN1_OCTET_STRING,
pub unauth_attr: *mut stack_st_X509_ATTRIBUTE, /* [ 1 ] */
pub pkey: *mut EVP_PKEY, /* The private key to sign with */
#[cfg(ossl300)]
pub ctx: *const PKCS7_CTX,
}
stack!(stack_st_PKCS7_SIGNER_INFO);
#[repr(C)]
pub struct PKCS7_RECIP_INFO {
pub version: *mut ASN1_INTEGER, /* version 0 */
pub issuer_and_serial: *mut PKCS7_ISSUER_AND_SERIAL,
pub key_enc_algor: *mut X509_ALGOR,
pub enc_key: *mut ASN1_OCTET_STRING,
pub cert: *mut X509, /* get the pub-key from this */
#[cfg(ossl300)]
pub ctx: *const PKCS7_CTX,
}
stack!(stack_st_PKCS7_RECIP_INFO);
extern "C" {
pub fn d2i_PKCS7(a: *mut *mut PKCS7, pp: *mut *const c_uchar, length: c_long) -> *mut PKCS7;
@@ -15,6 +152,7 @@ extern "C" {
const_ptr_api! {
extern "C" {
pub fn i2d_PKCS7(a: #[const_ptr_if(ossl300)] PKCS7, buf: *mut *mut u8) -> c_int;
pub fn i2d_PKCS7_bio(bio: *mut BIO, p7: #[const_ptr_if(ossl300)] PKCS7) -> c_int;
}
}
@@ -67,4 +205,53 @@ extern "C" {
) -> c_int;
pub fn SMIME_read_PKCS7(bio: *mut BIO, bcont: *mut *mut BIO) -> *mut PKCS7;
pub fn PKCS7_new() -> *mut PKCS7;
pub fn PKCS7_set_type(p7: *mut PKCS7, nid_pkcs7: c_int) -> c_int;
pub fn PKCS7_add_certificate(p7: *mut PKCS7, x509: *mut X509) -> c_int;
pub fn PKCS7_add_signature(
p7: *mut PKCS7,
x509: *mut X509,
pkey: *mut EVP_PKEY,
digest: *const EVP_MD,
) -> *mut PKCS7_SIGNER_INFO;
pub fn PKCS7_set_signed_attributes(
p7si: *mut PKCS7_SIGNER_INFO,
attributes: *mut stack_st_X509_ATTRIBUTE,
) -> c_int;
pub fn PKCS7_add_signed_attribute(
p7si: *mut PKCS7_SIGNER_INFO,
nid: c_int,
attrtype: c_int,
data: *mut c_void,
) -> c_int;
pub fn PKCS7_content_new(p7: *mut PKCS7, nid_pkcs7: c_int) -> c_int;
pub fn PKCS7_dataInit(p7: *mut PKCS7, bio: *mut BIO) -> *mut BIO;
pub fn PKCS7_dataFinal(p7: *mut PKCS7, bio: *mut BIO) -> c_int;
pub fn PKCS7_get_signer_info(p7: *mut PKCS7) -> *mut stack_st_PKCS7_SIGNER_INFO;
pub fn PKCS7_SIGNER_INFO_get0_algs(
si: *mut PKCS7_SIGNER_INFO,
pk: *mut *mut EVP_PKEY,
pdig: *mut *mut X509_ALGOR,
psig: *mut *mut X509_ALGOR,
);
}
const_ptr_api! {
extern "C" {
pub fn PKCS7_get_signed_attribute(
si: #[const_ptr_if(ossl300)] PKCS7_SIGNER_INFO,
nid: c_int
) -> *mut ASN1_TYPE;
}
}
+23
View File
@@ -0,0 +1,23 @@
use super::super::*;
use libc::*;
cfg_if! {
if #[cfg(libressl)] {
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct poly1305_context {
pub aligner: usize,
pub opaque: [::libc::c_uchar; 136usize],
}
pub type poly1305_state = poly1305_context;
extern "C" {
pub fn CRYPTO_poly1305_init(ctx: *mut poly1305_context, key: *const ::libc::c_uchar);
pub fn CRYPTO_poly1305_update(
ctx: *mut poly1305_context,
in_: *const ::libc::c_uchar,
len: usize,
);
pub fn CRYPTO_poly1305_finish(ctx: *mut poly1305_context, mac: *mut ::libc::c_uchar);
}
}
}
+15 -2
View File
@@ -648,6 +648,15 @@ extern "C" {
num: size_t,
readbytes: *mut size_t,
) -> c_int;
#[cfg(ossl111)]
pub fn SSL_bytes_to_cipher_list(
s: *mut SSL,
bytes: *const c_uchar,
len: size_t,
isv2format: c_int,
sk: *mut *mut stack_st_SSL_CIPHER,
scsvs: *mut *mut stack_st_SSL_CIPHER,
) -> c_int;
}
extern "C" {
@@ -905,9 +914,13 @@ extern "C" {
#[cfg(ossl111)]
pub fn SSL_set_num_tickets(s: *mut SSL, num_tickets: size_t) -> c_int;
#[cfg(ossl111)]
#[cfg(ossl111b)]
pub fn SSL_CTX_get_num_tickets(ctx: *const SSL_CTX) -> size_t;
#[cfg(all(ossl111, not(ossl111b)))]
pub fn SSL_CTX_get_num_tickets(ctx: *mut SSL_CTX) -> size_t;
#[cfg(ossl111)]
#[cfg(ossl111b)]
pub fn SSL_get_num_tickets(s: *const SSL) -> size_t;
#[cfg(all(ossl111, not(ossl111b)))]
pub fn SSL_get_num_tickets(s: *mut SSL) -> size_t;
}
+19 -2
View File
@@ -3,14 +3,27 @@ use libc::*;
#[allow(unused_imports)]
use super::super::*;
pub enum ASN1_OBJECT {}
pub enum ASN1_VALUE {}
pub type ASN1_BOOLEAN = c_int;
pub enum ASN1_INTEGER {}
pub enum ASN1_ENUMERATED {}
pub enum ASN1_GENERALIZEDTIME {}
pub enum ASN1_STRING {}
pub enum ASN1_BIT_STRING {}
pub enum ASN1_TIME {}
pub enum ASN1_TYPE {}
pub enum ASN1_OBJECT {}
pub enum ASN1_OCTET_STRING {}
pub enum ASN1_NULL {}
pub enum ASN1_PRINTABLESTRING {}
pub enum ASN1_T61STRING {}
pub enum ASN1_IA5STRING {}
pub enum ASN1_GENERALSTRING {}
pub enum ASN1_BMPSTRING {}
pub enum ASN1_UNIVERSALSTRING {}
pub enum ASN1_UTCTIME {}
pub enum ASN1_VISIBLESTRING {}
pub enum ASN1_UTF8STRING {}
pub enum bio_st {} // FIXME remove
cfg_if! {
@@ -112,6 +125,8 @@ pub enum EVP_PKEY_ASN1_METHOD {}
pub enum EVP_PKEY_CTX {}
pub enum CMAC_CTX {}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum HMAC_CTX {}
@@ -325,6 +340,8 @@ cfg_if! {
}
}
stack!(stack_st_X509_ALGOR);
pub enum X509_LOOKUP_METHOD {}
pub enum X509_NAME {}
+96 -4
View File
@@ -9,12 +9,16 @@ pub struct X509_VAL {
pub enum X509_NAME_ENTRY {}
stack!(stack_st_X509_NAME_ENTRY);
stack!(stack_st_X509_NAME);
pub enum X509_EXTENSION {}
stack!(stack_st_X509_EXTENSION);
pub enum X509_ATTRIBUTE {}
stack!(stack_st_X509_ATTRIBUTE);
cfg_if! {
@@ -274,6 +278,7 @@ extern "C" {
pub fn X509_NAME_ENTRY_free(x: *mut X509_NAME_ENTRY);
pub fn X509_NAME_new() -> *mut X509_NAME;
pub fn X509_NAME_cmp(x: *const X509_NAME, y: *const X509_NAME) -> c_int;
pub fn X509_NAME_free(x: *mut X509_NAME);
pub fn X509_new() -> *mut X509;
@@ -359,6 +364,33 @@ const_ptr_api! {
-> c_int;
}
}
extern "C" {
pub fn X509_REQ_get_attr_count(req: *const X509_REQ) -> c_int;
pub fn X509_REQ_get_attr_by_NID(req: *const X509_REQ, nid: c_int, lastpos: c_int) -> c_int;
pub fn X509_REQ_get_attr(req: *const X509_REQ, loc: c_int) -> *mut X509_ATTRIBUTE;
pub fn X509_REQ_delete_attr(req: *mut X509_REQ, loc: c_int) -> *mut X509_ATTRIBUTE;
pub fn X509_REQ_add1_attr_by_txt(
req: *mut X509_REQ,
attrname: *const c_char,
chtype: c_int,
bytes: *const c_uchar,
len: c_int,
) -> c_int;
pub fn X509_REQ_add1_attr_by_NID(
req: *mut X509_REQ,
nid: c_int,
chtype: c_int,
bytes: *const c_uchar,
len: c_int,
) -> c_int;
pub fn X509_REQ_add1_attr_by_OBJ(
req: *mut X509_REQ,
obj: *const ASN1_OBJECT,
chtype: c_int,
bytes: *const c_uchar,
len: c_int,
) -> c_int;
}
extern "C" {
pub fn X509_set_pubkey(x: *mut X509, pkey: *mut EVP_PKEY) -> c_int;
pub fn X509_REQ_verify(req: *mut X509_REQ, pkey: *mut EVP_PKEY) -> c_int;
@@ -612,10 +644,9 @@ const_ptr_api! {
extern "C" {
#[cfg(any(ossl110, libressl270))]
pub fn X509_STORE_get0_objects(ctx: #[const_ptr_if(ossl300)] X509_STORE) -> *mut stack_st_X509_OBJECT;
#[cfg(ossl300)]
pub fn X509_STORE_get1_all_certs(ctx: *mut X509_STORE) -> *mut stack_st_X509;
}
}
#[cfg(any(ossl110, libressl270))]
extern "C" {
pub fn X509_OBJECT_get0_X509(x: *const X509_OBJECT) -> *mut X509;
@@ -642,7 +673,6 @@ extern "C" {
extern "C" {
pub fn X509_cmp(a: *const X509, b: *const X509) -> c_int;
pub fn X509_NAME_cmp(a: *const X509_NAME, b: *const X509_NAME) -> c_int;
pub fn X509_issuer_and_serial_cmp(a: *const X509, b: *const X509) -> c_int;
pub fn X509_issuer_name_cmp(a: *const X509, b: *const X509) -> c_int;
pub fn X509_subject_name_cmp(a: *const X509, b: *const X509) -> c_int;
@@ -670,6 +700,68 @@ pub struct X509_PURPOSE {
const_ptr_api! {
extern "C" {
pub fn X509_PURPOSE_get_by_sname(sname: #[const_ptr_if(any(ossl110, libressl280))] c_char) -> c_int;
pub fn X509_PURPOSE_get0(idx: c_int) -> *mut X509_PURPOSE;
}
}
extern "C" {
pub fn X509_PURPOSE_get0(idx: c_int) -> *mut X509_PURPOSE;
}
extern "C" {
pub fn X509_ATTRIBUTE_new() -> *mut X509_ATTRIBUTE;
pub fn X509_ATTRIBUTE_free(attr: *mut X509_ATTRIBUTE);
pub fn X509_ATTRIBUTE_create(
nid: c_int,
atrtype: c_int,
value: *mut c_void,
) -> *mut X509_ATTRIBUTE;
pub fn X509_ATTRIBUTE_create_by_NID(
attr: *mut *mut X509_ATTRIBUTE,
nid: c_int,
atrtype: c_int,
data: *const c_void,
len: c_int,
) -> *mut X509_ATTRIBUTE;
pub fn X509_ATTRIBUTE_create_by_OBJ(
attr: *mut *mut X509_ATTRIBUTE,
obj: *const ASN1_OBJECT,
atrtype: c_int,
data: *const c_void,
len: c_int,
) -> *mut X509_ATTRIBUTE;
pub fn X509_ATTRIBUTE_create_by_txt(
attr: *mut *mut X509_ATTRIBUTE,
atrname: *const c_char,
atrtype: c_int,
bytes: *const c_uchar,
len: c_int,
) -> *mut X509_ATTRIBUTE;
pub fn X509_ATTRIBUTE_set1_object(attr: *mut X509_ATTRIBUTE, obj: *const ASN1_OBJECT) -> c_int;
pub fn X509_ATTRIBUTE_set1_data(
attr: *mut X509_ATTRIBUTE,
attrtype: c_int,
data: *const c_void,
len: c_int,
) -> c_int;
pub fn X509_ATTRIBUTE_get0_data(
attr: *mut X509_ATTRIBUTE,
idx: c_int,
atrtype: c_int,
data: *mut c_void,
) -> *mut c_void;
pub fn X509_ATTRIBUTE_get0_object(attr: *mut X509_ATTRIBUTE) -> *mut ASN1_OBJECT;
pub fn X509_ATTRIBUTE_get0_type(attr: *mut X509_ATTRIBUTE, idx: c_int) -> *mut ASN1_TYPE;
pub fn d2i_X509_ATTRIBUTE(
a: *mut *mut X509_ATTRIBUTE,
pp: *mut *const c_uchar,
length: c_long,
) -> *mut X509_ATTRIBUTE;
}
const_ptr_api! {
extern "C" {
pub fn X509_ATTRIBUTE_count(
attr: #[const_ptr_if(any(ossl110, libressl280))] X509_ATTRIBUTE // const since OpenSSL v1.1.0
) -> c_int;
pub fn i2d_X509_ATTRIBUTE(x: #[const_ptr_if(ossl300)] X509_ATTRIBUTE, buf: *mut *mut u8) -> c_int;
pub fn X509_ATTRIBUTE_dup(x: #[const_ptr_if(ossl300)] X509_ATTRIBUTE) -> *mut X509_ATTRIBUTE;
}
}
+42
View File
@@ -6,6 +6,11 @@ pub enum CONF_METHOD {}
extern "C" {
pub fn GENERAL_NAME_new() -> *mut GENERAL_NAME;
pub fn GENERAL_NAME_free(name: *mut GENERAL_NAME);
pub fn GENERAL_NAME_set0_othername(
gen: *mut GENERAL_NAME,
oid: *mut ASN1_OBJECT,
value: *mut ASN1_TYPE,
) -> c_int;
}
#[repr(C)]
@@ -96,10 +101,47 @@ extern "C" {
indent: c_int,
) -> c_int;
#[cfg(ossl110)]
pub fn X509_get_pathlen(x: *mut X509) -> c_long;
#[cfg(ossl110)]
pub fn X509_get_extension_flags(x: *mut X509) -> u32;
#[cfg(ossl110)]
pub fn X509_get_key_usage(x: *mut X509) -> u32;
#[cfg(ossl110)]
pub fn X509_get_extended_key_usage(x: *mut X509) -> u32;
#[cfg(ossl110)]
pub fn X509_get0_subject_key_id(x: *mut X509) -> *const ASN1_OCTET_STRING;
#[cfg(ossl110)]
pub fn X509_get0_authority_key_id(x: *mut X509) -> *const ASN1_OCTET_STRING;
#[cfg(ossl111d)]
pub fn X509_get0_authority_issuer(x: *mut X509) -> *const stack_st_GENERAL_NAME;
#[cfg(ossl111d)]
pub fn X509_get0_authority_serial(x: *mut X509) -> *const ASN1_INTEGER;
}
#[repr(C)]
pub struct DIST_POINT_NAME {
pub type_: c_int,
pub name: DIST_POINT_NAME_st_anon_union,
pub dpname: *mut X509_NAME,
}
#[repr(C)]
pub union DIST_POINT_NAME_st_anon_union {
pub fullname: *mut stack_st_GENERAL_NAME,
pub relativename: *mut stack_st_X509_NAME_ENTRY,
}
#[repr(C)]
pub struct DIST_POINT {
pub distpoint: *mut DIST_POINT_NAME,
pub reasons: *mut ASN1_BIT_STRING,
pub CRLissuer: *mut stack_st_GENERAL_NAME,
pub dp_reasons: c_int,
}
stack!(stack_st_DIST_POINT);
extern "C" {
pub fn DIST_POINT_free(dist_point: *mut DIST_POINT);
pub fn DIST_POINT_NAME_free(dist_point: *mut DIST_POINT_NAME);
}
+1 -4
View File
@@ -1,15 +1,12 @@
#![allow(
clippy::missing_safety_doc,
clippy::unreadable_literal,
clippy::uninlined_format_args,
clippy::upper_case_acronyms,
dead_code,
non_camel_case_types,
non_snake_case,
non_upper_case_globals,
overflowing_literals,
unused_imports
)]
#![cfg_attr(feature = "unstable_boringssl", allow(ambiguous_glob_reexports))]
#![doc(html_root_url = "https://docs.rs/openssl-sys/0.9")]
#![recursion_limit = "128"] // configure fixed limit across all rust versions
-18
View File
@@ -70,24 +70,6 @@ macro_rules! stack {
};
}
#[cfg(const_fn)]
macro_rules! const_fn {
($(pub const fn $name:ident($($arg:ident: $t:ty),*) -> $ret:ty $b:block)*) => {
$(
pub const fn $name($($arg: $t),*) -> $ret $b
)*
}
}
#[cfg(not(const_fn))]
macro_rules! const_fn {
($(pub const fn $name:ident($($arg:ident: $t:ty),*) -> $ret:ty $b:block)*) => {
$(
pub fn $name($($arg: $t),*) -> $ret $b
)*
}
}
// openssl changes `*mut` to `*const` in certain parameters in certain versions;
// in C this is ABI and (mostly) API compatible.
//
+4
View File
@@ -927,12 +927,16 @@ pub const NID_X448: c_int = 1035;
#[cfg(ossl110)]
pub const NID_hkdf: c_int = 1036;
#[cfg(ossl111)]
pub const NID_poly1305: c_int = 1061;
#[cfg(ossl111)]
pub const NID_ED25519: c_int = 1087;
#[cfg(libressl370)]
pub const NID_ED25519: c_int = 952;
#[cfg(ossl111)]
pub const NID_ED448: c_int = 1088;
#[cfg(ossl111)]
pub const NID_sm2: c_int = 1172;
#[cfg(ossl111)]
pub const NID_sm3: c_int = 1143;
#[cfg(libressl291)]
pub const NID_sm3: c_int = 968;
+4
View File
@@ -10,6 +10,10 @@ pub const TLS1_2_VERSION: c_int = 0x303;
#[cfg(any(ossl111, libressl340))]
pub const TLS1_3_VERSION: c_int = 0x304;
pub const DTLS1_VERSION: c_int = 0xFEFF;
#[cfg(any(ossl102, libressl332))]
pub const DTLS1_2_VERSION: c_int = 0xFEFD;
pub const TLS1_AD_DECODE_ERROR: c_int = 50;
pub const TLS1_AD_UNRECOGNIZED_NAME: c_int = 112;
+11
View File
@@ -91,3 +91,14 @@ pub const X509_PURPOSE_OCSP_HELPER: c_int = 8;
pub const X509_PURPOSE_TIMESTAMP_SIGN: c_int = 9;
pub const X509_PURPOSE_MIN: c_int = 1;
pub const X509_PURPOSE_MAX: c_int = 9;
pub const CRL_REASON_UNSPECIFIED: c_int = 0;
pub const CRL_REASON_KEY_COMPROMISE: c_int = 1;
pub const CRL_REASON_CA_COMPROMISE: c_int = 2;
pub const CRL_REASON_AFFILIATION_CHANGED: c_int = 3;
pub const CRL_REASON_SUPERSEDED: c_int = 4;
pub const CRL_REASON_CESSATION_OF_OPERATION: c_int = 5;
pub const CRL_REASON_CERTIFICATE_HOLD: c_int = 6;
pub const CRL_REASON_REMOVE_FROM_CRL: c_int = 8;
pub const CRL_REASON_PRIVILEGE_WITHDRAWN: c_int = 9;
pub const CRL_REASON_AA_COMPROMISE: c_int = 10;
+1 -1
View File
@@ -20,7 +20,7 @@ ohos_cargo_crate("lib") {
sources = [ "src/lib.rs" ]
edition = "2018"
cargo_pkg_version = "0.10.47"
cargo_pkg_version = "0.10.56"
cargo_pkg_authors = "Steven Fackler <sfackler@gmail.com>"
cargo_pkg_name = "openssl"
cargo_pkg_description = "OpenSSL bindings"
+89 -1
View File
@@ -2,6 +2,86 @@
## [Unreleased]
## [v0.10.56] - 2023-08-06
## Added
* Added `BigNumRef::mod_sqrt`.
* Added `PkeyCtxRef::set_signature_md` and `PkeyCtxRef::set_rsa_pss_saltlen`.
* Added `PkeyCtxRef::verify_recover_init` and `PkeyCtxRef::verify_recover`.
* Added `BigNumRef::is_even` and `BigNumRef::is_odd`.
* Added `EcPointRef::to_hex_str` and `EcPoint::from_hex_str`.
* Added support for AES key wrap and wrap pad.
## [v0.10.55] - 2023-06-20
### Fixed
* Fixed compilation with the latest version of BoringSSL.
* Fixed compilation when OpenSSL is compiled with `OPENSSL_NO_OCB`.
* Fixed a segfault in `X509VerifyParamRef::set_host` when called with an empty string.
### Added
* Added `Deriver::set_peer_ex`.
* Added `EcGroupRef::asn1_flag`.
* Exposed `EcPointRef::affine_coordinates` on BoringSSL and LibreSSL.
* Added `Nid::SM2` and `Id::SM2`
## [v0.10.54] - 2023-05-31
### Fixed
* `PKey::private_key_to_pkcs8_passphrase` no longer panics if a `passphrase` contains a NUL byte.
## [v0.10.53] - 2023-05-30
### Added
* Added `Dsa::from_pqg`, `Dsa::generate_key`, and `Dsa::generate_params`.
* Added `SslRef::bytes_to_cipher_list`.
* Added `SubjectAlternativeName::other_name2`
## [v0.10.52] - 2023-04-24
### Added
* Added `DhRef::check_key`.
* Added `Id::POLY1305`.
* Added `X509Ref::subject_key_id`, `X509Ref::authority_key_id`, `X509Ref::authority_issuer`, and `X509Ref::authority_serial`.
## [v0.10.51] - 2023-04-20
### Added
* Added `X509RevokedRef::issuer_name` and `X509RevokedRef::reason_code`.
* Added `Dh::set_key` and `Dh::set_public_key`
* Added `Asn1OctetString` and `Asn1OctetStringRef1`
* Added `X509Extension::new_from_der`
### Deprecated
* Deprecated `X509Extension::new` and `X509Extension::new_nid` in favor of `X509Extension::new_from_der` and the `extensions` module.
* Deprecated `X509Extension::add_alias`, it is not required with `new_from_der` or the `extensions` module.
## [v0.10.50] - 2023-04-09
### Added
* Added `CipherCtxRef::cipher_update_inplace`.
## [v0.10.49] - 2023-04-01
### Fixed
* `SslConnector` no longer sets the SNI extension when connecting to an IP address.
### Added
* Implemented `Ord`, `PartialOrd`, `Eq`, and `PartialEq` for `Asn1Integer` and `Asn1IntegerRef`.
* Added `X509Ref::crl_distribution_points`, and `DistPoint`.
## [v0.10.48] - 2023-03-23
### Fixed
@@ -707,7 +787,15 @@
Look at the [release tags] for information about older releases.
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.48...master
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.56...master
[v0.10.56]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.55...openssl-v0.10.56
[v0.10.55]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.54...openssl-v0.10.55
[v0.10.54]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.53...openssl-v0.10.54
[v0.10.53]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.52...openssl-v0.10.53
[v0.10.52]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.51...openssl-v0.10.52
[v0.10.51]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.50...openssl-v0.10.51
[v0.10.50]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.49...openssl-v0.10.50
[v0.10.49]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.48...openssl-v0.10.49
[v0.10.48]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.47...openssl-v0.10.48
[v0.10.47]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.46...openssl-v0.10.47
[v0.10.46]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.45...openssl-v0.10.46
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "openssl"
version = "0.10.48"
version = "0.10.56"
authors = ["Steven Fackler <sfackler@gmail.com>"]
license = "Apache-2.0"
description = "OpenSSL bindings"
@@ -30,7 +30,7 @@ libc = "0.2"
once_cell = "1.5.2"
openssl-macros = { version = "0.1.0", path = "../openssl-macros" }
ffi = { package = "openssl-sys", version = "0.9.83", path = "../openssl-sys" }
ffi = { package = "openssl-sys", version = "0.9.91", path = "../openssl-sys" }
[dev-dependencies]
hex = "0.3"
+139 -2
View File
@@ -27,8 +27,8 @@
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_char, c_int, c_long, time_t};
#[cfg(ossl102)]
use std::cmp::Ordering;
use std::convert::TryInto;
use std::ffi::CString;
use std::fmt;
use std::ptr;
@@ -512,6 +512,23 @@ impl Asn1Integer {
}
}
impl Ord for Asn1Integer {
fn cmp(&self, other: &Self) -> Ordering {
Asn1IntegerRef::cmp(self, other)
}
}
impl PartialOrd for Asn1Integer {
fn partial_cmp(&self, other: &Asn1Integer) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Eq for Asn1Integer {}
impl PartialEq for Asn1Integer {
fn eq(&self, other: &Asn1Integer) -> bool {
Asn1IntegerRef::eq(self, other)
}
}
impl Asn1IntegerRef {
#[allow(missing_docs, clippy::unnecessary_cast)]
#[deprecated(since = "0.10.6", note = "use to_bn instead")]
@@ -536,6 +553,30 @@ impl Asn1IntegerRef {
pub fn set(&mut self, value: i32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::ASN1_INTEGER_set(self.as_ptr(), value as c_long)).map(|_| ()) }
}
/// Creates a new Asn1Integer with the same value.
#[corresponds(ASN1_INTEGER_dup)]
pub fn to_owned(&self) -> Result<Asn1Integer, ErrorStack> {
unsafe { cvt_p(ffi::ASN1_INTEGER_dup(self.as_ptr())).map(|p| Asn1Integer::from_ptr(p)) }
}
}
impl Ord for Asn1IntegerRef {
fn cmp(&self, other: &Self) -> Ordering {
let res = unsafe { ffi::ASN1_INTEGER_cmp(self.as_ptr(), other.as_ptr()) };
res.cmp(&0)
}
}
impl PartialOrd for Asn1IntegerRef {
fn partial_cmp(&self, other: &Asn1IntegerRef) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Eq for Asn1IntegerRef {}
impl PartialEq for Asn1IntegerRef {
fn eq(&self, other: &Asn1IntegerRef) -> bool {
self.cmp(other) == Ordering::Equal
}
}
foreign_type_and_impl_send_sync! {
@@ -571,9 +612,50 @@ impl Asn1BitStringRef {
}
}
foreign_type_and_impl_send_sync! {
type CType = ffi::ASN1_OCTET_STRING;
fn drop = ffi::ASN1_OCTET_STRING_free;
/// ASN.1 OCTET STRING type
pub struct Asn1OctetString;
/// A reference to an [`Asn1OctetString`].
pub struct Asn1OctetStringRef;
}
impl Asn1OctetString {
/// Creates an Asn1OctetString from bytes
pub fn new_from_bytes(value: &[u8]) -> Result<Self, ErrorStack> {
ffi::init();
unsafe {
let s = cvt_p(ffi::ASN1_OCTET_STRING_new())?;
ffi::ASN1_OCTET_STRING_set(s, value.as_ptr(), value.len().try_into().unwrap());
Ok(Self::from_ptr(s))
}
}
}
impl Asn1OctetStringRef {
/// Returns the octet string as an array of bytes.
#[corresponds(ASN1_STRING_get0_data)]
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr().cast()), self.len()) }
}
/// Returns the number of bytes in the octet string.
#[corresponds(ASN1_STRING_length)]
pub fn len(&self) -> usize {
unsafe { ffi::ASN1_STRING_length(self.as_ptr().cast()) as usize }
}
/// Determines if the string is empty.
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
foreign_type_and_impl_send_sync! {
type CType = ffi::ASN1_OBJECT;
fn drop = ffi::ASN1_OBJECT_free;
fn clone = ffi::OBJ_dup;
/// Object Identifier
///
@@ -656,7 +738,7 @@ impl fmt::Debug for Asn1ObjectRef {
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
if #[cfg(any(ossl110, libressl273, boringssl))] {
use ffi::ASN1_STRING_get0_data;
} else {
#[allow(bad_style)]
@@ -666,6 +748,32 @@ cfg_if! {
}
}
foreign_type_and_impl_send_sync! {
type CType = ffi::ASN1_ENUMERATED;
fn drop = ffi::ASN1_ENUMERATED_free;
/// An ASN.1 enumerated.
pub struct Asn1Enumerated;
/// A reference to an [`Asn1Enumerated`].
pub struct Asn1EnumeratedRef;
}
impl Asn1EnumeratedRef {
/// Get the value, if it fits in the required bounds.
#[corresponds(ASN1_ENUMERATED_get_int64)]
#[cfg(ossl110)]
pub fn get_i64(&self) -> Result<i64, ErrorStack> {
let mut crl_reason = 0;
unsafe {
cvt(ffi::ASN1_ENUMERATED_get_int64(
&mut crl_reason,
self.as_ptr(),
))?;
}
Ok(crl_reason)
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -749,6 +857,28 @@ mod tests {
assert!(c_ref < a_ref);
}
#[test]
fn integer_to_owned() {
let a = Asn1Integer::from_bn(&BigNum::from_dec_str("42").unwrap()).unwrap();
let b = a.to_owned().unwrap();
assert_eq!(
a.to_bn().unwrap().to_dec_str().unwrap().to_string(),
b.to_bn().unwrap().to_dec_str().unwrap().to_string(),
);
assert_ne!(a.as_ptr(), b.as_ptr());
}
#[test]
fn integer_cmp() {
let a = Asn1Integer::from_bn(&BigNum::from_dec_str("42").unwrap()).unwrap();
let b = Asn1Integer::from_bn(&BigNum::from_dec_str("42").unwrap()).unwrap();
let c = Asn1Integer::from_bn(&BigNum::from_dec_str("43").unwrap()).unwrap();
assert!(a == b);
assert!(a != c);
assert!(a < c);
assert!(c > b);
}
#[test]
fn object_from_str() {
let object = Asn1Object::from_str("2.16.840.1.101.3.4.2.1").unwrap();
@@ -771,4 +901,11 @@ mod tests {
&[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01],
);
}
#[test]
fn asn1_octet_string() {
let octet_string = Asn1OctetString::new_from_bytes(b"hello world").unwrap();
assert_eq!(octet_string.as_slice(), b"hello world");
assert_eq!(octet_string.len(), 11);
}
}
+61 -1
View File
@@ -335,6 +335,20 @@ impl BigNumRef {
unsafe { BN_is_negative(self.as_ptr()) == 1 }
}
/// Returns `true` is `self` is even.
#[corresponds(BN_is_even)]
#[cfg(any(ossl110, boringssl, libressl350))]
pub fn is_even(&self) -> bool {
!self.is_odd()
}
/// Returns `true` is `self` is odd.
#[corresponds(BN_is_odd)]
#[cfg(any(ossl110, boringssl, libressl350))]
pub fn is_odd(&self) -> bool {
unsafe { ffi::BN_is_odd(self.as_ptr()) == 1 }
}
/// Returns the number of significant bits in `self`.
#[corresponds(BN_num_bits)]
#[allow(clippy::unnecessary_cast)]
@@ -639,6 +653,26 @@ impl BigNumRef {
}
}
/// Places into `self` the modular square root of `a` such that `self^2 = a (mod p)`
#[corresponds(BN_mod_sqrt)]
#[cfg(ossl110)]
pub fn mod_sqrt(
&mut self,
a: &BigNumRef,
p: &BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt_p(ffi::BN_mod_sqrt(
self.as_ptr(),
a.as_ptr(),
p.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
}
}
/// Places the result of `a^p` in `self`.
#[corresponds(BN_exp)]
pub fn exp(
@@ -814,7 +848,7 @@ impl BigNumRef {
/// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
/// ```
#[corresponds(BN_bn2binpad)]
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl340, boringssl))]
pub fn to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack> {
let mut v = Vec::with_capacity(pad_to as usize);
unsafe {
@@ -1455,4 +1489,30 @@ mod tests {
b.set_const_time();
assert!(b.is_const_time())
}
#[cfg(ossl110)]
#[test]
fn test_mod_sqrt() {
let mut ctx = BigNumContext::new().unwrap();
let s = BigNum::from_hex_str("47A8DD7626B9908C80ACD7E0D3344D69").unwrap();
let p = BigNum::from_hex_str("81EF47265B58BCE5").unwrap();
let mut out = BigNum::new().unwrap();
out.mod_sqrt(&s, &p, &mut ctx).unwrap();
assert_eq!(out, BigNum::from_hex_str("7C6D179E19B97BDD").unwrap());
}
#[test]
#[cfg(any(ossl110, boringssl, libressl350))]
fn test_odd_even() {
let a = BigNum::from_u32(17).unwrap();
let b = BigNum::from_u32(18).unwrap();
assert!(a.is_odd());
assert!(!b.is_odd());
assert!(!a.is_even());
assert!(b.is_even());
}
}
+54 -2
View File
@@ -12,6 +12,7 @@ use foreign_types::{ForeignTypeRef, Opaque};
use openssl_macros::corresponds;
#[cfg(ossl300)]
use std::ffi::CString;
use std::ops::{Deref, DerefMut};
#[cfg(ossl300)]
use std::ptr;
@@ -41,7 +42,6 @@ cfg_if! {
cfg_if! {
if #[cfg(ossl300)] {
use foreign_types::ForeignType;
use std::ops::{Deref, DerefMut};
type Inner = *mut ffi::EVP_CIPHER;
@@ -90,6 +90,22 @@ cfg_if! {
}
} else {
enum Inner {}
impl Deref for Cipher {
type Target = CipherRef;
#[inline]
fn deref(&self) -> &Self::Target {
match self.0 {}
}
}
impl DerefMut for Cipher {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
match self.0 {}
}
}
}
}
@@ -170,7 +186,6 @@ impl Cipher {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb8() as *mut _) }
}
#[cfg(not(boringssl))]
pub fn aes_128_gcm() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_gcm() as *mut _) }
}
@@ -191,6 +206,18 @@ impl Cipher {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ocb() as *mut _) }
}
/// Requires OpenSSL 1.0.2 or newer.
#[cfg(ossl102)]
pub fn aes_128_wrap() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap() as *mut _) }
}
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(ossl110)]
pub fn aes_128_wrap_pad() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap_pad() as *mut _) }
}
pub fn aes_192_ecb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ecb() as *mut _) }
}
@@ -236,6 +263,18 @@ impl Cipher {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ocb() as *mut _) }
}
/// Requires OpenSSL 1.0.2 or newer.
#[cfg(ossl102)]
pub fn aes_192_wrap() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap() as *mut _) }
}
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(ossl110)]
pub fn aes_192_wrap_pad() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap_pad() as *mut _) }
}
pub fn aes_256_ecb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ecb() as *mut _) }
}
@@ -281,6 +320,18 @@ impl Cipher {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ocb() as *mut _) }
}
/// Requires OpenSSL 1.0.2 or newer.
#[cfg(ossl102)]
pub fn aes_256_wrap() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap() as *mut _) }
}
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(ossl110)]
pub fn aes_256_wrap_pad() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap_pad() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_BF"))]
pub fn bf_cbc() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_bf_cbc() as *mut _) }
@@ -324,6 +375,7 @@ impl Cipher {
unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
pub fn rc4() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) }
}
+259 -4
View File
@@ -55,6 +55,8 @@ use crate::error::ErrorStack;
#[cfg(not(boringssl))]
use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef};
use crate::{cvt, cvt_p};
#[cfg(ossl102)]
use bitflags::bitflags;
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_int, c_uchar};
@@ -80,6 +82,15 @@ foreign_type_and_impl_send_sync! {
pub struct CipherCtxRef;
}
#[cfg(ossl102)]
bitflags! {
/// Flags for `EVP_CIPHER_CTX`.
pub struct CipherCtxFlags : c_int {
/// The flag used to opt into AES key wrap ciphers.
const FLAG_WRAP_ALLOW = ffi::EVP_CIPHER_CTX_FLAG_WRAP_ALLOW;
}
}
impl CipherCtx {
/// Creates a new context.
#[corresponds(EVP_CIPHER_CTX_new)]
@@ -509,6 +520,17 @@ impl CipherCtxRef {
Ok(())
}
/// Set ctx flags.
///
/// This function is currently used to enable AES key wrap feature supported by OpenSSL 1.0.2 or newer.
#[corresponds(EVP_CIPHER_CTX_set_flags)]
#[cfg(ossl102)]
pub fn set_flags(&mut self, flags: CipherCtxFlags) {
unsafe {
ffi::EVP_CIPHER_CTX_set_flags(self.as_ptr(), flags.bits());
}
}
/// Writes data into the context.
///
/// Providing no output buffer will cause the input to be considered additional authenticated data (AAD).
@@ -551,8 +573,7 @@ impl CipherCtxRef {
/// output size check removed. It can be used when the exact
/// buffer size control is maintained by the caller.
///
/// # Safety
/// The caller is expected to provide `output` buffer
/// SAFETY: The caller is expected to provide `output` buffer
/// large enough to contain correct number of bytes. For streaming
/// ciphers the output buffer size should be at least as big as
/// the input buffer. For block ciphers the size of the output
@@ -592,6 +613,50 @@ impl CipherCtxRef {
Ok(len)
}
/// Like [`Self::cipher_update`] except that it writes output into the
/// `data` buffer. The `inlen` parameter specifies the number of bytes in
/// `data` that are considered the input. For streaming ciphers, the size of
/// `data` must be at least the input size. Otherwise, it must be at least
/// an additional block size larger.
///
/// Note: Use [`Self::cipher_update`] with no output argument to write AAD.
///
/// # Panics
///
/// This function panics if the input size cannot be represented as `int` or
/// exceeds the buffer size, or if the output buffer does not contain enough
/// additional space.
#[corresponds(EVP_CipherUpdate)]
pub fn cipher_update_inplace(
&mut self,
data: &mut [u8],
inlen: usize,
) -> Result<usize, ErrorStack> {
assert!(inlen <= data.len(), "Input size may not exceed buffer size");
let block_size = self.block_size();
if block_size != 1 {
assert!(
data.len() >= inlen + block_size,
"Output buffer size must be at least {} bytes.",
inlen + block_size
);
}
let inlen = c_int::try_from(inlen).unwrap();
let mut outlen = 0;
unsafe {
cvt(ffi::EVP_CipherUpdate(
self.as_ptr(),
data.as_mut_ptr(),
&mut outlen,
data.as_ptr(),
inlen,
))
}?;
Ok(outlen as usize)
}
/// Finalizes the encryption or decryption process.
///
/// Any remaining data will be written to the output buffer.
@@ -620,8 +685,7 @@ impl CipherCtxRef {
/// This function is the same as [`Self::cipher_final`] but with
/// the output buffer size check removed.
///
/// # Safety
/// The caller is expected to provide `output` buffer
/// SAFETY: The caller is expected to provide `output` buffer
/// large enough to contain correct number of bytes. For streaming
/// ciphers the output buffer can be empty, for block ciphers the
/// output buffer should be at least as big as the block.
@@ -780,6 +844,26 @@ mod test {
ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
// encrypt again, but use in-place encryption this time
// First reset the IV
ctx.encrypt_init(None, None, Some(&iv)).unwrap();
ctx.set_padding(false);
let mut data_inplace: [u8; 32] = [1; 32];
let outlen = ctx
.cipher_update_inplace(&mut data_inplace[0..15], 15)
.unwrap();
assert_eq!(15, outlen);
let outlen = ctx
.cipher_update_inplace(&mut data_inplace[15..32], 17)
.unwrap();
assert_eq!(17, outlen);
ctx.cipher_final(&mut [0u8; 0]).unwrap();
// Check that the resulting data is encrypted in the same manner
assert_eq!(data_inplace.as_slice(), output.as_slice());
// try to decrypt
ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
.unwrap();
@@ -802,6 +886,19 @@ mod test {
ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
// check if the decrypted blocks are the same as input (all ones)
assert_eq!(output_decrypted, vec![1; 32]);
// decrypt again, but now the output in-place
ctx.decrypt_init(None, None, Some(&iv)).unwrap();
ctx.set_padding(false);
let outlen = ctx.cipher_update_inplace(&mut output[0..15], 15).unwrap();
assert_eq!(15, outlen);
let outlen = ctx.cipher_update_inplace(&mut output[15..], 17).unwrap();
assert_eq!(17, outlen);
ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
assert_eq!(output_decrypted, output);
}
#[test]
@@ -840,4 +937,162 @@ mod test {
ctx.cipher_update(&vec![0; block_size + 1], Some(&mut vec![0; block_size - 1]))
.unwrap();
}
#[cfg(ossl102)]
fn cipher_wrap_test(cipher: &CipherRef, pt: &str, ct: &str, key: &str, iv: Option<&str>) {
let pt = hex::decode(pt).unwrap();
let key = hex::decode(key).unwrap();
let expected = hex::decode(ct).unwrap();
let iv = iv.map(|v| hex::decode(v).unwrap());
let padding = 8 - pt.len() % 8;
let mut computed = vec![0; pt.len() + padding + cipher.block_size() * 2];
let mut ctx = CipherCtx::new().unwrap();
ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
ctx.encrypt_init(Some(cipher), Some(&key), iv.as_deref())
.unwrap();
let count = ctx.cipher_update(&pt, Some(&mut computed)).unwrap();
let rest = ctx.cipher_final(&mut computed[count..]).unwrap();
computed.truncate(count + rest);
if computed != expected {
println!("Computed: {}", hex::encode(&computed));
println!("Expected: {}", hex::encode(&expected));
if computed.len() != expected.len() {
println!(
"Lengths differ: {} in computed vs {} expected",
computed.len(),
expected.len()
);
}
panic!("test failure");
}
}
#[test]
#[cfg(ossl102)]
fn test_aes128_wrap() {
let pt = "00112233445566778899aabbccddeeff";
let ct = "7940ff694448b5bb5139c959a4896832e55d69aa04daa27e";
let key = "2b7e151628aed2a6abf7158809cf4f3c";
let iv = "0001020304050607";
cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, Some(iv));
}
#[test]
#[cfg(ossl102)]
fn test_aes128_wrap_default_iv() {
let pt = "00112233445566778899aabbccddeeff";
let ct = "38f1215f0212526f8a70b51955b9fbdc9fe3041d9832306e";
let key = "2b7e151628aed2a6abf7158809cf4f3c";
cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, None);
}
#[test]
#[cfg(ossl110)]
fn test_aes128_wrap_pad() {
let pt = "00112233445566778899aabbccddee";
let ct = "f13998f5ab32ef82a1bdbcbe585e1d837385b529572a1e1b";
let key = "2b7e151628aed2a6abf7158809cf4f3c";
let iv = "00010203";
cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, Some(iv));
}
#[test]
#[cfg(ossl110)]
fn test_aes128_wrap_pad_default_iv() {
let pt = "00112233445566778899aabbccddee";
let ct = "3a501085fb8cf66f4186b7df851914d471ed823411598add";
let key = "2b7e151628aed2a6abf7158809cf4f3c";
cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, None);
}
#[test]
#[cfg(ossl102)]
fn test_aes192_wrap() {
let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
let ct = "83b89142dfeeb4871e078bfb81134d33e23fedc19b03a1cf689973d3831b6813";
let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
let iv = "0001020304050607";
cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, Some(iv));
}
#[test]
#[cfg(ossl102)]
fn test_aes192_wrap_default_iv() {
let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
let ct = "c02c2cf11505d3e4851030d5534cbf5a1d7eca7ba8839adbf239756daf1b43e6";
let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, None);
}
#[test]
#[cfg(ossl110)]
fn test_aes192_wrap_pad() {
let pt = "00112233445566778899aabbccddee";
let ct = "b4f6bb167ef7caf061a74da82b36ad038ca057ab51e98d3a";
let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
let iv = "00010203";
cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, Some(iv));
}
#[test]
#[cfg(ossl110)]
fn test_aes192_wrap_pad_default_iv() {
let pt = "00112233445566778899aabbccddee";
let ct = "b2c37a28cc602753a7c944a4c2555a2df9c98b2eded5312e";
let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, None);
}
#[test]
#[cfg(ossl102)]
fn test_aes256_wrap() {
let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
let ct = "cc05da2a7f56f7dd0c144231f90bce58648fa20a8278f5a6b7d13bba6aa57a33229d4333866b7fd6";
let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
let iv = "0001020304050607";
cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, Some(iv));
}
#[test]
#[cfg(ossl102)]
fn test_aes256_wrap_default_iv() {
let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
let ct = "0b24f068b50e52bc6987868411c36e1b03900866ed12af81eb87cef70a8d1911731c1d7abf789d88";
let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, None);
}
#[test]
#[cfg(ossl110)]
fn test_aes256_wrap_pad() {
let pt = "00112233445566778899aabbccddee";
let ct = "91594e044ccc06130d60e6c84a996aa4f96a9faff8c5f6e7";
let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
let iv = "00010203";
cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, Some(iv));
}
#[test]
#[cfg(ossl110)]
fn test_aes256_wrap_pad_default_iv() {
let pt = "00112233445566778899aabbccddee";
let ct = "dc3c166a854afd68aea624a4272693554bf2e4fcbae602cd";
let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, None);
}
}
+39 -4
View File
@@ -56,6 +56,7 @@ use std::ptr;
use crate::error::ErrorStack;
use crate::pkey::{HasPrivate, HasPublic, PKeyRef};
use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
/// A type used to derive a shared secret between two keys.
pub struct Deriver<'a>(*mut ffi::EVP_PKEY_CTX, PhantomData<&'a ()>);
@@ -82,10 +83,7 @@ impl<'a> Deriver<'a> {
}
/// Sets the peer key used for secret derivation.
///
/// This corresponds to [`EVP_PKEY_derive_set_peer`]:
///
/// [`EVP_PKEY_derive_set_peer`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_derive_init.html
#[corresponds(EVP_PKEY_derive_set_peer)]
pub fn set_peer<T>(&mut self, key: &'a PKeyRef<T>) -> Result<(), ErrorStack>
where
T: HasPublic,
@@ -93,6 +91,29 @@ impl<'a> Deriver<'a> {
unsafe { cvt(ffi::EVP_PKEY_derive_set_peer(self.0, key.as_ptr())).map(|_| ()) }
}
/// Sets the peer key used for secret derivation along with optionally validating the peer public key.
///
/// Requires OpenSSL 3.0.0 or newer.
#[corresponds(EVP_PKEY_derive_set_peer_ex)]
#[cfg(ossl300)]
pub fn set_peer_ex<T>(
&mut self,
key: &'a PKeyRef<T>,
validate_peer: bool,
) -> Result<(), ErrorStack>
where
T: HasPublic,
{
unsafe {
cvt(ffi::EVP_PKEY_derive_set_peer_ex(
self.0,
key.as_ptr(),
validate_peer as i32,
))
.map(|_| ())
}
}
/// Returns the size of the shared secret.
///
/// It can be used to size the buffer passed to [`Deriver::derive`].
@@ -179,4 +200,18 @@ mod test {
let shared = deriver.derive_to_vec().unwrap();
assert!(!shared.is_empty());
}
#[test]
#[cfg(ossl300)]
fn test_ec_key_derive_ex() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let ec_key = EcKey::generate(&group).unwrap();
let ec_key2 = EcKey::generate(&group).unwrap();
let pkey = PKey::from_ec_key(ec_key).unwrap();
let pkey2 = PKey::from_ec_key(ec_key2).unwrap();
let mut deriver = Deriver::new(&pkey).unwrap();
deriver.set_peer_ex(&pkey2, true).unwrap();
let shared = deriver.derive_to_vec().unwrap();
assert!(!shared.is_empty());
}
}
+65 -1
View File
@@ -7,7 +7,7 @@ use std::ptr;
use crate::bn::{BigNum, BigNumRef};
use crate::error::ErrorStack;
use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private};
use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
@@ -39,6 +39,16 @@ where
params_to_der,
ffi::i2d_DHparams
}
/// Validates DH parameters for correctness
#[corresponds(DH_check_key)]
pub fn check_key(&self) -> Result<bool, ErrorStack> {
unsafe {
let mut codes = 0;
cvt(ffi::DH_check(self.as_ptr(), &mut codes))?;
Ok(codes == 0)
}
}
}
impl Dh<Params> {
@@ -66,6 +76,16 @@ impl Dh<Params> {
}
}
/// Sets the public key on the DH object.
pub fn set_public_key(self, pub_key: BigNum) -> Result<Dh<Public>, ErrorStack> {
unsafe {
let dh_ptr = self.0;
cvt(DH_set0_key(dh_ptr, pub_key.as_ptr(), ptr::null_mut()))?;
mem::forget((self, pub_key));
Ok(Dh::from_ptr(dh_ptr))
}
}
/// Sets the private key on the DH object and recomputes the public key.
pub fn set_private_key(self, priv_key: BigNum) -> Result<Dh<Private>, ErrorStack> {
unsafe {
@@ -79,6 +99,16 @@ impl Dh<Params> {
}
}
/// Sets the public and private keys on the DH object.
pub fn set_key(self, pub_key: BigNum, priv_key: BigNum) -> Result<Dh<Private>, ErrorStack> {
unsafe {
let dh_ptr = self.0;
cvt(DH_set0_key(dh_ptr, pub_key.as_ptr(), priv_key.as_ptr()))?;
mem::forget((self, pub_key, priv_key));
Ok(Dh::from_ptr(dh_ptr))
}
}
/// Generates DH params based on the given `prime_len` and a fixed `generator` value.
#[corresponds(DH_generate_parameters_ex)]
pub fn generate_params(prime_len: u32, generator: u32) -> Result<Dh<Params>, ErrorStack> {
@@ -367,6 +397,30 @@ mod tests {
assert_eq!(key1.private_key(), key2.private_key());
}
#[test]
#[cfg(ossl102)]
fn test_set_keys() {
let dh1 = Dh::get_2048_256().unwrap();
let key1 = dh1.generate_key().unwrap();
let dh2 = Dh::get_2048_256().unwrap();
let key2 = dh2
.set_public_key(key1.public_key().to_owned().unwrap())
.unwrap();
assert_eq!(key1.public_key(), key2.public_key());
let dh3 = Dh::get_2048_256().unwrap();
let key3 = dh3
.set_key(
key1.public_key().to_owned().unwrap(),
key1.private_key().to_owned().unwrap(),
)
.unwrap();
assert_eq!(key1.public_key(), key3.public_key());
assert_eq!(key1.private_key(), key3.private_key());
}
#[test]
fn test_dh_from_pem() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
@@ -413,4 +467,14 @@ mod tests {
assert_eq!(shared_a, shared_b);
}
#[test]
fn test_dh_check_key() {
let dh1 = Dh::generate_params(512, 2).unwrap();
let p = BigNum::from_hex_str("04").unwrap();
let g = BigNum::from_hex_str("02").unwrap();
let dh2 = Dh::from_pqg(p, None, g).unwrap();
assert!(dh1.check_key().unwrap());
assert!(!dh2.check_key().unwrap());
}
}
+65 -15
View File
@@ -7,6 +7,7 @@
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
#[cfg(not(boringssl))]
use libc::c_int;
use std::fmt;
use std::mem;
@@ -14,7 +15,7 @@ use std::ptr;
use crate::bn::{BigNum, BigNumRef};
use crate::error::ErrorStack;
use crate::pkey::{HasParams, HasPrivate, HasPublic, Private, Public};
use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
use crate::util::ForeignTypeRefExt;
use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
@@ -127,6 +128,13 @@ where
ffi::PEM_write_bio_DSAPrivateKey
}
to_der! {
/// Serializes the private_key to a DER-encoded `DSAPrivateKey` structure.
#[corresponds(i2d_DSAPrivateKey)]
private_key_to_der,
ffi::i2d_DSAPrivateKey
}
/// Returns a reference to the private key component of `self`.
#[corresponds(DSA_get0_key)]
pub fn priv_key(&self) -> &BigNumRef {
@@ -183,17 +191,21 @@ type BitType = libc::c_uint;
#[cfg(not(boringssl))]
type BitType = c_int;
impl Dsa<Private> {
/// Generate a DSA key pair.
///
/// Calls [`DSA_generate_parameters_ex`] to populate the `p`, `g`, and `q` values.
/// These values are used to generate the key pair with [`DSA_generate_key`].
///
/// The `bits` parameter corresponds to the length of the prime `p`.
///
/// [`DSA_generate_parameters_ex`]: https://www.openssl.org/docs/manmaster/crypto/DSA_generate_parameters_ex.html
/// [`DSA_generate_key`]: https://www.openssl.org/docs/manmaster/crypto/DSA_generate_key.html
pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
impl Dsa<Params> {
/// Creates a DSA params based upon the given parameters.
#[corresponds(DSA_set0_pqg)]
pub fn from_pqg(p: BigNum, q: BigNum, g: BigNum) -> Result<Dsa<Params>, ErrorStack> {
unsafe {
let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
mem::forget((p, q, g));
Ok(dsa)
}
}
/// Generates DSA params based on the given number of bits.
#[corresponds(DSA_generate_parameters_ex)]
pub fn generate_params(bits: u32) -> Result<Dsa<Params>, ErrorStack> {
ffi::init();
unsafe {
let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
@@ -206,11 +218,31 @@ impl Dsa<Private> {
ptr::null_mut(),
ptr::null_mut(),
))?;
cvt(ffi::DSA_generate_key(dsa.0))?;
Ok(dsa)
}
}
/// Generates a private key based on the DSA params.
#[corresponds(DSA_generate_key)]
pub fn generate_key(self) -> Result<Dsa<Private>, ErrorStack> {
unsafe {
let dsa_ptr = self.0;
cvt(ffi::DSA_generate_key(dsa_ptr))?;
mem::forget(self);
Ok(Dsa::from_ptr(dsa_ptr))
}
}
}
impl Dsa<Private> {
/// Generate a DSA key pair.
///
/// The `bits` parameter corresponds to the length of the prime `p`.
pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
let params = Dsa::generate_params(bits)?;
params.generate_key()
}
/// Create a DSA key pair with the given parameters
///
/// `p`, `q` and `g` are the common parameters.
@@ -283,7 +315,7 @@ impl<T> fmt::Debug for Dsa<T> {
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
if #[cfg(any(ossl110, libressl273, boringssl))] {
use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg};
} else {
#[allow(bad_style)]
@@ -462,7 +494,7 @@ impl DsaSigRef {
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
if #[cfg(any(ossl110, libressl273, boringssl))] {
use ffi::{DSA_SIG_set0, DSA_SIG_get0};
} else {
#[allow(bad_style)]
@@ -556,6 +588,24 @@ mod test {
assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
}
#[test]
fn test_params() {
let params = Dsa::generate_params(1024).unwrap();
let p = params.p().to_owned().unwrap();
let q = params.q().to_owned().unwrap();
let g = params.g().to_owned().unwrap();
let key = params.generate_key().unwrap();
let params2 = Dsa::from_pqg(
key.p().to_owned().unwrap(),
key.q().to_owned().unwrap(),
key.g().to_owned().unwrap(),
)
.unwrap();
assert_eq!(p, *params2.p());
assert_eq!(q, *params2.q());
assert_eq!(g, *params2.g());
}
#[test]
#[cfg(not(boringssl))]
fn test_signature() {
+80 -3
View File
@@ -15,6 +15,7 @@
//! [`EcGroup`]: struct.EcGroup.html
//! [`Nid`]: ../nid/struct.Nid.html
//! [Elliptic Curve Cryptography]: https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use std::fmt;
@@ -28,6 +29,13 @@ use crate::util::ForeignTypeRefExt;
use crate::{cvt, cvt_n, cvt_p, init};
use openssl_macros::corresponds;
cfg_if! {
if #[cfg(not(boringssl))] {
use std::ffi::CString;
use crate::string::OpensslString;
}
}
/// Compressed or Uncompressed conversion
///
/// Conversion from the binary value of the point on the curve is performed in one of
@@ -57,7 +65,7 @@ impl PointConversionForm {
/// Named Curve or Explicit
///
/// This type acts as a boolean as to whether the `EcGroup` is named or explicit.
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Asn1Flag(c_int);
impl Asn1Flag {
@@ -294,6 +302,12 @@ impl EcGroupRef {
}
}
/// Gets the flag determining if the group corresponds to a named curve.
#[corresponds(EC_GROUP_get_asn1_flag)]
pub fn asn1_flag(&self) -> Asn1Flag {
unsafe { Asn1Flag(ffi::EC_GROUP_get_asn1_flag(self.as_ptr())) }
}
/// Returns the name of the curve, if a name is associated.
#[corresponds(EC_GROUP_get_curve_name)]
pub fn curve_name(&self) -> Option<Nid> {
@@ -457,6 +471,26 @@ impl EcPointRef {
}
}
/// Serializes the point to a hexadecimal string representation.
#[corresponds(EC_POINT_point2hex)]
#[cfg(not(boringssl))]
pub fn to_hex_str(
&self,
group: &EcGroupRef,
form: PointConversionForm,
ctx: &mut BigNumContextRef,
) -> Result<OpensslString, ErrorStack> {
unsafe {
let buf = cvt_p(ffi::EC_POINT_point2hex(
group.as_ptr(),
self.as_ptr(),
form.0,
ctx.as_ptr(),
))?;
Ok(OpensslString::from_ptr(buf))
}
}
/// Creates a new point on the specified curve with the same value.
#[corresponds(EC_POINT_dup)]
pub fn to_owned(&self, group: &EcGroupRef) -> Result<EcPoint, ErrorStack> {
@@ -485,7 +519,7 @@ impl EcPointRef {
/// Places affine coordinates of a curve over a prime field in the provided
/// `x` and `y` `BigNum`s.
#[corresponds(EC_POINT_get_affine_coordinates)]
#[cfg(ossl111)]
#[cfg(any(ossl111, boringssl, libressl350))]
pub fn affine_coordinates(
&self,
group: &EcGroupRef,
@@ -625,6 +659,27 @@ impl EcPoint {
}
Ok(point)
}
/// Creates point from a hexadecimal string representation
#[corresponds(EC_POINT_hex2point)]
#[cfg(not(boringssl))]
pub fn from_hex_str(
group: &EcGroupRef,
s: &str,
ctx: &mut BigNumContextRef,
) -> Result<EcPoint, ErrorStack> {
let point = EcPoint::new(group)?;
unsafe {
let c_str = CString::new(s.as_bytes()).unwrap();
cvt_p(ffi::EC_POINT_hex2point(
group.as_ptr(),
c_str.as_ptr() as *const _,
point.as_ptr(),
ctx.as_ptr(),
))?;
}
Ok(point)
}
}
generic_foreign_type_and_impl_send_sync! {
@@ -1115,6 +1170,20 @@ mod test {
assert!(point.eq(&group, &point2, &mut ctx).unwrap());
}
#[test]
#[cfg(not(boringssl))]
fn point_hex_str() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
let point = key.public_key();
let mut ctx = BigNumContext::new().unwrap();
let hex = point
.to_hex_str(&group, PointConversionForm::COMPRESSED, &mut ctx)
.unwrap();
let point2 = EcPoint::from_hex_str(&group, &hex, &mut ctx).unwrap();
assert!(point.eq(&group, &point2, &mut ctx).unwrap());
}
#[test]
fn point_owned() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
@@ -1191,7 +1260,7 @@ mod test {
assert!(ec_key.check_key().is_ok());
}
#[cfg(ossl111)]
#[cfg(any(ossl111, boringssl, libressl350))]
#[test]
fn get_affine_coordinates() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
@@ -1265,4 +1334,12 @@ mod test {
let group2 = EcGroup::from_curve_name(Nid::X9_62_PRIME239V3).unwrap();
assert!(!g.is_on_curve(&group2, &mut ctx).unwrap());
}
#[test]
#[cfg(any(boringssl, ossl111, libressl350))]
fn asn1_flag() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let flag = group.asn1_flag();
assert_eq!(flag, Asn1Flag::NAMED_CURVE);
}
}
+1 -1
View File
@@ -110,7 +110,7 @@ impl EcdsaSigRef {
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
if #[cfg(any(ossl110, libressl273, boringssl))] {
use ffi::{ECDSA_SIG_set0, ECDSA_SIG_get0};
} else {
#[allow(bad_style)]
+1 -1
View File
@@ -43,7 +43,7 @@ use crate::nid::Nid;
use crate::{cvt, cvt_p};
cfg_if! {
if #[cfg(ossl110)] {
if #[cfg(any(ossl110, boringssl))] {
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
} else {
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
+2 -3
View File
@@ -1,7 +1,7 @@
//! Bindings to OpenSSL
//!
//! This crate provides a safe interface to the popular OpenSSL cryptography library. OpenSSL versions 1.0.1 through
//! 3.x.x and LibreSSL versions 2.5 through 3.4.1 are supported.
//! 3.x.x and LibreSSL versions 2.5 through 3.7.x are supported.
//!
//! # Building
//!
@@ -119,7 +119,7 @@
//! ```
#![doc(html_root_url = "https://docs.rs/openssl/0.10")]
#![warn(rust_2018_idioms)]
#![allow(clippy::uninlined_format_args, clippy::needless_doctest_main)]
#![allow(clippy::uninlined_format_args)]
#[doc(inline)]
pub use ffi::init;
@@ -166,7 +166,6 @@ pub mod nid;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_OCSP")))]
pub mod ocsp;
pub mod pkcs12;
#[cfg(not(boringssl))]
pub mod pkcs5;
#[cfg(not(boringssl))]
pub mod pkcs7;
+1 -1
View File
@@ -93,7 +93,7 @@ use std::convert::TryFrom;
use std::ptr;
cfg_if! {
if #[cfg(ossl110)] {
if #[cfg(any(ossl110, boringssl))] {
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
} else {
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
+12 -7
View File
@@ -51,13 +51,13 @@ pub struct Nid(c_int);
#[allow(non_snake_case)]
impl Nid {
/// Create a `Nid` from an integer representation.
pub fn from_raw(raw: c_int) -> Nid {
pub const fn from_raw(raw: c_int) -> Nid {
Nid(raw)
}
/// Return the integer representation of a `Nid`.
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn as_raw(&self) -> c_int {
pub const fn as_raw(&self) -> c_int {
self.0
}
@@ -1074,6 +1074,8 @@ impl Nid {
pub const AES_128_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_128_cbc_hmac_sha1);
pub const AES_192_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_192_cbc_hmac_sha1);
pub const AES_256_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_256_cbc_hmac_sha1);
#[cfg(ossl111)]
pub const SM2: Nid = Nid(ffi::NID_sm2);
#[cfg(any(ossl111, libressl291))]
pub const SM3: Nid = Nid(ffi::NID_sm3);
#[cfg(ossl111)]
@@ -1165,10 +1167,13 @@ mod test {
assert_eq!(nid.short_name().unwrap(), "foo");
assert_eq!(nid.long_name().unwrap(), "foobar");
let invalid_oid = Nid::create("invalid_oid", "invalid", "invalid");
assert!(
invalid_oid.is_err(),
"invalid_oid should not return a valid value"
);
// Due to a bug in OpenSSL 3.1.0, this test crashes on Windows
if !cfg!(ossl310) {
let invalid_oid = Nid::create("invalid_oid", "invalid", "invalid");
assert!(
invalid_oid.is_err(),
"invalid_oid should not return a valid value"
);
}
}
}
+15 -11
View File
@@ -1,9 +1,13 @@
#[cfg(not(boringssl))]
use libc::c_int;
use std::convert::TryInto;
#[cfg(not(boringssl))]
use std::ptr;
use crate::cvt;
use crate::error::ErrorStack;
use crate::hash::MessageDigest;
#[cfg(not(boringssl))]
use crate::symm::Cipher;
use openssl_macros::corresponds;
@@ -25,6 +29,7 @@ pub struct KeyIvPair {
/// `pbkdf2_hmac` or another more modern key derivation algorithm.
#[corresponds(EVP_BytesToKey)]
#[allow(clippy::useless_conversion)]
#[cfg(not(boringssl))]
pub fn bytes_to_key(
cipher: Cipher,
digest: MessageDigest,
@@ -91,19 +96,15 @@ pub fn pbkdf2_hmac(
key: &mut [u8],
) -> Result<(), ErrorStack> {
unsafe {
assert!(pass.len() <= c_int::max_value() as usize);
assert!(salt.len() <= c_int::max_value() as usize);
assert!(key.len() <= c_int::max_value() as usize);
ffi::init();
cvt(ffi::PKCS5_PBKDF2_HMAC(
pass.as_ptr() as *const _,
pass.len() as c_int,
pass.len().try_into().unwrap(),
salt.as_ptr(),
salt.len() as c_int,
iter as c_int,
salt.len().try_into().unwrap(),
iter.try_into().unwrap(),
hash.as_ptr(),
key.len() as c_int,
key.len().try_into().unwrap(),
key.as_mut_ptr(),
))
.map(|_| ())
@@ -114,7 +115,8 @@ pub fn pbkdf2_hmac(
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PBE_scrypt)]
#[cfg(any(ossl110))]
#[cfg(any(ossl110, boringssl))]
#[allow(clippy::useless_conversion)]
pub fn scrypt(
pass: &[u8],
salt: &[u8],
@@ -134,7 +136,7 @@ pub fn scrypt(
n,
r,
p,
maxmem,
maxmem.try_into().unwrap(),
key.as_mut_ptr() as *mut _,
key.len(),
))
@@ -145,6 +147,7 @@ pub fn scrypt(
#[cfg(test)]
mod tests {
use crate::hash::MessageDigest;
#[cfg(not(boringssl))]
use crate::symm::Cipher;
// Test vectors from
@@ -246,6 +249,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
fn bytes_to_key() {
let salt = [16_u8, 34_u8, 19_u8, 23_u8, 141_u8, 4_u8, 207_u8, 221_u8];
@@ -282,7 +286,7 @@ mod tests {
}
#[test]
#[cfg(any(ossl110))]
#[cfg(any(ossl110, boringssl))]
fn scrypt() {
let pass = "pleaseletmein";
let salt = "SodiumChloride";
+32 -30
View File
@@ -57,7 +57,7 @@ use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_int, c_long};
use openssl_macros::corresponds;
use std::convert::TryFrom;
use std::convert::{TryFrom, TryInto};
use std::ffi::CString;
use std::fmt;
use std::mem;
@@ -85,8 +85,10 @@ impl Id {
pub const DSA: Id = Id(ffi::EVP_PKEY_DSA);
pub const DH: Id = Id(ffi::EVP_PKEY_DH);
pub const EC: Id = Id(ffi::EVP_PKEY_EC);
#[cfg(ossl111)]
pub const SM2: Id = Id(ffi::EVP_PKEY_SM2);
#[cfg(ossl110)]
#[cfg(any(ossl110, boringssl))]
pub const HKDF: Id = Id(ffi::EVP_PKEY_HKDF);
#[cfg(any(ossl111, boringssl, libressl370))]
@@ -97,6 +99,8 @@ impl Id {
pub const X25519: Id = Id(ffi::EVP_PKEY_X25519);
#[cfg(ossl111)]
pub const X448: Id = Id(ffi::EVP_PKEY_X448);
#[cfg(ossl111)]
pub const POLY1305: Id = Id(ffi::EVP_PKEY_POLY1305);
/// Creates a `Id` from an integer representation.
pub fn from_raw(value: c_int) -> Id {
@@ -244,7 +248,11 @@ where
where
U: HasPublic,
{
unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 }
let res = unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 };
// Clear the stack. OpenSSL will put an error on the stack when the
// keys are different types in some situations.
let _ = ErrorStack::get();
res
}
/// Raw byte representation of a public key.
@@ -344,10 +352,6 @@ where
/// Serializes a private key into a DER-formatted PKCS#8, using the supplied password to
/// encrypt the key.
///
/// # Panics
///
/// Panics if `passphrase` contains an embedded null.
#[corresponds(i2d_PKCS8PrivateKey_bio)]
pub fn private_key_to_pkcs8_passphrase(
&self,
@@ -356,14 +360,12 @@ where
) -> Result<Vec<u8>, ErrorStack> {
unsafe {
let bio = MemBio::new()?;
let len = passphrase.len();
let passphrase = CString::new(passphrase).unwrap();
cvt(ffi::i2d_PKCS8PrivateKey_bio(
bio.as_ptr(),
self.as_ptr(),
cipher.as_ptr(),
passphrase.as_ptr() as *const _ as *mut _,
len as ::libc::c_int,
passphrase.len().try_into().unwrap(),
None,
ptr::null_mut(),
))?;
@@ -406,11 +408,7 @@ impl<T> PKey<T> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_RSA,
rsa.as_ptr() as *mut _,
))?;
cvt(ffi::EVP_PKEY_assign_RSA(pkey.0, rsa.as_ptr()))?;
mem::forget(rsa);
Ok(pkey)
}
@@ -422,11 +420,7 @@ impl<T> PKey<T> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_DSA,
dsa.as_ptr() as *mut _,
))?;
cvt(ffi::EVP_PKEY_assign_DSA(pkey.0, dsa.as_ptr()))?;
mem::forget(dsa);
Ok(pkey)
}
@@ -434,15 +428,12 @@ impl<T> PKey<T> {
/// Creates a new `PKey` containing a Diffie-Hellman key.
#[corresponds(EVP_PKEY_assign_DH)]
#[cfg(not(boringssl))]
pub fn from_dh(dh: Dh<T>) -> Result<PKey<T>, ErrorStack> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_DH,
dh.as_ptr() as *mut _,
))?;
cvt(ffi::EVP_PKEY_assign_DH(pkey.0, dh.as_ptr()))?;
mem::forget(dh);
Ok(pkey)
}
@@ -454,11 +445,7 @@ impl<T> PKey<T> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_EC,
ec_key.as_ptr() as *mut _,
))?;
cvt(ffi::EVP_PKEY_assign_EC_KEY(pkey.0, ec_key.as_ptr()))?;
mem::forget(ec_key);
Ok(pkey)
}
@@ -861,6 +848,7 @@ impl<T> TryFrom<PKey<T>> for Dsa<T> {
}
}
#[cfg(not(boringssl))]
impl<T> TryFrom<Dh<T>> for PKey<T> {
type Error = ErrorStack;
@@ -885,6 +873,7 @@ mod tests {
use crate::dh::Dh;
use crate::dsa::Dsa;
use crate::ec::EcKey;
use crate::error::Error;
use crate::nid::Nid;
use crate::rsa::Rsa;
use crate::symm::Cipher;
@@ -1168,4 +1157,17 @@ mod tests {
let key = PKey::ec_gen("prime256v1").unwrap();
assert!(key.ec_key().is_ok());
}
#[test]
fn test_public_eq() {
let rsa = Rsa::generate(2048).unwrap();
let pkey1 = PKey::from_rsa(rsa).unwrap();
let group = crate::ec::EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let ec_key = EcKey::generate(&group).unwrap();
let pkey2 = PKey::from_ec_key(ec_key).unwrap();
assert!(!pkey1.public_eq(&pkey2));
assert!(Error::get().is_none());
}
}
+211 -13
View File
@@ -70,7 +70,8 @@ use crate::error::ErrorStack;
use crate::md::MdRef;
use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private};
use crate::rsa::Padding;
use crate::{cvt, cvt_n, cvt_p};
use crate::sign::RsaPssSaltlen;
use crate::{cvt, cvt_p};
use foreign_types::{ForeignType, ForeignTypeRef};
#[cfg(not(boringssl))]
use libc::c_int;
@@ -164,6 +165,17 @@ where
Ok(())
}
/// Prepares the context for signature recovery using the public key.
#[corresponds(EVP_PKEY_verify_recover_init)]
#[inline]
pub fn verify_recover_init(&mut self) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_verify_recover_init(self.as_ptr()))?;
}
Ok(())
}
/// Encrypts data using the public key.
///
/// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be
@@ -209,16 +221,54 @@ where
#[inline]
pub fn verify(&mut self, data: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> {
unsafe {
let r = cvt_n(ffi::EVP_PKEY_verify(
let r = ffi::EVP_PKEY_verify(
self.as_ptr(),
sig.as_ptr(),
sig.len(),
data.as_ptr(),
data.len(),
))?;
);
// `EVP_PKEY_verify` is not terribly consistent about how it,
// reports errors. It does not clearly distinguish between 0 and
// -1, and may put errors on the stack in both cases. If there's
// errors on the stack, we return `Err()`, else we return
// `Ok(false)`.
if r <= 0 {
let errors = ErrorStack::get();
if !errors.errors().is_empty() {
return Err(errors);
}
}
Ok(r == 1)
}
}
/// Recovers the original data signed by the private key. You almost
/// always want `verify` instead.
///
/// Returns the number of bytes written to `to`, or the number of bytes
/// that would be written, if `to` is `None.
#[corresponds(EVP_PKEY_verify_recover)]
#[inline]
pub fn verify_recover(
&mut self,
sig: &[u8],
to: Option<&mut [u8]>,
) -> Result<usize, ErrorStack> {
let mut written = to.as_ref().map_or(0, |b| b.len());
unsafe {
cvt(ffi::EVP_PKEY_verify_recover(
self.as_ptr(),
to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
&mut written,
sig.as_ptr(),
sig.len(),
))?;
}
Ok(written)
}
}
impl<T> PkeyCtxRef<T>
@@ -351,6 +401,22 @@ impl<T> PkeyCtxRef<T> {
Ok(())
}
/// Sets which algorithm was used to compute the digest used in a
/// signature. With RSA signatures this causes the signature to be wrapped
/// in a `DigestInfo` structure. This is almost always what you want with
/// RSA signatures.
#[corresponds(EVP_PKEY_CTX_set_signature_md)]
#[inline]
pub fn set_signature_md(&self, md: &MdRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_signature_md(
self.as_ptr(),
md.as_ptr(),
))?;
}
Ok(())
}
/// Returns the RSA padding mode in use.
///
/// This is only useful for RSA keys.
@@ -381,6 +447,21 @@ impl<T> PkeyCtxRef<T> {
Ok(())
}
/// Sets the RSA PSS salt length.
///
/// This is only useful for RSA keys.
#[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)]
#[inline]
pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
self.as_ptr(),
len.as_raw(),
))
.map(|_| ())
}
}
/// Sets the RSA MGF1 algorithm.
///
/// This is only useful for RSA keys.
@@ -401,7 +482,7 @@ impl<T> PkeyCtxRef<T> {
///
/// This is only useful for RSA keys.
#[corresponds(EVP_PKEY_CTX_set_rsa_oaep_md)]
#[cfg(any(ossl102, libressl310))]
#[cfg(any(ossl102, libressl310, boringssl))]
#[inline]
pub fn set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
unsafe {
@@ -485,7 +566,7 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_set_hkdf_md)]
#[cfg(ossl110)]
#[cfg(any(ossl110, boringssl))]
#[inline]
pub fn set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack> {
unsafe {
@@ -527,10 +608,13 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_set1_hkdf_key)]
#[cfg(ossl110)]
#[cfg(any(ossl110, boringssl))]
#[inline]
pub fn set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
#[cfg(not(boringssl))]
let len = c_int::try_from(key.len()).unwrap();
#[cfg(boringssl)]
let len = key.len();
unsafe {
cvt(ffi::EVP_PKEY_CTX_set1_hkdf_key(
@@ -549,10 +633,13 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_set1_hkdf_salt)]
#[cfg(ossl110)]
#[cfg(any(ossl110, boringssl))]
#[inline]
pub fn set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack> {
#[cfg(not(boringssl))]
let len = c_int::try_from(salt.len()).unwrap();
#[cfg(boringssl)]
let len = salt.len();
unsafe {
cvt(ffi::EVP_PKEY_CTX_set1_hkdf_salt(
@@ -571,10 +658,13 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_add1_hkdf_info)]
#[cfg(ossl110)]
#[cfg(any(ossl110, boringssl))]
#[inline]
pub fn add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack> {
#[cfg(not(boringssl))]
let len = c_int::try_from(info.len()).unwrap();
#[cfg(boringssl)]
let len = info.len();
unsafe {
cvt(ffi::EVP_PKEY_CTX_add1_hkdf_info(
@@ -632,11 +722,12 @@ mod test {
#[cfg(not(boringssl))]
use crate::cipher::Cipher;
use crate::ec::{EcGroup, EcKey};
#[cfg(any(ossl102, libressl310))]
use crate::hash::{hash, MessageDigest};
use crate::md::Md;
use crate::nid::Nid;
use crate::pkey::PKey;
use crate::rsa::Rsa;
use crate::sign::Verifier;
#[test]
fn rsa() {
@@ -662,7 +753,7 @@ mod test {
}
#[test]
#[cfg(any(ossl102, libressl310))]
#[cfg(any(ossl102, libressl310, boringssl))]
fn rsa_oaep() {
let key = include_bytes!("../test/rsa.pem");
let rsa = Rsa::private_key_from_pem(key).unwrap();
@@ -689,6 +780,53 @@ mod test {
assert_eq!(pt, out);
}
#[test]
fn rsa_sign() {
let key = include_bytes!("../test/rsa.pem");
let rsa = Rsa::private_key_from_pem(key).unwrap();
let pkey = PKey::from_rsa(rsa).unwrap();
let mut ctx = PkeyCtx::new(&pkey).unwrap();
ctx.sign_init().unwrap();
ctx.set_rsa_padding(Padding::PKCS1).unwrap();
ctx.set_signature_md(Md::sha384()).unwrap();
let msg = b"hello world";
let digest = hash(MessageDigest::sha384(), msg).unwrap();
let mut signature = vec![];
ctx.sign_to_vec(&digest, &mut signature).unwrap();
let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap();
verifier.update(msg).unwrap();
assert!(matches!(verifier.verify(&signature), Ok(true)));
}
#[test]
fn rsa_sign_pss() {
let key = include_bytes!("../test/rsa.pem");
let rsa = Rsa::private_key_from_pem(key).unwrap();
let pkey = PKey::from_rsa(rsa).unwrap();
let mut ctx = PkeyCtx::new(&pkey).unwrap();
ctx.sign_init().unwrap();
ctx.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
ctx.set_signature_md(Md::sha384()).unwrap();
ctx.set_rsa_pss_saltlen(RsaPssSaltlen::custom(14)).unwrap();
let msg = b"hello world";
let digest = hash(MessageDigest::sha384(), msg).unwrap();
let mut signature = vec![];
ctx.sign_to_vec(&digest, &mut signature).unwrap();
let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap();
verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
verifier
.set_rsa_pss_saltlen(RsaPssSaltlen::custom(14))
.unwrap();
verifier.update(msg).unwrap();
assert!(matches!(verifier.verify(&signature), Ok(true)));
}
#[test]
fn derive() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
@@ -717,7 +855,7 @@ mod test {
}
#[test]
#[cfg(ossl110)]
#[cfg(any(ossl110, boringssl))]
fn hkdf() {
let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
ctx.derive_init().unwrap();
@@ -798,7 +936,67 @@ mod test {
let bad_data = b"Some Crypto text";
ctx.verify_init().unwrap();
let valid = ctx.verify(bad_data, &signature).unwrap();
assert!(!valid);
let valid = ctx.verify(bad_data, &signature);
assert!(matches!(valid, Ok(false) | Err(_)));
assert!(ErrorStack::get().errors().is_empty());
}
#[test]
fn verify_fail_ec() {
let key1 =
EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap();
let key1 = PKey::from_ec_key(key1).unwrap();
let data = b"Some Crypto Text";
let mut ctx = PkeyCtx::new(&key1).unwrap();
ctx.verify_init().unwrap();
assert!(matches!(ctx.verify(data, &[0; 64]), Ok(false) | Err(_)));
assert!(ErrorStack::get().errors().is_empty());
}
#[test]
fn test_verify_recover() {
let key = Rsa::generate(2048).unwrap();
let key = PKey::from_rsa(key).unwrap();
let digest = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
];
let mut ctx = PkeyCtx::new(&key).unwrap();
ctx.sign_init().unwrap();
ctx.set_rsa_padding(Padding::PKCS1).unwrap();
ctx.set_signature_md(Md::sha256()).unwrap();
let mut signature = vec![];
ctx.sign_to_vec(&digest, &mut signature).unwrap();
// Attempt recovery of just the digest.
let mut ctx = PkeyCtx::new(&key).unwrap();
ctx.verify_recover_init().unwrap();
ctx.set_rsa_padding(Padding::PKCS1).unwrap();
ctx.set_signature_md(Md::sha256()).unwrap();
let length = ctx.verify_recover(&signature, None).unwrap();
let mut result_buf = vec![0; length];
let length = ctx
.verify_recover(&signature, Some(&mut result_buf))
.unwrap();
assert_eq!(length, digest.len());
// result_buf contains the digest
assert_eq!(result_buf[..length], digest);
// Attempt recovery of teh entire DigestInfo
let mut ctx = PkeyCtx::new(&key).unwrap();
ctx.verify_recover_init().unwrap();
ctx.set_rsa_padding(Padding::PKCS1).unwrap();
let length = ctx.verify_recover(&signature, None).unwrap();
let mut result_buf = vec![0; length];
let length = ctx
.verify_recover(&signature, Some(&mut result_buf))
.unwrap();
// 32-bytes of SHA256 digest + the ASN.1 DigestInfo structure == 51 bytes
assert_eq!(length, 51);
// The digest is the end of the DigestInfo structure.
assert_eq!(result_buf[length - digest.len()..length], digest);
}
}
+1 -1
View File
@@ -581,7 +581,7 @@ impl<T> fmt::Debug for Rsa<T> {
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
if #[cfg(any(ossl110, libressl273, boringssl))] {
use ffi::{
RSA_get0_key, RSA_get0_factors, RSA_get0_crt_params, RSA_set0_key, RSA_set0_factors,
RSA_set0_crt_params,
+9 -9
View File
@@ -93,7 +93,7 @@ pub struct RsaPssSaltlen(c_int);
impl RsaPssSaltlen {
/// Returns the integer representation of `RsaPssSaltlen`.
fn as_raw(&self) -> c_int {
pub(crate) fn as_raw(&self) -> c_int {
self.0
}
@@ -117,10 +117,10 @@ pub struct Signer<'a> {
_p: PhantomData<&'a ()>,
}
unsafe impl<'a> Sync for Signer<'a> {}
unsafe impl<'a> Send for Signer<'a> {}
unsafe impl Sync for Signer<'_> {}
unsafe impl Send for Signer<'_> {}
impl<'a> Drop for Signer<'a> {
impl Drop for Signer<'_> {
fn drop(&mut self) {
// pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
unsafe {
@@ -130,7 +130,7 @@ impl<'a> Drop for Signer<'a> {
}
#[allow(clippy::len_without_is_empty)]
impl<'a> Signer<'a> {
impl Signer<'_> {
/// Creates a new `Signer`.
///
/// This cannot be used with Ed25519 or Ed448 keys. Please refer to
@@ -139,7 +139,7 @@ impl<'a> Signer<'a> {
/// OpenSSL documentation at [`EVP_DigestSignInit`].
///
/// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html
pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
pub fn new<'a, T>(type_: MessageDigest, pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
where
T: HasPrivate,
{
@@ -154,16 +154,16 @@ impl<'a> Signer<'a> {
/// OpenSSL documentation at [`EVP_DigestSignInit`].
///
/// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html
pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
pub fn new_without_digest<'a, T>(pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
where
T: HasPrivate,
{
Self::new_intern(None, pkey)
}
fn new_intern<T>(
fn new_intern<'a, T>(
type_: Option<MessageDigest>,
pkey: &'a PKeyRef<T>,
pkey: &PKeyRef<T>,
) -> Result<Signer<'a>, ErrorStack>
where
T: HasPrivate,
+3 -2
View File
@@ -11,6 +11,7 @@ use crate::ssl::{
SslOptions, SslRef, SslStream, SslVerifyMode,
};
use crate::version;
use std::net::IpAddr;
const FFDHE_2048: &str = "
-----BEGIN DH PARAMETERS-----
@@ -177,9 +178,9 @@ impl ConnectConfiguration {
/// Returns an `Ssl` configured to connect to the provided domain.
///
/// The domain is used for SNI and hostname verification if enabled.
/// The domain is used for SNI (if it is not an IP address) and hostname verification if enabled.
pub fn into_ssl(mut self, domain: &str) -> Result<Ssl, ErrorStack> {
if self.sni {
if self.sni && domain.parse::<IpAddr>().is_err() {
self.ssl.set_hostname(domain)?;
}
+72 -9
View File
@@ -72,7 +72,7 @@ use crate::srtp::{SrtpProtectionProfile, SrtpProtectionProfileRef};
use crate::ssl::bio::BioMethod;
use crate::ssl::callbacks::*;
use crate::ssl::error::InnerError;
use crate::stack::{Stack, StackRef};
use crate::stack::{Stack, StackRef, Stackable};
use crate::util::{ForeignTypeExt, ForeignTypeRefExt};
use crate::x509::store::{X509Store, X509StoreBuilderRef, X509StoreRef};
#[cfg(any(ossl102, libressl261))]
@@ -599,7 +599,7 @@ impl AlpnError {
/// Terminate the handshake with a fatal alert.
///
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(any(ossl110))]
#[cfg(ossl110)]
pub const ALERT_FATAL: AlpnError = AlpnError(ffi::SSL_TLSEXT_ERR_ALERT_FATAL);
/// Do not select a protocol, but continue the handshake.
@@ -644,6 +644,17 @@ impl SslVersion {
/// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
#[cfg(any(ossl111, libressl340))]
pub const TLS1_3: SslVersion = SslVersion(ffi::TLS1_3_VERSION);
/// DTLSv1.0
///
/// DTLS 1.0 corresponds to TLS 1.1.
pub const DTLS1: SslVersion = SslVersion(ffi::DTLS1_VERSION);
/// DTLSv1.2
///
/// DTLS 1.2 corresponds to TLS 1.2 to harmonize versions. There was never a DTLS 1.1.
#[cfg(any(ossl102, libressl332))]
pub const DTLS1_2: SslVersion = SslVersion(ffi::DTLS1_2_VERSION);
}
cfg_if! {
@@ -1120,7 +1131,7 @@ impl SslContextBuilder {
/// Sets the minimum supported protocol version.
///
/// A value of `None` will enable protocol versions down the the lowest version supported by
/// A value of `None` will enable protocol versions down to the lowest version supported by
/// OpenSSL.
///
/// Requires OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer.
@@ -1138,7 +1149,7 @@ impl SslContextBuilder {
/// Sets the maximum supported protocol version.
///
/// A value of `None` will enable protocol versions down the the highest version supported by
/// A value of `None` will enable protocol versions up to the highest version supported by
/// OpenSSL.
///
/// Requires OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer.
@@ -1156,7 +1167,7 @@ impl SslContextBuilder {
/// Gets the minimum supported protocol version.
///
/// A value of `None` indicates that all versions down the the lowest version supported by
/// A value of `None` indicates that all versions down to the lowest version supported by
/// OpenSSL are enabled.
///
/// Requires OpenSSL 1.1.0g or LibreSSL 2.7.0 or newer.
@@ -1175,7 +1186,7 @@ impl SslContextBuilder {
/// Gets the maximum supported protocol version.
///
/// A value of `None` indicates that all versions down the the highest version supported by
/// A value of `None` indicates that all versions up to the highest version supported by
/// OpenSSL are enabled.
///
/// Requires OpenSSL 1.1.0g or LibreSSL 2.7.0 or newer.
@@ -1929,6 +1940,10 @@ impl ForeignType for SslCipher {
}
}
impl Stackable for SslCipher {
type StackType = ffi::stack_st_SSL_CIPHER;
}
impl Deref for SslCipher {
type Target = SslCipherRef;
@@ -2045,6 +2060,19 @@ impl SslCipherRef {
}
}
impl fmt::Debug for SslCipherRef {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{}", self.name())
}
}
/// A stack of selected ciphers, and a stack of selected signalling cipher suites
#[derive(Debug)]
pub struct CipherLists {
pub suites: Stack<SslCipher>,
pub signalling_suites: Stack<SslCipher>,
}
foreign_type_and_impl_send_sync! {
type CType = ffi::SSL_SESSION;
fn drop = ffi::SSL_SESSION_free;
@@ -2385,7 +2413,7 @@ impl SslRef {
///
/// Requires OpenSSL 1.0.1 or 1.0.2.
#[corresponds(SSL_set_tmp_ecdh_callback)]
#[cfg(any(all(ossl101, not(ossl110))))]
#[cfg(all(ossl101, not(ossl110)))]
#[deprecated(note = "this function leaks memory and does not exist on newer OpenSSL versions")]
pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F)
where
@@ -3072,6 +3100,41 @@ impl SslRef {
}
}
/// Decodes a slice of wire-format cipher suite specification bytes. Unsupported cipher suites
/// are ignored.
///
/// Requires OpenSSL 1.1.1 or newer.
#[corresponds(SSL_bytes_to_cipher_list)]
#[cfg(ossl111)]
pub fn bytes_to_cipher_list(
&self,
bytes: &[u8],
isv2format: bool,
) -> Result<CipherLists, ErrorStack> {
unsafe {
let ptr = bytes.as_ptr();
let len = bytes.len();
let mut sk = ptr::null_mut();
let mut scsvs = ptr::null_mut();
let res = ffi::SSL_bytes_to_cipher_list(
self.as_ptr(),
ptr,
len,
isv2format as c_int,
&mut sk,
&mut scsvs,
);
if res == 1 {
Ok(CipherLists {
suites: Stack::from_ptr(sk),
signalling_suites: Stack::from_ptr(scsvs),
})
} else {
Err(ErrorStack::get())
}
}
}
/// Returns the compression methods field of the client's hello message.
///
/// This can only be used inside of the client hello callback. Otherwise, `None` is returned.
@@ -3223,7 +3286,7 @@ impl SslRef {
/// Sets the minimum supported protocol version.
///
/// A value of `None` will enable protocol versions down the the lowest version supported by
/// A value of `None` will enable protocol versions down to the lowest version supported by
/// OpenSSL.
///
/// Requires OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer.
@@ -3241,7 +3304,7 @@ impl SslRef {
/// Sets the maximum supported protocol version.
///
/// A value of `None` will enable protocol versions down the the highest version supported by
/// A value of `None` will enable protocol versions up to the highest version supported by
/// OpenSSL.
///
/// Requires OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer.
+60 -2
View File
@@ -21,10 +21,10 @@ use crate::hash::MessageDigest;
use crate::ocsp::{OcspResponse, OcspResponseStatus};
use crate::pkey::PKey;
use crate::srtp::SrtpProfileId;
use crate::ssl;
use crate::ssl::test::server::Server;
#[cfg(any(ossl110, ossl111, libressl261))]
use crate::ssl::SslVersion;
use crate::ssl::{self, NameType, SslConnectorBuilder};
#[cfg(ossl111)]
use crate::ssl::{ClientHelloResponse, ExtensionContext};
use crate::ssl::{
@@ -467,7 +467,7 @@ fn test_alpn_server_advertise_multiple() {
}
#[test]
#[cfg(any(ossl110))]
#[cfg(ossl110)]
fn test_alpn_server_select_none_fatal() {
let mut server = Server::builder();
server.ctx().set_alpn_select_callback(|_, client| {
@@ -767,6 +767,61 @@ fn connector_can_disable_verify() {
s.read_exact(&mut [0]).unwrap();
}
#[test]
fn connector_does_use_sni_with_dnsnames() {
static CALLED_BACK: AtomicBool = AtomicBool::new(false);
let mut builder = Server::builder();
builder.ctx().set_servername_callback(|ssl, _| {
assert_eq!(ssl.servername(NameType::HOST_NAME), Some("foobar.com"));
CALLED_BACK.store(true, Ordering::SeqCst);
Ok(())
});
let server = builder.build();
let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
connector.set_ca_file("test/root-ca.pem").unwrap();
let s = server.connect_tcp();
let mut s = connector
.build()
.configure()
.unwrap()
.connect("foobar.com", s)
.unwrap();
s.read_exact(&mut [0]).unwrap();
assert!(CALLED_BACK.load(Ordering::SeqCst));
}
#[test]
fn connector_doesnt_use_sni_with_ips() {
static CALLED_BACK: AtomicBool = AtomicBool::new(false);
let mut builder = Server::builder();
builder.ctx().set_servername_callback(|ssl, _| {
assert_eq!(ssl.servername(NameType::HOST_NAME), None);
CALLED_BACK.store(true, Ordering::SeqCst);
Ok(())
});
let server = builder.build();
let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
// The server's cert isn't issued for 127.0.0.1 but we don't care for this test.
connector.set_verify(SslVerifyMode::NONE);
let s = server.connect_tcp();
let mut s = connector
.build()
.configure()
.unwrap()
.connect("127.0.0.1", s)
.unwrap();
s.read_exact(&mut [0]).unwrap();
assert!(CALLED_BACK.load(Ordering::SeqCst));
}
fn test_mozilla_server(new: fn(SslMethod) -> Result<SslAcceptorBuilder, ErrorStack>) {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let port = listener.local_addr().unwrap().port();
@@ -1403,6 +1458,9 @@ fn client_hello() {
assert!(ssl.client_hello_session_id().is_some());
assert!(ssl.client_hello_ciphers().is_some());
assert!(ssl.client_hello_compression_methods().is_some());
assert!(ssl
.bytes_to_cipher_list(ssl.client_hello_ciphers().unwrap(), ssl.client_hello_isv2())
.is_ok());
CALLED_BACK.store(true, Ordering::SeqCst);
Ok(ClientHelloResponse::SUCCESS)
+10 -9
View File
@@ -142,7 +142,7 @@ impl Cipher {
}
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(ossl110)]
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
pub fn aes_128_ocb() -> Cipher {
unsafe { Cipher(ffi::EVP_aes_128_ocb()) }
}
@@ -187,7 +187,7 @@ impl Cipher {
}
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(ossl110)]
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
pub fn aes_192_ocb() -> Cipher {
unsafe { Cipher(ffi::EVP_aes_192_ocb()) }
}
@@ -237,7 +237,7 @@ impl Cipher {
}
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(ossl110)]
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
pub fn aes_256_ocb() -> Cipher {
unsafe { Cipher(ffi::EVP_aes_256_ocb()) }
}
@@ -283,6 +283,7 @@ impl Cipher {
unsafe { Cipher(ffi::EVP_des_ede3_cfb64()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
pub fn rc4() -> Cipher {
unsafe { Cipher(ffi::EVP_rc4()) }
}
@@ -401,14 +402,14 @@ impl Cipher {
}
/// Determines whether the cipher is using OCB mode
#[cfg(ossl110)]
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
fn is_ocb(self) -> bool {
self == Cipher::aes_128_ocb()
|| self == Cipher::aes_192_ocb()
|| self == Cipher::aes_256_ocb()
}
#[cfg(not(ossl110))]
#[cfg(any(not(ossl110), osslconf = "OPENSSL_NO_OCB"))]
const fn is_ocb(self) -> bool {
false
}
@@ -1421,7 +1422,7 @@ mod tests {
}
#[test]
#[cfg(ossl110)]
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
fn test_aes_128_ocb() {
let key = "000102030405060708090a0b0c0d0e0f";
let aad = "0001020304050607";
@@ -1457,7 +1458,7 @@ mod tests {
}
#[test]
#[cfg(ossl110)]
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
fn test_aes_128_ocb_fail() {
let key = "000102030405060708090a0b0c0d0e0f";
let aad = "0001020304050607";
@@ -1477,7 +1478,7 @@ mod tests {
}
#[test]
#[cfg(any(ossl110))]
#[cfg(ossl110)]
fn test_chacha20() {
let key = "0000000000000000000000000000000000000000000000000000000000000000";
let iv = "00000000000000000000000000000000";
@@ -1492,7 +1493,7 @@ mod tests {
}
#[test]
#[cfg(any(ossl110))]
#[cfg(ossl110)]
fn test_chacha20_poly1305() {
let key = "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f";
let iv = "070000004041424344454647";
+30 -5
View File
@@ -67,6 +67,9 @@ impl BasicConstraints {
}
/// Return the `BasicConstraints` extension as an `X509Extension`.
// Temporarily silence the deprecation warning - this should be ported to
// `X509Extension::new_internal`.
#[allow(deprecated)]
pub fn build(&self) -> Result<X509Extension, ErrorStack> {
let mut value = String::new();
if self.critical {
@@ -183,6 +186,9 @@ impl KeyUsage {
}
/// Return the `KeyUsage` extension as an `X509Extension`.
// Temporarily silence the deprecation warning - this should be ported to
// `X509Extension::new_internal`.
#[allow(deprecated)]
pub fn build(&self) -> Result<X509Extension, ErrorStack> {
let mut value = String::new();
let mut first = true;
@@ -346,6 +352,9 @@ impl SubjectKeyIdentifier {
}
/// Return a `SubjectKeyIdentifier` extension as an `X509Extension`.
// Temporarily silence the deprecation warning - this should be ported to
// `X509Extension::new_internal`.
#[allow(deprecated)]
pub fn build(&self, ctx: &X509v3Context<'_>) -> Result<X509Extension, ErrorStack> {
let mut value = String::new();
let mut first = true;
@@ -398,6 +407,9 @@ impl AuthorityKeyIdentifier {
}
/// Return a `AuthorityKeyIdentifier` extension as an `X509Extension`.
// Temporarily silence the deprecation warning - this should be ported to
// `X509Extension::new_internal`.
#[allow(deprecated)]
pub fn build(&self, ctx: &X509v3Context<'_>) -> Result<X509Extension, ErrorStack> {
let mut value = String::new();
let mut first = true;
@@ -422,6 +434,7 @@ enum RustGeneralName {
Uri(String),
Ip(String),
Rid(String),
OtherName(Asn1Object, Vec<u8>),
}
/// An extension that allows additional identities to be bound to the subject
@@ -494,12 +507,21 @@ impl SubjectAlternativeName {
/// Sets the `otherName` flag.
///
/// Not currently actually supported, always panics.
#[deprecated = "other_name is deprecated and always panics. Please file a bug if you have a use case for this."]
/// Not currently actually supported, always panics. Please use other_name2
#[deprecated = "other_name is deprecated and always panics. Please use other_name2."]
pub fn other_name(&mut self, _other_name: &str) -> &mut SubjectAlternativeName {
unimplemented!(
"This has not yet been adapted for the new internals. File a bug if you need this."
);
unimplemented!("This has not yet been adapted for the new internals. Use other_name2.");
}
/// Sets the `otherName` flag.
///
/// `content` must be a valid der encoded ASN1_TYPE
///
/// If you want to add just a ia5string use `other_name_ia5string`
pub fn other_name2(&mut self, oid: Asn1Object, content: &[u8]) -> &mut SubjectAlternativeName {
self.items
.push(RustGeneralName::OtherName(oid, content.into()));
self
}
/// Return a `SubjectAlternativeName` extension as an `X509Extension`.
@@ -514,6 +536,9 @@ impl SubjectAlternativeName {
GeneralName::new_ip(s.parse().map_err(|_| ErrorStack::get())?)?
}
RustGeneralName::Rid(s) => GeneralName::new_rid(Asn1Object::from_str(s)?)?,
RustGeneralName::OtherName(oid, content) => {
GeneralName::new_other_name(oid.clone(), content)?
}
};
stack.push(gn)?;
}
+317 -15
View File
@@ -24,8 +24,8 @@ use std::slice;
use std::str;
use crate::asn1::{
Asn1BitStringRef, Asn1IntegerRef, Asn1Object, Asn1ObjectRef, Asn1StringRef, Asn1TimeRef,
Asn1Type,
Asn1BitStringRef, Asn1Enumerated, Asn1IntegerRef, Asn1Object, Asn1ObjectRef,
Asn1OctetStringRef, Asn1StringRef, Asn1TimeRef, Asn1Type,
};
use crate::bio::MemBioSlice;
use crate::conf::ConfRef;
@@ -50,6 +50,16 @@ pub mod store;
#[cfg(test)]
mod tests;
/// A type of X509 extension.
///
/// # Safety
/// The value of NID and Output must match those in OpenSSL so that
/// `Output::from_ptr_opt(*_get_ext_d2i(*, NID, ...))` is valid.
pub unsafe trait ExtensionType {
const NID: Nid;
type Output: ForeignType;
}
foreign_type_and_impl_send_sync! {
type CType = ffi::X509_STORE_CTX;
fn drop = ffi::X509_STORE_CTX_free;
@@ -391,7 +401,10 @@ impl X509Ref {
/// Returns the hash of the certificates subject
#[corresponds(X509_subject_name_hash)]
pub fn subject_name_hash(&self) -> u32 {
unsafe { ffi::X509_subject_name_hash(self.as_ptr()) as u32 }
#[allow(clippy::unnecessary_cast)]
unsafe {
ffi::X509_subject_name_hash(self.as_ptr()) as u32
}
}
/// Returns this certificate's issuer name.
@@ -406,7 +419,10 @@ impl X509Ref {
/// Returns the hash of the certificates issuer
#[corresponds(X509_issuer_name_hash)]
pub fn issuer_name_hash(&self) -> u32 {
unsafe { ffi::X509_issuer_name_hash(self.as_ptr()) as u32 }
#[allow(clippy::unnecessary_cast)]
unsafe {
ffi::X509_issuer_name_hash(self.as_ptr()) as u32
}
}
/// Returns this certificate's subject alternative name entries, if they exist.
@@ -423,6 +439,20 @@ impl X509Ref {
}
}
/// Returns this certificate's CRL distribution points, if they exist.
#[corresponds(X509_get_ext_d2i)]
pub fn crl_distribution_points(&self) -> Option<Stack<DistPoint>> {
unsafe {
let stack = ffi::X509_get_ext_d2i(
self.as_ptr(),
ffi::NID_crl_distribution_points,
ptr::null_mut(),
ptr::null_mut(),
);
Stack::from_ptr_opt(stack as *mut _)
}
}
/// Returns this certificate's issuer alternative name entries, if they exist.
#[corresponds(X509_get_ext_d2i)]
pub fn issuer_alt_names(&self) -> Option<Stack<GeneralName>> {
@@ -453,6 +483,54 @@ impl X509Ref {
}
}
/// Retrieves the path length extension from a certificate, if it exists.
#[corresponds(X509_get_pathlen)]
#[cfg(ossl110)]
pub fn pathlen(&self) -> Option<u32> {
let v = unsafe { ffi::X509_get_pathlen(self.as_ptr()) };
u32::try_from(v).ok()
}
/// Returns this certificate's subject key id, if it exists.
#[corresponds(X509_get0_subject_key_id)]
#[cfg(ossl110)]
pub fn subject_key_id(&self) -> Option<&Asn1OctetStringRef> {
unsafe {
let data = ffi::X509_get0_subject_key_id(self.as_ptr());
Asn1OctetStringRef::from_const_ptr_opt(data)
}
}
/// Returns this certificate's authority key id, if it exists.
#[corresponds(X509_get0_authority_key_id)]
#[cfg(ossl110)]
pub fn authority_key_id(&self) -> Option<&Asn1OctetStringRef> {
unsafe {
let data = ffi::X509_get0_authority_key_id(self.as_ptr());
Asn1OctetStringRef::from_const_ptr_opt(data)
}
}
/// Returns this certificate's authority issuer name entries, if they exist.
#[corresponds(X509_get0_authority_issuer)]
#[cfg(ossl111d)]
pub fn authority_issuer(&self) -> Option<&StackRef<GeneralName>> {
unsafe {
let stack = ffi::X509_get0_authority_issuer(self.as_ptr());
StackRef::from_const_ptr_opt(stack)
}
}
/// Returns this certificate's authority serial number, if it exists.
#[corresponds(X509_get0_authority_serial)]
#[cfg(ossl111d)]
pub fn authority_serial(&self) -> Option<&Asn1IntegerRef> {
unsafe {
let r = ffi::X509_get0_authority_serial(self.as_ptr());
Asn1IntegerRef::from_const_ptr_opt(r)
}
}
#[corresponds(X509_get_pubkey)]
pub fn public_key(&self) -> Result<PKey<Public>, ErrorStack> {
unsafe {
@@ -548,6 +626,7 @@ impl X509Ref {
/// Note that `0` return value stands for version 1, `1` for version 2 and so on.
#[corresponds(X509_get_version)]
#[cfg(ossl110)]
#[allow(clippy::unnecessary_cast)]
pub fn version(&self) -> i32 {
unsafe { ffi::X509_get_version(self.as_ptr()) as i32 }
}
@@ -811,6 +890,13 @@ impl X509Extension {
/// mini-language that can read arbitrary files.
///
/// See the extension module for builder types which will construct certain common extensions.
///
/// This function is deprecated, `X509Extension::new_from_der` or the
/// types in `x509::extension` should be used in its place.
#[deprecated(
note = "Use x509::extension types or new_from_der instead",
since = "0.10.51"
)]
pub fn new(
conf: Option<&ConfRef>,
context: Option<&X509v3Context<'_>>,
@@ -856,6 +942,13 @@ impl X509Extension {
/// mini-language that can read arbitrary files.
///
/// See the extension module for builder types which will construct certain common extensions.
///
/// This function is deprecated, `X509Extension::new_from_der` or the
/// types in `x509::extension` should be used in its place.
#[deprecated(
note = "Use x509::extension types or new_from_der instead",
since = "0.10.51"
)]
pub fn new_nid(
conf: Option<&ConfRef>,
context: Option<&X509v3Context<'_>>,
@@ -890,6 +983,31 @@ impl X509Extension {
}
}
/// Constructs a new X509 extension value from its OID, whether it's
/// critical, and its DER contents.
///
/// The extent structure of the DER value will vary based on the
/// extension type, and can generally be found in the RFC defining the
/// extension.
///
/// For common extension types, there are Rust APIs provided in
/// `openssl::x509::extensions` which are more ergonomic.
pub fn new_from_der(
oid: &Asn1ObjectRef,
critical: bool,
der_contents: &Asn1OctetStringRef,
) -> Result<X509Extension, ErrorStack> {
unsafe {
cvt_p(ffi::X509_EXTENSION_create_by_OBJ(
ptr::null_mut(),
oid.as_ptr(),
critical as _,
der_contents.as_ptr(),
))
.map(X509Extension)
}
}
pub(crate) unsafe fn new_internal(
nid: Nid,
critical: bool,
@@ -905,6 +1023,10 @@ impl X509Extension {
///
/// This method modifies global state without locking and therefore is not thread safe
#[corresponds(X509V3_EXT_add_alias)]
#[deprecated(
note = "Use x509::extension types or new_from_der and then this is not necessary",
since = "0.10.51"
)]
pub unsafe fn add_alias(to: Nid, from: Nid) -> Result<(), ErrorStack> {
ffi::init();
cvt(ffi::X509V3_EXT_add_alias(to.as_raw(), from.as_raw())).map(|_| ())
@@ -955,13 +1077,13 @@ impl X509NameBuilder {
pub fn append_entry_by_text(&mut self, field: &str, value: &str) -> Result<(), ErrorStack> {
unsafe {
let field = CString::new(field).unwrap();
assert!(value.len() <= c_int::max_value() as usize);
assert!(value.len() <= crate::SLenType::max_value() as usize);
cvt(ffi::X509_NAME_add_entry_by_txt(
self.0.as_ptr(),
field.as_ptr() as *mut _,
ffi::MBSTRING_UTF8,
value.as_ptr(),
value.len() as c_int,
value.len() as crate::SLenType,
-1,
0,
))
@@ -982,13 +1104,13 @@ impl X509NameBuilder {
) -> Result<(), ErrorStack> {
unsafe {
let field = CString::new(field).unwrap();
assert!(value.len() <= c_int::max_value() as usize);
assert!(value.len() <= crate::SLenType::max_value() as usize);
cvt(ffi::X509_NAME_add_entry_by_txt(
self.0.as_ptr(),
field.as_ptr() as *mut _,
ty.as_raw(),
value.as_ptr(),
value.len() as c_int,
value.len() as crate::SLenType,
-1,
0,
))
@@ -1003,13 +1125,13 @@ impl X509NameBuilder {
/// [`X509_NAME_add_entry_by_NID`]: https://www.openssl.org/docs/manmaster/crypto/X509_NAME_add_entry_by_NID.html
pub fn append_entry_by_nid(&mut self, field: Nid, value: &str) -> Result<(), ErrorStack> {
unsafe {
assert!(value.len() <= c_int::max_value() as usize);
assert!(value.len() <= crate::SLenType::max_value() as usize);
cvt(ffi::X509_NAME_add_entry_by_NID(
self.0.as_ptr(),
field.as_raw(),
ffi::MBSTRING_UTF8,
value.as_ptr() as *mut _,
value.len() as c_int,
value.len() as crate::SLenType,
-1,
0,
))
@@ -1029,13 +1151,13 @@ impl X509NameBuilder {
ty: Asn1Type,
) -> Result<(), ErrorStack> {
unsafe {
assert!(value.len() <= c_int::max_value() as usize);
assert!(value.len() <= crate::SLenType::max_value() as usize);
cvt(ffi::X509_NAME_add_entry_by_NID(
self.0.as_ptr(),
field.as_raw(),
ty.as_raw(),
value.as_ptr() as *mut _,
value.len() as c_int,
value.len() as crate::SLenType,
-1,
0,
))
@@ -1428,6 +1550,7 @@ impl X509ReqRef {
/// This corresponds to [`X509_REQ_get_version`]
///
/// [`X509_REQ_get_version`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_get_version.html
#[allow(clippy::unnecessary_cast)]
pub fn version(&self) -> i32 {
unsafe { X509_REQ_get_version(self.as_ptr()) as i32 }
}
@@ -1481,13 +1604,41 @@ impl X509ReqRef {
}
}
/// The reason that a certificate was revoked.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct CrlReason(c_int);
#[allow(missing_docs)] // no need to document the constants
impl CrlReason {
pub const UNSPECIFIED: CrlReason = CrlReason(ffi::CRL_REASON_UNSPECIFIED);
pub const KEY_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_KEY_COMPROMISE);
pub const CA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_CA_COMPROMISE);
pub const AFFILIATION_CHANGED: CrlReason = CrlReason(ffi::CRL_REASON_AFFILIATION_CHANGED);
pub const SUPERSEDED: CrlReason = CrlReason(ffi::CRL_REASON_SUPERSEDED);
pub const CESSATION_OF_OPERATION: CrlReason = CrlReason(ffi::CRL_REASON_CESSATION_OF_OPERATION);
pub const CERTIFICATE_HOLD: CrlReason = CrlReason(ffi::CRL_REASON_CERTIFICATE_HOLD);
pub const REMOVE_FROM_CRL: CrlReason = CrlReason(ffi::CRL_REASON_REMOVE_FROM_CRL);
pub const PRIVILEGE_WITHDRAWN: CrlReason = CrlReason(ffi::CRL_REASON_PRIVILEGE_WITHDRAWN);
pub const AA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_AA_COMPROMISE);
/// Constructs an `CrlReason` from a raw OpenSSL value.
pub const fn from_raw(value: c_int) -> Self {
CrlReason(value)
}
/// Returns the raw OpenSSL value represented by this type.
pub const fn as_raw(&self) -> c_int {
self.0
}
}
foreign_type_and_impl_send_sync! {
type CType = ffi::X509_REVOKED;
fn drop = ffi::X509_REVOKED_free;
/// An `X509` certificate request.
/// An `X509` certificate revocation status.
pub struct X509Revoked;
/// Reference to `X509Crl`.
/// Reference to `X509Revoked`.
pub struct X509RevokedRef;
}
@@ -1513,6 +1664,13 @@ impl X509RevokedRef {
ffi::i2d_X509_REVOKED
}
/// Copies the entry to a new `X509Revoked`.
#[corresponds(X509_NAME_dup)]
#[cfg(any(boringssl, ossl110, libressl270))]
pub fn to_owned(&self) -> Result<X509Revoked, ErrorStack> {
unsafe { cvt_p(ffi::X509_REVOKED_dup(self.as_ptr())).map(|n| X509Revoked::from_ptr(n)) }
}
/// Get the date that the certificate was revoked
#[corresponds(X509_REVOKED_get0_revocationDate)]
pub fn revocation_date(&self) -> &Asn1TimeRef {
@@ -1532,13 +1690,67 @@ impl X509RevokedRef {
Asn1IntegerRef::from_ptr(r as *mut _)
}
}
/// Get the criticality and value of an extension.
///
/// This returns None if the extension is not present or occurs multiple times.
#[corresponds(X509_REVOKED_get_ext_d2i)]
pub fn extension<T: ExtensionType>(&self) -> Result<Option<(bool, T::Output)>, ErrorStack> {
let mut critical = -1;
let out = unsafe {
// SAFETY: self.as_ptr() is a valid pointer to an X509_REVOKED.
let ext = ffi::X509_REVOKED_get_ext_d2i(
self.as_ptr(),
T::NID.as_raw(),
&mut critical as *mut _,
ptr::null_mut(),
);
// SAFETY: Extensions's contract promises that the type returned by
// OpenSSL here is T::Output.
T::Output::from_ptr_opt(ext as *mut _)
};
match (critical, out) {
(0, Some(out)) => Ok(Some((false, out))),
(1, Some(out)) => Ok(Some((true, out))),
// -1 means the extension wasn't found, -2 means multiple were found.
(-1 | -2, _) => Ok(None),
// A critical value of 0 or 1 suggests success, but a null pointer
// was returned so something went wrong.
(0 | 1, None) => Err(ErrorStack::get()),
(c_int::MIN..=-2 | 2.., _) => panic!("OpenSSL should only return -2, -1, 0, or 1 for an extension's criticality but it returned {}", critical),
}
}
}
/// The CRL entry extension identifying the reason for revocation see [`CrlReason`],
/// this is as defined in RFC 5280 Section 5.3.1.
pub enum ReasonCode {}
// SAFETY: CertificateIssuer is defined to be a stack of GeneralName in the RFC
// and in OpenSSL.
unsafe impl ExtensionType for ReasonCode {
const NID: Nid = Nid::from_raw(ffi::NID_crl_reason);
type Output = Asn1Enumerated;
}
/// The CRL entry extension identifying the issuer of a certificate used in
/// indirect CRLs, as defined in RFC 5280 Section 5.3.3.
pub enum CertificateIssuer {}
// SAFETY: CertificateIssuer is defined to be a stack of GeneralName in the RFC
// and in OpenSSL.
unsafe impl ExtensionType for CertificateIssuer {
const NID: Nid = Nid::from_raw(ffi::NID_certificate_issuer);
type Output = Stack<GeneralName>;
}
foreign_type_and_impl_send_sync! {
type CType = ffi::X509_CRL;
fn drop = ffi::X509_CRL_free;
/// An `X509` certificate request.
/// An `X509` certificate revocation list.
pub struct X509Crl;
/// Reference to `X509Crl`.
pub struct X509CrlRef;
@@ -1842,6 +2054,37 @@ impl GeneralName {
Ok(GeneralName::from_ptr(gn))
}
}
pub(crate) fn new_other_name(
oid: Asn1Object,
value: &Vec<u8>,
) -> Result<GeneralName, ErrorStack> {
unsafe {
ffi::init();
let typ = cvt_p(ffi::d2i_ASN1_TYPE(
ptr::null_mut(),
&mut value.as_ptr().cast(),
value.len().try_into().unwrap(),
))?;
let gn = cvt_p(ffi::GENERAL_NAME_new())?;
(*gn).type_ = ffi::GEN_OTHERNAME;
if let Err(e) = cvt(ffi::GENERAL_NAME_set0_othername(
gn,
oid.as_ptr().cast(),
typ,
)) {
ffi::GENERAL_NAME_free(gn);
return Err(e);
}
mem::forget(oid);
Ok(GeneralName::from_ptr(gn))
}
}
}
impl GeneralNameRef {
@@ -1872,6 +2115,22 @@ impl GeneralNameRef {
self.ia5_string(ffi::GEN_EMAIL)
}
/// Returns the contents of this `GeneralName` if it is a `directoryName`.
pub fn directory_name(&self) -> Option<&X509NameRef> {
unsafe {
if (*self.as_ptr()).type_ != ffi::GEN_DIRNAME {
return None;
}
#[cfg(boringssl)]
let d = (*self.as_ptr()).d.ptr;
#[cfg(not(boringssl))]
let d = (*self.as_ptr()).d;
Some(X509NameRef::from_const_ptr(d as *const _))
}
}
/// Returns the contents of this `GeneralName` if it is a `dNSName`.
pub fn dnsname(&self) -> Option<&str> {
self.ia5_string(ffi::GEN_DNS)
@@ -1927,6 +2186,49 @@ impl Stackable for GeneralName {
type StackType = ffi::stack_st_GENERAL_NAME;
}
foreign_type_and_impl_send_sync! {
type CType = ffi::DIST_POINT;
fn drop = ffi::DIST_POINT_free;
/// A `X509` distribution point.
pub struct DistPoint;
/// Reference to `DistPoint`.
pub struct DistPointRef;
}
impl DistPointRef {
/// Returns the name of this distribution point if it exists
pub fn distpoint(&self) -> Option<&DistPointNameRef> {
unsafe { DistPointNameRef::from_const_ptr_opt((*self.as_ptr()).distpoint) }
}
}
foreign_type_and_impl_send_sync! {
type CType = ffi::DIST_POINT_NAME;
fn drop = ffi::DIST_POINT_NAME_free;
/// A `X509` distribution point.
pub struct DistPointName;
/// Reference to `DistPointName`.
pub struct DistPointNameRef;
}
impl DistPointNameRef {
/// Returns the contents of this DistPointName if it is a fullname.
pub fn fullname(&self) -> Option<&StackRef<GeneralName>> {
unsafe {
if (*self.as_ptr()).type_ != 0 {
return None;
}
StackRef::from_const_ptr_opt((*self.as_ptr()).name.fullname)
}
}
}
impl Stackable for DistPoint {
type StackType = ffi::stack_st_DIST_POINT;
}
foreign_type_and_impl_send_sync! {
type CType = ffi::ACCESS_DESCRIPTION;
fn drop = ffi::ACCESS_DESCRIPTION_free;
+2 -16
View File
@@ -42,13 +42,13 @@
//! ```
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use foreign_types::ForeignTypeRef;
use std::mem;
use crate::error::ErrorStack;
#[cfg(not(boringssl))]
use crate::ssl::SslFiletype;
use crate::stack::{Stack, StackRef};
use crate::stack::StackRef;
#[cfg(any(ossl102, libressl261))]
use crate::x509::verify::{X509VerifyFlags, X509VerifyParamRef};
use crate::x509::{X509Object, X509PurposeId, X509};
@@ -260,24 +260,10 @@ foreign_type_and_impl_send_sync! {
impl X509StoreRef {
/// Get a reference to the cache of certificates in this store.
///
/// This method is deprecated. It is **unsound** and will be removed in a
/// future version of rust-openssl. `X509StoreRef::all_certificates`
/// should be used instead.
#[deprecated(
note = "This method is unsound, and will be removed in a future version of rust-openssl. X509StoreRef::all_certificates should be used instead."
)]
#[corresponds(X509_STORE_get0_objects)]
pub fn objects(&self) -> &StackRef<X509Object> {
unsafe { StackRef::from_ptr(X509_STORE_get0_objects(self.as_ptr())) }
}
/// Returns a stack of all the certificates in this store.
#[corresponds(X509_STORE_get1_all_certs)]
#[cfg(ossl300)]
pub fn all_certificates(&self) -> Stack<X509> {
unsafe { Stack::from_ptr(ffi::X509_STORE_get1_all_certs(self.as_ptr())) }
}
}
cfg_if! {
+171 -13
View File
@@ -1,6 +1,6 @@
use std::cmp::Ordering;
use crate::asn1::Asn1Time;
use crate::asn1::{Asn1Object, Asn1OctetString, Asn1Time};
use crate::bn::{BigNum, MsbOption};
use crate::hash::MessageDigest;
use crate::nid::Nid;
@@ -18,19 +18,24 @@ use crate::x509::store::X509Lookup;
use crate::x509::store::X509StoreBuilder;
#[cfg(any(ossl102, libressl261))]
use crate::x509::verify::{X509VerifyFlags, X509VerifyParam};
#[cfg(ossl110)]
use crate::x509::X509Builder;
#[cfg(ossl102)]
use crate::x509::X509PurposeId;
#[cfg(any(ossl102, libressl261))]
use crate::x509::X509PurposeRef;
#[cfg(ossl110)]
use crate::x509::{CrlReason, X509Builder};
use crate::x509::{
CrlStatus, X509Crl, X509Extension, X509Name, X509Req, X509StoreContext, X509VerifyResult, X509,
};
#[cfg(ossl110)]
use foreign_types::ForeignType;
use hex::{self, FromHex};
#[cfg(any(ossl102, libressl261))]
use libc::time_t;
use super::{CertificateIssuer, ReasonCode};
fn pkey() -> PKey<Private> {
let rsa = Rsa::generate(2048).unwrap();
PKey::from_rsa(rsa).unwrap()
@@ -166,6 +171,70 @@ fn test_subject_alt_name() {
assert_eq!(Some("http://www.example.com"), subject_alt_names[4].uri());
}
#[test]
#[cfg(ossl110)]
fn test_retrieve_pathlen() {
let cert = include_bytes!("../../test/root-ca.pem");
let cert = X509::from_pem(cert).unwrap();
assert_eq!(cert.pathlen(), None);
let cert = include_bytes!("../../test/intermediate-ca.pem");
let cert = X509::from_pem(cert).unwrap();
assert_eq!(cert.pathlen(), Some(0));
let cert = include_bytes!("../../test/alt_name_cert.pem");
let cert = X509::from_pem(cert).unwrap();
assert_eq!(cert.pathlen(), None);
}
#[test]
#[cfg(ossl110)]
fn test_subject_key_id() {
let cert = include_bytes!("../../test/certv3.pem");
let cert = X509::from_pem(cert).unwrap();
let subject_key_id = cert.subject_key_id().unwrap();
assert_eq!(
subject_key_id.as_slice(),
&b"\xB6\x73\x2F\x61\xA5\x4B\xA1\xEF\x48\x2C\x15\xB1\x9F\xF3\xDC\x34\x2F\xBC\xAC\x30"[..]
);
}
#[test]
#[cfg(ossl110)]
fn test_authority_key_id() {
let cert = include_bytes!("../../test/certv3.pem");
let cert = X509::from_pem(cert).unwrap();
let authority_key_id = cert.authority_key_id().unwrap();
assert_eq!(
authority_key_id.as_slice(),
&b"\x6C\xD3\xA5\x03\xAB\x0D\x5F\x2C\xC9\x8D\x8A\x9C\x88\xA7\x88\x77\xB8\x37\xFD\x9A"[..]
);
}
#[test]
#[cfg(ossl111d)]
fn test_authority_issuer_and_serial() {
let cert = include_bytes!("../../test/authority_key_identifier.pem");
let cert = X509::from_pem(cert).unwrap();
let authority_issuer = cert.authority_issuer().unwrap();
assert_eq!(1, authority_issuer.len());
let dn = authority_issuer[0].directory_name().unwrap();
let mut o = dn.entries_by_nid(Nid::ORGANIZATIONNAME);
let o = o.next().unwrap().data().as_utf8().unwrap();
assert_eq!(o.as_bytes(), b"PyCA");
let mut cn = dn.entries_by_nid(Nid::COMMONNAME);
let cn = cn.next().unwrap().data().as_utf8().unwrap();
assert_eq!(cn.as_bytes(), b"cryptography.io");
let authority_serial = cert.authority_serial().unwrap();
let serial = authority_serial.to_bn().unwrap();
let expected = BigNum::from_u32(3).unwrap();
assert_eq!(serial, expected);
}
#[test]
fn test_subject_alt_name_iter() {
let cert = include_bytes!("../../test/alt_name_cert.pem");
@@ -288,6 +357,8 @@ fn x509_builder() {
}
#[test]
// This tests `X509Extension::new`, even though its deprecated.
#[allow(deprecated)]
fn x509_extension_new() {
assert!(X509Extension::new(None, None, "crlDistributionPoints", "section").is_err());
assert!(X509Extension::new(None, None, "proxyCertInfo", "").is_err());
@@ -295,6 +366,20 @@ fn x509_extension_new() {
assert!(X509Extension::new(None, None, "subjectAltName", "dirName:section").is_err());
}
#[test]
fn x509_extension_new_from_der() {
let ext = X509Extension::new_from_der(
&Asn1Object::from_str("2.5.29.19").unwrap(),
true,
&Asn1OctetString::new_from_bytes(b"\x30\x03\x01\x01\xff").unwrap(),
)
.unwrap();
assert_eq!(
ext.to_der().unwrap(),
b"0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff"
);
}
#[test]
fn x509_extension_to_der() {
let builder = X509::builder().unwrap();
@@ -611,6 +696,42 @@ fn test_load_crl() {
);
}
#[test]
fn test_crl_entry_extensions() {
let crl = include_bytes!("../../test/entry_extensions.crl");
let crl = X509Crl::from_pem(crl).unwrap();
let revoked_certs = crl.get_revoked().unwrap();
let entry = &revoked_certs[0];
let (critical, issuer) = entry
.extension::<CertificateIssuer>()
.unwrap()
.expect("Certificate issuer extension should be present");
assert!(critical, "Certificate issuer extension is critical");
assert_eq!(issuer.len(), 1, "Certificate issuer should have one entry");
let issuer = issuer[0]
.directory_name()
.expect("Issuer should be a directory name");
assert_eq!(
format!("{:?}", issuer),
r#"[countryName = "GB", commonName = "Test CA"]"#
);
// reason_code can't be inspected without ossl110
#[allow(unused_variables)]
let (critical, reason_code) = entry
.extension::<ReasonCode>()
.unwrap()
.expect("Reason code extension should be present");
assert!(!critical, "Reason code extension is not critical");
#[cfg(ossl110)]
assert_eq!(
CrlReason::KEY_COMPROMISE,
CrlReason::from_raw(reason_code.get_i64().unwrap() as ffi::c_int)
);
}
#[test]
fn test_save_subject_der() {
let cert = include_bytes!("../../test/cert.pem");
@@ -987,17 +1108,54 @@ fn ipv6_as_subject_alternative_name_is_formatted_in_debug() {
]);
}
#[cfg(ossl110)]
#[test]
#[cfg(ossl300)]
fn test_store_all_certificates() {
let cert = include_bytes!("../../test/cert.pem");
fn other_name_as_subject_alternative_name() {
let oid = Asn1Object::from_str("1.3.6.1.5.5.7.8.11").unwrap();
// this is the hex representation of "test" encoded as a ia5string
let content = [0x16, 0x04, 0x74, 0x65, 0x73, 0x74];
let mut builder = X509Builder::new().unwrap();
let san = SubjectAlternativeName::new()
.other_name2(oid, &content)
.build(&builder.x509v3_context(None, None))
.unwrap();
builder.append_extension(san).unwrap();
let cert = builder.build();
let general_name = cert
.subject_alt_names()
.into_iter()
.flatten()
.next()
.unwrap();
unsafe {
assert_eq!((*general_name.as_ptr()).type_, 0);
}
}
#[test]
fn test_dist_point() {
let cert = include_bytes!("../../test/certv3.pem");
let cert = X509::from_pem(cert).unwrap();
let store = {
let mut b = X509StoreBuilder::new().unwrap();
b.add_cert(cert).unwrap();
b.build()
};
let dps = cert.crl_distribution_points().unwrap();
let dp = dps.get(0).unwrap();
let dp_nm = dp.distpoint().unwrap();
let dp_gns = dp_nm.fullname().unwrap();
let dp_gn = dp_gns.get(0).unwrap();
assert_eq!(dp_gn.uri().unwrap(), "http://example.com/crl.pem");
assert_eq!(store.all_certificates().len(), 1);
}
let dp = dps.get(1).unwrap();
let dp_nm = dp.distpoint().unwrap();
let dp_gns = dp_nm.fullname().unwrap();
let dp_gn = dp_gns.get(0).unwrap();
assert_eq!(dp_gn.uri().unwrap(), "http://example.com/crl2.pem");
assert!(dps.get(2).is_none())
}
#[test]
fn test_dist_point_null() {
let cert = include_bytes!("../../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
assert!(cert.crl_distribution_points().is_none());
}
+19
View File
@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDIjCCAgqgAwIBAgIBAzANBgkqhkiG9w0BAQUFADApMQ0wCwYDVQQKDARQeUNB
MRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wHhcNMTUwNTAzMDk0OTU2WhcNMTYw
NTAyMDk0OTU2WjApMQ0wCwYDVQQKDARQeUNBMRgwFgYDVQQDDA9jcnlwdG9ncmFw
aHkuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCadi1UZioxdnP
ajqlRZHeKsSxvXXhgrWvlt91P3gV0dBThRFhJsLOhjNLz6PO6KeRbjz9GhTA2hdk
xtIpXrjvTv9dEJ1/k0xebsHWgFC43aTlgekw0U4cMwMe5NGeeg1tfzbJwldIN+cK
vabc08ADlkmM6DMnUArkzA2yii0DErRFMSIGrkDr6E9puord3h6Mh8Jfnc3TDAq8
Qo1DI2XM7oFSWNfecQ9KbIC5wzzT+7Shoyz7QmCk/XhRzt8Xcfc3yAXIwazvLf8b
YP1auaSG11a5E+w6onj91h8UHKKOXu+rdq5YYPZ+qUYpxA7ZJ/VAGadMulYbXaO8
Syi39HTpAgMBAAGjVTBTMFEGA1UdIwRKMEiAFDlFPso9Yh3qhkn2WqtAt6RwmPHs
oS2kKzApMQ0wCwYDVQQKDARQeUNBMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW+C
AQMwDQYJKoZIhvcNAQEFBQADggEBAFbZYy6aZJUK/f7nJx2Rs/ht6hMbM32/RoXZ
JGbYapNVqVu/vymcfc/se3FHS5OVmPsnRlo/FIKDn/r5DGl73Sn/FvDJiLJZFucT
msyYuHZ+ZRYWzWmN2fcB3cfxj0s3qps6f5OoCOqoINOSe4HRGlw4X9keZSD+3xAt
vHNwQdlPC7zWbPdrzLT+FqR0e/O81vFJJS6drHJWqPcR3NQVtZw+UF7A/HKwbfeL
Nu2zj6165hzOi9HUxa2/mPr/eLUUV1sTzXp2+TFjt3rVCjW1XnpMLdwNBHzjpyAB
dTOX3iw0+BPy3s2jtnCW1PLpc74kvSTaBwhg74sq39EXfIKax00=
-----END CERTIFICATE-----
+23
View File
@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIIDwTCCAqmgAwIBAgIUDeCGNunyJfBd3U/qUtmCcvbMyZwwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMzAxMjMxMzMzNTJaFw0zMzAx
MjAxMzMzNTJaMFoxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEzARBgNVBAMMCmZvb2Jh
ci5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo9CWMRLMXo1CF
/iORh9B4NhtJF/8tR9PlG95sNvyWuQQ/8jfev+8zErplxfLkt0pJqcoiZG8g9NU0
kU6o5T+/1QgZclCAoZaS0Jqxmoo2Yk/1Qsj16pnMBc10uSDk6V9aJSX1vKwONVNS
wiHA1MhX+i7Wf7/K0niq+k7hOkhleFkWgZtUq41gXh1VfOugka7UktYnk9mrBbAM
jmaloZNn2pMMAQxVg4ThiLm3zvuWqvXASWzUZc7IAd1GbN4AtDuhs252eqE9E4iT
Hk7F14wAS1JWqv666hReGHrmZJGx0xQTM9vPD1HN5t2U3KTfhO/mTlAUWVyg9tCt
OzboKgs1AgMBAAGjgZMwgZAwTgYDVR0fBEcwRTAgoB6gHIYaaHR0cDovL2V4YW1w
bGUuY29tL2NybC5wZW0wIaAfoB2GG2h0dHA6Ly9leGFtcGxlLmNvbS9jcmwyLnBl
bTAdBgNVHQ4EFgQUtnMvYaVLoe9ILBWxn/PcNC+8rDAwHwYDVR0jBBgwFoAUbNOl
A6sNXyzJjYqciKeId7g3/ZowDQYJKoZIhvcNAQELBQADggEBAJZyk6Eo4p3JIyOt
7t6ET3K18BKvlRilze+zrGkaQYvKRsP6YzbZWgcIq59hy5VeFCX5O2WP91CPG3MU
I9eRiih66/ry3G4I8QEdpRKnn0N5unbGjb5qPT5wXrhU4IO+vn3sGZGM4uIM1/3K
N/bOh9CTsu9YqrdHSGeDyNzCy/XZ/j5bP4aNm31ZDNCZDFsbjr3/yTLcpHPL0UP3
mCX8D16BDu1Nep+wK9VRuOEw6Z9tlT/VjTImzoOUoJO/o2UHfSHahX+n2aC5OpI6
BdhaFBuJ1vn+yTWf3zIjhWUdp9TlzgRyFiyetP2FcKwremVVGdDq/Y6dfXaq8CA1
6Fr9KTY=
-----END CERTIFICATE-----
+1
View File
@@ -0,0 +1 @@
crlDistributionPoints=URI:http://example.com/crl.pem,URI:http://example.com/crl2.pem
+10
View File
@@ -0,0 +1,10 @@
-----BEGIN X509 CRL-----
MIIBXDCCAQICAQEwCgYIKoZIzj0EAwIwETEPMA0GA1UEAwwGQ1JMIENBFw0yMzAz
MjgwOTQ5MThaFw0yMzA0MDQwOTUwMDdaMIGAMH4CFE+Y95/1pOqa6c9fUEJ8c04k
xu2PFw0yMzAzMjgwOTQ3MzNaMFcwLwYDVR0dAQH/BCUwI6QhMB8xCzAJBgNVBAYT
AkdCMRAwDgYDVQQDDAdUZXN0IENBMAoGA1UdFQQDCgEBMBgGA1UdGAQRGA8yMDIz
MDMyODA5NDQ0MFqgPTA7MB8GA1UdIwQYMBaAFNX1GZ0RWuC+4gz1wuy5H32T2W+R
MAoGA1UdFAQDAgEUMAwGA1UdHAQFMAOEAf8wCgYIKoZIzj0EAwIDSAAwRQIgbl7x
W+WVAb+zlvKcJLmHVuC+gbqR4jqwGIHHgQl2J8kCIQCo/sAF5sDqy/cL+fbzBeUe
YoY2h6lIkj9ENwU8ZCt03w==
-----END X509 CRL-----
+14 -2
View File
@@ -56,6 +56,7 @@ fn main() {
.header("openssl/bio.h")
.header("openssl/x509v3.h")
.header("openssl/safestack.h")
.header("openssl/cmac.h")
.header("openssl/hmac.h")
.header("openssl/obj_mac.h")
.header("openssl/ssl.h")
@@ -68,6 +69,10 @@ fn main() {
.header("openssl/evp.h")
.header("openssl/x509_vfy.h");
if libressl_version.is_some() {
cfg.header("openssl/poly1305.h");
}
if let Some(version) = openssl_version {
cfg.header("openssl/cms.h");
if version >= 0x10100000 {
@@ -110,7 +115,11 @@ fn main() {
|| s.starts_with("CRYPTO_EX_")
});
cfg.skip_struct(|s| {
s == "ProbeResult" || s == "X509_OBJECT_data" // inline union
s == "ProbeResult" ||
s == "X509_OBJECT_data" || // inline union
s == "DIST_POINT_NAME_st_anon_union" || // inline union
s == "PKCS7_data" ||
s == "ASN1_TYPE_value"
});
cfg.skip_fn(move |s| {
s == "CRYPTO_memcmp" || // uses volatile
@@ -130,7 +139,10 @@ fn main() {
cfg.skip_field_type(|s, field| {
(s == "EVP_PKEY" && field == "pkey") || // union
(s == "GENERAL_NAME" && field == "d") || // union
(s == "X509_OBJECT" && field == "data") // union
(s == "DIST_POINT_NAME" && field == "name") || // union
(s == "X509_OBJECT" && field == "data") || // union
(s == "PKCS7" && field == "d") || // union
(s == "ASN1_TYPE" && field == "value") // union
});
cfg.skip_signededness(|s| {
s.ends_with("_cb")