diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index efc975dbd2..212183e2c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,7 +62,7 @@ jobs: # Remember to also update `--rust-target` in `openssl-sys/build/run_bindgen.rs` - uses: sfackler/actions/rustup@master with: - version: 1.56.0 + version: 1.63.0 - run: echo "version=$(rustc --version)" >> $GITHUB_OUTPUT id: rust-version - uses: actions/cache@v4 @@ -72,8 +72,6 @@ jobs: restore-keys: | index-${{ runner.os }}- - run: cargo generate-lockfile - - run: | - cargo update -p cc --precise 1.0.94 - uses: actions/cache@v4 with: path: ~/.cargo/registry/cache @@ -155,22 +153,26 @@ jobs: version: e23fe9b6eecc10e4f9ea1f0027fea5eaee7bd6b6 - name: openssl version: vendored + - name: openssl + version: 3.4.0-beta1 - name: openssl version: 3.3.0 - name: openssl version: 3.2.0 - dl-path: / - name: openssl + old: true version: 1.1.1w - dl-path: / - name: openssl version: 1.1.0l + old: true dl-path: /old/1.1.0 - name: openssl version: 1.0.2u + old: true dl-path: /old/1.0.2 - name: openssl version: 1.0.1u + old: true dl-path: /old/1.0.1 include: - target: x86_64-unknown-linux-gnu @@ -182,17 +184,17 @@ jobs: bindgen: true library: name: libressl - version: 3.7.3 + version: 3.8.4 - target: x86_64-unknown-linux-gnu bindgen: true library: name: libressl - version: 3.8.3 + version: 3.9.2 - target: x86_64-unknown-linux-gnu bindgen: true library: name: libressl - version: 3.9.1 + version: 4.0.0 - target: x86_64-unknown-linux-gnu bindgen: false library: @@ -202,17 +204,17 @@ jobs: bindgen: false library: name: libressl - version: 3.7.3 + version: 3.8.4 - target: x86_64-unknown-linux-gnu bindgen: false library: name: libressl - version: 3.8.3 + version: 3.9.2 - target: x86_64-unknown-linux-gnu bindgen: false library: name: libressl - version: 3.9.1 + version: 4.0.0 name: ${{ matrix.target }}-${{ matrix.library.name }}-${{ matrix.library.version }}-${{ matrix.bindgen }} runs-on: ubuntu-latest env: @@ -257,7 +259,11 @@ jobs: run: | case "${{ matrix.library.name }}" in "openssl") - url="https://www.openssl.org/source${{ matrix.library.dl-path }}/openssl-${{ matrix.library.version }}.tar.gz" + if [[ "${{ matrix.library.old }}" == "true" ]]; then + url="https://www.openssl.org/source${{ matrix.library.dl-path }}/openssl-${{ matrix.library.version }}.tar.gz" + else + url="https://github.com/openssl/openssl/releases/download/openssl-${{ matrix.library.version }}/openssl-${{ matrix.library.version }}.tar.gz" + fi tar_flags="--strip-components=1" ;; "libressl") diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000000..bcb7e2d7f8 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1 @@ +# this project uses the default rustfmt settings diff --git a/Cargo.toml b/Cargo.toml index c33c3475a7..63194cb3fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +resolver = "2" members = [ "openssl", "openssl-errors", diff --git a/openssl-errors/Cargo.toml b/openssl-errors/Cargo.toml index 5285b266e1..24f724678f 100644 --- a/openssl-errors/Cargo.toml +++ b/openssl-errors/Cargo.toml @@ -2,12 +2,13 @@ name = "openssl-errors" version = "0.2.0" authors = ["Steven Fackler "] -edition = "2018" +edition = "2021" license = "MIT OR Apache-2.0" description = "Custom error library support for the openssl crate." repository = "https://github.com/sfackler/rust-openssl" readme = "README.md" categories = ["api-bindings"] +rust-version = "1.63.0" [dependencies] cfg-if = "1.0" diff --git a/openssl-macros/Cargo.toml b/openssl-macros/Cargo.toml index 90abfdfa2a..40134616b3 100644 --- a/openssl-macros/Cargo.toml +++ b/openssl-macros/Cargo.toml @@ -1,10 +1,11 @@ [package] name = "openssl-macros" version = "0.1.1" -edition = "2018" +edition = "2021" license = "MIT OR Apache-2.0" description = "Internal macros used by the openssl crate." repository = "https://github.com/sfackler/rust-openssl" +rust-version = "1.63.0" [lib] proc-macro = true diff --git a/openssl-sys/CHANGELOG.md b/openssl-sys/CHANGELOG.md index 37f35e0a66..641f0d4b7a 100644 --- a/openssl-sys/CHANGELOG.md +++ b/openssl-sys/CHANGELOG.md @@ -2,6 +2,22 @@ ## [Unreleased] +## [v0.9.104] - 2024-10-15 + +### Added + +* Added support for LibreSSL 4.0.x. +* Added `EVP_KDF_*` and `EVP_KDF_CTX_*` bindings. +* Added `EVP_DigestSqueeze`. +* Added `OSSL_PARAM_construct_octet_string`. +* Added `OSSL_set_max_threads` and `OSSL_get_max_threads`. + +### Changed + +* `openssl-sys` is now a 2021 edition crate +* Explicitly specify the MSRV in `Cargo.toml` +* Raised the `bindgen` (optional) dependency from 0.65 to 0.69 + ## [v0.9.103] - 2024-07-20 ### Added @@ -607,7 +623,8 @@ Fixed builds against OpenSSL built with `no-cast`. * Added `X509_verify` and `X509_REQ_verify`. * Added `EVP_MD_type` and `EVP_GROUP_get_curve_name`. -[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.103..master +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.104..master +[v0.9.104]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.103...openssl-sys-v0.9.104 [v0.9.103]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.102...openssl-sys-v0.9.103 [v0.9.102]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.101...openssl-sys-v0.9.102 [v0.9.101]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.100...openssl-sys-v0.9.101 diff --git a/openssl-sys/Cargo.toml b/openssl-sys/Cargo.toml index 131ebe684e..f82dbd3f1a 100644 --- a/openssl-sys/Cargo.toml +++ b/openssl-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" authors = [ "Alex Crichton ", "Steven Fackler ", @@ -12,7 +12,8 @@ readme = "README.md" categories = ["cryptography", "external-ffi-bindings"] links = "openssl" build = "build/main.rs" -edition = "2018" +edition = "2021" +rust-version = "1.63.0" [features] vendored = ['openssl-src'] @@ -23,7 +24,7 @@ libc = "0.2" bssl-sys = { version = "0.1.0", optional = true } [build-dependencies] -bindgen = { version = "0.65.0", optional = true, features = ["experimental"] } +bindgen = { version = "0.69.0", optional = true, features = ["experimental"] } cc = "1.0.61" openssl-src = { version = "300.2.0", optional = true, features = ["legacy"] } pkg-config = "0.3.9" diff --git a/openssl-sys/build/cfgs.rs b/openssl-sys/build/cfgs.rs index bbd3be59f3..cd03888e62 100644 --- a/openssl-sys/build/cfgs.rs +++ b/openssl-sys/build/cfgs.rs @@ -71,6 +71,9 @@ pub fn get(openssl_version: Option, libressl_version: Option) -> Vec<& } else { let openssl_version = openssl_version.unwrap(); + if openssl_version >= 0x3_04_00_00_0 { + cfgs.push("ossl340"); + } if openssl_version >= 0x3_03_00_00_0 { cfgs.push("ossl330"); } diff --git a/openssl-sys/build/find_normal.rs b/openssl-sys/build/find_normal.rs index 1e910a0eee..1439e9ab30 100644 --- a/openssl-sys/build/find_normal.rs +++ b/openssl-sys/build/find_normal.rs @@ -102,13 +102,21 @@ fn find_openssl_dir(target: &str) -> OsString { return OsString::from("/usr/local"); } + let msg_header = + "Could not find directory of OpenSSL installation, and this `-sys` crate cannot +proceed without this knowledge. If OpenSSL is installed and this crate had +trouble finding it, you can set the `OPENSSL_DIR` environment variable for the +compilation process."; + + println!( + "cargo:warning={} See stderr section below for further information.", + msg_header.replace('\n', " ") + ); + let mut msg = format!( " -Could not find directory of OpenSSL installation, and this `-sys` crate cannot -proceed without this knowledge. If OpenSSL is installed and this crate had -trouble finding it, you can set the `OPENSSL_DIR` environment variable for the -compilation process. +{} Make sure you also have the development packages of openssl installed. For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora. @@ -122,6 +130,7 @@ $TARGET = {} openssl-sys = {} ", + msg_header, host, target, env!("CARGO_PKG_VERSION") @@ -187,7 +196,8 @@ https://github.com/sfackler/rust-openssl#windows ); } - panic!("{}", msg); + eprintln!("{}", msg); + std::process::exit(101); // same as panic previously } /// Attempt to find OpenSSL through pkg-config. @@ -212,7 +222,7 @@ fn try_pkg_config() { { Ok(lib) => lib, Err(e) => { - println!("run pkg_config fail: {:?}", e); + println!("\n\nCould not find openssl via pkg-config:\n{}\n", e); return; } }; diff --git a/openssl-sys/build/main.rs b/openssl-sys/build/main.rs index 50ecc0f084..f379e1e6b3 100644 --- a/openssl-sys/build/main.rs +++ b/openssl-sys/build/main.rs @@ -120,6 +120,7 @@ fn main() { println!("cargo:rustc-check-cfg=cfg(ossl310)"); println!("cargo:rustc-check-cfg=cfg(ossl320)"); println!("cargo:rustc-check-cfg=cfg(ossl330)"); + println!("cargo:rustc-check-cfg=cfg(ossl340)"); check_ssl_kind(); @@ -379,6 +380,8 @@ See rust-openssl documentation for more information: (3, 8, _) => ('3', '8', 'x'), (3, 9, 0) => ('3', '9', '0'), (3, 9, _) => ('3', '9', 'x'), + (4, 0, 0) => ('4', '0', '0'), + (4, 0, _) => ('4', '0', 'x'), _ => version_error(), }; @@ -421,7 +424,7 @@ fn version_error() -> ! { " This crate is only compatible with OpenSSL (version 1.0.1 through 1.1.1, or 3), or LibreSSL 2.5 -through 3.9.x, but a different version of OpenSSL was found. The build is now aborting +through 4.0.x, but a different version of OpenSSL was found. The build is now aborting due to this version mismatch. " diff --git a/openssl-sys/build/run_bindgen.rs b/openssl-sys/build/run_bindgen.rs index ffaecdc81b..27bd482b38 100644 --- a/openssl-sys/build/run_bindgen.rs +++ b/openssl-sys/build/run_bindgen.rs @@ -63,6 +63,10 @@ const INCLUDES: &str = " #if defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_BORINGSSL) #include #endif + +#if OPENSSL_VERSION_NUMBER >= 0x30200000 +#include +#endif "; #[cfg(feature = "bindgen")] diff --git a/openssl-sys/src/evp.rs b/openssl-sys/src/evp.rs index a3a8a84fb5..4d26f0f607 100644 --- a/openssl-sys/src/evp.rs +++ b/openssl-sys/src/evp.rs @@ -184,12 +184,28 @@ cfg_if! { pub const EVP_PKEY_OP_DERIVE: c_int = 1 << 10; } } +#[cfg(ossl340)] +pub const EVP_PKEY_OP_SIGNMSG: c_int = 1 << 14; +#[cfg(ossl340)] +pub const EVP_PKEY_OP_VERIFYMSG: c_int = 1 << 15; -pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN - | EVP_PKEY_OP_VERIFY - | EVP_PKEY_OP_VERIFYRECOVER - | EVP_PKEY_OP_SIGNCTX - | EVP_PKEY_OP_VERIFYCTX; +cfg_if! { + if #[cfg(ossl340)] { + pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN + | EVP_PKEY_OP_SIGNMSG + | EVP_PKEY_OP_VERIFY + | EVP_PKEY_OP_VERIFYMSG + | EVP_PKEY_OP_VERIFYRECOVER + | EVP_PKEY_OP_SIGNCTX + | EVP_PKEY_OP_VERIFYCTX; + } else { + pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN + | EVP_PKEY_OP_VERIFY + | EVP_PKEY_OP_VERIFYRECOVER + | EVP_PKEY_OP_SIGNCTX + | EVP_PKEY_OP_VERIFYCTX; + } +} pub const EVP_PKEY_OP_TYPE_CRYPT: c_int = EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT; diff --git a/openssl-sys/src/handwritten/conf.rs b/openssl-sys/src/handwritten/conf.rs index 2348d7d4c9..fa05c5554f 100644 --- a/openssl-sys/src/handwritten/conf.rs +++ b/openssl-sys/src/handwritten/conf.rs @@ -1,7 +1,13 @@ use super::super::*; +const_ptr_api! { + extern "C" { + pub fn NCONF_new(meth: #[const_ptr_if(libressl400)] CONF_METHOD) -> *mut CONF; + } +} + extern "C" { - pub fn NCONF_new(meth: *mut CONF_METHOD) -> *mut CONF; + #[cfg(not(libressl400))] pub fn NCONF_default() -> *mut CONF_METHOD; pub fn NCONF_free(conf: *mut CONF); } diff --git a/openssl-sys/src/handwritten/kdf.rs b/openssl-sys/src/handwritten/kdf.rs index 0f14b63a9c..d34f27450c 100644 --- a/openssl-sys/src/handwritten/kdf.rs +++ b/openssl-sys/src/handwritten/kdf.rs @@ -21,6 +21,14 @@ cfg_if! { info: *const u8, infolen: c_int, ) -> c_int; + pub fn EVP_KDF_CTX_new(kdf: *mut EVP_KDF) -> *mut EVP_KDF_CTX; + pub fn EVP_KDF_CTX_free(ctx: *mut EVP_KDF_CTX); + pub fn EVP_KDF_CTX_reset(ctx: *mut EVP_KDF_CTX); + pub fn EVP_KDF_CTX_get_kdf_size(ctx: *mut EVP_KDF_CTX) -> size_t; + pub fn EVP_KDF_derive(ctx: *mut EVP_KDF_CTX, key: *mut u8, keylen: size_t, params: *const OSSL_PARAM) -> c_int; + pub fn EVP_KDF_fetch(ctx: *mut OSSL_LIB_CTX, algorithm: *const c_char, properties: *const c_char) -> *mut EVP_KDF; + pub fn EVP_KDF_free(kdf: *mut EVP_KDF); } + } } diff --git a/openssl-sys/src/handwritten/mod.rs b/openssl-sys/src/handwritten/mod.rs index f54ec9be5e..47b3360fd8 100644 --- a/openssl-sys/src/handwritten/mod.rs +++ b/openssl-sys/src/handwritten/mod.rs @@ -29,6 +29,8 @@ pub use self::sha::*; pub use self::srtp::*; pub use self::ssl::*; pub use self::stack::*; +#[cfg(ossl320)] +pub use self::thread::*; pub use self::tls1::*; pub use self::types::*; pub use self::x509::*; @@ -66,6 +68,8 @@ mod sha; mod srtp; mod ssl; mod stack; +#[cfg(ossl320)] +mod thread; mod tls1; mod types; mod x509; diff --git a/openssl-sys/src/handwritten/params.rs b/openssl-sys/src/handwritten/params.rs index 3ed00c0488..542cef3374 100644 --- a/openssl-sys/src/handwritten/params.rs +++ b/openssl-sys/src/handwritten/params.rs @@ -6,4 +6,11 @@ extern "C" { pub fn OSSL_PARAM_construct_uint(key: *const c_char, buf: *mut c_uint) -> OSSL_PARAM; #[cfg(ossl300)] pub fn OSSL_PARAM_construct_end() -> OSSL_PARAM; + #[cfg(ossl300)] + pub fn OSSL_PARAM_construct_octet_string( + key: *const c_char, + buf: *mut c_void, + bsize: size_t, + ) -> OSSL_PARAM; + } diff --git a/openssl-sys/src/handwritten/thread.rs b/openssl-sys/src/handwritten/thread.rs new file mode 100644 index 0000000000..de661e1c5c --- /dev/null +++ b/openssl-sys/src/handwritten/thread.rs @@ -0,0 +1,7 @@ +use super::super::*; +use libc::*; + +extern "C" { + pub fn OSSL_set_max_threads(ctx: *mut OSSL_LIB_CTX, max_threads: u64) -> c_int; + pub fn OSSL_get_max_threads(ctx: *mut OSSL_LIB_CTX) -> u64; +} diff --git a/openssl-sys/src/handwritten/types.rs b/openssl-sys/src/handwritten/types.rs index 8c69c3efb3..d465a44148 100644 --- a/openssl-sys/src/handwritten/types.rs +++ b/openssl-sys/src/handwritten/types.rs @@ -472,6 +472,7 @@ pub struct X509V3_CTX { subject_cert: *mut c_void, subject_req: *mut c_void, crl: *mut c_void, + #[cfg(not(libressl400))] db_meth: *mut c_void, db: *mut c_void, #[cfg(ossl300)] @@ -1138,3 +1139,8 @@ pub struct OSSL_PARAM { data_size: size_t, return_size: size_t, } + +#[cfg(ossl300)] +pub enum EVP_KDF {} +#[cfg(ossl300)] +pub enum EVP_KDF_CTX {} diff --git a/openssl-sys/src/handwritten/x509_vfy.rs b/openssl-sys/src/handwritten/x509_vfy.rs index a560e586d8..31928f8979 100644 --- a/openssl-sys/src/handwritten/x509_vfy.rs +++ b/openssl-sys/src/handwritten/x509_vfy.rs @@ -9,10 +9,14 @@ extern "C" { pub fn X509_LOOKUP_meth_free(method: *mut X509_LOOKUP_METHOD); } +const_ptr_api! { + extern "C" { + pub fn X509_LOOKUP_hash_dir() -> #[const_ptr_if(libressl400)] X509_LOOKUP_METHOD; + pub fn X509_LOOKUP_file() -> #[const_ptr_if(libressl400)] X509_LOOKUP_METHOD; + } +} extern "C" { pub fn X509_LOOKUP_free(ctx: *mut X509_LOOKUP); - pub fn X509_LOOKUP_hash_dir() -> *mut X509_LOOKUP_METHOD; - pub fn X509_LOOKUP_file() -> *mut X509_LOOKUP_METHOD; pub fn X509_LOOKUP_ctrl( ctx: *mut X509_LOOKUP, cmd: c_int, @@ -41,11 +45,6 @@ extern "C" { pub fn X509_STORE_add_cert(store: *mut X509_STORE, x: *mut X509) -> c_int; - pub fn X509_STORE_add_lookup( - store: *mut X509_STORE, - meth: *mut X509_LOOKUP_METHOD, - ) -> *mut X509_LOOKUP; - pub fn X509_STORE_set_default_paths(store: *mut X509_STORE) -> c_int; pub fn X509_STORE_set_flags(store: *mut X509_STORE, flags: c_ulong) -> c_int; pub fn X509_STORE_set_purpose(ctx: *mut X509_STORE, purpose: c_int) -> c_int; @@ -55,6 +54,10 @@ extern "C" { const_ptr_api! { extern "C" { + pub fn X509_STORE_add_lookup( + store: *mut X509_STORE, + meth: #[const_ptr_if(libressl400)] X509_LOOKUP_METHOD, + ) -> *mut X509_LOOKUP; pub fn X509_STORE_set1_param(store: *mut X509_STORE, pm: #[const_ptr_if(ossl300)] X509_VERIFY_PARAM) -> c_int; } } diff --git a/openssl-sys/src/obj_mac.rs b/openssl-sys/src/obj_mac.rs index 400f73388f..8dd720a7ac 100644 --- a/openssl-sys/src/obj_mac.rs +++ b/openssl-sys/src/obj_mac.rs @@ -346,7 +346,6 @@ pub const NID_id_mod_cmp2000: c_int = 284; pub const NID_info_access: c_int = 177; pub const NID_biometricInfo: c_int = 285; pub const NID_qcStatements: c_int = 286; -pub const NID_ac_auditEntity: c_int = 287; pub const NID_ac_targeting: c_int = 288; pub const NID_aaControls: c_int = 289; pub const NID_sbgp_ipAddrBlock: c_int = 290; @@ -1015,3 +1014,10 @@ pub const NID_shake256: c_int = 1101; pub const NID_chacha20_poly1305: c_int = 1018; #[cfg(libressl271)] pub const NID_chacha20_poly1305: c_int = 967; +cfg_if! { + if #[cfg(ossl340)] { + pub const NID_ac_auditEntity: c_int = 1323; + } else { + pub const NID_ac_auditEntity: c_int = 287; + } +} diff --git a/openssl/CHANGELOG.md b/openssl/CHANGELOG.md index e3d1045ac0..e939d4784a 100644 --- a/openssl/CHANGELOG.md +++ b/openssl/CHANGELOG.md @@ -2,6 +2,29 @@ ## [Unreleased] +## [v0.10.68] - 2024-10-16 + +### Fixed + +* Fixed building on Rust 1.63.0 (our MSRV) with OpenSSL 3.2 or newer. + +## [v0.10.67] - 2024-10-15 + +### Added + +* Added support for LibreSSL 4.0.x. +* Added `argon2id` + +### Fixed + +* Fixed a case where `MdCtxRef::digest_verify_final` could leave an error on the stack. +* Fixed a case where `RsaRef::check_key` could leave an errror on the stack. + +### Changed + +* `openssl` is now a 2021 edition crate +* Explicitly specify the MSRV in `Cargo.toml` + ## [v0.10.66] - 2024-07-21 ### Fixed @@ -908,7 +931,9 @@ Look at the [release tags] for information about older releases. -[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.66...master +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.68...master +[v0.10.68]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.67...openssl-v0.10.68 +[v0.10.67]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.66...openssl-v0.10.67 [v0.10.66]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.65...openssl-v0.10.66 [v0.10.65]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.64...openssl-v0.10.65 [v0.10.64]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.63...openssl-v0.10.64 diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index cc8ef0accc..42e5134328 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openssl" -version = "0.10.66" +version = "0.10.68" authors = ["Steven Fackler "] license = "Apache-2.0" description = "OpenSSL bindings" @@ -8,7 +8,8 @@ repository = "https://github.com/sfackler/rust-openssl" readme = "README.md" keywords = ["crypto", "tls", "ssl", "dtls"] categories = ["cryptography", "api-bindings"] -edition = "2018" +edition = "2021" +rust-version = "1.63.0" # these are deprecated and don't do anything anymore [features] @@ -29,8 +30,8 @@ foreign-types = "0.3.1" libc = "0.2" once_cell = "1.5.2" -openssl-macros = { version = "0.1.0", path = "../openssl-macros" } -ffi = { package = "openssl-sys", version = "0.9.103", path = "../openssl-sys" } +openssl-macros = { version = "0.1.1", path = "../openssl-macros" } +ffi = { package = "openssl-sys", version = "0.9.104", path = "../openssl-sys" } [dev-dependencies] -hex = "0.3" +hex = "0.4" diff --git a/openssl/build.rs b/openssl/build.rs index 16101ea309..33372efd51 100644 --- a/openssl/build.rs +++ b/openssl/build.rs @@ -7,7 +7,7 @@ use std::env; fn main() { - println!("cargo:rustc-check-cfg=cfg(osslconf, values(\"OPENSSL_NO_OCB\", \"OPENSSL_NO_SM4\", \"OPENSSL_NO_SEED\", \"OPENSSL_NO_CHACHA\", \"OPENSSL_NO_CAST\", \"OPENSSL_NO_IDEA\", \"OPENSSL_NO_CAMELLIA\", \"OPENSSL_NO_RC4\", \"OPENSSL_NO_BF\", \"OPENSSL_NO_PSK\", \"OPENSSL_NO_DEPRECATED_3_0\", \"OPENSSL_NO_SCRYPT\", \"OPENSSL_NO_SM3\", \"OPENSSL_NO_RMD160\", \"OPENSSL_NO_EC2M\", \"OPENSSL_NO_OCSP\", \"OPENSSL_NO_CMS\", \"OPENSSL_NO_EC\"))"); + println!("cargo:rustc-check-cfg=cfg(osslconf, values(\"OPENSSL_NO_OCB\", \"OPENSSL_NO_SM4\", \"OPENSSL_NO_SEED\", \"OPENSSL_NO_CHACHA\", \"OPENSSL_NO_CAST\", \"OPENSSL_NO_IDEA\", \"OPENSSL_NO_CAMELLIA\", \"OPENSSL_NO_RC4\", \"OPENSSL_NO_BF\", \"OPENSSL_NO_PSK\", \"OPENSSL_NO_DEPRECATED_3_0\", \"OPENSSL_NO_SCRYPT\", \"OPENSSL_NO_SM3\", \"OPENSSL_NO_RMD160\", \"OPENSSL_NO_EC2M\", \"OPENSSL_NO_OCSP\", \"OPENSSL_NO_CMS\", \"OPENSSL_NO_EC\", \"OPENSSL_NO_ARGON2\"))"); println!("cargo:rustc-check-cfg=cfg(libressl)"); println!("cargo:rustc-check-cfg=cfg(boringssl)"); @@ -31,6 +31,7 @@ fn main() { println!("cargo:rustc-check-cfg=cfg(libressl380)"); println!("cargo:rustc-check-cfg=cfg(libressl382)"); println!("cargo:rustc-check-cfg=cfg(libressl390)"); + println!("cargo:rustc-check-cfg=cfg(libressl400)"); println!("cargo:rustc-check-cfg=cfg(ossl101)"); println!("cargo:rustc-check-cfg=cfg(ossl102)"); @@ -112,6 +113,9 @@ fn main() { if version >= 0x3_09_00_00_0 { println!("cargo:rustc-cfg=libressl390"); } + if version >= 0x4_00_00_00_0 { + println!("cargo:rustc-cfg=libressl400"); + } } if let Ok(vars) = env::var("DEP_OPENSSL_CONF") { diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs index 03340820d0..19bd3b57bc 100644 --- a/openssl/src/asn1.rs +++ b/openssl/src/asn1.rs @@ -247,7 +247,7 @@ impl PartialEq for Asn1TimeRef { } #[cfg(any(ossl102, boringssl))] -impl<'a> PartialEq for &'a Asn1TimeRef { +impl PartialEq for &Asn1TimeRef { fn eq(&self, other: &Asn1Time) -> bool { self.diff(other) .map(|t| t.days == 0 && t.secs == 0) @@ -270,7 +270,7 @@ impl PartialOrd for Asn1TimeRef { } #[cfg(any(ossl102, boringssl))] -impl<'a> PartialOrd for &'a Asn1TimeRef { +impl PartialOrd for &Asn1TimeRef { fn partial_cmp(&self, other: &Asn1Time) -> Option { self.compare(other).ok() } diff --git a/openssl/src/bio.rs b/openssl/src/bio.rs index d5232d2ee1..e97374b8dd 100644 --- a/openssl/src/bio.rs +++ b/openssl/src/bio.rs @@ -9,7 +9,7 @@ use crate::util; pub struct MemBioSlice<'a>(*mut ffi::BIO, PhantomData<&'a [u8]>); -impl<'a> Drop for MemBioSlice<'a> { +impl Drop for MemBioSlice<'_> { fn drop(&mut self) { unsafe { ffi::BIO_free_all(self.0); diff --git a/openssl/src/bn.rs b/openssl/src/bn.rs index ba784aab1a..99292fd0fb 100644 --- a/openssl/src/bn.rs +++ b/openssl/src/bn.rs @@ -1272,7 +1272,7 @@ macro_rules! delegate { }; } -impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef { +impl Add<&BigNumRef> for &BigNumRef { type Output = BigNum; fn add(self, oth: &BigNumRef) -> BigNum { @@ -1284,7 +1284,7 @@ impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef { delegate!(Add, add); -impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef { +impl Sub<&BigNumRef> for &BigNumRef { type Output = BigNum; fn sub(self, oth: &BigNumRef) -> BigNum { @@ -1296,7 +1296,7 @@ impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef { delegate!(Sub, sub); -impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef { +impl Mul<&BigNumRef> for &BigNumRef { type Output = BigNum; fn mul(self, oth: &BigNumRef) -> BigNum { @@ -1309,7 +1309,7 @@ impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef { delegate!(Mul, mul); -impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef { +impl<'b> Div<&'b BigNumRef> for &BigNumRef { type Output = BigNum; fn div(self, oth: &'b BigNumRef) -> BigNum { @@ -1322,7 +1322,7 @@ impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef { delegate!(Div, div); -impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef { +impl<'b> Rem<&'b BigNumRef> for &BigNumRef { type Output = BigNum; fn rem(self, oth: &'b BigNumRef) -> BigNum { @@ -1335,7 +1335,7 @@ impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef { delegate!(Rem, rem); -impl<'a> Shl for &'a BigNumRef { +impl Shl for &BigNumRef { type Output = BigNum; fn shl(self, n: i32) -> BigNum { @@ -1345,7 +1345,7 @@ impl<'a> Shl for &'a BigNumRef { } } -impl<'a> Shl for &'a BigNum { +impl Shl for &BigNum { type Output = BigNum; fn shl(self, n: i32) -> BigNum { @@ -1353,7 +1353,7 @@ impl<'a> Shl for &'a BigNum { } } -impl<'a> Shr for &'a BigNumRef { +impl Shr for &BigNumRef { type Output = BigNum; fn shr(self, n: i32) -> BigNum { @@ -1363,7 +1363,7 @@ impl<'a> Shr for &'a BigNumRef { } } -impl<'a> Shr for &'a BigNum { +impl Shr for &BigNum { type Output = BigNum; fn shr(self, n: i32) -> BigNum { @@ -1371,7 +1371,7 @@ impl<'a> Shr for &'a BigNum { } } -impl<'a> Neg for &'a BigNumRef { +impl Neg for &BigNumRef { type Output = BigNum; fn neg(self) -> BigNum { @@ -1379,7 +1379,7 @@ impl<'a> Neg for &'a BigNumRef { } } -impl<'a> Neg for &'a BigNum { +impl Neg for &BigNum { type Output = BigNum; fn neg(self) -> BigNum { diff --git a/openssl/src/cipher_ctx.rs b/openssl/src/cipher_ctx.rs index abb1f11ef3..d31830ad0c 100644 --- a/openssl/src/cipher_ctx.rs +++ b/openssl/src/cipher_ctx.rs @@ -328,10 +328,6 @@ impl CipherCtxRef { /// /// Panics if the context has not been initialized with a cipher or if the buffer is smaller than the cipher's key /// length. - /// - /// This corresponds to [`EVP_CIPHER_CTX_rand_key`]. - /// - /// [`EVP_CIPHER_CTX_rand_key`]: https://www.openssl.org/docs/manmaster/man3/EVP_CIPHER_CTX_rand_key.html #[corresponds(EVP_CIPHER_CTX_rand_key)] #[cfg(not(boringssl))] pub fn rand_key(&self, buf: &mut [u8]) -> Result<(), ErrorStack> { diff --git a/openssl/src/conf.rs b/openssl/src/conf.rs index 715519c595..88740298b3 100644 --- a/openssl/src/conf.rs +++ b/openssl/src/conf.rs @@ -8,7 +8,7 @@ foreign_type_and_impl_send_sync! { pub struct ConfRef; } -#[cfg(not(boringssl))] +#[cfg(not(any(boringssl, libressl400)))] mod methods { use super::Conf; use crate::cvt_p; @@ -61,5 +61,5 @@ mod methods { } } } -#[cfg(not(boringssl))] +#[cfg(not(any(boringssl, libressl400)))] pub use methods::*; diff --git a/openssl/src/derive.rs b/openssl/src/derive.rs index 424c5f92d7..90a5650c0c 100644 --- a/openssl/src/derive.rs +++ b/openssl/src/derive.rs @@ -61,8 +61,8 @@ use openssl_macros::corresponds; /// A type used to derive a shared secret between two keys. pub struct Deriver<'a>(*mut ffi::EVP_PKEY_CTX, PhantomData<&'a ()>); -unsafe impl<'a> Sync for Deriver<'a> {} -unsafe impl<'a> Send for Deriver<'a> {} +unsafe impl Sync for Deriver<'_> {} +unsafe impl Send for Deriver<'_> {} #[allow(clippy::len_without_is_empty)] impl<'a> Deriver<'a> { @@ -163,7 +163,7 @@ impl<'a> Deriver<'a> { } } -impl<'a> Drop for Deriver<'a> { +impl Drop for Deriver<'_> { fn drop(&mut self) { unsafe { ffi::EVP_PKEY_CTX_free(self.0); diff --git a/openssl/src/encrypt.rs b/openssl/src/encrypt.rs index 4522146f89..c50be081cf 100644 --- a/openssl/src/encrypt.rs +++ b/openssl/src/encrypt.rs @@ -56,10 +56,10 @@ pub struct Encrypter<'a> { _p: PhantomData<&'a ()>, } -unsafe impl<'a> Sync for Encrypter<'a> {} -unsafe impl<'a> Send for Encrypter<'a> {} +unsafe impl Sync for Encrypter<'_> {} +unsafe impl Send for Encrypter<'_> {} -impl<'a> Drop for Encrypter<'a> { +impl Drop for Encrypter<'_> { fn drop(&mut self) { unsafe { ffi::EVP_PKEY_CTX_free(self.pctx); @@ -260,10 +260,10 @@ pub struct Decrypter<'a> { _p: PhantomData<&'a ()>, } -unsafe impl<'a> Sync for Decrypter<'a> {} -unsafe impl<'a> Send for Decrypter<'a> {} +unsafe impl Sync for Decrypter<'_> {} +unsafe impl Send for Decrypter<'_> {} -impl<'a> Drop for Decrypter<'a> { +impl Drop for Decrypter<'_> { fn drop(&mut self) { unsafe { ffi::EVP_PKEY_CTX_free(self.pctx); diff --git a/openssl/src/hash.rs b/openssl/src/hash.rs index 117bb2fb0d..8efb4239f1 100644 --- a/openssl/src/hash.rs +++ b/openssl/src/hash.rs @@ -41,6 +41,7 @@ use std::ptr; use crate::error::ErrorStack; use crate::nid::Nid; use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; cfg_if! { if #[cfg(any(ossl110, boringssl, libressl382))] { @@ -65,10 +66,7 @@ impl MessageDigest { } /// Returns the `MessageDigest` corresponding to an `Nid`. - /// - /// This corresponds to [`EVP_get_digestbynid`]. - /// - /// [`EVP_get_digestbynid`]: https://www.openssl.org/docs/manmaster/crypto/EVP_DigestInit.html + #[corresponds(EVP_get_digestbynid)] pub fn from_nid(type_: Nid) -> Option { ffi::init(); unsafe { @@ -82,10 +80,7 @@ impl MessageDigest { } /// Returns the `MessageDigest` corresponding to an algorithm name. - /// - /// This corresponds to [`EVP_get_digestbyname`]. - /// - /// [`EVP_get_digestbyname`]: https://www.openssl.org/docs/manmaster/crypto/EVP_DigestInit.html + #[corresponds(EVP_get_digestbyname)] pub fn from_name(name: &str) -> Option { ffi::init(); let name = CString::new(name).ok()?; diff --git a/openssl/src/kdf.rs b/openssl/src/kdf.rs new file mode 100644 index 0000000000..a5da352505 --- /dev/null +++ b/openssl/src/kdf.rs @@ -0,0 +1,176 @@ +#[cfg(ossl320)] +struct EvpKdf(*mut ffi::EVP_KDF); + +#[cfg(ossl320)] +impl Drop for EvpKdf { + fn drop(&mut self) { + unsafe { + ffi::EVP_KDF_free(self.0); + } + } +} + +#[cfg(ossl320)] +struct EvpKdfCtx(*mut ffi::EVP_KDF_CTX); + +#[cfg(ossl320)] +impl Drop for EvpKdfCtx { + fn drop(&mut self) { + unsafe { + ffi::EVP_KDF_CTX_free(self.0); + } + } +} + +cfg_if::cfg_if! { + if #[cfg(all(ossl320, not(osslconf = "OPENSSL_NO_ARGON2")))] { + use std::cmp; + use std::ffi::c_void; + use std::mem::MaybeUninit; + use std::ptr; + use foreign_types::ForeignTypeRef; + use libc::c_char; + use crate::{cvt, cvt_p}; + use crate::lib_ctx::LibCtxRef; + use crate::error::ErrorStack; + + /// Derives a key using the argon2id algorithm. + /// + /// To use multiple cores to process the lanes in parallel you must + /// set a global max thread count using `OSSL_set_max_threads`. On + /// builds with no threads all lanes will be processed sequentially. + /// + /// Requires OpenSSL 3.2.0 or newer. + #[allow(clippy::too_many_arguments)] + pub fn argon2id( + ctx: Option<&LibCtxRef>, + pass: &[u8], + salt: &[u8], + ad: Option<&[u8]>, + secret: Option<&[u8]>, + mut iter: u32, + mut lanes: u32, + mut memcost: u32, + out: &mut [u8], + ) -> Result<(), ErrorStack> { + unsafe { + ffi::init(); + let libctx = ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr); + + let max_threads = ffi::OSSL_get_max_threads(libctx); + let mut threads = 1; + // If max_threads is 0, then this isn't a threaded build. + // If max_threads is > u32::MAX we need to clamp since + // argon2id's threads parameter is a u32. + if max_threads > 0 { + threads = cmp::min(lanes, cmp::min(max_threads, u32::MAX as u64) as u32); + } + let mut params: [ffi::OSSL_PARAM; 10] = + core::array::from_fn(|_| MaybeUninit::::zeroed().assume_init()); + let mut idx = 0; + params[idx] = ffi::OSSL_PARAM_construct_octet_string( + b"pass\0".as_ptr() as *const c_char, + pass.as_ptr() as *mut c_void, + pass.len(), + ); + idx += 1; + params[idx] = ffi::OSSL_PARAM_construct_octet_string( + b"salt\0".as_ptr() as *const c_char, + salt.as_ptr() as *mut c_void, + salt.len(), + ); + idx += 1; + params[idx] = + ffi::OSSL_PARAM_construct_uint(b"threads\0".as_ptr() as *const c_char, &mut threads); + idx += 1; + params[idx] = + ffi::OSSL_PARAM_construct_uint(b"lanes\0".as_ptr() as *const c_char, &mut lanes); + idx += 1; + params[idx] = + ffi::OSSL_PARAM_construct_uint(b"memcost\0".as_ptr() as *const c_char, &mut memcost); + idx += 1; + params[idx] = + ffi::OSSL_PARAM_construct_uint(b"iter\0".as_ptr() as *const c_char, &mut iter); + idx += 1; + let mut size = out.len() as u32; + params[idx] = + ffi::OSSL_PARAM_construct_uint(b"size\0".as_ptr() as *const c_char, &mut size); + idx += 1; + if let Some(ad) = ad { + params[idx] = ffi::OSSL_PARAM_construct_octet_string( + b"ad\0".as_ptr() as *const c_char, + ad.as_ptr() as *mut c_void, + ad.len(), + ); + idx += 1; + } + if let Some(secret) = secret { + params[idx] = ffi::OSSL_PARAM_construct_octet_string( + b"secret\0".as_ptr() as *const c_char, + secret.as_ptr() as *mut c_void, + secret.len(), + ); + idx += 1; + } + params[idx] = ffi::OSSL_PARAM_construct_end(); + + let argon2 = EvpKdf(cvt_p(ffi::EVP_KDF_fetch( + libctx, + b"ARGON2ID\0".as_ptr() as *const c_char, + ptr::null(), + ))?); + let ctx = EvpKdfCtx(cvt_p(ffi::EVP_KDF_CTX_new(argon2.0))?); + cvt(ffi::EVP_KDF_derive( + ctx.0, + out.as_mut_ptr(), + out.len(), + params.as_ptr(), + )) + .map(|_| ()) + } + } + } +} + +#[cfg(test)] +mod tests { + #[test] + #[cfg(all(ossl320, not(osslconf = "OPENSSL_NO_ARGON2")))] + fn argon2id() { + // RFC 9106 test vector for argon2id + let pass = hex::decode("0101010101010101010101010101010101010101010101010101010101010101") + .unwrap(); + let salt = hex::decode("02020202020202020202020202020202").unwrap(); + let secret = hex::decode("0303030303030303").unwrap(); + let ad = hex::decode("040404040404040404040404").unwrap(); + let expected = "0d640df58d78766c08c037a34a8b53c9d01ef0452d75b65eb52520e96b01e659"; + + let mut actual = [0u8; 32]; + super::argon2id( + None, + &pass, + &salt, + Some(&ad), + Some(&secret), + 3, + 4, + 32, + &mut actual, + ) + .unwrap(); + assert_eq!(hex::encode(&actual[..]), expected); + } + + #[test] + #[cfg(all(ossl320, not(osslconf = "OPENSSL_NO_ARGON2")))] + fn argon2id_no_ad_secret() { + // Test vector from OpenSSL + let pass = b""; + let salt = hex::decode("02020202020202020202020202020202").unwrap(); + let expected = "0a34f1abde67086c82e785eaf17c68382259a264f4e61b91cd2763cb75ac189a"; + + let mut actual = [0u8; 32]; + super::argon2id(None, pass, &salt, None, None, 3, 4, 32, &mut actual).unwrap(); + assert_eq!(hex::encode(&actual[..]), expected); + } +} diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index 555eda9720..c58e5bf598 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -168,6 +168,7 @@ pub mod ex_data; #[cfg(not(any(libressl, ossl300)))] pub mod fips; pub mod hash; +pub mod kdf; #[cfg(ossl300)] pub mod lib_ctx; pub mod md; diff --git a/openssl/src/md_ctx.rs b/openssl/src/md_ctx.rs index 30e0337b47..36be3e9964 100644 --- a/openssl/src/md_ctx.rs +++ b/openssl/src/md_ctx.rs @@ -85,7 +85,7 @@ use crate::error::ErrorStack; use crate::md::MdRef; use crate::pkey::{HasPrivate, HasPublic, PKeyRef}; use crate::pkey_ctx::PkeyCtxRef; -use crate::{cvt, cvt_n, cvt_p}; +use crate::{cvt, cvt_p}; use cfg_if::cfg_if; use foreign_types::{ForeignType, ForeignTypeRef}; use openssl_macros::corresponds; @@ -309,12 +309,21 @@ impl MdCtxRef { #[inline] pub fn digest_verify_final(&mut self, signature: &[u8]) -> Result { unsafe { - let r = cvt_n(ffi::EVP_DigestVerifyFinal( + let r = ffi::EVP_DigestVerifyFinal( self.as_ptr(), signature.as_ptr() as *mut _, signature.len(), - ))?; - Ok(r == 1) + ); + if r == 1 { + Ok(true) + } else { + let errors = ErrorStack::get(); + if errors.errors().is_empty() { + Ok(false) + } else { + Err(errors) + } + } } } @@ -424,8 +433,11 @@ mod test { ctx.digest_verify_init(Some(md), &key1).unwrap(); ctx.digest_verify_update(bad_data).unwrap(); - let valid = ctx.digest_verify_final(&signature).unwrap(); - assert!(!valid); + assert!(matches!( + ctx.digest_verify_final(&signature), + Ok(false) | Err(_) + )); + assert!(ErrorStack::get().errors().is_empty()); } #[test] diff --git a/openssl/src/nid.rs b/openssl/src/nid.rs index e50feb0683..d093c67633 100644 --- a/openssl/src/nid.rs +++ b/openssl/src/nid.rs @@ -79,8 +79,6 @@ impl Nid { } /// Returns the `Nid`s of the digest and public key algorithms associated with a signature ID. - /// - /// This corresponds to `OBJ_find_sigid_algs`. #[corresponds(OBJ_find_sigid_algs)] #[allow(clippy::trivially_copy_pass_by_ref)] pub fn signature_algorithms(&self) -> Option { diff --git a/openssl/src/ocsp.rs b/openssl/src/ocsp.rs index 93a5d36b7e..570b8c2d0b 100644 --- a/openssl/src/ocsp.rs +++ b/openssl/src/ocsp.rs @@ -122,7 +122,7 @@ pub struct OcspStatus<'a> { pub next_update: &'a Asn1GeneralizedTimeRef, } -impl<'a> OcspStatus<'a> { +impl OcspStatus<'_> { /// Checks validity of the `this_update` and `next_update` fields. /// /// The `nsec` parameter specifies an amount of slack time that will be used when comparing diff --git a/openssl/src/pkey_ctx.rs b/openssl/src/pkey_ctx.rs index add7830484..f30f06973a 100644 --- a/openssl/src/pkey_ctx.rs +++ b/openssl/src/pkey_ctx.rs @@ -1087,14 +1087,14 @@ mod test { #[cfg(ossl320)] fn ecdsa_deterministic_signature() { let private_key_pem = "-----BEGIN PRIVATE KEY----- -MDkCAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQEEHzAdAgEBBBhvqwNJNOTA/Jrmf1tWWanX0f79GH7g -n9Q= +MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCDJr6nYRbp1FmtcIVdnsdaTTlDD2zbo +mxJ7imIrEg9nIQ== -----END PRIVATE KEY-----"; let key1 = EcKey::private_key_from_pem(private_key_pem.as_bytes()).unwrap(); let key1 = PKey::from_ec_key(key1).unwrap(); let input = "sample"; - let expected_output = hex::decode("303502190098C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF021857A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64").unwrap(); + let expected_output = hex::decode("3044022061340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D3202206D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB").unwrap(); let hashed_input = hash(MessageDigest::sha1(), input.as_bytes()).unwrap(); let mut ctx = PkeyCtx::new(&key1).unwrap(); diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index 9ef56942bf..2e6614aed3 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -234,14 +234,18 @@ where /// Validates RSA parameters for correctness #[corresponds(RSA_check_key)] - #[allow(clippy::unnecessary_cast)] pub fn check_key(&self) -> Result { unsafe { - let result = ffi::RSA_check_key(self.as_ptr()) as i32; - if result == -1 { - Err(ErrorStack::get()) + let result = ffi::RSA_check_key(self.as_ptr()); + if result != 1 { + let errors = ErrorStack::get(); + if errors.errors().is_empty() { + Ok(false) + } else { + Err(errors) + } } else { - Ok(result == 1) + Ok(true) } } } @@ -849,4 +853,21 @@ mod test { let e = BigNum::from_u32(0x10001).unwrap(); Rsa::generate_with_e(2048, &e).unwrap(); } + + #[test] + fn test_check_key() { + let k = Rsa::private_key_from_pem_passphrase( + include_bytes!("../test/rsa-encrypted.pem"), + b"mypass", + ) + .unwrap(); + assert!(matches!(k.check_key(), Ok(true))); + assert!(ErrorStack::get().errors().is_empty()); + + // BoringSSL simply rejects this key, because its corrupted! + if let Ok(k) = Rsa::private_key_from_pem(include_bytes!("../test/corrupted-rsa.pem")) { + assert!(matches!(k.check_key(), Ok(false) | Err(_))); + assert!(ErrorStack::get().errors().is_empty()); + } + } } diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs index 0154b1d4b7..bea91a5a43 100644 --- a/openssl/src/sign.rs +++ b/openssl/src/sign.rs @@ -79,6 +79,7 @@ use crate::hash::MessageDigest; use crate::pkey::{HasPrivate, HasPublic, PKeyRef}; use crate::rsa::Padding; use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; cfg_if! { if #[cfg(any(ossl110, libressl382))] { @@ -135,10 +136,7 @@ impl Signer<'_> { /// /// This cannot be used with Ed25519 or Ed448 keys. Please refer to /// `new_without_digest`. - /// - /// OpenSSL documentation at [`EVP_DigestSignInit`]. - /// - /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html + #[corresponds(EVP_DigestSignInit)] pub fn new<'a, T>(type_: MessageDigest, pkey: &PKeyRef) -> Result, ErrorStack> where T: HasPrivate, @@ -150,10 +148,7 @@ impl Signer<'_> { /// /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys. /// It can also be used to create a CMAC. - /// - /// OpenSSL documentation at [`EVP_DigestSignInit`]. - /// - /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html + #[corresponds(EVP_DigestSignInit)] pub fn new_without_digest<'a, T>(pkey: &PKeyRef) -> Result, ErrorStack> where T: HasPrivate, @@ -198,8 +193,7 @@ impl Signer<'_> { /// Returns the RSA padding mode in use. /// /// This is only useful for RSA keys. - /// - /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`. + #[corresponds(EVP_PKEY_CTX_get_rsa_padding)] pub fn rsa_padding(&self) -> Result { unsafe { let mut pad = 0; @@ -211,10 +205,7 @@ impl Signer<'_> { /// Sets the RSA padding mode. /// /// This is only useful for RSA keys. - /// - /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`]. - /// - /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html + #[corresponds(EVP_PKEY_CTX_set_rsa_padding)] pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( @@ -228,10 +219,7 @@ impl Signer<'_> { /// Sets the RSA PSS salt length. /// /// This is only useful for RSA keys. - /// - /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]. - /// - /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html + #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)] pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( @@ -245,10 +233,7 @@ impl Signer<'_> { /// Sets the RSA MGF1 algorithm. /// /// This is only useful for RSA keys. - /// - /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`]. - /// - /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html + #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)] pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( @@ -263,10 +248,7 @@ impl Signer<'_> { /// /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming. /// Use `sign_oneshot` instead. - /// - /// OpenSSL documentation at [`EVP_DigestUpdate`]. - /// - /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html + #[corresponds(EVP_DigestUpdate)] pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_DigestUpdate( @@ -282,10 +264,7 @@ impl Signer<'_> { /// /// The actual signature may be shorter than this value. Check the return value of /// `sign` to get the exact length. - /// - /// OpenSSL documentation at [`EVP_DigestSignFinal`]. - /// - /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/manmaster/crypto/EVP_DigestSignFinal.html + #[corresponds(EVP_DigestSignFinal)] pub fn len(&self) -> Result { self.len_intern() } @@ -322,10 +301,7 @@ impl Signer<'_> { /// /// This method will fail if the buffer is not large enough for the signature. Use the `len` /// method to get an upper bound on the required size. - /// - /// OpenSSL documentation at [`EVP_DigestSignFinal`]. - /// - /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/manmaster/crypto/EVP_DigestSignFinal.html + #[corresponds(EVP_DigestSignFinal)] pub fn sign(&self, buf: &mut [u8]) -> Result { unsafe { let mut len = buf.len(); @@ -356,10 +332,7 @@ impl Signer<'_> { /// /// This method will fail if the buffer is not large enough for the signature. Use the `len` /// method to get an upper bound on the required size. - /// - /// OpenSSL documentation at [`EVP_DigestSign`]. - /// - /// [`EVP_DigestSign`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestSign.html + #[corresponds(EVP_DigestSign)] #[cfg(any(ossl111, boringssl, libressl370))] pub fn sign_oneshot( &mut self, @@ -392,7 +365,7 @@ impl Signer<'_> { } } -impl<'a> Write for Signer<'a> { +impl Write for Signer<'_> { fn write(&mut self, buf: &[u8]) -> io::Result { self.update(buf)?; Ok(buf.len()) @@ -411,10 +384,10 @@ pub struct Verifier<'a> { pkey_pd: PhantomData<&'a ()>, } -unsafe impl<'a> Sync for Verifier<'a> {} -unsafe impl<'a> Send for Verifier<'a> {} +unsafe impl Sync for Verifier<'_> {} +unsafe impl Send for Verifier<'_> {} -impl<'a> Drop for Verifier<'a> { +impl Drop for Verifier<'_> { fn drop(&mut self) { // pkey_ctx is owned by the md_ctx, so no need to explicitly free it. unsafe { @@ -429,10 +402,7 @@ impl<'a> Verifier<'a> { /// /// This cannot be used with Ed25519 or Ed448 keys. Please refer to /// [`Verifier::new_without_digest`]. - /// - /// OpenSSL documentation at [`EVP_DigestVerifyInit`]. - /// - /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html + #[corresponds(EVP_DigestVerifyInit)] pub fn new(type_: MessageDigest, pkey: &'a PKeyRef) -> Result, ErrorStack> where T: HasPublic, @@ -443,10 +413,7 @@ impl<'a> Verifier<'a> { /// Creates a new `Verifier` without a digest. /// /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys. - /// - /// OpenSSL documentation at [`EVP_DigestVerifyInit`]. - /// - /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html + #[corresponds(EVP_DigestVerifyInit)] pub fn new_without_digest(pkey: &'a PKeyRef) -> Result, ErrorStack> where T: HasPublic, @@ -491,8 +458,7 @@ impl<'a> Verifier<'a> { /// Returns the RSA padding mode in use. /// /// This is only useful for RSA keys. - /// - /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`. + #[corresponds(EVP_PKEY_CTX_get_rsa_padding)] pub fn rsa_padding(&self) -> Result { unsafe { let mut pad = 0; @@ -504,10 +470,7 @@ impl<'a> Verifier<'a> { /// Sets the RSA padding mode. /// /// This is only useful for RSA keys. - /// - /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`]. - /// - /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html + #[corresponds(EVP_PKEY_CTX_set_rsa_padding)] pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( @@ -521,10 +484,7 @@ impl<'a> Verifier<'a> { /// Sets the RSA PSS salt length. /// /// This is only useful for RSA keys. - /// - /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]. - /// - /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html + #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)] pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( @@ -538,10 +498,7 @@ impl<'a> Verifier<'a> { /// Sets the RSA MGF1 algorithm. /// /// This is only useful for RSA keys. - /// - /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`]. - /// - /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html + #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)] pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( @@ -556,10 +513,7 @@ impl<'a> Verifier<'a> { /// /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming. /// Use [`Verifier::verify_oneshot`] instead. - /// - /// OpenSSL documentation at [`EVP_DigestUpdate`]. - /// - /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html + #[corresponds(EVP_DigestUpdate)] pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_DigestUpdate( @@ -572,10 +526,7 @@ impl<'a> Verifier<'a> { } /// Determines if the data fed into the `Verifier` matches the provided signature. - /// - /// OpenSSL documentation at [`EVP_DigestVerifyFinal`]. - /// - /// [`EVP_DigestVerifyFinal`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyFinal.html + #[corresponds(EVP_DigestVerifyFinal)] pub fn verify(&self, signature: &[u8]) -> Result { unsafe { let r = @@ -592,10 +543,7 @@ impl<'a> Verifier<'a> { } /// Determines if the data given in `buf` matches the provided signature. - /// - /// OpenSSL documentation at [`EVP_DigestVerify`]. - /// - /// [`EVP_DigestVerify`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestVerify.html + #[corresponds(EVP_DigestVerify)] #[cfg(any(ossl111, boringssl, libressl370))] pub fn verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result { unsafe { @@ -618,7 +566,7 @@ impl<'a> Verifier<'a> { } } -impl<'a> Write for Verifier<'a> { +impl Write for Verifier<'_> { fn write(&mut self, buf: &[u8]) -> io::Result { self.update(buf)?; Ok(buf.len()) diff --git a/openssl/src/ssl/callbacks.rs b/openssl/src/ssl/callbacks.rs index ccf5308509..f7e51a5d38 100644 --- a/openssl/src/ssl/callbacks.rs +++ b/openssl/src/ssl/callbacks.rs @@ -19,7 +19,7 @@ use crate::dh::Dh; use crate::ec::EcKey; use crate::error::ErrorStack; use crate::pkey::Params; -#[cfg(any(ossl102, libressl261))] +#[cfg(any(ossl102, libressl261, boringssl))] use crate::ssl::AlpnError; use crate::ssl::{ try_get_session_ctx_index, SniError, Ssl, SslAlert, SslContext, SslContextRef, SslRef, @@ -178,7 +178,7 @@ where } } -#[cfg(any(ossl102, libressl261))] +#[cfg(any(ossl102, libressl261, boringssl))] pub extern "C" fn raw_alpn_select( ssl: *mut ffi::SSL, out: *mut *const c_uchar, diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 322ca9541a..f5a696ab54 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -602,17 +602,17 @@ impl SslAlert { /// An error returned from an ALPN selection callback. /// -/// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. -#[cfg(any(ossl102, libressl261))] +/// Requires BoringSSL or OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. +#[cfg(any(ossl102, libressl261, boringssl))] #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct AlpnError(c_int); -#[cfg(any(ossl102, libressl261))] +#[cfg(any(ossl102, libressl261, boringssl))] impl AlpnError { /// Terminate the handshake with a fatal alert. /// - /// Requires OpenSSL 1.1.0 or newer. - #[cfg(ossl110)] + /// Requires BoringSSL or OpenSSL 1.1.0 or newer. + #[cfg(any(ossl110, boringssl))] pub const ALERT_FATAL: AlpnError = AlpnError(ffi::SSL_TLSEXT_ERR_ALERT_FATAL); /// Do not select a protocol, but continue the handshake. @@ -1267,23 +1267,30 @@ impl SslContextBuilder { /// of those protocols on success. The [`select_next_proto`] function implements the standard /// protocol selection algorithm. /// - /// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. + /// Requires BoringSSL or OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. /// /// [`SslContextBuilder::set_alpn_protos`]: struct.SslContextBuilder.html#method.set_alpn_protos /// [`select_next_proto`]: fn.select_next_proto.html #[corresponds(SSL_CTX_set_alpn_select_cb)] - #[cfg(any(ossl102, libressl261))] + #[cfg(any(ossl102, libressl261, boringssl))] pub fn set_alpn_select_callback(&mut self, callback: F) where F: for<'a> Fn(&mut SslRef, &'a [u8]) -> Result<&'a [u8], AlpnError> + 'static + Sync + Send, { unsafe { self.set_ex_data(SslContext::cached_ex_index::(), callback); + #[cfg(not(boringssl))] ffi::SSL_CTX_set_alpn_select_cb__fixed_rust( self.as_ptr(), Some(callbacks::raw_alpn_select::), ptr::null_mut(), ); + #[cfg(boringssl)] + ffi::SSL_CTX_set_alpn_select_cb( + self.as_ptr(), + Some(callbacks::raw_alpn_select::), + ptr::null_mut(), + ); } } @@ -2297,10 +2304,6 @@ impl Ssl { } /// Creates a new `Ssl`. - /// - /// This corresponds to [`SSL_new`]. - /// - /// [`SSL_new`]: https://www.openssl.org/docs/manmaster/ssl/SSL_new.html #[corresponds(SSL_new)] pub fn new(ctx: &SslContextRef) -> Result { let session_ctx_index = try_get_session_ctx_index()?; @@ -2314,15 +2317,10 @@ impl Ssl { } /// Initiates a client-side TLS handshake. - /// - /// This corresponds to [`SSL_connect`]. - /// /// # Warning /// /// OpenSSL's default configuration is insecure. It is highly recommended to use /// `SslConnector` rather than `Ssl` directly, as it manages that configuration. - /// - /// [`SSL_connect`]: https://www.openssl.org/docs/manmaster/man3/SSL_connect.html #[corresponds(SSL_connect)] #[allow(deprecated)] pub fn connect(self, stream: S) -> Result, HandshakeError> @@ -2334,14 +2332,10 @@ impl Ssl { /// Initiates a server-side TLS handshake. /// - /// This corresponds to [`SSL_accept`]. - /// /// # Warning /// /// OpenSSL's default configuration is insecure. It is highly recommended to use /// `SslAcceptor` rather than `Ssl` directly, as it manages that configuration. - /// - /// [`SSL_accept`]: https://www.openssl.org/docs/manmaster/man3/SSL_accept.html #[corresponds(SSL_accept)] #[allow(deprecated)] pub fn accept(self, stream: S) -> Result, HandshakeError> @@ -2656,10 +2650,6 @@ impl SslRef { } /// Enables the DTLS extension "use_srtp" as defined in RFC5764. - /// - /// This corresponds to [`SSL_set_tlsext_use_srtp`]. - /// - /// [`SSL_set_tlsext_use_srtp`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_tlsext_use_srtp.html #[corresponds(SSL_set_tlsext_use_srtp)] pub fn set_tlsext_use_srtp(&mut self, protocols: &str) -> Result<(), ErrorStack> { unsafe { @@ -2678,10 +2668,6 @@ impl SslRef { /// Gets all SRTP profiles that are enabled for handshake via set_tlsext_use_srtp /// /// DTLS extension "use_srtp" as defined in RFC5764 has to be enabled. - /// - /// This corresponds to [`SSL_get_srtp_profiles`]. - /// - /// [`SSL_get_srtp_profiles`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_tlsext_use_srtp.html #[corresponds(SSL_get_srtp_profiles)] pub fn srtp_profiles(&self) -> Option<&StackRef> { unsafe { @@ -3526,9 +3512,7 @@ where { /// Restarts the handshake process. /// - /// This corresponds to [`SSL_do_handshake`]. - /// - /// [`SSL_do_handshake`]: https://www.openssl.org/docs/manmaster/man3/SSL_do_handshake.html + #[corresponds(SSL_do_handshake)] pub fn handshake(mut self) -> Result, HandshakeError> { match self.stream.do_handshake() { Ok(()) => Ok(self.stream), @@ -4056,10 +4040,7 @@ where /// `accept`. If a HelloRetryRequest containing a fresh cookie was /// transmitted, `Ok(false)` is returned instead. If the handshake cannot /// proceed at all, `Err` is returned. - /// - /// This corresponds to [`SSL_stateless`] - /// - /// [`SSL_stateless`]: https://www.openssl.org/docs/manmaster/man3/SSL_stateless.html + #[corresponds(SSL_stateless)] #[cfg(ossl111)] pub fn stateless(&mut self) -> Result { match unsafe { ffi::SSL_stateless(self.inner.ssl.as_ptr()) } { @@ -4071,19 +4052,13 @@ where } /// Configure as an outgoing stream from a client. - /// - /// This corresponds to [`SSL_set_connect_state`]. - /// - /// [`SSL_set_connect_state`]: https://www.openssl.org/docs/manmaster/man3/SSL_set_connect_state.html + #[corresponds(SSL_set_connect_state)] pub fn set_connect_state(&mut self) { unsafe { ffi::SSL_set_connect_state(self.inner.ssl.as_ptr()) } } /// Configure as an incoming stream to a server. - /// - /// This corresponds to [`SSL_set_accept_state`]. - /// - /// [`SSL_set_accept_state`]: https://www.openssl.org/docs/manmaster/man3/SSL_set_accept_state.html + #[corresponds(SSL_set_accept_state)] pub fn set_accept_state(&mut self) { unsafe { ffi::SSL_set_accept_state(self.inner.ssl.as_ptr()) } } @@ -4129,10 +4104,7 @@ where /// Initiates the handshake. /// /// This will fail if `set_accept_state` or `set_connect_state` was not called first. - /// - /// This corresponds to [`SSL_do_handshake`]. - /// - /// [`SSL_do_handshake`]: https://www.openssl.org/docs/manmaster/man3/SSL_do_handshake.html + #[corresponds(SSL_do_handshake)] pub fn handshake(mut self) -> Result, HandshakeError> { match self.inner.do_handshake() { Ok(()) => Ok(self.inner), @@ -4160,10 +4132,7 @@ where /// Returns `Ok(0)` if all early data has been read. /// /// 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 + #[corresponds(SSL_read_early_data)] #[cfg(any(ossl111, libressl340))] pub fn read_early_data(&mut self, buf: &mut [u8]) -> Result { self.inner.read_early_data(buf) @@ -4175,10 +4144,7 @@ where /// `set_connect_state` first. /// /// 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 + #[corresponds(SSL_write_early_data)] #[cfg(any(ossl111, libressl340))] pub fn write_early_data(&mut self, buf: &[u8]) -> Result { self.inner.write_early_data(buf) diff --git a/openssl/src/ssl/test/mod.rs b/openssl/src/ssl/test/mod.rs index a98bc5644d..282558f805 100644 --- a/openssl/src/ssl/test/mod.rs +++ b/openssl/src/ssl/test/mod.rs @@ -502,7 +502,7 @@ fn test_connect_with_srtp_ssl() { /// Tests that when the `SslStream` is created as a server stream, the protocols /// are correctly advertised to the client. #[test] -#[cfg(any(ossl102, libressl261))] +#[cfg(any(ossl102, libressl261, boringssl))] fn test_alpn_server_advertise_multiple() { let mut server = Server::builder(); server.ctx().set_alpn_select_callback(|_, client| { @@ -517,7 +517,7 @@ fn test_alpn_server_advertise_multiple() { } #[test] -#[cfg(ossl110)] +#[cfg(any(ossl110, boringssl))] fn test_alpn_server_select_none_fatal() { let mut server = Server::builder(); server.ctx().set_alpn_select_callback(|_, client| { @@ -533,7 +533,7 @@ fn test_alpn_server_select_none_fatal() { } #[test] -#[cfg(any(ossl102, libressl261))] +#[cfg(any(ossl102, libressl261, boringssl))] fn test_alpn_server_select_none() { static CALLED_BACK: AtomicBool = AtomicBool::new(false); @@ -1367,20 +1367,20 @@ fn stateless() { pub struct Outgoing<'a>(&'a mut Vec); - impl<'a> Drop for Outgoing<'a> { + impl Drop for Outgoing<'_> { fn drop(&mut self) { self.0.clear(); } } - impl<'a> ::std::ops::Deref for Outgoing<'a> { + impl ::std::ops::Deref for Outgoing<'_> { type Target = [u8]; fn deref(&self) -> &[u8] { self.0 } } - impl<'a> AsRef<[u8]> for Outgoing<'a> { + impl AsRef<[u8]> for Outgoing<'_> { fn as_ref(&self) -> &[u8] { self.0 } diff --git a/openssl/src/stack.rs b/openssl/src/stack.rs index 58acac61ad..112aa7f649 100644 --- a/openssl/src/stack.rs +++ b/openssl/src/stack.rs @@ -343,7 +343,7 @@ impl<'a, T: Stackable> DoubleEndedIterator for Iter<'a, T> { } } -impl<'a, T: Stackable> ExactSizeIterator for Iter<'a, T> {} +impl ExactSizeIterator for Iter<'_, T> {} /// A mutable iterator over the stack's contents. pub struct IterMut<'a, T: Stackable> { @@ -377,4 +377,4 @@ impl<'a, T: Stackable> DoubleEndedIterator for IterMut<'a, T> { } } -impl<'a, T: Stackable> ExactSizeIterator for IterMut<'a, T> {} +impl ExactSizeIterator for IterMut<'_, T> {} diff --git a/openssl/src/symm.rs b/openssl/src/symm.rs index 0aae69db4f..3929c59404 100644 --- a/openssl/src/symm.rs +++ b/openssl/src/symm.rs @@ -57,6 +57,7 @@ use crate::error::ErrorStack; use crate::nid::Nid; use cfg_if::cfg_if; use foreign_types::ForeignTypeRef; +use openssl_macros::corresponds; #[derive(Copy, Clone)] pub enum Mode { @@ -74,10 +75,7 @@ pub struct Cipher(*const ffi::EVP_CIPHER); impl Cipher { /// Looks up the cipher for a certain nid. - /// - /// This corresponds to [`EVP_get_cipherbynid`] - /// - /// [`EVP_get_cipherbynid`]: https://www.openssl.org/docs/manmaster/crypto/EVP_get_cipherbyname.html + #[corresponds(EVP_get_cipherbynid)] pub fn from_nid(nid: Nid) -> Option { let ptr = unsafe { ffi::EVP_get_cipherbyname(ffi::OBJ_nid2sn(nid.as_raw())) }; if ptr.is_null() { @@ -88,10 +86,7 @@ impl Cipher { } /// Returns the cipher's Nid. - /// - /// This corresponds to [`EVP_CIPHER_nid`] - /// - /// [`EVP_CIPHER_nid`]: https://www.openssl.org/docs/manmaster/crypto/EVP_CIPHER_nid.html + #[corresponds(EVP_CIPHER_nid)] pub fn nid(&self) -> Nid { let nid = unsafe { ffi::EVP_CIPHER_nid(self.0) }; Nid::from_raw(nid) diff --git a/openssl/src/version.rs b/openssl/src/version.rs index f1a324c12c..12ab3d8aec 100644 --- a/openssl/src/version.rs +++ b/openssl/src/version.rs @@ -131,5 +131,4 @@ fn test_versions() { if !built_on().is_empty() { assert!(built_on().starts_with("built on:")); } - assert!(dir().starts_with("OPENSSLDIR:")); } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index e583518dae..67c86ee3d4 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -135,7 +135,7 @@ impl X509StoreContextRef { { struct Cleanup<'a>(&'a mut X509StoreContextRef); - impl<'a> Drop for Cleanup<'a> { + impl Drop for Cleanup<'_> { fn drop(&mut self) { unsafe { ffi::X509_STORE_CTX_cleanup(self.0.as_ptr()); @@ -873,7 +873,7 @@ 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)>); -impl<'a> X509v3Context<'a> { +impl X509v3Context<'_> { pub fn as_ptr(&self) -> *mut ffi::X509V3_CTX { &self.0 as *const _ as *mut _ } @@ -1085,10 +1085,7 @@ impl X509NameBuilder { } /// Add a field entry by str. - /// - /// This corresponds to [`X509_NAME_add_entry_by_txt`]. - /// - /// [`X509_NAME_add_entry_by_txt`]: https://www.openssl.org/docs/manmaster/crypto/X509_NAME_add_entry_by_txt.html + #[corresponds(X509_NAME_add_entry_by_txt)] pub fn append_entry_by_text(&mut self, field: &str, value: &str) -> Result<(), ErrorStack> { unsafe { let field = CString::new(field).unwrap(); @@ -1107,10 +1104,7 @@ impl X509NameBuilder { } /// Add a field entry by str with a specific type. - /// - /// This corresponds to [`X509_NAME_add_entry_by_txt`]. - /// - /// [`X509_NAME_add_entry_by_txt`]: https://www.openssl.org/docs/manmaster/crypto/X509_NAME_add_entry_by_txt.html + #[corresponds(X509_NAME_add_entry_by_txt)] pub fn append_entry_by_text_with_type( &mut self, field: &str, @@ -1134,10 +1128,7 @@ impl X509NameBuilder { } /// Add a field entry by NID. - /// - /// This corresponds to [`X509_NAME_add_entry_by_NID`]. - /// - /// [`X509_NAME_add_entry_by_NID`]: https://www.openssl.org/docs/manmaster/crypto/X509_NAME_add_entry_by_NID.html + #[corresponds(X509_NAME_add_entry_by_NID)] pub fn append_entry_by_nid(&mut self, field: Nid, value: &str) -> Result<(), ErrorStack> { unsafe { assert!(value.len() <= crate::SLenType::MAX as usize); @@ -1155,10 +1146,7 @@ impl X509NameBuilder { } /// Add a field entry by NID with a specific type. - /// - /// This corresponds to [`X509_NAME_add_entry_by_NID`]. - /// - /// [`X509_NAME_add_entry_by_NID`]: https://www.openssl.org/docs/manmaster/crypto/X509_NAME_add_entry_by_NID.html + #[corresponds(X509_NAME_add_entry_by_NID)] pub fn append_entry_by_nid_with_type( &mut self, field: Nid, @@ -1336,10 +1324,7 @@ foreign_type_and_impl_send_sync! { impl X509NameEntryRef { /// Returns the field value of an `X509NameEntry`. - /// - /// This corresponds to [`X509_NAME_ENTRY_get_data`]. - /// - /// [`X509_NAME_ENTRY_get_data`]: https://www.openssl.org/docs/manmaster/crypto/X509_NAME_ENTRY_get_data.html + #[corresponds(X509_NAME_ENTRY_get_data)] pub fn data(&self) -> &Asn1StringRef { unsafe { let data = ffi::X509_NAME_ENTRY_get_data(self.as_ptr()); @@ -1349,10 +1334,7 @@ impl X509NameEntryRef { /// Returns the `Asn1Object` value of an `X509NameEntry`. /// This is useful for finding out about the actual `Nid` when iterating over all `X509NameEntries`. - /// - /// This corresponds to [`X509_NAME_ENTRY_get_object`]. - /// - /// [`X509_NAME_ENTRY_get_object`]: https://www.openssl.org/docs/manmaster/crypto/X509_NAME_ENTRY_get_object.html + #[corresponds(X509_NAME_ENTRY_get_object)] pub fn object(&self) -> &Asn1ObjectRef { unsafe { let object = ffi::X509_NAME_ENTRY_get_object(self.as_ptr()); @@ -1372,10 +1354,7 @@ pub struct X509ReqBuilder(X509Req); impl X509ReqBuilder { /// Returns a builder for a certificate request. - /// - /// This corresponds to [`X509_REQ_new`]. - /// - ///[`X509_REQ_new`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_new.html + #[corresponds(X509_REQ_new)] pub fn new() -> Result { unsafe { ffi::init(); @@ -1384,10 +1363,7 @@ impl X509ReqBuilder { } /// Set the numerical value of the version field. - /// - /// This corresponds to [`X509_REQ_set_version`]. - /// - ///[`X509_REQ_set_version`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_set_version.html + #[corresponds(X509_REQ_set_version)] #[allow(clippy::useless_conversion)] pub fn set_version(&mut self, version: i32) -> Result<(), ErrorStack> { unsafe { @@ -1400,10 +1376,7 @@ impl X509ReqBuilder { } /// Set the issuer name. - /// - /// This corresponds to [`X509_REQ_set_subject_name`]. - /// - /// [`X509_REQ_set_subject_name`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_set_subject_name.html + #[corresponds(X509_REQ_set_subject_name)] pub fn set_subject_name(&mut self, subject_name: &X509NameRef) -> Result<(), ErrorStack> { unsafe { cvt(ffi::X509_REQ_set_subject_name( @@ -1415,10 +1388,7 @@ impl X509ReqBuilder { } /// Set the public key. - /// - /// This corresponds to [`X509_REQ_set_pubkey`]. - /// - /// [`X509_REQ_set_pubkey`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_set_pubkey.html + #[corresponds(X509_REQ_set_pubkey)] pub fn set_pubkey(&mut self, key: &PKeyRef) -> Result<(), ErrorStack> where T: HasPublic, @@ -1465,10 +1435,7 @@ impl X509ReqBuilder { } /// Sign the request using a private key. - /// - /// This corresponds to [`X509_REQ_sign`]. - /// - /// [`X509_REQ_sign`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_sign.html + #[corresponds(X509_REQ_sign)] pub fn sign(&mut self, key: &PKeyRef, hash: MessageDigest) -> Result<(), ErrorStack> where T: HasPrivate, @@ -1561,20 +1528,14 @@ impl X509ReqRef { } /// Returns the numerical value of the version field of the certificate request. - /// - /// This corresponds to [`X509_REQ_get_version`] - /// - /// [`X509_REQ_get_version`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_get_version.html + #[corresponds(X509_REQ_get_version)] #[allow(clippy::unnecessary_cast)] pub fn version(&self) -> i32 { unsafe { X509_REQ_get_version(self.as_ptr()) as i32 } } /// Returns the subject name of the certificate request. - /// - /// This corresponds to [`X509_REQ_get_subject_name`] - /// - /// [`X509_REQ_get_subject_name`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_get_subject_name.html + #[corresponds(X509_REQ_get_subject_name)] pub fn subject_name(&self) -> &X509NameRef { unsafe { let name = X509_REQ_get_subject_name(self.as_ptr()); @@ -1583,10 +1544,7 @@ impl X509ReqRef { } /// Returns the public key of the certificate request. - /// - /// This corresponds to [`X509_REQ_get_pubkey"] - /// - /// [`X509_REQ_get_pubkey`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_get_pubkey.html + #[corresponds(X509_REQ_get_pubkey)] pub fn public_key(&self) -> Result, ErrorStack> { unsafe { let key = cvt_p(ffi::X509_REQ_get_pubkey(self.as_ptr()))?; @@ -1597,10 +1555,7 @@ impl X509ReqRef { /// Check if the certificate request is signed using the given public key. /// /// Returns `true` if verification succeeds. - /// - /// This corresponds to [`X509_REQ_verify"]. - /// - /// [`X509_REQ_verify`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_verify.html + #[corresponds(X509_REQ_verify)] pub fn verify(&self, key: &PKeyRef) -> Result where T: HasPublic, @@ -1609,8 +1564,7 @@ impl X509ReqRef { } /// Returns the extensions of the certificate request. - /// - /// This corresponds to [`X509_REQ_get_extensions"] + #[corresponds(X509_REQ_get_extensions)] pub fn extensions(&self) -> Result, ErrorStack> { unsafe { let extensions = cvt_p(ffi::X509_REQ_get_extensions(self.as_ptr()))?; @@ -2012,10 +1966,7 @@ impl X509VerifyResult { } /// Return a human readable error string from the verification error. - /// - /// This corresponds to [`X509_verify_cert_error_string`]. - /// - /// [`X509_verify_cert_error_string`]: https://www.openssl.org/docs/manmaster/crypto/X509_verify_cert_error_string.html + #[corresponds(X509_verify_cert_error_string)] #[allow(clippy::trivially_copy_pass_by_ref)] pub fn error_string(&self) -> &'static str { ffi::init(); diff --git a/openssl/test/corrupted-rsa.pem b/openssl/test/corrupted-rsa.pem new file mode 100644 index 0000000000..fa2cc3b130 --- /dev/null +++ b/openssl/test/corrupted-rsa.pem @@ -0,0 +1,28 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCyiHMQLLOSG6T6 +AYpMTJj9f4WzXQF0+T0Ri/Mk6vcJMQdnLMrlEMIJA/4iCn32zvpQ0raYcuZZoyso +/Svqg7tAeC3aQ/iFopYWfaR+SDMEnpKMl26qwiIxlPcj9J8hAQw/9WA7YneBXq+T +ypONX4EeDn+bsp/mSNSZKYJBmwXevQ9xbnOOxmBrVd5OS07ZwYuQXy8uVsYe4IXX +7/F+BIyULnIlUxRcVRjKp9++PeS53KLJX04H6HeqUiWC8Ntd+DuD3df0a067L38o +sc+CVzwKXqvh75RwlXCR4/B3D9qEqSYmY7lxp9vA3hirWcSJn0xUIbHb7q1hzE0H +rL65mLwnAgMBAAECggEADePYJpKBGBAm35KTcB3ngJWAJp/I92ZVbieNb7peJOzC +btsJIBWT2xVgm2+7NCK5+Tl486xrfTQuLUlhNiTbQof3HUumKr4nCjHqmdlD1YtW +yzG+7kceAkMyOoMThwL+Bn3bPP42CQPVCjJmahyGPvs8H2DK2E+jRr/4KTgxQTki +s/MXmJa4+xhvfF4CmFVj8imkKCyUTFoaqvYevHDMrJ3cohXFONBPv0MT8X/Y0sgw +UVaZ1aw3dbLC2PBpZFotILGxch2rODXgOcer/GBC41aGQTBB8mLPwKb6KMh0xdPd +1E5NwyODA3YJ6W3fGe8WE0MIHoYlOkX+ukf4W4+U0wKBgQDhueBkZwrd1HdhqwhG +QKt1/itCx24Go75G/+5vJUCB4bcdaJP49aH0/H4BiSsKI8r+GVsVJcrKP8h3tgjw +hhuLLPSaWi9TiUsWeDTw0JrAJc7w6hwL1EYbnwcto5mRQdbfugitlkhh17yUmgdj +gczAKLfV3igxslnR67iNOEYrlwKBgQDKejyWNnxhBJoXerpR/hijoXhMaHqV6Z7T +gUy6F0BiJ5CqN+TOTaC17CEnsMmI28o1rWJ6bIKwOUPFXOE9Z5gyxuIJhY9M8n30 +iwm/Ug2oBTFAdZQyyCuCmPiNURnGo+Hhu1EtVwMWLt3Z0L+/DdI6pgPX8mG0NNZm ++pS96Lg9owKBgHOzCslr5638kZSGTh90Vm6McTAxeLv+gjFyTYy6022/fFSenfom +LXWdVhkDbgQshIfqBz23uVIhj2eM7tgaZVPZHydewpNW9B34T2qAAlIrDv99gBKw +I59UzCEgkj5aOQFEId6YAVHlesvQh6kBhymXtWLyFDgk6tUmtdns1krRAoGBAJj0 +pnhDSMpxk4ZRLBdsgGh8PkhaVOCSz2yvrKqXjgeYI+yytKI0ekdzzcgSAOzmPGc4 +R8B74G4HlG6vr2eXrp4NKAxRXOOf/A6UShTBg5d99KrhJ8cE9/l8XadDsNkiTC0e +OECsDqTfWrCExZUqd7neV+D2NWDQ2XaJrXuZJjVJAoGAIGA5ktXIxWIDeXkxo06b +nHeTEmOAgER/5UIikHnoSAnXo5JNZyFxqoylthWuA1fMPQw/UphAeawDwEXVKp1J +NEhLUfVAO/p1RBUsQi8LQVoO9Nql5u5dFjqoCnlRv5tbeAAzZH5magZk7/1rOS5T +Cj7WW2zW+iL20suUmXfCQGU= +-----END RSA PRIVATE KEY----- diff --git a/systest/build.rs b/systest/build.rs index 56230ada60..fc970f410a 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -85,6 +85,9 @@ fn main() { if version >= 0x30000000 { cfg.header("openssl/provider.h"); } + if version >= 0x30200000 { + cfg.header("openssl/thread.h"); + } } #[allow(clippy::if_same_then_else)]