!30 merge master into master

rust-openssl升级到0.10.73

Created-by: dragonswordy
Commit-by: ljy9810
Merged-by: openharmony_ci
Description: ### 一、内容说明(相关的Issue)
https://gitcode.com/openharmony/third_party_rust_rust-openssl/issues/72


### 二、建议测试周期和提测地址  
  建议测试完成时间:xxxx.xx.xx  
  投产上线时间:xxxx.xx.xx  
  提测地址:CI环境/压测环境  
  测试账号:  

### 三、变更内容
  * 3.1 关联PR列表

  * 3.2 数据库和部署说明  
    1. 常规更新 
    2. 重启unicorn
    3. 重启sidekiq
    4. 迁移任务:是否有迁移任务,没有写 "无"
    5. rake脚本:`bundle exec xxx RAILS_ENV = production`;没有写 "无"

  * 3.4 其他技术优化内容(做了什么,变更了什么)
    - 重构了 xxxx 代码
    - xxxx 算法优化


  * 3.5 废弃通知(什么字段、方法弃用?)



  * 3.6  后向不兼容变更(是否有无法向后兼容的变更?)


  
### 四、研发自测点(自测哪些?冒烟用例全部自测?)
  自测测试结论:


### 五、测试关注点(需要提醒QA重点关注的、可能会忽略的地方)
  检查点:

| 需求名称 | 是否影响xx公共模块 | 是否需要xx功能 | 需求升级是否依赖其他子产品 |
|------|------------|----------|---------------|
| xxx  | 否          | 需要       | 不需要           |
|      |            |          |               |

  接口测试:

  性能测试:

  并发测试:

  其他:



