Snap for 9550355 from 2c94df4e4919c129bc5ed99ad012659395a2257d to sdk-release
Change-Id: I8640c3ef14b4548251b8ee7c626bd75bd5d07239
diff --git a/.cargo/config.toml b/.cargo/config.toml
new file mode 100644
index 0000000..e2b197d
--- /dev/null
+++ b/.cargo/config.toml
@@ -0,0 +1,2 @@
+[patch.crates-io]
+bssl-ffi = { package = "bssl-sys", version = "0.1.0", path = "../../../boringssl/build/rust", optional=true }
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..1b8def3
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,6 @@
+{
+ "git": {
+ "sha1": "7db5cc72d326360ffa62398201635effedb885c6"
+ },
+ "path_in_vcs": "openssl"
+}
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index a93e396..4e9011c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,5 @@
-// This file is generated by cargo2android.py --config cargo2android.json.
+// This file is generated by cargo2android.py --config ./cargo2android.json.
+// Do not modify this file as changes will be overridden on upgrade.
// WARNING! This crate has a change in dependency structure that is not yet
// reflected on crates.io. This means that the automated update tool will
@@ -48,40 +49,24 @@
name: "libopenssl",
host_supported: true,
crate_name: "openssl",
- srcs: ["openssl/src/lib.rs"],
- vendor_available: true,
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.10.43",
+ srcs: ["src/lib.rs"],
edition: "2018",
- cfgs: [
- "boringssl",
- ],
- features: [
- "boringssl",
- ],
- proc_macros: [
- "libopenssl_macros",
- ],
+ features: ["unstable_boringssl"],
+ cfgs: ["boringssl", "soong"],
rustlibs: [
"libbitflags",
- "libbssl_ffi",
"libcfg_if",
+ "libbssl_ffi",
"libforeign_types",
"liblibc",
"libonce_cell",
],
+ proc_macros: ["libopenssl_macros"],
apex_available: [
"//apex_available:platform",
"com.android.virt",
],
-}
-
-rust_proc_macro {
- name: "libopenssl_macros",
- crate_name: "openssl_macros",
- srcs: ["openssl-macros/src/lib.rs"],
- edition: "2018",
- rustlibs: [
- "libquote",
- "libsyn",
- "libproc_macro2",
- ],
+ vendor_available: true,
}
diff --git a/openssl/CHANGELOG.md b/CHANGELOG.md
similarity index 90%
rename from openssl/CHANGELOG.md
rename to CHANGELOG.md
index 3604cae..3156498 100644
--- a/openssl/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,73 @@
## [Unreleased]
+## [v0.10.43] - 2022-11-23
+
+### Added
+
+* Added `Nid::BRAINPOOL_P256R1`, `Nid::BRAINPOOL_P384R1`, `Nid::BRAINPOOL_P512R1`.
+* Added `BigNumRef::copy_from_slice`.
+* Added `Cipher` constructors for Camellia, CAST5, and IDEA ciphers.
+* Added `DsaSig`.
+* Added `X509StoreBuilderRef::set_param`.
+* Added `X509VerifyParam::new`, `X509VerifyParamRef::set_time`, and `X509VerifyParamRef::set_depth`.
+
+## [v0.10.42] - 2022-09-26
+
+### Added
+
+* Added `SslRef::psk_identity_hint` and `SslRef::psk_identity`.
+* Added SHA-3 constants to `Nid`.
+* Added `SslOptions::PRIORITIZE_CHACHA`.
+* Added `X509ReqRef::to_text`.
+* Added `MdCtxRef::size`.
+* Added `X509NameRef::try_cmp`.
+* Added `MdCtxRef::reset`.
+* Added experimental, unstable support for BoringSSL.
+
+### Fixed
+
+* Fixed `MdCtxRef::digest_verify_init` to support `PKey`s with only public components.
+
+## [v0.10.41] - 2022-06-09
+
+### Fixed
+
+* Fixed a use-after-free in `Error::function` and `Error::file` with OpenSSL 3.x.
+
+### Added
+
+* Added `MessageDigest::block_size` and `MdRef::block_size`.
+* Implemented `Ord` and `Eq` for `X509` and `X509Ref`.
+* Added `X509Extension::add_alias`.
+* Added SM4 support.
+* Added `EcGroup::from_components` `EcGropuRef::set_generator`, and `EcPointRef::set_affine_coordinates_gfp`.
+
+## [v0.10.40] - 2022-05-04
+
+### Fixed
+
+* Fixed the openssl-sys dependency version.
+
+## [v0.10.39] - 2022-05-02
+
+### Deprecated
+
+* Deprecated `SslContextBuilder::set_tmp_ecdh_callback` and `SslRef::set_tmp_ecdh_callback`.
+
+### Added
+
+* Added `SslRef::extms_support`.
+* Added `Nid::create`.
+* Added `CipherCtx`, which exposes a more direct interface to `EVP_CIPHER_CTX`.
+* Added `PkeyCtx`, which exposes a more direct interface to `EVP_PKEY_CTX`.
+* Added `MdCtx`, which exposes a more direct interface to `EVP_MD_CTX`.
+* Added `Pkcs12Builder::mac_md`.
+* Added `Provider`.
+* Added `X509Ref::issuer_name_hash`.
+* Added `Decrypter::set_rsa_oaep_label`.
+* Added `X509Ref::to_text`.
+
## [v0.10.38] - 2021-10-31
### Added
@@ -574,7 +641,12 @@
Look at the [release tags] for information about older releases.
-[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.38...master
+[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.43...master
+[v0.10.43]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.42...openssl-v0.10.43
+[v0.10.42]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.41...openssl-v0.10.42
+[v0.10.41]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.40...openssl-v0.10.41
+[v0.10.40]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.39...openssl-v0.10.40
+[v0.10.39]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.38...openssl-v0.10.39
[v0.10.38]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.37...openssl-v0.10.38
[v0.10.37]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.36...openssl-v0.10.37
[v0.10.36]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.35...openssl-v0.10.36
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..2ab7922
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,463 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "0.7.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "bindgen"
+version = "0.60.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6"
+dependencies = [
+ "bitflags",
+ "cexpr",
+ "clang-sys",
+ "clap",
+ "env_logger",
+ "lazy_static",
+ "lazycell",
+ "log",
+ "peeking_take_while",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "rustc-hash",
+ "shlex",
+ "which",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bssl-sys"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "312d12393c060384f2e6ed14c7b4be37b3dd90249857485613c1a91b9a1abb5c"
+
+[[package]]
+name = "cc"
+version = "1.0.77"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
+
+[[package]]
+name = "cexpr"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clang-sys"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3"
+dependencies = [
+ "glob",
+ "libc",
+ "libloading",
+]
+
+[[package]]
+name = "clap"
+version = "3.2.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
+dependencies = [
+ "atty",
+ "bitflags",
+ "clap_lex",
+ "indexmap",
+ "strsim",
+ "termcolor",
+ "textwrap",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
+dependencies = [
+ "os_str_bytes",
+]
+
+[[package]]
+name = "either"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+
+[[package]]
+name = "env_logger"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hex"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
+
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
+name = "indexmap"
+version = "1.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "lazycell"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
+
+[[package]]
+name = "libc"
+version = "0.2.137"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
+
+[[package]]
+name = "libloading"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
+dependencies = [
+ "cfg-if",
+ "winapi",
+]
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "nom"
+version = "7.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
+
+[[package]]
+name = "openssl"
+version = "0.10.43"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "foreign-types",
+ "hex",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "openssl-src"
+version = "111.24.0+1.1.1s"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3498f259dab01178c6228c6b00dcef0ed2a2d5e20d648c017861227773ea4abd"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07d5c8cb6e57b3a3612064d7b18b117912b4ce70955c2504d4b741c9e244b132"
+dependencies = [
+ "autocfg",
+ "bindgen",
+ "bssl-sys",
+ "cc",
+ "libc",
+ "openssl-src",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "os_str_bytes"
+version = "6.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
+
+[[package]]
+name = "peeking_take_while"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "regex"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "shlex"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "syn"
+version = "1.0.103"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "which"
+version = "4.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b"
+dependencies = [
+ "either",
+ "libc",
+ "once_cell",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/Cargo.toml b/Cargo.toml
index 63e983a..bd166a8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,11 +1,65 @@
-[workspace]
-members = [
- "openssl",
- "openssl-errors",
- "openssl-macros",
- "openssl-sys",
- "systest",
-]
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
-[patch.crates-io]
-bindgen = { git = "https://github.com/daviddrysdale/rust-bindgen", branch = "allowlist-file" }
+[package]
+edition = "2018"
+name = "openssl"
+version = "0.10.43"
+authors = ["Steven Fackler <sfackler@gmail.com>"]
+description = "OpenSSL bindings"
+readme = "README.md"
+keywords = [
+ "crypto",
+ "tls",
+ "ssl",
+ "dtls",
+]
+categories = [
+ "cryptography",
+ "api-bindings",
+]
+license = "Apache-2.0"
+repository = "https://github.com/sfackler/rust-openssl"
+
+[dependencies.bitflags]
+version = "1.0"
+
+[dependencies.cfg-if]
+version = "1.0"
+
+[dependencies.ffi]
+version = "0.9.78"
+package = "openssl-sys"
+
+[dependencies.foreign-types]
+version = "0.3.1"
+
+[dependencies.libc]
+version = "0.2"
+
+[dependencies.once_cell]
+version = "1.5.2"
+
+[dependencies.openssl-macros]
+version = "0.1.0"
+
+[dev-dependencies.hex]
+version = "0.3"
+
+[features]
+bindgen = ["ffi/bindgen"]
+default = []
+unstable_boringssl = ["ffi/unstable_boringssl"]
+v101 = []
+v102 = []
+v110 = []
+v111 = []
+vendored = ["ffi/vendored"]
diff --git a/openssl/Cargo.toml b/Cargo.toml.orig
similarity index 65%
rename from openssl/Cargo.toml
rename to Cargo.toml.orig
index 4bb8db4..b6204e4 100644
--- a/openssl/Cargo.toml
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "openssl"
-version = "0.10.38"
+version = "0.10.43"
authors = ["Steven Fackler <sfackler@gmail.com>"]
license = "Apache-2.0"
description = "OpenSSL bindings"
@@ -19,8 +19,8 @@
vendored = ['ffi/vendored']
bindgen = ['ffi/bindgen']
-boringssl = ["bssl-ffi"]
-default = ["ffi"]
+unstable_boringssl = ["ffi/unstable_boringssl"]
+default = []
[dependencies]
bitflags = "1.0"
@@ -29,9 +29,8 @@
libc = "0.2"
once_cell = "1.5.2"
-openssl-macros = { path = "../openssl-macros" }
-bssl-ffi = { package = "bssl-sys", version = "0.1.0", path = "../../boringssl/build/rust", optional=true }
-ffi = { package = "openssl-sys", version = "0.9.69", path = "../openssl-sys", optional = true}
+openssl-macros = { version = "0.1.0", path = "../openssl-macros" }
+ffi = { package = "openssl-sys", version = "0.9.78", path = "../openssl-sys" }
[dev-dependencies]
hex = "0.3"
diff --git a/METADATA b/METADATA
index 5ac4e62..72a81ff 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/openssl
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
name: "openssl"
description: "OpenSSL bindings"
third_party {
@@ -6,14 +10,14 @@
value: "https://crates.io/crates/openssl"
}
url {
- type: GIT
- value: "https://github.com/sfackler/rust-openssl"
+ type: ARCHIVE
+ value: "https://static.crates.io/crates/openssl/openssl-0.10.43.crate"
}
- version: "973936042c31a868d0ade4f3bcbd25d317015c05"
+ version: "0.10.43"
license_type: NOTICE
last_upgrade_date {
year: 2022
- month: 4
- day: 11
+ month: 12
+ day: 1
}
}
diff --git a/README.android b/README.android
new file mode 100644
index 0000000..6499cfe
--- /dev/null
+++ b/README.android
@@ -0,0 +1,31 @@
+## Steps for updating this crate
+
+1. In order to run cargo2android, for this crate, the BoringSSL rust bindings first needs to be
+ built. Copy `googletest` to `boringssl`, which is needed to build the rust bindings
+
+ ```
+ $ cp -r external/googletest/googletest external/boringssl/src/third_party/
+ ```
+2. Build the rust bindings (More information at
+ https://boringssl.googlesource.com/boringssl/+/HEAD/BUILDING.md)
+
+ ```
+ $ cd external/boringssl
+ $ mkdir build && cd build
+ $ cmake .. -DRUST_BINDINGS=x86_64-unknown-linux-gnu
+ $ make
+ ```
+3. Run `tools/external_updater/updater.sh update rust/crates/openssl`. Cargo errors causing the
+ command to fail are expected (since the boringSSL crate is outside of the `openssl` directory,
+ redshell is not able to access it).
+4. The repository should now be in a `tmp_auto_upgrade` branch, and the Android.bp will contain
+ some error message.
+5. Run cargo2android
+
+ ```
+ $ cargo2android.py --config ./cargo2android.json
+ ```
+6. Clean up the changes in external/boringssl repository, and double check that the resulting
+ Android.bp builds correctly by running `m libopenssl`.
+7. Commit the changes and upload the CL.
+8. `external/rust/crates/openssl-macros` should also be updated at the same time.
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 9cce328..d2182d6 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,49 +1,23 @@
// Generated by update_crate_tests.py for tests that depend on this crate.
{
- "presubmit": [
+ "imports": [
{
- "name": "apkdmverity.test"
+ "path": "packages/modules/Virtualization/apkdmverity"
},
{
- "name": "authfs_device_test_src_lib"
+ "path": "packages/modules/Virtualization/authfs"
},
{
- "name": "libapkverify.integration_test"
+ "path": "packages/modules/Virtualization/avmd"
},
{
- "name": "libapkverify.test"
+ "path": "packages/modules/Virtualization/libs/apkverify"
},
{
- "name": "libidsig.test"
+ "path": "packages/modules/Virtualization/microdroid_manager"
},
{
- "name": "microdroid_manager_test"
- },
- {
- "name": "virtualizationservice_device_test"
- }
- ],
- "presubmit-rust": [
- {
- "name": "apkdmverity.test"
- },
- {
- "name": "authfs_device_test_src_lib"
- },
- {
- "name": "libapkverify.integration_test"
- },
- {
- "name": "libapkverify.test"
- },
- {
- "name": "libidsig.test"
- },
- {
- "name": "microdroid_manager_test"
- },
- {
- "name": "virtualizationservice_device_test"
+ "path": "packages/modules/Virtualization/virtualizationmanager"
}
]
}
diff --git a/THIRD_PARTY b/THIRD_PARTY
deleted file mode 100644
index aa6920c..0000000
--- a/THIRD_PARTY
+++ /dev/null
@@ -1,148 +0,0 @@
-rust-openssl contains code from OpenSSL, under the following license:
-
-OpenSSL License
- ---------------
-
-/* ====================================================================
- * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
- Original SSLeay License
- -----------------------
-
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-===============================================================================
-
-openssl-sys
-
-Copyright (c) 2014 Alex Crichton
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/openssl/build.rs b/build.rs
similarity index 83%
rename from openssl/build.rs
rename to build.rs
index 8104f07..fc64922 100644
--- a/openssl/build.rs
+++ b/build.rs
@@ -7,7 +7,7 @@
println!("cargo:rustc-cfg=libressl");
}
- if env::var("CARGO_FEATURE_BORINGSSL").is_ok() {
+ if env::var("CARGO_FEATURE_UNSTABLE_BORINGSSL").is_ok() {
println!("cargo:rustc-cfg=boringssl");
return;
}
@@ -51,6 +51,10 @@
if let Ok(version) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") {
let version = u64::from_str_radix(&version, 16).unwrap();
+ if version >= 0x2_05_01_00_0 {
+ println!("cargo:rustc-cfg=libressl251");
+ }
+
if version >= 0x2_06_01_00_0 {
println!("cargo:rustc-cfg=libressl261");
}
@@ -86,5 +90,17 @@
if version >= 0x3_04_00_00_0 {
println!("cargo:rustc-cfg=libressl340");
}
+
+ if version >= 0x3_05_00_00_0 {
+ println!("cargo:rustc-cfg=libressl350");
+ }
+
+ if version >= 0x3_06_00_00_0 {
+ println!("cargo:rustc-cfg=libressl360");
+ }
+
+ if version >= 0x3_06_01_00_0 {
+ println!("cargo:rustc-cfg=libressl361");
+ }
}
}
diff --git a/cargo2android.json b/cargo2android.json
index 41450f8..4caae30 100644
--- a/cargo2android.json
+++ b/cargo2android.json
@@ -4,7 +4,8 @@
"com.android.virt"
],
"device": true,
- "features": "boringssl",
+ "features": "unstable_boringssl",
"run": true,
- "vendor-available": true
+ "vendor-available": true,
+ "patch": "patches/Android.bp.diff"
}
diff --git a/openssl/examples/mk_certs.rs b/examples/mk_certs.rs
similarity index 100%
rename from openssl/examples/mk_certs.rs
rename to examples/mk_certs.rs
diff --git a/openssl-macros/Cargo.toml b/openssl-macros/Cargo.toml
deleted file mode 100644
index 684e31e..0000000
--- a/openssl-macros/Cargo.toml
+++ /dev/null
@@ -1,12 +0,0 @@
-[package]
-name = "openssl-macros"
-version = "0.1.0"
-edition = "2018"
-
-[lib]
-proc-macro = true
-
-[dependencies]
-proc-macro2 = "1"
-quote = "1"
-syn = { version = "1", features = ["full"] }
diff --git a/openssl-macros/src/lib.rs b/openssl-macros/src/lib.rs
deleted file mode 100644
index c007409..0000000
--- a/openssl-macros/src/lib.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-use proc_macro::TokenStream;
-use proc_macro2::Ident;
-use quote::quote;
-use syn::{parse_macro_input, ItemFn};
-
-#[proc_macro_attribute]
-pub fn corresponds(attr: TokenStream, item: TokenStream) -> TokenStream {
- let function = parse_macro_input!(attr as Ident);
- let item = parse_macro_input!(item as ItemFn);
-
- let function = function.to_string();
- let line = format!(
- "This corresponds to [`{0}`](https://www.openssl.org/docs/manmaster/man3/{0}.html).",
- function
- );
-
- let attrs = item.attrs;
- let vis = item.vis;
- let sig = item.sig;
- let block = item.block;
-
- let out = quote! {
- #(#attrs)*
- #[doc = ""]
- #[doc = #line]
- #[doc(alias = #function)]
- #vis #sig #block
- };
- out.into()
-}
diff --git a/openssl/LICENSE b/openssl/LICENSE
deleted file mode 100644
index f259067..0000000
--- a/openssl/LICENSE
+++ /dev/null
@@ -1,15 +0,0 @@
-Copyright 2011-2017 Google Inc.
- 2013 Jack Lloyd
- 2013-2014 Steven Fackler
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/openssl/README.md b/openssl/README.md
deleted file mode 120000
index 32d46ee..0000000
--- a/openssl/README.md
+++ /dev/null
@@ -1 +0,0 @@
-../README.md
\ No newline at end of file
diff --git a/openssl/src/conf.rs b/openssl/src/conf.rs
deleted file mode 100644
index e21f069..0000000
--- a/openssl/src/conf.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-//! Interface for processing OpenSSL configuration files.
-
-use crate::cvt_p;
-use crate::error::ErrorStack;
-use openssl_macros::corresponds;
-
-#[cfg(not(boringssl))]
-pub struct ConfMethod(*mut ffi::CONF_METHOD);
-
-#[cfg(not(boringssl))]
-impl ConfMethod {
- /// Retrieve handle to the default OpenSSL configuration file processing function.
- #[corresponds(NCONF_default)]
- pub fn default() -> ConfMethod {
- unsafe {
- ffi::init();
- // `NCONF` stands for "New Conf", as described in crypto/conf/conf_lib.c. This is
- // a newer API than the "CONF classic" functions.
- ConfMethod(ffi::NCONF_default())
- }
- }
-
- /// Construct from raw pointer.
- ///
- /// # Safety
- ///
- /// The caller must ensure that the pointer is valid.
- pub unsafe fn from_ptr(ptr: *mut ffi::CONF_METHOD) -> ConfMethod {
- ConfMethod(ptr)
- }
-
- /// Convert to raw pointer.
- pub fn as_ptr(&self) -> *mut ffi::CONF_METHOD {
- self.0
- }
-}
-
-foreign_type_and_impl_send_sync! {
- type CType = ffi::CONF;
- fn drop = ffi::NCONF_free;
-
- pub struct Conf;
- pub struct ConfRef;
-}
-
-#[cfg(not(boringssl))]
-impl Conf {
- /// Create a configuration parser.
- ///
- /// # Examples
- ///
- /// ```
- /// use openssl::conf::{Conf, ConfMethod};
- ///
- /// let conf = Conf::new(ConfMethod::default());
- /// ```
- #[corresponds(NCONF_new)]
- pub fn new(method: ConfMethod) -> Result<Conf, ErrorStack> {
- unsafe { cvt_p(ffi::NCONF_new(method.as_ptr())).map(Conf) }
- }
-}
diff --git a/patches/Android.bp.diff b/patches/Android.bp.diff
new file mode 100644
index 0000000..9f7b012
--- /dev/null
+++ b/patches/Android.bp.diff
@@ -0,0 +1,18 @@
+diff --git a/Android.bp b/Android.bp
+index 2282c66..4e9011c 100644
+--- a/Android.bp
++++ b/Android.bp
+@@ -54,11 +54,11 @@ rust_library {
+ srcs: ["src/lib.rs"],
+ edition: "2018",
+ features: ["unstable_boringssl"],
+- cfgs: ["boringssl"],
++ cfgs: ["boringssl", "soong"],
+ rustlibs: [
+ "libbitflags",
+ "libcfg_if",
+- "libopenssl_sys",
++ "libbssl_ffi",
+ "libforeign_types",
+ "liblibc",
+ "libonce_cell",
diff --git a/patches/local_changes.diff b/patches/local_changes.diff
new file mode 100644
index 0000000..06702fa
--- /dev/null
+++ b/patches/local_changes.diff
@@ -0,0 +1,525 @@
+diff --git a/.cargo/config.toml b/.cargo/config.toml
+new file mode 100644
+index 0000000..e2b197d
+--- /dev/null
++++ b/.cargo/config.toml
+@@ -0,0 +1,2 @@
++[patch.crates-io]
++bssl-ffi = { package = "bssl-sys", version = "0.1.0", path = "../../../boringssl/build/rust", optional=true }
+diff --git a/src/cipher.rs b/src/cipher.rs
+index ab5f49d..84a8265 100644
+--- a/src/cipher.rs
++++ b/src/cipher.rs
+@@ -208,6 +208,7 @@ impl Cipher {
+ unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb1() as *mut _) }
+ }
+
++ #[cfg(not(boringssl))]
+ pub fn aes_192_cfb128() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb128() as *mut _) }
+ }
+@@ -253,6 +254,7 @@ impl Cipher {
+ unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb1() as *mut _) }
+ }
+
++ #[cfg(not(boringssl))]
+ pub fn aes_256_cfb128() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb128() as *mut _) }
+ }
+@@ -282,11 +284,13 @@ impl Cipher {
+ }
+
+ #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
++ #[cfg(not(boringssl))]
+ pub fn bf_cbc() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_bf_cbc() as *mut _) }
+ }
+
+ #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
++ #[cfg(not(boringssl))]
+ pub fn bf_ecb() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_bf_ecb() as *mut _) }
+ }
+diff --git a/src/ec.rs b/src/ec.rs
+index a6a6dc9..88dcaaf 100644
+--- a/src/ec.rs
++++ b/src/ec.rs
+@@ -908,6 +908,26 @@ impl EcKey<Private> {
+ EcKey<Private>,
+ ffi::d2i_ECPrivateKey
+ }
++
++ /// Decodes a DER-encoded elliptic curve private key structure for the specified curve.
++ #[corresponds(EC_KEY_parse_private_key)]
++ #[cfg(boringssl)]
++ pub fn private_key_from_der_for_group(
++ der: &[u8],
++ group: &EcGroupRef,
++ ) -> Result<EcKey<Private>, ErrorStack> {
++ unsafe {
++ let mut cbs = ffi::CBS {
++ data: der.as_ptr(),
++ len: der.len(),
++ };
++ cvt_p(ffi::EC_KEY_parse_private_key(
++ &mut cbs as *mut ffi::CBS,
++ group.as_ptr(),
++ ))
++ .map(|p| EcKey::from_ptr(p))
++ }
++ }
+ }
+
+ impl<T> Clone for EcKey<T> {
+diff --git a/src/encrypt.rs b/src/encrypt.rs
+index 3cb10fc..34a9eb8 100644
+--- a/src/encrypt.rs
++++ b/src/encrypt.rs
+@@ -148,7 +148,7 @@ impl<'a> Encrypter<'a> {
+ /// This corresponds to [`EVP_PKEY_CTX_set_rsa_oaep_md`].
+ ///
+ /// [`EVP_PKEY_CTX_set_rsa_oaep_md`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set_rsa_oaep_md.html
+- #[cfg(any(ossl102, libressl310))]
++ #[cfg(any(ossl102, libressl310, boringssl))]
+ pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
+ unsafe {
+ cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
+@@ -352,7 +352,7 @@ impl<'a> Decrypter<'a> {
+ /// This corresponds to [`EVP_PKEY_CTX_set_rsa_oaep_md`].
+ ///
+ /// [`EVP_PKEY_CTX_set_rsa_oaep_md`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set_rsa_oaep_md.html
+- #[cfg(any(ossl102, libressl310))]
++ #[cfg(any(ossl102, libressl310, boringssl))]
+ pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
+ unsafe {
+ cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
+diff --git a/src/hkdf.rs b/src/hkdf.rs
+new file mode 100644
+index 0000000..cc7e5b3
+--- /dev/null
++++ b/src/hkdf.rs
+@@ -0,0 +1,89 @@
++use crate::cvt;
++use crate::error::ErrorStack;
++use crate::md::MdRef;
++use foreign_types::ForeignTypeRef;
++use openssl_macros::corresponds;
++
++/// Computes HKDF (as specified by RFC 5869).
++///
++/// HKDF is an Extract-and-Expand algorithm. It does not do any key stretching,
++/// and as such, is not suited to be used alone to generate a key from a
++/// password.
++#[corresponds(HKDF)]
++#[inline]
++pub fn hkdf(
++ out_key: &mut [u8],
++ md: &MdRef,
++ secret: &[u8],
++ salt: &[u8],
++ info: &[u8],
++) -> Result<(), ErrorStack> {
++ unsafe {
++ cvt(ffi::HKDF(
++ out_key.as_mut_ptr(),
++ out_key.len(),
++ md.as_ptr(),
++ secret.as_ptr(),
++ secret.len(),
++ salt.as_ptr(),
++ salt.len(),
++ info.as_ptr(),
++ info.len(),
++ ))?;
++ }
++
++ Ok(())
++}
++
++/// Computes a HKDF PRK (as specified by RFC 5869).
++///
++/// WARNING: This function orders the inputs differently from RFC 5869
++/// specification. Double-check which parameter is the secret/IKM and which is
++/// the salt when using.
++#[corresponds(HKDF_extract)]
++#[inline]
++pub fn hkdf_extract<'a>(
++ out_key: &'a mut [u8],
++ md: &MdRef,
++ secret: &[u8],
++ salt: &[u8],
++) -> Result<&'a [u8], ErrorStack> {
++ let mut out_len = out_key.len();
++ unsafe {
++ cvt(ffi::HKDF_extract(
++ out_key.as_mut_ptr(),
++ &mut out_len,
++ md.as_ptr(),
++ secret.as_ptr(),
++ secret.len(),
++ salt.as_ptr(),
++ salt.len(),
++ ))?;
++ }
++
++ Ok(&out_key[..out_len])
++}
++
++/// Computes a HKDF OKM (as specified by RFC 5869).
++#[corresponds(HKDF_expand)]
++#[inline]
++pub fn hkdf_expand(
++ out_key: &mut [u8],
++ md: &MdRef,
++ prk: &[u8],
++ info: &[u8],
++) -> Result<(), ErrorStack> {
++ unsafe {
++ cvt(ffi::HKDF_expand(
++ out_key.as_mut_ptr(),
++ out_key.len(),
++ md.as_ptr(),
++ prk.as_ptr(),
++ prk.len(),
++ info.as_ptr(),
++ info.len(),
++ ))?;
++ }
++
++ Ok(())
++}
+diff --git a/src/hmac.rs b/src/hmac.rs
+new file mode 100644
+index 0000000..601ae01
+--- /dev/null
++++ b/src/hmac.rs
+@@ -0,0 +1,68 @@
++use crate::cvt_p;
++use crate::error::ErrorStack;
++use crate::md::MdRef;
++use foreign_types::ForeignTypeRef;
++use openssl_macros::corresponds;
++use libc::{c_void, c_uint};
++use std::convert::TryFrom;
++
++/// Computes the HMAC as a one-shot operation.
++///
++/// Calculates the HMAC of data, using the given |key|
++/// and hash function |md|, and returns the result re-using the space from
++/// buffer |out|. On entry, |out| must contain at least |EVP_MD_size| bytes
++/// of space. The actual length of the result is used to resize the returned
++/// slice. An output size of |EVP_MAX_MD_SIZE| will always be large enough.
++/// It returns a resized |out| or ErrorStack on error.
++#[corresponds(HMAC)]
++#[inline]
++pub fn hmac<'a>(
++ md: &MdRef,
++ key: &[u8],
++ data: &[u8],
++ out: &'a mut [u8]
++) -> Result<&'a [u8], ErrorStack> {
++ let mut out_len = c_uint::try_from(out.len()).unwrap();
++ unsafe {
++ cvt_p(ffi::HMAC(
++ md.as_ptr(),
++ key.as_ptr() as *const c_void,
++ key.len(),
++ data.as_ptr(),
++ data.len(),
++ out.as_mut_ptr(),
++ &mut out_len
++ ))?;
++ }
++ Ok(&out[..out_len as usize])
++}
++
++#[cfg(test)]
++mod tests {
++ use super::*;
++ use crate::md::Md;
++ use crate::memcmp;
++
++ const SHA_256_DIGEST_SIZE:usize = 32;
++
++ #[test]
++ fn hmac_sha256_test() {
++ let expected_hmac = [0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0xb, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x0, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7];
++ let mut out: [u8; SHA_256_DIGEST_SIZE] = [0; SHA_256_DIGEST_SIZE];
++ let key:[u8; 20] = [0x0b; 20];
++ let data = b"Hi There";
++ let hmac_result = hmac(Md::sha256(), &key, data, &mut out).expect("Couldn't calculate sha256 hmac");
++ expect!(memcmp::eq(&hmac_result, &expected_hmac));
++ }
++
++ #[test]
++ fn hmac_sha256_test_big_buffer() {
++ let expected_hmac = [0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0xb, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x0, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7];
++ let mut out: [u8; 100] = [0; 100];
++ let key:[u8;20] = [0x0b; 20];
++ let data = b"Hi There";
++ let hmac_result = hmac(Md::sha256(), &key, data, &mut out).expect("Couldn't calculate sha256 hmac");
++ expect_eq!(hmac_result.len(), SHA_256_DIGEST_SIZE);
++ expect!(memcmp::eq(&hmac_result, &expected_hmac));
++ }
++}
+diff --git a/src/lib.rs b/src/lib.rs
+index 891651e..48b7ed1 100644
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -120,6 +120,9 @@
+ #![doc(html_root_url = "https://docs.rs/openssl/0.10")]
+ #![warn(rust_2018_idioms)]
+
++#[cfg(all(soong, boringssl))]
++extern crate bssl_ffi as ffi;
++
+ #[doc(inline)]
+ pub use ffi::init;
+
+@@ -155,6 +158,10 @@ pub mod ex_data;
+ #[cfg(not(any(libressl, ossl300)))]
+ pub mod fips;
+ pub mod hash;
++#[cfg(boringssl)]
++pub mod hkdf;
++#[cfg(boringssl)]
++pub mod hmac;
+ #[cfg(ossl300)]
+ pub mod lib_ctx;
+ pub mod md;
+diff --git a/src/pkey.rs b/src/pkey.rs
+index 7d438eb..7eaf068 100644
+--- a/src/pkey.rs
++++ b/src/pkey.rs
+@@ -47,7 +47,7 @@ use crate::dh::Dh;
+ use crate::dsa::Dsa;
+ use crate::ec::EcKey;
+ use crate::error::ErrorStack;
+-#[cfg(ossl110)]
++#[cfg(any(boringssl, ossl110))]
+ use crate::pkey_ctx::PkeyCtx;
+ use crate::rsa::Rsa;
+ use crate::symm::Cipher;
+@@ -89,11 +89,11 @@ impl Id {
+ #[cfg(ossl110)]
+ pub const HKDF: Id = Id(ffi::EVP_PKEY_HKDF);
+
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ pub const ED25519: Id = Id(ffi::EVP_PKEY_ED25519);
+ #[cfg(ossl111)]
+ pub const ED448: Id = Id(ffi::EVP_PKEY_ED448);
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ pub const X25519: Id = Id(ffi::EVP_PKEY_X25519);
+ #[cfg(ossl111)]
+ pub const X448: Id = Id(ffi::EVP_PKEY_X448);
+@@ -243,7 +243,7 @@ where
+ /// This function only works for algorithms that support raw public keys.
+ /// Currently this is: [`Id::X25519`], [`Id::ED25519`], [`Id::X448`] or [`Id::ED448`].
+ #[corresponds(EVP_PKEY_get_raw_public_key)]
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ pub fn raw_public_key(&self) -> Result<Vec<u8>, ErrorStack> {
+ unsafe {
+ let mut len = 0;
+@@ -294,7 +294,7 @@ where
+ /// This function only works for algorithms that support raw private keys.
+ /// Currently this is: [`Id::HMAC`], [`Id::X25519`], [`Id::ED25519`], [`Id::X448`] or [`Id::ED448`].
+ #[corresponds(EVP_PKEY_get_raw_private_key)]
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ pub fn raw_private_key(&self) -> Result<Vec<u8>, ErrorStack> {
+ unsafe {
+ let mut len = 0;
+@@ -475,7 +475,7 @@ impl PKey<Private> {
+ ctx.keygen()
+ }
+
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ fn generate_eddsa(id: Id) -> Result<PKey<Private>, ErrorStack> {
+ let mut ctx = PkeyCtx::new_id(id)?;
+ ctx.keygen_init()?;
+@@ -505,7 +505,7 @@ impl PKey<Private> {
+ /// assert_eq!(secret.len(), 32);
+ /// # Ok(()) }
+ /// ```
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ pub fn generate_x25519() -> Result<PKey<Private>, ErrorStack> {
+ PKey::generate_eddsa(Id::X25519)
+ }
+@@ -559,7 +559,7 @@ impl PKey<Private> {
+ /// assert_eq!(signature.len(), 64);
+ /// # Ok(()) }
+ /// ```
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ pub fn generate_ed25519() -> Result<PKey<Private>, ErrorStack> {
+ PKey::generate_eddsa(Id::ED25519)
+ }
+@@ -709,7 +709,7 @@ impl PKey<Private> {
+ ///
+ /// Algorithm types that support raw private keys are HMAC, X25519, ED25519, X448 or ED448
+ #[corresponds(EVP_PKEY_new_raw_private_key)]
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ pub fn private_key_from_raw_bytes(
+ bytes: &[u8],
+ key_type: Id,
+@@ -750,7 +750,7 @@ impl PKey<Public> {
+ ///
+ /// Algorithm types that support raw public keys are X25519, ED25519, X448 or ED448
+ #[corresponds(EVP_PKEY_new_raw_public_key)]
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ pub fn public_key_from_raw_bytes(
+ bytes: &[u8],
+ key_type: Id,
+diff --git a/src/sign.rs b/src/sign.rs
+index 457ff12..4de8ad0 100644
+--- a/src/sign.rs
++++ b/src/sign.rs
+@@ -290,7 +290,7 @@ impl<'a> Signer<'a> {
+ self.len_intern()
+ }
+
+- #[cfg(not(ossl111))]
++ #[cfg(not(any(boringssl, ossl111)))]
+ fn len_intern(&self) -> Result<usize, ErrorStack> {
+ unsafe {
+ let mut len = 0;
+@@ -303,7 +303,7 @@ impl<'a> Signer<'a> {
+ }
+ }
+
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ fn len_intern(&self) -> Result<usize, ErrorStack> {
+ unsafe {
+ let mut len = 0;
+@@ -360,7 +360,7 @@ impl<'a> Signer<'a> {
+ /// OpenSSL documentation at [`EVP_DigestSign`].
+ ///
+ /// [`EVP_DigestSign`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestSign.html
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ pub fn sign_oneshot(
+ &mut self,
+ sig_buf: &mut [u8],
+@@ -382,7 +382,7 @@ impl<'a> Signer<'a> {
+ /// Returns the signature.
+ ///
+ /// This is a simple convenience wrapper over `len` and `sign_oneshot`.
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ pub fn sign_oneshot_to_vec(&mut self, data_buf: &[u8]) -> Result<Vec<u8>, ErrorStack> {
+ let mut sig_buf = vec![0; self.len()?];
+ let len = self.sign_oneshot(&mut sig_buf, data_buf)?;
+@@ -594,7 +594,7 @@ impl<'a> Verifier<'a> {
+ /// OpenSSL documentation at [`EVP_DigestVerify`].
+ ///
+ /// [`EVP_DigestVerify`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestVerify.html
+- #[cfg(ossl111)]
++ #[cfg(any(boringssl, ossl111))]
+ pub fn verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> {
+ unsafe {
+ let r = ffi::EVP_DigestVerify(
+diff --git a/src/symm.rs b/src/symm.rs
+index c75bbc0..beff5fc 100644
+--- a/src/symm.rs
++++ b/src/symm.rs
+@@ -119,6 +119,7 @@ impl Cipher {
+ unsafe { Cipher(ffi::EVP_aes_128_cfb1()) }
+ }
+
++ #[cfg(not(boringssl))]
+ pub fn aes_128_cfb128() -> Cipher {
+ unsafe { Cipher(ffi::EVP_aes_128_cfb128()) }
+ }
+@@ -164,6 +165,7 @@ impl Cipher {
+ unsafe { Cipher(ffi::EVP_aes_192_cfb1()) }
+ }
+
++ #[cfg(not(boringssl))]
+ pub fn aes_192_cfb128() -> Cipher {
+ unsafe { Cipher(ffi::EVP_aes_192_cfb128()) }
+ }
+@@ -214,6 +216,7 @@ impl Cipher {
+ unsafe { Cipher(ffi::EVP_aes_256_cfb1()) }
+ }
+
++ #[cfg(not(boringssl))]
+ pub fn aes_256_cfb128() -> Cipher {
+ unsafe { Cipher(ffi::EVP_aes_256_cfb128()) }
+ }
+@@ -242,12 +245,12 @@ impl Cipher {
+ unsafe { Cipher(ffi::EVP_aes_256_ocb()) }
+ }
+
+- #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
++ #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))]
+ pub fn bf_cbc() -> Cipher {
+ unsafe { Cipher(ffi::EVP_bf_cbc()) }
+ }
+
+- #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
++ #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))]
+ pub fn bf_ecb() -> Cipher {
+ unsafe { Cipher(ffi::EVP_bf_ecb()) }
+ }
+diff --git a/src/x509/mod.rs b/src/x509/mod.rs
+index edd54aa..45f2467 100644
+--- a/src/x509/mod.rs
++++ b/src/x509/mod.rs
+@@ -353,6 +353,19 @@ impl X509Builder {
+ unsafe { cvt(ffi::X509_sign(self.0.as_ptr(), key.as_ptr(), hash.as_ptr())).map(|_| ()) }
+ }
+
++ /// Signs the certificate with a private key but without a digest.
++ ///
++ /// This is the only way to sign with Ed25519 keys as BoringSSL doesn't support the null
++ /// message digest.
++ #[cfg(boringssl)]
++ #[corresponds(X509_sign)]
++ pub fn sign_without_digest<T>(&mut self, key: &PKeyRef<T>) -> Result<(), ErrorStack>
++ where
++ T: HasPrivate,
++ {
++ unsafe { cvt(ffi::X509_sign(self.0.as_ptr(), key.as_ptr(), ptr::null())).map(|_| ()) }
++ }
++
+ /// Consumes the builder, returning the certificate.
+ pub fn build(self) -> X509 {
+ self.0
+@@ -1260,6 +1273,29 @@ impl X509ReqBuilder {
+ }
+ }
+
++ /// Sign the request using a private key without a digest.
++ ///
++ /// This is the only way to sign with Ed25519 keys as BoringSSL doesn't support the null
++ /// message digest.
++ ///
++ /// This corresponds to [`X509_REQ_sign`].
++ ///
++ /// [`X509_REQ_sign`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_sign.html
++ #[cfg(boringssl)]
++ pub fn sign_without_digest<T>(&mut self, key: &PKeyRef<T>) -> Result<(), ErrorStack>
++ where
++ T: HasPrivate,
++ {
++ unsafe {
++ cvt(ffi::X509_REQ_sign(
++ self.0.as_ptr(),
++ key.as_ptr(),
++ ptr::null(),
++ ))
++ .map(|_| ())
++ }
++ }
++
+ /// Returns the `X509Req`.
+ pub fn build(self) -> X509Req {
+ self.0
diff --git a/openssl/src/aes.rs b/src/aes.rs
similarity index 92%
rename from openssl/src/aes.rs
rename to src/aes.rs
index a0447e8..440dd05 100644
--- a/openssl/src/aes.rs
+++ b/src/aes.rs
@@ -21,22 +21,27 @@
//! [`Cipher`]: ../symm/struct.Cipher.html
//!
//! # Examples
-//!
-//! ## AES IGE
-//! ```rust
-//! use openssl::aes::{AesKey, aes_ige};
-//! use openssl::symm::Mode;
-//!
-//! let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
-//! let plaintext = b"\x12\x34\x56\x78\x90\x12\x34\x56\x12\x34\x56\x78\x90\x12\x34\x56";
-//! let mut iv = *b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\
-//! \x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
-//!
-//! let key = AesKey::new_encrypt(key).unwrap();
-//! let mut output = [0u8; 16];
-//! aes_ige(plaintext, &mut output, &key, &mut iv, Mode::Encrypt);
-//! assert_eq!(output, *b"\xa6\xad\x97\x4d\x5c\xea\x1d\x36\xd2\xf3\x67\x98\x09\x07\xed\x32");
-//! ```
+
+#![cfg_attr(
+ not(boringssl),
+ doc = r#"\
+## AES IGE
+```rust
+use openssl::aes::{AesKey, aes_ige};
+use openssl::symm::Mode;
+
+let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
+let plaintext = b"\x12\x34\x56\x78\x90\x12\x34\x56\x12\x34\x56\x78\x90\x12\x34\x56";
+let mut iv = *b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\
+ \x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
+
+ let key = AesKey::new_encrypt(key).unwrap();
+ let mut output = [0u8; 16];
+ aes_ige(plaintext, &mut output, &key, &mut iv, Mode::Encrypt);
+ assert_eq!(output, *b"\xa6\xad\x97\x4d\x5c\xea\x1d\x36\xd2\xf3\x67\x98\x09\x07\xed\x32");
+```"#
+)]
+
//!
//! ## Key wrapping
//! ```rust
@@ -60,6 +65,7 @@
use std::mem::MaybeUninit;
use std::ptr;
+#[cfg(not(boringssl))]
use crate::symm::Mode;
use openssl_macros::corresponds;
@@ -256,6 +262,7 @@
use hex::FromHex;
use super::*;
+ #[cfg(not(boringssl))]
use crate::symm::Mode;
// From https://www.mgp25.com/AESIGE/
diff --git a/openssl/src/asn1.rs b/src/asn1.rs
similarity index 100%
rename from openssl/src/asn1.rs
rename to src/asn1.rs
diff --git a/openssl/src/base64.rs b/src/base64.rs
similarity index 96%
rename from openssl/src/base64.rs
rename to src/base64.rs
index 75822d6..bfa8cbc 100644
--- a/openssl/src/base64.rs
+++ b/src/base64.rs
@@ -1,13 +1,8 @@
//! Base64 encoding support.
-use crate::cvt_n;
use crate::error::ErrorStack;
+use crate::{cvt_n, LenType};
+use libc::c_int;
use openssl_macros::corresponds;
-use libc::{c_int, size_t};
-
-#[cfg(not(boringssl))]
-type LenType = c_int;
-#[cfg(boringssl)]
-type LenType = size_t;
/// Encodes a slice of bytes to a base64 string.
///
diff --git a/openssl/src/bio.rs b/src/bio.rs
similarity index 98%
rename from openssl/src/bio.rs
rename to src/bio.rs
index 717ccd0..6a72552 100644
--- a/openssl/src/bio.rs
+++ b/src/bio.rs
@@ -67,6 +67,7 @@
}
}
+ #[cfg(not(boringssl))]
pub unsafe fn from_ptr(bio: *mut ffi::BIO) -> MemBio {
MemBio(bio)
}
diff --git a/openssl/src/bn.rs b/src/bn.rs
similarity index 96%
rename from openssl/src/bn.rs
rename to src/bn.rs
index c15ab53..68c94f9 100644
--- a/openssl/src/bn.rs
+++ b/src/bn.rs
@@ -33,11 +33,11 @@
use crate::asn1::Asn1Integer;
use crate::error::ErrorStack;
use crate::string::OpensslString;
-use crate::{cvt, cvt_n, cvt_p};
+use crate::{cvt, cvt_n, cvt_p, LenType};
use openssl_macros::corresponds;
cfg_if! {
- if #[cfg(ossl110)] {
+ if #[cfg(any(ossl110, libressl350))] {
use ffi::{
BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536,
BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
@@ -809,7 +809,7 @@
/// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
/// ```
#[corresponds(BN_bn2binpad)]
- #[cfg(ossl110)]
+ #[cfg(any(boringssl, ossl110))]
pub fn to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack> {
let mut v = Vec::with_capacity(pad_to as usize);
unsafe {
@@ -841,7 +841,7 @@
/// # use openssl::bn::BigNum;
/// let s = -BigNum::from_u32(0x99ff).unwrap();
///
- /// assert_eq!(&**s.to_hex_str().unwrap(), "-99FF");
+ /// assert_eq!(s.to_hex_str().unwrap().to_uppercase(), "-99FF");
/// ```
#[corresponds(BN_bn2hex)]
pub fn to_hex_str(&self) -> Result<OpensslString, ErrorStack> {
@@ -1070,13 +1070,38 @@
pub fn from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> {
unsafe {
ffi::init();
- assert!(n.len() <= c_int::max_value() as usize);
- #[cfg(boringssl)]
- let len = n.len();
- #[cfg(not(boringssl))]
- let len = n.len() as c_int;
+ assert!(n.len() <= LenType::max_value() as usize);
- cvt_p(ffi::BN_bin2bn(n.as_ptr(), len, ptr::null_mut())).map(|p| BigNum::from_ptr(p))
+ cvt_p(ffi::BN_bin2bn(
+ n.as_ptr(),
+ n.len() as LenType,
+ ptr::null_mut(),
+ ))
+ .map(|p| BigNum::from_ptr(p))
+ }
+ }
+
+ /// Copies data from a slice overwriting what was in the BigNum.
+ ///
+ /// This function can be used to copy data from a slice to a
+ /// [secure BigNum][`BigNum::new_secure`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use openssl::bn::BigNum;
+ /// let mut bignum = BigNum::new().unwrap();
+ /// bignum.copy_from_slice(&[0x12, 0x00, 0x34]).unwrap();
+ ///
+ /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
+ /// ```
+ #[corresponds(BN_bin2bn)]
+ pub fn copy_from_slice(&mut self, n: &[u8]) -> Result<(), ErrorStack> {
+ unsafe {
+ assert!(n.len() <= LenType::max_value() as usize);
+
+ cvt_p(ffi::BN_bin2bn(n.as_ptr(), n.len() as LenType, self.0))?;
+ Ok(())
}
}
}
diff --git a/openssl/src/cipher.rs b/src/cipher.rs
similarity index 80%
rename from openssl/src/cipher.rs
rename to src/cipher.rs
index 1801c44..84a8265 100644
--- a/openssl/src/cipher.rs
+++ b/src/cipher.rs
@@ -332,6 +332,56 @@
unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) }
}
+ #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
+ pub fn camellia128_cfb128() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cfb128() as *mut _) }
+ }
+
+ #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
+ pub fn camellia128_ecb() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ecb() as *mut _) }
+ }
+
+ #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
+ pub fn camellia192_cfb128() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cfb128() as *mut _) }
+ }
+
+ #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
+ pub fn camellia192_ecb() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ecb() as *mut _) }
+ }
+
+ #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
+ pub fn camellia256_cfb128() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cfb128() as *mut _) }
+ }
+
+ #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
+ pub fn camellia256_ecb() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ecb() as *mut _) }
+ }
+
+ #[cfg(not(boringssl))]
+ pub fn cast5_cfb64() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cfb64() as *mut _) }
+ }
+
+ #[cfg(not(boringssl))]
+ pub fn cast5_ecb() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ecb() as *mut _) }
+ }
+
+ #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_IDEA")))]
+ pub fn idea_cfb64() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_idea_cfb64() as *mut _) }
+ }
+
+ #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_IDEA")))]
+ pub fn idea_ecb() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_idea_ecb() as *mut _) }
+ }
+
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
pub fn chacha20() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_chacha20() as *mut _) }
@@ -365,6 +415,31 @@
pub fn seed_ofb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_seed_ofb() as *mut _) }
}
+
+ #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
+ pub fn sm4_ecb() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ecb() as *mut _) }
+ }
+
+ #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
+ pub fn sm4_cbc() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cbc() as *mut _) }
+ }
+
+ #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
+ pub fn sm4_ctr() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ctr() as *mut _) }
+ }
+
+ #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
+ pub fn sm4_cfb128() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cfb128() as *mut _) }
+ }
+
+ #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
+ pub fn sm4_ofb() -> &'static CipherRef {
+ unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ofb() as *mut _) }
+ }
}
/// A reference to a [`Cipher`].
diff --git a/openssl/src/cipher_ctx.rs b/src/cipher_ctx.rs
similarity index 98%
rename from openssl/src/cipher_ctx.rs
rename to src/cipher_ctx.rs
index 3f32ec2..8e01711 100644
--- a/openssl/src/cipher_ctx.rs
+++ b/src/cipher_ctx.rs
@@ -52,13 +52,14 @@
use crate::cipher::CipherRef;
use crate::error::ErrorStack;
+#[cfg(not(boringssl))]
use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef};
use crate::{cvt, cvt_p};
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
-use std::convert::{TryInto, TryFrom};
use libc::{c_int, c_uchar};
use openssl_macros::corresponds;
+use std::convert::{TryFrom, TryInto};
use std::ptr;
cfg_if! {
@@ -338,10 +339,11 @@
pub fn set_key_length(&mut self, len: usize) -> Result<(), ErrorStack> {
self.assert_cipher();
- let len = c_int::try_from(len).unwrap();
-
unsafe {
- cvt(ffi::EVP_CIPHER_CTX_set_key_length(self.as_ptr(), len.try_into().unwrap()))?;
+ cvt(ffi::EVP_CIPHER_CTX_set_key_length(
+ self.as_ptr(),
+ len.try_into().unwrap(),
+ ))?;
}
Ok(())
@@ -405,7 +407,7 @@
/// Retrieves the calculated authentication tag from the context.
///
- /// This should be called after `[Self::cipher_final]`, and is only supported by authenticated ciphers.
+ /// This should be called after [`Self::cipher_final`], and is only supported by authenticated ciphers.
///
/// The size of the buffer indicates the size of the tag. While some ciphers support a range of tag sizes, it is
/// recommended to pick the maximum size.
@@ -587,6 +589,7 @@
mod test {
use super::*;
use crate::cipher::Cipher;
+ #[cfg(not(boringssl))]
use std::slice;
#[test]
diff --git a/openssl/src/cms.rs b/src/cms.rs
similarity index 100%
rename from openssl/src/cms.rs
rename to src/cms.rs
diff --git a/src/conf.rs b/src/conf.rs
new file mode 100644
index 0000000..2c54cf2
--- /dev/null
+++ b/src/conf.rs
@@ -0,0 +1,64 @@
+//! Interface for processing OpenSSL configuration files.
+
+foreign_type_and_impl_send_sync! {
+ type CType = ffi::CONF;
+ fn drop = ffi::NCONF_free;
+
+ pub struct Conf;
+ pub struct ConfRef;
+}
+
+#[cfg(not(boringssl))]
+mod methods {
+ use super::Conf;
+ use crate::cvt_p;
+ use crate::error::ErrorStack;
+ use openssl_macros::corresponds;
+
+ pub struct ConfMethod(*mut ffi::CONF_METHOD);
+
+ impl ConfMethod {
+ /// Retrieve handle to the default OpenSSL configuration file processing function.
+ #[corresponds(NCONF_default)]
+ pub fn default() -> ConfMethod {
+ unsafe {
+ ffi::init();
+ // `NCONF` stands for "New Conf", as described in crypto/conf/conf_lib.c. This is
+ // a newer API than the "CONF classic" functions.
+ ConfMethod(ffi::NCONF_default())
+ }
+ }
+
+ /// Construct from raw pointer.
+ ///
+ /// # Safety
+ ///
+ /// The caller must ensure that the pointer is valid.
+ pub unsafe fn from_ptr(ptr: *mut ffi::CONF_METHOD) -> ConfMethod {
+ ConfMethod(ptr)
+ }
+
+ /// Convert to raw pointer.
+ pub fn as_ptr(&self) -> *mut ffi::CONF_METHOD {
+ self.0
+ }
+ }
+
+ impl Conf {
+ /// Create a configuration parser.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use openssl::conf::{Conf, ConfMethod};
+ ///
+ /// let conf = Conf::new(ConfMethod::default());
+ /// ```
+ #[corresponds(NCONF_new)]
+ pub fn new(method: ConfMethod) -> Result<Conf, ErrorStack> {
+ unsafe { cvt_p(ffi::NCONF_new(method.as_ptr())).map(Conf) }
+ }
+ }
+}
+#[cfg(not(boringssl))]
+pub use methods::*;
diff --git a/openssl/src/derive.rs b/src/derive.rs
similarity index 100%
rename from openssl/src/derive.rs
rename to src/derive.rs
diff --git a/openssl/src/dh.rs b/src/dh.rs
similarity index 100%
rename from openssl/src/dh.rs
rename to src/dh.rs
diff --git a/openssl/src/dsa.rs b/src/dsa.rs
similarity index 68%
rename from openssl/src/dsa.rs
rename to src/dsa.rs
index 7f04f4e..5f59ba8 100644
--- a/openssl/src/dsa.rs
+++ b/src/dsa.rs
@@ -7,7 +7,7 @@
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
-use libc::{c_int, c_uint};
+use libc::c_int;
use std::fmt;
use std::mem;
use std::ptr;
@@ -179,7 +179,7 @@
}
}
#[cfg(boringssl)]
-type BitType = c_uint;
+type BitType = libc::c_uint;
#[cfg(not(boringssl))]
type BitType = c_int;
@@ -344,12 +344,168 @@
}
}
+foreign_type_and_impl_send_sync! {
+ type CType = ffi::DSA_SIG;
+ fn drop = ffi::DSA_SIG_free;
+
+ /// Object representing DSA signature.
+ ///
+ /// DSA signatures consist of two components: `r` and `s`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::convert::TryInto;
+ ///
+ /// use openssl::bn::BigNum;
+ /// use openssl::dsa::{Dsa, DsaSig};
+ /// use openssl::hash::MessageDigest;
+ /// use openssl::pkey::PKey;
+ /// use openssl::sign::{Signer, Verifier};
+ ///
+ /// const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ /// let dsa_ref = Dsa::generate(1024).unwrap();
+ ///
+ /// let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap();
+ /// let priv_key: PKey<_> = dsa_ref.try_into().unwrap();
+ ///
+ /// let mut signer = if let Ok(signer) = Signer::new(MessageDigest::sha256(), &priv_key) {
+ /// signer
+ /// } else {
+ /// // DSA signing is not supported (eg. BoringSSL)
+ /// return;
+ /// };
+ ///
+ /// signer.update(TEST_DATA).unwrap();
+ ///
+ /// let signature = signer.sign_to_vec().unwrap();
+ /// // Parse DER-encoded DSA signature
+ /// let signature = DsaSig::from_der(&signature).unwrap();
+ ///
+ /// // Extract components `r` and `s`
+ /// let r = BigNum::from_slice(&signature.r().to_vec()).unwrap();
+ /// let s = BigNum::from_slice(&signature.s().to_vec()).unwrap();
+ ///
+ /// // Construct new DSA signature from components
+ /// let signature = DsaSig::from_private_components(r, s).unwrap();
+ ///
+ /// // Serialize DSA signature to DER
+ /// let signature = signature.to_der().unwrap();
+ ///
+ /// let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
+ /// verifier.update(TEST_DATA).unwrap();
+ /// assert!(verifier.verify(&signature[..]).unwrap());
+ /// ```
+ pub struct DsaSig;
+
+ /// Reference to a [`DsaSig`].
+ pub struct DsaSigRef;
+}
+
+impl DsaSig {
+ /// Returns a new `DsaSig` by setting the `r` and `s` values associated with an DSA signature.
+ #[corresponds(DSA_SIG_set0)]
+ pub fn from_private_components(r: BigNum, s: BigNum) -> Result<Self, ErrorStack> {
+ unsafe {
+ let sig = cvt_p(ffi::DSA_SIG_new())?;
+ DSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
+ mem::forget((r, s));
+ Ok(DsaSig::from_ptr(sig))
+ }
+ }
+
+ from_der! {
+ /// Decodes a DER-encoded DSA signature.
+ #[corresponds(d2i_DSA_SIG)]
+ from_der,
+ DsaSig,
+ ffi::d2i_DSA_SIG
+ }
+}
+
+impl fmt::Debug for DsaSig {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("DsaSig")
+ .field("r", self.r())
+ .field("s", self.s())
+ .finish()
+ }
+}
+
+impl DsaSigRef {
+ to_der! {
+ /// Serializes the DSA signature into a DER-encoded `DSASignature` structure.
+ #[corresponds(i2d_DSA_SIG)]
+ to_der,
+ ffi::i2d_DSA_SIG
+ }
+
+ /// Returns internal component `r` of an `DsaSig`.
+ #[corresponds(DSA_SIG_get0)]
+ pub fn r(&self) -> &BigNumRef {
+ unsafe {
+ let mut r = ptr::null();
+ DSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
+ BigNumRef::from_const_ptr(r)
+ }
+ }
+
+ /// Returns internal component `s` of an `DsaSig`.
+ #[corresponds(DSA_SIG_get0)]
+ pub fn s(&self) -> &BigNumRef {
+ unsafe {
+ let mut s = ptr::null();
+ DSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
+ BigNumRef::from_const_ptr(s)
+ }
+ }
+}
+
+cfg_if! {
+ if #[cfg(any(ossl110, libressl273))] {
+ use ffi::{DSA_SIG_set0, DSA_SIG_get0};
+ } else {
+ #[allow(bad_style)]
+ unsafe fn DSA_SIG_set0(
+ sig: *mut ffi::DSA_SIG,
+ r: *mut ffi::BIGNUM,
+ s: *mut ffi::BIGNUM,
+ ) -> c_int {
+ if r.is_null() || s.is_null() {
+ return 0;
+ }
+ ffi::BN_clear_free((*sig).r);
+ ffi::BN_clear_free((*sig).s);
+ (*sig).r = r;
+ (*sig).s = s;
+ 1
+ }
+
+ #[allow(bad_style)]
+ unsafe fn DSA_SIG_get0(
+ sig: *const ffi::DSA_SIG,
+ pr: *mut *const ffi::BIGNUM,
+ ps: *mut *const ffi::BIGNUM)
+ {
+ if !pr.is_null() {
+ (*pr) = (*sig).r;
+ }
+ if !ps.is_null() {
+ (*ps) = (*sig).s;
+ }
+ }
+ }
+}
+
#[cfg(test)]
mod test {
use super::*;
use crate::bn::BigNumContext;
+ #[cfg(not(boringssl))]
use crate::hash::MessageDigest;
+ #[cfg(not(boringssl))]
use crate::pkey::PKey;
+ #[cfg(not(boringssl))]
use crate::sign::{Signer, Verifier};
#[test]
@@ -442,9 +598,50 @@
}
#[test]
+ #[cfg(not(boringssl))]
+ fn test_signature_der() {
+ use std::convert::TryInto;
+
+ const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ let dsa_ref = Dsa::generate(1024).unwrap();
+
+ let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap();
+ let priv_key: PKey<_> = dsa_ref.try_into().unwrap();
+
+ let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
+ signer.update(TEST_DATA).unwrap();
+
+ let signature = signer.sign_to_vec().unwrap();
+ eprintln!("{:?}", signature);
+ let signature = DsaSig::from_der(&signature).unwrap();
+
+ let r = BigNum::from_slice(&signature.r().to_vec()).unwrap();
+ let s = BigNum::from_slice(&signature.s().to_vec()).unwrap();
+
+ let signature = DsaSig::from_private_components(r, s).unwrap();
+ let signature = signature.to_der().unwrap();
+
+ let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
+ verifier.update(TEST_DATA).unwrap();
+ assert!(verifier.verify(&signature[..]).unwrap());
+ }
+
+ #[test]
#[allow(clippy::redundant_clone)]
fn clone() {
let key = Dsa::generate(2048).unwrap();
drop(key.clone());
}
+
+ #[test]
+ fn dsa_sig_debug() {
+ let sig = DsaSig::from_der(&[
+ 48, 46, 2, 21, 0, 135, 169, 24, 58, 153, 37, 175, 248, 200, 45, 251, 112, 238, 238, 89,
+ 172, 177, 182, 166, 237, 2, 21, 0, 159, 146, 151, 237, 187, 8, 82, 115, 14, 183, 103,
+ 12, 203, 46, 161, 208, 251, 167, 123, 131,
+ ])
+ .unwrap();
+ let s = format!("{:?}", sig);
+ assert_eq!(s, "DsaSig { r: 774484690634577222213819810519929266740561094381, s: 910998676210681457251421818099943952372231273347 }");
+ }
}
diff --git a/openssl/src/ec.rs b/src/ec.rs
similarity index 85%
rename from openssl/src/ec.rs
rename to src/ec.rs
index 13f8bb3..88dcaaf 100644
--- a/openssl/src/ec.rs
+++ b/src/ec.rs
@@ -14,13 +14,13 @@
//!
//! [`EcGroup`]: struct.EcGroup.html
//! [`Nid`]: ../nid/struct.Nid.html
-//! [Eliptic Curve Cryptography]: https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography
+//! [Elliptic Curve Cryptography]: https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use std::fmt;
use std::ptr;
-use crate::bn::{BigNumContextRef, BigNumRef};
+use crate::bn::{BigNum, BigNumContextRef, BigNumRef};
use crate::error::ErrorStack;
use crate::nid::Nid;
use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
@@ -123,6 +123,25 @@
cvt_p(ffi::EC_GROUP_new_by_curve_name(nid.as_raw())).map(EcGroup)
}
}
+
+ /// Returns the group for given parameters
+ #[corresponds(EC_GROUP_new_curve_GFp)]
+ pub fn from_components(
+ p: BigNum,
+ a: BigNum,
+ b: BigNum,
+ ctx: &mut BigNumContextRef,
+ ) -> Result<EcGroup, ErrorStack> {
+ unsafe {
+ cvt_p(ffi::EC_GROUP_new_curve_GFp(
+ p.as_ptr(),
+ a.as_ptr(),
+ b.as_ptr(),
+ ctx.as_ptr(),
+ ))
+ .map(EcGroup)
+ }
+ }
}
impl EcGroupRef {
@@ -214,6 +233,25 @@
}
}
+ /// Sets the generator point for the given curve
+ #[corresponds(EC_GROUP_set_generator)]
+ pub fn set_generator(
+ &mut self,
+ generator: EcPoint,
+ order: BigNum,
+ cofactor: BigNum,
+ ) -> Result<(), ErrorStack> {
+ unsafe {
+ cvt(ffi::EC_GROUP_set_generator(
+ self.as_ptr(),
+ generator.as_ptr(),
+ order.as_ptr(),
+ cofactor.as_ptr(),
+ ))
+ .map(|_| ())
+ }
+ }
+
/// Places the order of the curve in the provided `BigNum`.
#[corresponds(EC_GROUP_get_order)]
pub fn order(
@@ -476,6 +514,28 @@
}
}
+ /// Sets affine coordinates of a curve over a prime field using the provided
+ /// `x` and `y` `BigNum`s
+ #[corresponds(EC_POINT_set_affine_coordinates_GFp)]
+ pub fn set_affine_coordinates_gfp(
+ &mut self,
+ group: &EcGroupRef,
+ x: &BigNumRef,
+ y: &BigNumRef,
+ ctx: &mut BigNumContextRef,
+ ) -> Result<(), ErrorStack> {
+ unsafe {
+ cvt(ffi::EC_POINT_set_affine_coordinates_GFp(
+ group.as_ptr(),
+ self.as_ptr(),
+ x.as_ptr(),
+ y.as_ptr(),
+ ctx.as_ptr(),
+ ))
+ .map(|_| ())
+ }
+ }
+
/// Places affine coordinates of a curve over a binary field in the provided
/// `x` and `y` `BigNum`s
#[corresponds(EC_POINT_get_affine_coordinates_GF2m)]
@@ -848,6 +908,26 @@
EcKey<Private>,
ffi::d2i_ECPrivateKey
}
+
+ /// Decodes a DER-encoded elliptic curve private key structure for the specified curve.
+ #[corresponds(EC_KEY_parse_private_key)]
+ #[cfg(boringssl)]
+ pub fn private_key_from_der_for_group(
+ der: &[u8],
+ group: &EcGroupRef,
+ ) -> Result<EcKey<Private>, ErrorStack> {
+ unsafe {
+ let mut cbs = ffi::CBS {
+ data: der.as_ptr(),
+ len: der.len(),
+ };
+ cvt_p(ffi::EC_KEY_parse_private_key(
+ &mut cbs as *mut ffi::CBS,
+ group.as_ptr(),
+ ))
+ .map(|p| EcKey::from_ptr(p))
+ }
+ }
}
impl<T> Clone for EcKey<T> {
@@ -882,6 +962,97 @@
}
#[test]
+ fn ec_group_from_components() {
+ // parameters are from secp256r1
+ let p = BigNum::from_hex_str(
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+ )
+ .unwrap();
+ let a = BigNum::from_hex_str(
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+ )
+ .unwrap();
+ let b = BigNum::from_hex_str(
+ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
+ )
+ .unwrap();
+ let mut ctx = BigNumContext::new().unwrap();
+
+ let _curve = EcGroup::from_components(p, a, b, &mut ctx).unwrap();
+ }
+
+ #[test]
+ fn ec_point_set_affine() {
+ // parameters are from secp256r1
+ let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
+ let mut ctx = BigNumContext::new().unwrap();
+ let mut gen_point = EcPoint::new(&group).unwrap();
+ let gen_x = BigNum::from_hex_str(
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+ )
+ .unwrap();
+ let gen_y = BigNum::from_hex_str(
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+ )
+ .unwrap();
+ gen_point
+ .set_affine_coordinates_gfp(&group, &gen_x, &gen_y, &mut ctx)
+ .unwrap();
+ assert!(gen_point.is_on_curve(&group, &mut ctx).unwrap());
+ }
+
+ #[test]
+ fn ec_group_set_generator() {
+ // parameters are from secp256r1
+ let mut ctx = BigNumContext::new().unwrap();
+ let p = BigNum::from_hex_str(
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+ )
+ .unwrap();
+ let a = BigNum::from_hex_str(
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+ )
+ .unwrap();
+ let b = BigNum::from_hex_str(
+ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
+ )
+ .unwrap();
+
+ let mut group = EcGroup::from_components(p, a, b, &mut ctx).unwrap();
+
+ let mut gen_point = EcPoint::new(&group).unwrap();
+ let gen_x = BigNum::from_hex_str(
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+ )
+ .unwrap();
+ let gen_y = BigNum::from_hex_str(
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+ )
+ .unwrap();
+ gen_point
+ .set_affine_coordinates_gfp(&group, &gen_x, &gen_y, &mut ctx)
+ .unwrap();
+
+ let order = BigNum::from_hex_str(
+ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
+ )
+ .unwrap();
+ let cofactor = BigNum::from_hex_str("01").unwrap();
+ group.set_generator(gen_point, order, cofactor).unwrap();
+ let mut constructed_order = BigNum::new().unwrap();
+ group.order(&mut constructed_order, &mut ctx).unwrap();
+
+ let named_group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
+ let mut named_order = BigNum::new().unwrap();
+ named_group.order(&mut named_order, &mut ctx).unwrap();
+
+ assert_eq!(
+ constructed_order.ucmp(&named_order),
+ std::cmp::Ordering::Equal
+ );
+ }
+
+ #[test]
fn cofactor() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let mut ctx = BigNumContext::new().unwrap();
diff --git a/openssl/src/ecdsa.rs b/src/ecdsa.rs
similarity index 97%
rename from openssl/src/ecdsa.rs
rename to src/ecdsa.rs
index e0c6c1b..0a960e7 100644
--- a/openssl/src/ecdsa.rs
+++ b/src/ecdsa.rs
@@ -2,7 +2,7 @@
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
-use libc::{c_int, size_t};
+use libc::c_int;
use std::mem;
use std::ptr;
@@ -11,7 +11,7 @@
use crate::error::ErrorStack;
use crate::pkey::{HasPrivate, HasPublic};
use crate::util::ForeignTypeRefExt;
-use crate::{cvt_n, cvt_p};
+use crate::{cvt_n, cvt_p, LenType};
use openssl_macros::corresponds;
foreign_type_and_impl_send_sync! {
@@ -24,11 +24,6 @@
pub struct EcdsaSigRef;
}
-#[cfg(boringssl)]
-type LenType = size_t;
-#[cfg(not(boringssl))]
-type LenType = c_int;
-
impl EcdsaSig {
/// Computes a digital signature of the hash value `data` using the private EC key eckey.
#[corresponds(ECDSA_do_sign)]
diff --git a/openssl/src/encrypt.rs b/src/encrypt.rs
similarity index 99%
rename from openssl/src/encrypt.rs
rename to src/encrypt.rs
index 3cb10fc..34a9eb8 100644
--- a/openssl/src/encrypt.rs
+++ b/src/encrypt.rs
@@ -148,7 +148,7 @@
/// This corresponds to [`EVP_PKEY_CTX_set_rsa_oaep_md`].
///
/// [`EVP_PKEY_CTX_set_rsa_oaep_md`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set_rsa_oaep_md.html
- #[cfg(any(ossl102, libressl310))]
+ #[cfg(any(ossl102, libressl310, boringssl))]
pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
@@ -352,7 +352,7 @@
/// This corresponds to [`EVP_PKEY_CTX_set_rsa_oaep_md`].
///
/// [`EVP_PKEY_CTX_set_rsa_oaep_md`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set_rsa_oaep_md.html
- #[cfg(any(ossl102, libressl310))]
+ #[cfg(any(ossl102, libressl310, boringssl))]
pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
diff --git a/openssl/src/envelope.rs b/src/envelope.rs
similarity index 100%
rename from openssl/src/envelope.rs
rename to src/envelope.rs
diff --git a/openssl/src/error.rs b/src/error.rs
similarity index 82%
rename from openssl/src/error.rs
rename to src/error.rs
index 572937b..58b4d70 100644
--- a/openssl/src/error.rs
+++ b/src/error.rs
@@ -16,8 +16,9 @@
//! }
//! ```
use cfg_if::cfg_if;
-use libc::{c_char, c_int, c_uint, c_ulong};
+use libc::{c_char, c_int};
use std::borrow::Cow;
+#[cfg(boringssl)]
use std::convert::TryInto;
use std::error;
use std::ffi::CStr;
@@ -27,9 +28,9 @@
use std::str;
#[cfg(not(boringssl))]
-type ErrType = c_ulong;
+type ErrType = libc::c_ulong;
#[cfg(boringssl)]
-type ErrType = c_uint;
+type ErrType = libc::c_uint;
/// Collection of [`Error`]s from OpenSSL.
///
@@ -98,9 +99,9 @@
#[derive(Clone)]
pub struct Error {
code: ErrType,
- file: *const c_char,
+ file: ShimStr,
line: c_int,
- func: *const c_char,
+ func: Option<ShimStr>,
data: Option<Cow<'static, str>>,
}
@@ -138,6 +139,15 @@
} else {
None
};
+
+ let file = ShimStr::new(file);
+
+ let func = if func.is_null() {
+ None
+ } else {
+ Some(ShimStr::new(func))
+ };
+
Some(Error {
code,
file,
@@ -183,7 +193,11 @@
fn put_error(&self) {
unsafe {
ffi::ERR_new();
- ffi::ERR_set_debug(self.file, self.line, self.func);
+ ffi::ERR_set_debug(
+ self.file.as_ptr(),
+ self.line,
+ self.func.as_ref().map_or(ptr::null(), |s| s.as_ptr()),
+ );
ffi::ERR_set_error(
ffi::ERR_GET_LIB(self.code),
ffi::ERR_GET_REASON(self.code),
@@ -194,13 +208,17 @@
#[cfg(not(ossl300))]
fn put_error(&self) {
+ #[cfg(not(boringssl))]
+ let line = self.line;
+ #[cfg(boringssl)]
+ let line = self.line.try_into().unwrap();
unsafe {
ffi::ERR_put_error(
ffi::ERR_GET_LIB(self.code),
ffi::ERR_GET_FUNC(self.code),
ffi::ERR_GET_REASON(self.code),
- self.file,
- self.line.try_into().unwrap(),
+ self.file.as_ptr(),
+ line,
);
}
}
@@ -223,14 +241,8 @@
}
/// Returns the name of the function reporting the error.
- pub fn function(&self) -> Option<&'static str> {
- unsafe {
- if self.func.is_null() {
- return None;
- }
- let bytes = CStr::from_ptr(self.func).to_bytes();
- Some(str::from_utf8(bytes).unwrap())
- }
+ pub fn function(&self) -> Option<RetStr<'_>> {
+ self.func.as_ref().map(|s| s.as_str())
}
/// Returns the reason for the error.
@@ -246,12 +258,8 @@
}
/// Returns the name of the source file which encountered the error.
- pub fn file(&self) -> &'static str {
- unsafe {
- assert!(!self.file.is_null());
- let bytes = CStr::from_ptr(self.file as *const _).to_bytes();
- str::from_utf8(bytes).unwrap()
- }
+ pub fn file(&self) -> RetStr<'_> {
+ self.file.as_str()
}
/// Returns the line in the source file which encountered the error.
@@ -317,7 +325,27 @@
cfg_if! {
if #[cfg(ossl300)] {
+ use std::ffi::{CString};
use ffi::ERR_get_error_all;
+
+ type RetStr<'a> = &'a str;
+
+ #[derive(Clone)]
+ struct ShimStr(CString);
+
+ impl ShimStr {
+ unsafe fn new(s: *const c_char) -> Self {
+ ShimStr(CStr::from_ptr(s).to_owned())
+ }
+
+ fn as_ptr(&self) -> *const c_char {
+ self.0.as_ptr()
+ }
+
+ fn as_str(&self) -> &str {
+ self.0.to_str().unwrap()
+ }
+ }
} else {
#[allow(bad_style)]
unsafe extern "C" fn ERR_get_error_all(
@@ -331,5 +359,26 @@
*func = ffi::ERR_func_error_string(code);
code
}
+
+ type RetStr<'a> = &'static str;
+
+ #[derive(Clone)]
+ struct ShimStr(*const c_char);
+
+ impl ShimStr {
+ unsafe fn new(s: *const c_char) -> Self {
+ ShimStr(s)
+ }
+
+ fn as_ptr(&self) -> *const c_char {
+ self.0
+ }
+
+ fn as_str(&self) -> &'static str {
+ unsafe {
+ CStr::from_ptr(self.0).to_str().unwrap()
+ }
+ }
+ }
}
}
diff --git a/openssl/src/ex_data.rs b/src/ex_data.rs
similarity index 100%
rename from openssl/src/ex_data.rs
rename to src/ex_data.rs
diff --git a/openssl/src/fips.rs b/src/fips.rs
similarity index 100%
rename from openssl/src/fips.rs
rename to src/fips.rs
diff --git a/openssl/src/hash.rs b/src/hash.rs
similarity index 91%
rename from openssl/src/hash.rs
rename to src/hash.rs
index a7c02fa..fd83869 100644
--- a/openssl/src/hash.rs
+++ b/src/hash.rs
@@ -484,6 +484,7 @@
assert_eq!(MessageDigest::md5().block_size(), 64);
assert_eq!(MessageDigest::md5().size(), 16);
+ assert_eq!(MessageDigest::md5().type_().as_raw(), Nid::MD5.as_raw());
}
#[test]
@@ -546,6 +547,7 @@
assert_eq!(MessageDigest::sha1().block_size(), 64);
assert_eq!(MessageDigest::sha1().size(), 20);
+ assert_eq!(MessageDigest::sha1().type_().as_raw(), Nid::SHA1.as_raw());
}
#[test]
@@ -561,6 +563,30 @@
assert_eq!(MessageDigest::sha256().block_size(), 64);
assert_eq!(MessageDigest::sha256().size(), 32);
+ assert_eq!(
+ MessageDigest::sha256().type_().as_raw(),
+ Nid::SHA256.as_raw()
+ );
+ }
+
+ #[test]
+ fn test_sha512() {
+ let tests = [(
+ "737465766566696e647365766572797468696e67",
+ "ba61d1f1af0f2dd80729f6cc900f19c0966bd38ba5c75e4471ef11b771dfe7551afab7fcbd300fdc4418f2\
+ b07a028fcd99e7b6446a566f2d9bcd7c604a1ea801",
+ )];
+
+ for test in tests.iter() {
+ hash_test(MessageDigest::sha512(), test);
+ }
+
+ assert_eq!(MessageDigest::sha512().block_size(), 128);
+ assert_eq!(MessageDigest::sha512().size(), 64);
+ assert_eq!(
+ MessageDigest::sha512().type_().as_raw(),
+ Nid::SHA512.as_raw()
+ );
}
#[cfg(ossl111)]
@@ -577,6 +603,10 @@
assert_eq!(MessageDigest::sha3_224().block_size(), 144);
assert_eq!(MessageDigest::sha3_224().size(), 28);
+ assert_eq!(
+ MessageDigest::sha3_224().type_().as_raw(),
+ Nid::SHA3_224.as_raw()
+ );
}
#[cfg(ossl111)]
@@ -593,6 +623,10 @@
assert_eq!(MessageDigest::sha3_256().block_size(), 136);
assert_eq!(MessageDigest::sha3_256().size(), 32);
+ assert_eq!(
+ MessageDigest::sha3_256().type_().as_raw(),
+ Nid::SHA3_256.as_raw()
+ );
}
#[cfg(ossl111)]
@@ -609,6 +643,10 @@
assert_eq!(MessageDigest::sha3_384().block_size(), 104);
assert_eq!(MessageDigest::sha3_384().size(), 48);
+ assert_eq!(
+ MessageDigest::sha3_384().type_().as_raw(),
+ Nid::SHA3_384.as_raw()
+ );
}
#[cfg(ossl111)]
@@ -625,6 +663,10 @@
assert_eq!(MessageDigest::sha3_512().block_size(), 72);
assert_eq!(MessageDigest::sha3_512().size(), 64);
+ assert_eq!(
+ MessageDigest::sha3_512().type_().as_raw(),
+ Nid::SHA3_512.as_raw()
+ );
}
#[cfg(ossl111)]
@@ -641,6 +683,10 @@
assert_eq!(MessageDigest::shake_128().block_size(), 168);
assert_eq!(MessageDigest::shake_128().size(), 16);
+ assert_eq!(
+ MessageDigest::shake_128().type_().as_raw(),
+ Nid::SHAKE128.as_raw()
+ );
}
#[cfg(ossl111)]
@@ -657,6 +703,10 @@
assert_eq!(MessageDigest::shake_256().block_size(), 136);
assert_eq!(MessageDigest::shake_256().size(), 32);
+ assert_eq!(
+ MessageDigest::shake_256().type_().as_raw(),
+ Nid::SHAKE256.as_raw()
+ );
}
#[test]
@@ -674,6 +724,10 @@
assert_eq!(MessageDigest::ripemd160().block_size(), 64);
assert_eq!(MessageDigest::ripemd160().size(), 20);
+ assert_eq!(
+ MessageDigest::ripemd160().type_().as_raw(),
+ Nid::RIPEMD160.as_raw()
+ );
}
#[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM3")))]
@@ -690,6 +744,7 @@
assert_eq!(MessageDigest::sm3().block_size(), 64);
assert_eq!(MessageDigest::sm3().size(), 32);
+ assert_eq!(MessageDigest::sm3().type_().as_raw(), Nid::SM3.as_raw());
}
#[test]
diff --git a/openssl/src/hkdf.rs b/src/hkdf.rs
similarity index 100%
rename from openssl/src/hkdf.rs
rename to src/hkdf.rs
diff --git a/openssl/src/hmac.rs b/src/hmac.rs
similarity index 100%
rename from openssl/src/hmac.rs
rename to src/hmac.rs
diff --git a/openssl/src/lib.rs b/src/lib.rs
similarity index 96%
rename from openssl/src/lib.rs
rename to src/lib.rs
index 0bba5b9..b91d067 100644
--- a/openssl/src/lib.rs
+++ b/src/lib.rs
@@ -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
-//! 1.1.1 and LibreSSL versions 2.5 through 3.4.1 are supported.
+//! 3.x.x and LibreSSL versions 2.5 through 3.4.1 are supported.
//!
//! # Building
//!
@@ -120,7 +120,7 @@
#![doc(html_root_url = "https://docs.rs/openssl/0.10")]
#![warn(rust_2018_idioms)]
-#[cfg(boringssl)]
+#[cfg(all(soong,boringssl))]
extern crate bssl_ffi as ffi;
#[doc(inline)]
@@ -191,6 +191,11 @@
pub mod version;
pub mod x509;
+#[cfg(boringssl)]
+type LenType = libc::size_t;
+#[cfg(not(boringssl))]
+type LenType = libc::c_int;
+
#[inline]
fn cvt_p<T>(r: *mut T) -> Result<*mut T, ErrorStack> {
if r.is_null() {
diff --git a/openssl/src/lib_ctx.rs b/src/lib_ctx.rs
similarity index 100%
rename from openssl/src/lib_ctx.rs
rename to src/lib_ctx.rs
diff --git a/openssl/src/macros.rs b/src/macros.rs
similarity index 100%
rename from openssl/src/macros.rs
rename to src/macros.rs
diff --git a/openssl/src/md.rs b/src/md.rs
similarity index 100%
rename from openssl/src/md.rs
rename to src/md.rs
diff --git a/openssl/src/md_ctx.rs b/src/md_ctx.rs
similarity index 67%
rename from openssl/src/md_ctx.rs
rename to src/md_ctx.rs
index 2d587e5..c4d3f06 100644
--- a/openssl/src/md_ctx.rs
+++ b/src/md_ctx.rs
@@ -50,34 +50,40 @@
//! assert!(valid);
//! ```
//!
-//! Compute and verify an HMAC-SHA256
-//!
-//! ```
-//! use openssl::md::Md;
-//! use openssl::md_ctx::MdCtx;
-//! use openssl::memcmp;
-//! use openssl::pkey::PKey;
-//!
-//! // Create a key with the HMAC secret.
-//! let key = PKey::hmac(b"my secret").unwrap();
-//!
-//! let text = b"Some Crypto Text";
-//!
-//! // Compute the HMAC.
-//! let mut ctx = MdCtx::new().unwrap();
-//! ctx.digest_sign_init(Some(Md::sha256()), &key).unwrap();
-//! ctx.digest_sign_update(text).unwrap();
-//! let mut hmac = vec![];
-//! ctx.digest_sign_final_to_vec(&mut hmac).unwrap();
-//!
-//! // Verify the HMAC. You can't use MdCtx to do this; instead use a constant time equality check.
-//! # let target = hmac.clone();
-//! let valid = memcmp::eq(&hmac, &target);
-//! assert!(valid);
-//! ```
+
+#![cfg_attr(
+ not(boringssl),
+ doc = r#"\
+Compute and verify an HMAC-SHA256
+
+```
+use openssl::md::Md;
+use openssl::md_ctx::MdCtx;
+use openssl::memcmp;
+use openssl::pkey::PKey;
+
+// Create a key with the HMAC secret.
+let key = PKey::hmac(b"my secret").unwrap();
+
+let text = b"Some Crypto Text";
+
+// Compute the HMAC.
+let mut ctx = MdCtx::new().unwrap();
+ctx.digest_sign_init(Some(Md::sha256()), &key).unwrap();
+ctx.digest_sign_update(text).unwrap();
+let mut hmac = vec![];
+ctx.digest_sign_final_to_vec(&mut hmac).unwrap();
+
+// Verify the HMAC. You can't use MdCtx to do this; instead use a constant time equality check.
+# let target = hmac.clone();
+let valid = memcmp::eq(&hmac, &target);
+assert!(valid);
+```"#
+)]
+
use crate::error::ErrorStack;
use crate::md::MdRef;
-use crate::pkey::{HasPrivate, PKeyRef};
+use crate::pkey::{HasPrivate, HasPublic, PKeyRef};
use crate::pkey_ctx::PkeyCtxRef;
use crate::{cvt, cvt_n, cvt_p};
use cfg_if::cfg_if;
@@ -170,7 +176,7 @@
pkey: &PKeyRef<T>,
) -> Result<&'a mut PkeyCtxRef<T>, ErrorStack>
where
- T: HasPrivate,
+ T: HasPublic,
{
unsafe {
let mut p = ptr::null_mut();
@@ -373,6 +379,24 @@
Ok(r == 1)
}
}
+
+ /// Returns the size of the message digest, i.e. the size of the hash
+ #[corresponds(EVP_MD_CTX_size)]
+ #[inline]
+ pub fn size(&self) -> usize {
+ unsafe { ffi::EVP_MD_CTX_size(self.as_ptr()) as usize }
+ }
+
+ /// Resets the underlying EVP_MD_CTX instance
+ #[corresponds(EVP_MD_CTX_reset)]
+ #[cfg(ossl111)]
+ #[inline]
+ pub fn reset(&mut self) -> Result<(), ErrorStack> {
+ unsafe {
+ let _ = cvt(ffi::EVP_MD_CTX_reset(self.as_ptr()))?;
+ Ok(())
+ }
+ }
}
#[cfg(test)]
@@ -403,4 +427,114 @@
let valid = ctx.digest_verify_final(&signature).unwrap();
assert!(!valid);
}
+
+ #[test]
+ fn verify_success() {
+ let key1 = Rsa::generate(2048).unwrap();
+ let key1 = PKey::from_rsa(key1).unwrap();
+
+ let md = Md::sha256();
+ let data = b"Some Crypto Text";
+
+ let mut ctx = MdCtx::new().unwrap();
+ ctx.digest_sign_init(Some(md), &key1).unwrap();
+ ctx.digest_sign_update(data).unwrap();
+ let mut signature = vec![];
+ ctx.digest_sign_final_to_vec(&mut signature).unwrap();
+
+ let good_data = b"Some Crypto Text";
+
+ ctx.digest_verify_init(Some(md), &key1).unwrap();
+ ctx.digest_verify_update(good_data).unwrap();
+ let valid = ctx.digest_verify_final(&signature).unwrap();
+ assert!(valid);
+ }
+
+ #[test]
+ fn verify_with_public_success() {
+ let rsa = Rsa::generate(2048).unwrap();
+ let key1 = PKey::from_rsa(rsa.clone()).unwrap();
+
+ let md = Md::sha256();
+ let data = b"Some Crypto Text";
+
+ let mut ctx = MdCtx::new().unwrap();
+ ctx.digest_sign_init(Some(md), &key1).unwrap();
+ ctx.digest_sign_update(data).unwrap();
+ let mut signature = vec![];
+ ctx.digest_sign_final_to_vec(&mut signature).unwrap();
+
+ let good_data = b"Some Crypto Text";
+
+ // try to verify using only public components of the key
+ let n = rsa.n().to_owned().unwrap();
+ let e = rsa.e().to_owned().unwrap();
+
+ let rsa = Rsa::from_public_components(n, e).unwrap();
+ let key1 = PKey::from_rsa(rsa).unwrap();
+
+ ctx.digest_verify_init(Some(md), &key1).unwrap();
+ ctx.digest_verify_update(good_data).unwrap();
+ let valid = ctx.digest_verify_final(&signature).unwrap();
+ assert!(valid);
+ }
+
+ #[test]
+ fn verify_md_ctx_size() {
+ let mut ctx = MdCtx::new().unwrap();
+ ctx.digest_init(Md::sha224()).unwrap();
+ assert_eq!(Md::sha224().size(), ctx.size());
+ assert_eq!(Md::sha224().size(), 28);
+
+ let mut ctx = MdCtx::new().unwrap();
+ ctx.digest_init(Md::sha256()).unwrap();
+ assert_eq!(Md::sha256().size(), ctx.size());
+ assert_eq!(Md::sha256().size(), 32);
+
+ let mut ctx = MdCtx::new().unwrap();
+ ctx.digest_init(Md::sha384()).unwrap();
+ assert_eq!(Md::sha384().size(), ctx.size());
+ assert_eq!(Md::sha384().size(), 48);
+
+ let mut ctx = MdCtx::new().unwrap();
+ ctx.digest_init(Md::sha512()).unwrap();
+ assert_eq!(Md::sha512().size(), ctx.size());
+ assert_eq!(Md::sha512().size(), 64);
+ }
+
+ #[test]
+ #[cfg(ossl111)]
+ fn verify_md_ctx_reset() {
+ let hello_expected =
+ hex::decode("185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969")
+ .unwrap();
+ let world_expected =
+ hex::decode("78ae647dc5544d227130a0682a51e30bc7777fbb6d8a8f17007463a3ecd1d524")
+ .unwrap();
+ // Calculate SHA-256 digest of "Hello"
+ let mut ctx = MdCtx::new().unwrap();
+ ctx.digest_init(Md::sha256()).unwrap();
+ ctx.digest_update(b"Hello").unwrap();
+ let mut result = vec![0; 32];
+ let result_len = ctx.digest_final(result.as_mut_slice()).unwrap();
+ assert_eq!(result_len, result.len());
+ // Validate result of "Hello"
+ assert_eq!(result, hello_expected);
+
+ // Create new context
+ let mut ctx = MdCtx::new().unwrap();
+ // Initialize and update to "Hello"
+ ctx.digest_init(Md::sha256()).unwrap();
+ ctx.digest_update(b"Hello").unwrap();
+ // Now reset, init to SHA-256 and use "World"
+ ctx.reset().unwrap();
+ ctx.digest_init(Md::sha256()).unwrap();
+ ctx.digest_update(b"World").unwrap();
+
+ let mut reset_result = vec![0; 32];
+ let result_len = ctx.digest_final(reset_result.as_mut_slice()).unwrap();
+ assert_eq!(result_len, reset_result.len());
+ // Validate result of digest of "World"
+ assert_eq!(reset_result, world_expected);
+ }
}
diff --git a/openssl/src/memcmp.rs b/src/memcmp.rs
similarity index 100%
rename from openssl/src/memcmp.rs
rename to src/memcmp.rs
diff --git a/openssl/src/nid.rs b/src/nid.rs
similarity index 98%
rename from openssl/src/nid.rs
rename to src/nid.rs
index d454428..eadae31 100644
--- a/openssl/src/nid.rs
+++ b/src/nid.rs
@@ -215,6 +215,12 @@
pub const SECT409R1: Nid = Nid(ffi::NID_sect409r1);
pub const SECT571K1: Nid = Nid(ffi::NID_sect571k1);
pub const SECT571R1: Nid = Nid(ffi::NID_sect571r1);
+ #[cfg(ossl110)]
+ pub const BRAINPOOL_P256R1: Nid = Nid(ffi::NID_brainpoolP256r1);
+ #[cfg(ossl110)]
+ pub const BRAINPOOL_P384R1: Nid = Nid(ffi::NID_brainpoolP384r1);
+ #[cfg(ossl110)]
+ pub const BRAINPOOL_P512R1: Nid = Nid(ffi::NID_brainpoolP512r1);
pub const WAP_WSG_IDM_ECID_WTLS1: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls1);
pub const WAP_WSG_IDM_ECID_WTLS3: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls3);
pub const WAP_WSG_IDM_ECID_WTLS4: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls4);
@@ -1068,6 +1074,20 @@
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(any(ossl111, libressl291))]
+ pub const SM3: Nid = Nid(ffi::NID_sm3);
+ #[cfg(ossl111)]
+ pub const SHA3_224: Nid = Nid(ffi::NID_sha3_224);
+ #[cfg(ossl111)]
+ pub const SHA3_256: Nid = Nid(ffi::NID_sha3_256);
+ #[cfg(ossl111)]
+ pub const SHA3_384: Nid = Nid(ffi::NID_sha3_384);
+ #[cfg(ossl111)]
+ pub const SHA3_512: Nid = Nid(ffi::NID_sha3_512);
+ #[cfg(ossl111)]
+ pub const SHAKE128: Nid = Nid(ffi::NID_shake128);
+ #[cfg(ossl111)]
+ pub const SHAKE256: Nid = Nid(ffi::NID_shake256);
}
#[cfg(test)]
diff --git a/openssl/src/ocsp.rs b/src/ocsp.rs
similarity index 100%
rename from openssl/src/ocsp.rs
rename to src/ocsp.rs
diff --git a/openssl/src/pkcs12.rs b/src/pkcs12.rs
similarity index 98%
rename from openssl/src/pkcs12.rs
rename to src/pkcs12.rs
index 758c7b9..d4e19dc 100644
--- a/openssl/src/pkcs12.rs
+++ b/src/pkcs12.rs
@@ -6,6 +6,7 @@
use std::ptr;
use crate::error::ErrorStack;
+#[cfg(not(boringssl))]
use crate::hash::MessageDigest;
use crate::nid::Nid;
use crate::pkey::{HasPrivate, PKey, PKeyRef, Private};
@@ -196,7 +197,7 @@
nid_key,
nid_cert,
self.iter,
- -1,
+ self.mac_iter,
keytype,
))
.map(Pkcs12)?;
@@ -268,7 +269,9 @@
let der = include_bytes!("../test/keystore-empty-chain.p12");
let pkcs12 = Pkcs12::from_der(der).unwrap();
let parsed = pkcs12.parse("cassandra").unwrap();
- assert!(parsed.chain.is_none());
+ if let Some(stack) = parsed.chain {
+ assert_eq!(stack.len(), 0);
+ }
}
#[test]
diff --git a/openssl/src/pkcs5.rs b/src/pkcs5.rs
similarity index 100%
rename from openssl/src/pkcs5.rs
rename to src/pkcs5.rs
diff --git a/openssl/src/pkcs7.rs b/src/pkcs7.rs
similarity index 97%
rename from openssl/src/pkcs7.rs
rename to src/pkcs7.rs
index e1b30f9..ae4571d 100644
--- a/openssl/src/pkcs7.rs
+++ b/src/pkcs7.rs
@@ -361,7 +361,9 @@
assert_eq!(content.expect("should be non-empty"), message.as_bytes());
}
+ /// https://marc.info/?l=openbsd-cvs&m=166602943014106&w=2
#[test]
+ #[cfg_attr(all(libressl360, not(libressl361)), ignore)]
fn sign_verify_test_normal() {
let cert = include_bytes!("../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
@@ -397,7 +399,9 @@
assert!(content.is_none());
}
+ /// https://marc.info/?l=openbsd-cvs&m=166602943014106&w=2
#[test]
+ #[cfg_attr(all(libressl360, not(libressl361)), ignore)]
fn signers() {
let cert = include_bytes!("../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
diff --git a/openssl/src/pkey.rs b/src/pkey.rs
similarity index 90%
rename from openssl/src/pkey.rs
rename to src/pkey.rs
index 5b5a4e0..7eaf068 100644
--- a/openssl/src/pkey.rs
+++ b/src/pkey.rs
@@ -80,7 +80,7 @@
pub const RSA: Id = Id(ffi::EVP_PKEY_RSA);
#[cfg(not(boringssl))]
pub const HMAC: Id = Id(ffi::EVP_PKEY_HMAC);
-#[cfg(not(boringssl))]
+ #[cfg(not(boringssl))]
pub const CMAC: Id = Id(ffi::EVP_PKEY_CMAC);
pub const DSA: Id = Id(ffi::EVP_PKEY_DSA);
pub const DH: Id = Id(ffi::EVP_PKEY_DH);
@@ -238,10 +238,10 @@
unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 }
}
- /// Raw byte representation of a public key
+ /// Raw byte representation of a public key.
///
/// This function only works for algorithms that support raw public keys.
- /// Currently this is: X25519, ED25519, X448 or ED448
+ /// Currently this is: [`Id::X25519`], [`Id::ED25519`], [`Id::X448`] or [`Id::ED448`].
#[corresponds(EVP_PKEY_get_raw_public_key)]
#[cfg(any(boringssl, ossl111))]
pub fn raw_public_key(&self) -> Result<Vec<u8>, ErrorStack> {
@@ -289,10 +289,10 @@
ffi::i2d_PrivateKey
}
- /// Raw byte representation of a private key
+ /// Raw byte representation of a private key.
///
/// This function only works for algorithms that support raw private keys.
- /// Currently this is: HMAC, X25519, ED25519, X448 or ED448
+ /// Currently this is: [`Id::HMAC`], [`Id::X25519`], [`Id::ED25519`], [`Id::X448`] or [`Id::ED448`].
#[corresponds(EVP_PKEY_get_raw_private_key)]
#[cfg(any(boringssl, ossl111))]
pub fn raw_private_key(&self) -> Result<Vec<u8>, ErrorStack> {
@@ -465,7 +465,7 @@
/// # Note
///
/// To compute CMAC values, use the `sign` module.
- #[cfg(any(not(boringssl), ossl110))]
+ #[cfg(all(not(boringssl), ossl110))]
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn cmac(cipher: &Cipher, key: &[u8]) -> Result<PKey<Private>, ErrorStack> {
let mut ctx = PkeyCtx::new_id(Id::CMAC)?;
@@ -482,25 +482,109 @@
ctx.keygen()
}
- /// Generates a new private Ed25519 key
+ /// Generates a new private X25519 key.
+ ///
+ /// To import a private key from raw bytes see [`PKey::private_key_from_raw_bytes`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+ /// use openssl::pkey::{PKey, Id};
+ /// use openssl::derive::Deriver;
+ ///
+ /// let public = // ...
+ /// # &PKey::generate_x25519()?.raw_public_key()?;
+ /// let public_key = PKey::public_key_from_raw_bytes(public, Id::X25519)?;
+ ///
+ /// let key = PKey::generate_x25519()?;
+ /// let mut deriver = Deriver::new(&key)?;
+ /// deriver.set_peer(&public_key)?;
+ ///
+ /// let secret = deriver.derive_to_vec()?;
+ /// assert_eq!(secret.len(), 32);
+ /// # Ok(()) }
+ /// ```
#[cfg(any(boringssl, ossl111))]
pub fn generate_x25519() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(Id::X25519)
}
- /// Generates a new private Ed448 key
+ /// Generates a new private X448 key.
+ ///
+ /// To import a private key from raw bytes see [`PKey::private_key_from_raw_bytes`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+ /// use openssl::pkey::{PKey, Id};
+ /// use openssl::derive::Deriver;
+ ///
+ /// let public = // ...
+ /// # &PKey::generate_x448()?.raw_public_key()?;
+ /// let public_key = PKey::public_key_from_raw_bytes(public, Id::X448)?;
+ ///
+ /// let key = PKey::generate_x448()?;
+ /// let mut deriver = Deriver::new(&key)?;
+ /// deriver.set_peer(&public_key)?;
+ ///
+ /// let secret = deriver.derive_to_vec()?;
+ /// assert_eq!(secret.len(), 56);
+ /// # Ok(()) }
+ /// ```
#[cfg(ossl111)]
pub fn generate_x448() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(Id::X448)
}
- /// Generates a new private Ed25519 key
+ /// Generates a new private Ed25519 key.
+ ///
+ /// To import a private key from raw bytes see [`PKey::private_key_from_raw_bytes`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+ /// use openssl::pkey::{PKey, Id};
+ /// use openssl::sign::Signer;
+ ///
+ /// let key = PKey::generate_ed25519()?;
+ /// let public_key = key.raw_public_key()?;
+ ///
+ /// let mut signer = Signer::new_without_digest(&key)?;
+ /// let digest = // ...
+ /// # &vec![0; 32];
+ /// let signature = signer.sign_oneshot_to_vec(digest)?;
+ /// assert_eq!(signature.len(), 64);
+ /// # Ok(()) }
+ /// ```
#[cfg(any(boringssl, ossl111))]
pub fn generate_ed25519() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(Id::ED25519)
}
- /// Generates a new private Ed448 key
+ /// Generates a new private Ed448 key.
+ ///
+ /// To import a private key from raw bytes see [`PKey::private_key_from_raw_bytes`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+ /// use openssl::pkey::{PKey, Id};
+ /// use openssl::sign::Signer;
+ ///
+ /// let key = PKey::generate_ed448()?;
+ /// let public_key = key.raw_public_key()?;
+ ///
+ /// let mut signer = Signer::new_without_digest(&key)?;
+ /// let digest = // ...
+ /// # &vec![0; 32];
+ /// let signature = signer.sign_oneshot_to_vec(digest)?;
+ /// assert_eq!(signature.len(), 114);
+ /// # Ok(()) }
+ /// ```
#[cfg(ossl111)]
pub fn generate_ed448() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(Id::ED448)
@@ -512,6 +596,8 @@
#[corresponds(EVP_EC_gen)]
#[cfg(ossl300)]
pub fn ec_gen(curve: &str) -> Result<PKey<Private>, ErrorStack> {
+ ffi::init();
+
let curve = CString::new(curve).unwrap();
unsafe {
let ptr = cvt_p(ffi::EVP_EC_gen(curve.as_ptr()))?;
@@ -767,6 +853,7 @@
mod tests {
use std::convert::TryInto;
+ #[cfg(not(boringssl))]
use crate::dh::Dh;
use crate::dsa::Dsa;
use crate::ec::EcKey;
diff --git a/openssl/src/pkey_ctx.rs b/src/pkey_ctx.rs
similarity index 96%
rename from openssl/src/pkey_ctx.rs
rename to src/pkey_ctx.rs
index a1d8a22..f79372f 100644
--- a/openssl/src/pkey_ctx.rs
+++ b/src/pkey_ctx.rs
@@ -19,20 +19,25 @@
//! let mut ciphertext = vec![];
//! ctx.encrypt_to_vec(data, &mut ciphertext).unwrap();
//! ```
-//!
-//! Generate a CMAC key
-//!
-//! ```
-//! use openssl::pkey_ctx::PkeyCtx;
-//! use openssl::pkey::Id;
-//! use openssl::cipher::Cipher;
-//!
-//! let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap();
-//! ctx.keygen_init().unwrap();
-//! ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap();
-//! ctx.set_keygen_mac_key(b"0123456789abcdef").unwrap();
-//! let cmac_key = ctx.keygen().unwrap();
-//! ```
+
+#![cfg_attr(
+ not(boringssl),
+ doc = r#"\
+Generate a CMAC key
+
+```
+use openssl::pkey_ctx::PkeyCtx;
+use openssl::pkey::Id;
+use openssl::cipher::Cipher;
+
+let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap();
+ctx.keygen_init().unwrap();
+ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap();
+ctx.set_keygen_mac_key(b"0123456789abcdef").unwrap();
+let cmac_key = ctx.keygen().unwrap();
+```"#
+)]
+
//!
//! Sign and verify data with RSA
//!
@@ -59,15 +64,15 @@
//! let valid = ctx.verify(text, &signature).unwrap();
//! assert!(valid);
//! ```
+#[cfg(not(boringssl))]
use crate::cipher::CipherRef;
use crate::error::ErrorStack;
use crate::md::MdRef;
use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private};
use crate::rsa::Padding;
-#[cfg(any(boringssl, ossl102, libressl310))]
-use crate::util;
use crate::{cvt, cvt_n, cvt_p};
use foreign_types::{ForeignType, ForeignTypeRef};
+#[cfg(not(boringssl))]
use libc::c_int;
use openssl_macros::corresponds;
use std::convert::TryFrom;
@@ -398,15 +403,20 @@
///
/// This is only useful for RSA keys.
#[corresponds(EVP_PKEY_CTX_set0_rsa_oaep_label)]
- #[cfg(any(ossl102, libressl310))]
+ #[cfg(any(ossl102, libressl310, boringssl))]
pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
- let len = c_int::try_from(label.len()).unwrap();
+ use crate::LenType;
+ let len = LenType::try_from(label.len()).unwrap();
unsafe {
let p = ffi::OPENSSL_malloc(label.len() as _);
ptr::copy_nonoverlapping(label.as_ptr(), p as *mut _, label.len());
- let r = cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(self.as_ptr(), p, len));
+ let r = cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
+ self.as_ptr(),
+ p as *mut _,
+ len,
+ ));
if r.is_err() {
ffi::OPENSSL_free(p);
}
@@ -591,6 +601,7 @@
#[cfg(test)]
mod test {
use super::*;
+ #[cfg(not(boringssl))]
use crate::cipher::Cipher;
use crate::ec::{EcGroup, EcKey};
#[cfg(any(ossl102, libressl310))]
diff --git a/openssl/src/provider.rs b/src/provider.rs
similarity index 100%
rename from openssl/src/provider.rs
rename to src/provider.rs
diff --git a/openssl/src/rand.rs b/src/rand.rs
similarity index 80%
rename from openssl/src/rand.rs
rename to src/rand.rs
index ff1dd44..8317951 100644
--- a/openssl/src/rand.rs
+++ b/src/rand.rs
@@ -10,17 +10,12 @@
//! let mut buf = [0; 256];
//! rand_bytes(&mut buf).unwrap();
//! ```
-use libc::{c_int, size_t};
+use libc::c_int;
-use crate::cvt;
use crate::error::ErrorStack;
+use crate::{cvt, LenType};
use openssl_macros::corresponds;
-#[cfg(not(boringssl))]
-type RandType = c_int;
-#[cfg(boringssl)]
-type RandType = size_t;
-
/// Fill buffer with cryptographically strong pseudo-random bytes.
///
/// # Examples
@@ -38,7 +33,7 @@
unsafe {
ffi::init();
assert!(buf.len() <= c_int::max_value() as usize);
- cvt(ffi::RAND_bytes(buf.as_mut_ptr(), buf.len() as RandType)).map(|_| ())
+ cvt(ffi::RAND_bytes(buf.as_mut_ptr(), buf.len() as LenType)).map(|_| ())
}
}
@@ -49,7 +44,7 @@
#[cfg(ossl111)]
pub fn keep_random_devices_open(keep: bool) {
unsafe {
- ffi::RAND_keep_random_devices_open(keep as RandType);
+ ffi::RAND_keep_random_devices_open(keep as LenType);
}
}
diff --git a/openssl/src/rsa.rs b/src/rsa.rs
similarity index 96%
rename from openssl/src/rsa.rs
rename to src/rsa.rs
index 0bb9e71..b5d0967 100644
--- a/openssl/src/rsa.rs
+++ b/src/rsa.rs
@@ -25,7 +25,7 @@
//! ```
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
-use libc::{c_int, size_t};
+use libc::c_int;
use std::fmt;
use std::mem;
use std::ptr;
@@ -34,14 +34,9 @@
use crate::error::ErrorStack;
use crate::pkey::{HasPrivate, HasPublic, Private, Public};
use crate::util::ForeignTypeRefExt;
-use crate::{cvt, cvt_n, cvt_p};
+use crate::{cvt, cvt_n, cvt_p, LenType};
use openssl_macros::corresponds;
-#[cfg(boringssl)]
-type BitType = size_t;
-#[cfg(not(boringssl))]
-type BitType = c_int;
-
/// Type of encryption padding to use.
///
/// Random length padding is primarily used to prevent attackers from
@@ -139,7 +134,7 @@
unsafe {
let len = cvt_n(ffi::RSA_private_decrypt(
- from.len() as BitType,
+ from.len() as LenType,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
@@ -167,7 +162,7 @@
unsafe {
let len = cvt_n(ffi::RSA_private_encrypt(
- from.len() as BitType,
+ from.len() as LenType,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
@@ -310,7 +305,7 @@
unsafe {
let len = cvt_n(ffi::RSA_public_decrypt(
- from.len() as BitType,
+ from.len() as LenType,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
@@ -337,7 +332,7 @@
unsafe {
let len = cvt_n(ffi::RSA_public_encrypt(
- from.len() as BitType,
+ from.len() as LenType,
from.as_ptr(),
to.as_mut_ptr(),
self.as_ptr(),
@@ -495,8 +490,18 @@
impl Rsa<Private> {
/// Creates a new RSA key with private components (public components are assumed).
///
- /// This a convenience method over
- /// `Rsa::build(n, e, d)?.set_factors(p, q)?.set_crt_params(dmp1, dmq1, iqmp)?.build()`
+ /// This a convenience method over:
+ /// ```
+ /// # use openssl::rsa::RsaPrivateKeyBuilder;
+ /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
+ /// # let bn = || openssl::bn::BigNum::new().unwrap();
+ /// # let (n, e, d, p, q, dmp1, dmq1, iqmp) = (bn(), bn(), bn(), bn(), bn(), bn(), bn(), bn());
+ /// RsaPrivateKeyBuilder::new(n, e, d)?
+ /// .set_factors(p, q)?
+ /// .set_crt_params(dmp1, dmq1, iqmp)?
+ /// .build();
+ /// # Ok(()) }
+ /// ```
#[allow(clippy::too_many_arguments, clippy::many_single_char_names)]
pub fn from_private_components(
n: BigNum,
diff --git a/openssl/src/sha.rs b/src/sha.rs
similarity index 100%
rename from openssl/src/sha.rs
rename to src/sha.rs
diff --git a/openssl/src/sign.rs b/src/sign.rs
similarity index 97%
rename from openssl/src/sign.rs
rename to src/sign.rs
index aecbaec..4de8ad0 100644
--- a/openssl/src/sign.rs
+++ b/src/sign.rs
@@ -34,33 +34,39 @@
//! verifier.update(data2).unwrap();
//! assert!(verifier.verify(&signature).unwrap());
//! ```
-//!
-//! Compute an HMAC:
-//!
-//! ```rust
-//! use openssl::hash::MessageDigest;
-//! use openssl::memcmp;
-//! use openssl::pkey::PKey;
-//! use openssl::sign::Signer;
-//!
-//! // Create a PKey
-//! let key = PKey::hmac(b"my secret").unwrap();
-//!
-//! let data = b"hello, world!";
-//! let data2 = b"hola, mundo!";
-//!
-//! // Compute the HMAC
-//! let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
-//! signer.update(data).unwrap();
-//! signer.update(data2).unwrap();
-//! let hmac = signer.sign_to_vec().unwrap();
-//!
-//! // `Verifier` cannot be used with HMACs; use the `memcmp::eq` function instead
-//! //
-//! // Do not simply check for equality with `==`!
-//! # let target = hmac.clone();
-//! assert!(memcmp::eq(&hmac, &target));
-//! ```
+
+#![cfg_attr(
+ not(boringssl),
+ doc = r#"\
+
+Compute an HMAC:
+
+```rust
+use openssl::hash::MessageDigest;
+use openssl::memcmp;
+use openssl::pkey::PKey;
+use openssl::sign::Signer;
+
+// Create a PKey
+let key = PKey::hmac(b"my secret").unwrap();
+
+let data = b"hello, world!";
+let data2 = b"hola, mundo!";
+
+// Compute the HMAC
+let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
+signer.update(data).unwrap();
+signer.update(data2).unwrap();
+let hmac = signer.sign_to_vec().unwrap();
+
+// `Verifier` cannot be used with HMACs; use the `memcmp::eq` function instead
+//
+// Do not simply check for equality with `==`!
+# let target = hmac.clone();
+assert!(memcmp::eq(&hmac, &target));
+```"#
+)]
+
use cfg_if::cfg_if;
use foreign_types::ForeignTypeRef;
use libc::c_int;
@@ -637,6 +643,7 @@
#[cfg(test)]
mod test {
use hex::{self, FromHex};
+ #[cfg(not(boringssl))]
use std::iter;
use crate::ec::{EcGroup, EcKey};
diff --git a/openssl/src/srtp.rs b/src/srtp.rs
similarity index 100%
rename from openssl/src/srtp.rs
rename to src/srtp.rs
diff --git a/openssl/src/ssl/bio.rs b/src/ssl/bio.rs
similarity index 98%
rename from openssl/src/ssl/bio.rs
rename to src/ssl/bio.rs
index 3ace35e..36cea23 100644
--- a/openssl/src/ssl/bio.rs
+++ b/src/ssl/bio.rs
@@ -183,7 +183,7 @@
let data = BIO_get_data(bio);
assert!(!data.is_null());
- Box::<StreamState<S>>::from_raw(data as *mut _);
+ let _ = Box::<StreamState<S>>::from_raw(data as *mut _);
BIO_set_data(bio, ptr::null_mut());
BIO_set_init(bio, 0);
1
@@ -257,7 +257,7 @@
impl Drop for BIO_METHOD {
fn drop(&mut self) {
unsafe {
- Box::<ffi::BIO_METHOD>::from_raw(self.0);
+ let _ = Box::<ffi::BIO_METHOD>::from_raw(self.0);
}
}
}
diff --git a/openssl/src/ssl/callbacks.rs b/src/ssl/callbacks.rs
similarity index 99%
rename from openssl/src/ssl/callbacks.rs
rename to src/ssl/callbacks.rs
index e4db9dc..45760dc 100644
--- a/openssl/src/ssl/callbacks.rs
+++ b/src/ssl/callbacks.rs
@@ -518,6 +518,7 @@
}
}
+#[cfg(not(boringssl))]
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
type CookiePtr = *const c_uchar;
@@ -526,6 +527,7 @@
}
}
+#[cfg(not(boringssl))]
pub extern "C" fn raw_cookie_verify<F>(
ssl: *mut ffi::SSL,
cookie: CookiePtr,
diff --git a/openssl/src/ssl/connector.rs b/src/ssl/connector.rs
similarity index 98%
rename from openssl/src/ssl/connector.rs
rename to src/ssl/connector.rs
index 991d3e2..39f729d 100644
--- a/openssl/src/ssl/connector.rs
+++ b/src/ssl/connector.rs
@@ -4,6 +4,8 @@
use crate::dh::Dh;
use crate::error::ErrorStack;
+#[cfg(any(ossl111, libressl340))]
+use crate::ssl::SslVersion;
use crate::ssl::{
HandshakeError, Ssl, SslContext, SslContextBuilder, SslContextRef, SslMethod, SslMode,
SslOptions, SslRef, SslStream, SslVerifyMode,
@@ -105,7 +107,7 @@
/// Returns a shared reference to the inner raw `SslContext`.
pub fn context(&self) -> &SslContextRef {
- &*self.0
+ &self.0
}
}
@@ -239,7 +241,7 @@
ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
)?;
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
ctx.set_ciphersuites(
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256",
)?;
@@ -251,13 +253,13 @@
/// This corresponds to the modern configuration of version 5 of Mozilla's server side TLS recommendations.
/// See its [documentation][docs] for more details on specifics.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
pub fn mozilla_modern_v5(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
let mut ctx = ctx(method)?;
- ctx.set_options(SslOptions::NO_SSL_MASK & !SslOptions::NO_TLSV1_3);
+ ctx.set_min_proto_version(Some(SslVersion::TLS1_3))?;
ctx.set_ciphersuites(
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256",
)?;
@@ -275,7 +277,7 @@
pub fn mozilla_intermediate(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
let mut ctx = ctx(method)?;
ctx.set_options(SslOptions::CIPHER_SERVER_PREFERENCE);
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
ctx.set_options(SslOptions::NO_TLSV1_3);
let dh = Dh::params_from_pem(FFDHE_2048.as_bytes())?;
ctx.set_tmp_dh(&dh)?;
@@ -305,7 +307,7 @@
ctx.set_options(
SslOptions::CIPHER_SERVER_PREFERENCE | SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1,
);
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
ctx.set_options(SslOptions::NO_TLSV1_3);
setup_curves(&mut ctx)?;
ctx.set_cipher_list(
@@ -332,7 +334,7 @@
/// Returns a shared reference to the inner raw `SslContext`.
pub fn context(&self) -> &SslContextRef {
- &*self.0
+ &self.0
}
}
diff --git a/openssl/src/ssl/error.rs b/src/ssl/error.rs
similarity index 100%
rename from openssl/src/ssl/error.rs
rename to src/ssl/error.rs
diff --git a/openssl/src/ssl/mod.rs b/src/ssl/mod.rs
similarity index 95%
rename from openssl/src/ssl/mod.rs
rename to src/ssl/mod.rs
index 8d01db0..4f349a4 100644
--- a/openssl/src/ssl/mod.rs
+++ b/src/ssl/mod.rs
@@ -57,27 +57,6 @@
//! }
//! }
//! ```
-// use bitflags::bitflags;
-// use cfg_if::cfg_if;
-// use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
-use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void};
-// use once_cell::sync::{Lazy, OnceCell};
-// use std::any::TypeId;
-// use std::cmp;
-// use std::collections::HashMap;
-// use std::ffi::{CStr, CString};
-// use std::fmt;
-// use std::io;
-// use std::io::prelude::*;
-// use std::marker::PhantomData;
-// use std::mem::{self, ManuallyDrop};
-// use std::ops::{Deref, DerefMut};
-// use std::panic::resume_unwind;
-// use std::path::Path;
-// use std::ptr;
-// use std::slice;
-// use std::str;
-// use std::sync::{Arc, Mutex};
use crate::dh::{Dh, DhRef};
#[cfg(all(ossl101, not(ossl110)))]
use crate::ec::EcKey;
@@ -86,7 +65,7 @@
use crate::ex_data::Index;
#[cfg(ossl111)]
use crate::hash::MessageDigest;
-#[cfg(ossl110)]
+#[cfg(any(ossl110, libressl270))]
use crate::nid::Nid;
use crate::pkey::{HasPrivate, PKeyRef, Params, Private};
use crate::srtp::{SrtpProtectionProfile, SrtpProtectionProfileRef};
@@ -103,6 +82,7 @@
use bitflags::bitflags;
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
+use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_void};
use once_cell::sync::{Lazy, OnceCell};
use openssl_macros::corresponds;
use std::any::TypeId;
@@ -155,7 +135,7 @@
if #[cfg(ossl300)] {
type SslOptionsRepr = u64;
} else if #[cfg(boringssl)] {
- type SslOptionsRepr = i32;
+ type SslOptionsRepr = u32;
} else {
type SslOptionsRepr = libc::c_ulong;
}
@@ -165,16 +145,16 @@
/// Options controlling the behavior of an `SslContext`.
pub struct SslOptions: SslOptionsRepr {
/// Disables a countermeasure against an SSLv3/TLSv1.0 vulnerability affecting CBC ciphers.
- const DONT_INSERT_EMPTY_FRAGMENTS = ffi::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
+ const DONT_INSERT_EMPTY_FRAGMENTS = ffi::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS as SslOptionsRepr;
/// A "reasonable default" set of options which enables compatibility flags.
#[cfg(not(boringssl))]
- const ALL = ffi::SSL_OP_ALL;
+ const ALL = ffi::SSL_OP_ALL as SslOptionsRepr;
/// Do not query the MTU.
///
/// Only affects DTLS connections.
- const NO_QUERY_MTU = ffi::SSL_OP_NO_QUERY_MTU;
+ const NO_QUERY_MTU = ffi::SSL_OP_NO_QUERY_MTU as SslOptionsRepr;
/// Enables Cookie Exchange as described in [RFC 4347 Section 4.2.1].
///
@@ -182,75 +162,75 @@
///
/// [RFC 4347 Section 4.2.1]: https://tools.ietf.org/html/rfc4347#section-4.2.1
#[cfg(not(boringssl))]
- const COOKIE_EXCHANGE = ffi::SSL_OP_COOKIE_EXCHANGE;
+ const COOKIE_EXCHANGE = ffi::SSL_OP_COOKIE_EXCHANGE as SslOptionsRepr;
/// Disables the use of session tickets for session resumption.
- const NO_TICKET = ffi::SSL_OP_NO_TICKET;
+ const NO_TICKET = ffi::SSL_OP_NO_TICKET as SslOptionsRepr;
/// Always start a new session when performing a renegotiation on the server side.
#[cfg(not(boringssl))]
const NO_SESSION_RESUMPTION_ON_RENEGOTIATION =
- ffi::SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
+ ffi::SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION as SslOptionsRepr;
/// Disables the use of TLS compression.
#[cfg(not(boringssl))]
- const NO_COMPRESSION = ffi::SSL_OP_NO_COMPRESSION;
+ const NO_COMPRESSION = ffi::SSL_OP_NO_COMPRESSION as SslOptionsRepr;
/// Allow legacy insecure renegotiation with servers or clients that do not support secure
/// renegotiation.
const ALLOW_UNSAFE_LEGACY_RENEGOTIATION =
- ffi::SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
+ ffi::SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION as SslOptionsRepr;
/// Creates a new key for each session when using ECDHE.
///
/// This is always enabled in OpenSSL 1.1.0.
- const SINGLE_ECDH_USE = ffi::SSL_OP_SINGLE_ECDH_USE;
+ const SINGLE_ECDH_USE = ffi::SSL_OP_SINGLE_ECDH_USE as SslOptionsRepr;
/// Creates a new key for each session when using DHE.
///
/// This is always enabled in OpenSSL 1.1.0.
- const SINGLE_DH_USE = ffi::SSL_OP_SINGLE_DH_USE;
+ const SINGLE_DH_USE = ffi::SSL_OP_SINGLE_DH_USE as SslOptionsRepr;
/// Use the server's preferences rather than the client's when selecting a cipher.
///
/// This has no effect on the client side.
- const CIPHER_SERVER_PREFERENCE = ffi::SSL_OP_CIPHER_SERVER_PREFERENCE;
+ const CIPHER_SERVER_PREFERENCE = ffi::SSL_OP_CIPHER_SERVER_PREFERENCE as SslOptionsRepr;
/// Disables version rollback attach detection.
- const TLS_ROLLBACK_BUG = ffi::SSL_OP_TLS_ROLLBACK_BUG;
+ const TLS_ROLLBACK_BUG = ffi::SSL_OP_TLS_ROLLBACK_BUG as SslOptionsRepr;
/// Disables the use of SSLv2.
- const NO_SSLV2 = ffi::SSL_OP_NO_SSLv2;
+ const NO_SSLV2 = ffi::SSL_OP_NO_SSLv2 as SslOptionsRepr;
/// Disables the use of SSLv3.
- const NO_SSLV3 = ffi::SSL_OP_NO_SSLv3;
+ const NO_SSLV3 = ffi::SSL_OP_NO_SSLv3 as SslOptionsRepr;
/// Disables the use of TLSv1.0.
- const NO_TLSV1 = ffi::SSL_OP_NO_TLSv1;
+ const NO_TLSV1 = ffi::SSL_OP_NO_TLSv1 as SslOptionsRepr;
/// Disables the use of TLSv1.1.
- const NO_TLSV1_1 = ffi::SSL_OP_NO_TLSv1_1;
+ const NO_TLSV1_1 = ffi::SSL_OP_NO_TLSv1_1 as SslOptionsRepr;
/// Disables the use of TLSv1.2.
- const NO_TLSV1_2 = ffi::SSL_OP_NO_TLSv1_2;
+ const NO_TLSV1_2 = ffi::SSL_OP_NO_TLSv1_2 as SslOptionsRepr;
/// Disables the use of TLSv1.3.
///
- /// Requires OpenSSL 1.1.1 or newer.
- #[cfg(ossl111)]
- const NO_TLSV1_3 = ffi::SSL_OP_NO_TLSv1_3;
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
+ #[cfg(any(boringssl, ossl111, libressl340))]
+ const NO_TLSV1_3 = ffi::SSL_OP_NO_TLSv1_3 as SslOptionsRepr;
/// Disables the use of DTLSv1.0
///
/// Requires OpenSSL 1.0.2 or LibreSSL 3.3.2 or newer.
- #[cfg(any(ossl102, ossl110, libressl332))]
- const NO_DTLSV1 = ffi::SSL_OP_NO_DTLSv1;
+ #[cfg(any(boringssl, ossl102, ossl110, libressl332))]
+ const NO_DTLSV1 = ffi::SSL_OP_NO_DTLSv1 as SslOptionsRepr;
/// Disables the use of DTLSv1.2.
///
/// Requires OpenSSL 1.0.2 or LibreSSL 3.3.2 or newer.
- #[cfg(any(ossl102, ossl110, libressl332))]
- const NO_DTLSV1_2 = ffi::SSL_OP_NO_DTLSv1_2;
+ #[cfg(any(boringssl, ossl102, ossl110, libressl332))]
+ const NO_DTLSV1_2 = ffi::SSL_OP_NO_DTLSv1_2 as SslOptionsRepr;
/// Disables the use of all (D)TLS protocol versions.
///
@@ -268,20 +248,34 @@
/// let options = SslOptions::NO_SSL_MASK & !SslOptions::NO_TLSV1_2;
/// ```
#[cfg(any(ossl102, ossl110))]
- const NO_SSL_MASK = ffi::SSL_OP_NO_SSL_MASK;
+ const NO_SSL_MASK = ffi::SSL_OP_NO_SSL_MASK as SslOptionsRepr;
/// Disallow all renegotiation in TLSv1.2 and earlier.
///
/// Requires OpenSSL 1.1.0h or newer.
- #[cfg(ossl110h)]
- const NO_RENEGOTIATION = ffi::SSL_OP_NO_RENEGOTIATION;
+ #[cfg(any(boringssl, ossl110h))]
+ const NO_RENEGOTIATION = ffi::SSL_OP_NO_RENEGOTIATION as SslOptionsRepr;
/// Enable TLSv1.3 Compatibility mode.
///
/// Requires OpenSSL 1.1.1 or newer. This is on by default in 1.1.1, but a future version
/// may have this disabled by default.
#[cfg(ossl111)]
- const ENABLE_MIDDLEBOX_COMPAT = ffi::SSL_OP_ENABLE_MIDDLEBOX_COMPAT;
+ const ENABLE_MIDDLEBOX_COMPAT = ffi::SSL_OP_ENABLE_MIDDLEBOX_COMPAT as SslOptionsRepr;
+
+ /// Prioritize ChaCha ciphers when preferred by clients.
+ ///
+ /// Temporarily reprioritize ChaCha20-Poly1305 ciphers to the top of the server cipher list
+ /// if a ChaCha20-Poly1305 cipher is at the top of the client cipher list. This helps those
+ /// clients (e.g. mobile) use ChaCha20-Poly1305 if that cipher is anywhere in the server
+ /// cipher list; but still allows other clients to use AES and other ciphers.
+ ///
+ /// Requires enable [`SslOptions::CIPHER_SERVER_PREFERENCE`].
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// [`SslOptions::CIPHER_SERVER_PREFERENCE`]: struct.SslOptions.html#associatedconstant.CIPHER_SERVER_PREFERENCE
+ #[cfg(ossl111)]
+ const PRIORITIZE_CHACHA = ffi::SSL_OP_PRIORITIZE_CHACHA as SslOptionsRepr;
}
}
@@ -564,7 +558,7 @@
_argp: *mut c_void,
) {
if !ptr.is_null() {
- Box::<T>::from_raw(ptr as *mut T);
+ let _ = Box::<T>::from_raw(ptr as *mut T);
}
}
@@ -647,27 +641,21 @@
/// TLSv1.3
///
- /// Requires OpenSSL 1.1.1 or newer.
- #[cfg(ossl111)]
+ /// 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);
}
cfg_if! {
if #[cfg(boringssl)] {
- type SslTy = i32;
- type SslModeTy = i32;
type SslCacheTy = i64;
- type SslCacheSize = c_ulong;
+ type SslCacheSize = libc::c_ulong;
type MtuTy = u32;
- type BitTy = u32;
type SizeTy = usize;
} else {
- type SslTy = u64;
- type SslModeTy = i64;
type SslCacheTy = i64;
type SslCacheSize = c_long;
- type MtuTy = i64;
- type BitTy = u64;
+ type MtuTy = c_long;
type SizeTy = u32;
}
}
@@ -778,13 +766,12 @@
// still stored in ex data to manage the lifetime.
let arg = self.set_ex_data_inner(SslContext::cached_ex_index::<F>(), callback);
ffi::SSL_CTX_set_tlsext_servername_arg(self.as_ptr(), arg);
-
- let f: extern "C" fn(_, _, _) -> _ = raw_sni::<F>;
+ #[cfg(boringssl)]
+ ffi::SSL_CTX_set_tlsext_servername_callback(self.as_ptr(), Some(raw_sni::<F>));
#[cfg(not(boringssl))]
- let f: extern "C" fn() = mem::transmute(f);
- ffi::SSL_CTX_set_tlsext_servername_callback(
+ ffi::SSL_CTX_set_tlsext_servername_callback__fixed_rust(
self.as_ptr(),
- Some(f),
+ Some(raw_sni::<F>),
);
}
}
@@ -840,7 +827,7 @@
#[corresponds(SSL_CTX_set_mode)]
pub fn set_mode(&mut self, mode: SslMode) -> SslMode {
unsafe {
- let bits = ffi::SSL_CTX_set_mode(self.as_ptr(), mode.bits() as MtuTy) as SslModeTy;
+ let bits = ffi::SSL_CTX_set_mode(self.as_ptr(), mode.bits() as MtuTy) as SslBitType;
SslMode { bits }
}
}
@@ -939,7 +926,6 @@
/// Add the provided CA certificate to the list sent by the server to the client when
/// requesting client-side TLS authentication.
#[corresponds(SSL_CTX_add_client_CA)]
- #[cfg(not(libressl))]
pub fn add_client_ca(&mut self, cacert: &X509Ref) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_CTX_add_client_CA(self.as_ptr(), cacert.as_ptr())).map(|_| ()) }
}
@@ -1081,9 +1067,9 @@
/// The format consists of TLSv1.3 cipher suite names separated by `:` characters in order of
/// preference.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
#[corresponds(SSL_CTX_set_ciphersuites)]
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
pub fn set_ciphersuites(&mut self, cipher_list: &str) -> Result<(), ErrorStack> {
let cipher_list = CString::new(cipher_list).unwrap();
unsafe {
@@ -1113,14 +1099,14 @@
#[corresponds(SSL_CTX_set_options)]
pub fn set_options(&mut self, option: SslOptions) -> SslOptions {
let bits =
- unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits() as BitTy) } as SslTy;
+ unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits()) } as SslOptionsRepr;
SslOptions { bits }
}
/// Returns the options used by the context.
#[corresponds(SSL_CTX_get_options)]
pub fn options(&self) -> SslOptions {
- let bits = unsafe { ffi::SSL_CTX_get_options(self.as_ptr()) } as SslTy;
+ let bits = unsafe { ffi::SSL_CTX_get_options(self.as_ptr()) } as SslOptionsRepr;
SslOptions { bits }
}
@@ -1128,7 +1114,7 @@
#[corresponds(SSL_CTX_clear_options)]
pub fn clear_options(&mut self, option: SslOptions) -> SslOptions {
let bits =
- unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits() as BitTy) } as SslTy;
+ unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits()) } as SslOptionsRepr;
SslOptions { bits }
}
@@ -1632,9 +1618,9 @@
///
/// Defaults to 0.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
#[corresponds(SSL_CTX_set_max_early_data)]
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
pub fn set_max_early_data(&mut self, bytes: u32) -> Result<(), ErrorStack> {
if unsafe { ffi::SSL_CTX_set_max_early_data(self.as_ptr(), bytes) } == 1 {
Ok(())
@@ -1691,9 +1677,9 @@
/// Sets the context's supported elliptic curve groups.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 2.5.1 or newer.
#[corresponds(SSL_CTX_set1_groups_list)]
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl251))]
pub fn set_groups_list(&mut self, groups: &str) -> Result<(), ErrorStack> {
let groups = CString::new(groups).unwrap();
unsafe {
@@ -1791,9 +1777,9 @@
impl SslContextRef {
/// Returns the certificate associated with this `SslContext`, if present.
///
- /// Requires OpenSSL 1.0.2 or newer.
+ /// Requires OpenSSL 1.0.2 or LibreSSL 2.7.0 or newer.
#[corresponds(SSL_CTX_get0_certificate)]
- #[cfg(any(ossl102, ossl110))]
+ #[cfg(any(ossl102, libressl270))]
pub fn certificate(&self) -> Option<&X509Ref> {
unsafe {
let ptr = ffi::SSL_CTX_get0_certificate(self.as_ptr());
@@ -1803,9 +1789,9 @@
/// Returns the private key associated with this `SslContext`, if present.
///
- /// Requires OpenSSL 1.0.2 or newer.
+ /// Requires OpenSSL 1.0.2 or LibreSSL 3.4.0 or newer.
#[corresponds(SSL_CTX_get0_privatekey)]
- #[cfg(any(ossl102, ossl110))]
+ #[cfg(any(ossl102, libressl340))]
pub fn private_key(&self) -> Option<&PKeyRef<Private>> {
unsafe {
let ptr = ffi::SSL_CTX_get0_privatekey(self.as_ptr());
@@ -1844,9 +1830,9 @@
/// Gets the maximum amount of early data that will be accepted on incoming connections.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
#[corresponds(SSL_CTX_get_max_early_data)]
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
pub fn max_early_data(&self) -> u32 {
unsafe { ffi::SSL_CTX_get_max_early_data(self.as_ptr()) }
}
@@ -2026,9 +2012,9 @@
/// Returns the NID corresponding to the cipher.
///
- /// Requires OpenSSL 1.1.0 or newer.
+ /// Requires OpenSSL 1.1.0 or LibreSSL 2.7.0 or newer.
#[corresponds(SSL_CIPHER_get_cipher_nid)]
- #[cfg(any(ossl110))]
+ #[cfg(any(ossl110, libressl270))]
pub fn cipher_nid(&self) -> Option<Nid> {
let n = unsafe { ffi::SSL_CIPHER_get_cipher_nid(self.as_ptr()) };
if n == 0 {
@@ -2108,9 +2094,9 @@
/// Gets the maximum amount of early data that can be sent on this session.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
#[corresponds(SSL_SESSION_get_max_early_data)]
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
pub fn max_early_data(&self) -> u32 {
unsafe { ffi::SSL_SESSION_get_max_early_data(self.as_ptr()) }
}
@@ -2133,9 +2119,9 @@
/// Returns the session's TLS protocol version.
///
- /// Requires OpenSSL 1.1.0 or newer.
+ /// Requires OpenSSL 1.1.0 or LibreSSL 2.7.0 or newer.
#[corresponds(SSL_SESSION_get_protocol_version)]
- #[cfg(ossl110)]
+ #[cfg(any(ossl110, libressl270))]
pub fn protocol_version(&self) -> SslVersion {
unsafe {
let version = ffi::SSL_SESSION_get_protocol_version(self.as_ptr());
@@ -2363,7 +2349,7 @@
#[cfg(boringssl)]
ffi::SSL_set_tmp_dh_callback(self.as_ptr(), Some(raw_tmp_dh_ssl::<F>));
#[cfg(not(boringssl))]
- ffi::SSL_set_tmp_dh_callback(self.as_ptr(), raw_tmp_dh_ssl::<F>);
+ ffi::SSL_set_tmp_dh_callback__fixed_rust(self.as_ptr(), Some(raw_tmp_dh_ssl::<F>));
}
}
@@ -2394,11 +2380,11 @@
/// Like [`SslContextBuilder::set_ecdh_auto`].
///
- /// Requires OpenSSL 1.0.2.
+ /// Requires OpenSSL 1.0.2 or LibreSSL.
///
/// [`SslContextBuilder::set_tmp_ecdh`]: struct.SslContextBuilder.html#method.set_tmp_ecdh
#[corresponds(SSL_set_ecdh_auto)]
- #[cfg(all(ossl102, not(ossl110)))]
+ #[cfg(any(all(ossl102, not(ossl110)), libressl))]
pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) }
}
@@ -2726,9 +2712,9 @@
/// Returns the number of bytes copied, or if the buffer is empty, the size of the `client_random`
/// value.
///
- /// Requires OpenSSL 1.1.0 or newer.
+ /// Requires OpenSSL 1.1.0 or LibreSSL 2.7.0 or newer.
#[corresponds(SSL_get_client_random)]
- #[cfg(any(ossl110))]
+ #[cfg(any(ossl110, libressl270))]
pub fn client_random(&self, buf: &mut [u8]) -> usize {
unsafe {
ffi::SSL_get_client_random(self.as_ptr(), buf.as_mut_ptr() as *mut c_uchar, buf.len())
@@ -2740,9 +2726,9 @@
/// Returns the number of bytes copied, or if the buffer is empty, the size of the `server_random`
/// value.
///
- /// Requires OpenSSL 1.1.0 or newer.
+ /// Requires OpenSSL 1.1.0 or LibreSSL 2.7.0 or newer.
#[corresponds(SSL_get_server_random)]
- #[cfg(any(ossl110))]
+ #[cfg(any(ossl110, libressl270))]
pub fn server_random(&self, buf: &mut [u8]) -> usize {
unsafe {
ffi::SSL_get_server_random(self.as_ptr(), buf.as_mut_ptr() as *mut c_uchar, buf.len())
@@ -2874,7 +2860,7 @@
cvt(ffi::SSL_set_tlsext_status_ocsp_resp(
self.as_ptr(),
p as *mut c_uchar,
- response.len() as i64,
+ response.len() as c_long,
) as c_int)
.map(|_| ())
}
@@ -2930,9 +2916,9 @@
/// Sets the maximum amount of early data that will be accepted on this connection.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
#[corresponds(SSL_set_max_early_data)]
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
pub fn set_max_early_data(&mut self, bytes: u32) -> Result<(), ErrorStack> {
if unsafe { ffi::SSL_set_max_early_data(self.as_ptr(), bytes) } == 1 {
Ok(())
@@ -2943,9 +2929,9 @@
/// Gets the maximum amount of early data that can be sent on this connection.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
#[corresponds(SSL_get_max_early_data)]
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
pub fn max_early_data(&self) -> u32 {
unsafe { ffi::SSL_get_max_early_data(self.as_ptr()) }
}
@@ -3088,6 +3074,36 @@
pub fn set_mtu(&mut self, mtu: u32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_set_mtu(self.as_ptr(), mtu as MtuTy) as c_int).map(|_| ()) }
}
+
+ /// Returns the PSK identity hint used during connection setup.
+ ///
+ /// May return `None` if no PSK identity hint was used during the connection setup.
+ #[corresponds(SSL_get_psk_identity_hint)]
+ #[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
+ pub fn psk_identity_hint(&self) -> Option<&[u8]> {
+ unsafe {
+ let ptr = ffi::SSL_get_psk_identity_hint(self.as_ptr());
+ if ptr.is_null() {
+ None
+ } else {
+ Some(CStr::from_ptr(ptr).to_bytes())
+ }
+ }
+ }
+
+ /// Returns the PSK identity used during connection setup.
+ #[corresponds(SSL_get_psk_identity)]
+ #[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
+ pub fn psk_identity(&self) -> Option<&[u8]> {
+ unsafe {
+ let ptr = ffi::SSL_get_psk_identity(self.as_ptr());
+ if ptr.is_null() {
+ None
+ } else {
+ Some(CStr::from_ptr(ptr).to_bytes())
+ }
+ }
+ }
}
/// An SSL stream midway through the handshake process.
@@ -3223,9 +3239,9 @@
///
/// Returns `Ok(0)` if all early data has been read.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
#[corresponds(SSL_read_early_data)]
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
pub fn read_early_data(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
let mut read = 0;
let ret = unsafe {
@@ -3249,9 +3265,9 @@
/// Useful for reducing latency, but vulnerable to replay attacks. Call
/// [`SslRef::set_connect_state`] first.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
#[corresponds(SSL_write_early_data)]
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
pub fn write_early_data(&mut self, buf: &[u8]) -> Result<usize, Error> {
let mut written = 0;
let ret = unsafe {
@@ -3667,12 +3683,12 @@
///
/// Returns `Ok(0)` if all early data has been read.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
///
/// This corresponds to [`SSL_read_early_data`].
///
/// [`SSL_read_early_data`]: https://www.openssl.org/docs/manmaster/man3/SSL_read_early_data.html
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
pub fn read_early_data(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
self.inner.read_early_data(buf)
}
@@ -3682,12 +3698,12 @@
/// Useful for reducing latency, but vulnerable to replay attacks. Call
/// `set_connect_state` first.
///
- /// Requires OpenSSL 1.1.1 or newer.
+ /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
///
/// This corresponds to [`SSL_write_early_data`].
///
/// [`SSL_write_early_data`]: https://www.openssl.org/docs/manmaster/man3/SSL_write_early_data.html
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
pub fn write_early_data(&mut self, buf: &[u8]) -> Result<usize, Error> {
self.inner.write_early_data(buf)
}
diff --git a/openssl/src/ssl/test/mod.rs b/src/ssl/test/mod.rs
similarity index 96%
rename from openssl/src/ssl/test/mod.rs
rename to src/ssl/test/mod.rs
index 0c65029..ab8d79a 100644
--- a/openssl/src/ssl/test/mod.rs
+++ b/src/ssl/test/mod.rs
@@ -204,7 +204,7 @@
CALLED_BACK.store(true, Ordering::SeqCst);
let cert = x509.current_cert().unwrap();
let digest = cert.digest(MessageDigest::sha1()).unwrap();
- assert_eq!(hex::encode(&digest), expected);
+ assert_eq!(hex::encode(digest), expected);
true
});
@@ -226,7 +226,7 @@
CALLED_BACK.store(true, Ordering::SeqCst);
let cert = x509.current_cert().unwrap();
let digest = cert.digest(MessageDigest::sha1()).unwrap();
- assert_eq!(hex::encode(&digest), expected);
+ assert_eq!(hex::encode(digest), expected);
true
});
@@ -319,9 +319,9 @@
let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap();
ctx.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32")
.unwrap();
- ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
+ ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM)
.unwrap();
- ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM)
+ ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM)
.unwrap();
let mut ssl = Ssl::new(&ctx.build()).unwrap();
ssl.set_mtu(1500).unwrap();
@@ -375,9 +375,9 @@
let guard = thread::spawn(move || {
let stream = listener.accept().unwrap().0;
let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap();
- ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
+ ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM)
.unwrap();
- ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM)
+ ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM)
.unwrap();
let mut ssl = Ssl::new(&ctx.build()).unwrap();
ssl.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32")
@@ -555,7 +555,7 @@
}
#[test]
-#[cfg_attr(libressl321, ignore)]
+#[cfg_attr(all(libressl321, not(libressl340)), ignore)]
#[should_panic(expected = "blammo")]
fn flush_panic() {
struct ExplodingStream(TcpStream);
@@ -795,7 +795,7 @@
}
#[test]
-#[cfg(ossl111)]
+#[cfg(any(ossl111, libressl340))]
fn connector_client_server_mozilla_modern_v5() {
test_mozilla_server(SslAcceptor::mozilla_modern_v5);
}
@@ -843,7 +843,7 @@
}
#[test]
-#[cfg_attr(any(libressl321, boringssl), ignore)]
+#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl), ignore)]
fn tmp_dh_callback() {
static CALLED_BACK: AtomicBool = AtomicBool::new(false);
@@ -858,7 +858,7 @@
let mut client = server.client();
// TLS 1.3 has no DH suites, so make sure we don't pick that version
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
client.ctx().set_options(super::SslOptions::NO_TLSV1_3);
client.ctx().set_cipher_list("EDH").unwrap();
client.connect();
@@ -891,7 +891,7 @@
}
#[test]
-#[cfg_attr(any(libressl321, boringssl), ignore)]
+#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl), ignore)]
fn tmp_dh_callback_ssl() {
static CALLED_BACK: AtomicBool = AtomicBool::new(false);
@@ -908,7 +908,7 @@
let mut client = server.client();
// TLS 1.3 has no DH suites, so make sure we don't pick that version
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, libressl340))]
client.ctx().set_options(super::SslOptions::NO_TLSV1_3);
client.ctx().set_cipher_list("EDH").unwrap();
client.connect();
@@ -949,6 +949,7 @@
assert!(ssl.session().is_none());
}
+/// possible LibreSSL bug since 3.2.1
#[test]
#[cfg_attr(libressl321, ignore)]
fn active_session() {
@@ -1006,6 +1007,7 @@
assert!(CALLED_BACK_CLIENT.load(Ordering::SeqCst));
}
+/// possible LibreSSL bug since 3.2.1
#[test]
#[cfg_attr(libressl321, ignore)]
fn new_session_callback() {
@@ -1030,6 +1032,7 @@
assert!(CALLED_BACK.load(Ordering::SeqCst));
}
+/// possible LibreSSL bug since 3.2.1
#[test]
#[cfg_attr(libressl321, ignore)]
fn new_session_callback_swapped_ctx() {
@@ -1070,9 +1073,9 @@
let guard = thread::spawn(move || {
let stream = listener.accept().unwrap().0;
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
- ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
+ ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM)
.unwrap();
- ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM)
+ ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM)
.unwrap();
let ssl = Ssl::new(&ctx.build()).unwrap();
let mut stream = ssl.accept(stream).unwrap();
@@ -1268,10 +1271,10 @@
let mut server_ctx = SslContext::builder(SslMethod::tls()).unwrap();
server_ctx
- .set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
+ .set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM)
.unwrap();
server_ctx
- .set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM)
+ .set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM)
.unwrap();
const COOKIE: &[u8] = b"chocolate chip";
server_ctx.set_stateless_cookie_generate_cb(|_tls, buf| {
@@ -1317,9 +1320,7 @@
let mut server = Server::builder();
server.ctx().set_cipher_list(CIPHER).unwrap();
server.ctx().set_psk_server_callback(|_, identity, psk| {
- eprintln!("hello???!");
assert!(identity.unwrap_or(&[]) == CLIENT_IDENT);
- eprintln!("hello???!");
psk[..PSK.len()].copy_from_slice(PSK);
SERVER_CALLED.store(true, Ordering::SeqCst);
Ok(PSK.len())
@@ -1329,13 +1330,12 @@
let mut client = server.client();
// This test relies on TLS 1.2 suites
- #[cfg(ossl111)]
+ #[cfg(any(boringssl, ossl111))]
client.ctx().set_options(super::SslOptions::NO_TLSV1_3);
client.ctx().set_cipher_list(CIPHER).unwrap();
client
.ctx()
.set_psk_client_callback(move |_, _, identity, psk| {
- eprintln!("hello???! 2");
identity[..CLIENT_IDENT.len()].copy_from_slice(CLIENT_IDENT);
identity[CLIENT_IDENT.len()] = 0;
psk[..PSK.len()].copy_from_slice(PSK);
diff --git a/openssl/src/ssl/test/server.rs b/src/ssl/test/server.rs
similarity index 100%
rename from openssl/src/ssl/test/server.rs
rename to src/ssl/test/server.rs
diff --git a/openssl/src/stack.rs b/src/stack.rs
similarity index 95%
rename from openssl/src/stack.rs
rename to src/stack.rs
index 70098df..416efd5 100644
--- a/openssl/src/stack.rs
+++ b/src/stack.rs
@@ -1,6 +1,6 @@
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
-use libc::{c_int, size_t};
+use libc::c_int;
use std::borrow::Borrow;
use std::convert::AsRef;
use std::fmt;
@@ -11,12 +11,7 @@
use crate::error::ErrorStack;
use crate::util::ForeignTypeExt;
-use crate::{cvt, cvt_p};
-
-#[cfg(not(boringssl))]
-type IdxType = c_int;
-#[cfg(boringssl)]
-type IdxType = size_t;
+use crate::{cvt, cvt_p, LenType};
cfg_if! {
if #[cfg(ossl110)] {
@@ -85,7 +80,7 @@
fn into_iter(self) -> IntoIter<T> {
let it = IntoIter {
stack: self.0,
- idxs: 0..self.len() as IdxType,
+ idxs: 0..self.len() as LenType,
};
mem::forget(self);
it
@@ -94,13 +89,13 @@
impl<T: Stackable> AsRef<StackRef<T>> for Stack<T> {
fn as_ref(&self) -> &StackRef<T> {
- &*self
+ self
}
}
impl<T: Stackable> Borrow<StackRef<T>> for Stack<T> {
fn borrow(&self) -> &StackRef<T> {
- &*self
+ self
}
}
@@ -140,7 +135,7 @@
pub struct IntoIter<T: Stackable> {
stack: *mut T::StackType,
- idxs: Range<IdxType>,
+ idxs: Range<LenType>,
}
impl<T: Stackable> Drop for IntoIter<T> {
@@ -209,13 +204,13 @@
pub fn iter(&self) -> Iter<'_, T> {
Iter {
stack: self,
- idxs: 0..self.len() as IdxType,
+ idxs: 0..self.len() as LenType,
}
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut {
- idxs: 0..self.len() as IdxType,
+ idxs: 0..self.len() as LenType,
stack: self,
}
}
@@ -262,7 +257,7 @@
}
unsafe fn _get(&self, idx: usize) -> *mut T::CType {
- OPENSSL_sk_value(self.as_stack(), idx as IdxType) as *mut _
+ OPENSSL_sk_value(self.as_stack(), idx as LenType) as *mut _
}
}
@@ -319,7 +314,7 @@
/// An iterator over the stack's contents.
pub struct Iter<'a, T: Stackable> {
stack: &'a StackRef<T>,
- idxs: Range<IdxType>,
+ idxs: Range<LenType>,
}
impl<'a, T: Stackable> Iterator for Iter<'a, T> {
@@ -353,7 +348,7 @@
/// A mutable iterator over the stack's contents.
pub struct IterMut<'a, T: Stackable> {
stack: &'a mut StackRef<T>,
- idxs: Range<IdxType>,
+ idxs: Range<LenType>,
}
impl<'a, T: Stackable> Iterator for IterMut<'a, T> {
diff --git a/openssl/src/string.rs b/src/string.rs
similarity index 98%
rename from openssl/src/string.rs
rename to src/string.rs
index 559218e..95494b5 100644
--- a/openssl/src/string.rs
+++ b/src/string.rs
@@ -34,7 +34,7 @@
impl AsRef<str> for OpensslString {
fn as_ref(&self) -> &str {
- &**self
+ self
}
}
@@ -57,7 +57,7 @@
impl AsRef<str> for OpensslStringRef {
fn as_ref(&self) -> &str {
- &*self
+ self
}
}
diff --git a/openssl/src/symm.rs b/src/symm.rs
similarity index 95%
rename from openssl/src/symm.rs
rename to src/symm.rs
index 9c9371e..beff5fc 100644
--- a/openssl/src/symm.rs
+++ b/src/symm.rs
@@ -51,11 +51,6 @@
//! assert_eq!("Foo bar", output_string);
//! println!("Decrypted: '{}'", output_string);
//! ```
-
-use libc::{c_int, c_uint};
-use std::cmp;
-use std::ptr;
-
use crate::cipher::CipherRef;
use crate::cipher_ctx::{CipherCtx, CipherCtxRef};
use crate::error::ErrorStack;
@@ -327,6 +322,31 @@
unsafe { Cipher(ffi::EVP_seed_ofb()) }
}
+ #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
+ pub fn sm4_ecb() -> Cipher {
+ unsafe { Cipher(ffi::EVP_sm4_ecb()) }
+ }
+
+ #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
+ pub fn sm4_cbc() -> Cipher {
+ unsafe { Cipher(ffi::EVP_sm4_cbc()) }
+ }
+
+ #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
+ pub fn sm4_ctr() -> Cipher {
+ unsafe { Cipher(ffi::EVP_sm4_ctr()) }
+ }
+
+ #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
+ pub fn sm4_cfb128() -> Cipher {
+ unsafe { Cipher(ffi::EVP_sm4_cfb128()) }
+ }
+
+ #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
+ pub fn sm4_ofb() -> Cipher {
+ unsafe { Cipher(ffi::EVP_sm4_ofb()) }
+ }
+
/// Creates a `Cipher` from a raw pointer to its OpenSSL type.
///
/// # Safety
@@ -757,29 +777,24 @@
Ok(out)
}
-#[cfg(not(boringssl))]
-type CipherRet = c_int;
-#[cfg(boringssl)]
-type CipherRet = c_uint;
-
cfg_if! {
if #[cfg(any(boringssl, ossl110, libressl273))] {
use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
} else {
- use libc::c_int;
+ use crate::LenType;
#[allow(bad_style)]
- pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> CipherRet {
+ pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> LenType {
(*ptr).iv_len
}
#[allow(bad_style)]
- pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> CipherRet {
+ pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> LenType {
(*ptr).block_size
}
#[allow(bad_style)]
- pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> CipherRet {
+ pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> LenType {
(*ptr).key_len
}
}
@@ -909,6 +924,7 @@
}
}
+ #[cfg(not(boringssl))]
fn cipher_test_nopad(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) {
let pt = Vec::from_hex(pt).unwrap();
let ct = Vec::from_hex(ct).unwrap();
@@ -1574,4 +1590,46 @@
cipher_test(super::Cipher::seed_ofb(), pt, ct, key, iv);
}
+
+ // GB/T 32907-2016
+ // http://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=7803DE42D3BC5E80B0C3E5D8E873D56A
+ #[test]
+ #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
+ fn test_sm4_ecb() {
+ use std::mem;
+
+ let key = vec![
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54,
+ 0x32, 0x10,
+ ];
+ let pt = vec![
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54,
+ 0x32, 0x10,
+ ];
+ let ct = vec![
+ 0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e, 0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e,
+ 0x42, 0x46,
+ ];
+ let ct1 = vec![
+ 0x59, 0x52, 0x98, 0xc7, 0xc6, 0xfd, 0x27, 0x1f, 0x04, 0x02, 0xf8, 0x04, 0xc3, 0x3d,
+ 0x3f, 0x66,
+ ];
+
+ let block_size = Cipher::sm4_ecb().block_size();
+ let mut c = Crypter::new(Cipher::sm4_ecb(), Mode::Encrypt, &key, None).unwrap();
+ c.pad(false);
+
+ // 1 round
+ let mut r = vec![0; pt.len() + Cipher::sm4_ecb().block_size()];
+ let count = c.update(&pt, &mut r).unwrap();
+ assert_eq!(ct, &r[..count]);
+
+ // 1000000 rounds
+ let mut r1 = vec![0; pt.len() + Cipher::sm4_ecb().block_size()];
+ for _ in 0..999999 {
+ c.update(&r[..block_size], &mut r1).unwrap();
+ mem::swap(&mut r, &mut r1);
+ }
+ assert_eq!(ct1, &r[..count]);
+ }
}
diff --git a/openssl/src/util.rs b/src/util.rs
similarity index 77%
rename from openssl/src/util.rs
rename to src/util.rs
index be04030..d852a4b 100644
--- a/openssl/src/util.rs
+++ b/src/util.rs
@@ -1,9 +1,6 @@
use crate::error::ErrorStack;
use foreign_types::{ForeignType, ForeignTypeRef};
-use std::convert::TryFrom;
use libc::{c_char, c_int, c_void};
-use crate::{cvt, cvt_p};
-use cfg_if::cfg_if;
use std::any::Any;
use std::panic::{self, AssertUnwindSafe};
use std::slice;
@@ -94,30 +91,3 @@
}
}
impl<FT: ForeignTypeRef> ForeignTypeRefExt for FT {}
-
-#[track_caller]
-#[inline]
-pub fn crypto_malloc(len: usize) -> Result<*mut c_void, ErrorStack> {
- // 1.0.2 uses c_int but 1.1.0+ uses size_t
- let len = TryFrom::try_from(len).unwrap();
-
- unsafe {
- cvt_p(ffi::CRYPTO_malloc(
- len,
- concat!(file!(), "\0").as_ptr() as *const _,
- line!() as _,
- ))
- }
-}
-
-#[track_caller]
-#[inline]
-pub unsafe fn crypto_free(ptr: *mut c_void) {
- cfg_if! {
- if #[cfg(any(ossl110, boringssl))] {
- ffi::CRYPTO_free(ptr, concat!(file!(), "\0").as_ptr() as *const _, line!() as _);
- } else {
- ffi::CRYPTO_free(ptr);
- }
- }
-}
diff --git a/openssl/src/version.rs b/src/version.rs
similarity index 100%
rename from openssl/src/version.rs
rename to src/version.rs
diff --git a/openssl/src/x509/extension.rs b/src/x509/extension.rs
similarity index 100%
rename from openssl/src/x509/extension.rs
rename to src/x509/extension.rs
diff --git a/openssl/src/x509/mod.rs b/src/x509/mod.rs
similarity index 93%
rename from openssl/src/x509/mod.rs
rename to src/x509/mod.rs
index 4faa26f..45f2467 100644
--- a/openssl/src/x509/mod.rs
+++ b/src/x509/mod.rs
@@ -10,6 +10,7 @@
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_int, c_long, c_uint};
+use std::cmp::{self, Ordering};
use std::error::Error;
use std::ffi::{CStr, CString};
use std::fmt;
@@ -227,7 +228,7 @@
/// the X.509 standard should pass `2` to this method.
#[corresponds(X509_set_version)]
pub fn set_version(&mut self, version: i32) -> Result<(), ErrorStack> {
- unsafe { cvt(ffi::X509_set_version(self.0.as_ptr(), version.into())).map(|_| ()) }
+ unsafe { cvt(ffi::X509_set_version(self.0.as_ptr(), version as c_long)).map(|_| ()) }
}
/// Sets the serial number of the certificate.
@@ -598,6 +599,13 @@
to_der,
ffi::i2d_X509
}
+
+ to_pem! {
+ /// Converts the certificate to human readable text.
+ #[corresponds(X509_print)]
+ to_text,
+ ffi::X509_print
+ }
}
impl ToOwned for X509Ref {
@@ -611,6 +619,41 @@
}
}
+impl Ord for X509Ref {
+ fn cmp(&self, other: &Self) -> cmp::Ordering {
+ // X509_cmp returns a number <0 for less than, 0 for equal and >0 for greater than.
+ // It can't fail if both pointers are valid, which we know is true.
+ let cmp = unsafe { ffi::X509_cmp(self.as_ptr(), other.as_ptr()) };
+ cmp.cmp(&0)
+ }
+}
+
+impl PartialOrd for X509Ref {
+ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl PartialOrd<X509> for X509Ref {
+ fn partial_cmp(&self, other: &X509) -> Option<cmp::Ordering> {
+ <X509Ref as PartialOrd<X509Ref>>::partial_cmp(self, other)
+ }
+}
+
+impl PartialEq for X509Ref {
+ fn eq(&self, other: &Self) -> bool {
+ self.cmp(other) == cmp::Ordering::Equal
+ }
+}
+
+impl PartialEq<X509> for X509Ref {
+ fn eq(&self, other: &X509) -> bool {
+ <X509Ref as PartialEq<X509Ref>>::eq(self, other)
+ }
+}
+
+impl Eq for X509Ref {}
+
impl X509 {
/// Returns a new builder.
pub fn builder() -> Result<X509Builder, ErrorStack> {
@@ -711,6 +754,38 @@
type StackType = ffi::stack_st_X509;
}
+impl Ord for X509 {
+ fn cmp(&self, other: &Self) -> cmp::Ordering {
+ X509Ref::cmp(self, other)
+ }
+}
+
+impl PartialOrd for X509 {
+ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
+ X509Ref::partial_cmp(self, other)
+ }
+}
+
+impl PartialOrd<X509Ref> for X509 {
+ fn partial_cmp(&self, other: &X509Ref) -> Option<cmp::Ordering> {
+ X509Ref::partial_cmp(self, other)
+ }
+}
+
+impl PartialEq for X509 {
+ fn eq(&self, other: &Self) -> bool {
+ X509Ref::eq(self, other)
+ }
+}
+
+impl PartialEq<X509Ref> for X509 {
+ fn eq(&self, other: &X509Ref) -> bool {
+ X509Ref::eq(self, other)
+ }
+}
+
+impl Eq for X509 {}
+
/// A context object required to construct certain `X509` extension values.
pub struct X509v3Context<'a>(ffi::X509V3_CTX, PhantomData<(&'a X509Ref, &'a ConfRef)>);
@@ -785,6 +860,17 @@
cvt_p(ffi::X509V3_EXT_nconf_nid(conf, context, name, value)).map(X509Extension)
}
}
+
+ /// Adds an alias for an extension
+ ///
+ /// # Safety
+ ///
+ /// This method modifies global state without locking and therefore is not thread safe
+ #[corresponds(X509V3_EXT_add_alias)]
+ 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(|_| ())
+ }
}
/// A builder used to construct an `X509Name`.
@@ -960,6 +1046,21 @@
}
}
+ /// Compare two names, like [`Ord`] but it may fail.
+ ///
+ /// With OpenSSL versions from 3.0.0 this may return an error if the underlying `X509_NAME_cmp`
+ /// call fails.
+ /// For OpenSSL versions before 3.0.0 it will never return an error, but due to a bug it may
+ /// spuriously return `Ordering::Less` if the `X509_NAME_cmp` call fails.
+ #[corresponds(X509_NAME_cmp)]
+ pub fn try_cmp(&self, other: &X509NameRef) -> Result<Ordering, ErrorStack> {
+ let cmp = unsafe { ffi::X509_NAME_cmp(self.as_ptr(), other.as_ptr()) };
+ if cfg!(ossl300) && cmp == -2 {
+ return Err(ErrorStack::get());
+ }
+ Ok(cmp.cmp(&0))
+ }
+
to_der! {
/// Serializes the certificate into a DER-encoded X509 name structure.
///
@@ -1079,7 +1180,13 @@
///
///[`X509_REQ_set_version`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_set_version.html
pub fn set_version(&mut self, version: i32) -> Result<(), ErrorStack> {
- unsafe { cvt(ffi::X509_REQ_set_version(self.0.as_ptr(), version.into())).map(|_| ()) }
+ unsafe {
+ cvt(ffi::X509_REQ_set_version(
+ self.0.as_ptr(),
+ version as c_long,
+ ))
+ .map(|_| ())
+ }
}
/// Set the issuer name.
@@ -1175,7 +1282,7 @@
///
/// [`X509_REQ_sign`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_sign.html
#[cfg(boringssl)]
- pub fn sign_without_digset<T>(&mut self, key: &PKeyRef<T>) -> Result<(), ErrorStack>
+ pub fn sign_without_digest<T>(&mut self, key: &PKeyRef<T>) -> Result<(), ErrorStack>
where
T: HasPrivate,
{
@@ -1259,6 +1366,13 @@
ffi::i2d_X509_REQ
}
+ to_pem! {
+ /// Converts the request to human readable text.
+ #[corresponds(X509_Req_print)]
+ to_text,
+ ffi::X509_REQ_print
+ }
+
/// Returns the numerical value of the version field of the certificate request.
///
/// This corresponds to [`X509_REQ_get_version`]
@@ -1395,7 +1509,7 @@
}
#[cfg(boringssl)]
- let d: *const ffi::ASN1_STRING = std::mem::transmute((*self.as_ptr()).d);
+ let d = (*self.as_ptr()).d.ptr;
#[cfg(not(boringssl))]
let d = (*self.as_ptr()).d;
@@ -1577,7 +1691,7 @@
}
cfg_if! {
- if #[cfg(any(boringssl, ossl110))] {
+ if #[cfg(any(boringssl, ossl110, libressl350))] {
use ffi::{
X509_ALGOR_get0, ASN1_STRING_get0_data, X509_STORE_CTX_get0_chain, X509_set1_notAfter,
X509_set1_notBefore, X509_REQ_get_version, X509_REQ_get_subject_name,
@@ -1632,7 +1746,7 @@
}
cfg_if! {
- if #[cfg(ossl110)] {
+ if #[cfg(any(ossl110, libressl350))] {
use ffi::X509_OBJECT_free;
} else if #[cfg(boringssl)] {
use ffi::X509_OBJECT_free_contents as X509_OBJECT_free;
diff --git a/openssl/src/x509/store.rs b/src/x509/store.rs
similarity index 90%
rename from openssl/src/x509/store.rs
rename to src/x509/store.rs
index f4835d9..120d636 100644
--- a/openssl/src/x509/store.rs
+++ b/src/x509/store.rs
@@ -8,6 +8,7 @@
//! ```rust
//! use openssl::x509::store::{X509StoreBuilder, X509Store};
//! use openssl::x509::{X509, X509Name};
+//! use openssl::asn1::Asn1Time;
//! use openssl::pkey::PKey;
//! use openssl::hash::MessageDigest;
//! use openssl::rsa::Rsa;
@@ -20,11 +21,16 @@
//! name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com").unwrap();
//! let name = name.build();
//!
+//! // Sep 27th, 2016
+//! let sample_time = Asn1Time::from_unix(1474934400).unwrap();
+//!
//! let mut builder = X509::builder().unwrap();
//! builder.set_version(2).unwrap();
//! builder.set_subject_name(&name).unwrap();
//! builder.set_issuer_name(&name).unwrap();
//! builder.set_pubkey(&pkey).unwrap();
+//! builder.set_not_before(&sample_time);
+//! builder.set_not_after(&sample_time);
//! builder.sign(&pkey, MessageDigest::sha256()).unwrap();
//!
//! let certificate: X509 = builder.build();
@@ -40,13 +46,15 @@
use std::mem;
use crate::error::ErrorStack;
+#[cfg(not(boringssl))]
use crate::ssl::SslFiletype;
use crate::stack::StackRef;
#[cfg(any(ossl102, libressl261))]
-use crate::x509::verify::X509VerifyFlags;
+use crate::x509::verify::{X509VerifyFlags, X509VerifyParamRef};
use crate::x509::{X509Object, X509};
use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
+#[cfg(not(boringssl))]
use std::ffi::CString;
foreign_type_and_impl_send_sync! {
@@ -114,6 +122,13 @@
pub fn set_flags(&mut self, flags: X509VerifyFlags) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_STORE_set_flags(self.as_ptr(), flags.bits())).map(|_| ()) }
}
+
+ /// Sets certificate chain validation related parameters.
+ #[corresponds[X509_STORE_set1_param]]
+ #[cfg(any(ossl102, libressl261))]
+ pub fn set_param(&mut self, param: &X509VerifyParamRef) -> Result<(), ErrorStack> {
+ unsafe { cvt(ffi::X509_STORE_set1_param(self.as_ptr(), param.as_ptr())).map(|_| ()) }
+ }
}
generic_foreign_type_and_impl_send_sync! {
diff --git a/openssl/src/x509/tests.rs b/src/x509/tests.rs
similarity index 71%
rename from openssl/src/x509/tests.rs
rename to src/x509/tests.rs
index 26587d1..ace6175 100644
--- a/openssl/src/x509/tests.rs
+++ b/src/x509/tests.rs
@@ -1,3 +1,5 @@
+use std::cmp::Ordering;
+
use crate::asn1::Asn1Time;
use crate::bn::{BigNum, MsbOption};
use crate::hash::MessageDigest;
@@ -11,11 +13,13 @@
};
use crate::x509::store::X509StoreBuilder;
#[cfg(any(ossl102, libressl261))]
-use crate::x509::verify::X509VerifyFlags;
+use crate::x509::verify::{X509VerifyFlags, X509VerifyParam};
#[cfg(ossl110)]
use crate::x509::X509Builder;
use crate::x509::{X509Name, X509Req, X509StoreContext, X509VerifyResult, X509};
use hex::{self, FromHex};
+#[cfg(any(ossl102, libressl261))]
+use libc::time_t;
fn pkey() -> PKey<Private> {
let rsa = Rsa::generate(2048).unwrap();
@@ -283,7 +287,7 @@
let name = name.build();
let mut builder = X509Req::builder().unwrap();
- builder.set_version(2).unwrap();
+ builder.set_version(0).unwrap();
builder.set_subject_name(&name).unwrap();
builder.set_pubkey(&pkey).unwrap();
@@ -479,3 +483,188 @@
];
X509Name::from_der(SUBJECT_DER).unwrap();
}
+
+#[test]
+fn test_convert_to_text() {
+ let cert = include_bytes!("../../test/cert.pem");
+ let cert = X509::from_pem(cert).unwrap();
+
+ const SUBSTRINGS: &[&str] = &[
+ "Certificate:\n",
+ "Serial Number:",
+ "Signature Algorithm:",
+ "Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd\n",
+ "Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=foobar.com\n",
+ "Subject Public Key Info:",
+ ];
+
+ let text = String::from_utf8(cert.to_text().unwrap()).unwrap();
+
+ for substring in SUBSTRINGS {
+ assert!(
+ text.contains(substring),
+ "{:?} not found inside {}",
+ substring,
+ text
+ );
+ }
+}
+
+#[test]
+fn test_convert_req_to_text() {
+ let csr = include_bytes!("../../test/csr.pem");
+ let csr = X509Req::from_pem(csr).unwrap();
+
+ const SUBSTRINGS: &[&str] = &[
+ "Certificate Request:\n",
+ "Version:",
+ "Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=foobar.com\n",
+ "Subject Public Key Info:",
+ "Signature Algorithm:",
+ ];
+
+ let text = String::from_utf8(csr.to_text().unwrap()).unwrap();
+
+ for substring in SUBSTRINGS {
+ assert!(
+ text.contains(substring),
+ "{:?} not found inside {}",
+ substring,
+ text
+ );
+ }
+}
+
+#[test]
+fn test_name_cmp() {
+ let cert = include_bytes!("../../test/cert.pem");
+ let cert = X509::from_pem(cert).unwrap();
+
+ let subject = cert.subject_name();
+ let issuer = cert.issuer_name();
+ assert_eq!(Ordering::Equal, subject.try_cmp(subject).unwrap());
+ assert_eq!(Ordering::Greater, subject.try_cmp(issuer).unwrap());
+}
+
+#[test]
+#[cfg(any(ossl102, libressl261))]
+fn test_verify_param_set_time_fails_verification() {
+ const TEST_T_2030: time_t = 1893456000;
+
+ let cert = include_bytes!("../../test/cert.pem");
+ let cert = X509::from_pem(cert).unwrap();
+ let ca = include_bytes!("../../test/root-ca.pem");
+ let ca = X509::from_pem(ca).unwrap();
+ let chain = Stack::new().unwrap();
+
+ let mut store_bldr = X509StoreBuilder::new().unwrap();
+ store_bldr.add_cert(ca).unwrap();
+ let mut verify_params = X509VerifyParam::new().unwrap();
+ verify_params.set_time(TEST_T_2030);
+ store_bldr.set_param(&verify_params).unwrap();
+ let store = store_bldr.build();
+
+ let mut context = X509StoreContext::new().unwrap();
+ assert_eq!(
+ context
+ .init(&store, &cert, &chain, |c| {
+ c.verify_cert()?;
+ Ok(c.error())
+ })
+ .unwrap()
+ .error_string(),
+ "certificate has expired"
+ )
+}
+
+#[test]
+#[cfg(any(ossl102, libressl261))]
+fn test_verify_param_set_time() {
+ const TEST_T_2020: time_t = 1577836800;
+
+ let cert = include_bytes!("../../test/cert.pem");
+ let cert = X509::from_pem(cert).unwrap();
+ let ca = include_bytes!("../../test/root-ca.pem");
+ let ca = X509::from_pem(ca).unwrap();
+ let chain = Stack::new().unwrap();
+
+ let mut store_bldr = X509StoreBuilder::new().unwrap();
+ store_bldr.add_cert(ca).unwrap();
+ let mut verify_params = X509VerifyParam::new().unwrap();
+ verify_params.set_time(TEST_T_2020);
+ store_bldr.set_param(&verify_params).unwrap();
+ let store = store_bldr.build();
+
+ let mut context = X509StoreContext::new().unwrap();
+ assert!(context
+ .init(&store, &cert, &chain, |c| c.verify_cert())
+ .unwrap());
+}
+
+#[test]
+#[cfg(any(ossl102, libressl261))]
+fn test_verify_param_set_depth() {
+ let cert = include_bytes!("../../test/leaf.pem");
+ let cert = X509::from_pem(cert).unwrap();
+ let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem");
+ let intermediate_ca = X509::from_pem(intermediate_ca).unwrap();
+ let ca = include_bytes!("../../test/root-ca.pem");
+ let ca = X509::from_pem(ca).unwrap();
+ let mut chain = Stack::new().unwrap();
+ chain.push(intermediate_ca).unwrap();
+
+ let mut store_bldr = X509StoreBuilder::new().unwrap();
+ store_bldr.add_cert(ca).unwrap();
+ let mut verify_params = X509VerifyParam::new().unwrap();
+ // OpenSSL 1.1.0+ considers the root certificate to not be part of the chain, while 1.0.2 and LibreSSL do
+ let expected_depth = if cfg!(any(ossl110)) { 1 } else { 2 };
+ verify_params.set_depth(expected_depth);
+ store_bldr.set_param(&verify_params).unwrap();
+ let store = store_bldr.build();
+
+ let mut context = X509StoreContext::new().unwrap();
+ assert!(context
+ .init(&store, &cert, &chain, |c| c.verify_cert())
+ .unwrap());
+}
+
+#[test]
+#[cfg(any(ossl102, libressl261))]
+fn test_verify_param_set_depth_fails_verification() {
+ let cert = include_bytes!("../../test/leaf.pem");
+ let cert = X509::from_pem(cert).unwrap();
+ let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem");
+ let intermediate_ca = X509::from_pem(intermediate_ca).unwrap();
+ let ca = include_bytes!("../../test/root-ca.pem");
+ let ca = X509::from_pem(ca).unwrap();
+ let mut chain = Stack::new().unwrap();
+ chain.push(intermediate_ca).unwrap();
+
+ let mut store_bldr = X509StoreBuilder::new().unwrap();
+ store_bldr.add_cert(ca).unwrap();
+ let mut verify_params = X509VerifyParam::new().unwrap();
+ // OpenSSL 1.1.0+ considers the root certificate to not be part of the chain, while 1.0.2 and LibreSSL do
+ let expected_depth = if cfg!(any(ossl110)) { 0 } else { 1 };
+ verify_params.set_depth(expected_depth);
+ store_bldr.set_param(&verify_params).unwrap();
+ let store = store_bldr.build();
+
+ // OpenSSL 1.1.0+ added support for X509_V_ERR_CERT_CHAIN_TOO_LONG, while 1.0.2 simply ignores the intermediate
+ let expected_error = if cfg!(any(ossl110, libressl261)) {
+ "certificate chain too long"
+ } else {
+ "unable to get local issuer certificate"
+ };
+
+ let mut context = X509StoreContext::new().unwrap();
+ assert_eq!(
+ context
+ .init(&store, &cert, &chain, |c| {
+ c.verify_cert()?;
+ Ok(c.error())
+ })
+ .unwrap()
+ .error_string(),
+ expected_error
+ )
+}
diff --git a/openssl/src/x509/verify.rs b/src/x509/verify.rs
similarity index 85%
rename from openssl/src/x509/verify.rs
rename to src/x509/verify.rs
index 4752133..20dd4be 100644
--- a/openssl/src/x509/verify.rs
+++ b/src/x509/verify.rs
@@ -1,10 +1,10 @@
use bitflags::bitflags;
use foreign_types::ForeignTypeRef;
-use libc::{c_uint, c_ulong};
+use libc::{c_int, c_uint, c_ulong, time_t};
use std::net::IpAddr;
-use crate::cvt;
use crate::error::ErrorStack;
+use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
bitflags! {
@@ -69,6 +69,17 @@
pub struct X509VerifyParamRef;
}
+impl X509VerifyParam {
+ /// Create an X509VerifyParam
+ #[corresponds(X509_VERIFY_PARAM_new)]
+ pub fn new() -> Result<X509VerifyParam, ErrorStack> {
+ unsafe {
+ ffi::init();
+ cvt_p(ffi::X509_VERIFY_PARAM_new()).map(X509VerifyParam)
+ }
+ }
+}
+
impl X509VerifyParamRef {
/// Set the host flags.
#[corresponds(X509_VERIFY_PARAM_set_hostflags)]
@@ -139,4 +150,16 @@
.map(|_| ())
}
}
+
+ /// Set the verification time, where time is of type time_t, traditionaly defined as seconds since the epoch
+ #[corresponds(X509_VERIFY_PARAM_set_time)]
+ pub fn set_time(&mut self, time: time_t) {
+ unsafe { ffi::X509_VERIFY_PARAM_set_time(self.as_ptr(), time) }
+ }
+
+ /// Set the verification depth
+ #[corresponds(X509_VERIFY_PARAM_set_depth)]
+ pub fn set_depth(&mut self, depth: c_int) {
+ unsafe { ffi::X509_VERIFY_PARAM_set_depth(self.as_ptr(), depth) }
+ }
}
diff --git a/openssl/test/aia_test_cert.pem b/test/aia_test_cert.pem
similarity index 100%
rename from openssl/test/aia_test_cert.pem
rename to test/aia_test_cert.pem
diff --git a/openssl/test/alt_name_cert.pem b/test/alt_name_cert.pem
similarity index 100%
rename from openssl/test/alt_name_cert.pem
rename to test/alt_name_cert.pem
diff --git a/openssl/test/cert.pem b/test/cert.pem
similarity index 100%
rename from openssl/test/cert.pem
rename to test/cert.pem
diff --git a/openssl/test/certs.pem b/test/certs.pem
similarity index 100%
rename from openssl/test/certs.pem
rename to test/certs.pem
diff --git a/openssl/test/cms.p12 b/test/cms.p12
similarity index 100%
rename from openssl/test/cms.p12
rename to test/cms.p12
Binary files differ
diff --git a/openssl/test/cms_pubkey.der b/test/cms_pubkey.der
similarity index 100%
rename from openssl/test/cms_pubkey.der
rename to test/cms_pubkey.der
Binary files differ
diff --git a/test/csr.pem b/test/csr.pem
new file mode 100644
index 0000000..cf9dde2
--- /dev/null
+++ b/test/csr.pem
@@ -0,0 +1,62 @@
+Certificate Request:
+ Data:
+ Version: 1 (0x0)
+ Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = foobar.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:a8:f4:25:8c:44:b3:17:a3:50:85:fe:23:91:87:
+ d0:78:36:1b:49:17:ff:2d:47:d3:e5:1b:de:6c:36:
+ fc:96:b9:04:3f:f2:37:de:bf:ef:33:12:ba:65:c5:
+ f2:e4:b7:4a:49:a9:ca:22:64:6f:20:f4:d5:34:91:
+ 4e:a8:e5:3f:bf:d5:08:19:72:50:80:a1:96:92:d0:
+ 9a:b1:9a:8a:36:62:4f:f5:42:c8:f5:ea:99:cc:05:
+ cd:74:b9:20:e4:e9:5f:5a:25:25:f5:bc:ac:0e:35:
+ 53:52:c2:21:c0:d4:c8:57:fa:2e:d6:7f:bf:ca:d2:
+ 78:aa:fa:4e:e1:3a:48:65:78:59:16:81:9b:54:ab:
+ 8d:60:5e:1d:55:7c:eb:a0:91:ae:d4:92:d6:27:93:
+ d9:ab:05:b0:0c:8e:66:a5:a1:93:67:da:93:0c:01:
+ 0c:55:83:84:e1:88:b9:b7:ce:fb:96:aa:f5:c0:49:
+ 6c:d4:65:ce:c8:01:dd:46:6c:de:00:b4:3b:a1:b3:
+ 6e:76:7a:a1:3d:13:88:93:1e:4e:c5:d7:8c:00:4b:
+ 52:56:aa:fe:ba:ea:14:5e:18:7a:e6:64:91:b1:d3:
+ 14:13:33:db:cf:0f:51:cd:e6:dd:94:dc:a4:df:84:
+ ef:e6:4e:50:14:59:5c:a0:f6:d0:ad:3b:36:e8:2a:
+ 0b:35
+ Exponent: 65537 (0x10001)
+ Attributes:
+ a0:00
+ Signature Algorithm: sha256WithRSAEncryption
+ 95:26:e1:84:56:e7:80:da:2c:a4:c0:b5:85:43:61:85:34:84:
+ 37:83:c0:bc:cf:70:20:89:46:ce:3d:7e:23:8a:40:a4:a5:fa:
+ c5:e3:3d:ee:e5:05:16:58:93:f9:6c:f3:86:ee:99:cc:e1:04:
+ 5c:68:99:da:66:72:a1:95:31:cd:13:6f:a5:6f:fc:a9:ec:75:
+ 6a:f7:e5:cf:0e:7b:5f:2f:db:8d:45:e6:66:52:12:1d:c9:ac:
+ 3a:86:35:bd:1f:7b:6e:b5:e1:f3:4f:80:6a:06:73:1c:a0:0d:
+ a3:63:b6:40:76:25:b0:e9:96:33:7a:9d:18:7e:5e:93:c0:47:
+ d7:0b:da:b3:03:17:94:d0:0c:78:18:f3:0e:cd:3c:f7:e8:25:
+ 08:c2:13:0a:af:1e:5c:48:5f:17:41:b2:2d:d2:0f:37:2e:b3:
+ 10:fd:2b:c0:77:e1:17:8a:57:0c:95:5e:c8:03:eb:63:14:2e:
+ 46:fd:1e:14:13:9f:38:c1:2f:e9:9b:47:c3:60:a9:d7:6e:a3:
+ d0:af:0b:6f:df:6e:37:f6:d9:a0:1b:dd:1f:a5:a5:33:89:1f:
+ a5:a3:44:14:91:83:c3:c8:b2:6e:fb:3f:f1:6d:d2:51:21:f7:
+ 98:20:0a:40:75:a5:60:c3:59:53:08:62:3d:39:e8:83:55:90:
+ 1a:bf:51:57
+-----BEGIN CERTIFICATE REQUEST-----
+MIICnzCCAYcCAQAwWjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
+ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKZm9v
+YmFyLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKj0JYxEsxej
+UIX+I5GH0Hg2G0kX/y1H0+Ub3mw2/Ja5BD/yN96/7zMSumXF8uS3SkmpyiJkbyD0
+1TSRTqjlP7/VCBlyUIChlpLQmrGaijZiT/VCyPXqmcwFzXS5IOTpX1olJfW8rA41
+U1LCIcDUyFf6LtZ/v8rSeKr6TuE6SGV4WRaBm1SrjWBeHVV866CRrtSS1ieT2asF
+sAyOZqWhk2fakwwBDFWDhOGIubfO+5aq9cBJbNRlzsgB3UZs3gC0O6GzbnZ6oT0T
+iJMeTsXXjABLUlaq/rrqFF4YeuZkkbHTFBMz288PUc3m3ZTcpN+E7+ZOUBRZXKD2
+0K07NugqCzUCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQCVJuGEVueA2iykwLWF
+Q2GFNIQ3g8C8z3AgiUbOPX4jikCkpfrF4z3u5QUWWJP5bPOG7pnM4QRcaJnaZnKh
+lTHNE2+lb/yp7HVq9+XPDntfL9uNReZmUhIdyaw6hjW9H3tuteHzT4BqBnMcoA2j
+Y7ZAdiWw6ZYzep0Yfl6TwEfXC9qzAxeU0Ax4GPMOzTz36CUIwhMKrx5cSF8XQbIt
+0g83LrMQ/SvAd+EXilcMlV7IA+tjFC5G/R4UE584wS/pm0fDYKnXbqPQrwtv3243
+9tmgG90fpaUziR+lo0QUkYPDyLJu+z/xbdJRIfeYIApAdaVgw1lTCGI9OeiDVZAa
+v1FX
+-----END CERTIFICATE REQUEST-----
diff --git a/openssl/test/dhparams.pem b/test/dhparams.pem
similarity index 100%
rename from openssl/test/dhparams.pem
rename to test/dhparams.pem
diff --git a/openssl/test/dsa.pem b/test/dsa.pem
similarity index 100%
rename from openssl/test/dsa.pem
rename to test/dsa.pem
diff --git a/openssl/test/dsa.pem.pub b/test/dsa.pem.pub
similarity index 100%
rename from openssl/test/dsa.pem.pub
rename to test/dsa.pem.pub
diff --git a/openssl/test/dsaparam.pem b/test/dsaparam.pem
similarity index 100%
rename from openssl/test/dsaparam.pem
rename to test/dsaparam.pem
diff --git a/openssl/test/identity.p12 b/test/identity.p12
similarity index 100%
rename from openssl/test/identity.p12
rename to test/identity.p12
Binary files differ
diff --git a/test/intermediate-ca.key b/test/intermediate-ca.key
new file mode 100644
index 0000000..48f4495
--- /dev/null
+++ b/test/intermediate-ca.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA1HsHFTpgKeWL/y6oKtARZm0Dy6J/08E0CujmdpVp0xnkXi/A
+RARnbMEbOPfmBUMOkVtQT3+l5aCgIAX+Kg6K7sQvio8nQUgOxuO1YpGlYu9EMtc7
+5fNxA1T0CuXXx8ClfEqW1ZV7ziQV0J4gzvuI26A7XyUhdk1oP/Al3F/94TmH6dtP
+SQ2K901O2zknU+bpPheQy08SE20k/nUOJAsiwtsxqY8hHOL1sXZ4K+I311hl0QpD
+OYf7eBcBdo2Mc5Nzjd9LPGLk1lE3itAXpayFMmfuuA0IdH1gNfy18axFEEVnj6CS
+2epGpmAckUEWUOse1WBhDEt6ddowT1iw7X4mWwIDAQABAoIBAGMGXzuudAiymTc5
+OFiTlbhlkAJEXkyC201GU7nqUmJ2y651lKZeYxEVQimfpszG/rARnXEfbWKCJH4o
+LNbO5kL2na12n/XVrkVU9EDW3fwoxGDpXFoDxaSm4AGAMrs+diFh5b/upb9ho+UQ
+/PtZ0OOCXokuFdU7qB08P3jgJ8LhooqWnZ4AC0rhN85CMNIKs/nrUrnmS3FZLVd/
+NWI9Vfjsndd41Gkho0A7tgOSnwRupk/Bv1b0px31h8ucp9/nLuR8vbGSdS/R9Sta
+pB9KNYYQ3LrhQGjddnEU0gj8qsuWgnoPf7eaWsLVunPLHQzL2hNNKL1eBADm7Lhh
+avIlnrkCgYEA8Q8UhOeIO0sMU8sB4NPTUf2UT9xjURoowGsGgbDEk21eABH6VC33
+VYt5r5xwbZFQvVaTbe+EI1YDpjH1cvpmorEWI47Nm4Vbf9JujW/hoQwuwpzOpdUT
+2G4tfMQrmTw/9HJ0l9+1Ib+A93dB8GvR0NE1uueaWanWvXARInwGiscCgYEA4aZ9
+mbhuwx88sSRMXwxSZw+R5BRrjdC0CeoimGg4/P84bKgc0YsjAha5jWaC/h8xN2Pb
+w45b3hQ0/FP8xohP0bp/5eeiDbqb6JuO5bI3CnfBrVpu1CAuIrf7lhkar3a0wluB
+k03fVHuVLtydACDJBKrZm1F39lpiZiEqlBIp080CgYEAwRwYjwPAEefkHzhQ7+Ah
+uNwQtQ1TjsQLA2J5mumWAJirphjA1jDgo+oQ+Iq1UkEIUjWJ85bd30TntXruK0bH
+c+uzVZbvxXfGvhZAtBN9x/svdn4R2a1hsY9J51prpt0qStRp7MSsoTV9xkEGVOi6
+87K1fV5OOyggvC+Lunlq8D8CgYAVSCOObPOdWYPa3SaKzFm1OKW00iw2qtlgGgH7
+R9EgI14J+W0GYk4B82y6plFycDSvGa7vaazGbDd3GOC9RLvqduF7KHaDPvdXX9yB
+U2aXiSXuGJpdTU+snJeQ13tJ0zNHJWQ6JV0L1cADNHFmQrFSzF5LpMpgpLOlGDmw
+z2m8fQKBgQDclFeonyn0zcXqznun9kAKkMij4s6lSdRgi/5Zh1WbJwOso9oWfwz9
+SSTP2KBO8B+/yFvuo5SWrbNaTz9/KuzMTv4HXz5ukLbyN9Jjtk73fdBBRSjL+zF5
+jU56oXHrwBhEqWQ77Ps60r+FmDjUgUhyJl14ZfkzICUK7NLFxKrvMQ==
+-----END RSA PRIVATE KEY-----
diff --git a/test/intermediate-ca.pem b/test/intermediate-ca.pem
new file mode 100644
index 0000000..266ef59
--- /dev/null
+++ b/test/intermediate-ca.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDszCCApugAwIBAgIEFSQSITANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMB4XDTIyMTEwMzA3MDc0OVoXDTI2MDgxMTA3MDc0OVowgYkxCzAJ
+BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
+dCBXaWRnaXRzIFB0eSBMdGQxIDAeBgNVBAsMF0ludGVybWVkaWF0ZSBEZXBhcnRt
+ZW50MSAwHgYDVQQDDBdpbnRlcm1lZGlhdGUuZm9vYmFyLmNvbTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBANR7BxU6YCnli/8uqCrQEWZtA8uif9PBNAro
+5naVadMZ5F4vwEQEZ2zBGzj35gVDDpFbUE9/peWgoCAF/ioOiu7EL4qPJ0FIDsbj
+tWKRpWLvRDLXO+XzcQNU9Arl18fApXxKltWVe84kFdCeIM77iNugO18lIXZNaD/w
+Jdxf/eE5h+nbT0kNivdNTts5J1Pm6T4XkMtPEhNtJP51DiQLIsLbMamPIRzi9bF2
+eCviN9dYZdEKQzmH+3gXAXaNjHOTc43fSzxi5NZRN4rQF6WshTJn7rgNCHR9YDX8
+tfGsRRBFZ4+gktnqRqZgHJFBFlDrHtVgYQxLenXaME9YsO1+JlsCAwEAAaNmMGQw
+HQYDVR0OBBYEFAXJImmmxYXx6L1SRRhgP3Tyq2J6MB8GA1UdIwQYMBaAFGzTpQOr
+DV8syY2KnIiniHe4N/2aMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQD
+AgGGMA0GCSqGSIb3DQEBCwUAA4IBAQCnUh7iNbnFBjVa4sFx02r65syxUhcvM/ya
+DcSe1esGUwjZLyKVl9BTfQ6kfNa/6Z/t5cprp0R3etalN31dxka7xSDwzFNdBczB
+zYDIVOVlcGLL1Xjozacm6YHo773dqxZS36rVMk3NqNUY6GJJ+CGso2xZShcBg2KG
+fPlNPiRz3847E3dwouDYcP1MXf2ql/Y7dRbE+8kb3bWkSusJVb/4EHjpR7yZjKmh
+eXHVVx1dKnCGRldn3+dSNhN6mxNaSeBE2hb158+diQvL5u3f//va7SOpCi0f4d8E
+UCnLhieyrDlr42XXfz42BqRpqBO1SDjQwzIIc9Fbevwb916OSExp
+-----END CERTIFICATE-----
diff --git a/openssl/test/key.der b/test/key.der
similarity index 100%
rename from openssl/test/key.der
rename to test/key.der
Binary files differ
diff --git a/openssl/test/key.der.pub b/test/key.der.pub
similarity index 100%
rename from openssl/test/key.der.pub
rename to test/key.der.pub
Binary files differ
diff --git a/openssl/test/key.pem b/test/key.pem
similarity index 100%
rename from openssl/test/key.pem
rename to test/key.pem
diff --git a/openssl/test/key.pem.pub b/test/key.pem.pub
similarity index 100%
rename from openssl/test/key.pem.pub
rename to test/key.pem.pub
diff --git a/openssl/test/keystore-empty-chain.p12 b/test/keystore-empty-chain.p12
similarity index 100%
rename from openssl/test/keystore-empty-chain.p12
rename to test/keystore-empty-chain.p12
Binary files differ
diff --git a/test/leaf.pem b/test/leaf.pem
new file mode 100644
index 0000000..0f7aa80
--- /dev/null
+++ b/test/leaf.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDejCCAmICBBUkEiQwDQYJKoZIhvcNAQELBQAwgYkxCzAJBgNVBAYTAkFVMRMw
+EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0
+eSBMdGQxIDAeBgNVBAsMF0ludGVybWVkaWF0ZSBEZXBhcnRtZW50MSAwHgYDVQQD
+DBdpbnRlcm1lZGlhdGUuZm9vYmFyLmNvbTAeFw0yMjExMDMwNzE3NTJaFw0yNjA4
+MTEwNzE3NTJaMHkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
+HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxGDAWBgNVBAsMD0xlYWYg
+RGVwYXJ0bWVudDEYMBYGA1UEAwwPbGVhZi5mb29iYXIuY29tMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs9STUHGIcSOtioK6+02k9Jx4JuYVJ0SB7Ebd
+FAhGiOxBSoOljRVmmALti89QMmRiRqlyJnGJch7AloCCRsLJA0MfUYvauqmKHZFk
+iqtZ1HocHQ/LGNKfkILcclb4xp2nGYntKAyEqer3Qc6aPWAnQAV/+BshU1vlMfwU
+T6vOJRG69mft6dkHEWSzZd7++7HmFQGnDmIs5jBJVCOgKVttkN8Bk2EsTvJi9zl2
+SXLTcVrTAxEvuawv2ZXvdI/Cpt1WW0litXlFLcYBGwt/N93TX/L3Iyw5HcNd/xf9
+QwOr6RR66krQJzKxwcIY934uq6cyTQhexgnffb65qXL4bbV5fwIDAQABMA0GCSqG
+SIb3DQEBCwUAA4IBAQAZf0/r04AeKN2QhQ7Z0o2Iu/Yj3OD2tnbxVoltYk8CRfp3
+7VGl/5PUbmXXBSwMc4Udj88JlreU7iNEPAKtBqFczw0pwNfvxKG4Eh3vsfKrP+5g
+gtVwDG0mWeKJ7udrmFt8N0uwxVYDKp/gv5+Bw2eMew9Eoyenj6k2yg0nbFKzA3EH
+DqngETzX0dhdiYwVcoJFUK5ni3tVl9qi6FpmaTE6C5nTQLyH4CI+vo2x/QHINGaJ
+OzY/rx35iyVqXVqxN/gO/hp6g0nT5zLuMg2rfvcAhdDsD7htYcHiNkofrC8s0oQE
+W+r01EhxdEVvY1nYWanBCF6tktc5v5qf2WMS4ye5
+-----END CERTIFICATE-----
diff --git a/openssl/test/nid_test_cert.pem b/test/nid_test_cert.pem
similarity index 100%
rename from openssl/test/nid_test_cert.pem
rename to test/nid_test_cert.pem
diff --git a/openssl/test/nid_uid_test_cert.pem b/test/nid_uid_test_cert.pem
similarity index 100%
rename from openssl/test/nid_uid_test_cert.pem
rename to test/nid_uid_test_cert.pem
diff --git a/openssl/test/pkcs1.pem.pub b/test/pkcs1.pem.pub
similarity index 100%
rename from openssl/test/pkcs1.pem.pub
rename to test/pkcs1.pem.pub
diff --git a/openssl/test/pkcs8-nocrypt.der b/test/pkcs8-nocrypt.der
similarity index 100%
rename from openssl/test/pkcs8-nocrypt.der
rename to test/pkcs8-nocrypt.der
Binary files differ
diff --git a/openssl/test/pkcs8.der b/test/pkcs8.der
similarity index 100%
rename from openssl/test/pkcs8.der
rename to test/pkcs8.der
Binary files differ
diff --git a/openssl/test/root-ca.key b/test/root-ca.key
similarity index 100%
rename from openssl/test/root-ca.key
rename to test/root-ca.key
diff --git a/openssl/test/root-ca.pem b/test/root-ca.pem
similarity index 100%
rename from openssl/test/root-ca.pem
rename to test/root-ca.pem
diff --git a/openssl/test/rsa-encrypted.pem b/test/rsa-encrypted.pem
similarity index 100%
rename from openssl/test/rsa-encrypted.pem
rename to test/rsa-encrypted.pem
diff --git a/openssl/test/rsa.pem b/test/rsa.pem
similarity index 100%
rename from openssl/test/rsa.pem
rename to test/rsa.pem
diff --git a/openssl/test/rsa.pem.pub b/test/rsa.pem.pub
similarity index 100%
rename from openssl/test/rsa.pem.pub
rename to test/rsa.pem.pub