See merge request: openharmony/third_party_rust_rust-openssl!30
This commit is contained in:
openharmony_ci
2025-11-14 15:53:20 +08:00
107 changed files with 4641 additions and 1390 deletions
-189
View File
@@ -1,189 +0,0 @@
restore_registry: &RESTORE_REGISTRY
restore_cache:
key: registry
save_registry: &SAVE_REGISTRY
save_cache:
key: registry-{{ .BuildNum }}
paths:
- /usr/local/cargo/registry/index
openssl_key: &OPENSSL_KEY
key: lib-{{ checksum "~/lib_key" }}-{{ checksum "test/build_openssl.sh" }}
restore_openssl: &RESTORE_OPENSSL
restore_cache:
<<: *OPENSSL_KEY
save_openssl: &SAVE_OPENSSL
save_cache:
<<: *OPENSSL_KEY
paths:
- /openssl
deps_key: &DEPS_KEY
key: deps-1.19.0-{{ checksum "Cargo.lock" }}-{{ checksum "~/lib_key" }}-2
restore_deps: &RESTORE_DEPS
restore_cache:
<<: *DEPS_KEY
save_deps: &SAVE_DEPS
save_cache:
<<: *DEPS_KEY
paths:
- target
- /usr/local/cargo/registry/cache
job: &JOB
working_directory: ~/build
docker:
- image: rust:1.19.0
steps:
- checkout
- run: apt-get update
- run: apt-get remove -y libssl-dev
- run: ./test/add_target.sh
- *RESTORE_REGISTRY
- run: cargo generate-lockfile
- *SAVE_REGISTRY
- run: echo "${LIBRARY}-${VERSION}-${TARGET}" > ~/lib_key
- *RESTORE_OPENSSL
- run: ./test/build_openssl.sh
- *SAVE_OPENSSL
- *RESTORE_DEPS
- run: cargo run --manifest-path=systest/Cargo.toml --target $TARGET
- run: |
ulimit -c unlimited
export PATH=$OPENSSL_DIR/bin:$PATH
if [ "${NO_RUN}" = "1" ]; then
TEST_ARGS=--no-run
fi
cargo test \
--manifest-path=openssl/Cargo.toml \
--target $TARGET \
--all-features \
$TEST_ARGS
- run:
command: |
mkdir -p /tmp/core_dumps
find . -name "core.*" -exec cp \{\} /tmp/core_dumps \;
cp target/$TARGET/debug/openssl-* /tmp/core_dumps
when: on_fail
- store_artifacts:
path: /tmp/core_dumps
- *SAVE_DEPS
macos_job: &MACOS_JOB
macos:
xcode: "9.0"
environment:
RUSTUP_HOME: /usr/local/rustup
CARGO_HOME: /usr/local/cargo
steps:
- checkout
- run: sudo mkdir /opt
- run: sudo chown -R $USER /usr/local /opt
- run: curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.19.0
- run: sudo ln -s $CARGO_HOME/bin/* /usr/local/bin
- *RESTORE_REGISTRY
- run: cargo generate-lockfile
- *SAVE_REGISTRY
- run: echo "homebrew-x86_64-apple-darwin" > ~/lib_key
- *RESTORE_DEPS
- run: cargo run --manifest-path=systest/Cargo.toml
- run: |
PATH=/usr/local/opt/openssl/bin:$PATH
cargo test --manifest-path=openssl/Cargo.toml --all-features
- *SAVE_DEPS
openssl_110: &OPENSSL_110
LIBRARY: openssl
VERSION: 1.1.0g
openssl_102: &OPENSSL_102
LIBRARY: openssl
VERSION: 1.0.2m
openssl_101: &OPENSSL_101
LIBRARY: openssl
VERSION: 1.0.1u
libressl_250: &LIBRESSL_250
LIBRARY: libressl
VERSION: 2.5.0
libressl_263: &LIBRESSL_263
LIBRARY: libressl
VERSION: 2.6.3
x86_64: &X86_64
TARGET: x86_64-unknown-linux-gnu
i686: &I686
TARGET: i686-unknown-linux-gnu
armhf: &ARMHF
TARGET: arm-unknown-linux-gnueabihf
NO_RUN: 1
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_AR: arm-linux-gnueabihf-ar
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER: qemu-arm-static
darwin: &DARWIN
TARGET: x86_64-apple-darwin
base: &BASE
RUST_BACKTRACE: 1
OPENSSL_DIR: /openssl
version: 2
jobs:
x86_64-openssl-1.1.0:
<<: *JOB
environment:
<<: [*OPENSSL_110, *X86_64, *BASE]
x86_64-openssl-1.0.2:
<<: *JOB
environment:
<<: [*OPENSSL_102, *X86_64, *BASE]
x86_64-openssl-1.0.1:
<<: *JOB
environment:
<<: [*OPENSSL_101, *X86_64, *BASE]
i686-openssl-1.1.0:
<<: *JOB
environment:
<<: [*OPENSSL_110, *I686, *BASE]
i686-openssl-1.0.2:
<<: *JOB
environment:
<<: [*OPENSSL_102, *I686, *BASE]
i686-openssl-1.0.1:
<<: *JOB
environment:
<<: [*OPENSSL_101, *I686, *BASE]
armhf-openssl-1.1.0:
<<: *JOB
environment:
<<: [*OPENSSL_110, *ARMHF, *BASE]
armhf-openssl-1.0.2:
<<: *JOB
environment:
<<: [*OPENSSL_102, *ARMHF, *BASE]
armhf-openssl-1.0.1:
<<: *JOB
environment:
<<: [*OPENSSL_101, *ARMHF, *BASE]
x86_64-libressl-2.5.0:
<<: *JOB
environment:
<<: [*LIBRESSL_250, *X86_64, *BASE]
x86_64-libressl-2.6.3:
<<: *JOB
environment:
<<: [*LIBRESSL_263, *X86_64, *BASE]
macos:
<<: *MACOS_JOB
workflows:
version: 2
tests:
jobs:
- x86_64-openssl-1.1.0
- x86_64-openssl-1.0.2
- x86_64-openssl-1.0.1
- i686-openssl-1.1.0
- i686-openssl-1.0.2
- i686-openssl-1.0.1
- armhf-openssl-1.1.0
- armhf-openssl-1.0.2
- armhf-openssl-1.0.1
- x86_64-libressl-2.5.0
- x86_64-libressl-2.6.3
- macos
+7
View File
@@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 1024
+422
View File
@@ -0,0 +1,422 @@
name: CI
on:
pull_request:
branches:
- master
push:
branches:
- master
env:
RUSTFLAGS: -Dwarnings
RUST_BACKTRACE: 1
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
rustfmt:
name: rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: sfackler/actions/rustup@master
- uses: sfackler/actions/rustfmt@master
clippy:
name: clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: sfackler/actions/rustup@master
- run: echo "version=$(rustc --version)" >> $GITHUB_OUTPUT
id: rust-version
- uses: actions/cache@v4
with:
path: ~/.cargo/registry/index
key: index-${{ runner.os }}-${{ github.run_number }}
restore-keys: |
index-${{ runner.os }}-
- run: cargo generate-lockfile
- uses: actions/cache@v4
with:
path: ~/.cargo/registry/cache
key: registry-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
- run: cargo fetch
- uses: actions/cache@v4
with:
path: target
key: target-${{ github.job }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
- run: cargo clippy --all --all-targets
min-version:
name: min-version
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Remember to also update `--rust-target` in `openssl-sys/build/run_bindgen.rs`
- uses: sfackler/actions/rustup@master
with:
version: 1.63.0
- run: echo "version=$(rustc --version)" >> $GITHUB_OUTPUT
id: rust-version
- uses: actions/cache@v4
with:
path: ~/.cargo/registry/index
key: index-${{ runner.os }}-${{ github.run_number }}
restore-keys: |
index-${{ runner.os }}-
- run: cargo generate-lockfile
- run: |
cargo update -p once_cell --precise 1.20.3
- uses: actions/cache@v4
with:
path: ~/.cargo/registry/cache
key: registry-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
- run: cargo fetch
- uses: actions/cache@v4
with:
path: target
key: target-${{ github.job }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
- run: cargo check -p openssl
windows-vcpkg:
name: windows-vcpkg
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: sfackler/actions/rustup@master
- run: echo "version=$(rustc --version)" >> $GITHUB_OUTPUT
id: rust-version
- run: echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append
- run: vcpkg install openssl:x64-windows-static-md
- uses: actions/cache@v4
with:
path: ~/.cargo/registry/index
key: index-${{ runner.os }}-${{ github.run_number }}
restore-keys: |
index-${{ runner.os }}-
- run: cargo generate-lockfile
- uses: actions/cache@v4
with:
path: ~/.cargo/registry/cache
key: registry-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
- run: cargo fetch
- uses: actions/cache@v4
with:
path: target
key: target-${{ github.job }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
# - run: cargo run -p systest
- run: cargo test -p openssl
- run: cargo test -p openssl-errors
macos-homebrew:
name: macos-homebrew
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: sfackler/actions/rustup@master
- run: echo "version=$(rustc --version)" >> $GITHUB_OUTPUT
id: rust-version
- uses: actions/cache@v4
with:
path: ~/.cargo/registry/index
key: index-${{ runner.os }}-${{ github.run_number }}
restore-keys: |
index-${{ runner.os }}-
- run: cargo generate-lockfile
- uses: actions/cache@v4
with:
path: ~/.cargo/registry/cache
key: registry-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
- run: cargo fetch
- run: cargo run -p systest
- run: cargo test -p openssl
- run: cargo test -p openssl-errors
linux:
strategy:
fail-fast: false
matrix:
target:
- x86_64-unknown-linux-gnu
- i686-unknown-linux-gnu
- arm-unknown-linux-gnueabihf
bindgen:
- true
- false
library:
- name: aws-lc
version: v1.48.2
- name: aws-lc
version: vendored
- name: boringssl
version: 71bae60c26549ce1875f07d8c394b934de4b0f7b
- name: openssl
version: vendored
- name: openssl
version: 3.5.0
- name: openssl
version: 3.4.0
- name: openssl
version: 3.3.0
- name: openssl
version: 3.2.0
- name: openssl
old: true
version: 1.1.1w
- 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
bindgen: true
library:
name: libressl
version: 2.5.5
- target: x86_64-unknown-linux-gnu
bindgen: true
library:
name: libressl
version: 3.9.2
- target: x86_64-unknown-linux-gnu
bindgen: true
library:
name: libressl
version: 4.0.0
- target: x86_64-unknown-linux-gnu
bindgen: true
library:
name: libressl
version: 4.1.0
- target: x86_64-unknown-linux-gnu
bindgen: false
library:
name: libressl
version: 2.5.5
- target: x86_64-unknown-linux-gnu
bindgen: false
library:
name: libressl
version: 3.9.2
- target: x86_64-unknown-linux-gnu
bindgen: false
library:
name: libressl
version: 4.0.0
- target: x86_64-unknown-linux-gnu
bindgen: false
library:
name: libressl
version: 4.1.0
name: ${{ matrix.target }}-${{ matrix.library.name }}-${{ matrix.library.version }}-${{ matrix.bindgen }}
runs-on: ubuntu-22.04
env:
OPENSSL_DIR: /opt/openssl
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_AR: arm-linux-gnueabihf-ar
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER: qemu-arm -L /usr/arm-linux-gnueabihf
steps:
- uses: actions/checkout@v4
- uses: sfackler/actions/rustup@master
- run: echo "version=$(rustc --version)" >> $GITHUB_OUTPUT
id: rust-version
- run: rustup target add ${{ matrix.target }}
- name: Install packages
run: |
case "${{ matrix.target }}" in
"x86_64-unknown-linux-gnu")
exit 0
;;
"i686-unknown-linux-gnu")
packages="gcc-multilib g++-multilib"
;;
"arm-unknown-linux-gnueabihf")
packages="gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf qemu-user"
;;
esac
sudo apt-get update
sudo apt-get install -y $packages
- run: sudo apt-get remove -y libssl-dev
- uses: actions/cache@v4
with:
path: /opt/openssl
key: openssl-${{ matrix.target }}-${{ matrix.library.name }}-${{ matrix.library.version }}-7
if: matrix.library.version != 'vendored'
id: openssl-cache
- run: |
echo "RUST_TEST_THREADS=1" >> $GITHUB_ENV
echo BINDGEN_EXTRA_CLANG_ARGS="--sysroot /usr/arm-linux-gnueabihf" >> $GITHUB_ENV
if: matrix.target == 'arm-unknown-linux-gnueabihf'
- name: Build OpenSSL
run: |
case "${{ matrix.library.name }}" in
"openssl")
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")
url="https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-${{ matrix.library.version }}.tar.gz"
tar_flags="--strip-components=1"
;;
"boringssl")
url="https://boringssl.googlesource.com/boringssl/+archive/${{ matrix.library.version }}.tar.gz"
tar_flags=""
;;
"aws-lc")
url="https://github.com/aws/aws-lc/archive/refs/tags/${{ matrix.library.version }}.tar.gz"
tar_flags="--strip-components=1"
;;
esac
case "${{ matrix.target}}" in
"x86_64-unknown-linux-gnu")
CPU=x86_64
OS_COMPILER=linux-x86_64
OS_FLAGS=""
;;
"i686-unknown-linux-gnu")
CPU=i686
OS_COMPILER=linux-elf
OS_FLAGS="-m32 -msse2"
;;
"arm-unknown-linux-gnueabihf")
CPU=armv4
OS_COMPILER=linux-armv4
OS_FLAGS=""
export AR=arm-linux-gnueabihf-ar
export CC=arm-linux-gnueabihf-gcc
export CXX=arm-linux-gnueabihf-g++
;;
esac
mkdir /tmp/build
cd /tmp/build
curl -L $url | tar $tar_flags -xzf -
case "${{ matrix.library.name }}" in
"openssl")
./Configure --prefix=$OPENSSL_DIR --libdir=lib $OS_COMPILER -fPIC -g $OS_FLAGS no-shared
make
make install_sw
;;
"libressl")
./configure --prefix=$OPENSSL_DIR --disable-shared --with-pic
make
make install_sw
;;
"boringssl")
mkdir build
cd build
echo "set(CMAKE_SYSTEM_NAME Linux)" > toolchain.cmake
echo "set(CMAKE_SYSTEM_PROCESSOR $CPU)" >> toolchain.cmake
echo "set(triple ${{ matrix.target }})" >> toolchain.cmake
echo 'set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} '$OS_FLAGS '" CACHE STRING "c++ flags")' >> toolchain.cmake
echo 'set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} '$OS_FLAGS '" CACHE STRING "c flags")' >> toolchain.cmake
echo 'set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} '$OS_FLAGS '" CACHE STRING "asm flags")' >> toolchain.cmake
cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DRUST_BINDINGS="${{ matrix.target }}" -DCMAKE_INSTALL_PREFIX="${OPENSSL_DIR}" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake
make -j "$(nproc)"
make install
# Copy stuff around so it's all as the build system expects.
cp -r ../rust/ "$OPENSSL_DIR/rust"
cp -r ./ "$OPENSSL_DIR/build"
;;
"aws-lc")
mkdir build
cd build
echo "set(CMAKE_SYSTEM_NAME Linux)" > toolchain.cmake
echo "set(CMAKE_SYSTEM_PROCESSOR $CPU)" >> toolchain.cmake
echo "set(triple ${{ matrix.target }})" >> toolchain.cmake
echo 'set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} '$OS_FLAGS '" CACHE STRING "c++ flags")' >> toolchain.cmake
echo 'set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} '$OS_FLAGS '" CACHE STRING "c flags")' >> toolchain.cmake
echo 'set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} '$OS_FLAGS '" CACHE STRING "asm flags")' >> toolchain.cmake
cmake .. -DCMAKE_INSTALL_PREFIX="${OPENSSL_DIR}" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake
make -j "$(nproc)"
make install
;;
esac
if: matrix.library.version != 'vendored' && !steps.openssl-cache.outputs.cache-hit
- run: |
mkdir -p .cargo
echo '[patch.crates-io]' > .cargo/config.toml
echo 'bssl-sys = { path = "'$OPENSSL_DIR'/rust/bssl-sys" }' >> .cargo/config.toml
if: matrix.library.name == 'boringssl' && !matrix.bindgen
- uses: actions/cache@v4
with:
path: ~/.cargo/registry/index
key: index-${{ runner.os }}-${{ github.run_number }}
restore-keys: |
index-${{ runner.os }}-
- run: cargo generate-lockfile
- uses: actions/cache@v4
with:
path: ~/.cargo/registry/cache
key: registry-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
- run: cargo fetch
- uses: actions/cache@v4
with:
path: target
key: target-${{ matrix.target }}-${{ matrix.bindgen }}-${{ matrix.library.name }}-${{ matrix.library.version }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
- name: Run systest
run: |
if [[ "${{ matrix.library.version }}" == "vendored" ]]; then
features="--features vendored"
fi
if [[ "${{ matrix.bindgen }}" == "true" ]]; then
features="$features --features bindgen"
fi
cargo run --manifest-path=systest/Cargo.toml --target ${{ matrix.target }} $features
if: ${{ !(matrix.library.name == 'boringssl' || matrix.library.name == 'aws-lc') }}
- name: Test openssl
run: |
if [[ "${{ matrix.library.name }}" == "boringssl" && "${{ matrix.bindgen }}" != "true" ]]; then
features="--features unstable_boringssl"
BORINGSSL_BUILD_DIR="$OPENSSL_DIR/build/"
fi
if [[ "${{ matrix.library.version }}" == "vendored" ]]; then
if [[ "${{ matrix.library.name }}" == "aws-lc" ]]; then
features="--features aws-lc"
else
features="--features vendored"
fi
fi
if [[ "${{ matrix.bindgen }}" == "true" ]]; then
features="$features --features bindgen"
fi
cargo test --manifest-path=openssl/Cargo.toml --target ${{ matrix.target }} $features
- name: Test openssl-errors
run: |
if [[ "${{ matrix.library.version }}" == "vendored" ]]; then
features="--features openssl-sys/vendored"
fi
if [[ "${{ matrix.bindgen }}" == "true" ]]; then
features="$features --features openssl-sys/bindgen"
fi
cargo test --manifest-path=openssl-errors/Cargo.toml --target ${{ matrix.target }} $features
if: ${{ !(matrix.library.name == 'boringssl' || matrix.library.name == 'aws-lc') }}
+1
View File
@@ -0,0 +1 @@
# this project uses the default rustfmt settings
+1
View File
@@ -1,4 +1,5 @@
[workspace]
resolver = "2"
members = [
"openssl",
"openssl-errors",
+1 -1
View File
@@ -3,7 +3,7 @@
"Name": "rust-openssl",
"License": "Apache-2.0",
"License File": "THIRD_PARTY",
"Version Number": "0.10.56",
"Version Number": "0.10.73",
"Owner": "xuelei3@huawei.com",
"Upstream URL": "https://github.com/sfackler/rust-openssl",
"Description": "OpenSSL bindings for Rust",
+4
View File
@@ -0,0 +1,4 @@
disallowed-methods = [
{ path = "std::slice::from_raw_parts", reason = "use util::from_raw_parts instead" },
{ path = "std::slice::from_raw_parts_mut", reason = "use util::from_raw_parts_mut instead" },
]
+2 -1
View File
@@ -2,12 +2,13 @@
name = "openssl-errors"
version = "0.2.0"
authors = ["Steven Fackler <sfackler@gmail.com>"]
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"
+2
View File
@@ -3,6 +3,8 @@
use std::env;
fn main() {
println!("cargo:rustc-check-cfg=cfg(ossl300)");
if let Ok(version) = env::var("DEP_OPENSSL_VERSION_NUMBER") {
let version = u64::from_str_radix(&version, 16).unwrap();
+1 -1
View File
@@ -19,7 +19,7 @@ ohos_cargo_crate("lib_macros") {
crate_root = "src/lib.rs"
sources = [ "src/lib.rs" ]
edition = "2018"
edition = "2021"
cargo_pkg_version = "0.1.1"
cargo_pkg_name = "openssl-macros"
cargo_pkg_description = "Internal macros used by the openssl crate."
+3 -1
View File
@@ -1,9 +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
+2 -2
View File
@@ -19,8 +19,8 @@ ohos_cargo_crate("lib_sys") {
crate_root = "src/lib.rs"
sources = [ "src/lib.rs" ]
edition = "2018"
cargo_pkg_version = "0.9.91"
edition = "2021"
cargo_pkg_version = "0.9.109"
cargo_pkg_authors = "Alex Crichton <alex@alexcrichton.com>, Steven Fackler <sfackler@gmail.com>"
cargo_pkg_name = "openssl-sys"
cargo_pkg_description = "FFI bindings to OpenSSL"
+184 -1
View File
@@ -2,6 +2,171 @@
## [Unreleased]
## [v0.9.109] - 2025-05-28
### Fixed
* Fixed building with `vcpkg`, a statically linked OpenSSL, and rust 1.87.0.
* Fixed building on the latest BoringSSL.
## [v0.9.108] - 2025-04-30
### Added
* Added support for LibreSSL 4.1.x.
## [v0.9.107] - 2025-04-04
### Added
* Support for building with AWS-LC.
## [v0.9.106] - 2025-02-15
### Added
* Support building with `OPENSSL_NO_RC2`.
* Exposed `EVP_rc2_cbc` and `EVP_rc2_40_cbc`.
## [v0.9.105] - 2025-02-02
### Added
* Added `DTLS_server_method` and `DTLS_client_method`.
## [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
* Added several functions and constants for datagram `BIO`s.
* Added `EVP_PKEY_set1_DSA`, `EVP_PKEY_set1_DH`, and `EVP_PKEY_set1_EC_KEY`.
* Added several functions related to QUIC support.
## [v0.9.102] - 2024-03-28
### Added
* Added support for LibreSSL 3.9.x.
## [v0.9.101] - 2024-02-21
### Fixed
* Fixed a bug where, when building with the `vendored` feature, this crate always needed to be rebuilt.
## [v0.9.100] - 2024-02-19
### Added
* Added `OSSL_PARAM`, `OSSL_PARAM_construct_uint` , `OSSL_PARAM_construct_end`.
* Added `EVP_PKEY_CTX_set_params` and `EVP_PKEY_CTX_get_params`.
* Added `X509_alias_get0`.
* Added `EVP_default_properties_enable_fips`.
## [v0.9.99] - 2024-01-19
### Added
* On macOS added Homebrew's `openssl@3.0` to the list of candidates to build against.
* `NID_brainpoolP256r1`, `NID_brainpoolP320r1`, `NID_brainpoolP384r1`, and `NID_brainpoolP512r1` are now available on LibreSSL.
### Changed
* `X509_PURPOSE` is now opaque on LibreSSL 3.9.0+.
## [v0.9.98] - 2023-12-22
### Added
* Added `RAND_priv_bytes`.
* Added `NID_brainpoolP320r1`.
### Changed
* `X509_PURPOSE_get0` now returns a `const` pointer on LibreSSL 3.9.0+.
* `X509V3_EXT_add_alias` is removed on LibreSSL 3.9.0+.
## [v0.9.97] - 2023-12-04
### Changed
* libatomic is no longer dynamically linked for 32 bit ARM targets.
### Added
* Added `SSL_read_ex`, `SSL_peek_ex`, and `SSL_write_ex`.
## [v0.9.96] - 2023-11-22
### Changed
* `EVP_chacha20` is now available on LibreSSL
### Added
* Added `EVP_des_ede3_ecb`, `EVP_des_ede3_cfb8`, `EVP_des_ede3_ofb`, `EVP_camellia_128_ofb`, `EVP_camellia_192_ofb`, `EVP_camellia_256_ofb`, `EVP_cast5_ofb`, `EVP_idea_ofb`
* Added `X509_STORE_get1_all_certs`
* Added `SSL_CTRL_GET_PEER_TMP_KEY`, `SSL_CTRL_GET_TMP_KEY`, `SSL_get_peer_tmp_key`, `SSL_get_tmp_key`
## [v0.9.95] - 2023-11-03
### Changed
* Fixed the availability of `EVP_PKEY_RSA_PSS` on OpenSSL
### Added
* Added support for LibreSSL 3.8.x.
* Added `NID_chacha20_poly1305`
## [v0.9.94] - 2023-11-01
### Changed
* `X509_ALGOR` is now opaque on new LibreSSL releases
### Added
* Added support for building with `OPENSSL_NO_SCRYPT`
* Added `EVP_PKEY_RSA_PSS` and `EVP_PKEY_DHX`
* Functions and constants for using HKDF `EVP_PKEY` are now available on LibreSSL.
* Added `SSL_CTX_set_security_level`, `SSL_set_security_level`, `SSL_CTX_get_security_level`, `SSL_get_security_level`
* Added `X509_check_host`, `X509_check_email`, `X509_check_ip`, `X509_check_ip_asc`
## [v0.9.93] - 2023-09-04
### Changed
* The `vendored` Cargo feature now builds OpenSSL 3.1, as 1.1.1 is reaching its EOL.
### Added
* Added support for LibreSSL 3.8.1.
## [v0.9.92] - 2023-08-27
### Added
* Added `EVP_CIPHER_CTX_copy`
* Expose `EVP_chacha20_poly1305` on LibreSSL
* Added `X509_VERIFY_PARAM_set1_email`
## [v0.9.91] - 2023-08-06
### Added
@@ -490,7 +655,25 @@ 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.91..master
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.109..master
[v0.9.109]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.108...openssl-sys-v0.9.109
[v0.9.108]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.107...openssl-sys-v0.9.108
[v0.9.107]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.106...openssl-sys-v0.9.107
[v0.9.106]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.105...openssl-sys-v0.9.106
[v0.9.105]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.104...openssl-sys-v0.9.105
[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
[v0.9.100]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.99...openssl-sys-v0.9.100
[v0.9.99]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.98...openssl-sys-v0.9.99
[v0.9.98]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.97...openssl-sys-v0.9.98
[v0.9.97]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.96...openssl-sys-v0.9.97
[v0.9.96]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.95...openssl-sys-v0.9.96
[v0.9.95]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.94...openssl-sys-v0.9.95
[v0.9.94]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.93...openssl-sys-v0.9.94
[v0.9.93]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.92...openssl-sys-v0.9.93
[v0.9.92]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.91...openssl-sys-v0.9.92
[v0.9.91]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.90...openssl-sys-v0.9.91
[v0.9.90]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.89...openssl-sys-v0.9.90
[v0.9.89]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.88...openssl-sys-v0.9.89
+7 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "openssl-sys"
version = "0.9.91"
version = "0.9.109"
authors = [
"Alex Crichton <alex@alexcrichton.com>",
"Steven Fackler <sfackler@gmail.com>",
@@ -12,20 +12,23 @@ 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']
unstable_boringssl = ['bssl-sys']
aws-lc = ['dep:aws-lc-sys']
[dependencies]
libc = "0.2"
bssl-sys = { version = "0.1.0", optional = true }
aws-lc-sys = { version = "0.27", features = ["ssl"], optional = true }
[build-dependencies]
bindgen = { version = "0.64.0", optional = true, features = ["experimental"] }
bindgen = { version = "0.69.0", optional = true, features = ["experimental"] }
cc = "1.0.61"
openssl-src = { version = "111", optional = true }
openssl-src = { version = "300.2.0", optional = true, features = ["legacy"] }
pkg-config = "0.3.9"
vcpkg = "0.2.8"
+27
View File
@@ -53,9 +53,36 @@ pub fn get(openssl_version: Option<u64>, libressl_version: Option<u64>) -> Vec<&
if libressl_version >= 0x3_07_00_00_0 {
cfgs.push("libressl370");
}
if libressl_version >= 0x3_08_00_00_0 {
cfgs.push("libressl380");
}
if libressl_version >= 0x3_08_01_00_0 {
cfgs.push("libressl381");
}
if libressl_version >= 0x3_08_02_00_0 {
cfgs.push("libressl382");
}
if libressl_version >= 0x3_09_00_00_0 {
cfgs.push("libressl390");
}
if libressl_version >= 0x4_00_00_00_0 {
cfgs.push("libressl400");
}
if libressl_version >= 0x4_01_00_00_0 {
cfgs.push("libressl410");
}
} 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");
}
if openssl_version >= 0x3_02_00_00_0 {
cfgs.push("ossl320");
}
if openssl_version >= 0x3_00_00_00_0 {
cfgs.push("ossl300");
}
+18
View File
@@ -19,6 +19,10 @@ VERSION(OPENSSL, OPENSSL_VERSION_NUMBER)
RUST_OPENSSL_IS_BORINGSSL
#endif
#ifdef OPENSSL_IS_AWSLC
RUST_OPENSSL_IS_AWSLC
#endif
#ifdef OPENSSL_NO_BF
RUST_CONF_OPENSSL_NO_BF
#endif
@@ -87,6 +91,10 @@ RUST_CONF_OPENSSL_NO_PSK
RUST_CONF_OPENSSL_NO_RC4
#endif
#ifdef OPENSSL_NO_RC2
RUST_CONF_OPENSSL_NO_RC2
#endif
#ifdef OPENSSL_NO_RFC3779
RUST_CONF_OPENSSL_NO_RFC3779
#endif
@@ -134,3 +142,13 @@ RUST_CONF_OPENSSL_NO_DEPRECATED_3_0
#ifdef OPENSSL_NO_SEED
RUST_CONF_OPENSSL_NO_SEED
#endif
#ifdef OPENSSL_NO_SCRYPT
RUST_CONF_OPENSSL_NO_SCRYPT
#endif
#define SYMBOL_PREFIX2(X) RUST_BINDGEN_SYMBOL_PREFIX_##X##_
#define SYMBOL_PREFIX(X) SYMBOL_PREFIX2(X)
#if defined(OPENSSL_IS_AWSLC) && defined(BORINGSSL_PREFIX)
SYMBOL_PREFIX(BORINGSSL_PREFIX)
#endif
+19 -8
View File
@@ -32,7 +32,7 @@ pub fn get_openssl(target: &str) -> (Vec<PathBuf>, PathBuf) {
}
fn resolve_with_wellknown_homebrew_location(dir: &str) -> Option<PathBuf> {
let versions = ["openssl@3", "openssl@1.1"];
let versions = ["openssl@3", "openssl@3.0", "openssl@1.1"];
// Check up default aarch 64 Homebrew installation location first
// for quick resolution if possible.
@@ -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")
@@ -165,7 +174,7 @@ installing `pkg-config`.
It looks like you're compiling for MinGW but you may not have either OpenSSL or
pkg-config installed. You can install these two dependencies with:
pacman -S openssl-devel pkg-config
pacman -S openssl-devel pkgconf
and try building this crate again.
@@ -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;
}
};
@@ -255,6 +265,7 @@ fn try_vcpkg() {
println!("cargo:rustc-link-lib=user32");
println!("cargo:rustc-link-lib=gdi32");
println!("cargo:rustc-link-lib=crypt32");
println!("cargo:rustc-link-lib=advapi32");
process::exit(0);
}
+10 -1
View File
@@ -1,8 +1,17 @@
use openssl_src;
use std::path::PathBuf;
use super::env;
pub fn get_openssl(_target: &str) -> (Vec<PathBuf>, PathBuf) {
let artifacts = openssl_src::Build::new().build();
let openssl_config_dir = env("OPENSSL_CONFIG_DIR");
let mut openssl_src_build = openssl_src::Build::new();
if let Some(value) = openssl_config_dir {
openssl_src_build.openssl_dir(PathBuf::from(value));
}
let artifacts = openssl_src_build.build();
println!("cargo:vendored=1");
println!(
"cargo:root={}",
+196 -18
View File
@@ -9,7 +9,7 @@ extern crate vcpkg;
use std::collections::HashSet;
use std::env;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
mod cfgs;
mod find_normal;
@@ -24,6 +24,7 @@ enum Version {
Openssl10x,
Libressl,
Boringssl,
AwsLc,
}
fn env_inner(name: &str) -> Option<OsString> {
@@ -60,22 +61,134 @@ fn check_ssl_kind() {
if cfg!(feature = "unstable_boringssl") {
println!("cargo:rustc-cfg=boringssl");
println!("cargo:boringssl=true");
if let Ok(vars) = env::var("DEP_BSSL_CONF") {
for var in vars.split(',') {
println!("cargo:rustc-cfg=osslconf=\"{}\"", var);
}
println!("cargo:conf={}", vars);
}
// BoringSSL does not have any build logic, exit early
std::process::exit(0);
}
let is_aws_lc = cfg!(feature = "aws-lc");
if is_aws_lc {
println!("cargo:rustc-cfg=awslc");
println!("cargo:awslc=true");
// The aws-lc-sys crate uses a link name that embeds
// the version number of crate. Examples (crate-name => links name):
// * aws-lc-sys => aws_lc_0_26_0
// This is done to avoid issues if the cargo dependency graph for an application
// were to resolve to multiple versions for the same crate.
//
// Due to this we need to determine what version of the AWS-LC has been selected (fips or non-fips)
// and then need to parse out the pieces we are interested in ignoring the version componenet of the name.
const AWS_LC_ENV_VAR_PREFIX: &str = "DEP_AWS_LC_";
let mut version = None;
for (name, _) in std::env::vars() {
if let Some(name) = name.strip_prefix(AWS_LC_ENV_VAR_PREFIX) {
if let Some(name) = name.strip_suffix("_INCLUDE") {
version = Some(name.to_owned());
break;
}
}
}
let version = version.expect("aws-lc version detected");
// Read the OpenSSL configuration statements and emit rust-cfg for each.
if let Ok(vars) = std::env::var(format!("{AWS_LC_ENV_VAR_PREFIX}{version}_CONF")) {
for var in vars.split(',') {
println!("cargo:rustc-cfg=osslconf=\"{var}\"");
}
println!("cargo:conf={vars}");
}
// Emit the include header directory from the aws-lc(-fips)-sys crate so that it can be used if needed
// by crates consuming openssl-sys.
if let Ok(val) = std::env::var(format!("{AWS_LC_ENV_VAR_PREFIX}{version}_INCLUDE")) {
println!("cargo:include={val}");
}
// AWS-LC does not have any build logic, exit early
std::process::exit(0);
}
}
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_COMP\", \"OPENSSL_NO_SOCK\", \"OPENSSL_NO_STDIO\", \"OPENSSL_NO_EC\", \"OPENSSL_NO_SSL3_METHOD\", \"OPENSSL_NO_KRB5\", \"OPENSSL_NO_TLSEXT\", \"OPENSSL_NO_SRP\", \"OPENSSL_NO_RFC3779\", \"OPENSSL_NO_SHA\", \"OPENSSL_NO_NEXTPROTONEG\", \"OPENSSL_NO_ENGINE\", \"OPENSSL_NO_BUF_FREELISTS\", \"OPENSSL_NO_RC2\"))");
println!("cargo:rustc-check-cfg=cfg(openssl)");
println!("cargo:rustc-check-cfg=cfg(libressl)");
println!("cargo:rustc-check-cfg=cfg(boringssl)");
println!("cargo:rustc-check-cfg=cfg(awslc)");
println!("cargo:rustc-check-cfg=cfg(libressl250)");
println!("cargo:rustc-check-cfg=cfg(libressl251)");
println!("cargo:rustc-check-cfg=cfg(libressl252)");
println!("cargo:rustc-check-cfg=cfg(libressl261)");
println!("cargo:rustc-check-cfg=cfg(libressl270)");
println!("cargo:rustc-check-cfg=cfg(libressl271)");
println!("cargo:rustc-check-cfg=cfg(libressl273)");
println!("cargo:rustc-check-cfg=cfg(libressl280)");
println!("cargo:rustc-check-cfg=cfg(libressl281)");
println!("cargo:rustc-check-cfg=cfg(libressl291)");
println!("cargo:rustc-check-cfg=cfg(libressl310)");
println!("cargo:rustc-check-cfg=cfg(libressl321)");
println!("cargo:rustc-check-cfg=cfg(libressl332)");
println!("cargo:rustc-check-cfg=cfg(libressl340)");
println!("cargo:rustc-check-cfg=cfg(libressl350)");
println!("cargo:rustc-check-cfg=cfg(libressl360)");
println!("cargo:rustc-check-cfg=cfg(libressl361)");
println!("cargo:rustc-check-cfg=cfg(libressl370)");
println!("cargo:rustc-check-cfg=cfg(libressl380)");
println!("cargo:rustc-check-cfg=cfg(libressl381)");
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(libressl410)");
println!("cargo:rustc-check-cfg=cfg(ossl101)");
println!("cargo:rustc-check-cfg=cfg(ossl102)");
println!("cargo:rustc-check-cfg=cfg(ossl102f)");
println!("cargo:rustc-check-cfg=cfg(ossl102h)");
println!("cargo:rustc-check-cfg=cfg(ossl110)");
println!("cargo:rustc-check-cfg=cfg(ossl110f)");
println!("cargo:rustc-check-cfg=cfg(ossl110g)");
println!("cargo:rustc-check-cfg=cfg(ossl110h)");
println!("cargo:rustc-check-cfg=cfg(ossl111)");
println!("cargo:rustc-check-cfg=cfg(ossl111b)");
println!("cargo:rustc-check-cfg=cfg(ossl111c)");
println!("cargo:rustc-check-cfg=cfg(ossl111d)");
println!("cargo:rustc-check-cfg=cfg(ossl300)");
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();
let target = env::var("TARGET").unwrap();
let (lib_dirs, include_dir) = find_openssl(&target);
// rerun-if-changed causes openssl-sys to rebuild if the openssl include
// dir has changed since the last build. However, this causes a rebuild
// every time when vendoring so we disable it.
let potential_path = include_dir.join("openssl");
if potential_path.exists() && !cfg!(feature = "vendored") {
if let Some(printable_include) = potential_path.to_str() {
println!("cargo:rerun-if-changed={}", printable_include);
}
}
if !lib_dirs.iter().all(|p| Path::new(p).exists()) {
if !lib_dirs.iter().all(|p| p.exists()) {
panic!("OpenSSL library directory does not exist: {:?}", lib_dirs);
}
if !Path::new(&include_dir).exists() {
if !include_dir.exists() {
panic!(
"OpenSSL include directory does not exist: {}",
include_dir.to_string_lossy()
@@ -115,6 +228,47 @@ fn main() {
println!("cargo:rustc-link-lib={}={}", kind, lib);
}
// libssl in BoringSSL requires the C++ runtime, and static libraries do
// not carry dependency information. On unix-like platforms, the C++
// runtime and standard library are typically picked up by default via the
// C++ compiler, which has a platform-specific default. (See implementations
// of `GetDefaultCXXStdlibType` in Clang.) Builds may also choose to
// override this and specify their own with `-nostdinc++` and `-nostdlib++`
// flags. Some compilers also provide options like `-stdlib=libc++`.
//
// Typically, such information is carried all the way up the build graph,
// but Cargo is not an integrated cross-language build system, so it cannot
// safely handle any of these situations. As a result, we need to make
// guesses. Getting this wrong may result in symbol conflicts and memory
// errors, but this unsafety is inherent to driving builds with
// externally-built libraries using Cargo.
//
// For now, we guess that the build was made with the defaults. This too is
// difficult because Rust does not expose this information from Clang, but
// try to match the behavior for common platforms. For a more robust option,
// this likely needs to be deferred to the caller with an environment
// variable.
if (version == Version::Boringssl || version == Version::AwsLc)
&& kind == "static"
&& env::var("CARGO_CFG_UNIX").is_ok()
{
let cpp_lib = match env::var("CARGO_CFG_TARGET_OS").unwrap().as_ref() {
"macos" => "c++",
_ => "stdc++",
};
println!("cargo:rustc-link-lib={}", cpp_lib);
}
// https://github.com/openssl/openssl/pull/15086
if version == Version::Openssl3xx
&& kind == "static"
&& (env::var("CARGO_CFG_TARGET_OS").unwrap() == "linux"
|| env::var("CARGO_CFG_TARGET_OS").unwrap() == "android")
&& env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap() == "32"
{
println!("cargo:rustc-link-lib=atomic");
}
if kind == "static" && target.contains("windows") {
println!("cargo:rustc-link-lib=dylib=gdi32");
println!("cargo:rustc-link-lib=dylib=user32");
@@ -127,8 +281,8 @@ fn main() {
fn postprocess(include_dirs: &[PathBuf]) -> Version {
let version = validate_headers(include_dirs);
// Never run bindgen for BoringSSL, if it was needed we already ran it.
if version != Version::Boringssl {
// Never run bindgen for BoringSSL or AWS-LC, if it was needed we already ran it.
if !(version == Version::Boringssl || version == Version::AwsLc) {
#[cfg(feature = "bindgen")]
run_bindgen::run(&include_dirs);
}
@@ -170,13 +324,13 @@ pointing to your OpenSSL installation or installing OpenSSL headers package
specific to your distribution:
# On Ubuntu
sudo apt-get install libssl-dev
sudo apt-get install pkg-config libssl-dev
# On Arch Linux
sudo pacman -S openssl
sudo pacman -S pkgconf openssl
# On Fedora
sudo dnf install openssl-devel
sudo dnf install pkgconf perl-FindBin perl-IPC-Cmd openssl-devel
# On Alpine Linux
apk add openssl-dev
apk add pkgconf openssl-dev
See rust-openssl documentation for more information:
@@ -192,14 +346,18 @@ See rust-openssl documentation for more information:
let mut openssl_version = None;
let mut libressl_version = None;
let mut is_boringssl = false;
let mut is_awslc = false;
let mut bindgen_symbol_prefix: Option<String> = None;
for line in expanded.lines() {
let line = line.trim();
let openssl_prefix = "RUST_VERSION_OPENSSL_";
let new_openssl_prefix = "RUST_VERSION_NEW_OPENSSL_";
let libressl_prefix = "RUST_VERSION_LIBRESSL_";
let boringsl_prefix = "RUST_OPENSSL_IS_BORINGSSL";
let boringssl_prefix = "RUST_OPENSSL_IS_BORINGSSL";
let awslc_prefix = "RUST_OPENSSL_IS_AWSLC";
let conf_prefix = "RUST_CONF_";
let symbol_prefix = "RUST_BINDGEN_SYMBOL_PREFIX_";
if let Some(version) = line.strip_prefix(openssl_prefix) {
openssl_version = Some(parse_version(version));
} else if let Some(version) = line.strip_prefix(new_openssl_prefix) {
@@ -208,11 +366,21 @@ See rust-openssl documentation for more information:
libressl_version = Some(parse_version(version));
} else if let Some(conf) = line.strip_prefix(conf_prefix) {
enabled.push(conf);
} else if line.starts_with(boringsl_prefix) {
} else if line.starts_with(boringssl_prefix) {
is_boringssl = true;
} else if line.starts_with(awslc_prefix) {
is_awslc = true;
} else if line.starts_with(symbol_prefix) {
let sym_prefix = String::from(line.strip_prefix(symbol_prefix).unwrap());
bindgen_symbol_prefix = Some(sym_prefix);
}
}
for enabled in &enabled {
println!("cargo:rustc-cfg=osslconf=\"{}\"", enabled);
}
println!("cargo:conf={}", enabled.join(","));
if is_boringssl {
println!("cargo:rustc-cfg=boringssl");
println!("cargo:boringssl=true");
@@ -220,14 +388,16 @@ See rust-openssl documentation for more information:
return Version::Boringssl;
}
if is_awslc {
println!("cargo:rustc-cfg=awslc");
println!("cargo:awslc=true");
run_bindgen::run_awslc(include_dirs, bindgen_symbol_prefix);
return Version::AwsLc;
}
// We set this for any non-BoringSSL lib.
println!("cargo:rustc-cfg=openssl");
for enabled in &enabled {
println!("cargo:rustc-cfg=osslconf=\"{}\"", enabled);
}
println!("cargo:conf={}", enabled.join(","));
for cfg in cfgs::get(openssl_version, libressl_version) {
println!("cargo:rustc-cfg={}", cfg);
}
@@ -273,6 +443,14 @@ See rust-openssl documentation for more information:
(3, 7, 1) => ('3', '7', '1'),
(3, 7, _) => ('3', '7', 'x'),
(3, 8, 0) => ('3', '8', '0'),
(3, 8, 1) => ('3', '8', '1'),
(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'),
(4, 1, 0) => ('4', '1', '0'),
(4, 1, _) => ('4', '1', 'x'),
_ => version_error(),
};
@@ -314,8 +492,8 @@ fn version_error() -> ! {
panic!(
"
This crate is only compatible with OpenSSL (version 1.0.1 through 1.1.1, or 3.0.0), or LibreSSL 2.5
through 3.8.0, but a different version of OpenSSL was found. The build is now aborting
This crate is only compatible with OpenSSL (version 1.0.1 through 1.1.1, or 3), or LibreSSL 2.5
through 4.1.x, but a different version of OpenSSL was found. The build is now aborting
due to this version mismatch.
"
+157 -26
View File
@@ -36,15 +36,20 @@ const INCLUDES: &str = "
#include <openssl/x509_vfy.h>
#include <openssl/x509v3.h>
#if !defined(OPENSSL_IS_AWSLC)
// this must be included after ssl.h for libressl!
#include <openssl/srtp.h>
#endif
#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
#if !(defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC))
#include <openssl/cms.h>
#endif
#if !defined(OPENSSL_IS_BORINGSSL)
#if !(defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC))
#include <openssl/comp.h>
#endif
#if !defined(OPENSSL_IS_BORINGSSL)
#include <openssl/ocsp.h>
#endif
@@ -56,9 +61,17 @@ const INCLUDES: &str = "
#include <openssl/provider.h>
#endif
#if defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_BORINGSSL)
#if OPENSSL_VERSION_NUMBER >= 0x30200000
#include <openssl/quic.h>
#endif
#if defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
#include <openssl/poly1305.h>
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30200000
#include <openssl/thread.h>
#endif
";
#[cfg(feature = "bindgen")]
@@ -70,8 +83,9 @@ pub fn run(include_dirs: &[PathBuf]) {
.rust_target(RustTarget::Stable_1_47)
.ctypes_prefix("::libc")
.raw_line("use libc::*;")
.raw_line("#[cfg(windows)] use std::os::windows::raw::HANDLE;")
.raw_line("type evp_pkey_st = EVP_PKEY;")
.allowlist_file(".*/openssl/[^/]+\\.h")
.allowlist_file(".*[/\\\\]openssl/[^/\\\\]+\\.h")
.allowlist_recursively(false)
// libc is missing pthread_once_t on macOS
.blocklist_type("CRYPTO_ONCE")
@@ -85,6 +99,8 @@ pub fn run(include_dirs: &[PathBuf]) {
.blocklist_type("OSSL_FUNC_core_vset_error_fn")
.blocklist_type("OSSL_FUNC_BIO_vprintf_fn")
.blocklist_type("OSSL_FUNC_BIO_vsnprintf_fn")
// struct hostent * does not exist on Windows
.blocklist_function("BIO_gethostbyname")
// Maintain compatibility for existing enum definitions
.rustified_enum("point_conversion_form_t")
// Maintain compatibility for pre-union definitions
@@ -111,6 +127,12 @@ pub fn run(include_dirs: &[PathBuf]) {
#[cfg(feature = "bindgen")]
pub fn run_boringssl(include_dirs: &[PathBuf]) {
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
fs::File::create(out_dir.join("boring_static_wrapper.h"))
.expect("Failed to create boring_static_wrapper.h")
.write_all(INCLUDES.as_bytes())
.expect("Failed to write contents to boring_static_wrapper.h");
let mut builder = bindgen::builder()
.rust_target(RustTarget::Stable_1_47)
.ctypes_prefix("::libc")
@@ -119,14 +141,19 @@ pub fn run_boringssl(include_dirs: &[PathBuf]) {
.enable_function_attribute_detection()
.default_macro_constant_type(MacroTypeVariation::Signed)
.rustified_enum("point_conversion_form_t")
.allowlist_file(".*/openssl/[^/]+\\.h")
.allowlist_file(".*[/\\\\]openssl/[^/]+\\.h")
.allowlist_recursively(false)
.blocklist_function("BIO_vsnprintf")
.blocklist_function("OPENSSL_vasprintf")
.wrap_static_fns(true)
.wrap_static_fns_path(out_dir.join("boring_static_wrapper").display().to_string())
.layout_tests(false)
.header_contents("includes.h", INCLUDES);
.header(
out_dir
.join("boring_static_wrapper.h")
.display()
.to_string(),
);
for include_dir in include_dirs {
builder = builder
@@ -140,21 +167,9 @@ pub fn run_boringssl(include_dirs: &[PathBuf]) {
.write_to_file(out_dir.join("bindgen.rs"))
.unwrap();
fs::File::create(out_dir.join("boring_static_wrapper.h"))
.expect("Failed to create boring_static_wrapper.h")
.write_all(INCLUDES.as_bytes())
.expect("Failed to write contents to boring_static_wrapper.h");
cc::Build::new()
.file(out_dir.join("boring_static_wrapper.c"))
.includes(include_dirs)
.flag("-include")
.flag(
&out_dir
.join("boring_static_wrapper.h")
.display()
.to_string(),
)
.compile("boring_static_wrapper");
}
@@ -180,7 +195,7 @@ pub fn run_boringssl(include_dirs: &[PathBuf]) {
.arg("--enable-function-attribute-detection")
.arg("--default-macro-constant-type=signed")
.arg("--rustified-enum=point_conversion_form_t")
.arg("--allowlist-file=.*/openssl/[^/]+\\.h")
.arg("--allowlist-file=.*[/\\\\]openssl/[^/]+\\.h")
.arg("--no-recursive-allowlist")
.arg("--blocklist-function=BIO_vsnprintf")
.arg("--blocklist-function=OPENSSL_vasprintf")
@@ -203,16 +218,132 @@ pub fn run_boringssl(include_dirs: &[PathBuf]) {
cc::Build::new()
.file(out_dir.join("boring_static_wrapper.c"))
.includes(include_dirs)
.flag("-include")
.flag(
&out_dir
.join("boring_static_wrapper.h")
.display()
.to_string(),
)
.compile("boring_static_wrapper");
}
#[cfg(feature = "bindgen")]
mod bindgen_options {
use bindgen::callbacks::{ItemInfo, ParseCallbacks};
#[derive(Debug)]
pub struct StripPrefixCallback {
remove_prefix: Option<String>,
}
impl StripPrefixCallback {
pub fn new(prefix: &str) -> StripPrefixCallback {
StripPrefixCallback {
remove_prefix: Some(prefix.to_string()),
}
}
}
impl ParseCallbacks for StripPrefixCallback {
fn generated_name_override(&self, item_info: ItemInfo<'_>) -> Option<String> {
self.remove_prefix
.as_ref()
.and_then(|s| item_info.name.strip_prefix(s.as_str()).map(String::from))
}
}
}
#[cfg(feature = "bindgen")]
pub fn run_awslc(include_dirs: &[PathBuf], symbol_prefix: Option<String>) {
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
fs::File::create(out_dir.join("awslc_static_wrapper.h"))
.expect("Failed to create awslc_static_wrapper.h")
.write_all(INCLUDES.as_bytes())
.expect("Failed to write contents to awslc_static_wrapper.h");
let mut builder = bindgen::builder()
.rust_target(RustTarget::Stable_1_47)
.ctypes_prefix("::libc")
.raw_line("use libc::*;")
.derive_default(false)
.enable_function_attribute_detection()
.default_macro_constant_type(MacroTypeVariation::Signed)
.rustified_enum("point_conversion_form_t")
.allowlist_file(r".*(/|\\)openssl((/|\\)[^/\\]+)+\.h")
.wrap_static_fns(true)
.wrap_static_fns_path(out_dir.join("awslc_static_wrapper").display().to_string())
.layout_tests(false)
.header(out_dir.join("awslc_static_wrapper.h").display().to_string());
if let Some(prefix) = symbol_prefix {
use bindgen_options::StripPrefixCallback;
let callback = StripPrefixCallback::new(prefix.as_str());
builder = builder.parse_callbacks(Box::from(callback));
}
for include_dir in include_dirs {
builder = builder
.clang_arg("-I")
.clang_arg(include_dir.display().to_string());
}
builder
.generate()
.unwrap()
.write_to_file(out_dir.join("bindgen.rs"))
.unwrap();
cc::Build::new()
.file(out_dir.join("awslc_static_wrapper.c"))
.includes(include_dirs)
.compile("awslc_static_wrapper");
}
#[cfg(not(feature = "bindgen"))]
pub fn run_awslc(include_dirs: &[PathBuf], symbol_prefix: Option<String>) {
if symbol_prefix.is_some() {
panic!("aws-lc installation has prefixed symbols, but bindgen-cli does not support removing prefixes. \
Enable the bindgen crate feature to support this installation.")
}
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
fs::File::create(out_dir.join("awslc_static_wrapper.h"))
.expect("Failed to create awslc_static_wrapper.h")
.write_all(INCLUDES.as_bytes())
.expect("Failed to write contents to awslc_static_wrapper.h");
let mut bindgen_cmd = process::Command::new("bindgen");
bindgen_cmd
.arg("-o")
.arg(out_dir.join("bindgen.rs"))
// Must be a valid version from
// https://docs.rs/bindgen/latest/bindgen/enum.RustTarget.html
.arg("--rust-target=1.47")
.arg("--ctypes-prefix=::libc")
.arg("--raw-line=use libc::*;")
.arg("--no-derive-default")
.arg("--enable-function-attribute-detection")
.arg("--default-macro-constant-type=signed")
.arg("--rustified-enum=point_conversion_form_t")
.arg(r"--allowlist-file=.*(/|\\)openssl((/|\\)[^/\\]+)+\.h")
.arg("--experimental")
.arg("--wrap-static-fns")
.arg("--wrap-static-fns-path")
.arg(out_dir.join("awslc_static_wrapper").display().to_string())
.arg(out_dir.join("awslc_static_wrapper.h"))
.arg("--")
.arg(format!("--target={}", env::var("TARGET").unwrap()));
for include_dir in include_dirs {
bindgen_cmd.arg("-I").arg(include_dir.display().to_string());
}
let result = bindgen_cmd.status().expect("bindgen failed to execute");
assert!(result.success());
cc::Build::new()
.file(out_dir.join("awslc_static_wrapper.c"))
.includes(include_dirs)
.compile("awslc_static_wrapper");
}
#[cfg(feature = "bindgen")]
#[derive(Debug)]
struct OpensslCallbacks;
+44
View File
@@ -70,3 +70,47 @@ extern "C" {
destroy: unsafe extern "C" fn(*mut BIO) -> c_int,
) -> c_int;
}
cfg_if! {
if #[cfg(ossl320)] {
use std::ptr;
pub const BIO_CTRL_DGRAM_GET_MTU: c_int = 41;
pub const BIO_CTRL_DGRAM_SET_MTU: c_int = 42;
pub const BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP: c_int = 82;
pub const BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE: c_int = 83;
pub const BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE: c_int = 84;
pub const BIO_CTRL_DGRAM_GET_CAPS: c_int = 86;
pub const BIO_CTRL_DGRAM_SET_CAPS: c_int = 87;
pub const BIO_CTRL_DGRAM_GET_NO_TRUNC: c_int = 88;
pub const BIO_CTRL_DGRAM_SET_NO_TRUNC: c_int = 89;
pub unsafe fn BIO_dgram_get_no_trunc(bio: *mut BIO) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_NO_TRUNC, 0, ptr::null_mut()) as c_int
}
pub unsafe fn BIO_dgram_set_no_trunc(bio: *mut BIO, enable: c_int) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_NO_TRUNC, enable as c_long, ptr::null_mut()) as c_int
}
pub unsafe fn BIO_dgram_get_cap(bio: *mut BIO) -> u32 {
BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_CAPS, 0, ptr::null_mut()) as u32
}
pub unsafe fn BIO_dgram_set_cap(bio: *mut BIO, cap: u32) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CAPS, cap as c_long, ptr::null_mut()) as c_int
}
pub unsafe fn BIO_dgram_get_local_addr_cap(bio: *mut BIO) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP, 0, ptr::null_mut()) as c_int
}
pub unsafe fn BIO_dgram_get_local_addr_enable(bio: *mut BIO, enable: *mut c_int) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE, 0, enable as *mut c_void) as c_int
}
pub unsafe fn BIO_dgram_set_local_addr_enable(bio: *mut BIO, enable: c_int) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE, enable as c_long, ptr::null_mut()) as c_int
}
pub unsafe fn BIO_dgram_get_mtu(bio: *mut BIO) -> c_uint {
BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_MTU, 0, ptr::null_mut()) as c_uint
}
pub unsafe fn BIO_dgram_set_mtu(bio: *mut BIO, mtu: c_uint) -> c_int {
BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_MTU, mtu as c_long, ptr::null_mut()) as c_int
}
}
}
+5 -5
View File
@@ -57,7 +57,7 @@ pub type CRYPTO_EX_free = unsafe extern "C" fn(
argp: *mut c_void,
);
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl390))]
#[inline]
#[track_caller]
pub unsafe fn OPENSSL_malloc(num: usize) -> *mut c_void {
@@ -68,7 +68,7 @@ pub unsafe fn OPENSSL_malloc(num: usize) -> *mut c_void {
)
}
#[cfg(not(ossl110))]
#[cfg(not(any(ossl110, libressl390)))]
#[inline]
#[track_caller]
pub unsafe fn OPENSSL_malloc(num: c_int) -> *mut c_void {
@@ -79,7 +79,7 @@ pub unsafe fn OPENSSL_malloc(num: c_int) -> *mut c_void {
)
}
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl390))]
#[inline]
#[track_caller]
pub unsafe fn OPENSSL_free(addr: *mut c_void) {
@@ -90,7 +90,7 @@ pub unsafe fn OPENSSL_free(addr: *mut c_void) {
)
}
#[cfg(not(ossl110))]
#[cfg(not(any(ossl110, libressl390)))]
#[inline]
pub unsafe fn OPENSSL_free(addr: *mut c_void) {
CRYPTO_free(addr)
@@ -106,7 +106,7 @@ pub const CRYPTO_LOCK_SSL_CTX: c_int = 12;
pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14;
cfg_if! {
if #[cfg(ossl110)] {
if #[cfg(any(ossl110, libressl381))] {
pub const CRYPTO_EX_INDEX_SSL: c_int = 0;
pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 1;
} else if #[cfg(libressl)] {
+2 -2
View File
@@ -9,8 +9,8 @@ pub const ERR_LIB_ASN1: c_int = 13;
cfg_if! {
if #[cfg(ossl300)] {
pub const ERR_SYSTEM_FLAG: c_ulong = c_int::max_value() as c_ulong + 1;
pub const ERR_SYSTEM_MASK: c_ulong = c_int::max_value() as c_ulong;
pub const ERR_SYSTEM_FLAG: c_ulong = c_int::MAX as c_ulong + 1;
pub const ERR_SYSTEM_MASK: c_ulong = c_int::MAX as c_ulong;
pub const ERR_LIB_OFFSET: c_ulong = 23;
pub const ERR_LIB_MASK: c_ulong = 0xff;
+40 -20
View File
@@ -7,8 +7,12 @@ pub const PKCS5_SALT_LEN: c_int = 8;
pub const PKCS12_DEFAULT_ITER: c_int = 2048;
pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption;
#[cfg(any(ossl111, libressl310, boringssl, awslc))]
pub const EVP_PKEY_RSA_PSS: c_int = NID_rsassaPss;
pub const EVP_PKEY_DSA: c_int = NID_dsa;
pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement;
#[cfg(ossl110)]
pub const EVP_PKEY_DHX: c_int = NID_dhpublicnumber;
pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey;
#[cfg(ossl111)]
pub const EVP_PKEY_SM2: c_int = NID_sm2;
@@ -24,7 +28,7 @@ pub const EVP_PKEY_HMAC: c_int = NID_hmac;
pub const EVP_PKEY_CMAC: c_int = NID_cmac;
#[cfg(ossl111)]
pub const EVP_PKEY_POLY1305: c_int = NID_poly1305;
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl360))]
pub const EVP_PKEY_HKDF: c_int = NID_hkdf;
#[cfg(ossl102)]
@@ -180,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;
@@ -197,31 +217,31 @@ pub const EVP_PKEY_CTRL_CIPHER: c_int = 12;
pub const EVP_PKEY_ALG_CTRL: c_int = 0x1000;
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl360))]
pub const EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: c_int = 0;
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl360))]
pub const EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: c_int = 1;
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl360))]
pub const EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: c_int = 2;
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl360))]
pub const EVP_PKEY_CTRL_HKDF_MD: c_int = EVP_PKEY_ALG_CTRL + 3;
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl360))]
pub const EVP_PKEY_CTRL_HKDF_SALT: c_int = EVP_PKEY_ALG_CTRL + 4;
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl360))]
pub const EVP_PKEY_CTRL_HKDF_KEY: c_int = EVP_PKEY_ALG_CTRL + 5;
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl360))]
pub const EVP_PKEY_CTRL_HKDF_INFO: c_int = EVP_PKEY_ALG_CTRL + 6;
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl360))]
pub const EVP_PKEY_CTRL_HKDF_MODE: c_int = EVP_PKEY_ALG_CTRL + 7;
#[cfg(all(ossl111, not(ossl300)))]
#[cfg(any(all(ossl111, not(ossl300)), libressl360))]
pub unsafe fn EVP_PKEY_CTX_set_hkdf_mode(ctx: *mut EVP_PKEY_CTX, mode: c_int) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
@@ -233,7 +253,7 @@ pub unsafe fn EVP_PKEY_CTX_set_hkdf_mode(ctx: *mut EVP_PKEY_CTX, mode: c_int) ->
)
}
#[cfg(all(ossl110, not(ossl300)))]
#[cfg(any(all(ossl110, not(ossl300)), libressl360))]
pub unsafe fn EVP_PKEY_CTX_set_hkdf_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
@@ -245,7 +265,7 @@ pub unsafe fn EVP_PKEY_CTX_set_hkdf_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD
)
}
#[cfg(all(ossl110, not(ossl300)))]
#[cfg(any(all(ossl110, not(ossl300)), libressl360))]
pub unsafe fn EVP_PKEY_CTX_set1_hkdf_salt(
ctx: *mut EVP_PKEY_CTX,
salt: *const u8,
@@ -261,7 +281,7 @@ pub unsafe fn EVP_PKEY_CTX_set1_hkdf_salt(
)
}
#[cfg(all(ossl110, not(ossl300)))]
#[cfg(any(all(ossl110, not(ossl300)), libressl360))]
pub unsafe fn EVP_PKEY_CTX_set1_hkdf_key(
ctx: *mut EVP_PKEY_CTX,
key: *const u8,
@@ -277,7 +297,7 @@ pub unsafe fn EVP_PKEY_CTX_set1_hkdf_key(
)
}
#[cfg(all(ossl110, not(ossl300)))]
#[cfg(any(all(ossl110, not(ossl300)), libressl360))]
pub unsafe fn EVP_PKEY_CTX_add1_hkdf_info(
ctx: *mut EVP_PKEY_CTX,
info: *const u8,
@@ -293,7 +313,7 @@ pub unsafe fn EVP_PKEY_CTX_add1_hkdf_info(
)
}
#[cfg(all(not(ossl300), not(boringssl)))]
#[cfg(not(any(ossl300, boringssl, awslc)))]
pub unsafe fn EVP_PKEY_CTX_set_signature_md(cxt: *mut EVP_PKEY_CTX, md: *mut EVP_MD) -> c_int {
EVP_PKEY_CTX_ctrl(
cxt,
+57
View File
@@ -106,3 +106,60 @@ extern "C" {
destroy: Option<unsafe extern "C" fn(*mut BIO) -> c_int>,
) -> c_int;
}
#[cfg(ossl320)]
extern "C" {
pub fn BIO_meth_set_sendmmsg(
biom: *mut BIO_METHOD,
f: Option<
unsafe extern "C" fn(
arg1: *mut BIO,
arg2: *mut BIO_MSG,
arg3: usize,
arg4: usize,
arg5: u64,
arg6: *mut usize,
) -> c_int,
>,
) -> c_int;
pub fn BIO_meth_set_recvmmsg(
biom: *mut BIO_METHOD,
f: Option<
unsafe extern "C" fn(
arg1: *mut BIO,
arg2: *mut BIO_MSG,
arg3: usize,
arg4: usize,
arg5: u64,
arg6: *mut usize,
) -> c_int,
>,
) -> c_int;
pub fn BIO_new_bio_dgram_pair(
bio1: *mut *mut BIO,
writebuf1: usize,
bio2: *mut *mut BIO,
writebuf2: usize,
) -> c_int;
pub fn BIO_s_dgram_pair() -> *const BIO_METHOD;
pub fn BIO_s_datagram() -> *const BIO_METHOD;
pub fn BIO_get_rpoll_descriptor(b: *mut BIO, desc: *mut BIO_POLL_DESCRIPTOR) -> c_int;
pub fn BIO_get_wpoll_descriptor(b: *mut BIO, desc: *mut BIO_POLL_DESCRIPTOR) -> c_int;
pub fn BIO_sendmmsg(
b: *mut BIO,
msg: *mut BIO_MSG,
stride: usize,
num_msg: usize,
flags: u64,
msgs_processed: *mut usize,
) -> c_int;
pub fn BIO_recvmmsg(
b: *mut BIO,
msg: *mut BIO_MSG,
stride: usize,
num_msg: usize,
flags: u64,
msgs_processed: *mut usize,
) -> c_int;
pub fn BIO_err_is_non_fatal(errcode: c_uint) -> c_int;
}
-1
View File
@@ -75,7 +75,6 @@ extern "C" {
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
#[cfg(ossl110)]
pub fn BN_mod_sqrt(
ret: *mut BIGNUM,
a: *const BIGNUM,
+7 -1
View File
@@ -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);
}
+1 -1
View File
@@ -57,7 +57,7 @@ extern "C" {
}
cfg_if! {
if #[cfg(ossl110)] {
if #[cfg(any(ossl110, libressl390))] {
extern "C" {
pub fn CRYPTO_malloc(num: size_t, file: *const c_char, line: c_int) -> *mut c_void;
pub fn CRYPTO_free(buf: *mut c_void, file: *const c_char, line: c_int);
+1
View File
@@ -5,6 +5,7 @@ extern "C" {
pub fn DH_free(dh: *mut DH);
pub fn DH_check(dh: *const DH, codes: *mut c_int) -> c_int;
#[cfg(not(libressl382))]
pub fn DH_generate_parameters(
prime_len: c_int,
generator: c_int,
+3 -1
View File
@@ -9,6 +9,7 @@ pub enum point_conversion_form_t {
POINT_CONVERSION_HYBRID = 6,
}
#[cfg(not(libressl410))]
pub enum EC_METHOD {}
pub enum EC_GROUP {}
pub enum EC_POINT {}
@@ -17,6 +18,7 @@ extern "C" {
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn EC_GF2m_simple_method() -> *const EC_METHOD;
#[cfg(not(libressl410))]
pub fn EC_GROUP_new(meth: *const EC_METHOD) -> *mut EC_GROUP;
pub fn EC_GROUP_free(group: *mut EC_GROUP);
@@ -101,7 +103,7 @@ extern "C" {
pub fn EC_POINT_dup(p: *const EC_POINT, group: *const EC_GROUP) -> *mut EC_POINT;
#[cfg(any(ossl111, boringssl, libressl350))]
#[cfg(any(ossl111, boringssl, libressl350, awslc))]
pub fn EC_POINT_get_affine_coordinates(
group: *const EC_GROUP,
p: *const EC_POINT,
+59 -17
View File
@@ -52,7 +52,7 @@ cfg_if! {
}
cfg_if! {
if #[cfg(ossl110)] {
if #[cfg(any(ossl110, libressl382))] {
extern "C" {
pub fn EVP_MD_CTX_new() -> *mut EVP_MD_CTX;
pub fn EVP_MD_CTX_free(ctx: *mut EVP_MD_CTX);
@@ -69,6 +69,7 @@ cfg_if! {
if #[cfg(ossl300)] {
extern "C" {
pub fn EVP_default_properties_is_fips_enabled(libctx: *mut OSSL_LIB_CTX) -> c_int;
pub fn EVP_default_properties_enable_fips(libctx: *mut OSSL_LIB_CTX, enable: c_int) -> c_int;
}
}
}
@@ -92,6 +93,8 @@ extern "C" {
pub fn EVP_DigestFinal(ctx: *mut EVP_MD_CTX, res: *mut u8, n: *mut u32) -> c_int;
#[cfg(ossl111)]
pub fn EVP_DigestFinalXOF(ctx: *mut EVP_MD_CTX, res: *mut u8, len: usize) -> c_int;
#[cfg(ossl330)]
pub fn EVP_DigestSqueeze(ctx: *mut EVP_MD_CTX, res: *mut u8, len: usize) -> c_int;
#[cfg(ossl300)]
pub fn EVP_MD_fetch(
@@ -271,6 +274,8 @@ const_ptr_api! {
extern "C" {
pub fn EVP_CIPHER_CTX_new() -> *mut EVP_CIPHER_CTX;
pub fn EVP_CIPHER_CTX_free(ctx: *mut EVP_CIPHER_CTX);
pub fn EVP_CIPHER_CTX_copy(dst: *mut EVP_CIPHER_CTX, src: *const EVP_CIPHER_CTX) -> c_int;
pub fn EVP_MD_CTX_copy_ex(dst: *mut EVP_MD_CTX, src: *const EVP_MD_CTX) -> c_int;
#[cfg(ossl111)]
pub fn EVP_MD_CTX_reset(ctx: *mut EVP_MD_CTX) -> c_int;
@@ -292,13 +297,13 @@ extern "C" {
pub fn EVP_sha256() -> *const EVP_MD;
pub fn EVP_sha384() -> *const EVP_MD;
pub fn EVP_sha512() -> *const EVP_MD;
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380))]
pub fn EVP_sha3_224() -> *const EVP_MD;
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380))]
pub fn EVP_sha3_256() -> *const EVP_MD;
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380))]
pub fn EVP_sha3_384() -> *const EVP_MD;
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380))]
pub fn EVP_sha3_512() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_shake128() -> *const EVP_MD;
@@ -310,7 +315,10 @@ extern "C" {
pub fn EVP_des_ecb() -> *const EVP_CIPHER;
pub fn EVP_des_ede3() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_cbc() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_ecb() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_cfb64() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_cfb8() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_ofb() -> *const EVP_CIPHER;
pub fn EVP_des_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
pub fn EVP_rc4() -> *const EVP_CIPHER;
@@ -365,9 +373,9 @@ extern "C" {
pub fn EVP_aes_256_wrap() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_aes_256_wrap_pad() -> *const EVP_CIPHER;
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
#[cfg(all(any(ossl110, libressl310), not(osslconf = "OPENSSL_NO_CHACHA")))]
pub fn EVP_chacha20() -> *const EVP_CIPHER;
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
#[cfg(all(any(ossl110, libressl360), not(osslconf = "OPENSSL_NO_CHACHA")))]
pub fn EVP_chacha20_poly1305() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
pub fn EVP_seed_cbc() -> *const EVP_CIPHER;
@@ -389,28 +397,53 @@ extern "C" {
#[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))]
pub fn EVP_sm4_ctr() -> *const EVP_CIPHER;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_128_cfb128() -> *const EVP_CIPHER;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_128_ecb() -> *const EVP_CIPHER;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_128_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_128_ofb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_192_cfb128() -> *const EVP_CIPHER;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_192_ecb() -> *const EVP_CIPHER;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_192_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_192_ofb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_256_cfb128() -> *const EVP_CIPHER;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_256_ecb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_256_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn EVP_camellia_256_ofb() -> *const EVP_CIPHER;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAST")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn EVP_cast5_cfb64() -> *const EVP_CIPHER;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAST")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn EVP_cast5_ecb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn EVP_cast5_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn EVP_cast5_ofb() -> *const EVP_CIPHER;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_IDEA")))]
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn EVP_idea_cfb64() -> *const EVP_CIPHER;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_IDEA")))]
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn EVP_idea_ecb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn EVP_idea_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn EVP_idea_ofb() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_RC2"))]
pub fn EVP_rc2_cbc() -> *const EVP_CIPHER;
#[cfg(not(osslconf = "OPENSSL_NO_RC2"))]
pub fn EVP_rc2_40_cbc() -> *const EVP_CIPHER;
#[cfg(not(ossl110))]
pub fn OPENSSL_add_all_algorithms_noconf();
@@ -444,8 +477,11 @@ extern "C" {
pub fn EVP_PKEY_set1_RSA(k: *mut EVP_PKEY, r: *mut RSA) -> c_int;
pub fn EVP_PKEY_get1_RSA(k: *mut EVP_PKEY) -> *mut RSA;
pub fn EVP_PKEY_set1_DSA(k: *mut EVP_PKEY, k: *mut DSA) -> c_int;
pub fn EVP_PKEY_get1_DSA(k: *mut EVP_PKEY) -> *mut DSA;
pub fn EVP_PKEY_set1_DH(k: *mut EVP_PKEY, k: *mut DH) -> c_int;
pub fn EVP_PKEY_get1_DH(k: *mut EVP_PKEY) -> *mut DH;
pub fn EVP_PKEY_set1_EC_KEY(k: *mut EVP_PKEY, k: *mut EC_KEY) -> c_int;
pub fn EVP_PKEY_get1_EC_KEY(k: *mut EVP_PKEY) -> *mut EC_KEY;
pub fn EVP_PKEY_new() -> *mut EVP_PKEY;
@@ -513,6 +549,12 @@ extern "C" {
#[cfg(ossl300)]
pub fn EVP_PKEY_CTX_set_signature_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_CTX_set_params(ctx: *mut EVP_PKEY_CTX, params: *const OSSL_PARAM) -> c_int;
#[cfg(ossl300)]
pub fn EVP_PKEY_CTX_get_params(ctx: *mut EVP_PKEY_CTX, params: *mut OSSL_PARAM) -> c_int;
pub fn EVP_PKEY_new_mac_key(
type_: c_int,
e: *mut ENGINE,
+8
View File
@@ -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);
}
}
}
+6
View File
@@ -15,6 +15,7 @@ pub use self::hmac::*;
pub use self::kdf::*;
pub use self::object::*;
pub use self::ocsp::*;
pub use self::params::*;
pub use self::pem::*;
pub use self::pkcs12::*;
pub use self::pkcs7::*;
@@ -28,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::*;
@@ -51,6 +54,7 @@ mod hmac;
mod kdf;
mod object;
mod ocsp;
mod params;
mod pem;
mod pkcs12;
mod pkcs7;
@@ -64,6 +68,8 @@ mod sha;
mod srtp;
mod ssl;
mod stack;
#[cfg(ossl320)]
mod thread;
mod tls1;
mod types;
mod x509;
+16
View File
@@ -0,0 +1,16 @@
use super::super::*;
use libc::*;
extern "C" {
#[cfg(ossl300)]
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;
}
+3
View File
@@ -3,6 +3,9 @@ use libc::*;
extern "C" {
pub fn RAND_bytes(buf: *mut u8, num: c_int) -> c_int;
#[cfg(ossl111)]
pub fn RAND_priv_bytes(buf: *mut u8, num: c_int) -> c_int;
#[cfg(ossl111)]
pub fn RAND_keep_random_devices_open(keep: c_int);
+87
View File
@@ -640,7 +640,13 @@ extern "C" {
pub fn SSL_stateless(s: *mut SSL) -> c_int;
pub fn SSL_connect(ssl: *mut SSL) -> c_int;
pub fn SSL_read(ssl: *mut SSL, buf: *mut c_void, num: c_int) -> c_int;
#[cfg(any(ossl111, libressl350))]
pub fn SSL_read_ex(ssl: *mut SSL, buf: *mut c_void, num: usize, readbytes: *mut usize)
-> c_int;
pub fn SSL_peek(ssl: *mut SSL, buf: *mut c_void, num: c_int) -> c_int;
#[cfg(any(ossl111, libressl350))]
pub fn SSL_peek_ex(ssl: *mut SSL, buf: *mut c_void, num: usize, readbytes: *mut usize)
-> c_int;
#[cfg(any(ossl111, libressl340))]
pub fn SSL_read_early_data(
s: *mut SSL,
@@ -661,6 +667,13 @@ extern "C" {
extern "C" {
pub fn SSL_write(ssl: *mut SSL, buf: *const c_void, num: c_int) -> c_int;
#[cfg(any(ossl111, libressl350))]
pub fn SSL_write_ex(
ssl: *mut SSL,
buf: *const c_void,
num: size_t,
written: *mut size_t,
) -> c_int;
#[cfg(any(ossl111, libressl340))]
pub fn SSL_write_early_data(
s: *mut SSL,
@@ -688,6 +701,10 @@ cfg_if! {
pub fn TLS_server_method() -> *const SSL_METHOD;
pub fn TLS_client_method() -> *const SSL_METHOD;
pub fn DTLS_server_method() -> *const SSL_METHOD;
pub fn DTLS_client_method() -> *const SSL_METHOD;
}
} else {
extern "C" {
@@ -924,3 +941,73 @@ extern "C" {
#[cfg(all(ossl111, not(ossl111b)))]
pub fn SSL_get_num_tickets(s: *mut SSL) -> size_t;
}
extern "C" {
#[cfg(any(ossl110, libressl360))]
pub fn SSL_CTX_set_security_level(ctx: *mut SSL_CTX, level: c_int);
#[cfg(any(ossl110, libressl360))]
pub fn SSL_set_security_level(s: *mut SSL, level: c_int);
#[cfg(any(ossl110, libressl360))]
pub fn SSL_CTX_get_security_level(ctx: *const SSL_CTX) -> c_int;
#[cfg(any(ossl110, libressl360))]
pub fn SSL_get_security_level(s: *const SSL) -> c_int;
}
#[cfg(ossl320)]
extern "C" {
pub fn OSSL_QUIC_client_method() -> *const SSL_METHOD;
pub fn OSSL_QUIC_client_thread_method() -> *const SSL_METHOD;
pub fn SSL_get_event_timeout(s: *mut SSL, tv: *mut timeval, is_infinite: *mut c_int) -> c_int;
pub fn SSL_handle_events(s: *mut SSL) -> c_int;
pub fn SSL_get_blocking_mode(s: *mut SSL) -> c_int;
pub fn SSL_set_blocking_mode(s: *mut SSL, blocking: c_int) -> c_int;
pub fn SSL_get_rpoll_descriptor(s: *mut SSL, desc: *mut BIO_POLL_DESCRIPTOR) -> c_int;
pub fn SSL_get_wpoll_descriptor(s: *mut SSL, desc: *mut BIO_POLL_DESCRIPTOR) -> c_int;
pub fn SSL_net_read_desired(s: *mut SSL) -> c_int;
pub fn SSL_net_write_desired(s: *mut SSL) -> c_int;
pub fn SSL_set1_initial_peer_addr(s: *mut SSL, peer_addr: *const BIO_ADDR) -> c_int;
pub fn SSL_shutdown_ex(
ssl: *mut SSL,
flags: u64,
args: *const SSL_SHUTDOWN_EX_ARGS,
args_len: usize,
) -> c_int;
pub fn SSL_stream_conclude(ssl: *mut SSL, flags: u64) -> c_int;
pub fn SSL_stream_reset(
ssl: *mut SSL,
args: *const SSL_STREAM_RESET_ARGS,
args_len: usize,
) -> c_int;
pub fn SSL_get_stream_read_state(ssl: *mut SSL) -> c_int;
pub fn SSL_get_stream_write_state(ssl: *mut SSL) -> c_int;
pub fn SSL_get_conn_close_info(
ssl: *mut SSL,
info: *mut SSL_CONN_CLOSE_INFO,
info_len: usize,
) -> c_int;
pub fn SSL_get0_connection(s: *mut SSL) -> *mut SSL;
pub fn SSL_is_connection(s: *mut SSL) -> c_int;
pub fn SSL_get_stream_type(s: *mut SSL) -> c_int;
pub fn SSL_get_stream_id(s: *mut SSL) -> u64;
pub fn SSL_new_stream(s: *mut SSL, flags: u64) -> *mut SSL;
pub fn SSL_accept_stream(s: *mut SSL, flags: u64) -> *mut SSL;
pub fn SSL_set_incoming_stream_policy(s: *mut SSL, policy: c_int, aec: u64) -> c_int;
pub fn SSL_get_accept_stream_queue_len(s: *mut SSL) -> usize;
pub fn SSL_set_default_stream_mode(s: *mut SSL, mode: u32) -> c_int;
}
#[cfg(ossl330)]
extern "C" {
pub fn SSL_write_ex2(
s: *mut SSL,
buf: *const c_void,
num: usize,
flags: u64,
written: *mut usize,
) -> c_int;
pub fn SSL_get_value_uint(s: *mut SSL, class_: u32, id: u32, v: *mut u64) -> c_int;
pub fn SSL_set_value_uint(s: *mut SSL, class_: u32, id: u32, v: u64) -> c_int;
}
+2
View File
@@ -3,6 +3,8 @@ use libc::*;
cfg_if! {
if #[cfg(ossl110)] {
pub enum OPENSSL_STACK {}
} else if #[cfg(libressl390)] {
pub enum _STACK {}
} else {
#[repr(C)]
pub struct _STACK {
+7
View File
@@ -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;
}
+52 -1
View File
@@ -52,6 +52,20 @@ cfg_if! {
}
}
}
cfg_if! {
if #[cfg(ossl320)] {
pub enum BIO_ADDR {}
pub enum BIO_POLL_DESCRIPTOR {}
#[repr(C)]
pub struct BIO_MSG {
pub data: *mut c_void,
pub data_len: usize,
pub peer: *mut BIO_ADDR,
pub local: *mut BIO_ADDR,
pub flags: u64,
}
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl350))] {
pub enum BIGNUM {}
@@ -329,7 +343,7 @@ cfg_if! {
}
}
cfg_if! {
if #[cfg(ossl110)] {
if #[cfg(any(ossl110, libressl382))] {
pub enum X509_ALGOR {}
} else {
#[repr(C)]
@@ -458,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)]
@@ -1032,6 +1047,27 @@ cfg_if! {
}
}
}
cfg_if! {
if #[cfg(ossl320)] {
#[repr(C)]
pub struct SSL_CONN_CLOSE_INFO {
pub error_code: u64,
pub frame_type: u64,
pub reason: *const ::libc::c_char,
pub reason_len: usize,
pub flags: u32,
}
#[repr(C)]
pub struct SSL_SHUTDOWN_EX_ARGS {
pub quic_error_code: u64,
pub quic_reason: *const c_char,
}
#[repr(C)]
pub struct SSL_STREAM_RESET_ARGS {
pub quic_error_code: u64,
}
}
}
pub enum COMP_CTX {}
@@ -1093,3 +1129,18 @@ pub enum OSSL_PROVIDER {}
#[cfg(ossl300)]
pub enum OSSL_LIB_CTX {}
#[cfg(ossl300)]
#[repr(C)]
pub struct OSSL_PARAM {
key: *const c_char,
data_type: c_uchar,
data: *mut c_void,
data_size: size_t,
return_size: size_t,
}
#[cfg(ossl300)]
pub enum EVP_KDF {}
#[cfg(ossl300)]
pub enum EVP_KDF_CTX {}
+29 -17
View File
@@ -1,10 +1,16 @@
use super::super::*;
use libc::*;
#[repr(C)]
pub struct X509_VAL {
pub notBefore: *mut ASN1_TIME,
pub notAfter: *mut ASN1_TIME,
cfg_if! {
if #[cfg(libressl400)] {
pub enum X509_VAL {}
} else {
#[repr(C)]
pub struct X509_VAL {
pub notBefore: *mut ASN1_TIME,
pub notAfter: *mut ASN1_TIME,
}
}
}
pub enum X509_NAME_ENTRY {}
@@ -311,6 +317,7 @@ extern "C" {
pub fn X509_get_version(x: *const X509) -> c_long;
pub fn X509_set_serialNumber(x: *mut X509, sn: *mut ASN1_INTEGER) -> c_int;
pub fn X509_get_serialNumber(x: *mut X509) -> *mut ASN1_INTEGER;
pub fn X509_alias_get0(x: *mut X509, len: *mut c_int) -> *mut c_uchar;
}
const_ptr_api! {
extern "C" {
@@ -687,26 +694,31 @@ extern "C" {
pub fn X509_REQ_print(bio: *mut BIO, req: *mut X509_REQ) -> c_int;
}
#[repr(C)]
pub struct X509_PURPOSE {
pub purpose: c_int,
pub trust: c_int, // Default trust ID
pub flags: c_int,
pub check_purpose:
Option<unsafe extern "C" fn(*const X509_PURPOSE, *const X509, c_int) -> c_int>,
pub name: *mut c_char,
pub sname: *mut c_char,
pub usr_data: *mut c_void,
cfg_if! {
if #[cfg(libressl390)] {
pub enum X509_PURPOSE {}
} else {
#[repr(C)]
pub struct X509_PURPOSE {
pub purpose: c_int,
pub trust: c_int, // Default trust ID
pub flags: c_int,
pub check_purpose:
Option<unsafe extern "C" fn(*const X509_PURPOSE, *const X509, c_int) -> c_int>,
pub name: *mut c_char,
pub sname: *mut c_char,
pub usr_data: *mut c_void,
}
}
}
const_ptr_api! {
extern "C" {
pub fn X509_PURPOSE_get_by_sname(sname: #[const_ptr_if(any(ossl110, libressl280))] c_char) -> c_int;
pub fn X509_PURPOSE_get_id(purpose: #[const_ptr_if(any(ossl110, libressl280))] X509_PURPOSE) -> c_int;
pub fn X509_PURPOSE_get0(idx: c_int) -> #[const_ptr_if(libressl390)] X509_PURPOSE;
}
}
extern "C" {
pub fn X509_PURPOSE_get0(idx: c_int) -> *mut X509_PURPOSE;
}
extern "C" {
pub fn X509_ATTRIBUTE_new() -> *mut X509_ATTRIBUTE;
+16 -7
View File
@@ -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;
}
}
@@ -118,6 +121,12 @@ extern "C" {
#[cfg(any(ossl102, libressl261))]
pub fn X509_VERIFY_PARAM_set_hostflags(param: *mut X509_VERIFY_PARAM, flags: c_uint);
#[cfg(any(ossl102, libressl261))]
pub fn X509_VERIFY_PARAM_set1_email(
param: *mut X509_VERIFY_PARAM,
email: *const c_char,
emaillen: size_t,
) -> c_int;
#[cfg(any(ossl102, libressl261))]
pub fn X509_VERIFY_PARAM_set1_ip(
param: *mut X509_VERIFY_PARAM,
ip: *const c_uchar,
+20
View File
@@ -84,6 +84,7 @@ const_ptr_api! {
}
extern "C" {
#[cfg(not(libressl390))]
pub fn X509V3_EXT_add_alias(nid_to: c_int, nid_from: c_int) -> c_int;
pub fn X509V3_EXT_d2i(ext: *mut X509_EXTENSION) -> *mut c_void;
pub fn X509V3_EXT_i2d(ext_nid: c_int, crit: c_int, ext: *mut c_void) -> *mut X509_EXTENSION;
@@ -145,3 +146,22 @@ extern "C" {
pub fn DIST_POINT_free(dist_point: *mut DIST_POINT);
pub fn DIST_POINT_NAME_free(dist_point: *mut DIST_POINT_NAME);
}
#[cfg(ossl102)]
extern "C" {
pub fn X509_check_host(
x: *mut X509,
chk: *const c_char,
chklen: usize,
flags: c_uint,
peername: *mut *mut c_char,
) -> c_int;
pub fn X509_check_email(
x: *mut X509,
chk: *const c_char,
chklen: usize,
flags: c_uint,
) -> c_int;
pub fn X509_check_ip(x: *mut X509, chk: *const c_uchar, chklen: usize, flags: c_uint) -> c_int;
pub fn X509_check_ip_asc(x: *mut X509, ipasc: *const c_char, flags: c_uint) -> c_int;
}
+34 -10
View File
@@ -6,31 +6,55 @@
non_upper_case_globals,
unused_imports
)]
#![cfg_attr(feature = "unstable_boringssl", allow(ambiguous_glob_reexports))]
#![doc(html_root_url = "https://docs.rs/openssl-sys/0.9")]
#![recursion_limit = "128"] // configure fixed limit across all rust versions
extern crate libc;
pub use libc::*;
pub use libc::c_int;
#[cfg(feature = "unstable_boringssl")]
extern crate bssl_sys;
#[cfg(feature = "unstable_boringssl")]
pub use bssl_sys::*;
#[cfg(all(boringssl, not(feature = "unstable_boringssl")))]
#[cfg(boringssl)]
#[path = "."]
mod boringssl {
#[cfg(feature = "unstable_boringssl")]
pub use bssl_sys::*;
#[cfg(not(feature = "unstable_boringssl"))]
include!(concat!(env!("OUT_DIR"), "/bindgen.rs"));
// BoringSSL does not require initialization.
pub fn init() {}
}
#[cfg(boringssl)]
pub use boringssl::*;
#[cfg(feature = "aws-lc")]
extern crate aws_lc_sys;
#[cfg(awslc)]
#[path = "."]
mod aws_lc {
#[cfg(feature = "aws-lc")]
pub use aws_lc_sys::*;
#[cfg(not(feature = "aws-lc"))]
include!(concat!(env!("OUT_DIR"), "/bindgen.rs"));
use libc::{c_char, c_long, c_void};
pub fn init() {
unsafe {
CRYPTO_library_init();
}
unsafe { CRYPTO_library_init() }
}
// BIO_get_mem_data is a C preprocessor macro by definition
#[allow(non_snake_case, clippy::not_unsafe_ptr_arg_deref)]
pub fn BIO_get_mem_data(b: *mut BIO, pp: *mut *mut c_char) -> c_long {
unsafe { BIO_ctrl(b, BIO_CTRL_INFO, 0, pp.cast::<c_void>()) }
}
}
#[cfg(all(boringssl, not(feature = "unstable_boringssl")))]
pub use boringssl::*;
#[cfg(awslc)]
pub use aws_lc::*;
#[cfg(openssl)]
#[path = "."]
+1 -1
View File
@@ -58,7 +58,7 @@ macro_rules! cfg_if {
macro_rules! stack {
($t:ident) => {
cfg_if! {
if #[cfg(ossl110)] {
if #[cfg(any(ossl110, libressl390))] {
pub enum $t {}
} else {
#[repr(C)]
+38 -1
View File
@@ -94,12 +94,27 @@ pub const NID_sect409k1: c_int = 731;
pub const NID_sect409r1: c_int = 732;
pub const NID_sect571k1: c_int = 733;
pub const NID_sect571r1: c_int = 734;
#[cfg(ossl110)]
pub const NID_brainpoolP256r1: c_int = 927;
#[cfg(libressl)]
pub const NID_brainpoolP256r1: c_int = 928;
#[cfg(ossl110)]
pub const NID_brainpoolP320r1: c_int = 929;
#[cfg(libressl)]
pub const NID_brainpoolP320r1: c_int = 930;
#[cfg(ossl110)]
pub const NID_brainpoolP384r1: c_int = 931;
#[cfg(libressl)]
pub const NID_brainpoolP384r1: c_int = 932;
#[cfg(ossl110)]
pub const NID_brainpoolP512r1: c_int = 933;
#[cfg(libressl)]
pub const NID_brainpoolP512r1: c_int = 934;
pub const NID_wap_wsg_idm_ecid_wtls1: c_int = 735;
pub const NID_wap_wsg_idm_ecid_wtls3: c_int = 736;
pub const NID_wap_wsg_idm_ecid_wtls4: c_int = 737;
@@ -135,6 +150,8 @@ pub const NID_sha512WithRSAEncryption: c_int = 670;
pub const NID_sha224WithRSAEncryption: c_int = 671;
pub const NID_pkcs3: c_int = 27;
pub const NID_dhKeyAgreement: c_int = 28;
#[cfg(ossl110)]
pub const NID_dhpublicnumber: c_int = 920;
pub const NID_pkcs5: c_int = 187;
pub const NID_pbeWithMD2AndDES_CBC: c_int = 9;
pub const NID_pbeWithMD5AndDES_CBC: c_int = 10;
@@ -329,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;
@@ -926,6 +942,8 @@ pub const NID_X25519: c_int = 950;
pub const NID_X448: c_int = 1035;
#[cfg(ossl110)]
pub const NID_hkdf: c_int = 1036;
#[cfg(libressl360)]
pub const NID_hkdf: c_int = 1022;
#[cfg(ossl111)]
pub const NID_poly1305: c_int = 1061;
#[cfg(ossl111)]
@@ -974,13 +992,32 @@ pub const NID_sm4_ctr: c_int = 1139;
pub const NID_sm4_ctr: c_int = 979;
#[cfg(ossl111)]
pub const NID_sha3_224: c_int = 1096;
#[cfg(libressl380)]
pub const NID_sha3_224: c_int = 1031;
#[cfg(ossl111)]
pub const NID_sha3_256: c_int = 1097;
#[cfg(libressl380)]
pub const NID_sha3_256: c_int = 1032;
#[cfg(ossl111)]
pub const NID_sha3_384: c_int = 1098;
#[cfg(libressl380)]
pub const NID_sha3_384: c_int = 1033;
#[cfg(ossl111)]
pub const NID_sha3_512: c_int = 1099;
#[cfg(libressl380)]
pub const NID_sha3_512: c_int = 1034;
#[cfg(ossl111)]
pub const NID_shake128: c_int = 1100;
#[cfg(ossl111)]
pub const NID_shake256: c_int = 1101;
#[cfg(ossl110)]
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;
}
}
+1 -1
View File
@@ -76,7 +76,7 @@ pub unsafe fn EVP_PKEY_CTX_set0_rsa_oaep_label(
EVP_PKEY_OP_TYPE_CRYPT,
EVP_PKEY_CTRL_RSA_OAEP_LABEL,
len,
label as *mut c_void,
label,
)
}
+85
View File
@@ -349,6 +349,8 @@ pub const SSL_CTRL_SET_ECDH_AUTO: c_int = 94;
pub const SSL_CTRL_SET_SIGALGS_LIST: c_int = 98;
#[cfg(ossl102)]
pub const SSL_CTRL_SET_VERIFY_CERT_STORE: c_int = 106;
#[cfg(ossl300)]
pub const SSL_CTRL_GET_PEER_TMP_KEY: c_int = 109;
#[cfg(ossl110)]
pub const SSL_CTRL_GET_EXTMS_SUPPORT: c_int = 122;
#[cfg(any(ossl110, libressl261))]
@@ -359,6 +361,8 @@ pub const SSL_CTRL_SET_MAX_PROTO_VERSION: c_int = 124;
pub const SSL_CTRL_GET_MIN_PROTO_VERSION: c_int = 130;
#[cfg(any(ossl110g, libressl270))]
pub const SSL_CTRL_GET_MAX_PROTO_VERSION: c_int = 131;
#[cfg(ossl300)]
pub const SSL_CTRL_GET_TMP_KEY: c_int = 133;
pub unsafe fn SSL_CTX_set_tmp_dh(ctx: *mut SSL_CTX, dh: *mut DH) -> c_long {
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, dh as *mut c_void)
@@ -506,6 +510,17 @@ cfg_if! {
}
}
}
cfg_if! {
if #[cfg(ossl300)] {
pub unsafe fn SSL_get_peer_tmp_key(ssl: *mut SSL, key: *mut *mut EVP_PKEY) -> c_long {
SSL_ctrl(ssl, SSL_CTRL_GET_PEER_TMP_KEY, 0, key as *mut c_void)
}
pub unsafe fn SSL_get_tmp_key(ssl: *mut SSL, key: *mut *mut EVP_PKEY) -> c_long {
SSL_ctrl(ssl, SSL_CTRL_GET_TMP_KEY, 0, key as *mut c_void)
}
}
}
#[cfg(ossl111)]
pub const SSL_CLIENT_HELLO_SUCCESS: c_int = 1;
@@ -629,3 +644,73 @@ pub unsafe fn SSL_session_reused(ssl: *mut SSL) -> c_int {
pub const OPENSSL_INIT_LOAD_SSL_STRINGS: u64 = 0x00200000;
#[cfg(ossl111b)]
pub const OPENSSL_INIT_NO_ATEXIT: u64 = 0x00080000;
cfg_if! {
if #[cfg(ossl330)] {
pub const SSL_VALUE_CLASS_GENERIC: c_uint = 0;
pub const SSL_VALUE_CLASS_FEATURE_REQUEST: c_uint = 1;
pub const SSL_VALUE_CLASS_FEATURE_PEER_REQUEST: c_uint = 2;
pub const SSL_VALUE_CLASS_FEATURE_NEGOTIATED: c_uint = 3;
pub const SSL_VALUE_NONE: c_uint = 0;
pub const SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL: c_uint = 1;
pub const SSL_VALUE_QUIC_STREAM_BIDI_REMOTE_AVAIL: c_uint = 2;
pub const SSL_VALUE_QUIC_STREAM_UNI_LOCAL_AVAIL: c_uint = 3;
pub const SSL_VALUE_QUIC_STREAM_UNI_REMOTE_AVAIL: c_uint = 4;
pub const SSL_VALUE_QUIC_IDLE_TIMEOUT: c_uint = 5;
pub const SSL_VALUE_EVENT_HANDLING_MODE: c_uint = 6;
pub const SSL_VALUE_STREAM_WRITE_BUF_SIZE: c_uint = 7;
pub const SSL_VALUE_STREAM_WRITE_BUF_USED: c_uint = 8;
pub const SSL_VALUE_STREAM_WRITE_BUF_AVAIL: c_uint = 9;
pub const SSL_VALUE_EVENT_HANDLING_MODE_INHERIT: c_uint = 0;
pub const SSL_VALUE_EVENT_HANDLING_MODE_IMPLICIT: c_uint = 1;
pub const SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT: c_uint = 2;
pub unsafe fn SSL_get_generic_value_uint(ssl: *mut SSL, id: u32, value: *mut u64) -> c_int {
SSL_get_value_uint(ssl, SSL_VALUE_CLASS_GENERIC, id, value)
}
pub unsafe fn SSL_set_generic_value_uint(ssl: *mut SSL, id: u32, value: u64) -> c_int {
SSL_set_value_uint(ssl, SSL_VALUE_CLASS_GENERIC, id, value)
}
pub unsafe fn SSL_get_feature_request_uint(ssl: *mut SSL, id: u32, value: *mut u64) -> c_int {
SSL_get_value_uint(ssl, SSL_VALUE_CLASS_FEATURE_REQUEST, id, value)
}
pub unsafe fn SSL_set_feature_request_uint(ssl: *mut SSL, id: u32, value: u64) -> c_int {
SSL_set_value_uint(ssl, SSL_VALUE_CLASS_FEATURE_REQUEST, id, value)
}
pub unsafe fn SSL_get_feature_peer_request_uint(ssl: *mut SSL, id: u32, value: *mut u64) -> c_int {
SSL_get_value_uint(ssl, SSL_VALUE_CLASS_FEATURE_PEER_REQUEST, id, value)
}
pub unsafe fn SSL_get_feature_negotiated_uint(ssl: *mut SSL, id: u32, value: *mut u64) -> c_int {
SSL_get_value_uint(ssl, SSL_VALUE_CLASS_FEATURE_NEGOTIATED, id, value)
}
pub unsafe fn SSL_get_quic_stream_bidi_local_avail(ssl: *mut SSL, value: *mut u64) -> c_int {
SSL_get_generic_value_uint(ssl, SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL, value)
}
pub unsafe fn SSL_get_quic_stream_bidi_remote_avail(ssl: *mut SSL, value: *mut u64) -> c_int {
SSL_get_generic_value_uint(ssl, SSL_VALUE_QUIC_STREAM_BIDI_REMOTE_AVAIL, value)
}
pub unsafe fn SSL_get_quic_stream_uni_local_avail(ssl: *mut SSL, value: *mut u64) -> c_int {
SSL_get_generic_value_uint(ssl, SSL_VALUE_QUIC_STREAM_UNI_LOCAL_AVAIL, value)
}
pub unsafe fn SSL_get_quic_stream_uni_remote_avail(ssl: *mut SSL, value: *mut u64) -> c_int {
SSL_get_generic_value_uint(ssl, SSL_VALUE_QUIC_STREAM_UNI_REMOTE_AVAIL, value)
}
pub unsafe fn SSL_get_event_handling_mode(ssl: *mut SSL, value: *mut u64) -> c_int {
SSL_get_generic_value_uint(ssl, SSL_VALUE_EVENT_HANDLING_MODE, value)
}
pub unsafe fn SSL_set_event_handling_mode(ssl: *mut SSL, value: u64) -> c_int {
SSL_set_generic_value_uint(ssl, SSL_VALUE_EVENT_HANDLING_MODE, value)
}
pub unsafe fn SSL_get_stream_write_buf_size(ssl: *mut SSL, value: *mut u64) -> c_int {
SSL_get_generic_value_uint(ssl, SSL_VALUE_STREAM_WRITE_BUF_SIZE, value)
}
pub unsafe fn SSL_get_stream_write_buf_avail(ssl: *mut SSL, value: *mut u64) -> c_int {
SSL_get_generic_value_uint(ssl, SSL_VALUE_STREAM_WRITE_BUF_AVAIL, value)
}
pub unsafe fn SSL_get_stream_write_buf_used(ssl: *mut SSL, value: *mut u64) -> c_int {
SSL_get_generic_value_uint(ssl, SSL_VALUE_STREAM_WRITE_BUF_USED, value)
}
}
}
+18 -2
View File
@@ -74,7 +74,16 @@ pub unsafe fn SSL_CTX_set_tlsext_servername_callback__fixed_rust(
ctx: *mut SSL_CTX,
cb: Option<unsafe extern "C" fn(*mut SSL, *mut c_int, *mut c_void) -> c_int>,
) -> c_long {
SSL_CTX_callback_ctrl__fixed_rust(ctx, SSL_CTRL_SET_TLSEXT_SERVERNAME_CB, mem::transmute(cb))
SSL_CTX_callback_ctrl__fixed_rust(
ctx,
SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,
mem::transmute::<
std::option::Option<
unsafe extern "C" fn(*mut SSL, *mut c_int, *mut libc::c_void) -> i32,
>,
std::option::Option<unsafe extern "C" fn()>,
>(cb),
)
}
pub const SSL_TLSEXT_ERR_OK: c_int = 0;
@@ -90,7 +99,14 @@ pub unsafe fn SSL_CTX_set_tlsext_status_cb(
ctx: *mut SSL_CTX,
cb: Option<unsafe extern "C" fn(*mut SSL, *mut c_void) -> c_int>,
) -> c_long {
SSL_CTX_callback_ctrl__fixed_rust(ctx, SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB, mem::transmute(cb))
SSL_CTX_callback_ctrl__fixed_rust(
ctx,
SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,
mem::transmute::<
std::option::Option<unsafe extern "C" fn(*mut SSL, *mut c_void) -> i32>,
std::option::Option<unsafe extern "C" fn()>,
>(cb),
)
}
pub unsafe fn SSL_CTX_set_tlsext_status_arg(ctx: *mut SSL_CTX, arg: *mut c_void) -> c_long {
+9 -1
View File
@@ -89,8 +89,16 @@ pub const X509_PURPOSE_CRL_SIGN: c_int = 6;
pub const X509_PURPOSE_ANY: c_int = 7;
pub const X509_PURPOSE_OCSP_HELPER: c_int = 8;
pub const X509_PURPOSE_TIMESTAMP_SIGN: c_int = 9;
#[cfg(ossl320)]
pub const X509_PURPOSE_CODE_SIGN: c_int = 10;
pub const X509_PURPOSE_MIN: c_int = 1;
pub const X509_PURPOSE_MAX: c_int = 9;
cfg_if! {
if #[cfg(ossl320)] {
pub const X509_PURPOSE_MAX: c_int = 10;
} else {
pub const X509_PURPOSE_MAX: c_int = 9;
}
}
pub const CRL_REASON_UNSPECIFIED: c_int = 0;
pub const CRL_REASON_KEY_COMPROMISE: c_int = 1;
+2 -2
View File
@@ -19,8 +19,8 @@ ohos_cargo_crate("lib") {
crate_root = "src/lib.rs"
sources = [ "src/lib.rs" ]
edition = "2018"
cargo_pkg_version = "0.10.56"
edition = "2021"
cargo_pkg_version = "0.10.73"
cargo_pkg_authors = "Steven Fackler <sfackler@gmail.com>"
cargo_pkg_name = "openssl"
cargo_pkg_description = "OpenSSL bindings"
+210 -1
View File
@@ -2,6 +2,198 @@
## [Unreleased]
## [v0.10.73] - 2025-05-28
### Fixed
* Fixed building on the latest BoringSSL.
### Changed
* Replaced ctest2 with ctest in systest.
## [v0.10.72] - 2025-04-04
### Fixed
* Fixed use-after-free in `Md::fetch` and `Cipher::fetch` when `properties` is `Some(...)`. In practice this use-after-free most likely resulted in OpenSSL treating the `properties` as `b""`.
### Added
* Support for building with AWS-LC.
## [v0.10.71] - 2025-02-15
### Added
* Added `Cipher::rc2_cbc` and `Cipher::rc2_40_cbc`.
## [v0.10.70] - 2025-02-02
### Fixed
* Fixed improper lifetime constraints in `ssl::select_next_proto` that allowed a use after free.
### Added
* Added `SslMethod::dtls_client` and `SslMethod::dtls_server`.
## [v0.10.69] - 2025-01-25
### Fixed
* Fixed the version constraint on `openssl-macros`.
### Added
* Added `SslContextBuilder::load_verify_locations`.
* Added `Hasher::squeeze_xof`.
* Added `SslContextBuilder::set_alpn_select_callback` support for boringssl.
## [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
- Fixed undefined behavior in `MemBio::get_buf` when the resulting buffer had a length of 0.
## [v0.10.65] - 2024-07-20
### Fixed
* Ensure we are initialized in `MessageDigest::from_nid`, `Md::from_nid`, `Md::fetch`
### Changed
* Expose `SslContextBuilder::set_keylog_callback` on BoringSSL
## [v0.10.64] - 2024-02-19
### Added
* Added `PkeyCtxRef::{nonce_type, set_nonce_type}`.
* Added `X509Ref::alias`.
## [v0.10.63] - 2024-01-19
### Added
* Added `Pkcs7Ref::{type_,signed}`.
* Added `Pkcs7SignedRef::certificates`.
* Added `Cipher::{aes_256_xts,des_ede3_ecb,des_ede3_cfb8,des_ede3_ofb,camellia128_ofb,camellia192_ofb,camellia256_ofb,cast5_ofb,idea_ofb}`
* Added `PKey::from_dhx`
* Added `PKey::{public_key_from_pem_passphrase,public_key_from_pem_callback}`.
### Changed
* `Cipher::aes_128_ofb` is now available on BoringSSL
* `Nid::{BRAINPOOL_P256R1,BRAINPOOL_P320R1,BRAINPOOL_P384R1,BRAINPOOL_P512R1}` are now available on LibreSSL.
## [v0.10.62] - 2023-12-22
### Added
* Added `Nid::BRAINPOOL_P320R1`
* Added `rand_priv_bytes`
### Fixed
* Fixed building on the latest version of BoringSSL
## [v0.10.61] - 2023-12-04
### Changed
* `SslStream` now uses `SSL_read_ex`, `SSL_write_ex`, and `SSL_peek_ex` when available
### Added
* Added `SslStream::{read_uninit, ssl_read_uninit}`.
## [v0.10.60] - 2023-11-22
### Deprecated
* Deprecated `X509StoreRef::objects`. It is unsound. All callers should migrate to using `X509StoreRef::all_certificates` instead.
### Fixed
* Fixed a memory leak when calling `SslContextBuilder::set_ex_data` and `SslRef::set_ex_data` multiple times with the same index.
### Added
* Added `X509StoreRef::all_certificates`
* Added `cipher::Cipher::{camellia128_cbc,camellia192_cbc,camellia256_cbc,cast5_cbc,idea_cbc}`
* Added `symm::Cipher::{des_ede3_ecb,des_ede3_cfb8,des_ede3_ofb,camellia_128_ecb,camellia_128_ofb,camellia_128_cfb128,camellia_192_ecb,camellia_192_ofb,camellia_192_cfb128,camellia_256_ecb,camellia_256_ofb,camellia_256_cfb128,cast5_ecb,cast5_ofb,cast5_cfb64,idea_ecb,idea_ofb,idea_cfb64}`
* Added `Crypter::update_unchecked`
* Added `SslRef::{peer_tmp_key,tmp_key}`
### Changed
* `cipher::Cipher::chacha20` is now available on LibreSSL
* `symm::Cipher::chacha20` is now available on LibreSSL
## [v0.10.59] - 2023-11-03
### Added
* Added `Nid::CHACHA20_POLY1305`
### Changed
* Fixed the availability of `Id::RSA_PSS` on OpenSSL
## [v0.10.58] - 2023-11-01
### Added
* Added `Id::{RSA_PSS,DHX}` constants
* Added `SslContextBuilder::set_security_level`
* Added `SslContextRef::security_level`
* Added `SslRef::set_security_level`, `SslRef::security_level`
* Added `Cipher::{camellia_128_cbc, camellia_192_cbc, camellia_256_cbc, cast5_cbc, idea_cbc}`
* Added `X509CrlRef::extension`
* Added `X509PurposeId::CODE_SIGN`
### Changed
* `Pkey` HKDF functionality now works on LibreSSL
* `BigNum::mod_sqrt` is now available on all OpenSSLs
* `MessageDigest::sha3*` are now available on LibreSSL
## [v0.10.57] - 2023-08-27
### Added
* Added `X509VerifyParam::set_email`
* `Cipher::chacha20_poly1305` is now available on LibreSSL
* Added `CipherCtx::copy`
### Changed
* Updated `bitflags` dependecy to the 2.x series
## [v0.10.56] - 2023-08-06
## Added
@@ -787,7 +979,24 @@
Look at the [release tags] for information about older releases.
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.56...master
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.73...master
[v0.10.73]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.72...openssl-v0.10.73
[v0.10.72]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.71...openssl-v0.10.72
[v0.10.71]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.70...openssl-v0.10.71
[v0.10.70]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.69...openssl-v0.10.70
[v0.10.69]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.68...openssl-v0.10.69
[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
[v0.10.63]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.62...openssl-v0.10.63
[v0.10.62]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.61...openssl-v0.10.62
[v0.10.61]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.60...openssl-v0.10.61
[v0.10.60]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.59...openssl-v0.10.60
[v0.10.59]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.58...openssl-v0.10.59
[v0.10.58]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.57...openssl-v0.10.58
[v0.10.57]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.56...openssl-v0.10.57
[v0.10.56]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.55...openssl-v0.10.56
[v0.10.55]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.54...openssl-v0.10.55
[v0.10.54]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.53...openssl-v0.10.54
+8 -6
View File
@@ -1,6 +1,6 @@
[package]
name = "openssl"
version = "0.10.56"
version = "0.10.73"
authors = ["Steven Fackler <sfackler@gmail.com>"]
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]
@@ -20,17 +21,18 @@ v111 = []
vendored = ['ffi/vendored']
bindgen = ['ffi/bindgen']
unstable_boringssl = ["ffi/unstable_boringssl"]
aws-lc = ["ffi/aws-lc"]
default = []
[dependencies]
bitflags = "1.0"
bitflags = "2.2.1"
cfg-if = "1.0"
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.91", path = "../openssl-sys" }
openssl-macros = { version = "0.1.1", path = "../openssl-macros" }
ffi = { package = "openssl-sys", version = "0.9.109", path = "../openssl-sys" }
[dev-dependencies]
hex = "0.3"
hex = "0.4"
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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.
+66 -55
View File
@@ -7,13 +7,56 @@
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\", \"OPENSSL_NO_ARGON2\", \"OPENSSL_NO_RC2\"))");
println!("cargo:rustc-check-cfg=cfg(libressl)");
println!("cargo:rustc-check-cfg=cfg(boringssl)");
println!("cargo:rustc-check-cfg=cfg(awslc)");
println!("cargo:rustc-check-cfg=cfg(libressl250)");
println!("cargo:rustc-check-cfg=cfg(libressl251)");
println!("cargo:rustc-check-cfg=cfg(libressl261)");
println!("cargo:rustc-check-cfg=cfg(libressl270)");
println!("cargo:rustc-check-cfg=cfg(libressl271)");
println!("cargo:rustc-check-cfg=cfg(libressl273)");
println!("cargo:rustc-check-cfg=cfg(libressl280)");
println!("cargo:rustc-check-cfg=cfg(libressl291)");
println!("cargo:rustc-check-cfg=cfg(libressl310)");
println!("cargo:rustc-check-cfg=cfg(libressl321)");
println!("cargo:rustc-check-cfg=cfg(libressl332)");
println!("cargo:rustc-check-cfg=cfg(libressl340)");
println!("cargo:rustc-check-cfg=cfg(libressl350)");
println!("cargo:rustc-check-cfg=cfg(libressl360)");
println!("cargo:rustc-check-cfg=cfg(libressl361)");
println!("cargo:rustc-check-cfg=cfg(libressl370)");
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(libressl410)");
println!("cargo:rustc-check-cfg=cfg(ossl101)");
println!("cargo:rustc-check-cfg=cfg(ossl102)");
println!("cargo:rustc-check-cfg=cfg(ossl110)");
println!("cargo:rustc-check-cfg=cfg(ossl110g)");
println!("cargo:rustc-check-cfg=cfg(ossl110h)");
println!("cargo:rustc-check-cfg=cfg(ossl111)");
println!("cargo:rustc-check-cfg=cfg(ossl111d)");
println!("cargo:rustc-check-cfg=cfg(ossl300)");
println!("cargo:rustc-check-cfg=cfg(ossl310)");
println!("cargo:rustc-check-cfg=cfg(ossl320)");
println!("cargo:rustc-check-cfg=cfg(ossl330)");
if env::var("DEP_OPENSSL_LIBRESSL").is_ok() {
println!("cargo:rustc-cfg=libressl");
}
if env::var("DEP_OPENSSL_BORINGSSL").is_ok() {
println!("cargo:rustc-cfg=boringssl");
return;
}
if env::var("DEP_OPENSSL_AWSLC").is_ok() {
println!("cargo:rustc-cfg=awslc");
}
if let Ok(v) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") {
@@ -67,6 +110,21 @@ fn main() {
if version >= 0x3_07_00_00_0 {
println!("cargo:rustc-cfg=libressl370");
}
if version >= 0x3_08_00_00_0 {
println!("cargo:rustc-cfg=libressl380");
}
if version >= 0x3_08_02_00_0 {
println!("cargo:rustc-cfg=libressl382");
}
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 version >= 0x4_01_00_00_0 {
println!("cargo:rustc-cfg=libressl410");
}
}
if let Ok(vars) = env::var("DEP_OPENSSL_CONF") {
@@ -96,67 +154,20 @@ fn main() {
if version >= 0x1_01_01_00_0 {
println!("cargo:rustc-cfg=ossl111");
}
if version >= 0x1_01_01_04_0 {
println!("cargo:rustc-cfg=ossl111d");
}
if version >= 0x3_00_00_00_0 {
println!("cargo:rustc-cfg=ossl300");
}
if version >= 0x3_01_00_00_0 {
println!("cargo:rustc-cfg=ossl310");
}
}
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 >= 0x3_02_00_00_0 {
println!("cargo:rustc-cfg=ossl320");
}
if version >= 0x2_06_01_00_0 {
println!("cargo:rustc-cfg=libressl261");
}
if version >= 0x2_07_00_00_0 {
println!("cargo:rustc-cfg=libressl270");
}
if version >= 0x2_07_01_00_0 {
println!("cargo:rustc-cfg=libressl271");
}
if version >= 0x2_07_03_00_0 {
println!("cargo:rustc-cfg=libressl273");
}
if version >= 0x2_08_00_00_0 {
println!("cargo:rustc-cfg=libressl280");
}
if version >= 0x2_09_01_00_0 {
println!("cargo:rustc-cfg=libressl291");
}
if version >= 0x3_02_01_00_0 {
println!("cargo:rustc-cfg=libressl321");
}
if version >= 0x3_03_02_00_0 {
println!("cargo:rustc-cfg=libressl332");
}
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");
if version >= 0x3_03_00_00_0 {
println!("cargo:rustc-cfg=ossl330");
}
}
}
+12 -8
View File
@@ -23,7 +23,11 @@
//! # Examples
#![cfg_attr(
all(not(boringssl), not(osslconf = "OPENSSL_NO_DEPRECATED_3_0")),
all(
not(boringssl),
not(awslc),
not(osslconf = "OPENSSL_NO_DEPRECATED_3_0")
),
doc = r#"\
## AES IGE
```rust
@@ -65,7 +69,7 @@ use libc::{c_int, c_uint};
use std::mem::MaybeUninit;
use std::ptr;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use crate::symm::Mode;
use openssl_macros::corresponds;
@@ -77,7 +81,7 @@ pub struct KeyError(());
pub struct AesKey(ffi::AES_KEY);
cfg_if! {
if #[cfg(boringssl)] {
if #[cfg(any(boringssl, awslc))] {
type AesBitType = c_uint;
type AesSizeType = usize;
} else {
@@ -95,7 +99,7 @@ impl AesKey {
#[corresponds(AES_set_encrypt_key)]
pub fn new_encrypt(key: &[u8]) -> Result<AesKey, KeyError> {
unsafe {
assert!(key.len() <= c_int::max_value() as usize / 8);
assert!(key.len() <= c_int::MAX as usize / 8);
let mut aes_key = MaybeUninit::uninit();
let r = ffi::AES_set_encrypt_key(
@@ -119,7 +123,7 @@ impl AesKey {
#[corresponds(AES_set_decrypt_key)]
pub fn new_decrypt(key: &[u8]) -> Result<AesKey, KeyError> {
unsafe {
assert!(key.len() <= c_int::max_value() as usize / 8);
assert!(key.len() <= c_int::MAX as usize / 8);
let mut aes_key = MaybeUninit::uninit();
let r = ffi::AES_set_decrypt_key(
@@ -155,7 +159,7 @@ impl AesKey {
///
/// Panics if `in_` is not the same length as `out`, if that length is not a multiple of 16, or if
/// `iv` is not at least 32 bytes.
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
#[corresponds(AES_ige_encrypt)]
pub fn aes_ige(in_: &[u8], out: &mut [u8], key: &AesKey, iv: &mut [u8], mode: Mode) {
@@ -263,12 +267,12 @@ mod test {
use hex::FromHex;
use super::*;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use crate::symm::Mode;
// From https://www.mgp25.com/AESIGE/
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
fn ige_vector_1() {
let raw_key = "000102030405060708090A0B0C0D0E0F";
+22 -22
View File
@@ -165,7 +165,7 @@ impl Asn1Type {
/// [`diff`]: struct.Asn1TimeRef.html#method.diff
/// [`Asn1TimeRef`]: struct.Asn1TimeRef.html
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
pub struct TimeDiff {
/// Difference in days
pub days: c_int,
@@ -198,7 +198,7 @@ foreign_type_and_impl_send_sync! {
impl Asn1TimeRef {
/// Find difference between two times
#[corresponds(ASN1_TIME_diff)]
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
pub fn diff(&self, compare: &Self) -> Result<TimeDiff, ErrorStack> {
let mut days = 0;
let mut secs = 0;
@@ -214,7 +214,7 @@ impl Asn1TimeRef {
/// Compare two times
#[corresponds(ASN1_TIME_compare)]
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
pub fn compare(&self, other: &Self) -> Result<Ordering, ErrorStack> {
let d = self.diff(other)?;
if d.days > 0 || d.secs > 0 {
@@ -228,7 +228,7 @@ impl Asn1TimeRef {
}
}
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
impl PartialEq for Asn1TimeRef {
fn eq(&self, other: &Asn1TimeRef) -> bool {
self.diff(other)
@@ -237,7 +237,7 @@ impl PartialEq for Asn1TimeRef {
}
}
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
impl PartialEq<Asn1Time> for Asn1TimeRef {
fn eq(&self, other: &Asn1Time) -> bool {
self.diff(other)
@@ -246,8 +246,8 @@ impl PartialEq<Asn1Time> for Asn1TimeRef {
}
}
#[cfg(ossl102)]
impl<'a> PartialEq<Asn1Time> for &'a Asn1TimeRef {
#[cfg(any(ossl102, boringssl, awslc))]
impl PartialEq<Asn1Time> for &Asn1TimeRef {
fn eq(&self, other: &Asn1Time) -> bool {
self.diff(other)
.map(|t| t.days == 0 && t.secs == 0)
@@ -255,22 +255,22 @@ impl<'a> PartialEq<Asn1Time> for &'a Asn1TimeRef {
}
}
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
impl PartialOrd for Asn1TimeRef {
fn partial_cmp(&self, other: &Asn1TimeRef) -> Option<Ordering> {
self.compare(other).ok()
}
}
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
impl PartialOrd<Asn1Time> for Asn1TimeRef {
fn partial_cmp(&self, other: &Asn1Time) -> Option<Ordering> {
self.compare(other).ok()
}
}
#[cfg(ossl102)]
impl<'a> PartialOrd<Asn1Time> for &'a Asn1TimeRef {
#[cfg(any(ossl102, boringssl, awslc))]
impl PartialOrd<Asn1Time> for &Asn1TimeRef {
fn partial_cmp(&self, other: &Asn1Time) -> Option<Ordering> {
self.compare(other).ok()
}
@@ -351,9 +351,9 @@ impl Asn1Time {
/// Creates a new time corresponding to the specified X509 time string.
///
/// Requires OpenSSL 1.1.1 or newer.
/// Requires BoringSSL or OpenSSL 1.1.1 or newer.
#[corresponds(ASN1_TIME_set_string_X509)]
#[cfg(ossl111)]
#[cfg(any(ossl111, boringssl, awslc))]
pub fn from_str_x509(s: &str) -> Result<Asn1Time, ErrorStack> {
unsafe {
let s = CString::new(s).unwrap();
@@ -366,7 +366,7 @@ impl Asn1Time {
}
}
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
impl PartialEq for Asn1Time {
fn eq(&self, other: &Asn1Time) -> bool {
self.diff(other)
@@ -375,7 +375,7 @@ impl PartialEq for Asn1Time {
}
}
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
impl PartialEq<Asn1TimeRef> for Asn1Time {
fn eq(&self, other: &Asn1TimeRef) -> bool {
self.diff(other)
@@ -384,7 +384,7 @@ impl PartialEq<Asn1TimeRef> for Asn1Time {
}
}
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
impl<'a> PartialEq<&'a Asn1TimeRef> for Asn1Time {
fn eq(&self, other: &&'a Asn1TimeRef) -> bool {
self.diff(other)
@@ -393,21 +393,21 @@ impl<'a> PartialEq<&'a Asn1TimeRef> for Asn1Time {
}
}
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
impl PartialOrd for Asn1Time {
fn partial_cmp(&self, other: &Asn1Time) -> Option<Ordering> {
self.compare(other).ok()
}
}
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
impl PartialOrd<Asn1TimeRef> for Asn1Time {
fn partial_cmp(&self, other: &Asn1TimeRef) -> Option<Ordering> {
self.compare(other).ok()
}
}
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
impl<'a> PartialOrd<&'a Asn1TimeRef> for Asn1Time {
fn partial_cmp(&self, other: &&'a Asn1TimeRef) -> Option<Ordering> {
self.compare(other).ok()
@@ -737,7 +737,7 @@ impl fmt::Debug for Asn1ObjectRef {
}
cfg_if! {
if #[cfg(any(ossl110, libressl273, boringssl))] {
if #[cfg(any(ossl110, libressl273, boringssl, awslc))] {
use ffi::ASN1_STRING_get0_data;
} else {
#[allow(bad_style)]
@@ -808,7 +808,7 @@ mod tests {
}
#[test]
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
fn time_eq() {
let a = Asn1Time::from_str("99991231235959Z").unwrap();
let b = Asn1Time::from_str("99991231235959Z").unwrap();
@@ -827,7 +827,7 @@ mod tests {
}
#[test]
#[cfg(ossl102)]
#[cfg(any(ossl102, boringssl, awslc))]
fn time_ord() {
let a = Asn1Time::from_str("99991231235959Z").unwrap();
let b = Asn1Time::from_str("99991231235959Z").unwrap();
+2 -2
View File
@@ -11,7 +11,7 @@ use openssl_macros::corresponds;
/// Panics if the input length or computed output length overflow a signed C integer.
#[corresponds(EVP_EncodeBlock)]
pub fn encode_block(src: &[u8]) -> String {
assert!(src.len() <= c_int::max_value() as usize);
assert!(src.len() <= c_int::MAX as usize);
let src_len = src.len() as LenType;
let len = encoded_len(src_len).unwrap();
@@ -42,7 +42,7 @@ pub fn decode_block(src: &str) -> Result<Vec<u8>, ErrorStack> {
return Ok(vec![]);
}
assert!(src.len() <= c_int::max_value() as usize);
assert!(src.len() <= c_int::MAX as usize);
let src_len = src.len() as LenType;
let len = decoded_len(src_len).unwrap();
+5 -5
View File
@@ -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);
@@ -21,7 +21,7 @@ impl<'a> MemBioSlice<'a> {
pub fn new(buf: &'a [u8]) -> Result<MemBioSlice<'a>, ErrorStack> {
ffi::init();
assert!(buf.len() <= c_int::max_value() as usize);
assert!(buf.len() <= c_int::MAX as usize);
let bio = unsafe {
cvt_p(BIO_new_mem_buf(
buf.as_ptr() as *const _,
@@ -67,14 +67,14 @@ impl MemBio {
}
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub unsafe fn from_ptr(bio: *mut ffi::BIO) -> MemBio {
MemBio(bio)
}
}
cfg_if! {
if #[cfg(any(ossl102, boringssl))] {
if #[cfg(any(ossl102, boringssl, awslc))] {
use ffi::BIO_new_mem_buf;
} else {
#[allow(bad_style)]
@@ -93,4 +93,4 @@ mod tests {
let b = MemBio::new().unwrap();
assert_eq!(b.get_buf(), &[]);
}
}
}
+48 -33
View File
@@ -37,18 +37,15 @@ use crate::{cvt, cvt_n, cvt_p, LenType};
use openssl_macros::corresponds;
cfg_if! {
if #[cfg(any(ossl110, libressl350))] {
if #[cfg(any(ossl110, libressl350, awslc))] {
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,
BN_get_rfc3526_prime_1536, BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192, BN_is_negative,
};
} else if #[cfg(boringssl)] {
use ffi::BN_is_negative;
} else {
use ffi::{
get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536,
get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048,
get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072,
@@ -64,6 +61,19 @@ cfg_if! {
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl350))] {
use ffi::{
BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768
};
} else if #[cfg(not(any(boringssl, awslc)))] {
use ffi::{
get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
};
}
}
/// Options for the most significant bits of a randomly generated `BigNum`.
pub struct MsbOption(c_int);
@@ -187,7 +197,7 @@ impl BigNumRef {
pub fn div_word(&mut self, w: u32) -> Result<u64, ErrorStack> {
unsafe {
let r = ffi::BN_div_word(self.as_ptr(), w.into());
if r == ffi::BN_ULONG::max_value() {
if r == ffi::BN_ULONG::MAX {
Err(ErrorStack::get())
} else {
Ok(r.into())
@@ -201,7 +211,7 @@ impl BigNumRef {
pub fn mod_word(&self, w: u32) -> Result<u64, ErrorStack> {
unsafe {
let r = ffi::BN_mod_word(self.as_ptr(), w.into());
if r == ffi::BN_ULONG::max_value() {
if r == ffi::BN_ULONG::MAX {
Err(ErrorStack::get())
} else {
Ok(r.into())
@@ -337,14 +347,14 @@ impl BigNumRef {
/// Returns `true` is `self` is even.
#[corresponds(BN_is_even)]
#[cfg(any(ossl110, boringssl, libressl350))]
#[cfg(any(ossl110, boringssl, libressl350, awslc))]
pub fn is_even(&self) -> bool {
!self.is_odd()
}
/// Returns `true` is `self` is odd.
#[corresponds(BN_is_odd)]
#[cfg(any(ossl110, boringssl, libressl350))]
#[cfg(any(ossl110, boringssl, libressl350, awslc))]
pub fn is_odd(&self) -> bool {
unsafe { ffi::BN_is_odd(self.as_ptr()) == 1 }
}
@@ -655,7 +665,6 @@ impl BigNumRef {
/// Places into `self` the modular square root of `a` such that `self^2 = a (mod p)`
#[corresponds(BN_mod_sqrt)]
#[cfg(ossl110)]
pub fn mod_sqrt(
&mut self,
a: &BigNumRef,
@@ -848,7 +857,7 @@ impl BigNumRef {
/// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
/// ```
#[corresponds(BN_bn2binpad)]
#[cfg(any(ossl110, libressl340, boringssl))]
#[cfg(any(ossl110, libressl340, boringssl, awslc))]
pub fn to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack> {
let mut v = Vec::with_capacity(pad_to as usize);
unsafe {
@@ -987,7 +996,7 @@ impl BigNum {
///
/// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
#[corresponds(BN_get_rfc2409_prime_768)]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub fn get_rfc2409_prime_768() -> Result<BigNum, ErrorStack> {
unsafe {
ffi::init();
@@ -1001,7 +1010,7 @@ impl BigNum {
///
/// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
#[corresponds(BN_get_rfc2409_prime_1024)]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub fn get_rfc2409_prime_1024() -> Result<BigNum, ErrorStack> {
unsafe {
ffi::init();
@@ -1109,7 +1118,7 @@ impl BigNum {
pub fn from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> {
unsafe {
ffi::init();
assert!(n.len() <= LenType::max_value() as usize);
assert!(n.len() <= LenType::MAX as usize);
cvt_p(ffi::BN_bin2bn(
n.as_ptr(),
@@ -1137,7 +1146,7 @@ impl BigNum {
#[corresponds(BN_bin2bn)]
pub fn copy_from_slice(&mut self, n: &[u8]) -> Result<(), ErrorStack> {
unsafe {
assert!(n.len() <= LenType::max_value() as usize);
assert!(n.len() <= LenType::MAX as usize);
cvt_p(ffi::BN_bin2bn(n.as_ptr(), n.len() as LenType, self.0))?;
Ok(())
@@ -1229,7 +1238,7 @@ impl Ord for BigNumRef {
impl PartialOrd for BigNum {
fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
self.deref().partial_cmp(oth.deref())
Some(self.cmp(oth))
}
}
@@ -1273,7 +1282,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 {
@@ -1285,7 +1294,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 {
@@ -1297,7 +1306,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 {
@@ -1310,7 +1319,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 {
@@ -1323,7 +1332,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 {
@@ -1336,7 +1345,7 @@ impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef {
delegate!(Rem, rem);
impl<'a> Shl<i32> for &'a BigNumRef {
impl Shl<i32> for &BigNumRef {
type Output = BigNum;
fn shl(self, n: i32) -> BigNum {
@@ -1346,7 +1355,7 @@ impl<'a> Shl<i32> for &'a BigNumRef {
}
}
impl<'a> Shl<i32> for &'a BigNum {
impl Shl<i32> for &BigNum {
type Output = BigNum;
fn shl(self, n: i32) -> BigNum {
@@ -1354,7 +1363,7 @@ impl<'a> Shl<i32> for &'a BigNum {
}
}
impl<'a> Shr<i32> for &'a BigNumRef {
impl Shr<i32> for &BigNumRef {
type Output = BigNum;
fn shr(self, n: i32) -> BigNum {
@@ -1364,7 +1373,7 @@ impl<'a> Shr<i32> for &'a BigNumRef {
}
}
impl<'a> Shr<i32> for &'a BigNum {
impl Shr<i32> for &BigNum {
type Output = BigNum;
fn shr(self, n: i32) -> BigNum {
@@ -1372,7 +1381,7 @@ impl<'a> Shr<i32> for &'a BigNum {
}
}
impl<'a> Neg for &'a BigNumRef {
impl Neg for &BigNumRef {
type Output = BigNum;
fn neg(self) -> BigNum {
@@ -1380,7 +1389,7 @@ impl<'a> Neg for &'a BigNumRef {
}
}
impl<'a> Neg for &'a BigNum {
impl Neg for &BigNum {
type Output = BigNum;
fn neg(self) -> BigNum {
@@ -1490,21 +1499,27 @@ mod tests {
assert!(b.is_const_time())
}
#[cfg(ossl110)]
#[test]
fn test_mod_sqrt() {
let mut ctx = BigNumContext::new().unwrap();
let s = BigNum::from_hex_str("47A8DD7626B9908C80ACD7E0D3344D69").unwrap();
let p = BigNum::from_hex_str("81EF47265B58BCE5").unwrap();
let s = BigNum::from_hex_str("2").unwrap();
let p = BigNum::from_hex_str("7DEB1").unwrap();
let mut sqrt = BigNum::new().unwrap();
let mut out = BigNum::new().unwrap();
out.mod_sqrt(&s, &p, &mut ctx).unwrap();
assert_eq!(out, BigNum::from_hex_str("7C6D179E19B97BDD").unwrap());
// Square the root because OpenSSL randomly returns one of 2E42C or 4FA85
sqrt.mod_sqrt(&s, &p, &mut ctx).unwrap();
out.mod_sqr(&sqrt, &p, &mut ctx).unwrap();
assert!(out == s);
let s = BigNum::from_hex_str("3").unwrap();
let p = BigNum::from_hex_str("5").unwrap();
assert!(out.mod_sqrt(&s, &p, &mut ctx).is_err());
}
#[test]
#[cfg(any(ossl110, boringssl, libressl350))]
#[cfg(any(ossl110, boringssl, libressl350, awslc))]
fn test_odd_even() {
let a = BigNum::from_u32(17).unwrap();
let b = BigNum::from_u32(18).unwrap();
+87 -26
View File
@@ -17,7 +17,7 @@ use std::ops::{Deref, DerefMut};
use std::ptr;
cfg_if! {
if #[cfg(any(boringssl, ossl110, libressl273))] {
if #[cfg(any(boringssl, ossl110, libressl273, awslc))] {
use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
} else {
use libc::c_int;
@@ -161,12 +161,16 @@ impl Cipher {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cbc() as *mut _) }
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub fn aes_128_xts() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_xts() as *mut _) }
}
#[cfg(not(boringssl))]
pub fn aes_256_xts() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_xts() as *mut _) }
}
pub fn aes_128_ctr() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ctr() as *mut _) }
}
@@ -195,13 +199,12 @@ impl Cipher {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ccm() as *mut _) }
}
#[cfg(not(boringssl))]
pub fn aes_128_ofb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ofb() as *mut _) }
}
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(ossl110)]
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
pub fn aes_128_ocb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ocb() as *mut _) }
}
@@ -258,7 +261,7 @@ impl Cipher {
}
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(ossl110)]
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
pub fn aes_192_ocb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ocb() as *mut _) }
}
@@ -315,7 +318,7 @@ impl Cipher {
}
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(ossl110)]
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
pub fn aes_256_ocb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ocb() as *mut _) }
}
@@ -343,13 +346,11 @@ impl Cipher {
}
#[cfg(not(osslconf = "OPENSSL_NO_BF"))]
#[cfg(not(boringssl))]
pub fn bf_cfb64() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_bf_cfb64() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_BF"))]
#[cfg(not(boringssl))]
pub fn bf_ofb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_bf_ofb() as *mut _) }
}
@@ -366,100 +367,160 @@ impl Cipher {
unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3() as *mut _) }
}
pub fn des_ede3_ecb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ecb() as *mut _) }
}
pub fn des_ede3_cbc() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cbc() as *mut _) }
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub fn des_ede3_cfb8() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb8() as *mut _) }
}
#[cfg(not(any(boringssl, awslc)))]
pub fn des_ede3_cfb64() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) }
}
#[cfg(not(any(boringssl, awslc)))]
pub fn des_ede3_ofb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ofb() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
pub fn rc4() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) }
}
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))]
#[cfg(not(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")))]
#[cfg(not(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")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia128_cbc() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cbc() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia128_ofb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ofb() as *mut _) }
}
#[cfg(not(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")))]
#[cfg(not(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")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia192_cbc() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cbc() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia192_ofb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ofb() as *mut _) }
}
#[cfg(not(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")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia256_ecb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ecb() as *mut _) }
}
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAST")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia256_cbc() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cbc() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia256_ofb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ofb() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn cast5_cfb64() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cfb64() as *mut _) }
}
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAST")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn cast5_ecb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ecb() as *mut _) }
}
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_IDEA")))]
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn cast5_cbc() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cbc() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn cast5_ofb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ofb() as *mut _) }
}
#[cfg(not(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")))]
#[cfg(not(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")))]
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn idea_cbc() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_idea_cbc() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn idea_ofb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_idea_ofb() as *mut _) }
}
#[cfg(all(any(ossl110, libressl310), not(osslconf = "OPENSSL_NO_CHACHA")))]
pub fn chacha20() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_chacha20() as *mut _) }
}
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
#[cfg(all(any(ossl110, libressl360, awslc), not(osslconf = "OPENSSL_NO_CHACHA")))]
pub fn chacha20_poly1305() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_chacha20_poly1305() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
#[cfg(not(boringssl))]
pub fn seed_cbc() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_seed_cbc() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
#[cfg(not(boringssl))]
pub fn seed_cfb128() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_seed_cfb128() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
#[cfg(not(boringssl))]
pub fn seed_ecb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_seed_ecb() as *mut _) }
}
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
#[cfg(not(boringssl))]
pub fn seed_ofb() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_seed_ofb() as *mut _) }
}
@@ -545,4 +606,4 @@ mod test {
fn test_cipher_fetch_properties() {
assert!(Cipher::fetch(None, "AES-128-GCM", Some("provider=gibberish")).is_err());
}
}
}
+182 -11
View File
@@ -52,7 +52,7 @@
use crate::cipher::CipherRef;
use crate::error::ErrorStack;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef};
use crate::{cvt, cvt_p};
#[cfg(ossl102)]
@@ -105,6 +105,14 @@ impl CipherCtx {
}
impl CipherCtxRef {
#[corresponds(EVP_CIPHER_CTX_copy)]
pub fn copy(&mut self, src: &CipherCtxRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_CIPHER_CTX_copy(self.as_ptr(), src.as_ptr()))?;
Ok(())
}
}
/// Initializes the context for encryption.
///
/// Normally this is called once to set all of the cipher, key, and IV. However, this process can be split up
@@ -194,7 +202,7 @@ impl CipherCtxRef {
/// Panics if `pub_keys` is not the same size as `encrypted_keys`, the IV buffer is smaller than the cipher's IV
/// size, or if an IV is provided before the cipher.
#[corresponds(EVP_SealInit)]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub fn seal_init<T>(
&mut self,
type_: Option<&CipherRef>,
@@ -251,7 +259,7 @@ impl CipherCtxRef {
/// Panics if the IV buffer is smaller than the cipher's required IV size or if the IV is provided before the
/// cipher.
#[corresponds(EVP_OpenInit)]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub fn open_init<T>(
&mut self,
type_: Option<&CipherRef>,
@@ -320,12 +328,8 @@ 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))]
#[cfg(not(any(boringssl, awslc)))]
pub fn rand_key(&self, buf: &mut [u8]) -> Result<(), ErrorStack> {
assert!(buf.len() >= self.key_length());
@@ -540,7 +544,7 @@ impl CipherCtxRef {
/// # Panics
///
/// Panics if `output` doesn't contain enough space for data to be
/// written as specified by [`Self::minimal_output_size`].
/// written.
#[corresponds(EVP_CipherUpdate)]
pub fn cipher_update(
&mut self,
@@ -574,6 +578,7 @@ impl CipherCtxRef {
/// buffer size control is maintained by the caller.
///
/// # Safety
///
/// The caller is expected to provide `output` buffer
/// large enough to contain correct number of bytes. For streaming
/// ciphers the output buffer size should be at least as big as
@@ -687,6 +692,7 @@ impl CipherCtxRef {
/// the output buffer size check removed.
///
/// # Safety
///
/// The caller is expected to provide `output` buffer
/// large enough to contain correct number of bytes. For streaming
/// ciphers the output buffer can be empty, for block ciphers the
@@ -722,11 +728,11 @@ impl CipherCtxRef {
mod test {
use super::*;
use crate::{cipher::Cipher, rand::rand_bytes};
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use std::slice;
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn seal_open() {
let private_pem = include_bytes!("../test/rsa.pem");
let public_pem = include_bytes!("../test/rsa.pem.pub");
@@ -803,8 +809,173 @@ mod test {
aes_128_cbc(cipher);
}
#[cfg(not(boringssl))]
#[test]
fn default_aes_128_ccm() {
// from https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/mac/ccmtestvectors.zip
let cipher = Cipher::aes_128_ccm();
aes_ccm(
cipher,
"26511fb51fcfa75cb4b44da75a6e5a0e",
"ea98ec44f5a86715014783172e",
"4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
"e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
"1bf0ba0ebb20d8edba59f29a9371750c9c714078f73c335d",
"2f1322ac69b848b001476323aed84c47",
);
}
#[cfg(not(boringssl))]
#[test]
fn default_aes_192_ccm() {
// from https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/mac/ccmtestvectors.zip
let cipher = Cipher::aes_192_ccm();
aes_ccm(
cipher,
"26511fb51fcfa75cb4b44da75a6e5a0eb8d9c8f3b906f886",
"ea98ec44f5a86715014783172e",
"4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
"e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
"30c154c616946eccc2e241d336ad33720953e449a0e6b0f0",
"dbf8e9464909bdf337e48093c082a10b",
);
}
#[cfg(not(boringssl))]
#[test]
fn default_aes_256_ccm() {
// from https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/mac/ccmtestvectors.zip
let cipher = Cipher::aes_256_ccm();
aes_ccm(
cipher,
"314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e",
"3542fbe0f59a6d5f3abf619b7d",
"c5b3d71312ea14f2f8fae5bd1a453192b6604a45db75c5ed",
"dd4531f158a2fa3bc8a339f770595048f4a42bc1b03f2e824efc6ba4985119d8",
"39c2e8f6edfe663b90963b98eb79e2d4f7f28a5053ae8881",
"567a6b4426f1667136bed4a5e32a2bc1",
);
}
#[cfg(not(boringssl))]
fn aes_ccm(
cipher: &CipherRef,
key: &'static str,
iv: &'static str,
pt: &'static str,
aad: &'static str,
ct: &'static str,
tag: &'static str,
) {
let key = hex::decode(key).unwrap();
let iv = hex::decode(iv).unwrap();
let pt = hex::decode(pt).unwrap();
let ct = hex::decode(ct).unwrap();
let aad = hex::decode(aad).unwrap();
let tag = hex::decode(tag).unwrap();
let mut ctx = CipherCtx::new().unwrap();
ctx.encrypt_init(Some(cipher), None, None).unwrap();
ctx.set_iv_length(iv.len()).unwrap();
ctx.set_tag_length(tag.len()).unwrap();
ctx.encrypt_init(None, Some(&key), Some(&iv)).unwrap();
ctx.set_data_len(pt.len()).unwrap();
let mut buf = vec![];
ctx.cipher_update(&aad, None).unwrap();
ctx.cipher_update_vec(&pt, &mut buf).unwrap();
ctx.cipher_final_vec(&mut buf).unwrap();
assert_eq!(buf, ct);
let mut out_tag = vec![0u8; tag.len()];
ctx.tag(&mut out_tag).unwrap();
assert_eq!(tag, out_tag);
ctx.decrypt_init(Some(cipher), None, None).unwrap();
ctx.set_iv_length(iv.len()).unwrap();
ctx.set_tag(&tag).unwrap();
ctx.decrypt_init(None, Some(&key), Some(&iv)).unwrap();
ctx.set_data_len(pt.len()).unwrap();
let mut buf = vec![];
ctx.cipher_update(&aad, None).unwrap();
ctx.cipher_update_vec(&ct, &mut buf).unwrap();
// Some older libraries don't support calling EVP_CipherFinal/EVP_DecryptFinal for CCM
// https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption#Authenticated_Decryption_using_CCM_mode
#[cfg(any(ossl111, awslc, boringssl))]
ctx.cipher_final_vec(&mut buf).unwrap();
assert_eq!(buf, pt);
}
#[cfg(not(any(boringssl, awslc)))]
#[test]
fn default_aes_128_xts() {
// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/aes/XTSTestVectors.zip
let cipher = Cipher::aes_128_xts();
aes_xts(
cipher,
"a1b90cba3f06ac353b2c343876081762090923026e91771815f29dab01932f2f",
"4faef7117cda59c66e4b92013e768ad5",
"ebabce95b14d3c8d6fb350390790311c",
"778ae8b43cb98d5a825081d5be471c63",
);
}
#[cfg(not(boringssl))]
#[test]
fn default_aes_256_xts() {
// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/aes/XTSTestVectors.zip
let cipher = Cipher::aes_256_xts();
aes_xts(cipher, "1ea661c58d943a0e4801e42f4b0947149e7f9f8e3e68d0c7505210bd311a0e7cd6e13ffdf2418d8d1911c004cda58da3d619b7e2b9141e58318eea392cf41b08", "adf8d92627464ad2f0428e84a9f87564", "2eedea52cd8215e1acc647e810bbc3642e87287f8d2e57e36c0a24fbc12a202e", "cbaad0e2f6cea3f50b37f934d46a9b130b9d54f07e34f36af793e86f73c6d7db");
}
#[cfg(not(boringssl))]
fn aes_xts(
cipher: &CipherRef,
key: &'static str,
i: &'static str,
pt: &'static str,
ct: &'static str,
) {
let key = hex::decode(key).unwrap();
let i = hex::decode(i).unwrap();
let pt = hex::decode(pt).unwrap();
let ct = hex::decode(ct).unwrap();
let mut ctx = CipherCtx::new().unwrap();
ctx.encrypt_init(Some(cipher), Some(&key), Some(&i))
.unwrap();
let mut buf = vec![];
ctx.cipher_update_vec(&pt, &mut buf).unwrap();
ctx.cipher_final_vec(&mut buf).unwrap();
assert_eq!(ct, buf);
ctx.decrypt_init(Some(cipher), Some(&key), Some(&i))
.unwrap();
let mut buf = vec![];
ctx.cipher_update_vec(&ct, &mut buf).unwrap();
ctx.cipher_final_vec(&mut buf).unwrap();
assert_eq!(pt, buf);
}
#[test]
fn test_stream_ciphers() {
#[cfg(not(boringssl))]
{
test_stream_cipher(Cipher::aes_128_cfb1());
test_stream_cipher(Cipher::aes_128_cfb8());
test_stream_cipher(Cipher::aes_128_cfb128());
test_stream_cipher(Cipher::aes_192_cfb1());
test_stream_cipher(Cipher::aes_192_cfb8());
test_stream_cipher(Cipher::aes_192_cfb128());
test_stream_cipher(Cipher::aes_256_cfb1());
test_stream_cipher(Cipher::aes_256_cfb8());
test_stream_cipher(Cipher::aes_256_cfb128());
}
test_stream_cipher(Cipher::aes_192_ctr());
test_stream_cipher(Cipher::aes_256_ctr());
}
+7 -9
View File
@@ -20,6 +20,8 @@ use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
bitflags! {
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct CMSOptions : c_uint {
const TEXT = ffi::CMS_TEXT;
const CMS_NOCERTS = ffi::CMS_NOCERTS;
@@ -473,14 +475,10 @@ mod test {
// check verification result - this is an invalid signature
// defined in openssl crypto/cms/cms.h
const CMS_R_CERTIFICATE_VERIFY_ERROR: i32 = 100;
match res {
Err(es) => {
let error_array = es.errors();
assert_eq!(1, error_array.len());
let code = error_array[0].code();
assert_eq!(ffi::ERR_GET_REASON(code), CMS_R_CERTIFICATE_VERIFY_ERROR);
}
_ => panic!("expected CMS verification error, got Ok()"),
}
let es = res.unwrap_err();
let error_array = es.errors();
assert_eq!(1, error_array.len());
let code = error_array[0].reason_code();
assert_eq!(code, CMS_R_CERTIFICATE_VERIFY_ERROR);
}
}
+2 -2
View File
@@ -8,7 +8,7 @@ foreign_type_and_impl_send_sync! {
pub struct ConfRef;
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, libressl400, awslc)))]
mod methods {
use super::Conf;
use crate::cvt_p;
@@ -61,5 +61,5 @@ mod methods {
}
}
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, libressl400, awslc)))]
pub use methods::*;
+3 -3
View File
@@ -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);
+21 -2
View File
@@ -269,7 +269,7 @@ where
}
cfg_if! {
if #[cfg(any(ossl110, libressl270, boringssl))] {
if #[cfg(any(ossl110, libressl270, boringssl, awslc))] {
use ffi::{DH_set0_pqg, DH_get0_pqg, DH_get0_key, DH_set0_key};
} else {
#[allow(bad_style)]
@@ -334,6 +334,8 @@ cfg_if! {
mod tests {
use crate::bn::BigNum;
use crate::dh::Dh;
#[cfg(all(not(any(boringssl, awslc)), ossl110))]
use crate::pkey::PKey;
use crate::ssl::{SslContext, SslMethod};
#[test]
@@ -382,6 +384,23 @@ mod tests {
assert_eq!(dh.generator(), &generator);
}
#[test]
#[cfg(all(not(any(boringssl, awslc)), ossl110))]
fn test_from_dhx_serializes_q() {
let p = BigNum::from_hex_str("00ad107e1e9123a9d0d660faa79559c51fa20d64e5683b9fd1b54b1597b61d0a75e6fa141df95a56dbaf9a3c407ba1df15eb3d688a309c180e1de6b85a1274a0a66d3f8152ad6ac2129037c9edefda4df8d91e8fef55b7394b7ad5b7d0b6c12207c9f98d11ed34dbf6c6ba0b2c8bbc27be6a00e0a0b9c49708b3bf8a317091883681286130bc8985db1602e714415d9330278273c7de31efdc7310f7121fd5a07415987d9adc0a486dcdf93acc44328387315d75e198c641a480cd86a1b9e587e8be60e69cc928b2b9c52172e413042e9b23f10b0e16e79763c9b53dcf4ba80a29e3fb73c16b8e75b97ef363e2ffa31f71cf9de5384e71b81c0ac4dffe0c10e64f").unwrap();
let g = BigNum::from_hex_str("00ac4032ef4f2d9ae39df30b5c8ffdac506cdebe7b89998caf74866a08cfe4ffe3a6824a4e10b9a6f0dd921f01a70c4afaab739d7700c29f52c57db17c620a8652be5e9001a8d66ad7c17669101999024af4d027275ac1348bb8a762d0521bc98ae247150422ea1ed409939d54da7460cdb5f6c6b250717cbef180eb34118e98d119529a45d6f834566e3025e316a330efbb77a86f0c1ab15b051ae3d428c8f8acb70a8137150b8eeb10e183edd19963ddd9e263e4770589ef6aa21e7f5f2ff381b539cce3409d13cd566afbb48d6c019181e1bcfe94b30269edfe72fe9b6aa4bd7b5a0f1c71cfff4c19c418e1f6ec017981bc087f2a7065b384b890d3191f2bfa").unwrap();
let q = BigNum::from_hex_str("00801c0d34c58d93fe997177101f80535a4738cebcbf389a99b36371eb")
.unwrap();
let y = BigNum::from_hex_str("0082c165bb576243ecf46d58c3d1501616955fca0320fa95ea11d2e6c1b9cf217676720dc1c08c85bf20c4d232b60a29a1e51c7b773bc645014587c525c86151b30d75486ec7b6c98efb5f74955b83116d01d0af1232af89213c2de574369d701aba9357300b920d3d8b98252d46c46952c16a5f33554b38317809c7b9add4701f5c158c1b7035e9fe39366ececb90d2896b78c523c4a577287ef5ba7a2663ed58aa20b5ec66e30f316610dfaa38583e495ab6af771c284387e660edbef4edb872e2e80e1d244ee95622e76d028e61c1e887c2aa792717362139f4dd26eafd49b2366eeb2350b01fe1b56022a2809e379559c37b375ba01c4eaacc14fd1b247837").unwrap();
let dh = Dh::from_params(p, g, q).unwrap();
let dh = dh.set_public_key(y).unwrap();
// Verify that 'q' is serialized in the public key.
let pkey = PKey::from_dhx(dh).unwrap();
assert_eq!(pkey.public_key_to_der().unwrap(), b"\x30\x82\x03\x44\x30\x82\x02\x36\x06\x07\x2a\x86\x48\xce\x3e\x02\x01\x30\x82\x02\x29\x02\x82\x01\x01\x00\xad\x10\x7e\x1e\x91\x23\xa9\xd0\xd6\x60\xfa\xa7\x95\x59\xc5\x1f\xa2\x0d\x64\xe5\x68\x3b\x9f\xd1\xb5\x4b\x15\x97\xb6\x1d\x0a\x75\xe6\xfa\x14\x1d\xf9\x5a\x56\xdb\xaf\x9a\x3c\x40\x7b\xa1\xdf\x15\xeb\x3d\x68\x8a\x30\x9c\x18\x0e\x1d\xe6\xb8\x5a\x12\x74\xa0\xa6\x6d\x3f\x81\x52\xad\x6a\xc2\x12\x90\x37\xc9\xed\xef\xda\x4d\xf8\xd9\x1e\x8f\xef\x55\xb7\x39\x4b\x7a\xd5\xb7\xd0\xb6\xc1\x22\x07\xc9\xf9\x8d\x11\xed\x34\xdb\xf6\xc6\xba\x0b\x2c\x8b\xbc\x27\xbe\x6a\x00\xe0\xa0\xb9\xc4\x97\x08\xb3\xbf\x8a\x31\x70\x91\x88\x36\x81\x28\x61\x30\xbc\x89\x85\xdb\x16\x02\xe7\x14\x41\x5d\x93\x30\x27\x82\x73\xc7\xde\x31\xef\xdc\x73\x10\xf7\x12\x1f\xd5\xa0\x74\x15\x98\x7d\x9a\xdc\x0a\x48\x6d\xcd\xf9\x3a\xcc\x44\x32\x83\x87\x31\x5d\x75\xe1\x98\xc6\x41\xa4\x80\xcd\x86\xa1\xb9\xe5\x87\xe8\xbe\x60\xe6\x9c\xc9\x28\xb2\xb9\xc5\x21\x72\xe4\x13\x04\x2e\x9b\x23\xf1\x0b\x0e\x16\xe7\x97\x63\xc9\xb5\x3d\xcf\x4b\xa8\x0a\x29\xe3\xfb\x73\xc1\x6b\x8e\x75\xb9\x7e\xf3\x63\xe2\xff\xa3\x1f\x71\xcf\x9d\xe5\x38\x4e\x71\xb8\x1c\x0a\xc4\xdf\xfe\x0c\x10\xe6\x4f\x02\x82\x01\x01\x00\xac\x40\x32\xef\x4f\x2d\x9a\xe3\x9d\xf3\x0b\x5c\x8f\xfd\xac\x50\x6c\xde\xbe\x7b\x89\x99\x8c\xaf\x74\x86\x6a\x08\xcf\xe4\xff\xe3\xa6\x82\x4a\x4e\x10\xb9\xa6\xf0\xdd\x92\x1f\x01\xa7\x0c\x4a\xfa\xab\x73\x9d\x77\x00\xc2\x9f\x52\xc5\x7d\xb1\x7c\x62\x0a\x86\x52\xbe\x5e\x90\x01\xa8\xd6\x6a\xd7\xc1\x76\x69\x10\x19\x99\x02\x4a\xf4\xd0\x27\x27\x5a\xc1\x34\x8b\xb8\xa7\x62\xd0\x52\x1b\xc9\x8a\xe2\x47\x15\x04\x22\xea\x1e\xd4\x09\x93\x9d\x54\xda\x74\x60\xcd\xb5\xf6\xc6\xb2\x50\x71\x7c\xbe\xf1\x80\xeb\x34\x11\x8e\x98\xd1\x19\x52\x9a\x45\xd6\xf8\x34\x56\x6e\x30\x25\xe3\x16\xa3\x30\xef\xbb\x77\xa8\x6f\x0c\x1a\xb1\x5b\x05\x1a\xe3\xd4\x28\xc8\xf8\xac\xb7\x0a\x81\x37\x15\x0b\x8e\xeb\x10\xe1\x83\xed\xd1\x99\x63\xdd\xd9\xe2\x63\xe4\x77\x05\x89\xef\x6a\xa2\x1e\x7f\x5f\x2f\xf3\x81\xb5\x39\xcc\xe3\x40\x9d\x13\xcd\x56\x6a\xfb\xb4\x8d\x6c\x01\x91\x81\xe1\xbc\xfe\x94\xb3\x02\x69\xed\xfe\x72\xfe\x9b\x6a\xa4\xbd\x7b\x5a\x0f\x1c\x71\xcf\xff\x4c\x19\xc4\x18\xe1\xf6\xec\x01\x79\x81\xbc\x08\x7f\x2a\x70\x65\xb3\x84\xb8\x90\xd3\x19\x1f\x2b\xfa\x02\x1d\x00\x80\x1c\x0d\x34\xc5\x8d\x93\xfe\x99\x71\x77\x10\x1f\x80\x53\x5a\x47\x38\xce\xbc\xbf\x38\x9a\x99\xb3\x63\x71\xeb\x03\x82\x01\x06\x00\x02\x82\x01\x01\x00\x82\xc1\x65\xbb\x57\x62\x43\xec\xf4\x6d\x58\xc3\xd1\x50\x16\x16\x95\x5f\xca\x03\x20\xfa\x95\xea\x11\xd2\xe6\xc1\xb9\xcf\x21\x76\x76\x72\x0d\xc1\xc0\x8c\x85\xbf\x20\xc4\xd2\x32\xb6\x0a\x29\xa1\xe5\x1c\x7b\x77\x3b\xc6\x45\x01\x45\x87\xc5\x25\xc8\x61\x51\xb3\x0d\x75\x48\x6e\xc7\xb6\xc9\x8e\xfb\x5f\x74\x95\x5b\x83\x11\x6d\x01\xd0\xaf\x12\x32\xaf\x89\x21\x3c\x2d\xe5\x74\x36\x9d\x70\x1a\xba\x93\x57\x30\x0b\x92\x0d\x3d\x8b\x98\x25\x2d\x46\xc4\x69\x52\xc1\x6a\x5f\x33\x55\x4b\x38\x31\x78\x09\xc7\xb9\xad\xd4\x70\x1f\x5c\x15\x8c\x1b\x70\x35\xe9\xfe\x39\x36\x6e\xce\xcb\x90\xd2\x89\x6b\x78\xc5\x23\xc4\xa5\x77\x28\x7e\xf5\xba\x7a\x26\x63\xed\x58\xaa\x20\xb5\xec\x66\xe3\x0f\x31\x66\x10\xdf\xaa\x38\x58\x3e\x49\x5a\xb6\xaf\x77\x1c\x28\x43\x87\xe6\x60\xed\xbe\xf4\xed\xb8\x72\xe2\xe8\x0e\x1d\x24\x4e\xe9\x56\x22\xe7\x6d\x02\x8e\x61\xc1\xe8\x87\xc2\xaa\x79\x27\x17\x36\x21\x39\xf4\xdd\x26\xea\xfd\x49\xb2\x36\x6e\xeb\x23\x50\xb0\x1f\xe1\xb5\x60\x22\xa2\x80\x9e\x37\x95\x59\xc3\x7b\x37\x5b\xa0\x1c\x4e\xaa\xcc\x14\xfd\x1b\x24\x78\x37");
}
#[test]
#[cfg(ossl102)]
fn test_dh_stored_restored() {
@@ -475,6 +494,6 @@ mod tests {
let g = BigNum::from_hex_str("02").unwrap();
let dh2 = Dh::from_pqg(p, None, g).unwrap();
assert!(dh1.check_key().unwrap());
assert!(!dh2.check_key().unwrap());
assert!(matches!(dh2.check_key(), Ok(false) | Err(_)));
}
}
+5 -5
View File
@@ -7,7 +7,7 @@
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use libc::c_int;
use std::fmt;
use std::mem;
@@ -186,9 +186,9 @@ where
}
}
}
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
type BitType = libc::c_uint;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
type BitType = c_int;
impl Dsa<Params> {
@@ -315,7 +315,7 @@ impl<T> fmt::Debug for Dsa<T> {
}
cfg_if! {
if #[cfg(any(ossl110, libressl273, boringssl))] {
if #[cfg(any(ossl110, libressl273, boringssl, awslc))] {
use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg};
} else {
#[allow(bad_style)]
@@ -494,7 +494,7 @@ impl DsaSigRef {
}
cfg_if! {
if #[cfg(any(ossl110, libressl273, boringssl))] {
if #[cfg(any(ossl110, libressl273, boringssl, awslc))] {
use ffi::{DSA_SIG_set0, DSA_SIG_get0};
} else {
#[allow(bad_style)]
+10 -10
View File
@@ -30,7 +30,7 @@ use crate::{cvt, cvt_n, cvt_p, init};
use openssl_macros::corresponds;
cfg_if! {
if #[cfg(not(boringssl))] {
if #[cfg(not(any(boringssl, awslc)))] {
use std::ffi::CString;
use crate::string::OpensslString;
}
@@ -195,7 +195,7 @@ impl EcGroupRef {
/// a term in the polynomial. It will be set to 3 `1`s or 5 `1`s depending on
/// using a trinomial or pentanomial.
#[corresponds(EC_GROUP_get_curve_GF2m)]
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_EC2M")))]
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn components_gf2m(
&self,
p: &mut BigNumRef,
@@ -473,7 +473,7 @@ impl EcPointRef {
/// Serializes the point to a hexadecimal string representation.
#[corresponds(EC_POINT_point2hex)]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub fn to_hex_str(
&self,
group: &EcGroupRef,
@@ -519,7 +519,7 @@ impl EcPointRef {
/// Places affine coordinates of a curve over a prime field in the provided
/// `x` and `y` `BigNum`s.
#[corresponds(EC_POINT_get_affine_coordinates)]
#[cfg(any(ossl111, boringssl, libressl350))]
#[cfg(any(ossl111, boringssl, libressl350, awslc))]
pub fn affine_coordinates(
&self,
group: &EcGroupRef,
@@ -586,7 +586,7 @@ impl EcPointRef {
/// 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)]
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_EC2M")))]
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn affine_coordinates_gf2m(
&self,
group: &EcGroupRef,
@@ -662,7 +662,7 @@ impl EcPoint {
/// Creates point from a hexadecimal string representation
#[corresponds(EC_POINT_hex2point)]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub fn from_hex_str(
group: &EcGroupRef,
s: &str,
@@ -1171,7 +1171,7 @@ mod test {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn point_hex_str() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
@@ -1260,7 +1260,7 @@ mod test {
assert!(ec_key.check_key().is_ok());
}
#[cfg(any(ossl111, boringssl, libressl350))]
#[cfg(any(ossl111, boringssl, libressl350, awslc))]
#[test]
fn get_affine_coordinates() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
@@ -1324,7 +1324,7 @@ mod test {
}
#[test]
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_EC2M")))]
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
fn is_on_curve() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let mut ctx = BigNumContext::new().unwrap();
@@ -1336,7 +1336,7 @@ mod test {
}
#[test]
#[cfg(any(boringssl, ossl111, libressl350))]
#[cfg(any(boringssl, ossl111, libressl350, awslc))]
fn asn1_flag() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let flag = group.asn1_flag();
+6 -6
View File
@@ -32,7 +32,7 @@ impl EcdsaSig {
T: HasPrivate,
{
unsafe {
assert!(data.len() <= c_int::max_value() as usize);
assert!(data.len() <= c_int::MAX as usize);
let sig = cvt_p(ffi::ECDSA_do_sign(
data.as_ptr(),
data.len() as LenType,
@@ -77,7 +77,7 @@ impl EcdsaSigRef {
T: HasPublic,
{
unsafe {
assert!(data.len() <= c_int::max_value() as usize);
assert!(data.len() <= c_int::MAX as usize);
cvt_n(ffi::ECDSA_do_verify(
data.as_ptr(),
data.len() as LenType,
@@ -110,7 +110,7 @@ impl EcdsaSigRef {
}
cfg_if! {
if #[cfg(any(ossl110, libressl273, boringssl))] {
if #[cfg(any(ossl110, libressl273, boringssl, awslc))] {
use ffi::{ECDSA_SIG_set0, ECDSA_SIG_get0};
} else {
#[allow(bad_style)]
@@ -158,7 +158,7 @@ mod test {
}
#[test]
#[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)]
#[cfg_attr(osslconf = "OPENSSL_NO_EC", ignore)]
fn sign_and_verify() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let private_key = EcKey::generate(&group).unwrap();
@@ -186,7 +186,7 @@ mod test {
}
#[test]
#[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)]
#[cfg_attr(osslconf = "OPENSSL_NO_EC", ignore)]
fn check_private_components() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let private_key = EcKey::generate(&group).unwrap();
@@ -206,7 +206,7 @@ mod test {
}
#[test]
#[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)]
#[cfg_attr(osslconf = "OPENSSL_NO_EC", ignore)]
fn serialize_deserialize() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let private_key = EcKey::generate(&group).unwrap();
+13 -13
View File
@@ -40,7 +40,7 @@
//! assert_eq!(&*decrypted, data);
//! ```
#[cfg(any(ossl102, libressl310))]
use libc::{c_int, c_void};
use libc::c_int;
use std::{marker::PhantomData, ptr};
use crate::error::ErrorStack;
@@ -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);
@@ -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, awslc))]
pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
@@ -174,7 +174,7 @@ impl<'a> Encrypter<'a> {
cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
self.pctx,
p as *mut c_void,
p,
label.len() as c_int,
))
.map(|_| ())
@@ -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);
@@ -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, awslc))]
pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
@@ -378,7 +378,7 @@ impl<'a> Decrypter<'a> {
cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
self.pctx,
p as *mut c_void,
p,
label.len() as c_int,
))
.map(|_| ())
@@ -478,7 +478,7 @@ mod test {
use hex::FromHex;
use crate::encrypt::{Decrypter, Encrypter};
#[cfg(any(ossl102, libressl310))]
#[cfg(any(ossl102, libressl310, boringssl, awslc))]
use crate::hash::MessageDigest;
use crate::pkey::PKey;
use crate::rsa::{Padding, Rsa};
@@ -513,7 +513,7 @@ mod test {
}
#[test]
#[cfg(any(ossl102, libressl310))]
#[cfg(any(ossl102, libressl310, boringssl, awslc))]
fn rsa_encrypt_decrypt_with_sha256() {
let key = include_bytes!("../test/rsa.pem");
let private_key = Rsa::private_key_from_pem(key).unwrap();
+2 -2
View File
@@ -75,7 +75,7 @@ impl Seal {
///
/// Panics if `output.len() < input.len() + block_size` where `block_size` is
/// the block size of the cipher (see `Cipher::block_size`), or if
/// `output.len() > c_int::max_value()`.
/// `output.len() > c_int::MAX`.
pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
self.ctx.cipher_update(input, Some(output))
}
@@ -130,7 +130,7 @@ impl Open {
///
/// Panics if `output.len() < input.len() + block_size` where
/// `block_size` is the block size of the cipher (see `Cipher::block_size`),
/// or if `output.len() > c_int::max_value()`.
/// or if `output.len() > c_int::MAX`.
pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
self.ctx.cipher_update(input, Some(output))
}
+12 -12
View File
@@ -18,7 +18,7 @@
use cfg_if::cfg_if;
use libc::{c_char, c_int};
use std::borrow::Cow;
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
use std::convert::TryInto;
use std::error;
use std::ffi::CStr;
@@ -27,9 +27,9 @@ use std::io;
use std::ptr;
use std::str;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
type ErrType = libc::c_ulong;
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
type ErrType = libc::c_uint;
/// Collection of [`Error`]s from OpenSSL.
@@ -127,13 +127,13 @@ impl Error {
let data = if flags & ffi::ERR_TXT_STRING != 0 {
let bytes = CStr::from_ptr(data as *const _).to_bytes();
let data = str::from_utf8(bytes).unwrap();
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
let data = if flags & ffi::ERR_TXT_MALLOCED != 0 {
Cow::Owned(data.to_string())
} else {
Cow::Borrowed(data)
};
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
let data = Cow::Borrowed(data);
Some(data)
} else {
@@ -204,9 +204,9 @@ impl Error {
#[cfg(not(ossl300))]
fn put_error(&self) {
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
let line = self.line;
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
let line = self.line.try_into().unwrap();
unsafe {
ffi::ERR_put_error(
@@ -238,7 +238,7 @@ impl Error {
/// Returns the raw OpenSSL error constant for the library reporting the
/// error.
// On BoringSSL ERR_GET_{LIB,FUNC,REASON} are `unsafe`, but on
// On AWS-LC and BoringSSL ERR_GET_{LIB,FUNC,REASON} are `unsafe`, but on
// OpenSSL/LibreSSL they're safe.
#[allow(unused_unsafe)]
pub fn library_code(&self) -> libc::c_int {
@@ -263,7 +263,7 @@ impl Error {
}
/// Returns the raw OpenSSL error constant for the reason for the error.
// On BoringSSL ERR_GET_{LIB,FUNC,REASON} are `unsafe`, but on
// On AWS-LC and BoringSSL ERR_GET_{LIB,FUNC,REASON} are `unsafe`, but on
// OpenSSL/LibreSSL they're safe.
#[allow(unused_unsafe)]
pub fn reason_code(&self) -> libc::c_int {
@@ -310,7 +310,7 @@ impl fmt::Debug for Error {
}
impl fmt::Display for Error {
// On BoringSSL ERR_GET_{LIB,FUNC,REASON} are `unsafe`, but on
// On AWS-LC and BoringSSL ERR_GET_{LIB,FUNC,REASON} are `unsafe`, but on
// OpenSSL/LibreSSL they're safe.
#[allow(unused_unsafe)]
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -410,9 +410,9 @@ mod tests {
fn test_error_library_code() {
let stack = Nid::create("not-an-oid", "invalid", "invalid").unwrap_err();
let errors = stack.errors();
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
assert_eq!(errors[0].library_code(), ffi::ERR_LIB_ASN1);
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
assert_eq!(errors[0].library_code(), ffi::ERR_LIB_OBJ as libc::c_int);
}
}
+115 -28
View File
@@ -41,9 +41,10 @@ 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))] {
if #[cfg(any(ossl110, boringssl, libressl382, awslc))] {
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
} else {
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
@@ -65,11 +66,9 @@ 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<MessageDigest> {
ffi::init();
unsafe {
let ptr = ffi::EVP_get_digestbynid(type_.as_raw());
if ptr.is_null() {
@@ -81,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<MessageDigest> {
ffi::init();
let name = CString::new(name).ok()?;
@@ -127,37 +123,37 @@ impl MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha512()) }
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
pub fn sha3_224() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_224()) }
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
pub fn sha3_256() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_256()) }
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
pub fn sha3_384() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_384()) }
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
pub fn sha3_512() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_512()) }
}
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
pub fn shake_128() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_shake128()) }
}
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
pub fn shake_256() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_shake256()) }
}
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_RMD160")))]
#[cfg(not(osslconf = "OPENSSL_NO_RMD160"))]
pub fn ripemd160() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_ripemd160()) }
}
@@ -198,6 +194,8 @@ unsafe impl Send for MessageDigest {}
enum State {
Reset,
Updated,
#[cfg(ossl330)]
Squeeze,
Finalized,
}
@@ -264,6 +262,8 @@ impl Hasher {
Updated => {
self.finish()?;
}
#[cfg(ossl330)]
Squeeze => (),
Finalized => (),
}
unsafe {
@@ -278,6 +278,19 @@ impl Hasher {
if self.state == Finalized {
self.init()?;
}
#[cfg(ossl330)]
if self.state == Squeeze {
// [`EVP_DigestUpdate`], depending on the implementation, may allow Updates after Squeezes.
// But, [FIPS 202], as shown in Figure 7, has a distinguished absorbing phase followed by a squeezing phase.
// Indeed, the [`sha3.c`] implmentation disallows Updates after Squeezes.
// For consistency, we always return an error when Update is called after Squeeze.
//
// [`EVP_DigestUpdate`]: https://github.com/openssl/openssl/blob/b3bb214720f20f3b126ae4b9c330e9a48b835415/crypto/evp/digest.c#L385-L393
// [FIPS 202]: https://dx.doi.org/10.6028/NIST.FIPS.202
// [`sha3.c`]: https://github.com/openssl/openssl/blob/b3bb214720f20f3b126ae4b9c330e9a48b835415/crypto/sha/sha3.c#L52-L63
let errors = ErrorStack::get();
return Err(errors);
}
unsafe {
cvt(ffi::EVP_DigestUpdate(
self.ctx,
@@ -289,15 +302,30 @@ impl Hasher {
Ok(())
}
/// Squeezes buf out of the hasher. Can be called multiple times, unlike `finish_xof`.
/// The output will be as long as the buf.
#[cfg(ossl330)]
pub fn squeeze_xof(&mut self, buf: &mut [u8]) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_DigestSqueeze(
self.ctx,
buf.as_mut_ptr(),
buf.len(),
))?;
self.state = Squeeze;
Ok(())
}
}
/// Returns the hash of the data written and resets the non-XOF hasher.
pub fn finish(&mut self) -> Result<DigestBytes, ErrorStack> {
if self.state == Finalized {
self.init()?;
}
unsafe {
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
let mut len = ffi::EVP_MAX_MD_SIZE;
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
let mut len = ffi::EVP_MAX_MD_SIZE as u32;
let mut buf = [0; ffi::EVP_MAX_MD_SIZE as usize];
cvt(ffi::EVP_DigestFinal_ex(
@@ -315,7 +343,7 @@ impl Hasher {
/// Writes the hash of the data into the supplied buf and resets the XOF hasher.
/// The hash will be as long as the buf.
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
pub fn finish_xof(&mut self, buf: &mut [u8]) -> Result<(), ErrorStack> {
if self.state == Finalized {
self.init()?;
@@ -453,7 +481,7 @@ pub fn hash(t: MessageDigest, data: &[u8]) -> Result<DigestBytes, ErrorStack> {
/// assert_eq!(buf, spec);
/// ```
///
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
pub fn hash_xof(t: MessageDigest, data: &[u8], buf: &mut [u8]) -> Result<(), ErrorStack> {
let mut h = Hasher::new(t)?;
h.update(data)?;
@@ -472,7 +500,7 @@ mod tests {
assert_eq!(hex::encode(res), hashtest.1);
}
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
fn hash_xof_test(hashtype: MessageDigest, hashtest: &(&str, &str)) {
let expected = Vec::from_hex(hashtest.1).unwrap();
let mut buf = vec![0; expected.len()];
@@ -485,6 +513,21 @@ mod tests {
assert_eq!(buf, expected);
}
/// Squeezes the expected length by doing two squeezes.
#[cfg(ossl330)]
fn hash_xof_squeeze_test(hashtype: MessageDigest, hashtest: &(&str, &str)) {
let data = Vec::from_hex(hashtest.0).unwrap();
let mut h = Hasher::new(hashtype).unwrap();
h.update(&data).unwrap();
let expected = Vec::from_hex(hashtest.1).unwrap();
let mut buf = vec![0; expected.len()];
assert!(expected.len() > 10);
h.squeeze_xof(&mut buf[..10]).unwrap();
h.squeeze_xof(&mut buf[10..]).unwrap();
assert_eq!(buf, expected);
}
fn hash_recycle_test(h: &mut Hasher, hashtest: &(&str, &str)) {
h.write_all(&Vec::from_hex(hashtest.0).unwrap()).unwrap();
let res = h.finish().unwrap();
@@ -541,6 +584,40 @@ mod tests {
assert_eq!(&*res, &*null);
}
#[cfg(ossl330)]
#[test]
fn test_finish_then_squeeze() {
let digest = MessageDigest::shake_128();
let mut h = Hasher::new(digest).unwrap();
let mut buf = vec![0; digest.size()];
h.finish_xof(&mut buf).unwrap();
h.squeeze_xof(&mut buf)
.expect_err("squeezing after finalize should fail");
}
#[cfg(ossl330)]
#[test]
fn test_squeeze_then_update() {
let digest = MessageDigest::shake_128();
let data = Vec::from_hex(MD5_TESTS[6].0).unwrap();
let mut h = Hasher::new(digest).unwrap();
let mut buf = vec![0; digest.size()];
h.squeeze_xof(&mut buf).unwrap();
h.update(&data)
.expect_err("updating after squeeze should fail");
}
#[cfg(ossl330)]
#[test]
fn test_squeeze_then_finalize() {
let digest = MessageDigest::shake_128();
let mut h = Hasher::new(digest).unwrap();
let mut buf = vec![0; digest.size()];
h.squeeze_xof(&mut buf).unwrap();
h.finish_xof(&mut buf)
.expect_err("finalize after squeeze should fail");
}
#[test]
#[allow(clippy::redundant_clone)]
fn test_clone() {
@@ -624,7 +701,7 @@ mod tests {
);
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
#[test]
fn test_sha3_224() {
let tests = [(
@@ -644,7 +721,7 @@ mod tests {
);
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
#[test]
fn test_sha3_256() {
let tests = [(
@@ -664,7 +741,7 @@ mod tests {
);
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
#[test]
fn test_sha3_384() {
let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
@@ -684,7 +761,7 @@ mod tests {
);
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
#[test]
fn test_sha3_512() {
let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
@@ -704,7 +781,7 @@ mod tests {
);
}
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
#[test]
fn test_shake_128() {
let tests = [(
@@ -714,17 +791,22 @@ mod tests {
for test in tests.iter() {
hash_xof_test(MessageDigest::shake_128(), test);
#[cfg(ossl330)]
hash_xof_squeeze_test(MessageDigest::shake_128(), test);
}
assert_eq!(MessageDigest::shake_128().block_size(), 168);
#[cfg(ossl111)]
assert_eq!(MessageDigest::shake_128().size(), 16);
#[cfg(awslc)]
assert_eq!(MessageDigest::shake_128().size(), 0);
assert_eq!(
MessageDigest::shake_128().type_().as_raw(),
Nid::SHAKE128.as_raw()
);
}
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
#[test]
fn test_shake_256() {
let tests = [(
@@ -734,10 +816,15 @@ mod tests {
for test in tests.iter() {
hash_xof_test(MessageDigest::shake_256(), test);
#[cfg(ossl330)]
hash_xof_squeeze_test(MessageDigest::shake_256(), test);
}
assert_eq!(MessageDigest::shake_256().block_size(), 136);
#[cfg(ossl111)]
assert_eq!(MessageDigest::shake_256().size(), 32);
#[cfg(awslc)]
assert_eq!(MessageDigest::shake_256().size(), 0);
assert_eq!(
MessageDigest::shake_256().type_().as_raw(),
Nid::SHAKE256.as_raw()
@@ -745,7 +832,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(osslconf = "OPENSSL_NO_RMD160"))]
#[cfg_attr(ossl300, ignore)]
fn test_ripemd160() {
#[cfg(ossl300)]
+176
View File
@@ -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::<ffi::OSSL_PARAM>::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);
}
}
+53 -18
View File
@@ -19,8 +19,9 @@
//! openssl = { version = "0.10", features = ["vendored"] }
//! ```
//!
//! The vendored copy will not be configured to automatically find the system's root certificates, but the
//! `openssl-probe` crate can be used to do that instead.
//! The vendored copy will be configured to automatically find a configuration and root certificates at `/usr/local/ssl`.
//! This path can be overridden with an environment variable (see the manual section below).
//! Alternatively, the `openssl-probe` crate can be used to find root certificates at runtime.
//!
//! ## Automatic
//!
@@ -38,16 +39,19 @@
//! $ sudo pkgin install openssl
//!
//! # Arch Linux
//! $ sudo pacman -S pkg-config openssl
//! $ sudo pacman -S pkgconf openssl
//!
//! # Debian and Ubuntu
//! $ sudo apt-get install pkg-config libssl-dev
//!
//! # Fedora
//! $ sudo dnf install pkg-config openssl-devel
//! $ sudo dnf install pkgconf perl-FindBin perl-IPC-Cmd openssl-devel
//!
//! # Alpine Linux
//! $ apk add pkgconfig openssl-dev
//! $ apk add pkgconf openssl-dev
//!
//! # openSUSE
//! $ sudo zypper in libopenssl-devel
//! ```
//!
//! ## Manual
@@ -56,14 +60,20 @@
//! override the automatic detection logic.
//!
//! * `OPENSSL_DIR` - If specified, the directory of an OpenSSL installation. The directory should contain `lib` and
//! `include` subdirectories containing the libraries and headers respectively.
//! `include` subdirectories containing the libraries and headers respectively.
//! * `OPENSSL_LIB_DIR` and `OPENSSL_INCLUDE_DIR` - If specified, the directories containing the OpenSSL libraries and
//! headers respectively. This can be used if the OpenSSL installation is split in a nonstandard directory layout.
//! headers respectively. This can be used if the OpenSSL installation is split in a nonstandard directory layout.
//! * `OPENSSL_STATIC` - If set, the crate will statically link to OpenSSL rather than dynamically link.
//! * `OPENSSL_LIBS` - If set, a `:`-separated list of library names to link to (e.g. `ssl:crypto`). This can be used
//! if nonstandard library names were used for whatever reason.
//! if nonstandard library names were used for whatever reason.
//! * `OPENSSL_NO_VENDOR` - If set, always find OpenSSL in the system, even if the `vendored` feature is enabled.
//!
//! If the `vendored` Cargo feature is enabled, the following environment variable can also be used to further configure
//! the OpenSSL build.
//!
//! * `OPENSSL_CONFIG_DIR` - If set, the copy of OpenSSL built by the `openssl-src` crate will be configured to look for
//! configuration files and root certificates in this directory.
//!
//! Additionally, these variables can be prefixed with the upper-cased target architecture (e.g.
//! `X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR`), which can be useful when cross compiling.
//!
@@ -124,9 +134,11 @@
#[doc(inline)]
pub use ffi::init;
use libc::c_int;
extern crate openssl_sys as ffi;
use libc::c_int;
#[cfg(ossl300)]
use libc::c_long;
use crate::error::ErrorStack;
#[macro_use]
@@ -141,7 +153,7 @@ pub mod base64;
pub mod bn;
pub mod cipher;
pub mod cipher_ctx;
#[cfg(all(not(boringssl), not(libressl), not(osslconf = "OPENSSL_NO_CMS")))]
#[cfg(all(not(libressl), not(osslconf = "OPENSSL_NO_CMS")))]
pub mod cms;
pub mod conf;
pub mod derive;
@@ -150,24 +162,25 @@ pub mod dsa;
pub mod ec;
pub mod ecdsa;
pub mod encrypt;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub mod envelope;
pub mod error;
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;
pub mod md_ctx;
pub mod memcmp;
pub mod nid;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_OCSP")))]
#[cfg(not(osslconf = "OPENSSL_NO_OCSP"))]
pub mod ocsp;
pub mod pkcs12;
pub mod pkcs5;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub mod pkcs7;
pub mod pkey;
pub mod pkey_ctx;
@@ -185,14 +198,14 @@ pub mod symm;
pub mod version;
pub mod x509;
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
type LenType = libc::size_t;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
type LenType = libc::c_int;
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
type SLenType = libc::ssize_t;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
type SLenType = libc::c_int;
#[inline]
@@ -204,6 +217,15 @@ fn cvt_p<T>(r: *mut T) -> Result<*mut T, ErrorStack> {
}
}
#[inline]
fn cvt_p_const<T>(r: *const T) -> Result<*const T, ErrorStack> {
if r.is_null() {
Err(ErrorStack::get())
} else {
Ok(r)
}
}
#[inline]
fn cvt(r: c_int) -> Result<c_int, ErrorStack> {
if r <= 0 {
@@ -213,6 +235,19 @@ fn cvt(r: c_int) -> Result<c_int, ErrorStack> {
}
}
// cvt_long is currently only used in functions that require openssl >= 3.0.0,
// so this cfg statement is used to avoid "unused function" errors when
// compiling with openssl < 3.0.0
#[inline]
#[cfg(ossl300)]
fn cvt_long(r: c_long) -> Result<c_long, ErrorStack> {
if r <= 0 {
Err(ErrorStack::get())
} else {
Ok(r)
}
}
#[inline]
fn cvt_n(r: c_int) -> Result<c_int, ErrorStack> {
if r < 0 {
+2 -2
View File
@@ -59,7 +59,7 @@ macro_rules! private_key_to_pem {
) -> Result<Vec<u8>, crate::error::ErrorStack> {
unsafe {
let bio = crate::bio::MemBio::new()?;
assert!(passphrase.len() <= ::libc::c_int::max_value() as usize);
assert!(passphrase.len() <= ::libc::c_int::MAX as usize);
cvt($f(bio.as_ptr(),
self.as_ptr(),
cipher.as_ptr(),
@@ -109,7 +109,7 @@ macro_rules! from_der {
use std::convert::TryInto;
unsafe {
ffi::init();
let len = ::std::cmp::min(der.len(), ::libc::c_long::max_value() as usize) as ::libc::c_long;
let len = ::std::cmp::min(der.len(), ::libc::c_long::MAX as usize) as ::libc::c_long;
crate::cvt_p($f(::std::ptr::null_mut(), &mut der.as_ptr(), len.try_into().unwrap()))
.map(|p| ::foreign_types::ForeignType::from_ptr(p))
}
+7 -7
View File
@@ -80,6 +80,7 @@ impl Md {
/// Returns the `Md` corresponding to an [`Nid`].
#[corresponds(EVP_get_digestbynid)]
pub fn from_nid(type_: Nid) -> Option<&'static MdRef> {
ffi::init();
unsafe {
let ptr = ffi::EVP_get_digestbynid(type_.as_raw());
if ptr.is_null() {
@@ -100,6 +101,7 @@ impl Md {
algorithm: &str,
properties: Option<&str>,
) -> Result<Self, ErrorStack> {
ffi::init();
let algorithm = CString::new(algorithm).unwrap();
let properties = properties.map(|s| CString::new(s).unwrap());
@@ -150,25 +152,25 @@ impl Md {
unsafe { MdRef::from_ptr(ffi::EVP_sha512() as *mut _) }
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380))]
#[inline]
pub fn sha3_224() -> &'static MdRef {
unsafe { MdRef::from_ptr(ffi::EVP_sha3_224() as *mut _) }
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380))]
#[inline]
pub fn sha3_256() -> &'static MdRef {
unsafe { MdRef::from_ptr(ffi::EVP_sha3_256() as *mut _) }
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380))]
#[inline]
pub fn sha3_384() -> &'static MdRef {
unsafe { MdRef::from_ptr(ffi::EVP_sha3_384() as *mut _) }
}
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380))]
#[inline]
pub fn sha3_512() -> &'static MdRef {
unsafe { MdRef::from_ptr(ffi::EVP_sha3_512() as *mut _) }
@@ -188,14 +190,12 @@ impl Md {
#[cfg(not(osslconf = "OPENSSL_NO_RMD160"))]
#[inline]
#[cfg(not(boringssl))]
pub fn ripemd160() -> &'static MdRef {
unsafe { MdRef::from_ptr(ffi::EVP_ripemd160() as *mut _) }
}
#[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM3")))]
#[inline]
#[cfg(not(boringssl))]
pub fn sm3() -> &'static MdRef {
unsafe { MdRef::from_ptr(ffi::EVP_sm3() as *mut _) }
}
@@ -244,4 +244,4 @@ mod test {
fn test_md_fetch_properties() {
assert!(Md::fetch(None, "SHA-256", Some("provider=gibberish")).is_err());
}
}
}
+21 -9
View File
@@ -52,7 +52,7 @@
//!
#![cfg_attr(
not(boringssl),
not(any(boringssl, awslc)),
doc = r#"\
Compute and verify an HMAC-SHA256
@@ -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;
@@ -93,7 +93,7 @@ use std::convert::TryFrom;
use std::ptr;
cfg_if! {
if #[cfg(any(ossl110, boringssl))] {
if #[cfg(any(ossl110, boringssl, libressl382, awslc))] {
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
} else {
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
@@ -258,7 +258,7 @@ impl MdCtxRef {
/// Requires OpenSSL 1.1.1 or newer.
#[corresponds(EVP_DigestFinalXOF)]
#[inline]
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
pub fn digest_final_xof(&mut self, out: &mut [u8]) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_DigestFinalXOF(
@@ -309,12 +309,21 @@ impl MdCtxRef {
#[inline]
pub fn digest_verify_final(&mut self, signature: &[u8]) -> Result<bool, ErrorStack> {
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]
+15 -13
View File
@@ -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<SignatureAlgorithms> {
@@ -120,11 +118,11 @@ impl Nid {
pub const UNDEF: Nid = Nid(ffi::NID_undef);
pub const ITU_T: Nid = Nid(ffi::NID_itu_t);
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub const CCITT: Nid = Nid(ffi::NID_ccitt);
pub const ISO: Nid = Nid(ffi::NID_iso);
pub const JOINT_ISO_ITU_T: Nid = Nid(ffi::NID_joint_iso_itu_t);
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub const JOINT_ISO_CCITT: Nid = Nid(ffi::NID_joint_iso_ccitt);
pub const MEMBER_BODY: Nid = Nid(ffi::NID_member_body);
pub const IDENTIFIED_ORGANIZATION: Nid = Nid(ffi::NID_identified_organization);
@@ -215,11 +213,13 @@ impl Nid {
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)]
#[cfg(any(ossl110, libressl))]
pub const BRAINPOOL_P256R1: Nid = Nid(ffi::NID_brainpoolP256r1);
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl))]
pub const BRAINPOOL_P320R1: Nid = Nid(ffi::NID_brainpoolP320r1);
#[cfg(any(ossl110, libressl))]
pub const BRAINPOOL_P384R1: Nid = Nid(ffi::NID_brainpoolP384r1);
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl))]
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);
@@ -1078,18 +1078,20 @@ impl Nid {
pub const SM2: Nid = Nid(ffi::NID_sm2);
#[cfg(any(ossl111, libressl291))]
pub const SM3: Nid = Nid(ffi::NID_sm3);
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
pub const SHA3_224: Nid = Nid(ffi::NID_sha3_224);
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
pub const SHA3_256: Nid = Nid(ffi::NID_sha3_256);
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
pub const SHA3_384: Nid = Nid(ffi::NID_sha3_384);
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl380, awslc))]
pub const SHA3_512: Nid = Nid(ffi::NID_sha3_512);
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
pub const SHAKE128: Nid = Nid(ffi::NID_shake128);
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
pub const SHAKE256: Nid = Nid(ffi::NID_shake256);
#[cfg(any(ossl110, libressl271, awslc))]
pub const CHACHA20_POLY1305: Nid = Nid(ffi::NID_chacha20_poly1305);
}
#[cfg(test)]
+14 -12
View File
@@ -15,18 +15,20 @@ use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
bitflags! {
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct OcspFlag: c_ulong {
const NO_CERTS = ffi::OCSP_NOCERTS;
const NO_INTERN = ffi::OCSP_NOINTERN;
const NO_CHAIN = ffi::OCSP_NOCHAIN;
const NO_VERIFY = ffi::OCSP_NOVERIFY;
const NO_EXPLICIT = ffi::OCSP_NOEXPLICIT;
const NO_CA_SIGN = ffi::OCSP_NOCASIGN;
const NO_DELEGATED = ffi::OCSP_NODELEGATED;
const NO_CHECKS = ffi::OCSP_NOCHECKS;
const TRUST_OTHER = ffi::OCSP_TRUSTOTHER;
const RESPID_KEY = ffi::OCSP_RESPID_KEY;
const NO_TIME = ffi::OCSP_NOTIME;
const NO_CERTS = ffi::OCSP_NOCERTS as c_ulong;
const NO_INTERN = ffi::OCSP_NOINTERN as c_ulong;
const NO_CHAIN = ffi::OCSP_NOCHAIN as c_ulong;
const NO_VERIFY = ffi::OCSP_NOVERIFY as c_ulong;
const NO_EXPLICIT = ffi::OCSP_NOEXPLICIT as c_ulong;
const NO_CA_SIGN = ffi::OCSP_NOCASIGN as c_ulong;
const NO_DELEGATED = ffi::OCSP_NODELEGATED as c_ulong;
const NO_CHECKS = ffi::OCSP_NOCHECKS as c_ulong;
const TRUST_OTHER = ffi::OCSP_TRUSTOTHER as c_ulong;
const RESPID_KEY = ffi::OCSP_RESPID_KEY as c_ulong;
const NO_TIME = ffi::OCSP_NOTIME as c_ulong;
}
}
@@ -120,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
+16 -3
View File
@@ -226,6 +226,8 @@ impl Pkcs12Builder {
pub fn build2(&self, password: &str) -> Result<Pkcs12, ErrorStack> {
unsafe {
let pass = CString::new(password).unwrap();
#[cfg(not(boringssl))]
let pass_len = pass.as_bytes().len();
let pass = pass.as_ptr();
let friendly_name = self.name.as_ref().map_or(ptr::null(), |p| p.as_ptr());
let pkey = self.pkey.as_ref().map_or(ptr::null(), |p| p.as_ptr());
@@ -259,7 +261,7 @@ impl Pkcs12Builder {
#[cfg(not(boringssl))]
// BoringSSL does not support overriding the MAC and will always
// use SHA-1
// use SHA-1.
{
let md_type = self
.mac_md
@@ -269,7 +271,7 @@ impl Pkcs12Builder {
cvt(ffi::PKCS12_set_mac(
pkcs12.as_ptr(),
pass,
-1,
pass_len.try_into().unwrap(),
ptr::null_mut(),
0,
self.mac_iter,
@@ -304,9 +306,20 @@ mod test {
let parsed = pkcs12.parse2("mypass").unwrap();
assert_eq!(
hex::encode(parsed.cert.unwrap().digest(MessageDigest::sha1()).unwrap()),
hex::encode(
parsed
.cert
.as_ref()
.unwrap()
.digest(MessageDigest::sha1())
.unwrap()
),
"59172d9313e84459bcff27f967e79e6e9217e584"
);
assert_eq!(
parsed.cert.as_ref().unwrap().alias(),
Some(b"foobar.com" as &[u8])
);
let chain = parsed.ca.unwrap();
assert_eq!(chain.len(), 1);
+9 -9
View File
@@ -1,13 +1,13 @@
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use libc::c_int;
use std::convert::TryInto;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use std::ptr;
use crate::cvt;
use crate::error::ErrorStack;
use crate::hash::MessageDigest;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use crate::symm::Cipher;
use openssl_macros::corresponds;
@@ -29,7 +29,7 @@ pub struct KeyIvPair {
/// `pbkdf2_hmac` or another more modern key derivation algorithm.
#[corresponds(EVP_BytesToKey)]
#[allow(clippy::useless_conversion)]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub fn bytes_to_key(
cipher: Cipher,
digest: MessageDigest,
@@ -38,7 +38,7 @@ pub fn bytes_to_key(
count: i32,
) -> Result<KeyIvPair, ErrorStack> {
unsafe {
assert!(data.len() <= c_int::max_value() as usize);
assert!(data.len() <= c_int::MAX as usize);
let salt_ptr = match salt {
Some(salt) => {
assert_eq!(salt.len(), ffi::PKCS5_SALT_LEN as usize);
@@ -115,7 +115,7 @@ pub fn pbkdf2_hmac(
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PBE_scrypt)]
#[cfg(any(ossl110, boringssl))]
#[cfg(all(any(ossl110, boringssl, awslc), not(osslconf = "OPENSSL_NO_SCRYPT")))]
#[allow(clippy::useless_conversion)]
pub fn scrypt(
pass: &[u8],
@@ -147,7 +147,7 @@ pub fn scrypt(
#[cfg(test)]
mod tests {
use crate::hash::MessageDigest;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use crate::symm::Cipher;
// Test vectors from
@@ -249,7 +249,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn bytes_to_key() {
let salt = [16_u8, 34_u8, 19_u8, 23_u8, 141_u8, 4_u8, 207_u8, 221_u8];
@@ -286,7 +286,7 @@ mod tests {
}
#[test]
#[cfg(any(ossl110, boringssl))]
#[cfg(any(ossl110, boringssl, awslc))]
fn scrypt() {
let pass = "pleaseletmein";
let salt = "SodiumChloride";
+134 -7
View File
@@ -4,16 +4,31 @@ use libc::c_int;
use std::mem;
use std::ptr;
use crate::asn1::Asn1ObjectRef;
use crate::bio::{MemBio, MemBioSlice};
use crate::error::ErrorStack;
use crate::nid::Nid;
use crate::pkey::{HasPrivate, PKeyRef};
use crate::stack::{Stack, StackRef};
use crate::stack::{Stack, StackRef, Stackable};
use crate::symm::Cipher;
use crate::util::ForeignTypeRefExt;
use crate::x509::store::X509StoreRef;
use crate::x509::{X509Ref, X509};
use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
foreign_type_and_impl_send_sync! {
type CType = ffi::PKCS7_SIGNER_INFO;
fn drop = ffi::PKCS7_SIGNER_INFO_free;
pub struct Pkcs7SignerInfo;
pub struct Pkcs7SignerInfoRef;
}
impl Stackable for Pkcs7SignerInfo {
type StackType = ffi::stack_st_PKCS7_SIGNER_INFO;
}
foreign_type_and_impl_send_sync! {
type CType = ffi::PKCS7;
fn drop = ffi::PKCS7_free;
@@ -27,7 +42,22 @@ foreign_type_and_impl_send_sync! {
pub struct Pkcs7Ref;
}
foreign_type_and_impl_send_sync! {
type CType = ffi::PKCS7_SIGNED;
fn drop = ffi::PKCS7_SIGNED_free;
/// A PKCS#7 signed data structure.
///
/// Contains signed data.
pub struct Pkcs7Signed;
/// Reference to `Pkcs7Signed`
pub struct Pkcs7SignedRef;
}
bitflags! {
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct Pkcs7Flags: c_int {
const TEXT = ffi::PKCS7_TEXT;
const NOCERTS = ffi::PKCS7_NOCERTS;
@@ -111,7 +141,7 @@ impl Pkcs7 {
certs.as_ptr(),
input_bio.as_ptr(),
cipher.as_ptr(),
flags.bits,
flags.bits(),
))
.map(Pkcs7)
}
@@ -141,7 +171,7 @@ impl Pkcs7 {
pkey.as_ptr(),
certs.as_ptr(),
input_bio.as_ptr(),
flags.bits,
flags.bits(),
))
.map(Pkcs7)
}
@@ -159,7 +189,7 @@ impl Pkcs7Ref {
output.as_ptr(),
self.as_ptr(),
input_bio.as_ptr(),
flags.bits,
flags.bits(),
))
.map(|_| output.get_buf().to_owned())
}
@@ -205,7 +235,7 @@ impl Pkcs7Ref {
pkey.as_ptr(),
cert.as_ptr(),
output.as_ptr(),
flags.bits,
flags.bits(),
))
.map(|_| output.get_buf().to_owned())
}
@@ -241,7 +271,7 @@ impl Pkcs7Ref {
store.as_ptr(),
indata_bio_ptr,
out_bio.as_ptr(),
flags.bits,
flags.bits(),
))
.map(|_| ())?
}
@@ -265,7 +295,7 @@ impl Pkcs7Ref {
let ptr = cvt_p(ffi::PKCS7_get0_signers(
self.as_ptr(),
certs.as_ptr(),
flags.bits,
flags.bits(),
))?;
// The returned stack is owned by the caller, but the certs inside are not! Our stack interface can't deal
@@ -279,11 +309,43 @@ impl Pkcs7Ref {
Ok(stack)
}
}
/// Return the type of a PKCS#7 structure as an Asn1Object
pub fn type_(&self) -> Option<&Asn1ObjectRef> {
unsafe {
let ptr = (*self.as_ptr()).type_;
Asn1ObjectRef::from_const_ptr_opt(ptr)
}
}
/// Get the signed data of a PKCS#7 structure of type PKCS7_SIGNED
pub fn signed(&self) -> Option<&Pkcs7SignedRef> {
unsafe {
if self.type_().map(|x| x.nid()) != Some(Nid::PKCS7_SIGNED) {
return None;
}
let signed_data = (*self.as_ptr()).d.sign;
Pkcs7SignedRef::from_const_ptr_opt(signed_data)
}
}
}
impl Pkcs7SignedRef {
/// Get the stack of certificates from the PKCS7_SIGNED object
pub fn certificates(&self) -> Option<&StackRef<X509>> {
unsafe {
self.as_ptr()
.as_ref()
.and_then(|x| x.cert.as_mut())
.and_then(|x| StackRef::<X509>::from_const_ptr_opt(x))
}
}
}
#[cfg(test)]
mod tests {
use crate::hash::MessageDigest;
use crate::nid::Nid;
use crate::pkcs7::{Pkcs7, Pkcs7Flags};
use crate::pkey::PKey;
use crate::stack::Stack;
@@ -305,6 +367,10 @@ mod tests {
let pkcs7 =
Pkcs7::encrypt(&certs, message.as_bytes(), cipher, flags).expect("should succeed");
assert_eq!(
pkcs7.type_().expect("PKCS7 should have a type").nid(),
Nid::PKCS7_ENVELOPED
);
let encrypted = pkcs7
.to_smime(message.as_bytes(), flags)
@@ -338,6 +404,10 @@ mod tests {
let pkcs7 =
Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed");
assert_eq!(
pkcs7.type_().expect("PKCS7 should have a type").nid(),
Nid::PKCS7_SIGNED
);
let signed = pkcs7
.to_smime(message.as_bytes(), flags)
@@ -382,6 +452,10 @@ mod tests {
let pkcs7 =
Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed");
assert_eq!(
pkcs7.type_().expect("PKCS7 should have a type").nid(),
Nid::PKCS7_SIGNED
);
let signed = pkcs7
.to_smime(message.as_bytes(), flags)
@@ -419,6 +493,10 @@ mod tests {
let pkcs7 =
Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed");
assert_eq!(
pkcs7.type_().expect("PKCS7 should have a type").nid(),
Nid::PKCS7_SIGNED
);
let signed = pkcs7
.to_smime(message.as_bytes(), flags)
@@ -443,4 +521,53 @@ mod tests {
assert!(result.is_err());
}
#[test]
fn signed_data_certificates() {
let cert = include_bytes!("../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
let mut extra_certs = Stack::<X509>::new().unwrap();
for cert in
X509::stack_from_pem(include_bytes!("../test/certs.pem")).expect("should succeed")
{
extra_certs.push(cert).expect("should succeed");
}
let message = "foo";
let flags = Pkcs7Flags::STREAM;
let pkey = include_bytes!("../test/key.pem");
let pkey = PKey::private_key_from_pem(pkey).unwrap();
let pkcs7 = Pkcs7::sign(&cert, &pkey, &extra_certs, message.as_bytes(), flags)
.expect("should succeed");
assert_eq!(
pkcs7.type_().expect("PKCS7 should have a type").nid(),
Nid::PKCS7_SIGNED
);
let signed_data_certs = pkcs7.signed().and_then(|x| x.certificates());
assert_eq!(signed_data_certs.expect("should succeed").len(), 3);
}
#[test]
fn signed_data_certificates_no_signed_data() {
let cert = include_bytes!("../test/certs.pem");
let cert = X509::from_pem(cert).unwrap();
let mut certs = Stack::new().unwrap();
certs.push(cert).unwrap();
let message: String = String::from("foo");
let cipher = Cipher::des_ede3_cbc();
let flags = Pkcs7Flags::STREAM;
// Use `Pkcs7::encrypt` since it populates the PKCS7_ENVELOPE struct rather than
// PKCS7_SIGNED
let pkcs7 =
Pkcs7::encrypt(&certs, message.as_bytes(), cipher, flags).expect("should succeed");
assert_eq!(
pkcs7.type_().expect("PKCS7 should have a type").nid(),
Nid::PKCS7_ENVELOPED
);
let signed_data_certs = pkcs7.signed().and_then(|x| x.certificates());
assert!(signed_data_certs.is_none())
}
}
+89 -40
View File
@@ -47,7 +47,7 @@ use crate::dh::Dh;
use crate::dsa::Dsa;
use crate::ec::EcKey;
use crate::error::ErrorStack;
#[cfg(any(ossl110, boringssl, libressl370))]
#[cfg(any(ossl110, boringssl, libressl370, awslc))]
use crate::pkey_ctx::PkeyCtx;
use crate::rsa::Rsa;
use crate::symm::Cipher;
@@ -60,6 +60,7 @@ use openssl_macros::corresponds;
use std::convert::{TryFrom, TryInto};
use std::ffi::CString;
use std::fmt;
#[cfg(all(not(any(boringssl, awslc)), ossl110))]
use std::mem;
use std::ptr;
@@ -78,24 +79,28 @@ pub struct Id(c_int);
impl Id {
pub const RSA: Id = Id(ffi::EVP_PKEY_RSA);
#[cfg(any(ossl111, libressl310, boringssl, awslc))]
pub const RSA_PSS: Id = Id(ffi::EVP_PKEY_RSA_PSS);
#[cfg(not(boringssl))]
pub const HMAC: Id = Id(ffi::EVP_PKEY_HMAC);
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
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);
#[cfg(ossl110)]
pub const DHX: Id = Id(ffi::EVP_PKEY_DHX);
pub const EC: Id = Id(ffi::EVP_PKEY_EC);
#[cfg(ossl111)]
pub const SM2: Id = Id(ffi::EVP_PKEY_SM2);
#[cfg(any(ossl110, boringssl))]
#[cfg(any(ossl110, boringssl, libressl360, awslc))]
pub const HKDF: Id = Id(ffi::EVP_PKEY_HKDF);
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
pub const ED25519: Id = Id(ffi::EVP_PKEY_ED25519);
#[cfg(ossl111)]
pub const ED448: Id = Id(ffi::EVP_PKEY_ED448);
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
pub const X25519: Id = Id(ffi::EVP_PKEY_X25519);
#[cfg(ossl111)]
pub const X448: Id = Id(ffi::EVP_PKEY_X448);
@@ -260,7 +265,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(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
pub fn raw_public_key(&self) -> Result<Vec<u8>, ErrorStack> {
unsafe {
let mut len = 0;
@@ -311,7 +316,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(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
pub fn raw_private_key(&self) -> Result<Vec<u8>, ErrorStack> {
unsafe {
let mut len = 0;
@@ -379,15 +384,31 @@ impl<T> fmt::Debug for PKey<T> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let alg = match self.id() {
Id::RSA => "RSA",
#[cfg(any(ossl111, libressl310, boringssl, awslc))]
Id::RSA_PSS => "RSA-PSS",
#[cfg(not(boringssl))]
Id::HMAC => "HMAC",
#[cfg(not(any(boringssl, awslc)))]
Id::CMAC => "CMAC",
Id::DSA => "DSA",
Id::DH => "DH",
#[cfg(ossl110)]
Id::DHX => "DHX",
Id::EC => "EC",
#[cfg(ossl111)]
Id::SM2 => "SM2",
#[cfg(any(ossl110, boringssl, libressl360, awslc))]
Id::HKDF => "HKDF",
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
Id::ED25519 => "Ed25519",
#[cfg(ossl111)]
Id::ED448 => "Ed448",
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
Id::X25519 => "X25519",
#[cfg(ossl111)]
Id::X448 => "X448",
#[cfg(ossl111)]
Id::POLY1305 => "POLY1305",
_ => "unknown",
};
fmt.debug_struct("PKey").field("algorithm", &alg).finish()
@@ -403,50 +424,64 @@ impl<T> Clone for PKey<T> {
impl<T> PKey<T> {
/// Creates a new `PKey` containing an RSA key.
#[corresponds(EVP_PKEY_assign_RSA)]
#[corresponds(EVP_PKEY_set1_RSA)]
pub fn from_rsa(rsa: Rsa<T>) -> Result<PKey<T>, ErrorStack> {
// TODO: Next time we make backwards incompatible changes, this could
// become an `&RsaRef<T>`. Same for all the other `from_*` methods.
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
cvt(ffi::EVP_PKEY_assign_RSA(pkey.0, rsa.as_ptr()))?;
mem::forget(rsa);
cvt(ffi::EVP_PKEY_set1_RSA(pkey.0, rsa.as_ptr()))?;
Ok(pkey)
}
}
/// Creates a new `PKey` containing a DSA key.
#[corresponds(EVP_PKEY_assign_DSA)]
#[corresponds(EVP_PKEY_set1_DSA)]
pub fn from_dsa(dsa: Dsa<T>) -> Result<PKey<T>, ErrorStack> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
cvt(ffi::EVP_PKEY_assign_DSA(pkey.0, dsa.as_ptr()))?;
mem::forget(dsa);
cvt(ffi::EVP_PKEY_set1_DSA(pkey.0, dsa.as_ptr()))?;
Ok(pkey)
}
}
/// Creates a new `PKey` containing a Diffie-Hellman key.
#[corresponds(EVP_PKEY_assign_DH)]
#[corresponds(EVP_PKEY_set1_DH)]
#[cfg(not(boringssl))]
pub fn from_dh(dh: Dh<T>) -> Result<PKey<T>, ErrorStack> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
cvt(ffi::EVP_PKEY_assign_DH(pkey.0, dh.as_ptr()))?;
cvt(ffi::EVP_PKEY_set1_DH(pkey.0, dh.as_ptr()))?;
Ok(pkey)
}
}
/// Creates a new `PKey` containing a Diffie-Hellman key with type DHX.
#[cfg(all(not(any(boringssl, awslc)), ossl110))]
pub fn from_dhx(dh: Dh<T>) -> Result<PKey<T>, ErrorStack> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_DHX,
dh.as_ptr().cast(),
))?;
mem::forget(dh);
Ok(pkey)
}
}
/// Creates a new `PKey` containing an elliptic curve key.
#[corresponds(EVP_PKEY_assign_EC_KEY)]
#[corresponds(EVP_PKEY_set1_EC_KEY)]
pub fn from_ec_key(ec_key: EcKey<T>) -> Result<PKey<T>, ErrorStack> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
cvt(ffi::EVP_PKEY_assign_EC_KEY(pkey.0, ec_key.as_ptr()))?;
mem::forget(ec_key);
cvt(ffi::EVP_PKEY_set1_EC_KEY(pkey.0, ec_key.as_ptr()))?;
Ok(pkey)
}
}
@@ -461,13 +496,17 @@ impl PKey<Private> {
#[corresponds(EVP_PKEY_new_mac_key)]
#[cfg(not(boringssl))]
pub fn hmac(key: &[u8]) -> Result<PKey<Private>, ErrorStack> {
#[cfg(awslc)]
let key_len = key.len();
#[cfg(not(awslc))]
let key_len = key.len() as c_int;
unsafe {
assert!(key.len() <= c_int::max_value() as usize);
assert!(key.len() <= c_int::MAX as usize);
let key = cvt_p(ffi::EVP_PKEY_new_mac_key(
ffi::EVP_PKEY_HMAC,
ptr::null_mut(),
key.as_ptr() as *const _,
key.len() as c_int,
key_len,
))?;
Ok(PKey::from_ptr(key))
}
@@ -480,7 +519,7 @@ impl PKey<Private> {
/// # Note
///
/// To compute CMAC values, use the `sign` module.
#[cfg(all(not(boringssl), ossl110))]
#[cfg(all(not(any(boringssl, awslc)), 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)?;
@@ -490,7 +529,7 @@ impl PKey<Private> {
ctx.keygen()
}
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
fn generate_eddsa(id: Id) -> Result<PKey<Private>, ErrorStack> {
let mut ctx = PkeyCtx::new_id(id)?;
ctx.keygen_init()?;
@@ -520,7 +559,7 @@ impl PKey<Private> {
/// assert_eq!(secret.len(), 32);
/// # Ok(()) }
/// ```
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
pub fn generate_x25519() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(Id::X25519)
}
@@ -574,7 +613,7 @@ impl PKey<Private> {
/// assert_eq!(signature.len(), 64);
/// # Ok(()) }
/// ```
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
pub fn generate_ed25519() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(Id::ED25519)
}
@@ -656,7 +695,7 @@ impl PKey<Private> {
pub fn private_key_from_pkcs8(der: &[u8]) -> Result<PKey<Private>, ErrorStack> {
unsafe {
ffi::init();
let len = der.len().min(c_long::max_value() as usize) as c_long;
let len = der.len().min(c_long::MAX as usize) as c_long;
let p8inf = cvt_p(ffi::d2i_PKCS8_PRIV_KEY_INFO(
ptr::null_mut(),
&mut der.as_ptr(),
@@ -724,7 +763,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(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
pub fn private_key_from_raw_bytes(
bytes: &[u8],
key_type: Id,
@@ -743,12 +782,22 @@ impl PKey<Private> {
}
impl PKey<Public> {
from_pem! {
private_key_from_pem! {
/// Decodes a PEM-encoded SubjectPublicKeyInfo structure.
///
/// The input should have a header of `-----BEGIN PUBLIC KEY-----`.
#[corresponds(PEM_read_bio_PUBKEY)]
public_key_from_pem,
/// Decodes a PEM-encoded SubjectPublicKeyInfo structure.
#[corresponds(PEM_read_bio_PUBKEY)]
public_key_from_pem_passphrase,
/// Decodes a PEM-encoded SubjectPublicKeyInfo structure.
///
/// The callback should fill the password into the provided buffer and return its length.
#[corresponds(PEM_read_bio_PrivateKey)]
public_key_from_pem_callback,
PKey<Public>,
ffi::PEM_read_bio_PUBKEY
}
@@ -765,7 +814,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(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
pub fn public_key_from_raw_bytes(
bytes: &[u8],
key_type: Id,
@@ -784,7 +833,7 @@ impl PKey<Public> {
}
cfg_if! {
if #[cfg(any(boringssl, ossl110, libressl270))] {
if #[cfg(any(boringssl, ossl110, libressl270, awslc))] {
use ffi::EVP_PKEY_up_ref;
} else {
#[allow(bad_style)]
@@ -880,7 +929,7 @@ mod tests {
use super::*;
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
use crate::rand::rand_bytes;
#[test]
@@ -1073,7 +1122,7 @@ mod tests {
assert_eq!(&g, dh_.generator());
}
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
fn test_raw_public_key(gen: fn() -> Result<PKey<Private>, ErrorStack>, key_type: Id) {
// Generate a new key
let key = gen().unwrap();
@@ -1089,7 +1138,7 @@ mod tests {
);
}
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
fn test_raw_private_key(gen: fn() -> Result<PKey<Private>, ErrorStack>, key_type: Id) {
// Generate a new key
let key = gen().unwrap();
@@ -1105,29 +1154,29 @@ mod tests {
);
}
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
#[test]
fn test_raw_public_key_bytes() {
test_raw_public_key(PKey::generate_x25519, Id::X25519);
test_raw_public_key(PKey::generate_ed25519, Id::ED25519);
#[cfg(all(not(boringssl), not(libressl370)))]
#[cfg(not(any(boringssl, libressl370, awslc)))]
test_raw_public_key(PKey::generate_x448, Id::X448);
#[cfg(all(not(boringssl), not(libressl370)))]
#[cfg(not(any(boringssl, libressl370, awslc)))]
test_raw_public_key(PKey::generate_ed448, Id::ED448);
}
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
#[test]
fn test_raw_private_key_bytes() {
test_raw_private_key(PKey::generate_x25519, Id::X25519);
test_raw_private_key(PKey::generate_ed25519, Id::ED25519);
#[cfg(all(not(boringssl), not(libressl370)))]
#[cfg(not(any(boringssl, libressl370, awslc)))]
test_raw_private_key(PKey::generate_x448, Id::X448);
#[cfg(all(not(boringssl), not(libressl370)))]
#[cfg(not(any(boringssl, libressl370, awslc)))]
test_raw_private_key(PKey::generate_ed448, Id::ED448);
}
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
#[test]
fn test_raw_hmac() {
let mut test_bytes = vec![0u8; 32];
@@ -1140,7 +1189,7 @@ mod tests {
assert_eq!(key_bytes, test_bytes);
}
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
#[test]
fn test_raw_key_fail() {
// Getting a raw byte representation will not work with Nist curves
+135 -27
View File
@@ -21,7 +21,7 @@
//! ```
#![cfg_attr(
not(boringssl),
not(any(boringssl, awslc)),
doc = r#"\
Generate a CMAC key
@@ -64,7 +64,7 @@ let cmac_key = ctx.keygen().unwrap();
//! let valid = ctx.verify(text, &signature).unwrap();
//! assert!(valid);
//! ```
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use crate::cipher::CipherRef;
use crate::error::ErrorStack;
use crate::md::MdRef;
@@ -73,17 +73,21 @@ use crate::rsa::Padding;
use crate::sign::RsaPssSaltlen;
use crate::{cvt, cvt_p};
use foreign_types::{ForeignType, ForeignTypeRef};
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use libc::c_int;
#[cfg(ossl320)]
use libc::c_uint;
use openssl_macros::corresponds;
use std::convert::TryFrom;
#[cfg(ossl320)]
use std::ffi::CStr;
use std::ptr;
/// HKDF modes of operation.
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl360))]
pub struct HkdfMode(c_int);
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl360))]
impl HkdfMode {
/// This is the default mode. Calling [`derive`][PkeyCtxRef::derive] on a [`PkeyCtxRef`] set up
/// for HKDF will perform an extract followed by an expand operation in one go. The derived key
@@ -105,6 +109,21 @@ impl HkdfMode {
pub const EXPAND_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXPAND_ONLY);
}
/// Nonce type for ECDSA and DSA.
#[cfg(ossl320)]
#[derive(Debug, PartialEq)]
pub struct NonceType(c_uint);
#[cfg(ossl320)]
impl NonceType {
/// This is the default mode. It uses a random value for the nonce k as defined in FIPS 186-4 Section 6.3
/// “Secret Number Generation”.
pub const RANDOM_K: Self = NonceType(0);
/// Uses a deterministic value for the nonce k as defined in RFC #6979 (See Section 3.2 “Generation of k”).
pub const DETERMINISTIC_K: Self = NonceType(1);
}
generic_foreign_type_and_impl_send_sync! {
type CType = ffi::EVP_PKEY_CTX;
fn drop = ffi::EVP_PKEY_CTX_free;
@@ -129,7 +148,7 @@ impl<T> PkeyCtx<T> {
impl PkeyCtx<()> {
/// Creates a new pkey context for the specified algorithm ID.
#[corresponds(EVP_PKEY_new_id)]
#[corresponds(EVP_PKEY_CTX_new_id)]
#[inline]
pub fn new_id(id: Id) -> Result<Self, ErrorStack> {
unsafe {
@@ -482,7 +501,7 @@ impl<T> PkeyCtxRef<T> {
///
/// This is only useful for RSA keys.
#[corresponds(EVP_PKEY_CTX_set_rsa_oaep_md)]
#[cfg(any(ossl102, libressl310, boringssl))]
#[cfg(any(ossl102, libressl310, boringssl, awslc))]
#[inline]
pub fn set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> {
unsafe {
@@ -499,7 +518,7 @@ impl<T> PkeyCtxRef<T> {
///
/// This is only useful for RSA keys.
#[corresponds(EVP_PKEY_CTX_set0_rsa_oaep_label)]
#[cfg(any(ossl102, libressl310, boringssl))]
#[cfg(any(ossl102, libressl310, boringssl, awslc))]
pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
use crate::LenType;
let len = LenType::try_from(label.len()).unwrap();
@@ -523,7 +542,7 @@ impl<T> PkeyCtxRef<T> {
}
/// Sets the cipher used during key generation.
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
#[corresponds(EVP_PKEY_CTX_ctrl)]
#[inline]
pub fn set_keygen_cipher(&mut self, cipher: &CipherRef) -> Result<(), ErrorStack> {
@@ -542,7 +561,7 @@ impl<T> PkeyCtxRef<T> {
}
/// Sets the key MAC key used during key generation.
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
#[corresponds(EVP_PKEY_CTX_ctrl)]
#[inline]
pub fn set_keygen_mac_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
@@ -566,7 +585,7 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_set_hkdf_md)]
#[cfg(any(ossl110, boringssl))]
#[cfg(any(ossl110, boringssl, libressl360, awslc))]
#[inline]
pub fn set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack> {
unsafe {
@@ -589,7 +608,7 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.1 or newer.
#[corresponds(EVP_PKEY_CTX_set_hkdf_mode)]
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl360))]
#[inline]
pub fn set_hkdf_mode(&mut self, mode: HkdfMode) -> Result<(), ErrorStack> {
unsafe {
@@ -608,12 +627,12 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_set1_hkdf_key)]
#[cfg(any(ossl110, boringssl))]
#[cfg(any(ossl110, boringssl, libressl360, awslc))]
#[inline]
pub fn set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
let len = c_int::try_from(key.len()).unwrap();
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
let len = key.len();
unsafe {
@@ -633,12 +652,12 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_set1_hkdf_salt)]
#[cfg(any(ossl110, boringssl))]
#[cfg(any(ossl110, boringssl, libressl360, awslc))]
#[inline]
pub fn set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack> {
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
let len = c_int::try_from(salt.len()).unwrap();
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
let len = salt.len();
unsafe {
@@ -658,12 +677,12 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_add1_hkdf_info)]
#[cfg(any(ossl110, boringssl))]
#[cfg(any(ossl110, boringssl, libressl360, awslc))]
#[inline]
pub fn add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack> {
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
let len = c_int::try_from(info.len()).unwrap();
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
let len = info.len();
unsafe {
@@ -714,12 +733,59 @@ impl<T> PkeyCtxRef<T> {
Ok(PKey::from_ptr(key))
}
}
/// Sets the nonce type for a private key context.
///
/// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979).
///
/// This is only useful for DSA and ECDSA.
/// Requires OpenSSL 3.2.0 or newer.
#[cfg(ossl320)]
#[corresponds(EVP_PKEY_CTX_set_params)]
pub fn set_nonce_type(&mut self, nonce_type: NonceType) -> Result<(), ErrorStack> {
let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap();
let mut nonce_type = nonce_type.0;
unsafe {
let param_nonce =
ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type);
let param_end = ffi::OSSL_PARAM_construct_end();
let params = [param_nonce, param_end];
cvt(ffi::EVP_PKEY_CTX_set_params(self.as_ptr(), params.as_ptr()))?;
}
Ok(())
}
/// Gets the nonce type for a private key context.
///
/// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979).
///
/// This is only useful for DSA and ECDSA.
/// Requires OpenSSL 3.2.0 or newer.
#[cfg(ossl320)]
#[corresponds(EVP_PKEY_CTX_get_params)]
pub fn nonce_type(&mut self) -> Result<NonceType, ErrorStack> {
let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap();
let mut nonce_type: c_uint = 0;
unsafe {
let param_nonce =
ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type);
let param_end = ffi::OSSL_PARAM_construct_end();
let mut params = [param_nonce, param_end];
cvt(ffi::EVP_PKEY_CTX_get_params(
self.as_ptr(),
params.as_mut_ptr(),
))?;
}
Ok(NonceType(nonce_type))
}
}
#[cfg(test)]
mod test {
use super::*;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use crate::cipher::Cipher;
use crate::ec::{EcGroup, EcKey};
use crate::hash::{hash, MessageDigest};
@@ -753,7 +819,7 @@ mod test {
}
#[test]
#[cfg(any(ossl102, libressl310, boringssl))]
#[cfg(any(ossl102, libressl310, boringssl, awslc))]
fn rsa_oaep() {
let key = include_bytes!("../test/rsa.pem");
let rsa = Rsa::private_key_from_pem(key).unwrap();
@@ -844,7 +910,7 @@ mod test {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn cmac_keygen() {
let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap();
ctx.keygen_init().unwrap();
@@ -855,7 +921,7 @@ mod test {
}
#[test]
#[cfg(any(ossl110, boringssl))]
#[cfg(any(ossl110, boringssl, libressl360, awslc))]
fn hkdf() {
let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
ctx.derive_init().unwrap();
@@ -877,7 +943,7 @@ mod test {
}
#[test]
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl360))]
fn hkdf_expand() {
let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
ctx.derive_init().unwrap();
@@ -901,7 +967,7 @@ mod test {
}
#[test]
#[cfg(ossl111)]
#[cfg(any(ossl111, libressl360))]
fn hkdf_extract() {
let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
ctx.derive_init().unwrap();
@@ -999,4 +1065,46 @@ mod test {
// The digest is the end of the DigestInfo structure.
assert_eq!(result_buf[length - digest.len()..length], digest);
}
#[test]
#[cfg(ossl320)]
fn set_nonce_type() {
let key1 =
EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap();
let key1 = PKey::from_ec_key(key1).unwrap();
let mut ctx = PkeyCtx::new(&key1).unwrap();
ctx.sign_init().unwrap();
ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap();
let nonce_type = ctx.nonce_type().unwrap();
assert_eq!(nonce_type, NonceType::DETERMINISTIC_K);
assert!(ErrorStack::get().errors().is_empty());
}
// Test vector from
// https://github.com/openssl/openssl/blob/openssl-3.2.0/test/recipes/30-test_evp_data/evppkey_ecdsa_rfc6979.txt
#[test]
#[cfg(ossl320)]
fn ecdsa_deterministic_signature() {
let private_key_pem = "-----BEGIN PRIVATE KEY-----
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("3044022061340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D3202206D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB").unwrap();
let hashed_input = hash(MessageDigest::sha1(), input.as_bytes()).unwrap();
let mut ctx = PkeyCtx::new(&key1).unwrap();
ctx.sign_init().unwrap();
ctx.set_signature_md(Md::sha1()).unwrap();
ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap();
let mut output = vec![];
ctx.sign_to_vec(&hashed_input, &mut output).unwrap();
assert_eq!(output, expected_output);
assert!(ErrorStack::get().errors().is_empty());
}
}
+4
View File
@@ -55,6 +55,10 @@ impl Provider {
retain_fallbacks as _,
))?;
// OSSL_PROVIDER_try_load seems to leave errors on the stack, even
// when it succeeds.
let _ = ErrorStack::get();
Ok(Provider::from_ptr(p))
}
}
+34 -4
View File
@@ -32,11 +32,36 @@ use openssl_macros::corresponds;
pub fn rand_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> {
unsafe {
ffi::init();
assert!(buf.len() <= c_int::max_value() as usize);
assert!(buf.len() <= c_int::MAX as usize);
cvt(ffi::RAND_bytes(buf.as_mut_ptr(), buf.len() as LenType)).map(|_| ())
}
}
/// Fill buffer with cryptographically strong pseudo-random bytes. It is
/// intended to be used for generating values that should remain private.
///
/// # Examples
///
/// To generate a buffer with cryptographically strong random bytes:
///
/// ```
/// use openssl::rand::rand_priv_bytes;
///
/// let mut buf = [0; 256];
/// rand_priv_bytes(&mut buf).unwrap();
/// ```
///
/// Requires OpenSSL 1.1.1 or newer.
#[corresponds(RAND_priv_bytes)]
#[cfg(ossl111)]
pub fn rand_priv_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> {
unsafe {
ffi::init();
assert!(buf.len() <= c_int::MAX as usize);
cvt(ffi::RAND_priv_bytes(buf.as_mut_ptr(), buf.len() as LenType)).map(|_| ())
}
}
/// Controls random device file descriptor behavior.
///
/// Requires OpenSSL 1.1.1 or newer.
@@ -50,11 +75,16 @@ pub fn keep_random_devices_open(keep: bool) {
#[cfg(test)]
mod tests {
use super::rand_bytes;
#[test]
fn test_rand_bytes() {
let mut buf = [0; 32];
rand_bytes(&mut buf).unwrap();
super::rand_bytes(&mut buf).unwrap();
}
#[test]
#[cfg(ossl111)]
fn test_rand_priv_bytes() {
let mut buf = [0; 32];
super::rand_priv_bytes(&mut buf).unwrap();
}
}
+31 -10
View File
@@ -129,7 +129,7 @@ where
to: &mut [u8],
padding: Padding,
) -> Result<usize, ErrorStack> {
assert!(from.len() <= i32::max_value() as usize);
assert!(from.len() <= i32::MAX as usize);
assert!(to.len() >= self.size() as usize);
unsafe {
@@ -157,7 +157,7 @@ where
to: &mut [u8],
padding: Padding,
) -> Result<usize, ErrorStack> {
assert!(from.len() <= i32::max_value() as usize);
assert!(from.len() <= i32::MAX as usize);
assert!(to.len() >= self.size() as usize);
unsafe {
@@ -234,14 +234,18 @@ where
/// Validates RSA parameters for correctness
#[corresponds(RSA_check_key)]
#[allow(clippy::unnecessary_cast)]
pub fn check_key(&self) -> Result<bool, ErrorStack> {
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)
}
}
}
@@ -301,7 +305,7 @@ where
to: &mut [u8],
padding: Padding,
) -> Result<usize, ErrorStack> {
assert!(from.len() <= i32::max_value() as usize);
assert!(from.len() <= i32::MAX as usize);
assert!(to.len() >= self.size() as usize);
unsafe {
@@ -328,7 +332,7 @@ where
to: &mut [u8],
padding: Padding,
) -> Result<usize, ErrorStack> {
assert!(from.len() <= i32::max_value() as usize);
assert!(from.len() <= i32::MAX as usize);
assert!(to.len() >= self.size() as usize);
unsafe {
@@ -581,7 +585,7 @@ impl<T> fmt::Debug for Rsa<T> {
}
cfg_if! {
if #[cfg(any(ossl110, libressl273, boringssl))] {
if #[cfg(any(ossl110, libressl273, boringssl, awslc))] {
use ffi::{
RSA_get0_key, RSA_get0_factors, RSA_get0_crt_params, RSA_set0_key, RSA_set0_factors,
RSA_set0_crt_params,
@@ -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());
}
}
}
+35 -87
View File
@@ -36,7 +36,7 @@
//! ```
#![cfg_attr(
not(boringssl),
not(any(boringssl, awslc)),
doc = r#"\
Compute an HMAC:
@@ -79,9 +79,10 @@ 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(ossl110)] {
if #[cfg(any(ossl110, libressl382))] {
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
} else {
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
@@ -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<T>) -> Result<Signer<'a>, 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<T>) -> Result<Signer<'a>, 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<Padding, ErrorStack> {
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,15 +264,12 @@ 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<usize, ErrorStack> {
self.len_intern()
}
#[cfg(all(not(ossl111), not(boringssl), not(libressl370)))]
#[cfg(not(any(ossl111, boringssl, libressl370, awslc)))]
fn len_intern(&self) -> Result<usize, ErrorStack> {
unsafe {
let mut len = 0;
@@ -303,7 +282,7 @@ impl Signer<'_> {
}
}
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
fn len_intern(&self) -> Result<usize, ErrorStack> {
unsafe {
let mut len = 0;
@@ -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<usize, ErrorStack> {
unsafe {
let mut len = buf.len();
@@ -356,11 +332,8 @@ 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
#[cfg(any(ossl111, boringssl, libressl370))]
#[corresponds(EVP_DigestSign)]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
pub fn sign_oneshot(
&mut self,
sig_buf: &mut [u8],
@@ -382,7 +355,7 @@ impl Signer<'_> {
/// Returns the signature.
///
/// This is a simple convenience wrapper over `len` and `sign_oneshot`.
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
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)?;
@@ -392,7 +365,7 @@ impl Signer<'_> {
}
}
impl<'a> Write for Signer<'a> {
impl Write for Signer<'_> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
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<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, 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<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, 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<Padding, ErrorStack> {
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<bool, ErrorStack> {
unsafe {
let r =
@@ -592,11 +543,8 @@ 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
#[cfg(any(ossl111, boringssl, libressl370))]
#[corresponds(EVP_DigestVerify)]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
pub fn verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> {
unsafe {
let r = ffi::EVP_DigestVerify(
@@ -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<usize> {
self.update(buf)?;
Ok(buf.len())
@@ -653,7 +601,7 @@ mod test {
use crate::nid::Nid;
use crate::pkey::PKey;
use crate::rsa::{Padding, Rsa};
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
use crate::sign::RsaPssSaltlen;
use crate::sign::{Signer, Verifier};
@@ -846,7 +794,7 @@ mod test {
}
#[test]
#[cfg(any(ossl111, boringssl, libressl370))]
#[cfg(any(ossl111, boringssl, libressl370, awslc))]
fn eddsa() {
let key = PKey::generate_ed25519().unwrap();
@@ -858,7 +806,7 @@ mod test {
}
#[test]
#[cfg(ossl111)]
#[cfg(any(ossl111, awslc))]
fn rsa_sign_verify() {
let key = include_bytes!("../test/rsa.pem");
let private_key = Rsa::private_key_from_pem(key).unwrap();
+2 -2
View File
@@ -46,10 +46,10 @@ impl SrtpProfileId {
SrtpProfileId(ffi::SRTP_AES128_F8_SHA1_32 as c_ulong);
pub const SRTP_NULL_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_80 as c_ulong);
pub const SRTP_NULL_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_32 as c_ulong);
#[cfg(any(boringssl, ossl110))]
#[cfg(any(boringssl, ossl110, awslc))]
pub const SRTP_AEAD_AES_128_GCM: SrtpProfileId =
SrtpProfileId(ffi::SRTP_AEAD_AES_128_GCM as c_ulong);
#[cfg(any(boringssl, ossl110))]
#[cfg(any(boringssl, ossl110, awslc))]
pub const SRTP_AEAD_AES_256_GCM: SrtpProfileId =
SrtpProfileId(ffi::SRTP_AEAD_AES_256_GCM as c_ulong);
+28 -9
View File
@@ -9,7 +9,7 @@ use std::io;
use std::io::prelude::*;
use std::panic::{catch_unwind, AssertUnwindSafe};
use std::ptr;
use crate::error::ErrorStack;
use crate::{cvt_p, util};
@@ -71,7 +71,7 @@ pub unsafe fn get_mut<'a, S: 'a>(bio: *mut BIO) -> &'a mut S {
}
pub unsafe fn set_dtls_mtu_size<S>(bio: *mut BIO, mtu_size: usize) {
if mtu_size as u64 > c_long::max_value() as u64 {
if mtu_size as u64 > c_long::MAX as u64 {
panic!(
"Given MTU size {} can't be represented in a positive `c_long` range",
mtu_size
@@ -189,7 +189,7 @@ unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int {
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
if #[cfg(any(ossl110, libressl273, boringssl))] {
use ffi::{BIO_get_data, BIO_set_data, BIO_set_flags, BIO_set_init};
use crate::cvt;
@@ -201,15 +201,34 @@ cfg_if! {
impl BIO_METHOD {
fn new<S: Read + Write>() -> Result<BIO_METHOD, ErrorStack> {
#[cfg(not(boringssl))]
use ffi::{
BIO_meth_set_write__fixed_rust as BIO_meth_set_write,
BIO_meth_set_read__fixed_rust as BIO_meth_set_read,
BIO_meth_set_puts__fixed_rust as BIO_meth_set_puts,
BIO_meth_set_ctrl__fixed_rust as BIO_meth_set_ctrl,
BIO_meth_set_create__fixed_rust as BIO_meth_set_create,
BIO_meth_set_destroy__fixed_rust as BIO_meth_set_destroy,
};
#[cfg(boringssl)]
use ffi::{
BIO_meth_set_write,
BIO_meth_set_read,
BIO_meth_set_puts,
BIO_meth_set_ctrl,
BIO_meth_set_create,
BIO_meth_set_destroy,
};
unsafe {
let ptr = cvt_p(ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _))?;
let method = BIO_METHOD(ptr);
cvt(ffi::BIO_meth_set_write__fixed_rust(method.0, Some(bwrite::<S>)))?;
cvt(ffi::BIO_meth_set_read__fixed_rust(method.0, Some(bread::<S>)))?;
cvt(ffi::BIO_meth_set_puts__fixed_rust(method.0, Some(bputs::<S>)))?;
cvt(ffi::BIO_meth_set_ctrl__fixed_rust(method.0, Some(ctrl::<S>)))?;
cvt(ffi::BIO_meth_set_create__fixed_rust(method.0, Some(create)))?;
cvt(ffi::BIO_meth_set_destroy__fixed_rust(method.0, Some(destroy::<S>)))?;
cvt(BIO_meth_set_write(method.0, Some(bwrite::<S>)))?;
cvt(BIO_meth_set_read(method.0, Some(bread::<S>)))?;
cvt(BIO_meth_set_puts(method.0, Some(bputs::<S>)))?;
cvt(BIO_meth_set_ctrl(method.0, Some(ctrl::<S>)))?;
cvt(BIO_meth_set_create(method.0, Some(create)))?;
cvt(BIO_meth_set_destroy(method.0, Some(destroy::<S>)))?;
Ok(method)
}
}
+18 -9
View File
@@ -10,7 +10,7 @@ use libc::{c_int, c_uchar, c_uint, c_void};
use std::ffi::CStr;
use std::mem;
use std::ptr;
#[cfg(ossl111)]
#[cfg(any(ossl111, boringssl, awslc))]
use std::str;
use std::sync::Arc;
@@ -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, awslc))]
use crate::ssl::AlpnError;
use crate::ssl::{
try_get_session_ctx_index, SniError, Ssl, SslAlert, SslContext, SslContextRef, SslRef,
@@ -28,7 +28,7 @@ use crate::ssl::{
#[cfg(ossl111)]
use crate::ssl::{ClientHelloResponse, ExtensionContext};
use crate::util;
#[cfg(ossl111)]
#[cfg(any(ossl111, boringssl, awslc))]
use crate::util::ForeignTypeRefExt;
#[cfg(ossl111)]
use crate::x509::X509Ref;
@@ -86,6 +86,7 @@ where
};
// Give the callback mutable slices into which it can write the identity and psk.
let identity_sl = util::from_raw_parts_mut(identity as *mut u8, max_identity_len as usize);
#[allow(clippy::unnecessary_cast)]
let psk_sl = util::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize);
match (*callback)(ssl, hint, identity_sl, psk_sl) {
Ok(psk_len) => psk_len as u32,
@@ -124,6 +125,7 @@ where
Some(CStr::from_ptr(identity).to_bytes())
};
// Give the callback mutable slices into which it can write the psk.
#[allow(clippy::unnecessary_cast)]
let psk_sl = util::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize);
match (*callback)(ssl, identity, psk_sl) {
Ok(psk_len) => psk_len as u32,
@@ -176,7 +178,7 @@ where
}
}
#[cfg(any(ossl102, libressl261))]
#[cfg(any(ossl102, libressl261, boringssl, awslc))]
pub extern "C" fn raw_alpn_select<F>(
ssl: *mut ffi::SSL,
out: *mut *const c_uchar,
@@ -194,6 +196,7 @@ where
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: alpn callback missing") as *const F;
#[allow(clippy::unnecessary_cast)]
let protos = util::from_raw_parts(inbuf as *const u8, inlen as usize);
match (*callback)(ssl, protos) {
@@ -388,7 +391,7 @@ pub unsafe extern "C" fn raw_remove_session<F>(
}
cfg_if! {
if #[cfg(any(ossl110, libressl280, boringssl))] {
if #[cfg(any(ossl110, libressl280, boringssl, awslc))] {
type DataPtr = *const c_uchar;
} else {
type DataPtr = *mut c_uchar;
@@ -412,6 +415,7 @@ where
.expect("BUG: session context missing")
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: get session callback missing") as *const F;
#[allow(clippy::unnecessary_cast)]
let data = util::from_raw_parts(data as *const u8, len as usize);
match (*callback)(ssl, data) {
@@ -425,7 +429,7 @@ where
}
}
#[cfg(ossl111)]
#[cfg(any(ossl111, boringssl, awslc))]
pub unsafe extern "C" fn raw_keylog<F>(ssl: *const ffi::SSL, line: *const c_char)
where
F: Fn(&SslRef, &str) + 'static + Sync + Send,
@@ -455,6 +459,7 @@ where
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: stateless cookie generate callback missing") as *const F;
#[allow(clippy::unnecessary_cast)]
let slice = util::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize);
match (*callback)(ssl, slice) {
Ok(len) => {
@@ -482,11 +487,12 @@ where
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: stateless cookie verify callback missing") as *const F;
#[allow(clippy::unnecessary_cast)]
let slice = util::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len);
(*callback)(ssl, slice) as c_int
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub extern "C" fn raw_cookie_generate<F>(
ssl: *mut ffi::SSL,
cookie: *mut c_uchar,
@@ -503,6 +509,7 @@ where
.expect("BUG: cookie generate callback missing") as *const F;
// We subtract 1 from DTLS1_COOKIE_LENGTH as the ostensible value, 256, is erroneous but retained for
// compatibility. See comments in dtls1.h.
#[allow(clippy::unnecessary_cast)]
let slice =
util::from_raw_parts_mut(cookie as *mut u8, ffi::DTLS1_COOKIE_LENGTH as usize - 1);
match (*callback)(ssl, slice) {
@@ -518,7 +525,7 @@ where
}
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
type CookiePtr = *const c_uchar;
@@ -527,7 +534,7 @@ cfg_if! {
}
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub extern "C" fn raw_cookie_verify<F>(
ssl: *mut ffi::SSL,
cookie: CookiePtr,
@@ -542,6 +549,7 @@ where
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: cookie verify callback missing") as *const F;
#[allow(clippy::unnecessary_cast)]
let slice =
util::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize);
(*callback)(ssl, slice) as c_int
@@ -654,6 +662,7 @@ where
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: custom ext parse callback missing") as *const F;
let ectx = ExtensionContext::from_bits_truncate(context);
#[allow(clippy::unnecessary_cast)]
let slice = util::from_raw_parts(input as *const u8, inlen);
let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) {
Some((chainidx, X509Ref::from_ptr(x)))
+1 -1
View File
@@ -29,7 +29,7 @@ fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
let mut ctx = SslContextBuilder::new(method)?;
cfg_if! {
if #[cfg(not(boringssl))] {
if #[cfg(not(any(boringssl, awslc)))] {
let mut opts = SslOptions::ALL
| SslOptions::NO_COMPRESSION
| SslOptions::NO_SSLV2
+400 -217
View File
File diff suppressed because it is too large Load Diff
+141 -22
View File
@@ -10,16 +10,16 @@ use std::net::UdpSocket;
use std::net::{SocketAddr, TcpListener, TcpStream};
use std::path::Path;
use std::process::{Child, ChildStdin, Command, Stdio};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::thread;
use std::time::Duration;
use crate::dh::Dh;
use crate::error::ErrorStack;
use crate::hash::MessageDigest;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
use crate::ocsp::{OcspResponse, OcspResponseStatus};
use crate::pkey::PKey;
use crate::pkey::{Id, PKey};
use crate::srtp::SrtpProfileId;
use crate::ssl::test::server::Server;
#[cfg(any(ossl110, ossl111, libressl261))]
@@ -264,7 +264,7 @@ fn set_ctx_options() {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn clear_ctx_options() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_options(SslOptions::ALL);
@@ -309,19 +309,71 @@ fn pending() {
#[test]
fn state() {
const EXPECTED_STATE_STRING_LONG: &str = "SSL negotiation finished successfully";
let server = Server::builder().build();
let s = server.client().connect();
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
assert_eq!(s.ssl().state_string().trim(), "SSLOK");
#[cfg(boringssl)]
assert_eq!(s.ssl().state_string(), "!!!!!!");
assert_eq!(
s.ssl().state_string_long(),
"SSL negotiation finished successfully"
#[cfg(awslc)]
assert_eq!(s.ssl().state_string(), EXPECTED_STATE_STRING_LONG);
assert_eq!(s.ssl().state_string_long(), EXPECTED_STATE_STRING_LONG);
}
// when a connection uses ECDHE P-384 key exchange, then the temp key APIs
// return P-384 keys, and the peer and local keys are different.
#[test]
#[cfg(ossl300)]
fn peer_tmp_key_p384() {
let mut server = Server::builder();
server.ctx().set_groups_list("P-384").unwrap();
let server = server.build();
let s = server.client().connect();
let peer_temp = s.ssl().peer_tmp_key().unwrap();
assert_eq!(peer_temp.id(), Id::EC);
assert_eq!(peer_temp.bits(), 384);
let local_temp = s.ssl().tmp_key().unwrap();
assert_eq!(local_temp.id(), Id::EC);
assert_eq!(local_temp.bits(), 384);
assert_ne!(
peer_temp.ec_key().unwrap().public_key_to_der().unwrap(),
local_temp.ec_key().unwrap().public_key_to_der().unwrap(),
);
}
// when a connection uses RSA key exchange, then the peer (server) temp key is
// an Error because there is no temp key, and the local (client) temp key is the
// temp key sent in the initial key share.
#[test]
#[cfg(ossl300)]
fn peer_tmp_key_rsa() {
let mut server = Server::builder();
server.ctx().set_cipher_list("RSA").unwrap();
// RSA key exchange is not allowed in TLS 1.3, so force the connection
// to negotiate TLS 1.2
server
.ctx()
.set_max_proto_version(Some(SslVersion::TLS1_2))
.unwrap();
let server = server.build();
let mut client = server.client();
client.ctx().set_groups_list("P-521").unwrap();
let s = client.connect();
let peer_temp = s.ssl().peer_tmp_key();
assert!(peer_temp.is_err());
// this is the temp key that the client sent in the initial key share
let local_temp = s.ssl().tmp_key().unwrap();
assert_eq!(local_temp.id(), Id::EC);
assert_eq!(local_temp.bits(), 521);
}
/// Tests that when both the client as well as the server use SRTP and their
/// lists of supported protocols have an overlap -- with only ONE protocol
/// being valid for both.
@@ -452,7 +504,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, awslc))]
fn test_alpn_server_advertise_multiple() {
let mut server = Server::builder();
server.ctx().set_alpn_select_callback(|_, client| {
@@ -467,7 +519,7 @@ fn test_alpn_server_advertise_multiple() {
}
#[test]
#[cfg(ossl110)]
#[cfg(any(ossl110, boringssl, awslc))]
fn test_alpn_server_select_none_fatal() {
let mut server = Server::builder();
server.ctx().set_alpn_select_callback(|_, client| {
@@ -483,7 +535,7 @@ fn test_alpn_server_select_none_fatal() {
}
#[test]
#[cfg(any(ossl102, libressl261))]
#[cfg(any(ossl102, libressl261, boringssl, awslc))]
fn test_alpn_server_select_none() {
static CALLED_BACK: AtomicBool = AtomicBool::new(false);
@@ -502,7 +554,7 @@ fn test_alpn_server_select_none() {
}
#[test]
#[cfg(any(ossl102, libressl261))]
#[cfg(any(boringssl, ossl102, libressl261, awslc))]
fn test_alpn_server_unilateral() {
let server = Server::builder().build();
@@ -917,7 +969,7 @@ fn cert_store() {
}
#[test]
#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl), ignore)]
#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl, awslc), ignore)]
fn tmp_dh_callback() {
static CALLED_BACK: AtomicBool = AtomicBool::new(false);
@@ -965,7 +1017,7 @@ fn tmp_ecdh_callback() {
}
#[test]
#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl), ignore)]
#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl, awslc), ignore)]
fn tmp_dh_callback_ssl() {
static CALLED_BACK: AtomicBool = AtomicBool::new(false);
@@ -1023,7 +1075,9 @@ fn idle_session() {
assert!(ssl.session().is_none());
}
/// possible LibreSSL bug since 3.2.1
/// LibreSSL 3.2.1 enabled TLSv1.3 by default for clients and sessions do
/// not work due to lack of PSK support. The test passes with NO_TLSV1_3,
/// but let's ignore it until LibreSSL supports it out of the box.
#[test]
#[cfg_attr(libressl321, ignore)]
fn active_session() {
@@ -1042,7 +1096,7 @@ fn active_session() {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn status_callbacks() {
static CALLED_BACK_SERVER: AtomicBool = AtomicBool::new(false);
static CALLED_BACK_CLIENT: AtomicBool = AtomicBool::new(false);
@@ -1081,7 +1135,9 @@ fn status_callbacks() {
assert!(CALLED_BACK_CLIENT.load(Ordering::SeqCst));
}
/// possible LibreSSL bug since 3.2.1
/// LibreSSL 3.2.1 enabled TLSv1.3 by default for clients and sessions do
/// not work due to lack of PSK support. The test passes with NO_TLSV1_3,
/// but let's ignore it until LibreSSL supports it out of the box.
#[test]
#[cfg_attr(libressl321, ignore)]
fn new_session_callback() {
@@ -1106,7 +1162,9 @@ fn new_session_callback() {
assert!(CALLED_BACK.load(Ordering::SeqCst));
}
/// possible LibreSSL bug since 3.2.1
/// LibreSSL 3.2.1 enabled TLSv1.3 by default for clients and sessions do
/// not work due to lack of PSK support. The test passes with NO_TLSV1_3,
/// but let's ignore it until LibreSSL supports it out of the box.
#[test]
#[cfg_attr(libressl321, ignore)]
fn new_session_callback_swapped_ctx() {
@@ -1311,20 +1369,20 @@ fn stateless() {
pub struct Outgoing<'a>(&'a mut Vec<u8>);
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
}
@@ -1404,7 +1462,7 @@ fn psk_ciphers() {
let mut client = server.client();
// This test relies on TLS 1.2 suites
#[cfg(any(boringssl, ossl111))]
#[cfg(any(boringssl, ossl111, awslc))]
client.ctx().set_options(super::SslOptions::NO_TLSV1_3);
client.ctx().set_cipher_list(CIPHER).unwrap();
client
@@ -1568,3 +1626,64 @@ fn set_num_tickets() {
let ssl = ssl;
assert_eq!(5, ssl.num_tickets());
}
#[test]
#[cfg(ossl110)]
fn set_security_level() {
let mut ctx = SslContext::builder(SslMethod::tls_server()).unwrap();
ctx.set_security_level(3);
let ctx = ctx.build();
assert_eq!(3, ctx.security_level());
let mut ssl = Ssl::new(&ctx).unwrap();
ssl.set_security_level(4);
let ssl = ssl;
assert_eq!(4, ssl.security_level());
}
#[test]
fn ssl_ctx_ex_data_leak() {
static DROPS: AtomicUsize = AtomicUsize::new(0);
struct DropTest;
impl Drop for DropTest {
fn drop(&mut self) {
DROPS.fetch_add(1, Ordering::Relaxed);
}
}
let idx = SslContext::new_ex_index().unwrap();
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_ex_data(idx, DropTest);
ctx.set_ex_data(idx, DropTest);
assert_eq!(DROPS.load(Ordering::Relaxed), 1);
drop(ctx);
assert_eq!(DROPS.load(Ordering::Relaxed), 2);
}
#[test]
fn ssl_ex_data_leak() {
static DROPS: AtomicUsize = AtomicUsize::new(0);
struct DropTest;
impl Drop for DropTest {
fn drop(&mut self) {
DROPS.fetch_add(1, Ordering::Relaxed);
}
}
let idx = Ssl::new_ex_index().unwrap();
let ctx = SslContext::builder(SslMethod::tls()).unwrap().build();
let mut ssl = Ssl::new(&ctx).unwrap();
ssl.set_ex_data(idx, DropTest);
ssl.set_ex_data(idx, DropTest);
assert_eq!(DROPS.load(Ordering::Relaxed), 1);
drop(ssl);
assert_eq!(DROPS.load(Ordering::Relaxed), 2);
}
+3 -3
View File
@@ -14,7 +14,7 @@ use crate::util::ForeignTypeExt;
use crate::{cvt, cvt_p, LenType};
cfg_if! {
if #[cfg(ossl110)] {
if #[cfg(any(ossl110, boringssl, awslc))] {
use ffi::{
OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK,
OPENSSL_sk_new_null, OPENSSL_sk_push,
@@ -343,7 +343,7 @@ impl<'a, T: Stackable> DoubleEndedIterator for Iter<'a, T> {
}
}
impl<'a, T: Stackable> ExactSizeIterator for Iter<'a, T> {}
impl<T: Stackable> 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<T: Stackable> ExactSizeIterator for IterMut<'_, T> {}
+2 -2
View File
@@ -80,13 +80,13 @@ impl fmt::Debug for OpensslStringRef {
}
#[inline]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
unsafe fn free(buf: *mut c_char) {
ffi::OPENSSL_free(buf as *mut c_void);
}
#[inline]
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
unsafe fn free(buf: *mut c_char) {
ffi::CRYPTO_free(
buf as *mut c_void,
+189 -49
View File
@@ -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<Cipher> {
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)
@@ -105,7 +100,7 @@ impl Cipher {
unsafe { Cipher(ffi::EVP_aes_128_cbc()) }
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub fn aes_128_xts() -> Cipher {
unsafe { Cipher(ffi::EVP_aes_128_xts()) }
}
@@ -177,7 +172,7 @@ impl Cipher {
unsafe { Cipher(ffi::EVP_aes_192_gcm()) }
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
pub fn aes_192_ccm() -> Cipher {
unsafe { Cipher(ffi::EVP_aes_192_ccm()) }
}
@@ -252,12 +247,12 @@ impl Cipher {
unsafe { Cipher(ffi::EVP_bf_ecb()) }
}
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))]
#[cfg(not(osslconf = "OPENSSL_NO_BF"))]
pub fn bf_cfb64() -> Cipher {
unsafe { Cipher(ffi::EVP_bf_cfb64()) }
}
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))]
#[cfg(not(osslconf = "OPENSSL_NO_BF"))]
pub fn bf_ofb() -> Cipher {
unsafe { Cipher(ffi::EVP_bf_ofb()) }
}
@@ -278,44 +273,158 @@ impl Cipher {
unsafe { Cipher(ffi::EVP_des_ede3_cbc()) }
}
#[cfg(not(boringssl))]
pub fn des_ede3_ecb() -> Cipher {
unsafe { Cipher(ffi::EVP_des_ede3_ecb()) }
}
#[cfg(not(any(boringssl, awslc)))]
pub fn des_ede3_cfb64() -> Cipher {
unsafe { Cipher(ffi::EVP_des_ede3_cfb64()) }
}
#[cfg(not(any(boringssl, awslc)))]
pub fn des_ede3_cfb8() -> Cipher {
unsafe { Cipher(ffi::EVP_des_ede3_cfb8()) }
}
#[cfg(not(any(boringssl, awslc)))]
pub fn des_ede3_ofb() -> Cipher {
unsafe { Cipher(ffi::EVP_des_ede3_ofb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
pub fn rc4() -> Cipher {
unsafe { Cipher(ffi::EVP_rc4()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_128_cbc() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_128_cbc()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_128_ecb() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_128_ecb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_128_ofb() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_128_ofb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_128_cfb128() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_128_cfb128()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_192_cbc() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_192_cbc()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_192_ecb() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_192_ecb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_192_ofb() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_192_ofb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_192_cfb128() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_192_cfb128()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_256_cbc() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_256_cbc()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_256_ecb() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_256_ecb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_256_ofb() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_256_ofb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
pub fn camellia_256_cfb128() -> Cipher {
unsafe { Cipher(ffi::EVP_camellia_256_cfb128()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn cast5_cbc() -> Cipher {
unsafe { Cipher(ffi::EVP_cast5_cbc()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn cast5_ecb() -> Cipher {
unsafe { Cipher(ffi::EVP_cast5_ecb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn cast5_ofb() -> Cipher {
unsafe { Cipher(ffi::EVP_cast5_ofb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
pub fn cast5_cfb64() -> Cipher {
unsafe { Cipher(ffi::EVP_cast5_cfb64()) }
}
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
#[cfg(all(any(ossl110, libressl310), not(osslconf = "OPENSSL_NO_CHACHA")))]
pub fn chacha20() -> Cipher {
unsafe { Cipher(ffi::EVP_chacha20()) }
}
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))]
#[cfg(all(any(ossl110, libressl360, awslc), not(osslconf = "OPENSSL_NO_CHACHA")))]
pub fn chacha20_poly1305() -> Cipher {
unsafe { Cipher(ffi::EVP_chacha20_poly1305()) }
}
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn idea_cbc() -> Cipher {
unsafe { Cipher(ffi::EVP_idea_cbc()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn idea_ecb() -> Cipher {
unsafe { Cipher(ffi::EVP_idea_ecb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn idea_ofb() -> Cipher {
unsafe { Cipher(ffi::EVP_idea_ofb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
pub fn idea_cfb64() -> Cipher {
unsafe { Cipher(ffi::EVP_idea_cfb64()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
pub fn seed_cbc() -> Cipher {
unsafe { Cipher(ffi::EVP_seed_cbc()) }
}
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
pub fn seed_cfb128() -> Cipher {
unsafe { Cipher(ffi::EVP_seed_cfb128()) }
}
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
pub fn seed_ecb() -> Cipher {
unsafe { Cipher(ffi::EVP_seed_ecb()) }
}
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
#[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
pub fn seed_ofb() -> Cipher {
unsafe { Cipher(ffi::EVP_seed_ofb()) }
}
@@ -345,6 +454,16 @@ impl Cipher {
unsafe { Cipher(ffi::EVP_sm4_ofb()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_RC2"))]
pub fn rc2_cbc() -> Cipher {
unsafe { Cipher(ffi::EVP_rc2_cbc()) }
}
#[cfg(not(osslconf = "OPENSSL_NO_RC2"))]
pub fn rc2_40_cbc() -> Cipher {
unsafe { Cipher(ffi::EVP_rc2_40_cbc()) }
}
/// Creates a `Cipher` from a raw pointer to its OpenSSL type.
///
/// # Safety
@@ -390,13 +509,13 @@ impl Cipher {
}
/// Determines whether the cipher is using CCM mode
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn is_ccm(self) -> bool {
// NOTE: OpenSSL returns pointers to static structs, which makes this work as expected
self == Cipher::aes_128_ccm() || self == Cipher::aes_256_ccm()
}
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
fn is_ccm(self) -> bool {
false
}
@@ -577,11 +696,32 @@ impl Crypter {
/// Panics for block ciphers if `output.len() < input.len() + block_size`,
/// where `block_size` is the block size of the cipher (see `Cipher::block_size`).
///
/// Panics if `output.len() > c_int::max_value()`.
/// Panics if `output.len() > c_int::MAX`.
pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
self.ctx.cipher_update(input, Some(output))
}
/// Feeds data from `input` through the cipher, writing encrypted/decrypted
/// bytes into `output`.
///
/// The number of bytes written to `output` is returned. Note that this may
/// not be equal to the length of `input`.
///
/// # Safety
///
/// The caller must provide an `output` buffer large enough to contain
/// correct number of bytes. For streaming ciphers the output buffer size
/// should be at least as big as the input buffer. For block ciphers the
/// size of the output buffer depends on the state of partially updated
/// blocks.
pub unsafe fn update_unchecked(
&mut self,
input: &[u8],
output: &mut [u8],
) -> Result<usize, ErrorStack> {
self.ctx.cipher_update_unchecked(input, Some(output))
}
/// Finishes the encryption/decryption process, writing any remaining data
/// to `output`.
///
@@ -776,7 +916,7 @@ pub fn decrypt_aead(
}
cfg_if! {
if #[cfg(any(boringssl, ossl110, libressl273))] {
if #[cfg(any(boringssl, ossl110, libressl273, awslc))] {
use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
} else {
use crate::LenType;
@@ -922,7 +1062,7 @@ mod tests {
}
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
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();
@@ -968,7 +1108,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes256_xts() {
// Test case 174 from
// http://csrc.nist.gov/groups/STM/cavp/documents/aes/XTSTestVectors.zip
@@ -996,7 +1136,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes128_cfb1() {
// Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
@@ -1009,7 +1149,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes128_cfb128() {
let pt = "6bc1bee22e409f96e93d7e117393172a";
let ct = "3b3fd92eb72dad20333449f8e83cfb4a";
@@ -1020,7 +1160,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes128_cfb8() {
let pt = "6bc1bee22e409f96e93d7e117393172aae2d";
let ct = "3b79424c9c0dd436bace9e0ed4586a4f32b9";
@@ -1055,7 +1195,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes192_cfb1() {
// Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
@@ -1068,7 +1208,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes192_cfb128() {
// Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
@@ -1081,7 +1221,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes192_cfb8() {
// Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
@@ -1106,7 +1246,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes256_cfb1() {
let pt = "6bc1";
let ct = "9029";
@@ -1117,7 +1257,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes256_cfb128() {
let pt = "6bc1bee22e409f96e93d7e117393172a";
let ct = "dc7e84bfda79164b7ecd8486985d3860";
@@ -1128,7 +1268,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes256_cfb8() {
let pt = "6bc1bee22e409f96e93d7e117393172aae2d";
let ct = "dc1f1a8520a64db55fcc8ac554844e889700";
@@ -1152,7 +1292,7 @@ mod tests {
#[test]
#[cfg_attr(ossl300, ignore)]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_bf_cbc() {
#[cfg(ossl300)]
let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap();
@@ -1169,7 +1309,7 @@ mod tests {
#[test]
#[cfg_attr(ossl300, ignore)]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_bf_ecb() {
#[cfg(ossl300)]
let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap();
@@ -1184,7 +1324,7 @@ mod tests {
#[test]
#[cfg_attr(ossl300, ignore)]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_bf_cfb64() {
#[cfg(ossl300)]
let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap();
@@ -1199,7 +1339,7 @@ mod tests {
#[test]
#[cfg_attr(ossl300, ignore)]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_bf_ofb() {
#[cfg(ossl300)]
let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap();
@@ -1259,7 +1399,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_des_ede3_cfb64() {
let pt = "2b1773784b5889dc788477367daa98ad";
let ct = "6f2867cfefda048a4046ef7e556c7132";
@@ -1306,7 +1446,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes128_ccm() {
let key = "3ee186594f110fb788a8bf8aa8be5d4a";
let nonce = "44f705d52acf27b7f17196aa9b";
@@ -1343,7 +1483,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes128_ccm_verify_fail() {
let key = "3ee186594f110fb788a8bf8aa8be5d4a";
let nonce = "44f705d52acf27b7f17196aa9b";
@@ -1364,7 +1504,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes256_ccm() {
let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d";
let nonce = "dde2a362ce81b2b6913abc3095";
@@ -1401,7 +1541,7 @@ mod tests {
}
#[test]
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
fn test_aes256_ccm_verify_fail() {
let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d";
let nonce = "dde2a362ce81b2b6913abc3095";
@@ -1478,7 +1618,7 @@ mod tests {
}
#[test]
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl310))]
fn test_chacha20() {
let key = "0000000000000000000000000000000000000000000000000000000000000000";
let iv = "00000000000000000000000000000000";
@@ -1493,7 +1633,7 @@ mod tests {
}
#[test]
#[cfg(ossl110)]
#[cfg(any(ossl110, libressl360, awslc))]
fn test_chacha20_poly1305() {
let key = "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f";
let iv = "070000004041424344454647";
@@ -1534,7 +1674,7 @@ mod tests {
}
#[test]
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))]
#[cfg(not(any(osslconf = "OPENSSL_NO_SEED", ossl300)))]
fn test_seed_cbc() {
#[cfg(ossl300)]
let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap();
@@ -1548,7 +1688,7 @@ mod tests {
}
#[test]
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))]
#[cfg(not(any(osslconf = "OPENSSL_NO_SEED", ossl300)))]
fn test_seed_cfb128() {
#[cfg(ossl300)]
let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap();
@@ -1562,7 +1702,7 @@ mod tests {
}
#[test]
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))]
#[cfg(not(any(osslconf = "OPENSSL_NO_SEED", ossl300)))]
fn test_seed_ecb() {
#[cfg(ossl300)]
let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap();
@@ -1576,7 +1716,7 @@ mod tests {
}
#[test]
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))]
#[cfg(not(any(osslconf = "OPENSSL_NO_SEED", ossl300)))]
fn test_seed_ofb() {
#[cfg(ossl300)]
let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap();
+1 -1
View File
@@ -115,4 +115,4 @@ pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T]
#[allow(clippy::disallowed_methods)]
slice::from_raw_parts_mut(data, len)
}
}
}
+5 -2
View File
@@ -111,7 +111,7 @@ fn test_versions() {
println!("Platform: '{}'", platform());
println!("Dir: '{}'", dir());
#[cfg(not(any(libressl, boringssl)))]
#[cfg(not(any(libressl, boringssl, awslc)))]
fn expected_name() -> &'static str {
"OpenSSL"
}
@@ -123,6 +123,10 @@ fn test_versions() {
fn expected_name() -> &'static str {
"BoringSSL"
}
#[cfg(awslc)]
fn expected_name() -> &'static str {
"AWS-LC"
}
assert!(number() > 0);
assert!(version().starts_with(expected_name()));
@@ -131,5 +135,4 @@ fn test_versions() {
if !built_on().is_empty() {
assert!(built_on().starts_with("built on:"));
}
assert!(dir().starts_with("OPENSSLDIR:"));
}
+132 -118
View File
@@ -37,10 +37,10 @@ use crate::ssl::SslRef;
use crate::stack::{Stack, StackRef, Stackable};
use crate::string::OpensslString;
use crate::util::{self, ForeignTypeExt, ForeignTypeRefExt};
use crate::{cvt, cvt_n, cvt_p};
use crate::{cvt, cvt_n, cvt_p, cvt_p_const};
use openssl_macros::corresponds;
#[cfg(any(ossl102, libressl261))]
#[cfg(any(ossl102, boringssl, libressl261, awslc))]
pub mod verify;
pub mod extension;
@@ -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());
@@ -382,11 +382,6 @@ foreign_type_and_impl_send_sync! {
pub struct X509Ref;
}
#[cfg(boringssl)]
type X509LenTy = c_uint;
#[cfg(not(boringssl))]
type X509LenTy = c_int;
impl X509Ref {
/// Returns this certificate's subject name.
#[corresponds(X509_get_subject_name)]
@@ -484,7 +479,7 @@ impl X509Ref {
/// Retrieves the path length extension from a certificate, if it exists.
#[corresponds(X509_get_pathlen)]
#[cfg(ossl110)]
#[cfg(any(ossl110, boringssl, awslc))]
pub fn pathlen(&self) -> Option<u32> {
let v = unsafe { ffi::X509_get_pathlen(self.as_ptr()) };
u32::try_from(v).ok()
@@ -492,7 +487,7 @@ impl X509Ref {
/// Returns this certificate's subject key id, if it exists.
#[corresponds(X509_get0_subject_key_id)]
#[cfg(ossl110)]
#[cfg(any(ossl110, boringssl, awslc))]
pub fn subject_key_id(&self) -> Option<&Asn1OctetStringRef> {
unsafe {
let data = ffi::X509_get0_subject_key_id(self.as_ptr());
@@ -502,7 +497,7 @@ impl X509Ref {
/// Returns this certificate's authority key id, if it exists.
#[corresponds(X509_get0_authority_key_id)]
#[cfg(ossl110)]
#[cfg(any(ossl110, boringssl, awslc))]
pub fn authority_key_id(&self) -> Option<&Asn1OctetStringRef> {
unsafe {
let data = ffi::X509_get0_authority_key_id(self.as_ptr());
@@ -653,6 +648,24 @@ impl X509Ref {
}
}
/// Returns this certificate's "alias". This field is populated by
/// OpenSSL in some situations -- specifically OpenSSL will store a
/// PKCS#12 `friendlyName` in this field. This is not a part of the X.509
/// certificate itself, OpenSSL merely attaches it to this structure in
/// memory.
#[corresponds(X509_alias_get0)]
pub fn alias(&self) -> Option<&[u8]> {
unsafe {
let mut len = 0;
let ptr = ffi::X509_alias_get0(self.as_ptr(), &mut len);
if ptr.is_null() {
None
} else {
Some(util::from_raw_parts(ptr, len as usize))
}
}
}
to_pem! {
/// Serializes the certificate into a PEM-encoded X509 structure.
///
@@ -759,15 +772,17 @@ impl X509 {
let r =
ffi::PEM_read_bio_X509(bio.as_ptr(), ptr::null_mut(), None, ptr::null_mut());
if r.is_null() {
let err = ffi::ERR_peek_last_error();
if ffi::ERR_GET_LIB(err) as X509LenTy == ffi::ERR_LIB_PEM
&& ffi::ERR_GET_REASON(err) == ffi::PEM_R_NO_START_LINE
{
ffi::ERR_clear_error();
break;
let e = ErrorStack::get();
if let Some(err) = e.errors().last() {
if err.library_code() == ffi::ERR_LIB_PEM as libc::c_int
&& err.reason_code() == ffi::PEM_R_NO_START_LINE as libc::c_int
{
break;
}
}
return Err(ErrorStack::get());
return Err(e);
} else {
certs.push(X509(r));
}
@@ -831,7 +846,7 @@ impl Ord for X509 {
impl PartialOrd for X509 {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
X509Ref::partial_cmp(self, other)
Some(self.cmp(other))
}
}
@@ -858,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 _
}
@@ -1021,6 +1036,7 @@ impl X509Extension {
/// # Safety
///
/// This method modifies global state without locking and therefore is not thread safe
#[cfg(not(libressl390))]
#[corresponds(X509V3_EXT_add_alias)]
#[deprecated(
note = "Use x509::extension types or new_from_der and then this is not necessary",
@@ -1069,14 +1085,11 @@ 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();
assert!(value.len() <= crate::SLenType::max_value() as usize);
assert!(value.len() <= crate::SLenType::MAX as usize);
cvt(ffi::X509_NAME_add_entry_by_txt(
self.0.as_ptr(),
field.as_ptr() as *mut _,
@@ -1091,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,
@@ -1103,7 +1113,7 @@ impl X509NameBuilder {
) -> Result<(), ErrorStack> {
unsafe {
let field = CString::new(field).unwrap();
assert!(value.len() <= crate::SLenType::max_value() as usize);
assert!(value.len() <= crate::SLenType::MAX as usize);
cvt(ffi::X509_NAME_add_entry_by_txt(
self.0.as_ptr(),
field.as_ptr() as *mut _,
@@ -1118,13 +1128,10 @@ 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_value() as usize);
assert!(value.len() <= crate::SLenType::MAX as usize);
cvt(ffi::X509_NAME_add_entry_by_NID(
self.0.as_ptr(),
field.as_raw(),
@@ -1139,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,
@@ -1150,7 +1154,7 @@ impl X509NameBuilder {
ty: Asn1Type,
) -> Result<(), ErrorStack> {
unsafe {
assert!(value.len() <= crate::SLenType::max_value() as usize);
assert!(value.len() <= crate::SLenType::MAX as usize);
cvt(ffi::X509_NAME_add_entry_by_NID(
self.0.as_ptr(),
field.as_raw(),
@@ -1249,7 +1253,7 @@ impl X509NameRef {
/// Copies the name to a new `X509Name`.
#[corresponds(X509_NAME_dup)]
#[cfg(any(boringssl, ossl110, libressl270))]
#[cfg(any(boringssl, ossl110, libressl270, awslc))]
pub fn to_owned(&self) -> Result<X509Name, ErrorStack> {
unsafe { cvt_p(ffi::X509_NAME_dup(self.as_ptr())).map(|n| X509Name::from_ptr(n)) }
}
@@ -1320,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());
@@ -1333,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());
@@ -1356,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<X509ReqBuilder, ErrorStack> {
unsafe {
ffi::init();
@@ -1368,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 {
@@ -1384,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(
@@ -1399,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<T>(&mut self, key: &PKeyRef<T>) -> Result<(), ErrorStack>
where
T: HasPublic,
@@ -1449,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<T>(&mut self, key: &PKeyRef<T>, hash: MessageDigest) -> Result<(), ErrorStack>
where
T: HasPrivate,
@@ -1545,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());
@@ -1567,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<PKey<Public>, ErrorStack> {
unsafe {
let key = cvt_p(ffi::X509_REQ_get_pubkey(self.as_ptr()))?;
@@ -1581,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<T>(&self, key: &PKeyRef<T>) -> Result<bool, ErrorStack>
where
T: HasPublic,
@@ -1593,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<Stack<X509Extension>, ErrorStack> {
unsafe {
let extensions = cvt_p(ffi::X509_REQ_get_extensions(self.as_ptr()))?;
@@ -1665,7 +1635,7 @@ impl X509RevokedRef {
/// Copies the entry to a new `X509Revoked`.
#[corresponds(X509_NAME_dup)]
#[cfg(any(boringssl, ossl110, libressl270))]
#[cfg(any(boringssl, ossl110, libressl270, awslc))]
pub fn to_owned(&self) -> Result<X509Revoked, ErrorStack> {
unsafe { cvt_p(ffi::X509_REVOKED_dup(self.as_ptr())).map(|n| X509Revoked::from_ptr(n)) }
}
@@ -1745,6 +1715,17 @@ unsafe impl ExtensionType for CertificateIssuer {
type Output = Stack<GeneralName>;
}
/// The CRL extension identifying how to access information and services for the issuer of the CRL
pub enum AuthorityInformationAccess {}
// SAFETY: AuthorityInformationAccess is defined to be a stack of AccessDescription in the RFC
// and in OpenSSL.
unsafe impl ExtensionType for AuthorityInformationAccess {
const NID: Nid = Nid::from_raw(ffi::NID_info_access);
type Output = Stack<AccessDescription>;
}
foreign_type_and_impl_send_sync! {
type CType = ffi::X509_CRL;
fn drop = ffi::X509_CRL_free;
@@ -1914,6 +1895,36 @@ impl X509CrlRef {
{
unsafe { cvt_n(ffi::X509_CRL_verify(self.as_ptr(), key.as_ptr())).map(|n| n != 0) }
}
/// Get the criticality and value of an extension.
///
/// This returns None if the extension is not present or occurs multiple times.
#[corresponds(X509_CRL_get_ext_d2i)]
pub fn extension<T: ExtensionType>(&self) -> Result<Option<(bool, T::Output)>, ErrorStack> {
let mut critical = -1;
let out = unsafe {
// SAFETY: self.as_ptr() is a valid pointer to an X509_CRL.
let ext = ffi::X509_CRL_get_ext_d2i(
self.as_ptr(),
T::NID.as_raw(),
&mut critical as *mut _,
ptr::null_mut(),
);
// SAFETY: Extensions's contract promises that the type returned by
// OpenSSL here is T::Output.
T::Output::from_ptr_opt(ext as *mut _)
};
match (critical, out) {
(0, Some(out)) => Ok(Some((false, out))),
(1, Some(out)) => Ok(Some((true, out))),
// -1 means the extension wasn't found, -2 means multiple were found.
(-1 | -2, _) => Ok(None),
// A critical value of 0 or 1 suggests success, but a null pointer
// was returned so something went wrong.
(0 | 1, None) => Err(ErrorStack::get()),
(c_int::MIN..=-2 | 2.., _) => panic!("OpenSSL should only return -2, -1, 0, or 1 for an extension's criticality but it returned {}", critical),
}
}
}
/// The result of peer certificate verification.
@@ -1955,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();
@@ -1998,11 +2006,11 @@ impl GeneralName {
let s = cvt_p(ffi::ASN1_STRING_type_new(asn1_type.as_raw()))?;
ffi::ASN1_STRING_set(s, value.as_ptr().cast(), value.len().try_into().unwrap());
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
{
(*gn.as_ptr()).d.ptr = s.cast();
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
{
(*gn.as_ptr()).d = s.cast();
}
@@ -2039,11 +2047,11 @@ impl GeneralName {
let gn = cvt_p(ffi::GENERAL_NAME_new())?;
(*gn).type_ = ffi::GEN_RID;
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
{
(*gn).d.registeredID = oid.as_ptr();
}
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
{
(*gn).d = oid.as_ptr().cast();
}
@@ -2054,10 +2062,7 @@ impl GeneralName {
}
}
pub(crate) fn new_other_name(
oid: Asn1Object,
value: &Vec<u8>,
) -> Result<GeneralName, ErrorStack> {
pub(crate) fn new_other_name(oid: Asn1Object, value: &[u8]) -> Result<GeneralName, ErrorStack> {
unsafe {
ffi::init();
@@ -2093,14 +2098,15 @@ impl GeneralNameRef {
return None;
}
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
let d = (*self.as_ptr()).d.ptr;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
let d = (*self.as_ptr()).d;
let ptr = ASN1_STRING_get0_data(d as *mut _);
let len = ffi::ASN1_STRING_length(d as *mut _);
#[allow(clippy::unnecessary_cast)]
let slice = util::from_raw_parts(ptr as *const u8, len as usize);
// IA5Strings are stated to be ASCII (specifically IA5). Hopefully
// OpenSSL checks that when loading a certificate but if not we'll
@@ -2121,9 +2127,9 @@ impl GeneralNameRef {
return None;
}
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
let d = (*self.as_ptr()).d.ptr;
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
let d = (*self.as_ptr()).d;
Some(X509NameRef::from_const_ptr(d as *const _))
@@ -2146,14 +2152,15 @@ impl GeneralNameRef {
if (*self.as_ptr()).type_ != ffi::GEN_IPADD {
return None;
}
#[cfg(boringssl)]
#[cfg(any(boringssl, awslc))]
let d: *const ffi::ASN1_STRING = std::mem::transmute((*self.as_ptr()).d);
#[cfg(not(boringssl))]
#[cfg(not(any(boringssl, awslc)))]
let d = (*self.as_ptr()).d;
let ptr = ASN1_STRING_get0_data(d as *mut _);
let len = ffi::ASN1_STRING_length(d as *mut _);
#[allow(clippy::unnecessary_cast)]
Some(util::from_raw_parts(ptr as *const u8, len as usize))
}
}
@@ -2299,7 +2306,7 @@ impl Stackable for X509Object {
}
cfg_if! {
if #[cfg(any(boringssl, ossl110, libressl273))] {
if #[cfg(any(boringssl, ossl110, libressl273, awslc))] {
use ffi::{X509_getm_notAfter, X509_getm_notBefore, X509_up_ref, X509_get0_signature};
} else {
#[allow(bad_style)]
@@ -2340,7 +2347,7 @@ cfg_if! {
}
cfg_if! {
if #[cfg(any(boringssl, ossl110, libressl350))] {
if #[cfg(any(boringssl, ossl110, libressl350, awslc))] {
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,
@@ -2380,7 +2387,7 @@ cfg_if! {
}
cfg_if! {
if #[cfg(any(ossl110, boringssl, libressl270))] {
if #[cfg(any(ossl110, boringssl, libressl270, awslc))] {
use ffi::X509_OBJECT_get0_X509;
} else {
#[allow(bad_style)]
@@ -2395,10 +2402,8 @@ cfg_if! {
}
cfg_if! {
if #[cfg(any(ossl110, libressl350))] {
if #[cfg(any(ossl110, libressl350, boringssl, awslc))] {
use ffi::X509_OBJECT_free;
} else if #[cfg(boringssl)] {
use ffi::X509_OBJECT_free_contents as X509_OBJECT_free;
} else {
#[allow(bad_style)]
unsafe fn X509_OBJECT_free(x: *mut ffi::X509_OBJECT) {
@@ -2409,7 +2414,7 @@ cfg_if! {
}
cfg_if! {
if #[cfg(any(ossl110, libressl350, boringssl))] {
if #[cfg(any(ossl110, libressl350, boringssl, awslc))] {
use ffi::{
X509_CRL_get_issuer, X509_CRL_get0_nextUpdate, X509_CRL_get0_lastUpdate,
X509_CRL_get_REVOKED,
@@ -2456,6 +2461,8 @@ impl X509PurposeId {
pub const ANY: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_ANY);
pub const OCSP_HELPER: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_OCSP_HELPER);
pub const TIMESTAMP_SIGN: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_TIMESTAMP_SIGN);
#[cfg(ossl320)]
pub const CODE_SIGN: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_CODE_SIGN);
/// Constructs an `X509PurposeId` from a raw OpenSSL value.
pub fn from_raw(id: c_int) -> Self {
@@ -2488,13 +2495,14 @@ impl X509PurposeRef {
/// - "any",
/// - "ocsphelper",
/// - "timestampsign"
///
/// The index can be used with `X509PurposeRef::from_idx()` to get the purpose.
#[allow(clippy::unnecessary_cast)]
pub fn get_by_sname(sname: &str) -> Result<c_int, ErrorStack> {
unsafe {
let sname = CString::new(sname).unwrap();
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
if #[cfg(any(ossl110, libressl280, boringssl, awslc))] {
let purpose = cvt_n(ffi::X509_PURPOSE_get_by_sname(sname.as_ptr() as *const _))?;
} else {
let purpose = cvt_n(ffi::X509_PURPOSE_get_by_sname(sname.as_ptr() as *mut _))?;
@@ -2508,8 +2516,8 @@ impl X509PurposeRef {
#[corresponds(X509_PURPOSE_get0)]
pub fn from_idx(idx: c_int) -> Result<&'static X509PurposeRef, ErrorStack> {
unsafe {
let ptr = cvt_p(ffi::X509_PURPOSE_get0(idx))?;
Ok(X509PurposeRef::from_ptr(ptr))
let ptr = cvt_p_const(ffi::X509_PURPOSE_get0(idx))?;
Ok(X509PurposeRef::from_const_ptr(ptr))
}
}
@@ -2525,8 +2533,14 @@ impl X509PurposeRef {
/// - `X509_PURPOSE_TIMESTAMP_SIGN`
pub fn purpose(&self) -> X509PurposeId {
unsafe {
let x509_purpose: *mut ffi::X509_PURPOSE = self.as_ptr();
X509PurposeId::from_raw((*x509_purpose).purpose)
cfg_if! {
if #[cfg(any(ossl110, libressl280, boringssl, awslc))] {
let x509_purpose = self.as_ptr() as *const ffi::X509_PURPOSE;
} else {
let x509_purpose = self.as_ptr() as *mut ffi::X509_PURPOSE;
}
}
X509PurposeId::from_raw(ffi::X509_PURPOSE_get_id(x509_purpose))
}
}
}

Some files were not shown because too many files have changed in this diff Show More