Compare commits

..

2 Commits

Author SHA1 Message Date
Steven Fackler
95c7bf3cba Release openssl v0.9.24 2018-02-12 11:19:10 -08:00
Steven Fackler
62514d376e Don't leak X509s
(cherry picked from commit b1ab0ec473)
2018-02-12 11:03:09 -08:00
124 changed files with 13072 additions and 21161 deletions

View File

@ -1,303 +1,189 @@
version: 2.1
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
jobs:
linux:
parameters:
target:
type: string
library:
type: string
default: ""
version:
type: string
default: ""
vendored:
type: boolean
default: false
no_run:
type: boolean
default: false
image:
type: string
default: 1.33.0
minimal_build:
type: boolean
default: false
docker:
- image: rust:<< parameters.image >>
environment:
RUST_BACKTRACE: 1
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-static
steps:
- checkout
- run: apt-get update
- run: apt-get remove -y libssl-dev
- run: |
case "<< parameters.target >>" in
"i686-unknown-linux-gnu")
apt-get install -y --no-install-recommends gcc-multilib
;;
"x86_64-unknown-linux-musl")
apt-get install -y --no-install-recommends musl-tools
;;
"arm-unknown-linux-gnueabihf")
dpkg --add-architecture armhf
apt-get update
apt-get install -y --no-install-recommends \
gcc-arm-linux-gnueabihf \
libc6-dev:armhf \
qemu-user-static
;;
"x86_64-unknown-linux-gnu")
exit 0
esac
rustup target add << parameters.target >>
- unless:
condition: << parameters.vendored >>
steps:
- restore_cache:
key: openssl-<< parameters.target >>-<< parameters.library >>-<< parameters.version >>
- run: |
if [ -d "$OPENSSL_DIR" ]; then
exit 0
fi
case "<< parameters.library >>" in
"libressl")
URL="https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-<< parameters.version >>.tar.gz"
;;
"openssl")
URL="https://openssl.org/source/openssl-<< parameters.version >>.tar.gz"
;;
esac
case "<< parameters.target >>" in
"x86_64-unknown-linux-gnu")
OS_COMPILER=linux-x86_64
OS_FLAGS=""
;;
"i686-unknown-linux-gnu")
OS_COMPILER=linux-elf
OS_FLAGS=-m32
;;
"arm-unknown-linux-gnueabihf")
OS_COMPILER=linux-armv4
OS_FLAGS=""
export AR=arm-linux-gnueabihf-ar
export CC=arm-linux-gnueabihf-gcc
;;
esac
mkdir /tmp/build
cd /tmp/build
curl -L $URL | tar --strip-components=1 -xzf -
case "<< parameters.library >>" in
"openssl")
./Configure --prefix=$OPENSSL_DIR $OS_COMPILER -fPIC -g $OS_FLAGS no-shared
;;
"libressl")
./configure --prefix=$OPENSSL_DIR --disable-shared --with-pic
;;
esac
make
make install_sw
- save_cache:
key: openssl-<< parameters.target >>-<< parameters.library >>-<< parameters.version >>
paths:
- /opt/openssl
- restore_cache:
key: registry
- run: cargo generate-lockfile
- when:
condition: << parameters.minimal_build >>
steps:
- run: cargo update -p pkg-config --precise 0.3.14
- save_cache:
key: registry-{{ .BuildNum }}
paths:
- /usr/local/cargo/registry/index
- restore_cache:
key: deps-<< parameters.image >>-<< parameters.target >>-<< parameters.library >>-<< parameters.version >>-{{ checksum "Cargo.lock" }}
- run: |
cargo build \
--manifest-path=openssl/Cargo.toml \
<<# parameters.vendored >>--features vendored<</ parameters.vendored >> \
--target << parameters.target >>
- unless:
condition: << parameters.minimal_build >>
steps:
- run: |
cargo run \
--manifest-path=systest/Cargo.toml \
<<# parameters.vendored >>--features vendored<</ parameters.vendored >> \
--target << parameters.target >>
- run: |
cargo test \
--manifest-path=openssl-errors/Cargo.toml \
<<# parameters.vendored >>--features openssl-sys/vendored<</ parameters.vendored >> \
--target << parameters.target >> \
<<# parameters.no_run >>--no-run<</ parameters.no_run >>
- run: |
ulimit -c unlimited
cargo test \
--manifest-path=openssl/Cargo.toml \
<<# parameters.vendored >>--features vendored<</ parameters.vendored >> \
--target << parameters.target >> \
<<# parameters.no_run >>--no-run<</ parameters.no_run >>
- save_cache:
key: deps-<< parameters.image >>-<< parameters.target >>-<< parameters.library >>-<< parameters.version >>-{{ checksum "Cargo.lock" }}
paths:
- /usr/local/cargo/registry/cache
- target
- run:
command: |
mkdir -p /tmp/core_dumps
find . -name "core.*" -exec cp \{\} /tmp/core_dumps \;
cp target/<< parameters.target >>/debug/openssl-* /tmp/core_dumps
when: on_fail
- store_artifacts:
path: /tmp/core_dumps
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:
parameters:
vendored:
type: boolean
default: false
image:
type: string
default: 1.33.0
macos:
xcode: "9.0"
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:
RUST_BACKTRACE: 1
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 << parameters.image >>
- run: sudo ln -s ~/.cargo/bin/* /usr/local/bin
- run: cargo generate-lockfile
- restore_cache:
key: deps-<< parameters.image >>-macos-<< parameters.vendored >>-{{ checksum "Cargo.lock" }}
- run: |
cargo run \
--manifest-path=systest/Cargo.toml \
<<# parameters.vendored >> --features vendored <</ parameters.vendored >>
- run: |
cargo test \
--manifest-path=openssl-errors/Cargo.toml \
<<# parameters.vendored >> --features openssl-sys/vendored <</ parameters.vendored >>
- run: |
cargo test \
--manifest-path=openssl/Cargo.toml \
<<# parameters.vendored >> --features vendored <</ parameters.vendored >>
- save_cache:
key: deps-<< parameters.image >>-macos-<< parameters.vendored >>-{{ checksum "Cargo.lock" }}
paths:
- ~/.cargo/registry/cache
- target
openssl_111: &openssl_111
library: openssl
version: 1.1.1d
openssl_110: &openssl_110
library: openssl
version: 1.1.0l
openssl_102: &openssl_102
library: openssl
version: 1.0.2t
openssl_101: &openssl_101
library: openssl
version: 1.0.1u
<<: [*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:
test:
version: 2
tests:
jobs:
- linux:
name: mimimal-version
target: x86_64-unknown-linux-musl
vendored: true
image: 1.31.0
minimal_build: true
- linux:
name: musl-vendored
target: x86_64-unknown-linux-musl
vendored: true
- linux:
name: x86_64-vendored
target: x86_64-unknown-linux-gnu
vendored: true
- linux:
<<: *openssl_111
name: x86_64-openssl-1.1.1
target: x86_64-unknown-linux-gnu
- linux:
<<: *openssl_110
name: x86_64-openssl-1.1.0
target: x86_64-unknown-linux-gnu
- linux:
<<: *openssl_102
name: x86_64-openssl-1.0.2
target: x86_64-unknown-linux-gnu
- linux:
<<: *openssl_101
name: x86_64-openssl-1.0.1
target: x86_64-unknown-linux-gnu
- linux:
name: i686-vendored
target: i686-unknown-linux-gnu
vendored: true
- linux:
<<: *openssl_111
name: i686-openssl-1.1.1
target: i686-unknown-linux-gnu
- linux:
<<: *openssl_110
name: i686-openssl-1.1.0
target: i686-unknown-linux-gnu
- linux:
<<: *openssl_102
name: i686-openssl-1.0.2
target: i686-unknown-linux-gnu
- linux:
name: armhf-vendored
target: arm-unknown-linux-gnueabihf
vendored: true
no_run: true
- linux:
<<: *openssl_111
name: armhf-openssl-1.1.1
target: arm-unknown-linux-gnueabihf
no_run: true
- linux:
<<: *openssl_110
name: armhf-openssl-1.1.0
target: arm-unknown-linux-gnueabihf
no_run: true
- linux:
<<: *openssl_102
name: armhf-openssl-1.0.2
target: arm-unknown-linux-gnueabihf
no_run: true
- linux:
name: x86_64-libressl-2.5
target: x86_64-unknown-linux-gnu
library: libressl
version: 2.5.5
- linux:
name: x86_64-libressl-3.0.1
target: x86_64-unknown-linux-gnu
library: libressl
version: 3.0.1
- macos:
name: macos
- macos:
name: macos-vendored
vendored: true
- 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

View File

@ -1,7 +1,2 @@
[workspace]
members = [
"openssl",
"openssl-errors",
"openssl-sys",
"systest",
]
members = ["openssl", "openssl-sys", "systest"]

176
README.md
View File

@ -1,20 +1,176 @@
# rust-openssl
[![CircleCI](https://circleci.com/gh/sfackler/rust-openssl.svg?style=shield)](https://circleci.com/gh/sfackler/rust-openssl)
[![Build status](https://ci.appveyor.com/api/projects/status/d1knobws948pyynk/branch/master?svg=true)](https://ci.appveyor.com/project/sfackler/rust-openssl/branch/master)
[![crates.io](https://img.shields.io/crates/v/openssl.svg)](https://crates.io/crates/openssl)
OpenSSL bindings for the Rust programming language.
[![CircleCI](https://circleci.com/gh/sfackler/rust-openssl.svg?style=shield)](https://circleci.com/gh/sfackler/rust-openssl) [![Build status](https://ci.appveyor.com/api/projects/status/d1knobws948pyynk/branch/master?svg=true)](https://ci.appveyor.com/project/sfackler/rust-openssl/branch/master)
[Documentation](https://docs.rs/openssl).
## Release Support
## Warning
The current supported release is 0.10.
This README does not correspond to rust-openssl 0.7.x or 0.8.x. See
[here](https://github.com/sfackler/rust-openssl/blob/b8fb29db5c246175a096260eacca38180cd77dd0/README.md)
for that README.
New major versions will be published at most once per year. After a new
release, the previous major version will be partially supported with bug
fixes for 3 months, after which support will be dropped entirely.
## Building
rust-openssl depends on OpenSSL version 1.0.1 or above, or LibreSSL. Both the
libraries and headers need to be present in the build environment before this
crate is compiled, and some instructions of how to do this are in the sections
below.
### Linux
On Linux, you can typically install OpenSSL via your package manager. The
headers are sometimes provided in a separate package than the runtime libraries
- look for something like `openssl-devel` or `libssl-dev`. You will also need the
regular development utilities, like `pkg-config`, as the custom build script relies
on them.
```bash
# On Debian and Ubuntu
sudo apt-get install pkg-config libssl-dev
# On Arch Linux
sudo pacman -S openssl
# On Fedora
sudo dnf install openssl-devel
```
If installation via a package manager is not possible, or if you're cross
compiling to a separate target, you'll typically need to compile OpenSSL from
source. That can normally be done with:
```
curl -O https://www.openssl.org/source/openssl-1.1.0f.tar.gz
tar xf openssl-1.1.0f.tar.gz
cd openssl-1.1.0f
export CC=...
./Configure --prefix=... linux-x86_64 -fPIC
make -j$(nproc)
make install
```
### OSX
Although OpenSSL 0.9.8 is preinstalled on OSX this library is being phased out
of OSX and this crate also does not support that version of OpenSSL. To use this
crate on OSX you'll need to install OpenSSL via some alternate means, typically
Homebrew:
```bash
brew install openssl
```
Occasionally an update of XCode or MacOS will cause the linker to fail after compilation, to rectify this you may want to try and run:
```bash
xcode-select --install
```
If Homebrew is installed to the default location of `/usr/local`, OpenSSL will be
automatically detected.
### Windows MSVC
On MSVC it's unfortunately not always a trivial process acquiring OpenSSL. A couple of possibilities
are downloading precompiled binaries for OpenSSL 1.1.0, or installing OpenSSL 1.0.2 using vcpkg.
#### Installing OpenSSL 1.1.0 using precompiled binaries
Perhaps the easiest way to do this right now is to download [precompiled
binaries] and install them on your system. Currently it's recommended to
install the 1.1.0 (non-light) installation if you're choosing this route.
[precompiled binaries]: http://slproweb.com/products/Win32OpenSSL.html
Once a precompiled binary is installed you can configure this crate to find the
installation via an environment variable:
```
set OPENSSL_DIR=C:\OpenSSL-Win64
```
During the installation process if you select "Copy OpenSSL DLLs to: The OpenSSL binaries (/bin)
directory", you will need to add them to the `PATH` environment variable:
```
set PATH=%PATH%;C:\OpenSSL-Win64\bin
```
Now you will need to [install root certificates.](#acquiring-root-certificates)
#### Installing OpenSSL 1.0.2 using vcpkg
Install [vcpkg](https://github.com/Microsoft/vcpkg), and install the OpenSSL port like this:
```Batchfile
vcpkg install openssl:x64-windows
set VCPKG_ROOT=c:\path\to\vcpkg\installation
cargo build
```
For more information see the vcpkg build helper [documentation](http://docs.rs/vcpkg).
To finsh setting up OpenSSL you will need to [install root certificates.](#acquiring-root-certificates)
#### Acquiring Root Certificates
Neither of the above OpenSSL distributions ship with any root certificates.
So to make requests to servers on the internet, you have to install them
manually. Download the [cacert.pem file from here], copy it somewhere safe
(`C:\OpenSSL-Win64\certs` is a good place) and point the `SSL_CERT_FILE`
environment variable there:
```
set SSL_CERT_FILE=C:\OpenSSL-Win64\certs\cacert.pem
```
[cacert.pem file from here]: https://curl.haxx.se/docs/caextract.html
After that, you're just a `cargo build` away!
### Windows GNU (MinGW)
The easiest way to acquire OpenSSL when working with MinGW is to ensure you're
using [MSYS2](http://msys2.github.io) and to then execute:
```
# 32-bit
pacman -S mingw-w64-i686-openssl
# 64-bit
pacman -S mingw-w64-x86_64-openssl
```
And after that, a `cargo build` should be all you need!
### Manual configuration
rust-openssl's build script will by default attempt to locate OpenSSL via
pkg-config or other system-specific mechanisms. This will not work in some
situations however, for example cross compiling or when using a copy of OpenSSL
other than the normal system install.
The build script can be configured via environment variables:
* `OPENSSL_DIR` - If specified, a directory that will be used to find
OpenSSL installation. It's expected that under this directory the `include`
folder has header files and a `lib` folder has the runtime libraries.
* `OPENSSL_LIB_DIR` - If specified, a directory that will be used to find
OpenSSL libraries. Overrides the `lib` folder implied by `OPENSSL_DIR`
(if specified).
* `OPENSSL_INCLUDE_DIR` - If specified, a directory that will be used to find
OpenSSL header files. Overrides the `include` folder implied by `OPENSSL_DIR`
(if specified).
* `OPENSSL_STATIC` - If specified, OpenSSL libraries will be statically rather
than dynamically linked.
* `OPENSSL_LIBS` - If specified, the names of the OpenSSL libraries that will be
linked, e.g. `ssl:crypto`.
If `OPENSSL_DIR` or `OPENSSL_LIB_DIR` and `OPENSSL_INCLUDE_DIR` is specified,
then the build script will skip the pkg-config step.
For target-specific configuration, each of these environment variables can be
prefixed by an upper-cased target, for example,
`X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR`. This can be useful in cross compilation
contexts.
### Contribution

View File

@ -1,24 +1,25 @@
environment:
SSL_CERT_FILE: "C:\\OpenSSL\\cacert.pem"
matrix:
# 1.1.1, 64 bit
# 1.1.0, 64/32 bit
- TARGET: i686-pc-windows-gnu
BITS: 32
MSYS2: 1
OPENSSL_VERSION: 1_1_0g
- TARGET: x86_64-pc-windows-msvc
BITS: 64
OPENSSL_VERSION: 1_1_1d
OPENSSL_VERSION: 1_1_0g
OPENSSL_DIR: C:\OpenSSL
# 1.0.2, 32 bit
- TARGET: i686-pc-windows-msvc
BITS: 32
OPENSSL_VERSION: 1_0_2t
OPENSSL_DIR: C:\OpenSSL
# mingw
# 1.0.2, 64/32 bit
- TARGET: x86_64-pc-windows-gnu
BITS: 64
MSYS2: 1
# vcpkg
OPENSSL_VERSION: 1_0_2m
- TARGET: i686-pc-windows-msvc
BITS: 32
OPENSSL_VERSION: 1_0_2m
OPENSSL_DIR: C:\OpenSSL
- TARGET: x86_64-pc-windows-msvc
VCPKG_DEFAULT_TRIPLET: x64-windows
VCPKGRS_DYNAMIC: 1

View File

@ -1,9 +0,0 @@
# Change Log
## [Unreleased]
## v0.1.0 - 2019-03-14
Initial release
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-errors-v0.1.0...master

View File

@ -1,18 +0,0 @@
[package]
name = "openssl-errors"
version = "0.1.0"
authors = ["Steven Fackler <sfackler@gmail.com>"]
edition = "2018"
license = "MIT/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"]
[dependencies]
libc = "0.2"
openssl-sys = { version = "0.9.42", path = "../openssl-sys" }
[dev-dependencies]
openssl = { version = "0.10.19", path = "../openssl" }

View File

@ -1,202 +0,0 @@
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.

View File

@ -1,19 +0,0 @@
Copyright (c) 2019 Steven Fackler
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1 +0,0 @@
../README.md

View File

@ -1,286 +0,0 @@
//! Custom error library support for the `openssl` crate.
//!
//! OpenSSL allows third-party libraries to integrate with its error API. This crate provides a safe interface to that.
//!
//! # Examples
//!
//! ```
//! use openssl_errors::{openssl_errors, put_error};
//! use openssl::error::Error;
//!
//! // Errors are organized at the top level into "libraries". The
//! // openssl_errors! macro can define these.
//! //
//! // Libraries contain a set of functions and reasons. The library itself,
//! // its functions, and its definitions all all have an associated message
//! // string. This string is what's shown in OpenSSL errors.
//! //
//! // The macro creates a type for each library with associated constants for
//! // its functions and reasons.
//! openssl_errors! {
//! pub library MyLib("my cool library") {
//! functions {
//! FIND_PRIVATE_KEY("find_private_key");
//! }
//!
//! reasons {
//! IO_ERROR("IO error");
//! BAD_PASSWORD("invalid private key password");
//! }
//! }
//! }
//!
//! // The put_error! macro pushes errors onto the OpenSSL error stack.
//! put_error!(MyLib::FIND_PRIVATE_KEY, MyLib::BAD_PASSWORD);
//!
//! // Prints `error:80001002:my cool library:find_private_key:invalid private key password:src/lib.rs:27:`
//! println!("{}", Error::get().unwrap());
//!
//! // You can also optionally attach an extra string of context using the
//! // standard Rust format syntax.
//! let tries = 2;
//! put_error!(MyLib::FIND_PRIVATE_KEY, MyLib::IO_ERROR, "tried {} times", tries);
//!
//! // Prints `error:80001001:my cool library:find_private_key:IO error:src/lib.rs:34:tried 2 times`
//! println!("{}", Error::get().unwrap());
//! ```
#![warn(missing_docs)]
#![doc(html_root_url = "https://docs.rs/openssl-errors/0.1")]
use libc::{c_char, c_int};
use std::borrow::Cow;
use std::marker::PhantomData;
use std::ptr;
#[doc(hidden)]
pub mod export {
pub use libc::{c_char, c_int};
pub use openssl_sys::{
init, ERR_get_next_error_library, ERR_load_strings, ERR_PACK, ERR_STRING_DATA,
};
pub use std::borrow::Cow;
pub use std::option::Option;
pub use std::ptr::null;
pub use std::sync::Once;
}
/// An OpenSSL error library.
pub trait Library {
/// Returns the ID assigned to this library by OpenSSL.
fn id() -> c_int;
}
/// A function declaration, parameterized by its error library.
pub struct Function<T>(c_int, PhantomData<T>);
impl<T> Function<T> {
/// Creates a function from its raw identifier.
#[inline]
pub const fn from_raw(raw: c_int) -> Function<T> {
Function(raw, PhantomData)
}
/// Returns the function's raw identifier.
#[inline]
pub const fn as_raw(&self) -> c_int {
self.0
}
}
/// A reason declaration, parameterized by its error library.
pub struct Reason<T>(c_int, PhantomData<T>);
impl<T> Reason<T> {
/// Creates a reason from its raw identifier.
#[inline]
pub const fn from_raw(raw: c_int) -> Reason<T> {
Reason(raw, PhantomData)
}
/// Returns the reason's raw identifier.
#[inline]
pub const fn as_raw(&self) -> c_int {
self.0
}
}
/// This is not considered part of this crate's public API. It is subject to change at any time.
///
/// # Safety
///
/// `file` and `message` must be null-terminated.
#[doc(hidden)]
pub unsafe fn __put_error<T>(
func: Function<T>,
reason: Reason<T>,
file: &'static str,
line: u32,
message: Option<Cow<'static, str>>,
) where
T: Library,
{
openssl_sys::ERR_put_error(
T::id(),
func.as_raw(),
reason.as_raw(),
file.as_ptr() as *const c_char,
line as c_int,
);
let data = match message {
Some(Cow::Borrowed(s)) => Some((s.as_ptr() as *const c_char as *mut c_char, 0)),
Some(Cow::Owned(s)) => {
let ptr = openssl_sys::CRYPTO_malloc(
s.len() as _,
concat!(file!(), "\0").as_ptr() as *const c_char,
line!() as c_int,
) as *mut c_char;
if ptr.is_null() {
None
} else {
ptr::copy_nonoverlapping(s.as_ptr(), ptr as *mut u8, s.len());
Some((ptr, openssl_sys::ERR_TXT_MALLOCED))
}
}
None => None,
};
if let Some((ptr, flags)) = data {
openssl_sys::ERR_set_error_data(ptr, flags | openssl_sys::ERR_TXT_STRING);
}
}
/// Pushes an error onto the OpenSSL error stack.
///
/// A function and reason are required, and must be associated with the same error library. An additional formatted
/// message string can also optionally be provided.
#[macro_export]
macro_rules! put_error {
($function:expr, $reason:expr) => {
unsafe {
$crate::__put_error(
$function,
$reason,
concat!(file!(), "\0"),
line!(),
$crate::export::Option::None,
);
}
};
($function:expr, $reason:expr, $message:expr) => {
unsafe {
$crate::__put_error(
$function,
$reason,
concat!(file!(), "\0"),
line!(),
$crate::export::Option::Some($crate::export::Cow::Borrowed(
concat!($message, "\0"),
)),
);
}
};
($function:expr, $reason:expr, $message:expr, $($args:tt)*) => {
unsafe {
$crate::__put_error(
$function,
$reason,
concat!(file!(), "\0"),
line!(),
$crate::export::Option::Some($crate::export::Cow::Owned(
format!(concat!($message, "\0"), $($args)*)),
),
);
}
};
}
/// Defines custom OpenSSL error libraries.
///
/// The created libraries can be used with the `put_error!` macro to create custom OpenSSL errors.
#[macro_export]
macro_rules! openssl_errors {
($(
$(#[$lib_attr:meta])*
$lib_vis:vis library $lib_name:ident($lib_str:expr) {
functions {
$(
$(#[$func_attr:meta])*
$func_name:ident($func_str:expr);
)*
}
reasons {
$(
$(#[$reason_attr:meta])*
$reason_name:ident($reason_str:expr);
)*
}
}
)*) => {$(
$(#[$lib_attr])*
$lib_vis enum $lib_name {}
impl $crate::Library for $lib_name {
fn id() -> $crate::export::c_int {
static INIT: $crate::export::Once = $crate::export::Once::new();
static mut LIB_NUM: $crate::export::c_int = 0;
static mut STRINGS: [
$crate::export::ERR_STRING_DATA;
2 + $crate::openssl_errors!(@count $($func_name;)* $($reason_name;)*)
] = [
$crate::export::ERR_STRING_DATA {
error: 0,
string: concat!($lib_str, "\0").as_ptr() as *const $crate::export::c_char,
},
$(
$crate::export::ERR_STRING_DATA {
error: $crate::export::ERR_PACK(0, $lib_name::$func_name.as_raw(), 0),
string: concat!($func_str, "\0").as_ptr() as *const $crate::export::c_char,
},
)*
$(
$crate::export::ERR_STRING_DATA {
error: $crate::export::ERR_PACK(0, 0, $lib_name::$reason_name.as_raw()),
string: concat!($reason_str, "\0").as_ptr() as *const $crate::export::c_char,
},
)*
$crate::export::ERR_STRING_DATA {
error: 0,
string: $crate::export::null(),
}
];
unsafe {
INIT.call_once(|| {
$crate::export::init();
LIB_NUM = $crate::export::ERR_get_next_error_library();
STRINGS[0].error = $crate::export::ERR_PACK(LIB_NUM, 0, 0);
$crate::export::ERR_load_strings(LIB_NUM, STRINGS.as_mut_ptr());
});
LIB_NUM
}
}
}
impl $lib_name {
$crate::openssl_errors!(@func_consts $lib_name; 1; $($(#[$func_attr])* $func_name;)*);
$crate::openssl_errors!(@reason_consts $lib_name; 1; $($(#[$reason_attr])* $reason_name;)*);
}
)*};
(@func_consts $lib_name:ident; $n:expr; $(#[$attr:meta])* $name:ident; $($tt:tt)*) => {
$(#[$attr])*
pub const $name: $crate::Function<$lib_name> = $crate::Function::from_raw($n);
$crate::openssl_errors!(@func_consts $lib_name; $n + 1; $($tt)*);
};
(@func_consts $lib_name:ident; $n:expr;) => {};
(@reason_consts $lib_name:ident; $n:expr; $(#[$attr:meta])* $name:ident; $($tt:tt)*) => {
$(#[$attr])*
pub const $name: $crate::Reason<$lib_name> = $crate::Reason::from_raw($n);
$crate::openssl_errors!(@reason_consts $lib_name; $n + 1; $($tt)*);
};
(@reason_consts $lib_name:ident; $n:expr;) => {};
(@count $i:ident; $($tt:tt)*) => {
1 + $crate::openssl_errors!(@count $($tt)*)
};
(@count) => { 0 };
}

View File

@ -1,54 +0,0 @@
use openssl::error::Error;
openssl_errors::openssl_errors! {
library Test("test library") {
functions {
FOO("function foo");
BAR("function bar");
}
reasons {
NO_MILK("out of milk");
NO_BACON("out of bacon");
}
}
}
#[test]
fn basic() {
openssl_errors::put_error!(Test::FOO, Test::NO_MILK);
let error = Error::get().unwrap();
assert_eq!(error.library().unwrap(), "test library");
assert_eq!(error.function().unwrap(), "function foo");
assert_eq!(error.reason().unwrap(), "out of milk");
assert_eq!(error.file(), "openssl-errors/tests/test.rs");
assert_eq!(error.line(), 19);
assert_eq!(error.data(), None);
}
#[test]
fn static_data() {
openssl_errors::put_error!(Test::BAR, Test::NO_BACON, "foobar");
let error = Error::get().unwrap();
assert_eq!(error.library().unwrap(), "test library");
assert_eq!(error.function().unwrap(), "function bar");
assert_eq!(error.reason().unwrap(), "out of bacon");
assert_eq!(error.file(), "openssl-errors/tests/test.rs");
assert_eq!(error.line(), 32);
assert_eq!(error.data(), Some("foobar"));
}
#[test]
fn dynamic_data() {
openssl_errors::put_error!(Test::BAR, Test::NO_MILK, "hello {}", "world");
let error = Error::get().unwrap();
assert_eq!(error.library().unwrap(), "test library");
assert_eq!(error.function().unwrap(), "function bar");
assert_eq!(error.reason().unwrap(), "out of milk");
assert_eq!(error.file(), "openssl-errors/tests/test.rs");
assert_eq!(error.line(), 45);
assert_eq!(error.data(), Some("hello world"));
}

View File

@ -1,76 +0,0 @@
# Change Log
## [Unreleased]
## [v0.9.50] - 2019-10-02
### Added
* Added `CRYPTO_LOCK_EVP_PKEY`.
* Added `EVP_PKEY_ED25519` and `EVP_PKEY_ED448`.
* Added `EVP_DigestSign` and `EVP_DigestVerify`.
* Added `EVP_PKEY_up_ref`.
* Added `NID_ED25519` and `NID_ED448`.
## [v0.9.49] - 2019-08-15
### Added
* Added support for LibreSSL 3.0.0.
## [v0.9.48] - 2019-07-19
### Added
* Added `AES_wrap_key` and `AES_unwrap_key`.
* Added `EC_GROUP_get_cofactor`, `EC_GROUP_get0_generator`, and `EC_POINT_dup`.
* Added `EVP_aes_128_ofb`, `EVP_aes_192_ecb`, `EVP_aes_192_cbc`, `EVP_aes_192_cfb1`, `EVP_aes_192_cfb8`,
`EVP_aes_192_cfb_128`, `EVP_aes_192_ctr`, `EVP_aes_192_ccm`, `EVP_aes_192_gcm`, `EVP_aes_192_ofb`, and
`EVP_aes_256_ofb`.
* Added `PEM_read_bio_CMS` and `PEM_write_bio_CMS`.
## [v0.9.47] - 2019-05-18
### Added
* Added `SSL_CTX_add_client_CA`.
## [v0.9.46] - 2019-05-08
### Added
* Added support for the LibreSSL 2.9.x series.
## [v0.9.45] - 2019-05-03
### Fixed
* Reverted a change to windows-gnu library names that caused regressions.
## [v0.9.44] - 2019-04-30
### Added
* The `DEP_OPENSSL_VENDORED` environment variable tells downstream build scripts if the vendored feature was enabled.
* Added `EVP_SealInit`, `EVP_SealFinal`, `EVP_EncryptUpdate`, `EVP_OpenInit`, `EVP_OpenFinal`, and `EVP_DecryptUpdate`.
* Added `EVP_PKEY_size`.
### Fixed
* Fixed library names when targeting windows-gnu and pkg-config fails.
## [v0.9.43] - 2019-03-20
### Added
* Added `d2i_CMS_ContentInfo` and `CMS_encrypt`.
* 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.48...master
[v0.9.47]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.47...openssl-sys-v0.9.48
[v0.9.47]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.46...openssl-sys-v0.9.47
[v0.9.46]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.45...openssl-sys-v0.9.46
[v0.9.45]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.44...openssl-sys-v0.9.45
[v0.9.44]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.43...openssl-sys-v0.9.44
[v0.9.43]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.42...openssl-sys-v0.9.43

View File

@ -1,6 +1,6 @@
[package]
name = "openssl-sys"
version = "0.9.50"
version = "0.9.23"
authors = ["Alex Crichton <alex@alexcrichton.com>",
"Steven Fackler <sfackler@gmail.com>"]
license = "MIT"
@ -9,19 +9,14 @@ repository = "https://github.com/sfackler/rust-openssl"
readme = "README.md"
categories = ["cryptography", "external-ffi-bindings"]
links = "openssl"
build = "build/main.rs"
[features]
vendored = ['openssl-src']
build = "build.rs"
[dependencies]
libc = "0.2"
[build-dependencies]
cc = "1.0"
openssl-src = { version = "111.0.1", optional = true }
pkg-config = "0.3.9"
autocfg = "0.1.2"
cc = "1.0"
[target.'cfg(target_env = "msvc")'.build-dependencies]
vcpkg = "0.2"

543
openssl-sys/build.rs Normal file
View File

@ -0,0 +1,543 @@
extern crate pkg_config;
#[cfg(target_env = "msvc")]
extern crate vcpkg;
extern crate cc;
use std::collections::HashSet;
use std::env;
use std::ffi::OsString;
use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::{Path, PathBuf};
use std::panic::{self, AssertUnwindSafe};
use std::process::Command;
// The set of `OPENSSL_NO_<FOO>`s that we care about.
const DEFINES: &'static [&'static str] = &[
"OPENSSL_NO_BUF_FREELISTS",
"OPENSSL_NO_COMP",
"OPENSSL_NO_EC",
"OPENSSL_NO_EC2M",
"OPENSSL_NO_ENGINE",
"OPENSSL_NO_KRB5",
"OPENSSL_NO_NEXTPROTONEG",
"OPENSSL_NO_PSK",
"OPENSSL_NO_RFC3779",
"OPENSSL_NO_SHA",
"OPENSSL_NO_SRP",
"OPENSSL_NO_SSL3_METHOD",
"OPENSSL_NO_TLSEXT",
];
enum Version {
Openssl110,
Openssl102,
Openssl101,
Libressl,
}
fn env(name: &str) -> Option<OsString> {
let prefix = env::var("TARGET").unwrap().to_uppercase().replace("-", "_");
let prefixed = format!("{}_{}", prefix, name);
println!("cargo:rerun-if-env-changed={}", prefixed);
if let Some(var) = env::var_os(&prefixed) {
return Some(var);
}
println!("cargo:rerun-if-env-changed={}", name);
env::var_os(name)
}
fn main() {
let target = env::var("TARGET").unwrap();
let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from);
let include_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from);
let (lib_dir, include_dir) = if lib_dir.is_none() || include_dir.is_none() {
let openssl_dir = env("OPENSSL_DIR").unwrap_or_else(|| find_openssl_dir(&target));
let openssl_dir = Path::new(&openssl_dir);
let lib_dir = lib_dir.unwrap_or_else(|| openssl_dir.join("lib"));
let include_dir = include_dir.unwrap_or_else(|| openssl_dir.join("include"));
(lib_dir, include_dir)
} else {
(lib_dir.unwrap(), include_dir.unwrap())
};
if !Path::new(&lib_dir).exists() {
panic!(
"OpenSSL library directory does not exist: {}",
lib_dir.to_string_lossy()
);
}
if !Path::new(&include_dir).exists() {
panic!(
"OpenSSL include directory does not exist: {}",
include_dir.to_string_lossy()
);
}
println!(
"cargo:rustc-link-search=native={}",
lib_dir.to_string_lossy()
);
println!("cargo:include={}", include_dir.to_string_lossy());
let version = validate_headers(&[include_dir.clone().into()]);
let libs_env = env("OPENSSL_LIBS");
let libs = match libs_env.as_ref().and_then(|s| s.to_str()) {
Some(ref v) => v.split(":").collect(),
None => {
match version {
Version::Openssl101 |
Version::Openssl102 if target.contains("windows") => vec!["ssleay32", "libeay32"],
Version::Openssl110 if target.contains("windows") => vec!["libssl", "libcrypto"],
_ => vec!["ssl", "crypto"],
}
}
};
let kind = determine_mode(Path::new(&lib_dir), &libs);
for lib in libs.into_iter() {
println!("cargo:rustc-link-lib={}={}", kind, lib);
}
}
fn find_openssl_dir(target: &str) -> OsString {
let host = env::var("HOST").unwrap();
if host.contains("apple-darwin") && target.contains("apple-darwin") {
let homebrew = Path::new("/usr/local/opt/openssl@1.1");
if homebrew.exists() {
return homebrew.to_path_buf().into();
}
let homebrew = Path::new("/usr/local/opt/openssl");
if homebrew.exists() {
return homebrew.to_path_buf().into();
}
}
try_pkg_config();
try_vcpkg();
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.
If you're in a situation where you think the directory *should* be found
automatically, please open a bug at https://github.com/sfackler/rust-openssl
and include information about your system as well as this message.
$HOST = {}
$TARGET = {}
openssl-sys = {}
",
host,
target,
env!("CARGO_PKG_VERSION")
);
if host.contains("apple-darwin") && target.contains("apple-darwin") {
let system = Path::new("/usr/lib/libssl.0.9.8.dylib");
if system.exists() {
msg.push_str(&format!(
"
It looks like you're compiling on macOS, where the system contains a version of
OpenSSL 0.9.8. This crate no longer supports OpenSSL 0.9.8.
As a consumer of this crate, you can fix this error by using Homebrew to
install the `openssl` package, or as a maintainer you can use the openssl-sys
0.7 crate for support with OpenSSL 0.9.8.
Unfortunately though the compile cannot continue, so aborting.
"
));
}
}
if host.contains("unknown-linux") && target.contains("unknown-linux-gnu") {
if Command::new("pkg-config").output().is_err() {
msg.push_str(&format!(
"
It looks like you're compiling on Linux and also targeting Linux. Currently this
requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config`
could not be found. If you have OpenSSL installed you can likely fix this by
installing `pkg-config`.
"
));
}
}
if host.contains("windows") && target.contains("windows-gnu") {
msg.push_str(&format!(
"
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
and try building this crate again.
"
));
}
if host.contains("windows") && target.contains("windows-msvc") {
msg.push_str(&format!(
"
It looks like you're compiling for MSVC but we couldn't detect an OpenSSL
installation. If there isn't one installed then you can try the rust-openssl
README for more information about how to download precompiled binaries of
OpenSSL:
https://github.com/sfackler/rust-openssl#windows
"
));
}
panic!(msg);
}
/// Attempt to find OpenSSL through pkg-config.
///
/// Note that if this succeeds then the function does not return as pkg-config
/// typically tells us all the information that we need.
fn try_pkg_config() {
let target = env::var("TARGET").unwrap();
let host = env::var("HOST").unwrap();
// If we're going to windows-gnu we can use pkg-config, but only so long as
// we're coming from a windows host.
//
// Otherwise if we're going to windows we probably can't use pkg-config.
if target.contains("windows-gnu") && host.contains("windows") {
env::set_var("PKG_CONFIG_ALLOW_CROSS", "1");
} else if target.contains("windows") {
return;
}
let lib = match pkg_config::Config::new().print_system_libs(false).find(
"openssl",
) {
Ok(lib) => lib,
Err(e) => {
println!("run pkg_config fail: {:?}", e);
return;
}
};
validate_headers(&lib.include_paths);
for include in lib.include_paths.iter() {
println!("cargo:include={}", include.display());
}
std::process::exit(0);
}
/// Attempt to find OpenSSL through vcpkg.
///
/// Note that if this succeeds then the function does not return as vcpkg
/// should emit all of the cargo metadata that we need.
#[cfg(target_env = "msvc")]
fn try_vcpkg() {
// vcpkg will not emit any metadata if it can not find libraries
// appropriate for the target triple with the desired linkage.
let mut lib = vcpkg::Config::new()
.emit_includes(true)
.lib_name("libcrypto")
.lib_name("libssl")
.probe("openssl");
if let Err(e) = lib {
println!("note: vcpkg did not find openssl as libcrypto and libssl : {:?}",
e);
lib = vcpkg::Config::new()
.emit_includes(true)
.lib_name("libeay32")
.lib_name("ssleay32")
.probe("openssl");
}
if let Err(e) = lib {
println!("note: vcpkg did not find openssl as ssleay32 and libeay32: {:?}",
e);
return;
}
let lib = lib.unwrap();
validate_headers(&lib.include_paths);
println!("cargo:rustc-link-lib=user32");
println!("cargo:rustc-link-lib=gdi32");
println!("cargo:rustc-link-lib=crypt32");
std::process::exit(0);
}
#[cfg(not(target_env = "msvc"))]
fn try_vcpkg() {}
/// Validates the header files found in `include_dir` and then returns the
/// version string of OpenSSL.
fn validate_headers(include_dirs: &[PathBuf]) -> Version {
// This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, and 1.1.0. To
// correctly expose the right API from this crate, take a look at
// `opensslv.h` to see what version OpenSSL claims to be.
//
// OpenSSL has a number of build-time configuration options which affect
// various structs and such. Since OpenSSL 1.1.0 this isn't really a problem
// as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem.
//
// To handle all this conditional compilation we slurp up the configuration
// file of OpenSSL, `opensslconf.h`, and then dump out everything it defines
// as our own #[cfg] directives. That way the `ossl10x.rs` bindings can
// account for compile differences and such.
let mut path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
path.push("expando.c");
let mut file = BufWriter::new(File::create(&path).unwrap());
write!(
file,
"\
#include <openssl/opensslv.h>
#include <openssl/opensslconf.h>
#if LIBRESSL_VERSION_NUMBER >= 0x20700000
RUST_LIBRESSL_NEW
#elif LIBRESSL_VERSION_NUMBER >= 0x20603000
RUST_LIBRESSL_26X
#elif LIBRESSL_VERSION_NUMBER >= 0x20602000
RUST_LIBRESSL_262
#elif LIBRESSL_VERSION_NUMBER >= 0x20601000
RUST_LIBRESSL_261
#elif LIBRESSL_VERSION_NUMBER >= 0x20600000
RUST_LIBRESSL_260
#elif LIBRESSL_VERSION_NUMBER >= 0x20503000
RUST_LIBRESSL_25X
#elif LIBRESSL_VERSION_NUMBER >= 0x20502000
RUST_LIBRESSL_252
#elif LIBRESSL_VERSION_NUMBER >= 0x20501000
RUST_LIBRESSL_251
#elif LIBRESSL_VERSION_NUMBER >= 0x20500000
RUST_LIBRESSL_250
#elif defined (LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20500000
RUST_LIBRESSL_OLD
#elif OPENSSL_VERSION_NUMBER >= 0x10101000
RUST_OPENSSL_NEW
#elif OPENSSL_VERSION_NUMBER >= 0x10100060
RUST_OPENSSL_110F
#elif OPENSSL_VERSION_NUMBER >= 0x10100000
RUST_OPENSSL_110
#elif OPENSSL_VERSION_NUMBER >= 0x10002000
RUST_OPENSSL_102
#elif OPENSSL_VERSION_NUMBER >= 0x10001000
RUST_OPENSSL_101
#else
RUST_OPENSSL_OLD
#endif
"
).unwrap();
for define in DEFINES {
write!(
file,
"\
#ifdef {define}
RUST_{define}_RUST
#endif
",
define = define
).unwrap();
}
file.flush().unwrap();
drop(file);
let mut gcc = cc::Build::new();
for include_dir in include_dirs {
gcc.include(include_dir);
}
// https://github.com/alexcrichton/gcc-rs/issues/133
let expanded = match panic::catch_unwind(AssertUnwindSafe(|| gcc.file(&path).expand())) {
Ok(expanded) => expanded,
Err(_) => {
panic!(
"
Failed to find OpenSSL development headers.
You can try fixing this setting the `OPENSSL_DIR` environment variable
pointing to your OpenSSL installation or installing OpenSSL headers package
specific to your distribution:
# On Ubuntu
sudo apt-get install libssl-dev
# On Arch Linux
sudo pacman -S openssl
# On Fedora
sudo dnf install openssl-devel
See rust-openssl README for more information:
https://github.com/sfackler/rust-openssl#linux
"
);
}
};
let expanded = String::from_utf8(expanded).unwrap();
let mut enabled = vec![];
for &define in DEFINES {
if expanded.contains(&format!("RUST_{}_RUST", define)) {
println!("cargo:rustc-cfg=osslconf=\"{}\"", define);
enabled.push(define);
}
}
println!("cargo:conf={}", enabled.join(","));
if expanded.contains("RUST_LIBRESSL_250") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl250");
println!("cargo:libressl=true");
println!("cargo:libressl_version=250");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_251") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl251");
println!("cargo:libressl=true");
println!("cargo:libressl_version=251");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_252") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl252");
println!("cargo:libressl=true");
println!("cargo:libressl_version=252");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_25X") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl25x");
println!("cargo:libressl=true");
println!("cargo:libressl_version=25x");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_260") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl260");
println!("cargo:libressl=true");
println!("cargo:libressl_version=260");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_261") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl261");
println!("cargo:libressl=true");
println!("cargo:libressl_version=261");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_262") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl262");
println!("cargo:libressl=true");
println!("cargo:libressl_version=262");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_LIBRESSL_26X") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:rustc-cfg=libressl26x");
println!("cargo:libressl=true");
println!("cargo:libressl_version=26x");
println!("cargo:version=101");
Version::Libressl
} else if expanded.contains("RUST_OPENSSL_110F") {
println!("cargo:rustc-cfg=ossl110");
println!("cargo:rustc-cfg=ossl110f");
println!("cargo:version=110");
println!("cargo:patch=f");
Version::Openssl110
} else if expanded.contains("RUST_OPENSSL_110") {
println!("cargo:rustc-cfg=ossl110");
println!("cargo:version=110");
Version::Openssl110
} else if expanded.contains("RUST_OPENSSL_102") {
println!("cargo:rustc-cfg=ossl102");
println!("cargo:version=102");
Version::Openssl102
} else if expanded.contains("RUST_OPENSSL_101") {
println!("cargo:rustc-cfg=ossl101");
println!("cargo:version=101");
Version::Openssl101
} else {
panic!(
"
This crate is only compatible with OpenSSL 1.0.1, 1.0.2, and 1.1.0, or LibreSSL
2.5 and 2.6.0, but a different version of OpenSSL was found. The build is now
aborting due to this version mismatch.
"
);
}
}
/// Given a libdir for OpenSSL (where artifacts are located) as well as the name
/// of the libraries we're linking to, figure out whether we should link them
/// statically or dynamically.
fn determine_mode(libdir: &Path, libs: &[&str]) -> &'static str {
// First see if a mode was explicitly requested
let kind = env("OPENSSL_STATIC");
match kind.as_ref().and_then(|s| s.to_str()).map(|s| &s[..]) {
Some("0") => return "dylib",
Some(_) => return "static",
None => {}
}
// Next, see what files we actually have to link against, and see what our
// possibilities even are.
let files = libdir
.read_dir()
.unwrap()
.map(|e| e.unwrap())
.map(|e| e.file_name())
.filter_map(|e| e.into_string().ok())
.collect::<HashSet<_>>();
let can_static = libs.iter().all(|l| {
files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l))
});
let can_dylib = libs.iter().all(|l| {
files.contains(&format!("lib{}.so", l)) || files.contains(&format!("{}.dll", l)) ||
files.contains(&format!("lib{}.dylib", l))
});
match (can_static, can_dylib) {
(true, false) => return "static",
(false, true) => return "dylib",
(false, false) => {
panic!(
"OpenSSL libdir at `{}` does not contain the required files \
to either statically or dynamically link OpenSSL",
libdir.display()
);
}
(true, true) => {}
}
// Ok, we've got not explicit preference and can *either* link statically or
// link dynamically. In the interest of "security upgrades" and/or "best
// practices with security libs", let's link dynamically.
"dylib"
}

View File

@ -1,67 +0,0 @@
pub fn get(openssl_version: Option<u64>, libressl_version: Option<u64>) -> Vec<&'static str> {
let mut cfgs = vec![];
if let Some(libressl_version) = libressl_version {
cfgs.push("libressl");
if libressl_version >= 0x2_05_01_00_0 {
cfgs.push("libressl251");
}
if libressl_version >= 0x2_06_01_00_0 {
cfgs.push("libressl261");
}
if libressl_version >= 0x2_07_00_00_0 {
cfgs.push("libressl270");
}
if libressl_version >= 0x2_07_01_00_0 {
cfgs.push("libressl271");
}
if libressl_version >= 0x2_07_03_00_0 {
cfgs.push("libressl273");
}
if libressl_version >= 0x2_08_00_00_0 {
cfgs.push("libressl280");
}
if libressl_version >= 0x2_08_01_00_0 {
cfgs.push("libressl281");
}
if libressl_version >= 0x2_09_01_00_0 {
cfgs.push("libressl291");
}
} else {
let openssl_version = openssl_version.unwrap();
if openssl_version >= 0x1_00_01_00_0 {
cfgs.push("ossl101");
}
if openssl_version >= 0x1_00_02_00_0 {
cfgs.push("ossl102");
}
if openssl_version >= 0x1_00_02_06_0 {
cfgs.push("ossl102f");
}
if openssl_version >= 0x1_00_02_08_0 {
cfgs.push("ossl102h");
}
if openssl_version >= 0x1_01_00_00_0 {
cfgs.push("ossl110");
}
if openssl_version >= 0x1_01_00_06_0 {
cfgs.push("ossl110f");
}
if openssl_version >= 0x1_01_00_07_0 {
cfgs.push("ossl110g");
}
if openssl_version >= 0x1_01_01_00_0 {
cfgs.push("ossl111");
}
if openssl_version >= 0x1_01_01_02_0 {
cfgs.push("ossl111b");
}
if openssl_version >= 0x1_01_01_03_0 {
cfgs.push("ossl111c");
}
}
cfgs
}

View File

@ -1,67 +0,0 @@
#include <openssl/opensslv.h>
#include <openssl/opensslconf.h>
#define VERSION2(n, v) RUST_VERSION_##n##_##v
#define VERSION(n, v) VERSION2(n, v)
#ifdef LIBRESSL_VERSION_NUMBER
VERSION(LIBRESSL, LIBRESSL_VERSION_NUMBER)
#else
VERSION(OPENSSL, OPENSSL_VERSION_NUMBER)
#endif
#ifdef OPENSSL_NO_BUF_FREELISTS
RUST_CONF_OPENSSL_NO_BUF_FREELISTS
#endif
#ifdef OPENSSL_NO_COMP
RUST_CONF_OPENSSL_NO_COMP
#endif
#ifdef OPENSSL_NO_EC
RUST_CONF_OPENSSL_NO_EC
#endif
#ifdef OPENSSL_NO_EC2M
RUST_CONF_OPENSSL_NO_EC2M
#endif
#ifdef OPENSSL_NO_ENGINE
RUST_CONF_OPENSSL_NO_ENGINE
#endif
#ifdef OPENSSL_NO_KRB5
RUST_CONF_OPENSSL_NO_KRB5
#endif
#ifdef OPENSSL_NO_NEXTPROTONEG
RUST_CONF_OPENSSL_NO_NEXTPROTONEG
#endif
#ifdef OPENSSL_NO_PSK
RUST_CONF_OPENSSL_NO_PSK
#endif
#ifdef OPENSSL_NO_RFC3779
RUST_CONF_OPENSSL_NO_RFC3779
#endif
#ifdef OPENSSL_NO_SHA
RUST_CONF_OPENSSL_NO_SHA
#endif
#ifdef OPENSSL_NO_SRP
RUST_CONF_OPENSSL_NO_SRP
#endif
#ifdef OPENSSL_NO_SSL3_METHOD
RUST_CONF_OPENSSL_NO_SSL3_METHOD
#endif
#ifdef OPENSSL_NO_TLSEXT
RUST_CONF_OPENSSL_NO_TLSEXT
#endif
#ifdef OPENSSL_NO_STDIO
RUST_CONF_OPENSSL_NO_STDIO
#endif

View File

@ -1,251 +0,0 @@
use pkg_config;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
use std::process::{self, Command};
use super::env;
pub fn get_openssl(target: &str) -> (PathBuf, PathBuf) {
let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from);
let include_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from);
if lib_dir.is_none() || include_dir.is_none() {
let openssl_dir = env("OPENSSL_DIR").unwrap_or_else(|| find_openssl_dir(&target));
let openssl_dir = Path::new(&openssl_dir);
let lib_dir = lib_dir.unwrap_or_else(|| openssl_dir.join("lib"));
let include_dir = include_dir.unwrap_or_else(|| openssl_dir.join("include"));
(lib_dir, include_dir)
} else {
(lib_dir.unwrap(), include_dir.unwrap())
}
}
fn find_openssl_dir(target: &str) -> OsString {
let host = env::var("HOST").unwrap();
if host == target && target.contains("apple-darwin") {
// Check up default Homebrew installation location first
// for quick resolution if possible.
let homebrew = Path::new("/usr/local/opt/openssl@1.1");
if homebrew.exists() {
return homebrew.to_path_buf().into();
}
let homebrew = Path::new("/usr/local/opt/openssl");
if homebrew.exists() {
return homebrew.to_path_buf().into();
}
// Calling `brew --prefix <package>` command usually slow and
// takes seconds, and will be used only as a last resort.
let output = execute_command_and_get_output("brew", &["--prefix", "openssl@1.1"]);
if let Some(ref output) = output {
let homebrew = Path::new(&output);
if homebrew.exists() {
return homebrew.to_path_buf().into();
}
}
let output = execute_command_and_get_output("brew", &["--prefix", "openssl"]);
if let Some(ref output) = output {
let homebrew = Path::new(&output);
if homebrew.exists() {
return homebrew.to_path_buf().into();
}
}
}
try_pkg_config();
try_vcpkg();
// FreeBSD ships with OpenSSL but doesn't include a pkg-config file :(
if host == target && target.contains("freebsd") {
return OsString::from("/usr");
}
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.
If you're in a situation where you think the directory *should* be found
automatically, please open a bug at https://github.com/sfackler/rust-openssl
and include information about your system as well as this message.
$HOST = {}
$TARGET = {}
openssl-sys = {}
",
host,
target,
env!("CARGO_PKG_VERSION")
);
if host.contains("apple-darwin") && target.contains("apple-darwin") {
let system = Path::new("/usr/lib/libssl.0.9.8.dylib");
if system.exists() {
msg.push_str(&format!(
"
It looks like you're compiling on macOS, where the system contains a version of
OpenSSL 0.9.8. This crate no longer supports OpenSSL 0.9.8.
As a consumer of this crate, you can fix this error by using Homebrew to
install the `openssl` package, or as a maintainer you can use the openssl-sys
0.7 crate for support with OpenSSL 0.9.8.
Unfortunately though the compile cannot continue, so aborting.
"
));
}
}
if host.contains("unknown-linux") && target.contains("unknown-linux-gnu") {
if Command::new("pkg-config").output().is_err() {
msg.push_str(&format!(
"
It looks like you're compiling on Linux and also targeting Linux. Currently this
requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config`
could not be found. If you have OpenSSL installed you can likely fix this by
installing `pkg-config`.
"
));
}
}
if host.contains("windows") && target.contains("windows-gnu") {
msg.push_str(&format!(
"
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
and try building this crate again.
"
));
}
if host.contains("windows") && target.contains("windows-msvc") {
msg.push_str(&format!(
"
It looks like you're compiling for MSVC but we couldn't detect an OpenSSL
installation. If there isn't one installed then you can try the rust-openssl
README for more information about how to download precompiled binaries of
OpenSSL:
https://github.com/sfackler/rust-openssl#windows
"
));
}
panic!(msg);
}
/// Attempt to find OpenSSL through pkg-config.
///
/// Note that if this succeeds then the function does not return as pkg-config
/// typically tells us all the information that we need.
fn try_pkg_config() {
let target = env::var("TARGET").unwrap();
let host = env::var("HOST").unwrap();
// If we're going to windows-gnu we can use pkg-config, but only so long as
// we're coming from a windows host.
//
// Otherwise if we're going to windows we probably can't use pkg-config.
if target.contains("windows-gnu") && host.contains("windows") {
env::set_var("PKG_CONFIG_ALLOW_CROSS", "1");
} else if target.contains("windows") {
return;
}
let lib = match pkg_config::Config::new()
.print_system_libs(false)
.find("openssl")
{
Ok(lib) => lib,
Err(e) => {
println!("run pkg_config fail: {:?}", e);
return;
}
};
super::validate_headers(&lib.include_paths);
for include in lib.include_paths.iter() {
println!("cargo:include={}", include.display());
}
process::exit(0);
}
/// Attempt to find OpenSSL through vcpkg.
///
/// Note that if this succeeds then the function does not return as vcpkg
/// should emit all of the cargo metadata that we need.
#[cfg(target_env = "msvc")]
fn try_vcpkg() {
use vcpkg;
// vcpkg will not emit any metadata if it can not find libraries
// appropriate for the target triple with the desired linkage.
let mut lib = vcpkg::Config::new()
.emit_includes(true)
.lib_name("libcrypto")
.lib_name("libssl")
.probe("openssl");
if let Err(e) = lib {
println!(
"note: vcpkg did not find openssl as libcrypto and libssl: {}",
e
);
lib = vcpkg::Config::new()
.emit_includes(true)
.lib_name("libeay32")
.lib_name("ssleay32")
.probe("openssl");
}
if let Err(e) = lib {
println!(
"note: vcpkg did not find openssl as ssleay32 and libeay32: {}",
e
);
return;
}
let lib = lib.unwrap();
super::validate_headers(&lib.include_paths);
println!("cargo:rustc-link-lib=user32");
println!("cargo:rustc-link-lib=gdi32");
println!("cargo:rustc-link-lib=crypt32");
process::exit(0);
}
#[cfg(not(target_env = "msvc"))]
fn try_vcpkg() {}
fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option<String> {
let out = Command::new(cmd).args(args).output();
if let Ok(ref r1) = out {
if r1.status.success() {
let r2 = String::from_utf8(r1.stdout.clone());
if let Ok(r3) = r2 {
return Some(r3.trim().to_string());
}
}
}
return None;
}

View File

@ -1,13 +0,0 @@
use openssl_src;
use std::path::PathBuf;
pub fn get_openssl(_target: &str) -> (PathBuf, PathBuf) {
let artifacts = openssl_src::Build::new().build();
println!("cargo:vendored=1");
println!("cargo:root={}", artifacts.lib_dir().parent().unwrap().display());
(
artifacts.lib_dir().to_path_buf(),
artifacts.include_dir().to_path_buf(),
)
}

View File

@ -1,315 +0,0 @@
extern crate cc;
#[cfg(feature = "vendored")]
extern crate openssl_src;
extern crate pkg_config;
extern crate autocfg;
#[cfg(target_env = "msvc")]
extern crate vcpkg;
use std::collections::HashSet;
use std::env;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
mod cfgs;
#[cfg_attr(feature = "vendored", path = "find_vendored.rs")]
#[cfg_attr(not(feature = "vendored"), path = "find_normal.rs")]
mod find;
enum Version {
Openssl11x,
Openssl10x,
Libressl,
}
fn env_inner(name: &str) -> Option<OsString> {
let var = env::var_os(name);
println!("cargo:rerun-if-env-changed={}", name);
match var {
Some(ref v) => println!("{} = {}", name, v.to_string_lossy()),
None => println!("{} unset", name),
}
var
}
fn env(name: &str) -> Option<OsString> {
let prefix = env::var("TARGET").unwrap().to_uppercase().replace("-", "_");
let prefixed = format!("{}_{}", prefix, name);
env_inner(&prefixed).or_else(|| env_inner(name))
}
fn main() {
check_rustc_versions();
let target = env::var("TARGET").unwrap();
let (lib_dir, include_dir) = find::get_openssl(&target);
if !Path::new(&lib_dir).exists() {
panic!(
"OpenSSL library directory does not exist: {}",
lib_dir.to_string_lossy()
);
}
if !Path::new(&include_dir).exists() {
panic!(
"OpenSSL include directory does not exist: {}",
include_dir.to_string_lossy()
);
}
println!(
"cargo:rustc-link-search=native={}",
lib_dir.to_string_lossy()
);
println!("cargo:include={}", include_dir.to_string_lossy());
let version = validate_headers(&[include_dir.clone().into()]);
let libs_env = env("OPENSSL_LIBS");
let libs = match libs_env.as_ref().and_then(|s| s.to_str()) {
Some(ref v) => v.split(":").collect(),
None => match version {
Version::Openssl10x if target.contains("windows") => vec!["ssleay32", "libeay32"],
Version::Openssl11x if target.contains("windows") => vec!["libssl", "libcrypto"],
_ => vec!["ssl", "crypto"],
},
};
let kind = determine_mode(Path::new(&lib_dir), &libs);
for lib in libs.into_iter() {
println!("cargo:rustc-link-lib={}={}", kind, lib);
}
if kind == "static" && target.contains("windows") {
println!("cargo:rustc-link-lib=dylib=gdi32");
println!("cargo:rustc-link-lib=dylib=user32");
println!("cargo:rustc-link-lib=dylib=crypt32");
println!("cargo:rustc-link-lib=dylib=ws2_32");
println!("cargo:rustc-link-lib=dylib=advapi32");
}
}
fn check_rustc_versions() {
let cfg = autocfg::new();
if cfg.probe_rustc_version(1, 31) {
println!("cargo:rustc-cfg=const_fn");
}
}
/// Validates the header files found in `include_dir` and then returns the
/// version string of OpenSSL.
fn validate_headers(include_dirs: &[PathBuf]) -> Version {
// This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, and 1.1.0. To
// correctly expose the right API from this crate, take a look at
// `opensslv.h` to see what version OpenSSL claims to be.
//
// OpenSSL has a number of build-time configuration options which affect
// various structs and such. Since OpenSSL 1.1.0 this isn't really a problem
// as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem.
//
// To handle all this conditional compilation we slurp up the configuration
// file of OpenSSL, `opensslconf.h`, and then dump out everything it defines
// as our own #[cfg] directives. That way the `ossl10x.rs` bindings can
// account for compile differences and such.
let mut gcc = cc::Build::new();
for include_dir in include_dirs {
gcc.include(include_dir);
}
let expanded = match gcc.file("build/expando.c").try_expand() {
Ok(expanded) => expanded,
Err(e) => {
panic!(
"
Header expansion error:
{:?}
Failed to find OpenSSL development headers.
You can try fixing this setting the `OPENSSL_DIR` environment variable
pointing to your OpenSSL installation or installing OpenSSL headers package
specific to your distribution:
# On Ubuntu
sudo apt-get install libssl-dev
# On Arch Linux
sudo pacman -S openssl
# On Fedora
sudo dnf install openssl-devel
See rust-openssl README for more information:
https://github.com/sfackler/rust-openssl#linux
",
e
);
}
};
let expanded = String::from_utf8(expanded).unwrap();
let mut enabled = vec![];
let mut openssl_version = None;
let mut libressl_version = None;
for line in expanded.lines() {
let line = line.trim();
let openssl_prefix = "RUST_VERSION_OPENSSL_";
let libressl_prefix = "RUST_VERSION_LIBRESSL_";
let conf_prefix = "RUST_CONF_";
if line.starts_with(openssl_prefix) {
let version = &line[openssl_prefix.len()..];
openssl_version = Some(parse_version(version));
} else if line.starts_with(libressl_prefix) {
let version = &line[libressl_prefix.len()..];
libressl_version = Some(parse_version(version));
} else if line.starts_with(conf_prefix) {
enabled.push(&line[conf_prefix.len()..]);
}
}
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);
}
if let Some(libressl_version) = libressl_version {
println!("cargo:libressl_version_number={:x}", libressl_version);
let major = (libressl_version >> 28) as u8;
let minor = (libressl_version >> 20) as u8;
let fix = (libressl_version >> 12) as u8;
let (major, minor, fix) = match (major, minor, fix) {
(2, 5, 0) => ('2', '5', '0'),
(2, 5, 1) => ('2', '5', '1'),
(2, 5, 2) => ('2', '5', '2'),
(2, 5, _) => ('2', '5', 'x'),
(2, 6, 0) => ('2', '6', '0'),
(2, 6, 1) => ('2', '6', '1'),
(2, 6, 2) => ('2', '6', '2'),
(2, 6, _) => ('2', '6', 'x'),
(2, 7, _) => ('2', '7', 'x'),
(2, 8, 0) => ('2', '8', '0'),
(2, 8, 1) => ('2', '8', '1'),
(2, 8, _) => ('2', '8', 'x'),
(2, 9, 0) => ('2', '9', '0'),
(2, 9, _) => ('2', '9', 'x'),
(3, 0, 0) => ('3', '0', '0'),
(3, 0, 1) => ('3', '0', '1'),
_ => version_error(),
};
println!("cargo:libressl=true");
println!("cargo:libressl_version={}{}{}", major, minor, fix);
println!("cargo:version=101");
Version::Libressl
} else {
let openssl_version = openssl_version.unwrap();
println!("cargo:version_number={:x}", openssl_version);
if openssl_version >= 0x1_01_02_00_0 {
version_error()
} else if openssl_version >= 0x1_01_01_00_0 {
println!("cargo:version=111");
Version::Openssl11x
} else if openssl_version >= 0x1_01_00_06_0 {
println!("cargo:version=110");
println!("cargo:patch=f");
Version::Openssl11x
} else if openssl_version >= 0x1_01_00_00_0 {
println!("cargo:version=110");
Version::Openssl11x
} else if openssl_version >= 0x1_00_02_00_0 {
println!("cargo:version=102");
Version::Openssl10x
} else if openssl_version >= 0x1_00_01_00_0 {
println!("cargo:version=101");
Version::Openssl10x
} else {
version_error()
}
}
}
fn version_error() -> ! {
panic!(
"
This crate is only compatible with OpenSSL 1.0.1 through 1.1.1, or LibreSSL 2.5
through 3.0.1, but a different version of OpenSSL was found. The build is now aborting
due to this version mismatch.
"
);
}
// parses a string that looks like "0x100020cfL"
#[allow(deprecated)] // trim_right_matches is now trim_end_matches
fn parse_version(version: &str) -> u64 {
// cut off the 0x prefix
assert!(version.starts_with("0x"));
let version = &version[2..];
// and the type specifier suffix
let version = version.trim_right_matches(|c: char| match c {
'0'..='9' | 'a'..='f' | 'A'..='F' => false,
_ => true,
});
u64::from_str_radix(version, 16).unwrap()
}
/// Given a libdir for OpenSSL (where artifacts are located) as well as the name
/// of the libraries we're linking to, figure out whether we should link them
/// statically or dynamically.
fn determine_mode(libdir: &Path, libs: &[&str]) -> &'static str {
// First see if a mode was explicitly requested
let kind = env("OPENSSL_STATIC");
match kind.as_ref().and_then(|s| s.to_str()).map(|s| &s[..]) {
Some("0") => return "dylib",
Some(_) => return "static",
None => {}
}
// Next, see what files we actually have to link against, and see what our
// possibilities even are.
let files = libdir
.read_dir()
.unwrap()
.map(|e| e.unwrap())
.map(|e| e.file_name())
.filter_map(|e| e.into_string().ok())
.collect::<HashSet<_>>();
let can_static = libs
.iter()
.all(|l| files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l)));
let can_dylib = libs.iter().all(|l| {
files.contains(&format!("lib{}.so", l))
|| files.contains(&format!("{}.dll", l))
|| files.contains(&format!("lib{}.dylib", l))
});
match (can_static, can_dylib) {
(true, false) => return "static",
(false, true) => return "dylib",
(false, false) => {
panic!(
"OpenSSL libdir at `{}` does not contain the required files \
to either statically or dynamically link OpenSSL",
libdir.display()
);
}
(true, true) => {}
}
// Ok, we've got not explicit preference and can *either* link statically or
// link dynamically. In the interest of "security upgrades" and/or "best
// practices with security libs", let's link dynamically.
"dylib"
}

View File

@ -1,44 +0,0 @@
use libc::*;
pub const AES_ENCRYPT: c_int = 1;
pub const AES_DECRYPT: c_int = 0;
pub const AES_MAXNR: c_int = 14;
pub const AES_BLOCK_SIZE: c_int = 16;
#[repr(C)]
pub struct AES_KEY {
// There is some business with AES_LONG which is there to ensure the values here are 32 bits
rd_key: [u32; 4 * (AES_MAXNR as usize + 1)],
rounds: c_int,
}
extern "C" {
pub fn AES_set_encrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int;
pub fn AES_set_decrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int;
pub fn AES_ige_encrypt(
in_: *const c_uchar,
out: *mut c_uchar,
length: size_t,
key: *const AES_KEY,
ivec: *mut c_uchar,
enc: c_int,
);
pub fn AES_wrap_key(
key: *mut AES_KEY,
iv: *const c_uchar,
out: *mut c_uchar,
in_: *const c_uchar,
inlen: c_uint,
) -> c_int;
pub fn AES_unwrap_key(
key: *mut AES_KEY,
iv: *const c_uchar,
out: *mut c_uchar,
in_: *const c_uchar,
inlen: c_uint,
) -> c_int;
}

View File

@ -1,66 +0,0 @@
use libc::*;
use *;
pub const V_ASN1_UTCTIME: c_int = 23;
pub const V_ASN1_GENERALIZEDTIME: c_int = 24;
pub const MBSTRING_FLAG: c_int = 0x1000;
pub const MBSTRING_UTF8: c_int = MBSTRING_FLAG;
pub const MBSTRING_ASC: c_int = MBSTRING_FLAG | 1;
pub const MBSTRING_BMP: c_int = MBSTRING_FLAG | 2;
pub const MBSTRING_UNIV: c_int = MBSTRING_FLAG | 4;
#[repr(C)]
pub struct ASN1_ENCODING {
pub enc: *mut c_uchar,
pub len: c_long,
pub modified: c_int,
}
extern "C" {
pub fn ASN1_OBJECT_free(x: *mut ASN1_OBJECT);
}
stack!(stack_st_ASN1_OBJECT);
extern "C" {
pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING;
#[cfg(any(ossl110, libressl273))]
pub fn ASN1_STRING_get0_data(x: *const ASN1_STRING) -> *const c_uchar;
#[cfg(any(all(ossl101, not(ossl110)), libressl))]
pub fn ASN1_STRING_data(x: *mut ASN1_STRING) -> *mut c_uchar;
pub fn ASN1_BIT_STRING_free(x: *mut ASN1_BIT_STRING);
pub fn ASN1_STRING_free(x: *mut ASN1_STRING);
pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int;
pub fn ASN1_GENERALIZEDTIME_free(tm: *mut ASN1_GENERALIZEDTIME);
pub fn ASN1_GENERALIZEDTIME_print(b: *mut BIO, tm: *const ASN1_GENERALIZEDTIME) -> c_int;
pub fn ASN1_TIME_new() -> *mut ASN1_TIME;
pub fn ASN1_TIME_free(tm: *mut ASN1_TIME);
pub fn ASN1_TIME_print(b: *mut BIO, tm: *const ASN1_TIME) -> c_int;
pub fn ASN1_INTEGER_free(x: *mut ASN1_INTEGER);
pub fn ASN1_INTEGER_get(dest: *const ASN1_INTEGER) -> c_long;
pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int;
pub fn BN_to_ASN1_INTEGER(bn: *const BIGNUM, ai: *mut ASN1_INTEGER) -> *mut ASN1_INTEGER;
pub fn ASN1_INTEGER_to_BN(ai: *const ASN1_INTEGER, bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn ASN1_TIME_set_string(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
#[cfg(ossl111)]
pub fn ASN1_TIME_set_string_X509(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
extern "C" {
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *const ASN1_STRING) -> c_int;
}
} else {
extern "C" {
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *mut ASN1_STRING) -> c_int;
}
}
}

View File

@ -1,151 +0,0 @@
use libc::*;
use *;
pub const BIO_TYPE_NONE: c_int = 0;
pub const BIO_CTRL_EOF: c_int = 2;
pub const BIO_CTRL_INFO: c_int = 3;
pub const BIO_CTRL_FLUSH: c_int = 11;
pub const BIO_C_SET_BUF_MEM_EOF_RETURN: c_int = 130;
extern "C" {
pub fn BIO_set_flags(b: *mut BIO, flags: c_int);
pub fn BIO_clear_flags(b: *mut BIO, flags: c_int);
}
pub unsafe fn BIO_set_retry_read(b: *mut BIO) {
BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY)
}
pub unsafe fn BIO_set_retry_write(b: *mut BIO) {
BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY)
}
pub unsafe fn BIO_clear_retry_flags(b: *mut BIO) {
BIO_clear_flags(b, BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY)
}
pub const BIO_FLAGS_READ: c_int = 0x01;
pub const BIO_FLAGS_WRITE: c_int = 0x02;
pub const BIO_FLAGS_IO_SPECIAL: c_int = 0x04;
pub const BIO_FLAGS_RWS: c_int = BIO_FLAGS_READ | BIO_FLAGS_WRITE | BIO_FLAGS_IO_SPECIAL;
pub const BIO_FLAGS_SHOULD_RETRY: c_int = 0x08;
pub type bio_info_cb =
Option<unsafe extern "C" fn(*mut BIO, c_int, *const c_char, c_int, c_long, c_long)>;
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum BIO_METHOD {}
} else {
#[repr(C)]
pub struct BIO_METHOD {
pub type_: c_int,
pub name: *const c_char,
pub bwrite: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int) -> c_int>,
pub bread: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
pub bputs: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char) -> c_int>,
pub bgets: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
pub ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, c_long, *mut c_void) -> c_long>,
pub create: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
pub destroy: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
pub callback_ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, ::bio_info_cb) -> c_long>,
}
}
}
pub unsafe fn BIO_get_mem_data(b: *mut BIO, pp: *mut *mut c_char) -> c_long {
BIO_ctrl(b, BIO_CTRL_INFO, 0, pp as *mut c_void)
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
extern "C" {
pub fn BIO_s_file() -> *const BIO_METHOD;
pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO;
}
} else {
extern "C" {
pub fn BIO_s_file() -> *mut BIO_METHOD;
pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO;
}
}
}
extern "C" {
#[cfg(not(osslconf = "OPENSSL_NO_STDIO"))]
pub fn BIO_new_fp(stream: *mut FILE, close_flag: c_int) -> *mut BIO;
#[cfg(any(ossl110, libressl273))]
pub fn BIO_set_data(a: *mut ::BIO, data: *mut c_void);
#[cfg(any(ossl110, libressl273))]
pub fn BIO_get_data(a: *mut ::BIO) -> *mut c_void;
#[cfg(any(ossl110, libressl273))]
pub fn BIO_set_init(a: *mut ::BIO, init: c_int);
pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int;
pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int;
pub fn BIO_ctrl(b: *mut BIO, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long;
pub fn BIO_free_all(b: *mut BIO);
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
extern "C" {
pub fn BIO_s_mem() -> *const BIO_METHOD;
}
} else {
extern "C" {
pub fn BIO_s_mem() -> *mut BIO_METHOD;
}
}
}
cfg_if! {
if #[cfg(any(ossl102, libressl280))] {
extern "C" {
pub fn BIO_new_mem_buf(buf: *const c_void, len: c_int) -> *mut BIO;
}
} else {
extern "C" {
pub fn BIO_new_mem_buf(buf: *mut c_void, len: c_int) -> *mut BIO;
}
}
}
extern "C" {
pub fn BIO_new_socket(sock: c_int, close_flag: c_int) -> *mut BIO;
#[cfg(any(ossl110, libressl273))]
pub fn BIO_meth_new(type_: c_int, name: *const c_char) -> *mut BIO_METHOD;
#[cfg(any(ossl110, libressl273))]
pub fn BIO_meth_free(biom: *mut BIO_METHOD);
// FIXME should wrap in Option
#[cfg(any(ossl110, libressl273))]
pub fn BIO_meth_set_write(
biom: *mut BIO_METHOD,
write: unsafe extern "C" fn(*mut BIO, *const c_char, c_int) -> c_int,
) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn BIO_meth_set_read(
biom: *mut BIO_METHOD,
read: unsafe extern "C" fn(*mut BIO, *mut c_char, c_int) -> c_int,
) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn BIO_meth_set_puts(
biom: *mut BIO_METHOD,
read: unsafe extern "C" fn(*mut BIO, *const c_char) -> c_int,
) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn BIO_meth_set_ctrl(
biom: *mut BIO_METHOD,
read: unsafe extern "C" fn(*mut BIO, c_int, c_long, *mut c_void) -> c_long,
) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn BIO_meth_set_create(
biom: *mut BIO_METHOD,
create: unsafe extern "C" fn(*mut BIO) -> c_int,
) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn BIO_meth_set_destroy(
biom: *mut BIO_METHOD,
destroy: unsafe extern "C" fn(*mut BIO) -> c_int,
) -> c_int;
}

View File

@ -1,160 +0,0 @@
use libc::*;
use *;
#[cfg(target_pointer_width = "64")]
pub type BN_ULONG = c_ulonglong;
#[cfg(target_pointer_width = "32")]
pub type BN_ULONG = c_uint;
extern "C" {
pub fn BN_CTX_new() -> *mut BN_CTX;
pub fn BN_CTX_free(ctx: *mut BN_CTX);
pub fn BN_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int;
pub fn BN_pseudo_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int;
pub fn BN_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int;
pub fn BN_pseudo_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int;
pub fn BN_new() -> *mut BIGNUM;
pub fn BN_num_bits(bn: *const BIGNUM) -> c_int;
pub fn BN_clear_free(bn: *mut BIGNUM);
pub fn BN_bin2bn(s: *const u8, size: c_int, ret: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_bn2bin(a: *const BIGNUM, to: *mut u8) -> c_int;
pub fn BN_sub(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;
pub fn BN_add(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;
pub fn BN_mul(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
pub fn BN_sqr(r: *mut BIGNUM, a: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
pub fn BN_set_negative(bn: *mut BIGNUM, n: c_int);
#[cfg(ossl110)]
pub fn BN_is_negative(b: *const ::BIGNUM) -> c_int;
pub fn BN_div(
dv: *mut BIGNUM,
rem: *mut BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_nnmod(
rem: *mut BIGNUM,
a: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mod_add(
r: *mut BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mod_sub(
r: *mut BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mod_mul(
r: *mut BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mod_sqr(
r: *mut BIGNUM,
a: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mod_word(r: *const BIGNUM, w: BN_ULONG) -> BN_ULONG;
pub fn BN_div_word(r: *mut BIGNUM, w: BN_ULONG) -> BN_ULONG;
pub fn BN_mul_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int;
pub fn BN_add_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int;
pub fn BN_sub_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int;
pub fn BN_set_word(bn: *mut BIGNUM, n: BN_ULONG) -> c_int;
pub fn BN_cmp(a: *const BIGNUM, b: *const BIGNUM) -> c_int;
pub fn BN_free(bn: *mut BIGNUM);
pub fn BN_is_bit_set(a: *const BIGNUM, n: c_int) -> c_int;
pub fn BN_lshift(r: *mut BIGNUM, a: *const BIGNUM, n: c_int) -> c_int;
pub fn BN_lshift1(r: *mut BIGNUM, a: *const BIGNUM) -> c_int;
pub fn BN_exp(r: *mut BIGNUM, a: *const BIGNUM, p: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
pub fn BN_mod_exp(
r: *mut BIGNUM,
a: *const BIGNUM,
p: *const BIGNUM,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn BN_mask_bits(a: *mut BIGNUM, n: c_int) -> c_int;
pub fn BN_rshift(r: *mut BIGNUM, a: *const BIGNUM, n: c_int) -> c_int;
pub fn BN_rshift1(r: *mut BIGNUM, a: *const BIGNUM) -> c_int;
pub fn BN_bn2hex(a: *const BIGNUM) -> *mut c_char;
pub fn BN_bn2dec(a: *const BIGNUM) -> *mut c_char;
pub fn BN_hex2bn(a: *mut *mut BIGNUM, s: *const c_char) -> c_int;
pub fn BN_dec2bn(a: *mut *mut BIGNUM, s: *const c_char) -> c_int;
pub fn BN_gcd(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
pub fn BN_mod_inverse(
r: *mut BIGNUM,
a: *const BIGNUM,
n: *const BIGNUM,
ctx: *mut BN_CTX,
) -> *mut BIGNUM;
pub fn BN_clear(bn: *mut BIGNUM);
pub fn BN_dup(n: *const BIGNUM) -> *mut BIGNUM;
pub fn BN_ucmp(a: *const BIGNUM, b: *const BIGNUM) -> c_int;
pub fn BN_set_bit(a: *mut BIGNUM, n: c_int) -> c_int;
pub fn BN_clear_bit(a: *mut BIGNUM, n: c_int) -> c_int;
pub fn BN_generate_prime_ex(
r: *mut BIGNUM,
bits: c_int,
safe: c_int,
add: *const BIGNUM,
rem: *const BIGNUM,
cb: *mut BN_GENCB,
) -> c_int;
pub fn BN_is_prime_ex(
p: *const BIGNUM,
checks: c_int,
ctx: *mut BN_CTX,
cb: *mut BN_GENCB,
) -> c_int;
pub fn BN_is_prime_fasttest_ex(
p: *const BIGNUM,
checks: c_int,
ctx: *mut BN_CTX,
do_trial_division: c_int,
cb: *mut BN_GENCB,
) -> c_int;
}
cfg_if! {
if #[cfg(ossl110)] {
extern "C" {
pub fn BN_get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
}
} else {
extern "C" {
pub fn get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
}
}
}

View File

@ -1,91 +0,0 @@
use libc::*;
use *;
pub enum CMS_ContentInfo {}
extern "C" {
#[cfg(ossl101)]
pub fn CMS_ContentInfo_free(cms: *mut ::CMS_ContentInfo);
#[cfg(ossl101)]
pub fn i2d_CMS_ContentInfo(a: *mut ::CMS_ContentInfo, pp: *mut *mut c_uchar) -> c_int;
#[cfg(ossl101)]
pub fn d2i_CMS_ContentInfo(a: *mut *mut ::CMS_ContentInfo, pp: *mut *const c_uchar, length: c_long) -> *mut ::CMS_ContentInfo;
}
#[cfg(ossl101)]
pub const CMS_TEXT: c_uint = 0x1;
#[cfg(ossl101)]
pub const CMS_NOCERTS: c_uint = 0x2;
#[cfg(ossl101)]
pub const CMS_NO_CONTENT_VERIFY: c_uint = 0x4;
#[cfg(ossl101)]
pub const CMS_NO_ATTR_VERIFY: c_uint = 0x8;
#[cfg(ossl101)]
pub const CMS_NOSIGS: c_uint = 0x4 | 0x8;
#[cfg(ossl101)]
pub const CMS_NOINTERN: c_uint = 0x10;
#[cfg(ossl101)]
pub const CMS_NO_SIGNER_CERT_VERIFY: c_uint = 0x20;
#[cfg(ossl101)]
pub const CMS_NOVERIFY: c_uint = 0x20;
#[cfg(ossl101)]
pub const CMS_DETACHED: c_uint = 0x40;
#[cfg(ossl101)]
pub const CMS_BINARY: c_uint = 0x80;
#[cfg(ossl101)]
pub const CMS_NOATTR: c_uint = 0x100;
#[cfg(ossl101)]
pub const CMS_NOSMIMECAP: c_uint = 0x200;
#[cfg(ossl101)]
pub const CMS_NOOLDMIMETYPE: c_uint = 0x400;
#[cfg(ossl101)]
pub const CMS_CRLFEOL: c_uint = 0x800;
#[cfg(ossl101)]
pub const CMS_STREAM: c_uint = 0x1000;
#[cfg(ossl101)]
pub const CMS_NOCRL: c_uint = 0x2000;
#[cfg(ossl101)]
pub const CMS_PARTIAL: c_uint = 0x4000;
#[cfg(ossl101)]
pub const CMS_REUSE_DIGEST: c_uint = 0x8000;
#[cfg(ossl101)]
pub const CMS_USE_KEYID: c_uint = 0x10000;
#[cfg(ossl101)]
pub const CMS_DEBUG_DECRYPT: c_uint = 0x20000;
#[cfg(ossl102)]
pub const CMS_KEY_PARAM: c_uint = 0x40000;
#[cfg(ossl110)]
pub const CMS_ASCIICRLF: c_uint = 0x80000;
extern "C" {
#[cfg(ossl101)]
pub fn SMIME_read_CMS(bio: *mut ::BIO, bcont: *mut *mut ::BIO) -> *mut ::CMS_ContentInfo;
#[cfg(ossl101)]
pub fn CMS_sign(
signcert: *mut ::X509,
pkey: *mut ::EVP_PKEY,
certs: *mut ::stack_st_X509,
data: *mut ::BIO,
flags: c_uint,
) -> *mut ::CMS_ContentInfo;
#[cfg(ossl101)]
pub fn CMS_encrypt(
certs: *mut stack_st_X509,
data: *mut ::BIO,
cipher: *const EVP_CIPHER,
flags: c_uint
) -> *mut ::CMS_ContentInfo;
#[cfg(ossl101)]
pub fn CMS_decrypt(
cms: *mut ::CMS_ContentInfo,
pkey: *mut ::EVP_PKEY,
cert: *mut ::X509,
dcont: *mut ::BIO,
out: *mut ::BIO,
flags: c_uint,
) -> c_int;
}

View File

@ -1,7 +0,0 @@
use *;
extern "C" {
pub fn NCONF_new(meth: *mut CONF_METHOD) -> *mut CONF;
pub fn NCONF_default() -> *mut CONF_METHOD;
pub fn NCONF_free(conf: *mut CONF);
}

View File

@ -1,130 +0,0 @@
use libc::*;
use *;
#[cfg(not(ossl110))]
pub const CRYPTO_LOCK_X509: c_int = 3;
#[cfg(not(ossl110))]
pub const CRYPTO_LOCK_EVP_PKEY: c_int = 10;
#[cfg(not(ossl110))]
pub const CRYPTO_LOCK_SSL_CTX: c_int = 12;
#[cfg(not(ossl110))]
pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14;
stack!(stack_st_void);
cfg_if! {
if #[cfg(ossl110)] {
pub const CRYPTO_EX_INDEX_SSL: c_int = 0;
pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 1;
} else if #[cfg(libressl)] {
pub const CRYPTO_EX_INDEX_SSL: c_int = 1;
pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 2;
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl271))] {
extern "C" {
pub fn OpenSSL_version_num() -> c_ulong;
pub fn OpenSSL_version(key: c_int) -> *const c_char;
}
pub const OPENSSL_VERSION: c_int = 0;
pub const OPENSSL_CFLAGS: c_int = 1;
pub const OPENSSL_BUILT_ON: c_int = 2;
pub const OPENSSL_PLATFORM: c_int = 3;
pub const OPENSSL_DIR: c_int = 4;
} else {
extern "C" {
pub fn SSLeay() -> c_ulong;
pub fn SSLeay_version(key: c_int) -> *const c_char;
}
pub const SSLEAY_VERSION: c_int = 0;
pub const SSLEAY_CFLAGS: c_int = 2;
pub const SSLEAY_BUILT_ON: c_int = 3;
pub const SSLEAY_PLATFORM: c_int = 4;
pub const SSLEAY_DIR: c_int = 5;
}
}
// FIXME should be options
pub type CRYPTO_EX_new = unsafe extern "C" fn(
parent: *mut c_void,
ptr: *mut c_void,
ad: *const CRYPTO_EX_DATA,
idx: c_int,
argl: c_long,
argp: *const c_void,
) -> c_int;
pub type CRYPTO_EX_dup = unsafe extern "C" fn(
to: *mut CRYPTO_EX_DATA,
from: *mut CRYPTO_EX_DATA,
from_d: *mut c_void,
idx: c_int,
argl: c_long,
argp: *mut c_void,
) -> c_int;
pub type CRYPTO_EX_free = unsafe extern "C" fn(
parent: *mut c_void,
ptr: *mut c_void,
ad: *mut CRYPTO_EX_DATA,
idx: c_int,
argl: c_long,
argp: *mut c_void,
);
extern "C" {
#[cfg(any(ossl110, libressl))]
pub fn CRYPTO_get_ex_new_index(
class_index: c_int,
argl: c_long,
argp: *mut c_void,
new_func: Option<CRYPTO_EX_new>,
dup_func: Option<CRYPTO_EX_dup>,
free_func: Option<CRYPTO_EX_free>,
) -> c_int;
}
pub const CRYPTO_LOCK: c_int = 1;
extern "C" {
#[cfg(not(ossl110))]
pub fn CRYPTO_num_locks() -> c_int;
#[cfg(not(ossl110))]
pub fn CRYPTO_set_locking_callback(
func: unsafe extern "C" fn(mode: c_int, n: c_int, file: *const c_char, line: c_int),
);
#[cfg(not(ossl110))]
pub fn CRYPTO_set_id_callback(func: unsafe extern "C" fn() -> c_ulong);
#[cfg(not(ossl110))]
pub fn CRYPTO_add_lock(
pointer: *mut c_int,
amount: c_int,
type_: c_int,
file: *const c_char,
line: c_int,
) -> c_int;
}
cfg_if! {
if #[cfg(ossl110)] {
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);
}
} else {
extern "C" {
pub fn CRYPTO_malloc(num: c_int, file: *const c_char, line: c_int) -> *mut c_void;
pub fn CRYPTO_free(buf: *mut c_void);
}
}
}
extern "C" {
#[cfg(ossl101)]
pub fn FIPS_mode() -> c_int;
#[cfg(ossl101)]
pub fn FIPS_mode_set(onoff: c_int) -> c_int;
pub fn CRYPTO_memcmp(a: *const c_void, b: *const c_void, len: size_t) -> c_int;
}

View File

@ -1,19 +0,0 @@
use *;
extern "C" {
pub fn DH_new() -> *mut DH;
pub fn DH_free(dh: *mut DH);
pub fn d2i_DHparams(k: *mut *mut DH, pp: *mut *const c_uchar, length: c_long) -> *mut DH;
pub fn i2d_DHparams(dh: *const DH, pp: *mut *mut c_uchar) -> c_int;
#[cfg(ossl102)]
pub fn DH_get_1024_160() -> *mut DH;
#[cfg(ossl102)]
pub fn DH_get_2048_224() -> *mut DH;
#[cfg(ossl102)]
pub fn DH_get_2048_256() -> *mut DH;
#[cfg(any(ossl110, libressl273))]
pub fn DH_set0_pqg(dh: *mut DH, p: *mut BIGNUM, q: *mut BIGNUM, g: *mut BIGNUM) -> c_int;
}

View File

@ -1,58 +0,0 @@
use libc::*;
use *;
extern "C" {
pub fn DSA_new() -> *mut DSA;
pub fn DSA_free(dsa: *mut DSA);
pub fn DSA_up_ref(dsa: *mut DSA) -> c_int;
pub fn DSA_size(dsa: *const DSA) -> c_int;
pub fn DSA_sign(
dummy: c_int,
dgst: *const c_uchar,
len: c_int,
sigret: *mut c_uchar,
siglen: *mut c_uint,
dsa: *mut DSA,
) -> c_int;
pub fn DSA_verify(
dummy: c_int,
dgst: *const c_uchar,
len: c_int,
sigbuf: *const c_uchar,
siglen: c_int,
dsa: *mut DSA,
) -> c_int;
pub fn d2i_DSAPublicKey(a: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long) -> *mut DSA;
pub fn d2i_DSAPrivateKey(a: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long)
-> *mut DSA;
pub fn DSA_generate_parameters_ex(
dsa: *mut DSA,
bits: c_int,
seed: *const c_uchar,
seed_len: c_int,
counter_ref: *mut c_int,
h_ret: *mut c_ulong,
cb: *mut BN_GENCB,
) -> c_int;
pub fn DSA_generate_key(dsa: *mut DSA) -> c_int;
pub fn i2d_DSAPublicKey(a: *const DSA, pp: *mut *mut c_uchar) -> c_int;
pub fn i2d_DSAPrivateKey(a: *const DSA, pp: *mut *mut c_uchar) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn DSA_get0_pqg(
d: *const DSA,
p: *mut *const BIGNUM,
q: *mut *const BIGNUM,
q: *mut *const BIGNUM,
);
#[cfg(any(ossl110, libressl273))]
pub fn DSA_set0_pqg(d: *mut DSA, p: *mut BIGNUM, q: *mut BIGNUM, q: *mut BIGNUM) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn DSA_get0_key(d: *const DSA, pub_key: *mut *const BIGNUM, priv_key: *mut *const BIGNUM);
#[cfg(any(ossl110, libressl273))]
pub fn DSA_set0_key(d: *mut DSA, pub_key: *mut BIGNUM, priv_key: *mut BIGNUM) -> c_int;
}

View File

@ -1,3 +0,0 @@
use libc::*;
pub const DTLS1_COOKIE_LENGTH: c_uint = 256;

View File

@ -1,226 +0,0 @@
use libc::*;
use *;
#[repr(C)]
#[derive(Copy, Clone)]
pub enum point_conversion_form_t {
POINT_CONVERSION_COMPRESSED = 2,
POINT_CONVERSION_UNCOMPRESSED = 4,
POINT_CONVERSION_HYBRID = 6,
}
pub enum EC_METHOD {}
pub enum EC_GROUP {}
pub enum EC_POINT {}
pub const OPENSSL_EC_NAMED_CURVE: c_int = 1;
extern "C" {
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn EC_GF2m_simple_method() -> *const EC_METHOD;
pub fn EC_GROUP_new(meth: *const EC_METHOD) -> *mut EC_GROUP;
pub fn EC_GROUP_free(group: *mut EC_GROUP);
pub fn EC_GROUP_get_order(
group: *const EC_GROUP,
order: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_GROUP_get_cofactor(
group: *const EC_GROUP,
cofactor: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_GROUP_get0_generator(group: *const EC_GROUP) -> *const EC_POINT;
pub fn EC_GROUP_get_curve_name(group: *const EC_GROUP) -> c_int;
pub fn EC_GROUP_set_asn1_flag(key: *mut EC_GROUP, flag: c_int);
pub fn EC_GROUP_get_curve_GFp(
group: *const EC_GROUP,
p: *mut BIGNUM,
a: *mut BIGNUM,
b: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn EC_GROUP_get_curve_GF2m(
group: *const EC_GROUP,
p: *mut BIGNUM,
a: *mut BIGNUM,
b: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_GROUP_get_degree(group: *const EC_GROUP) -> c_int;
pub fn EC_GROUP_new_curve_GFp(
p: *const BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
ctx: *mut BN_CTX,
) -> *mut EC_GROUP;
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn EC_GROUP_new_curve_GF2m(
p: *const BIGNUM,
a: *const BIGNUM,
b: *const BIGNUM,
ctx: *mut BN_CTX,
) -> *mut EC_GROUP;
pub fn EC_GROUP_new_by_curve_name(nid: c_int) -> *mut EC_GROUP;
pub fn EC_POINT_new(group: *const EC_GROUP) -> *mut EC_POINT;
pub fn EC_POINT_free(point: *mut EC_POINT);
pub fn EC_POINT_dup(
p: *const EC_POINT,
group: *const EC_GROUP,
) -> *mut EC_POINT;
pub fn EC_POINT_get_affine_coordinates_GFp(
group: *const EC_GROUP,
p: *const EC_POINT,
x: *mut BIGNUM,
y: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
pub fn EC_POINT_get_affine_coordinates_GF2m(
group: *const EC_GROUP,
p: *const EC_POINT,
x: *mut BIGNUM,
y: *mut BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_point2oct(
group: *const EC_GROUP,
p: *const EC_POINT,
form: point_conversion_form_t,
buf: *mut c_uchar,
len: size_t,
ctx: *mut BN_CTX,
) -> size_t;
pub fn EC_POINT_oct2point(
group: *const EC_GROUP,
p: *mut EC_POINT,
buf: *const c_uchar,
len: size_t,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_add(
group: *const EC_GROUP,
r: *mut EC_POINT,
a: *const EC_POINT,
b: *const EC_POINT,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_invert(group: *const EC_GROUP, r: *mut EC_POINT, ctx: *mut BN_CTX) -> c_int;
pub fn EC_POINT_cmp(
group: *const EC_GROUP,
a: *const EC_POINT,
b: *const EC_POINT,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_POINT_mul(
group: *const EC_GROUP,
r: *mut EC_POINT,
n: *const BIGNUM,
q: *const EC_POINT,
m: *const BIGNUM,
ctx: *mut BN_CTX,
) -> c_int;
pub fn EC_KEY_new() -> *mut EC_KEY;
pub fn EC_KEY_new_by_curve_name(nid: c_int) -> *mut EC_KEY;
pub fn EC_KEY_free(key: *mut EC_KEY);
pub fn EC_KEY_dup(key: *const EC_KEY) -> *mut EC_KEY;
pub fn EC_KEY_up_ref(key: *mut EC_KEY) -> c_int;
pub fn EC_KEY_get0_group(key: *const EC_KEY) -> *const EC_GROUP;
pub fn EC_KEY_set_group(key: *mut EC_KEY, group: *const EC_GROUP) -> c_int;
pub fn EC_KEY_get0_private_key(key: *const EC_KEY) -> *const BIGNUM;
pub fn EC_KEY_set_private_key(key: *mut EC_KEY, key: *const BIGNUM) -> c_int;
pub fn EC_KEY_get0_public_key(key: *const EC_KEY) -> *const EC_POINT;
pub fn EC_KEY_set_public_key(key: *mut EC_KEY, key: *const EC_POINT) -> c_int;
pub fn EC_KEY_generate_key(key: *mut EC_KEY) -> c_int;
pub fn EC_KEY_check_key(key: *const EC_KEY) -> c_int;
pub fn EC_KEY_set_public_key_affine_coordinates(
key: *mut EC_KEY,
x: *mut BIGNUM,
y: *mut BIGNUM,
) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum ECDSA_SIG {}
} else {
#[repr(C)]
pub struct ECDSA_SIG {
pub r: *mut BIGNUM,
pub s: *mut BIGNUM,
}
}
}
extern "C" {
pub fn ECDSA_SIG_new() -> *mut ECDSA_SIG;
pub fn ECDSA_SIG_free(sig: *mut ECDSA_SIG);
#[cfg(any(ossl110, libressl273))]
pub fn ECDSA_SIG_get0(sig: *const ECDSA_SIG, pr: *mut *const BIGNUM, ps: *mut *const BIGNUM);
#[cfg(any(ossl110, libressl273))]
pub fn ECDSA_SIG_set0(sig: *mut ECDSA_SIG, pr: *mut BIGNUM, ps: *mut BIGNUM) -> c_int;
pub fn ECDSA_do_sign(
dgst: *const c_uchar,
dgst_len: c_int,
eckey: *mut EC_KEY,
) -> *mut ECDSA_SIG;
pub fn ECDSA_do_verify(
dgst: *const c_uchar,
dgst_len: c_int,
sig: *const ECDSA_SIG,
eckey: *mut EC_KEY,
) -> c_int;
pub fn d2i_ECDSA_SIG(
sig: *mut *mut ECDSA_SIG,
inp: *mut *const c_uchar,
length: c_long,
) -> *mut ECDSA_SIG;
pub fn i2d_ECDSA_SIG(sig: *const ECDSA_SIG, out: *mut *mut c_uchar) -> c_int;
}

View File

@ -1,58 +0,0 @@
use libc::*;
pub const ERR_TXT_MALLOCED: c_int = 0x01;
pub const ERR_TXT_STRING: c_int = 0x02;
pub const ERR_LIB_PEM: c_int = 9;
const_fn! {
pub const fn ERR_PACK(l: c_int, f: c_int, r: c_int) -> c_ulong {
((l as c_ulong & 0x0FF) << 24) |
((f as c_ulong & 0xFFF) << 12) |
((r as c_ulong & 0xFFF))
}
pub const fn ERR_GET_LIB(l: c_ulong) -> c_int {
((l >> 24) & 0x0FF) as c_int
}
pub const fn ERR_GET_FUNC(l: c_ulong) -> c_int {
((l >> 12) & 0xFFF) as c_int
}
pub const fn ERR_GET_REASON(l: c_ulong) -> c_int {
(l & 0xFFF) as c_int
}
}
#[repr(C)]
pub struct ERR_STRING_DATA {
pub error: c_ulong,
pub string: *const c_char,
}
extern "C" {
pub fn ERR_put_error(lib: c_int, func: c_int, reason: c_int, file: *const c_char, line: c_int);
pub fn ERR_set_error_data(data: *mut c_char, flags: c_int);
pub fn ERR_get_error() -> c_ulong;
pub fn ERR_get_error_line_data(
file: *mut *const c_char,
line: *mut c_int,
data: *mut *const c_char,
flags: *mut c_int,
) -> c_ulong;
pub fn ERR_peek_last_error() -> c_ulong;
pub fn ERR_clear_error();
pub fn ERR_lib_error_string(err: c_ulong) -> *const c_char;
pub fn ERR_func_error_string(err: c_ulong) -> *const c_char;
pub fn ERR_reason_error_string(err: c_ulong) -> *const c_char;
#[cfg(ossl110)]
pub fn ERR_load_strings(lib: c_int, str: *mut ERR_STRING_DATA) -> c_int;
#[cfg(not(ossl110))]
pub fn ERR_load_strings(lib: c_int, str: *mut ERR_STRING_DATA);
#[cfg(not(ossl110))]
pub fn ERR_load_crypto_strings();
pub fn ERR_get_next_error_library() -> c_int;
}

View File

@ -1,405 +0,0 @@
use libc::*;
use *;
pub const EVP_MAX_MD_SIZE: c_uint = 64;
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;
pub const EVP_PKEY_DSA: c_int = NID_dsa;
pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement;
pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey;
#[cfg(ossl111)]
pub const EVP_PKEY_ED25519: c_int = NID_ED25519;
#[cfg(ossl111)]
pub const EVP_PKEY_ED448: c_int = NID_ED448;
pub const EVP_PKEY_HMAC: c_int = NID_hmac;
pub const EVP_PKEY_CMAC: c_int = NID_cmac;
pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9;
pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10;
pub const EVP_CTRL_GCM_SET_TAG: c_int = 0x11;
pub unsafe fn EVP_get_digestbynid(type_: c_int) -> *const EVP_MD {
EVP_get_digestbyname(OBJ_nid2sn(type_))
}
extern "C" {
pub fn EVP_MD_size(md: *const EVP_MD) -> c_int;
pub fn EVP_MD_type(md: *const EVP_MD) -> c_int;
pub fn EVP_CIPHER_key_length(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_block_size(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_iv_length(cipher: *const EVP_CIPHER) -> c_int;
}
cfg_if! {
if #[cfg(ossl110)] {
extern "C" {
pub fn EVP_MD_CTX_new() -> *mut EVP_MD_CTX;
pub fn EVP_MD_CTX_free(ctx: *mut EVP_MD_CTX);
}
} else {
extern "C" {
pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
}
}
}
extern "C" {
pub fn EVP_DigestInit_ex(ctx: *mut EVP_MD_CTX, typ: *const EVP_MD, imple: *mut ENGINE)
-> c_int;
pub fn EVP_DigestUpdate(ctx: *mut EVP_MD_CTX, data: *const c_void, n: size_t) -> c_int;
pub fn EVP_DigestFinal_ex(ctx: *mut EVP_MD_CTX, res: *mut u8, n: *mut u32) -> c_int;
pub fn EVP_DigestInit(ctx: *mut EVP_MD_CTX, typ: *const EVP_MD) -> c_int;
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;
pub fn EVP_BytesToKey(
typ: *const EVP_CIPHER,
md: *const EVP_MD,
salt: *const u8,
data: *const u8,
datalen: c_int,
count: c_int,
key: *mut u8,
iv: *mut u8,
) -> c_int;
pub fn EVP_CipherInit(
ctx: *mut EVP_CIPHER_CTX,
evp: *const EVP_CIPHER,
key: *const u8,
iv: *const u8,
mode: c_int,
) -> c_int;
pub fn EVP_CipherInit_ex(
ctx: *mut EVP_CIPHER_CTX,
type_: *const EVP_CIPHER,
impl_: *mut ENGINE,
key: *const c_uchar,
iv: *const c_uchar,
enc: c_int,
) -> c_int;
pub fn EVP_CipherUpdate(
ctx: *mut EVP_CIPHER_CTX,
outbuf: *mut u8,
outlen: *mut c_int,
inbuf: *const u8,
inlen: c_int,
) -> c_int;
pub fn EVP_CipherFinal(ctx: *mut EVP_CIPHER_CTX, res: *mut u8, len: *mut c_int) -> c_int;
pub fn EVP_DigestSignInit(
ctx: *mut EVP_MD_CTX,
pctx: *mut *mut EVP_PKEY_CTX,
type_: *const EVP_MD,
e: *mut ENGINE,
pkey: *mut EVP_PKEY,
) -> c_int;
pub fn EVP_DigestSignFinal(
ctx: *mut EVP_MD_CTX,
sig: *mut c_uchar,
siglen: *mut size_t,
) -> c_int;
pub fn EVP_DigestVerifyInit(
ctx: *mut EVP_MD_CTX,
pctx: *mut *mut EVP_PKEY_CTX,
type_: *const EVP_MD,
e: *mut ENGINE,
pkey: *mut EVP_PKEY,
) -> c_int;
pub fn EVP_SealInit(
ctx: *mut EVP_CIPHER_CTX,
type_: *const EVP_CIPHER,
ek: *mut *mut c_uchar,
ekl: *mut c_int,
iv: *mut c_uchar,
pubk: *mut *mut EVP_PKEY,
npubk: c_int,
) -> c_int;
pub fn EVP_SealFinal(ctx: *mut EVP_CIPHER_CTX, out: *mut c_uchar, outl: *mut c_int) -> c_int;
pub fn EVP_EncryptUpdate(
ctx: *mut EVP_CIPHER_CTX,
out: *mut c_uchar,
outl: *mut c_int,
in_: *const u8,
inl: c_int,
) -> c_int;
pub fn EVP_OpenInit(
ctx: *mut EVP_CIPHER_CTX,
type_: *const EVP_CIPHER,
ek: *const c_uchar,
ekl: c_int,
iv: *const c_uchar,
priv_: *mut EVP_PKEY,
) -> c_int;
pub fn EVP_OpenFinal(ctx: *mut EVP_CIPHER_CTX, out: *mut c_uchar, outl: *mut c_int) -> c_int;
pub fn EVP_DecryptUpdate(
ctx: *mut EVP_CIPHER_CTX,
out: *mut c_uchar,
outl: *mut c_int,
in_: *const u8,
inl: c_int,
) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl111b, libressl280))] {
extern "C" {
pub fn EVP_PKEY_size(pkey: *const EVP_PKEY) -> c_int;
}
} else {
extern "C" {
pub fn EVP_PKEY_size(pkey: *mut EVP_PKEY) -> c_int;
}
}
}
cfg_if! {
if #[cfg(ossl111)] {
extern "C" {
pub fn EVP_DigestSign(
ctx: *mut EVP_MD_CTX,
sigret: *mut c_uchar,
siglen: *mut size_t,
tbs: *const c_uchar,
tbslen: size_t
) -> c_int;
pub fn EVP_DigestVerify(
ctx: *mut EVP_MD_CTX,
sigret: *const c_uchar,
siglen: size_t,
tbs: *const c_uchar,
tbslen: size_t
) -> c_int;
}
}
}
cfg_if! {
if #[cfg(any(ossl102, libressl280))] {
extern "C" {
pub fn EVP_DigestVerifyFinal(
ctx: *mut EVP_MD_CTX,
sigret: *const c_uchar,
siglen: size_t,
) -> c_int;
}
} else {
extern "C" {
pub fn EVP_DigestVerifyFinal(
ctx: *mut EVP_MD_CTX,
sigret: *mut c_uchar,
siglen: size_t,
) -> c_int;
}
}
}
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_MD_CTX_copy_ex(dst: *mut EVP_MD_CTX, src: *const EVP_MD_CTX) -> c_int;
pub fn EVP_CIPHER_CTX_set_key_length(ctx: *mut EVP_CIPHER_CTX, keylen: c_int) -> c_int;
pub fn EVP_CIPHER_CTX_set_padding(ctx: *mut EVP_CIPHER_CTX, padding: c_int) -> c_int;
pub fn EVP_CIPHER_CTX_ctrl(
ctx: *mut EVP_CIPHER_CTX,
type_: c_int,
arg: c_int,
ptr: *mut c_void,
) -> c_int;
pub fn EVP_md5() -> *const EVP_MD;
pub fn EVP_sha1() -> *const EVP_MD;
pub fn EVP_sha224() -> *const EVP_MD;
pub fn EVP_sha256() -> *const EVP_MD;
pub fn EVP_sha384() -> *const EVP_MD;
pub fn EVP_sha512() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_sha3_224() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_sha3_256() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_sha3_384() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_sha3_512() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_shake128() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_shake256() -> *const EVP_MD;
pub fn EVP_ripemd160() -> *const EVP_MD;
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_cfb64() -> *const EVP_CIPHER;
pub fn EVP_des_cbc() -> *const EVP_CIPHER;
pub fn EVP_rc4() -> *const EVP_CIPHER;
pub fn EVP_bf_ecb() -> *const EVP_CIPHER;
pub fn EVP_bf_cbc() -> *const EVP_CIPHER;
pub fn EVP_bf_cfb64() -> *const EVP_CIPHER;
pub fn EVP_bf_ofb() -> *const EVP_CIPHER;
pub fn EVP_aes_128_ecb() -> *const EVP_CIPHER;
pub fn EVP_aes_128_cbc() -> *const EVP_CIPHER;
pub fn EVP_aes_128_cfb1() -> *const EVP_CIPHER;
pub fn EVP_aes_128_cfb8() -> *const EVP_CIPHER;
pub fn EVP_aes_128_cfb128() -> *const EVP_CIPHER;
pub fn EVP_aes_128_ctr() -> *const EVP_CIPHER;
pub fn EVP_aes_128_ccm() -> *const EVP_CIPHER;
pub fn EVP_aes_128_gcm() -> *const EVP_CIPHER;
pub fn EVP_aes_128_xts() -> *const EVP_CIPHER;
pub fn EVP_aes_128_ofb() -> *const EVP_CIPHER;
pub fn EVP_aes_192_ecb() -> *const EVP_CIPHER;
pub fn EVP_aes_192_cbc() -> *const EVP_CIPHER;
pub fn EVP_aes_192_cfb1() -> *const EVP_CIPHER;
pub fn EVP_aes_192_cfb8() -> *const EVP_CIPHER;
pub fn EVP_aes_192_cfb128() -> *const EVP_CIPHER;
pub fn EVP_aes_192_ctr() -> *const EVP_CIPHER;
pub fn EVP_aes_192_ccm() -> *const EVP_CIPHER;
pub fn EVP_aes_192_gcm() -> *const EVP_CIPHER;
pub fn EVP_aes_192_ofb() -> *const EVP_CIPHER;
pub fn EVP_aes_256_ecb() -> *const EVP_CIPHER;
pub fn EVP_aes_256_cbc() -> *const EVP_CIPHER;
pub fn EVP_aes_256_cfb1() -> *const EVP_CIPHER;
pub fn EVP_aes_256_cfb8() -> *const EVP_CIPHER;
pub fn EVP_aes_256_cfb128() -> *const EVP_CIPHER;
pub fn EVP_aes_256_ctr() -> *const EVP_CIPHER;
pub fn EVP_aes_256_ccm() -> *const EVP_CIPHER;
pub fn EVP_aes_256_gcm() -> *const EVP_CIPHER;
pub fn EVP_aes_256_xts() -> *const EVP_CIPHER;
pub fn EVP_aes_256_ofb() -> *const EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_chacha20() -> *const ::EVP_CIPHER;
#[cfg(ossl110)]
pub fn EVP_chacha20_poly1305() -> *const ::EVP_CIPHER;
#[cfg(not(ossl110))]
pub fn OPENSSL_add_all_algorithms_noconf();
pub fn EVP_get_digestbyname(name: *const c_char) -> *const EVP_MD;
pub fn EVP_get_cipherbyname(name: *const c_char) -> *const EVP_CIPHER;
pub fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
extern "C" {
pub fn EVP_PKEY_bits(key: *const EVP_PKEY) -> c_int;
}
} else {
extern "C" {
pub fn EVP_PKEY_bits(key: *mut EVP_PKEY) -> c_int;
}
}
}
extern "C" {
pub fn EVP_PKEY_assign(pkey: *mut EVP_PKEY, typ: c_int, key: *mut c_void) -> c_int;
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_get1_DSA(k: *mut EVP_PKEY) -> *mut DSA;
pub fn EVP_PKEY_get1_DH(k: *mut EVP_PKEY) -> *mut DH;
pub fn EVP_PKEY_get1_EC_KEY(k: *mut EVP_PKEY) -> *mut EC_KEY;
pub fn EVP_PKEY_new() -> *mut EVP_PKEY;
pub fn EVP_PKEY_free(k: *mut EVP_PKEY);
#[cfg(any(ossl110, libressl270))]
pub fn EVP_PKEY_up_ref(pkey: *mut EVP_PKEY) -> c_int;
pub fn d2i_AutoPrivateKey(
a: *mut *mut EVP_PKEY,
pp: *mut *const c_uchar,
length: c_long,
) -> *mut EVP_PKEY;
pub fn EVP_PKEY_cmp(a: *const EVP_PKEY, b: *const EVP_PKEY) -> c_int;
pub fn EVP_PKEY_copy_parameters(to: *mut EVP_PKEY, from: *const EVP_PKEY) -> c_int;
pub fn PKCS5_PBKDF2_HMAC_SHA1(
pass: *const c_char,
passlen: c_int,
salt: *const u8,
saltlen: c_int,
iter: c_int,
keylen: c_int,
out: *mut u8,
) -> c_int;
pub fn PKCS5_PBKDF2_HMAC(
pass: *const c_char,
passlen: c_int,
salt: *const c_uchar,
saltlen: c_int,
iter: c_int,
digest: *const EVP_MD,
keylen: c_int,
out: *mut u8,
) -> c_int;
#[cfg(ossl110)]
pub fn EVP_PBE_scrypt(
pass: *const c_char,
passlen: size_t,
salt: *const c_uchar,
saltlen: size_t,
N: u64,
r: u64,
p: u64,
maxmem: u64,
key: *mut c_uchar,
keylen: size_t,
) -> c_int;
}
pub const EVP_PKEY_OP_KEYGEN: c_int = 1 << 2;
pub const EVP_PKEY_OP_SIGN: c_int = 1 << 3;
pub const EVP_PKEY_OP_VERIFY: c_int = 1 << 4;
pub const EVP_PKEY_OP_VERIFYRECOVER: c_int = 1 << 5;
pub const EVP_PKEY_OP_SIGNCTX: c_int = 1 << 6;
pub const EVP_PKEY_OP_VERIFYCTX: c_int = 1 << 7;
pub const EVP_PKEY_OP_ENCRYPT: c_int = 1 << 8;
pub const EVP_PKEY_OP_DECRYPT: c_int = 1 << 9;
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;
pub const EVP_PKEY_CTRL_SET_MAC_KEY: c_int = 6;
pub const EVP_PKEY_CTRL_CIPHER: c_int = 12;
pub const EVP_PKEY_ALG_CTRL: c_int = 0x1000;
extern "C" {
pub fn EVP_PKEY_CTX_new(k: *mut EVP_PKEY, e: *mut ENGINE) -> *mut EVP_PKEY_CTX;
pub fn EVP_PKEY_CTX_new_id(id: c_int, e: *mut ENGINE) -> *mut EVP_PKEY_CTX;
pub fn EVP_PKEY_CTX_free(ctx: *mut EVP_PKEY_CTX);
pub fn EVP_PKEY_CTX_ctrl(
ctx: *mut EVP_PKEY_CTX,
keytype: c_int,
optype: c_int,
cmd: c_int,
p1: c_int,
p2: *mut c_void,
) -> c_int;
pub fn EVP_PKEY_new_mac_key(
type_: c_int,
e: *mut ENGINE,
key: *const c_uchar,
keylen: c_int,
) -> *mut EVP_PKEY;
pub fn EVP_PKEY_derive_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
pub fn EVP_PKEY_derive_set_peer(ctx: *mut EVP_PKEY_CTX, peer: *mut EVP_PKEY) -> c_int;
pub fn EVP_PKEY_derive(ctx: *mut EVP_PKEY_CTX, key: *mut c_uchar, size: *mut size_t) -> c_int;
pub fn EVP_PKEY_keygen_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
pub fn EVP_PKEY_keygen(ctx: *mut EVP_PKEY_CTX, key: *mut *mut EVP_PKEY) -> c_int;
}

View File

@ -1,30 +0,0 @@
use libc::*;
use *;
cfg_if! {
if #[cfg(ossl110)] {
extern "C" {
pub fn HMAC_CTX_new() -> *mut HMAC_CTX;
pub fn HMAC_CTX_free(ctx: *mut HMAC_CTX);
}
} else {
extern "C" {
pub fn HMAC_CTX_init(ctx: *mut HMAC_CTX);
pub fn HMAC_CTX_cleanup(ctx: *mut HMAC_CTX);
}
}
}
extern "C" {
pub fn HMAC_Init_ex(
ctx: *mut HMAC_CTX,
key: *const c_void,
len: c_int,
md: *const EVP_MD,
impl_: *mut ENGINE,
) -> c_int;
pub fn HMAC_Update(ctx: *mut HMAC_CTX, data: *const c_uchar, len: size_t) -> c_int;
pub fn HMAC_Final(ctx: *mut HMAC_CTX, md: *mut c_uchar, len: *mut c_uint) -> c_int;
pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,600 @@
use std::sync::{Mutex, MutexGuard};
use std::sync::{Once, ONCE_INIT};
use std::mem;
use std::ptr;
#[cfg(libressl250)]
pub use libressl::v250::*;
#[cfg(not(libressl250))]
pub use libressl::v25x::*;
use libc::{c_int, c_char, c_void, c_long, c_uchar, size_t, c_uint, c_ulong};
#[cfg(libressl250)]
mod v250;
#[cfg(not(libressl250))]
mod v25x;
#[repr(C)]
pub struct stack_st_ASN1_OBJECT {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_X509 {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_X509_NAME {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_X509_ATTRIBUTE {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_X509_EXTENSION {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_GENERAL_NAME {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_void {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_SSL_CIPHER {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_OPENSSL_STRING {
pub stack: _STACK,
}
#[repr(C)]
pub struct _STACK {
pub num: c_int,
pub data: *mut *mut c_char,
pub sorted: c_int,
pub num_alloc: c_int,
pub comp: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
}
#[repr(C)]
pub struct BIO_METHOD {
pub type_: c_int,
pub name: *const c_char,
pub bwrite: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int) -> c_int>,
pub bread: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
pub bputs: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char) -> c_int>,
pub bgets: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
pub ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, c_long, *mut c_void) -> c_long>,
pub create: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
pub destroy: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
pub callback_ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, ::bio_info_cb) -> c_long>,
}
#[repr(C)]
pub struct RSA {
pub pad: c_int,
pub version: c_long,
pub meth: *const ::RSA_METHOD,
pub engine: *mut ::ENGINE,
pub n: *mut ::BIGNUM,
pub e: *mut ::BIGNUM,
pub d: *mut ::BIGNUM,
pub p: *mut ::BIGNUM,
pub q: *mut ::BIGNUM,
pub dmp1: *mut ::BIGNUM,
pub dmq1: *mut ::BIGNUM,
pub iqmp: *mut ::BIGNUM,
pub ex_data: ::CRYPTO_EX_DATA,
pub references: c_int,
pub flags: c_int,
pub _method_mod_n: *mut ::BN_MONT_CTX,
pub _method_mod_p: *mut ::BN_MONT_CTX,
pub _method_mod_q: *mut ::BN_MONT_CTX,
pub blinding: *mut ::BN_BLINDING,
pub mt_blinding: *mut ::BN_BLINDING,
}
#[repr(C)]
pub struct DSA {
pub pad: c_int,
pub version: c_long,
pub write_params: c_int,
pub p: *mut ::BIGNUM,
pub q: *mut ::BIGNUM,
pub g: *mut ::BIGNUM,
pub pub_key: *mut ::BIGNUM,
pub priv_key: *mut ::BIGNUM,
pub kinv: *mut ::BIGNUM,
pub r: *mut ::BIGNUM,
pub flags: c_int,
pub method_mont_p: *mut ::BN_MONT_CTX,
pub references: c_int,
pub ex_data: ::CRYPTO_EX_DATA,
pub meth: *const ::DSA_METHOD,
pub engine: *mut ::ENGINE,
}
#[repr(C)]
pub struct EVP_PKEY {
pub type_: c_int,
pub save_type: c_int,
pub references: c_int,
pub ameth: *const ::EVP_PKEY_ASN1_METHOD,
pub engine: *mut ::ENGINE,
pub pkey: *mut c_void,
pub save_parameters: c_int,
pub attributes: *mut stack_st_X509_ATTRIBUTE,
}
#[repr(C)]
pub struct BIO {
pub method: *mut ::BIO_METHOD,
pub callback: Option<
unsafe extern "C" fn(*mut ::BIO,
c_int,
*const c_char,
c_int,
c_long,
c_long)
-> c_long,
>,
pub cb_arg: *mut c_char,
pub init: c_int,
pub shutdown: c_int,
pub flags: c_int,
pub retry_reason: c_int,
pub num: c_int,
pub ptr: *mut c_void,
pub next_bio: *mut ::BIO,
pub prev_bio: *mut ::BIO,
pub references: c_int,
pub num_read: c_ulong,
pub num_write: c_ulong,
pub ex_data: ::CRYPTO_EX_DATA,
}
#[repr(C)]
pub struct CRYPTO_EX_DATA {
pub sk: *mut ::stack_st_void,
}
#[repr(C)]
pub struct EVP_MD_CTX {
digest: *mut ::EVP_MD,
engine: *mut ::ENGINE,
flags: c_ulong,
md_data: *mut c_void,
pctx: *mut ::EVP_PKEY_CTX,
update: *mut c_void,
}
#[repr(C)]
pub struct EVP_CIPHER {
pub nid: c_int,
pub block_size: c_int,
pub key_len: c_int,
pub iv_len: c_int,
pub flags: c_ulong,
pub init: Option<
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*const c_uchar,
*const c_uchar,
c_int)
-> c_int,
>,
pub do_cipher: Option<
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*mut c_uchar,
*const c_uchar,
size_t)
-> c_int,
>,
pub cleanup: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX) -> c_int>,
pub ctx_size: c_int,
pub set_asn1_parameters:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
pub get_asn1_parameters:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
pub ctrl:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, c_int, c_int, *mut c_void) -> c_int>,
pub app_data: *mut c_void,
}
#[repr(C)]
pub struct HMAC_CTX {
md: *mut ::EVP_MD,
md_ctx: ::EVP_MD_CTX,
i_ctx: ::EVP_MD_CTX,
o_ctx: ::EVP_MD_CTX,
key_length: c_uint,
key: [c_uchar; 128],
}
#[repr(C)]
pub struct BIGNUM {
pub d: *mut ::BN_ULONG,
pub top: c_int,
pub dmax: c_int,
pub neg: c_int,
pub flags: c_int,
}
#[repr(C)]
pub struct DH {
pub pad: c_int,
pub version: c_int,
pub p: *mut ::BIGNUM,
pub g: *mut ::BIGNUM,
pub length: c_long,
pub pub_key: *mut ::BIGNUM,
pub priv_key: *mut ::BIGNUM,
pub flags: c_int,
pub method_mont_p: *mut ::BN_MONT_CTX,
pub q: *mut ::BIGNUM,
pub j: *mut ::BIGNUM,
pub seed: *mut c_uchar,
pub seedlen: c_int,
pub counter: *mut ::BIGNUM,
pub references: c_int,
pub ex_data: ::CRYPTO_EX_DATA,
pub meth: *const ::DH_METHOD,
pub engine: *mut ::ENGINE,
}
#[repr(C)]
pub struct X509 {
pub cert_info: *mut X509_CINF,
pub sig_alg: *mut ::X509_ALGOR,
pub signature: *mut ::ASN1_BIT_STRING,
pub valid: c_int,
pub references: c_int,
pub name: *mut c_char,
pub ex_data: ::CRYPTO_EX_DATA,
pub ex_pathlen: c_long,
pub ex_pcpathlen: c_long,
pub ex_flags: c_ulong,
pub ex_kusage: c_ulong,
pub ex_xkusage: c_ulong,
pub ex_nscert: c_ulong,
skid: *mut c_void,
akid: *mut c_void,
policy_cache: *mut c_void,
crldp: *mut c_void,
altname: *mut c_void,
nc: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_SHA"))]
sha1_hash: [c_uchar; 20],
aux: *mut c_void,
}
#[repr(C)]
pub struct X509_CINF {
version: *mut c_void,
serialNumber: *mut c_void,
signature: *mut c_void,
issuer: *mut c_void,
pub validity: *mut X509_VAL,
subject: *mut c_void,
key: *mut c_void,
issuerUID: *mut c_void,
subjectUID: *mut c_void,
pub extensions: *mut stack_st_X509_EXTENSION,
enc: ASN1_ENCODING,
}
#[repr(C)]
pub struct X509_ALGOR {
pub algorithm: *mut ::ASN1_OBJECT,
parameter: *mut c_void,
}
#[repr(C)]
pub struct ASN1_ENCODING {
pub enc: *mut c_uchar,
pub len: c_long,
pub modified: c_int,
}
#[repr(C)]
pub struct X509_VAL {
pub notBefore: *mut ::ASN1_TIME,
pub notAfter: *mut ::ASN1_TIME,
}
#[repr(C)]
pub struct X509_REQ_INFO {
pub enc: ASN1_ENCODING,
pub version: *mut ::ASN1_INTEGER,
pub subject: *mut ::X509_NAME,
pubkey: *mut c_void,
pub attributes: *mut stack_st_X509_ATTRIBUTE,
}
#[repr(C)]
pub struct X509_REQ {
pub req_info: *mut X509_REQ_INFO,
sig_alg: *mut c_void,
signature: *mut c_void,
references: c_int,
}
pub enum X509_VERIFY_PARAM_ID {}
pub enum PKCS12 {}
pub const SSL_CTRL_GET_SESSION_REUSED: c_int = 8;
pub const SSL_CTRL_OPTIONS: c_int = 32;
pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77;
pub const SSL_CTRL_SET_ECDH_AUTO: c_int = 94;
#[cfg(any(libressl261, libressl262, libressl26x))]
pub const SSL_OP_ALL: c_ulong = 0x4;
#[cfg(not(any(libressl261, libressl262, libressl26x)))]
pub const SSL_OP_ALL: c_ulong = 0x80000014;
pub const SSL_OP_CISCO_ANYCONNECT: c_ulong = 0x0;
pub const SSL_OP_NO_COMPRESSION: c_ulong = 0x0;
pub const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: c_ulong = 0x0;
pub const SSL_OP_NO_SSLv3: c_ulong = 0x0;
pub const SSL_OP_MICROSOFT_SESS_ID_BUG: c_ulong = 0x0;
pub const SSL_OP_NETSCAPE_CHALLENGE_BUG: c_ulong = 0x0;
pub const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: c_ulong = 0x0;
pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: c_ulong = 0x0;
pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: c_ulong = 0x0;
pub const SSL_OP_TLS_D5_BUG: c_ulong = 0x0;
pub const SSL_OP_TLS_BLOCK_PADDING_BUG: c_ulong = 0x0;
#[cfg(any(libressl261, libressl262, libressl26x))]
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x0;
#[cfg(not(any(libressl261, libressl262, libressl26x)))]
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00080000;
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000;
pub const SSL_OP_NO_SSLv2: c_ulong = 0x0;
pub const SSL_MAX_SSL_SESSION_ID_LENGTH: c_int = 32;
pub const SSL_MAX_SID_CTX_LENGTH: c_int = 32;
pub const SSL_MAX_MASTER_KEY_LENGTH: c_int = 48;
pub const SSLEAY_VERSION: c_int = 0;
pub const SSLEAY_CFLAGS: c_int = 2;
pub const SSLEAY_BUILT_ON: c_int = 3;
pub const SSLEAY_PLATFORM: c_int = 4;
pub const SSLEAY_DIR: c_int = 5;
pub const CRYPTO_LOCK_X509: c_int = 3;
pub const CRYPTO_LOCK_SSL_CTX: c_int = 12;
pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14;
static mut MUTEXES: *mut Vec<Mutex<()>> = 0 as *mut Vec<Mutex<()>>;
static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> = 0 as
*mut Vec<Option<MutexGuard<'static, ()>>>;
unsafe extern "C" fn locking_function(mode: c_int, n: c_int, _file: *const c_char, _line: c_int) {
let mutex = &(*MUTEXES)[n as usize];
if mode & ::CRYPTO_LOCK != 0 {
(*GUARDS)[n as usize] = Some(mutex.lock().unwrap());
} else {
&(*GUARDS)[n as usize].take().expect("lock already unlocked");
}
}
pub fn init() {
static INIT: Once = ONCE_INIT;
INIT.call_once(|| unsafe {
SSL_library_init();
SSL_load_error_strings();
OPENSSL_add_all_algorithms_noconf();
let num_locks = ::CRYPTO_num_locks();
let mut mutexes = Box::new(Vec::new());
for _ in 0..num_locks {
mutexes.push(Mutex::new(()));
}
MUTEXES = mem::transmute(mutexes);
let guards: Box<Vec<Option<MutexGuard<()>>>> =
Box::new((0..num_locks).map(|_| None).collect());
GUARDS = mem::transmute(guards);
CRYPTO_set_locking_callback(locking_function);
set_id_callback();
})
}
#[cfg(unix)]
fn set_id_callback() {
unsafe extern "C" fn thread_id() -> c_ulong {
::libc::pthread_self() as c_ulong
}
unsafe {
CRYPTO_set_id_callback(thread_id);
}
}
#[cfg(not(unix))]
fn set_id_callback() {}
// macros
pub unsafe fn SSL_CTX_set_ecdh_auto(ctx: *mut SSL_CTX, onoff: c_int) -> c_int {
::SSL_CTX_ctrl(
ctx,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut(),
) as c_int
}
pub unsafe fn SSL_set_ecdh_auto(ssl: *mut ::SSL, onoff: c_int) -> c_int {
::SSL_ctrl(
ssl,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut(),
) as c_int
}
pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int {
::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int
}
extern "C" {
pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO;
pub fn BIO_s_file() -> *mut BIO_METHOD;
pub fn BIO_s_mem() -> *mut BIO_METHOD;
pub fn get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn CRYPTO_malloc(num: c_int, file: *const c_char, line: c_int) -> *mut c_void;
pub fn CRYPTO_free(buf: *mut c_void);
pub fn CRYPTO_num_locks() -> c_int;
pub fn CRYPTO_set_locking_callback(
func: unsafe extern "C" fn(mode: c_int, n: c_int, file: *const c_char, line: c_int),
);
pub fn CRYPTO_set_id_callback(func: unsafe extern "C" fn() -> c_ulong);
pub fn ERR_load_crypto_strings();
pub fn RSA_generate_key(
modsz: c_int,
e: c_ulong,
cb: Option<extern "C" fn(c_int, c_int, *mut c_void)>,
cbarg: *mut c_void,
) -> *mut RSA;
pub fn OCSP_cert_to_id(
dgst: *const ::EVP_MD,
subject: *mut ::X509,
issuer: *mut ::X509,
) -> *mut ::OCSP_CERTID;
pub fn PKCS12_create(
pass: *mut c_char,
friendly_name: *mut c_char,
pkey: *mut EVP_PKEY,
cert: *mut X509,
ca: *mut stack_st_X509,
nid_key: c_int,
nid_cert: c_int,
iter: c_int,
mac_iter: c_int,
keytype: c_int,
) -> *mut PKCS12;
pub fn SSL_library_init() -> c_int;
pub fn SSL_load_error_strings();
pub fn OPENSSL_add_all_algorithms_noconf();
pub fn HMAC_CTX_init(ctx: *mut ::HMAC_CTX);
pub fn HMAC_CTX_cleanup(ctx: *mut ::HMAC_CTX);
pub fn TLSv1_method() -> *const ::SSL_METHOD;
pub fn SSLv23_method() -> *const ::SSL_METHOD;
pub fn TLSv1_1_method() -> *const ::SSL_METHOD;
pub fn TLSv1_2_method() -> *const ::SSL_METHOD;
pub fn DTLSv1_method() -> *const ::SSL_METHOD;
pub fn SSL_get_ex_new_index(
argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>,
) -> c_int;
pub fn SSL_set_tmp_ecdh_callback(
ssl: *mut ::SSL,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
-> *mut ::EC_KEY,
);
pub fn SSL_CIPHER_get_version(cipher: *const ::SSL_CIPHER) -> *mut c_char;
pub fn SSL_CTX_get_ex_new_index(
argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>,
) -> c_int;
pub fn SSL_CTX_set_tmp_ecdh_callback(
ctx: *mut ::SSL_CTX,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
-> *mut ::EC_KEY,
);
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_get_ext_d2i(
x: *mut ::X509,
nid: c_int,
crit: *mut c_int,
idx: *mut c_int,
) -> *mut c_void;
pub fn X509_NAME_add_entry_by_NID(
x: *mut ::X509_NAME,
field: c_int,
ty: c_int,
bytes: *mut c_uchar,
len: c_int,
loc: c_int,
set: c_int,
) -> c_int;
pub fn X509_NAME_get_entry(n: *mut ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
pub fn X509_NAME_ENTRY_get_data(ne: *mut ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
pub fn X509_STORE_CTX_get_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
pub fn X509V3_EXT_nconf_nid(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
ext_nid: c_int,
value: *mut c_char,
) -> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
name: *mut c_char,
value: *mut c_char,
) -> *mut ::X509_EXTENSION;
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *mut ::ASN1_STRING) -> c_int;
pub fn ASN1_STRING_data(x: *mut ::ASN1_STRING) -> *mut c_uchar;
pub fn CRYPTO_add_lock(
pointer: *mut c_int,
amount: c_int,
type_: c_int,
file: *const c_char,
line: c_int,
) -> c_int;
pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
pub fn EVP_PKEY_bits(key: *mut EVP_PKEY) -> c_int;
pub fn sk_new_null() -> *mut _STACK;
pub fn sk_num(st: *const _STACK) -> c_int;
pub fn sk_value(st: *const _STACK, n: c_int) -> *mut c_void;
pub fn sk_free(st: *mut _STACK);
pub fn sk_push(st: *mut _STACK, data: *mut c_void) -> c_int;
pub fn sk_pop_free(st: *mut _STACK, free: Option<unsafe extern "C" fn(*mut c_void)>);
pub fn sk_pop(st: *mut _STACK) -> *mut c_void;
pub fn SSLeay() -> c_ulong;
pub fn SSLeay_version(key: c_int) -> *const c_char;
}

View File

@ -0,0 +1,221 @@
use libc::{c_int, c_char, c_void, c_long, c_uchar, size_t, c_uint, c_ulong, time_t};
use super::*;
#[repr(C)]
pub struct SSL {
version: c_int,
type_: c_int,
method: *const ::SSL_METHOD,
rbio: *mut c_void,
wbio: *mut c_void,
bbio: *mut c_void,
rwstate: c_int,
in_handshake: c_int,
handshake_func: Option<unsafe extern "C" fn(*mut SSL) -> c_int>,
pub server: c_int,
new_session: c_int,
quiet_shutdown: c_int,
shutdown: c_int,
state: c_int,
rstate: c_int,
init_buf: *mut c_void,
init_msg: *mut c_void,
init_num: c_int,
init_off: c_int,
packet: *mut c_uchar,
packet_length: c_uint,
s3: *mut c_void,
d1: *mut c_void,
read_ahead: c_int,
msg_callback: Option<
unsafe extern "C" fn(c_int,
c_int,
c_int,
*const c_void,
size_t,
*mut SSL,
*mut c_void),
>,
msg_callback_arg: *mut c_void,
hit: c_int,
param: *mut c_void,
cipher_list: *mut stack_st_SSL_CIPHER,
cipher_list_by_id: *mut stack_st_SSL_CIPHER,
mac_flags: c_int,
aead_read_ctx: *mut c_void,
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
read_hash: *mut ::EVP_MD_CTX,
aead_write_ctx: *mut c_void,
enc_write_ctx: *mut ::EVP_CIPHER_CTX,
write_hash: *mut ::EVP_MD_CTX,
cert: *mut c_void,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
session: *mut ::SSL_SESSION,
generate_session_id: ::GEN_SESSION_CB,
verify_mode: c_int,
verify_callback: Option<unsafe extern "C" fn(c_int, *mut ::X509_STORE_CTX) -> c_int>,
info_callback: Option<unsafe extern "C" fn(*mut SSL, c_int, c_int)>,
error: c_int,
error_code: c_int,
ctx: *mut ::SSL_CTX,
debug: c_int,
verify_result: c_long,
ex_data: ::CRYPTO_EX_DATA,
client_CA: *mut stack_st_X509_NAME,
references: c_int,
options: c_ulong,
mode: c_ulong,
max_cert_list: c_long,
first_packet: c_int,
client_version: c_int,
max_send_fragment: c_uint,
tlsext_debug_cb:
Option<unsafe extern "C" fn(*mut SSL, c_int, c_int, *mut c_uchar, c_int, *mut c_void)>,
tlsext_debug_arg: *mut c_void,
tlsext_hostname: *mut c_char,
servername_done: c_int,
tlsext_status_type: c_int,
tlsext_status_expected: c_int,
tlsext_ocsp_ids: *mut c_void,
tlsext_ocsp_exts: *mut c_void,
tlsext_ocsp_resp: *mut c_uchar,
tlsext_ocsp_resplen: c_int,
tlsext_ticket_expected: c_int,
tlsext_ecpointformatlist_length: size_t,
tlsext_ecpointformatlist: *mut c_uchar,
tlsext_ellipticcurvelist_length: size_t,
tlsext_ellipticcurvelist: *mut c_uchar,
tlsext_session_ticket: *mut c_void,
tlsext_session_ticket_ext_cb: ::tls_session_ticket_ext_cb_fn,
tls_session_ticket_ext_cb_arg: *mut c_void,
tls_session_secret_cb: ::tls_session_secret_cb_fn,
tls_session_secret_cb_arg: *mut c_void,
initial_ctx: *mut ::SSL_CTX,
next_proto_negotiated: *mut c_uchar,
next_proto_negotiated_len: c_uchar,
srtp_profiles: *mut c_void,
srtp_profile: *mut c_void,
tlsext_heartbeat: c_uint,
tlsext_hb_pending: c_uint,
tlsext_hb_seq: c_uint,
alpn_client_proto_list: *mut c_uchar,
alpn_client_proto_list_len: c_uint,
renegotiate: c_int,
}
#[repr(C)]
pub struct SSL_CTX {
method: *mut c_void,
cipher_list: *mut c_void,
cipher_list_by_id: *mut c_void,
cert_store: *mut c_void,
sessions: *mut c_void,
session_cache_size: c_ulong,
session_cache_head: *mut c_void,
session_cache_tail: *mut c_void,
session_cache_mode: c_int,
session_timeout: c_long,
new_session_cb: *mut c_void,
remove_session_cb: *mut c_void,
get_session_cb: *mut c_void,
stats: [c_int; 11],
pub references: c_int,
app_verify_callback: *mut c_void,
app_verify_arg: *mut c_void,
default_passwd_callback: *mut c_void,
default_passwd_callback_userdata: *mut c_void,
client_cert_cb: *mut c_void,
app_gen_cookie_cb: *mut c_void,
app_verify_cookie_cb: *mut c_void,
ex_dat: ::CRYPTO_EX_DATA,
rsa_md5: *mut c_void,
md5: *mut c_void,
sha1: *mut c_void,
extra_certs: *mut c_void,
comp_methods: *mut c_void,
info_callback: *mut c_void,
client_CA: *mut c_void,
options: c_ulong,
mode: c_ulong,
max_cert_list: c_long,
cert: *mut c_void,
read_ahead: c_int,
msg_callback: *mut c_void,
msg_callback_arg: *mut c_void,
verify_mode: c_int,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; 32],
default_verify_callback: *mut c_void,
generate_session_id: *mut c_void,
param: *mut c_void,
quiet_shutdown: c_int,
max_send_fragment: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))]
client_cert_engine: *mut c_void,
tlsext_servername_callback: *mut c_void,
tlsect_servername_arg: *mut c_void,
tlsext_tick_key_name: [c_uchar; 16],
tlsext_tick_hmac_key: [c_uchar; 16],
tlsext_tick_aes_key: [c_uchar; 16],
tlsext_ticket_key_cb: *mut c_void,
tlsext_status_cb: *mut c_void,
tlsext_status_arg: *mut c_void,
tlsext_opaque_prf_input_callback: *mut c_void,
tlsext_opaque_prf_input_callback_arg: *mut c_void,
next_protos_advertised_cb: *mut c_void,
next_protos_advertised_cb_arg: *mut c_void,
next_proto_select_cb: *mut c_void,
next_proto_select_cb_arg: *mut c_void,
srtp_profiles: *mut c_void,
}
#[repr(C)]
pub struct SSL_SESSION {
ssl_version: c_int,
pub master_key_length: c_int,
pub master_key: [c_uchar; 48],
session_id_length: c_uint,
session_id: [c_uchar; SSL_MAX_SSL_SESSION_ID_LENGTH as usize],
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize],
not_resumable: c_int,
sess_cert: *mut c_void,
peer: *mut X509,
verify_result: c_long,
timeout: c_long,
time: time_t,
pub references: c_int,
cipher: *const c_void,
cipher_id: c_ulong,
ciphers: *mut c_void,
ex_data: ::CRYPTO_EX_DATA,
prev: *mut c_void,
next: *mut c_void,
tlsext_hostname: *mut c_char,
tlsext_ecpointformatlist_length: size_t,
tlsext_ecpointformatlist: *mut u8,
tlsext_ellipticcurvelist_length: size_t,
tlsext_ellipticcurvelist: *mut u16,
tlsext_tick: *mut c_uchar,
tlsext_ticklen: size_t,
tlsext_tick_lifetime_hint: c_long,
}
#[repr(C)]
pub struct X509_VERIFY_PARAM {
pub name: *mut c_char,
pub check_time: time_t,
pub inh_flags: c_ulong,
pub flags: c_ulong,
pub purpose: c_int,
pub trust: c_int,
pub depth: c_int,
pub policies: *mut stack_st_ASN1_OBJECT,
//pub id: *mut X509_VERIFY_PARAM_ID,
}

View File

@ -0,0 +1,89 @@
use libc::{c_int, c_char, c_void, c_long, c_uchar, size_t, c_uint, c_ulong, time_t};
use super::*;
#[repr(C)]
pub struct SSL {
version: c_int,
method: *const ::SSL_METHOD,
rbio: *mut ::BIO,
wbio: *mut ::BIO,
bbio: *mut ::BIO,
pub server: c_int,
s3: *mut c_void,
d1: *mut c_void,
param: *mut c_void,
cipher_list: *mut stack_st_SSL_CIPHER,
cert: *mut c_void,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
session: *mut ::SSL_SESSION,
verify_mode: c_int,
error: c_int,
error_code: c_int,
ctx: *mut ::SSL_CTX,
verify_result: c_long,
references: c_int,
client_version: c_int,
max_send_fragment: c_uint,
tlsext_hostname: *mut c_char,
tlsext_status_type: c_int,
initial_ctx: *mut ::SSL_CTX,
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
read_hash: *mut EVP_MD_CTX,
internal: *mut c_void,
}
#[repr(C)]
pub struct SSL_CTX {
method: *const ::SSL_METHOD,
cipher_list: *mut stack_st_SSL_CIPHER,
cert_store: *mut c_void,
session_timeout: c_long,
pub references: c_int,
extra_certs: *mut stack_st_X509,
verify_mode: c_int,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
param: *mut ::X509_VERIFY_PARAM,
default_passwd_callback: *mut c_void,
default_passwd_callback_userdata: *mut c_void,
internal: *mut c_void,
}
#[repr(C)]
pub struct SSL_SESSION {
ssl_version: c_int,
pub master_key_length: c_int,
pub master_key: [c_uchar; 48],
session_id_length: c_uint,
session_id: [c_uchar; ::SSL_MAX_SSL_SESSION_ID_LENGTH as usize],
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
peer: *mut ::X509,
verify_result: c_long,
timeout: c_long,
time: time_t,
pub references: c_int,
cipher: *const ::SSL_CIPHER,
cipher_id: c_long,
ciphers: *mut stack_st_SSL_CIPHER,
tlsext_hostname: *mut c_char,
tlsext_tick: *mut c_uchar,
tlsext_ticklen: size_t,
tlsext_tick_lifetime_int: c_long,
internal: *mut c_void,
}
#[repr(C)]
pub struct X509_VERIFY_PARAM {
pub name: *mut c_char,
pub check_time: time_t,
pub inh_flags: c_ulong,
pub flags: c_ulong,
pub purpose: c_int,
pub trust: c_int,
pub depth: c_int,
policies: *mut stack_st_ASN1_OBJECT,
id: *mut c_void,
}

View File

@ -1,87 +0,0 @@
// vendored from the cfg-if crate to avoid breaking ctest
macro_rules! cfg_if {
// match if/else chains with a final `else`
($(
if #[cfg($($meta:meta),*)] { $($it:item)* }
) else * else {
$($it2:item)*
}) => {
cfg_if! {
@__items
() ;
$( ( ($($meta),*) ($($it)*) ), )*
( () ($($it2)*) ),
}
};
// match if/else chains lacking a final `else`
(
if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
$(
else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
)*
) => {
cfg_if! {
@__items
() ;
( ($($i_met),*) ($($i_it)*) ),
$( ( ($($e_met),*) ($($e_it)*) ), )*
( () () ),
}
};
// Internal and recursive macro to emit all the items
//
// Collects all the negated cfgs in a list at the beginning and after the
// semicolon is all the remaining items
(@__items ($($not:meta,)*) ; ) => {};
(@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
// Emit all items within one block, applying an approprate #[cfg]. The
// #[cfg] will require all `$m` matchers specified and must also negate
// all previous matchers.
cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
// Recurse to emit all other items in `$rest`, and when we do so add all
// our `$m` matchers to the list of `$not` matchers as future emissions
// will have to negate everything we just matched as well.
cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
};
// Internal macro to Apply a cfg attribute to a list of items
(@__apply $m:meta, $($it:item)*) => {
$(#[$m] $it)*
};
}
macro_rules! stack {
($t:ident) => {
cfg_if! {
if #[cfg(ossl110)] {
pub enum $t {}
} else {
#[repr(C)]
pub struct $t {
pub stack: ::_STACK,
}
}
}
};
}
#[cfg(const_fn)]
macro_rules! const_fn {
($(pub const fn $name:ident($($arg:ident: $t:ty),*) -> $ret:ty $b:block)*) => {
$(
pub const fn $name($($arg: $t),*) -> $ret $b
)*
}
}
#[cfg(not(const_fn))]
macro_rules! const_fn {
($(pub const fn $name:ident($($arg:ident: $t:ty),*) -> $ret:ty $b:block)*) => {
$(
pub fn $name($($arg: $t),*) -> $ret $b
)*
}
}

View File

@ -1,918 +0,0 @@
use libc::*;
pub const NID_undef: c_int = 0;
pub const NID_itu_t: c_int = 645;
pub const NID_ccitt: c_int = 404;
pub const NID_iso: c_int = 181;
pub const NID_joint_iso_itu_t: c_int = 646;
pub const NID_joint_iso_ccitt: c_int = 393;
pub const NID_member_body: c_int = 182;
pub const NID_identified_organization: c_int = 676;
pub const NID_hmac_md5: c_int = 780;
pub const NID_hmac_sha1: c_int = 781;
pub const NID_certicom_arc: c_int = 677;
pub const NID_international_organizations: c_int = 647;
pub const NID_wap: c_int = 678;
pub const NID_wap_wsg: c_int = 679;
pub const NID_selected_attribute_types: c_int = 394;
pub const NID_clearance: c_int = 395;
pub const NID_ISO_US: c_int = 183;
pub const NID_X9_57: c_int = 184;
pub const NID_X9cm: c_int = 185;
pub const NID_dsa: c_int = 116;
pub const NID_dsaWithSHA1: c_int = 113;
pub const NID_ansi_X9_62: c_int = 405;
pub const NID_X9_62_prime_field: c_int = 406;
pub const NID_X9_62_characteristic_two_field: c_int = 407;
pub const NID_X9_62_id_characteristic_two_basis: c_int = 680;
pub const NID_X9_62_onBasis: c_int = 681;
pub const NID_X9_62_tpBasis: c_int = 682;
pub const NID_X9_62_ppBasis: c_int = 683;
pub const NID_X9_62_id_ecPublicKey: c_int = 408;
pub const NID_X9_62_c2pnb163v1: c_int = 684;
pub const NID_X9_62_c2pnb163v2: c_int = 685;
pub const NID_X9_62_c2pnb163v3: c_int = 686;
pub const NID_X9_62_c2pnb176v1: c_int = 687;
pub const NID_X9_62_c2tnb191v1: c_int = 688;
pub const NID_X9_62_c2tnb191v2: c_int = 689;
pub const NID_X9_62_c2tnb191v3: c_int = 690;
pub const NID_X9_62_c2onb191v4: c_int = 691;
pub const NID_X9_62_c2onb191v5: c_int = 692;
pub const NID_X9_62_c2pnb208w1: c_int = 693;
pub const NID_X9_62_c2tnb239v1: c_int = 694;
pub const NID_X9_62_c2tnb239v2: c_int = 695;
pub const NID_X9_62_c2tnb239v3: c_int = 696;
pub const NID_X9_62_c2onb239v4: c_int = 697;
pub const NID_X9_62_c2onb239v5: c_int = 698;
pub const NID_X9_62_c2pnb272w1: c_int = 699;
pub const NID_X9_62_c2pnb304w1: c_int = 700;
pub const NID_X9_62_c2tnb359v1: c_int = 701;
pub const NID_X9_62_c2pnb368w1: c_int = 702;
pub const NID_X9_62_c2tnb431r1: c_int = 703;
pub const NID_X9_62_prime192v1: c_int = 409;
pub const NID_X9_62_prime192v2: c_int = 410;
pub const NID_X9_62_prime192v3: c_int = 411;
pub const NID_X9_62_prime239v1: c_int = 412;
pub const NID_X9_62_prime239v2: c_int = 413;
pub const NID_X9_62_prime239v3: c_int = 414;
pub const NID_X9_62_prime256v1: c_int = 415;
pub const NID_ecdsa_with_SHA1: c_int = 416;
pub const NID_ecdsa_with_Recommended: c_int = 791;
pub const NID_ecdsa_with_Specified: c_int = 792;
pub const NID_ecdsa_with_SHA224: c_int = 793;
pub const NID_ecdsa_with_SHA256: c_int = 794;
pub const NID_ecdsa_with_SHA384: c_int = 795;
pub const NID_ecdsa_with_SHA512: c_int = 796;
pub const NID_secp112r1: c_int = 704;
pub const NID_secp112r2: c_int = 705;
pub const NID_secp128r1: c_int = 706;
pub const NID_secp128r2: c_int = 707;
pub const NID_secp160k1: c_int = 708;
pub const NID_secp160r1: c_int = 709;
pub const NID_secp160r2: c_int = 710;
pub const NID_secp192k1: c_int = 711;
pub const NID_secp224k1: c_int = 712;
pub const NID_secp224r1: c_int = 713;
pub const NID_secp256k1: c_int = 714;
pub const NID_secp384r1: c_int = 715;
pub const NID_secp521r1: c_int = 716;
pub const NID_sect113r1: c_int = 717;
pub const NID_sect113r2: c_int = 718;
pub const NID_sect131r1: c_int = 719;
pub const NID_sect131r2: c_int = 720;
pub const NID_sect163k1: c_int = 721;
pub const NID_sect163r1: c_int = 722;
pub const NID_sect163r2: c_int = 723;
pub const NID_sect193r1: c_int = 724;
pub const NID_sect193r2: c_int = 725;
pub const NID_sect233k1: c_int = 726;
pub const NID_sect233r1: c_int = 727;
pub const NID_sect239k1: c_int = 728;
pub const NID_sect283k1: c_int = 729;
pub const NID_sect283r1: c_int = 730;
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;
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;
pub const NID_wap_wsg_idm_ecid_wtls5: c_int = 738;
pub const NID_wap_wsg_idm_ecid_wtls6: c_int = 739;
pub const NID_wap_wsg_idm_ecid_wtls7: c_int = 740;
pub const NID_wap_wsg_idm_ecid_wtls8: c_int = 741;
pub const NID_wap_wsg_idm_ecid_wtls9: c_int = 742;
pub const NID_wap_wsg_idm_ecid_wtls10: c_int = 743;
pub const NID_wap_wsg_idm_ecid_wtls11: c_int = 744;
pub const NID_wap_wsg_idm_ecid_wtls12: c_int = 745;
pub const NID_cast5_cbc: c_int = 108;
pub const NID_cast5_ecb: c_int = 109;
pub const NID_cast5_cfb64: c_int = 110;
pub const NID_cast5_ofb64: c_int = 111;
pub const NID_pbeWithMD5AndCast5_CBC: c_int = 112;
pub const NID_id_PasswordBasedMAC: c_int = 782;
pub const NID_id_DHBasedMac: c_int = 783;
pub const NID_rsadsi: c_int = 1;
pub const NID_pkcs: c_int = 2;
pub const NID_pkcs1: c_int = 186;
pub const NID_rsaEncryption: c_int = 6;
pub const NID_md2WithRSAEncryption: c_int = 7;
pub const NID_md4WithRSAEncryption: c_int = 396;
pub const NID_md5WithRSAEncryption: c_int = 8;
pub const NID_sha1WithRSAEncryption: c_int = 65;
pub const NID_rsaesOaep: c_int = 919;
pub const NID_mgf1: c_int = 911;
pub const NID_rsassaPss: c_int = 912;
pub const NID_sha256WithRSAEncryption: c_int = 668;
pub const NID_sha384WithRSAEncryption: c_int = 669;
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;
pub const NID_pkcs5: c_int = 187;
pub const NID_pbeWithMD2AndDES_CBC: c_int = 9;
pub const NID_pbeWithMD5AndDES_CBC: c_int = 10;
pub const NID_pbeWithMD2AndRC2_CBC: c_int = 168;
pub const NID_pbeWithMD5AndRC2_CBC: c_int = 169;
pub const NID_pbeWithSHA1AndDES_CBC: c_int = 170;
pub const NID_pbeWithSHA1AndRC2_CBC: c_int = 68;
pub const NID_id_pbkdf2: c_int = 69;
pub const NID_pbes2: c_int = 161;
pub const NID_pbmac1: c_int = 162;
pub const NID_pkcs7: c_int = 20;
pub const NID_pkcs7_data: c_int = 21;
pub const NID_pkcs7_signed: c_int = 22;
pub const NID_pkcs7_enveloped: c_int = 23;
pub const NID_pkcs7_signedAndEnveloped: c_int = 24;
pub const NID_pkcs7_digest: c_int = 25;
pub const NID_pkcs7_encrypted: c_int = 26;
pub const NID_pkcs9: c_int = 47;
pub const NID_pkcs9_emailAddress: c_int = 48;
pub const NID_pkcs9_unstructuredName: c_int = 49;
pub const NID_pkcs9_contentType: c_int = 50;
pub const NID_pkcs9_messageDigest: c_int = 51;
pub const NID_pkcs9_signingTime: c_int = 52;
pub const NID_pkcs9_countersignature: c_int = 53;
pub const NID_pkcs9_challengePassword: c_int = 54;
pub const NID_pkcs9_unstructuredAddress: c_int = 55;
pub const NID_pkcs9_extCertAttributes: c_int = 56;
pub const NID_ext_req: c_int = 172;
pub const NID_SMIMECapabilities: c_int = 167;
pub const NID_SMIME: c_int = 188;
pub const NID_id_smime_mod: c_int = 189;
pub const NID_id_smime_ct: c_int = 190;
pub const NID_id_smime_aa: c_int = 191;
pub const NID_id_smime_alg: c_int = 192;
pub const NID_id_smime_cd: c_int = 193;
pub const NID_id_smime_spq: c_int = 194;
pub const NID_id_smime_cti: c_int = 195;
pub const NID_id_smime_mod_cms: c_int = 196;
pub const NID_id_smime_mod_ess: c_int = 197;
pub const NID_id_smime_mod_oid: c_int = 198;
pub const NID_id_smime_mod_msg_v3: c_int = 199;
pub const NID_id_smime_mod_ets_eSignature_88: c_int = 200;
pub const NID_id_smime_mod_ets_eSignature_97: c_int = 201;
pub const NID_id_smime_mod_ets_eSigPolicy_88: c_int = 202;
pub const NID_id_smime_mod_ets_eSigPolicy_97: c_int = 203;
pub const NID_id_smime_ct_receipt: c_int = 204;
pub const NID_id_smime_ct_authData: c_int = 205;
pub const NID_id_smime_ct_publishCert: c_int = 206;
pub const NID_id_smime_ct_TSTInfo: c_int = 207;
pub const NID_id_smime_ct_TDTInfo: c_int = 208;
pub const NID_id_smime_ct_contentInfo: c_int = 209;
pub const NID_id_smime_ct_DVCSRequestData: c_int = 210;
pub const NID_id_smime_ct_DVCSResponseData: c_int = 211;
pub const NID_id_smime_ct_compressedData: c_int = 786;
pub const NID_id_ct_asciiTextWithCRLF: c_int = 787;
pub const NID_id_smime_aa_receiptRequest: c_int = 212;
pub const NID_id_smime_aa_securityLabel: c_int = 213;
pub const NID_id_smime_aa_mlExpandHistory: c_int = 214;
pub const NID_id_smime_aa_contentHint: c_int = 215;
pub const NID_id_smime_aa_msgSigDigest: c_int = 216;
pub const NID_id_smime_aa_encapContentType: c_int = 217;
pub const NID_id_smime_aa_contentIdentifier: c_int = 218;
pub const NID_id_smime_aa_macValue: c_int = 219;
pub const NID_id_smime_aa_equivalentLabels: c_int = 220;
pub const NID_id_smime_aa_contentReference: c_int = 221;
pub const NID_id_smime_aa_encrypKeyPref: c_int = 222;
pub const NID_id_smime_aa_signingCertificate: c_int = 223;
pub const NID_id_smime_aa_smimeEncryptCerts: c_int = 224;
pub const NID_id_smime_aa_timeStampToken: c_int = 225;
pub const NID_id_smime_aa_ets_sigPolicyId: c_int = 226;
pub const NID_id_smime_aa_ets_commitmentType: c_int = 227;
pub const NID_id_smime_aa_ets_signerLocation: c_int = 228;
pub const NID_id_smime_aa_ets_signerAttr: c_int = 229;
pub const NID_id_smime_aa_ets_otherSigCert: c_int = 230;
pub const NID_id_smime_aa_ets_contentTimestamp: c_int = 231;
pub const NID_id_smime_aa_ets_CertificateRefs: c_int = 232;
pub const NID_id_smime_aa_ets_RevocationRefs: c_int = 233;
pub const NID_id_smime_aa_ets_certValues: c_int = 234;
pub const NID_id_smime_aa_ets_revocationValues: c_int = 235;
pub const NID_id_smime_aa_ets_escTimeStamp: c_int = 236;
pub const NID_id_smime_aa_ets_certCRLTimestamp: c_int = 237;
pub const NID_id_smime_aa_ets_archiveTimeStamp: c_int = 238;
pub const NID_id_smime_aa_signatureType: c_int = 239;
pub const NID_id_smime_aa_dvcs_dvc: c_int = 240;
pub const NID_id_smime_alg_ESDHwith3DES: c_int = 241;
pub const NID_id_smime_alg_ESDHwithRC2: c_int = 242;
pub const NID_id_smime_alg_3DESwrap: c_int = 243;
pub const NID_id_smime_alg_RC2wrap: c_int = 244;
pub const NID_id_smime_alg_ESDH: c_int = 245;
pub const NID_id_smime_alg_CMS3DESwrap: c_int = 246;
pub const NID_id_smime_alg_CMSRC2wrap: c_int = 247;
pub const NID_id_alg_PWRI_KEK: c_int = 893;
pub const NID_id_smime_cd_ldap: c_int = 248;
pub const NID_id_smime_spq_ets_sqt_uri: c_int = 249;
pub const NID_id_smime_spq_ets_sqt_unotice: c_int = 250;
pub const NID_id_smime_cti_ets_proofOfOrigin: c_int = 251;
pub const NID_id_smime_cti_ets_proofOfReceipt: c_int = 252;
pub const NID_id_smime_cti_ets_proofOfDelivery: c_int = 253;
pub const NID_id_smime_cti_ets_proofOfSender: c_int = 254;
pub const NID_id_smime_cti_ets_proofOfApproval: c_int = 255;
pub const NID_id_smime_cti_ets_proofOfCreation: c_int = 256;
pub const NID_friendlyName: c_int = 156;
pub const NID_localKeyID: c_int = 157;
pub const NID_ms_csp_name: c_int = 417;
pub const NID_LocalKeySet: c_int = 856;
pub const NID_x509Certificate: c_int = 158;
pub const NID_sdsiCertificate: c_int = 159;
pub const NID_x509Crl: c_int = 160;
pub const NID_pbe_WithSHA1And128BitRC4: c_int = 144;
pub const NID_pbe_WithSHA1And40BitRC4: c_int = 145;
pub const NID_pbe_WithSHA1And3_Key_TripleDES_CBC: c_int = 146;
pub const NID_pbe_WithSHA1And2_Key_TripleDES_CBC: c_int = 147;
pub const NID_pbe_WithSHA1And128BitRC2_CBC: c_int = 148;
pub const NID_pbe_WithSHA1And40BitRC2_CBC: c_int = 149;
pub const NID_keyBag: c_int = 150;
pub const NID_pkcs8ShroudedKeyBag: c_int = 151;
pub const NID_certBag: c_int = 152;
pub const NID_crlBag: c_int = 153;
pub const NID_secretBag: c_int = 154;
pub const NID_safeContentsBag: c_int = 155;
pub const NID_md2: c_int = 3;
pub const NID_md4: c_int = 257;
pub const NID_md5: c_int = 4;
pub const NID_md5_sha1: c_int = 114;
pub const NID_hmacWithMD5: c_int = 797;
pub const NID_hmacWithSHA1: c_int = 163;
pub const NID_hmacWithSHA224: c_int = 798;
pub const NID_hmacWithSHA256: c_int = 799;
pub const NID_hmacWithSHA384: c_int = 800;
pub const NID_hmacWithSHA512: c_int = 801;
pub const NID_rc2_cbc: c_int = 37;
pub const NID_rc2_ecb: c_int = 38;
pub const NID_rc2_cfb64: c_int = 39;
pub const NID_rc2_ofb64: c_int = 40;
pub const NID_rc2_40_cbc: c_int = 98;
pub const NID_rc2_64_cbc: c_int = 166;
pub const NID_rc4: c_int = 5;
pub const NID_rc4_40: c_int = 97;
pub const NID_des_ede3_cbc: c_int = 44;
pub const NID_rc5_cbc: c_int = 120;
pub const NID_rc5_ecb: c_int = 121;
pub const NID_rc5_cfb64: c_int = 122;
pub const NID_rc5_ofb64: c_int = 123;
pub const NID_ms_ext_req: c_int = 171;
pub const NID_ms_code_ind: c_int = 134;
pub const NID_ms_code_com: c_int = 135;
pub const NID_ms_ctl_sign: c_int = 136;
pub const NID_ms_sgc: c_int = 137;
pub const NID_ms_efs: c_int = 138;
pub const NID_ms_smartcard_login: c_int = 648;
pub const NID_ms_upn: c_int = 649;
pub const NID_idea_cbc: c_int = 34;
pub const NID_idea_ecb: c_int = 36;
pub const NID_idea_cfb64: c_int = 35;
pub const NID_idea_ofb64: c_int = 46;
pub const NID_bf_cbc: c_int = 91;
pub const NID_bf_ecb: c_int = 92;
pub const NID_bf_cfb64: c_int = 93;
pub const NID_bf_ofb64: c_int = 94;
pub const NID_id_pkix: c_int = 127;
pub const NID_id_pkix_mod: c_int = 258;
pub const NID_id_pe: c_int = 175;
pub const NID_id_qt: c_int = 259;
pub const NID_id_kp: c_int = 128;
pub const NID_id_it: c_int = 260;
pub const NID_id_pkip: c_int = 261;
pub const NID_id_alg: c_int = 262;
pub const NID_id_cmc: c_int = 263;
pub const NID_id_on: c_int = 264;
pub const NID_id_pda: c_int = 265;
pub const NID_id_aca: c_int = 266;
pub const NID_id_qcs: c_int = 267;
pub const NID_id_cct: c_int = 268;
pub const NID_id_ppl: c_int = 662;
pub const NID_id_ad: c_int = 176;
pub const NID_id_pkix1_explicit_88: c_int = 269;
pub const NID_id_pkix1_implicit_88: c_int = 270;
pub const NID_id_pkix1_explicit_93: c_int = 271;
pub const NID_id_pkix1_implicit_93: c_int = 272;
pub const NID_id_mod_crmf: c_int = 273;
pub const NID_id_mod_cmc: c_int = 274;
pub const NID_id_mod_kea_profile_88: c_int = 275;
pub const NID_id_mod_kea_profile_93: c_int = 276;
pub const NID_id_mod_cmp: c_int = 277;
pub const NID_id_mod_qualified_cert_88: c_int = 278;
pub const NID_id_mod_qualified_cert_93: c_int = 279;
pub const NID_id_mod_attribute_cert: c_int = 280;
pub const NID_id_mod_timestamp_protocol: c_int = 281;
pub const NID_id_mod_ocsp: c_int = 282;
pub const NID_id_mod_dvcs: c_int = 283;
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;
pub const NID_sbgp_autonomousSysNum: c_int = 291;
pub const NID_sbgp_routerIdentifier: c_int = 292;
pub const NID_ac_proxying: c_int = 397;
pub const NID_sinfo_access: c_int = 398;
pub const NID_proxyCertInfo: c_int = 663;
pub const NID_id_qt_cps: c_int = 164;
pub const NID_id_qt_unotice: c_int = 165;
pub const NID_textNotice: c_int = 293;
pub const NID_server_auth: c_int = 129;
pub const NID_client_auth: c_int = 130;
pub const NID_code_sign: c_int = 131;
pub const NID_email_protect: c_int = 132;
pub const NID_ipsecEndSystem: c_int = 294;
pub const NID_ipsecTunnel: c_int = 295;
pub const NID_ipsecUser: c_int = 296;
pub const NID_time_stamp: c_int = 133;
pub const NID_OCSP_sign: c_int = 180;
pub const NID_dvcs: c_int = 297;
pub const NID_id_it_caProtEncCert: c_int = 298;
pub const NID_id_it_signKeyPairTypes: c_int = 299;
pub const NID_id_it_encKeyPairTypes: c_int = 300;
pub const NID_id_it_preferredSymmAlg: c_int = 301;
pub const NID_id_it_caKeyUpdateInfo: c_int = 302;
pub const NID_id_it_currentCRL: c_int = 303;
pub const NID_id_it_unsupportedOIDs: c_int = 304;
pub const NID_id_it_subscriptionRequest: c_int = 305;
pub const NID_id_it_subscriptionResponse: c_int = 306;
pub const NID_id_it_keyPairParamReq: c_int = 307;
pub const NID_id_it_keyPairParamRep: c_int = 308;
pub const NID_id_it_revPassphrase: c_int = 309;
pub const NID_id_it_implicitConfirm: c_int = 310;
pub const NID_id_it_confirmWaitTime: c_int = 311;
pub const NID_id_it_origPKIMessage: c_int = 312;
pub const NID_id_it_suppLangTags: c_int = 784;
pub const NID_id_regCtrl: c_int = 313;
pub const NID_id_regInfo: c_int = 314;
pub const NID_id_regCtrl_regToken: c_int = 315;
pub const NID_id_regCtrl_authenticator: c_int = 316;
pub const NID_id_regCtrl_pkiPublicationInfo: c_int = 317;
pub const NID_id_regCtrl_pkiArchiveOptions: c_int = 318;
pub const NID_id_regCtrl_oldCertID: c_int = 319;
pub const NID_id_regCtrl_protocolEncrKey: c_int = 320;
pub const NID_id_regInfo_utf8Pairs: c_int = 321;
pub const NID_id_regInfo_certReq: c_int = 322;
pub const NID_id_alg_des40: c_int = 323;
pub const NID_id_alg_noSignature: c_int = 324;
pub const NID_id_alg_dh_sig_hmac_sha1: c_int = 325;
pub const NID_id_alg_dh_pop: c_int = 326;
pub const NID_id_cmc_statusInfo: c_int = 327;
pub const NID_id_cmc_identification: c_int = 328;
pub const NID_id_cmc_identityProof: c_int = 329;
pub const NID_id_cmc_dataReturn: c_int = 330;
pub const NID_id_cmc_transactionId: c_int = 331;
pub const NID_id_cmc_senderNonce: c_int = 332;
pub const NID_id_cmc_recipientNonce: c_int = 333;
pub const NID_id_cmc_addExtensions: c_int = 334;
pub const NID_id_cmc_encryptedPOP: c_int = 335;
pub const NID_id_cmc_decryptedPOP: c_int = 336;
pub const NID_id_cmc_lraPOPWitness: c_int = 337;
pub const NID_id_cmc_getCert: c_int = 338;
pub const NID_id_cmc_getCRL: c_int = 339;
pub const NID_id_cmc_revokeRequest: c_int = 340;
pub const NID_id_cmc_regInfo: c_int = 341;
pub const NID_id_cmc_responseInfo: c_int = 342;
pub const NID_id_cmc_queryPending: c_int = 343;
pub const NID_id_cmc_popLinkRandom: c_int = 344;
pub const NID_id_cmc_popLinkWitness: c_int = 345;
pub const NID_id_cmc_confirmCertAcceptance: c_int = 346;
pub const NID_id_on_personalData: c_int = 347;
pub const NID_id_on_permanentIdentifier: c_int = 858;
pub const NID_id_pda_dateOfBirth: c_int = 348;
pub const NID_id_pda_placeOfBirth: c_int = 349;
pub const NID_id_pda_gender: c_int = 351;
pub const NID_id_pda_countryOfCitizenship: c_int = 352;
pub const NID_id_pda_countryOfResidence: c_int = 353;
pub const NID_id_aca_authenticationInfo: c_int = 354;
pub const NID_id_aca_accessIdentity: c_int = 355;
pub const NID_id_aca_chargingIdentity: c_int = 356;
pub const NID_id_aca_group: c_int = 357;
pub const NID_id_aca_role: c_int = 358;
pub const NID_id_aca_encAttrs: c_int = 399;
pub const NID_id_qcs_pkixQCSyntax_v1: c_int = 359;
pub const NID_id_cct_crs: c_int = 360;
pub const NID_id_cct_PKIData: c_int = 361;
pub const NID_id_cct_PKIResponse: c_int = 362;
pub const NID_id_ppl_anyLanguage: c_int = 664;
pub const NID_id_ppl_inheritAll: c_int = 665;
pub const NID_Independent: c_int = 667;
pub const NID_ad_OCSP: c_int = 178;
pub const NID_ad_ca_issuers: c_int = 179;
pub const NID_ad_timeStamping: c_int = 363;
pub const NID_ad_dvcs: c_int = 364;
pub const NID_caRepository: c_int = 785;
pub const NID_id_pkix_OCSP_basic: c_int = 365;
pub const NID_id_pkix_OCSP_Nonce: c_int = 366;
pub const NID_id_pkix_OCSP_CrlID: c_int = 367;
pub const NID_id_pkix_OCSP_acceptableResponses: c_int = 368;
pub const NID_id_pkix_OCSP_noCheck: c_int = 369;
pub const NID_id_pkix_OCSP_archiveCutoff: c_int = 370;
pub const NID_id_pkix_OCSP_serviceLocator: c_int = 371;
pub const NID_id_pkix_OCSP_extendedStatus: c_int = 372;
pub const NID_id_pkix_OCSP_valid: c_int = 373;
pub const NID_id_pkix_OCSP_path: c_int = 374;
pub const NID_id_pkix_OCSP_trustRoot: c_int = 375;
pub const NID_algorithm: c_int = 376;
pub const NID_md5WithRSA: c_int = 104;
pub const NID_des_ecb: c_int = 29;
pub const NID_des_cbc: c_int = 31;
pub const NID_des_ofb64: c_int = 45;
pub const NID_des_cfb64: c_int = 30;
pub const NID_rsaSignature: c_int = 377;
pub const NID_dsa_2: c_int = 67;
pub const NID_dsaWithSHA: c_int = 66;
pub const NID_shaWithRSAEncryption: c_int = 42;
pub const NID_des_ede_ecb: c_int = 32;
pub const NID_des_ede3_ecb: c_int = 33;
pub const NID_des_ede_cbc: c_int = 43;
pub const NID_des_ede_cfb64: c_int = 60;
pub const NID_des_ede3_cfb64: c_int = 61;
pub const NID_des_ede_ofb64: c_int = 62;
pub const NID_des_ede3_ofb64: c_int = 63;
pub const NID_desx_cbc: c_int = 80;
pub const NID_sha: c_int = 41;
pub const NID_sha1: c_int = 64;
pub const NID_dsaWithSHA1_2: c_int = 70;
pub const NID_sha1WithRSA: c_int = 115;
pub const NID_ripemd160: c_int = 117;
pub const NID_ripemd160WithRSA: c_int = 119;
pub const NID_sxnet: c_int = 143;
pub const NID_X500: c_int = 11;
pub const NID_X509: c_int = 12;
pub const NID_commonName: c_int = 13;
pub const NID_surname: c_int = 100;
pub const NID_serialNumber: c_int = 105;
pub const NID_countryName: c_int = 14;
pub const NID_localityName: c_int = 15;
pub const NID_stateOrProvinceName: c_int = 16;
pub const NID_streetAddress: c_int = 660;
pub const NID_organizationName: c_int = 17;
pub const NID_organizationalUnitName: c_int = 18;
pub const NID_title: c_int = 106;
pub const NID_description: c_int = 107;
pub const NID_searchGuide: c_int = 859;
pub const NID_businessCategory: c_int = 860;
pub const NID_postalAddress: c_int = 861;
pub const NID_postalCode: c_int = 661;
pub const NID_postOfficeBox: c_int = 862;
pub const NID_physicalDeliveryOfficeName: c_int = 863;
pub const NID_telephoneNumber: c_int = 864;
pub const NID_telexNumber: c_int = 865;
pub const NID_teletexTerminalIdentifier: c_int = 866;
pub const NID_facsimileTelephoneNumber: c_int = 867;
pub const NID_x121Address: c_int = 868;
pub const NID_internationaliSDNNumber: c_int = 869;
pub const NID_registeredAddress: c_int = 870;
pub const NID_destinationIndicator: c_int = 871;
pub const NID_preferredDeliveryMethod: c_int = 872;
pub const NID_presentationAddress: c_int = 873;
pub const NID_supportedApplicationContext: c_int = 874;
pub const NID_member: c_int = 875;
pub const NID_owner: c_int = 876;
pub const NID_roleOccupant: c_int = 877;
pub const NID_seeAlso: c_int = 878;
pub const NID_userPassword: c_int = 879;
pub const NID_userCertificate: c_int = 880;
pub const NID_cACertificate: c_int = 881;
pub const NID_authorityRevocationList: c_int = 882;
pub const NID_certificateRevocationList: c_int = 883;
pub const NID_crossCertificatePair: c_int = 884;
pub const NID_name: c_int = 173;
pub const NID_givenName: c_int = 99;
pub const NID_initials: c_int = 101;
pub const NID_generationQualifier: c_int = 509;
pub const NID_x500UniqueIdentifier: c_int = 503;
pub const NID_dnQualifier: c_int = 174;
pub const NID_enhancedSearchGuide: c_int = 885;
pub const NID_protocolInformation: c_int = 886;
pub const NID_distinguishedName: c_int = 887;
pub const NID_uniqueMember: c_int = 888;
pub const NID_houseIdentifier: c_int = 889;
pub const NID_supportedAlgorithms: c_int = 890;
pub const NID_deltaRevocationList: c_int = 891;
pub const NID_dmdName: c_int = 892;
pub const NID_pseudonym: c_int = 510;
pub const NID_role: c_int = 400;
pub const NID_X500algorithms: c_int = 378;
pub const NID_rsa: c_int = 19;
pub const NID_mdc2WithRSA: c_int = 96;
pub const NID_mdc2: c_int = 95;
pub const NID_id_ce: c_int = 81;
pub const NID_subject_directory_attributes: c_int = 769;
pub const NID_subject_key_identifier: c_int = 82;
pub const NID_key_usage: c_int = 83;
pub const NID_private_key_usage_period: c_int = 84;
pub const NID_subject_alt_name: c_int = 85;
pub const NID_issuer_alt_name: c_int = 86;
pub const NID_basic_constraints: c_int = 87;
pub const NID_crl_number: c_int = 88;
pub const NID_crl_reason: c_int = 141;
pub const NID_invalidity_date: c_int = 142;
pub const NID_delta_crl: c_int = 140;
pub const NID_issuing_distribution_point: c_int = 770;
pub const NID_certificate_issuer: c_int = 771;
pub const NID_name_constraints: c_int = 666;
pub const NID_crl_distribution_points: c_int = 103;
pub const NID_certificate_policies: c_int = 89;
pub const NID_any_policy: c_int = 746;
pub const NID_policy_mappings: c_int = 747;
pub const NID_authority_key_identifier: c_int = 90;
pub const NID_policy_constraints: c_int = 401;
pub const NID_ext_key_usage: c_int = 126;
pub const NID_freshest_crl: c_int = 857;
pub const NID_inhibit_any_policy: c_int = 748;
pub const NID_target_information: c_int = 402;
pub const NID_no_rev_avail: c_int = 403;
pub const NID_anyExtendedKeyUsage: c_int = 910;
pub const NID_netscape: c_int = 57;
pub const NID_netscape_cert_extension: c_int = 58;
pub const NID_netscape_data_type: c_int = 59;
pub const NID_netscape_cert_type: c_int = 71;
pub const NID_netscape_base_url: c_int = 72;
pub const NID_netscape_revocation_url: c_int = 73;
pub const NID_netscape_ca_revocation_url: c_int = 74;
pub const NID_netscape_renewal_url: c_int = 75;
pub const NID_netscape_ca_policy_url: c_int = 76;
pub const NID_netscape_ssl_server_name: c_int = 77;
pub const NID_netscape_comment: c_int = 78;
pub const NID_netscape_cert_sequence: c_int = 79;
pub const NID_ns_sgc: c_int = 139;
pub const NID_org: c_int = 379;
pub const NID_dod: c_int = 380;
pub const NID_iana: c_int = 381;
pub const NID_Directory: c_int = 382;
pub const NID_Management: c_int = 383;
pub const NID_Experimental: c_int = 384;
pub const NID_Private: c_int = 385;
pub const NID_Security: c_int = 386;
pub const NID_SNMPv2: c_int = 387;
pub const NID_Mail: c_int = 388;
pub const NID_Enterprises: c_int = 389;
pub const NID_dcObject: c_int = 390;
pub const NID_mime_mhs: c_int = 504;
pub const NID_mime_mhs_headings: c_int = 505;
pub const NID_mime_mhs_bodies: c_int = 506;
pub const NID_id_hex_partial_message: c_int = 507;
pub const NID_id_hex_multipart_message: c_int = 508;
pub const NID_zlib_compression: c_int = 125;
pub const NID_aes_128_ecb: c_int = 418;
pub const NID_aes_128_cbc: c_int = 419;
pub const NID_aes_128_ofb128: c_int = 420;
pub const NID_aes_128_cfb128: c_int = 421;
pub const NID_id_aes128_wrap: c_int = 788;
pub const NID_aes_128_gcm: c_int = 895;
pub const NID_aes_128_ccm: c_int = 896;
pub const NID_id_aes128_wrap_pad: c_int = 897;
pub const NID_aes_192_ecb: c_int = 422;
pub const NID_aes_192_cbc: c_int = 423;
pub const NID_aes_192_ofb128: c_int = 424;
pub const NID_aes_192_cfb128: c_int = 425;
pub const NID_id_aes192_wrap: c_int = 789;
pub const NID_aes_192_gcm: c_int = 898;
pub const NID_aes_192_ccm: c_int = 899;
pub const NID_id_aes192_wrap_pad: c_int = 900;
pub const NID_aes_256_ecb: c_int = 426;
pub const NID_aes_256_cbc: c_int = 427;
pub const NID_aes_256_ofb128: c_int = 428;
pub const NID_aes_256_cfb128: c_int = 429;
pub const NID_id_aes256_wrap: c_int = 790;
pub const NID_aes_256_gcm: c_int = 901;
pub const NID_aes_256_ccm: c_int = 902;
pub const NID_id_aes256_wrap_pad: c_int = 903;
pub const NID_aes_128_cfb1: c_int = 650;
pub const NID_aes_192_cfb1: c_int = 651;
pub const NID_aes_256_cfb1: c_int = 652;
pub const NID_aes_128_cfb8: c_int = 653;
pub const NID_aes_192_cfb8: c_int = 654;
pub const NID_aes_256_cfb8: c_int = 655;
pub const NID_aes_128_ctr: c_int = 904;
pub const NID_aes_192_ctr: c_int = 905;
pub const NID_aes_256_ctr: c_int = 906;
pub const NID_aes_128_xts: c_int = 913;
pub const NID_aes_256_xts: c_int = 914;
pub const NID_des_cfb1: c_int = 656;
pub const NID_des_cfb8: c_int = 657;
pub const NID_des_ede3_cfb1: c_int = 658;
pub const NID_des_ede3_cfb8: c_int = 659;
pub const NID_sha256: c_int = 672;
pub const NID_sha384: c_int = 673;
pub const NID_sha512: c_int = 674;
pub const NID_sha224: c_int = 675;
pub const NID_dsa_with_SHA224: c_int = 802;
pub const NID_dsa_with_SHA256: c_int = 803;
pub const NID_hold_instruction_code: c_int = 430;
pub const NID_hold_instruction_none: c_int = 431;
pub const NID_hold_instruction_call_issuer: c_int = 432;
pub const NID_hold_instruction_reject: c_int = 433;
pub const NID_data: c_int = 434;
pub const NID_pss: c_int = 435;
pub const NID_ucl: c_int = 436;
pub const NID_pilot: c_int = 437;
pub const NID_pilotAttributeType: c_int = 438;
pub const NID_pilotAttributeSyntax: c_int = 439;
pub const NID_pilotObjectClass: c_int = 440;
pub const NID_pilotGroups: c_int = 441;
pub const NID_iA5StringSyntax: c_int = 442;
pub const NID_caseIgnoreIA5StringSyntax: c_int = 443;
pub const NID_pilotObject: c_int = 444;
pub const NID_pilotPerson: c_int = 445;
pub const NID_account: c_int = 446;
pub const NID_document: c_int = 447;
pub const NID_room: c_int = 448;
pub const NID_documentSeries: c_int = 449;
pub const NID_Domain: c_int = 392;
pub const NID_rFC822localPart: c_int = 450;
pub const NID_dNSDomain: c_int = 451;
pub const NID_domainRelatedObject: c_int = 452;
pub const NID_friendlyCountry: c_int = 453;
pub const NID_simpleSecurityObject: c_int = 454;
pub const NID_pilotOrganization: c_int = 455;
pub const NID_pilotDSA: c_int = 456;
pub const NID_qualityLabelledData: c_int = 457;
pub const NID_userId: c_int = 458;
pub const NID_textEncodedORAddress: c_int = 459;
pub const NID_rfc822Mailbox: c_int = 460;
pub const NID_info: c_int = 461;
pub const NID_favouriteDrink: c_int = 462;
pub const NID_roomNumber: c_int = 463;
pub const NID_photo: c_int = 464;
pub const NID_userClass: c_int = 465;
pub const NID_host: c_int = 466;
pub const NID_manager: c_int = 467;
pub const NID_documentIdentifier: c_int = 468;
pub const NID_documentTitle: c_int = 469;
pub const NID_documentVersion: c_int = 470;
pub const NID_documentAuthor: c_int = 471;
pub const NID_documentLocation: c_int = 472;
pub const NID_homeTelephoneNumber: c_int = 473;
pub const NID_secretary: c_int = 474;
pub const NID_otherMailbox: c_int = 475;
pub const NID_lastModifiedTime: c_int = 476;
pub const NID_lastModifiedBy: c_int = 477;
pub const NID_domainComponent: c_int = 391;
pub const NID_aRecord: c_int = 478;
pub const NID_pilotAttributeType27: c_int = 479;
pub const NID_mXRecord: c_int = 480;
pub const NID_nSRecord: c_int = 481;
pub const NID_sOARecord: c_int = 482;
pub const NID_cNAMERecord: c_int = 483;
pub const NID_associatedDomain: c_int = 484;
pub const NID_associatedName: c_int = 485;
pub const NID_homePostalAddress: c_int = 486;
pub const NID_personalTitle: c_int = 487;
pub const NID_mobileTelephoneNumber: c_int = 488;
pub const NID_pagerTelephoneNumber: c_int = 489;
pub const NID_friendlyCountryName: c_int = 490;
pub const NID_organizationalStatus: c_int = 491;
pub const NID_janetMailbox: c_int = 492;
pub const NID_mailPreferenceOption: c_int = 493;
pub const NID_buildingName: c_int = 494;
pub const NID_dSAQuality: c_int = 495;
pub const NID_singleLevelQuality: c_int = 496;
pub const NID_subtreeMinimumQuality: c_int = 497;
pub const NID_subtreeMaximumQuality: c_int = 498;
pub const NID_personalSignature: c_int = 499;
pub const NID_dITRedirect: c_int = 500;
pub const NID_audio: c_int = 501;
pub const NID_documentPublisher: c_int = 502;
pub const NID_id_set: c_int = 512;
pub const NID_set_ctype: c_int = 513;
pub const NID_set_msgExt: c_int = 514;
pub const NID_set_attr: c_int = 515;
pub const NID_set_policy: c_int = 516;
pub const NID_set_certExt: c_int = 517;
pub const NID_set_brand: c_int = 518;
pub const NID_setct_PANData: c_int = 519;
pub const NID_setct_PANToken: c_int = 520;
pub const NID_setct_PANOnly: c_int = 521;
pub const NID_setct_OIData: c_int = 522;
pub const NID_setct_PI: c_int = 523;
pub const NID_setct_PIData: c_int = 524;
pub const NID_setct_PIDataUnsigned: c_int = 525;
pub const NID_setct_HODInput: c_int = 526;
pub const NID_setct_AuthResBaggage: c_int = 527;
pub const NID_setct_AuthRevReqBaggage: c_int = 528;
pub const NID_setct_AuthRevResBaggage: c_int = 529;
pub const NID_setct_CapTokenSeq: c_int = 530;
pub const NID_setct_PInitResData: c_int = 531;
pub const NID_setct_PI_TBS: c_int = 532;
pub const NID_setct_PResData: c_int = 533;
pub const NID_setct_AuthReqTBS: c_int = 534;
pub const NID_setct_AuthResTBS: c_int = 535;
pub const NID_setct_AuthResTBSX: c_int = 536;
pub const NID_setct_AuthTokenTBS: c_int = 537;
pub const NID_setct_CapTokenData: c_int = 538;
pub const NID_setct_CapTokenTBS: c_int = 539;
pub const NID_setct_AcqCardCodeMsg: c_int = 540;
pub const NID_setct_AuthRevReqTBS: c_int = 541;
pub const NID_setct_AuthRevResData: c_int = 542;
pub const NID_setct_AuthRevResTBS: c_int = 543;
pub const NID_setct_CapReqTBS: c_int = 544;
pub const NID_setct_CapReqTBSX: c_int = 545;
pub const NID_setct_CapResData: c_int = 546;
pub const NID_setct_CapRevReqTBS: c_int = 547;
pub const NID_setct_CapRevReqTBSX: c_int = 548;
pub const NID_setct_CapRevResData: c_int = 549;
pub const NID_setct_CredReqTBS: c_int = 550;
pub const NID_setct_CredReqTBSX: c_int = 551;
pub const NID_setct_CredResData: c_int = 552;
pub const NID_setct_CredRevReqTBS: c_int = 553;
pub const NID_setct_CredRevReqTBSX: c_int = 554;
pub const NID_setct_CredRevResData: c_int = 555;
pub const NID_setct_PCertReqData: c_int = 556;
pub const NID_setct_PCertResTBS: c_int = 557;
pub const NID_setct_BatchAdminReqData: c_int = 558;
pub const NID_setct_BatchAdminResData: c_int = 559;
pub const NID_setct_CardCInitResTBS: c_int = 560;
pub const NID_setct_MeAqCInitResTBS: c_int = 561;
pub const NID_setct_RegFormResTBS: c_int = 562;
pub const NID_setct_CertReqData: c_int = 563;
pub const NID_setct_CertReqTBS: c_int = 564;
pub const NID_setct_CertResData: c_int = 565;
pub const NID_setct_CertInqReqTBS: c_int = 566;
pub const NID_setct_ErrorTBS: c_int = 567;
pub const NID_setct_PIDualSignedTBE: c_int = 568;
pub const NID_setct_PIUnsignedTBE: c_int = 569;
pub const NID_setct_AuthReqTBE: c_int = 570;
pub const NID_setct_AuthResTBE: c_int = 571;
pub const NID_setct_AuthResTBEX: c_int = 572;
pub const NID_setct_AuthTokenTBE: c_int = 573;
pub const NID_setct_CapTokenTBE: c_int = 574;
pub const NID_setct_CapTokenTBEX: c_int = 575;
pub const NID_setct_AcqCardCodeMsgTBE: c_int = 576;
pub const NID_setct_AuthRevReqTBE: c_int = 577;
pub const NID_setct_AuthRevResTBE: c_int = 578;
pub const NID_setct_AuthRevResTBEB: c_int = 579;
pub const NID_setct_CapReqTBE: c_int = 580;
pub const NID_setct_CapReqTBEX: c_int = 581;
pub const NID_setct_CapResTBE: c_int = 582;
pub const NID_setct_CapRevReqTBE: c_int = 583;
pub const NID_setct_CapRevReqTBEX: c_int = 584;
pub const NID_setct_CapRevResTBE: c_int = 585;
pub const NID_setct_CredReqTBE: c_int = 586;
pub const NID_setct_CredReqTBEX: c_int = 587;
pub const NID_setct_CredResTBE: c_int = 588;
pub const NID_setct_CredRevReqTBE: c_int = 589;
pub const NID_setct_CredRevReqTBEX: c_int = 590;
pub const NID_setct_CredRevResTBE: c_int = 591;
pub const NID_setct_BatchAdminReqTBE: c_int = 592;
pub const NID_setct_BatchAdminResTBE: c_int = 593;
pub const NID_setct_RegFormReqTBE: c_int = 594;
pub const NID_setct_CertReqTBE: c_int = 595;
pub const NID_setct_CertReqTBEX: c_int = 596;
pub const NID_setct_CertResTBE: c_int = 597;
pub const NID_setct_CRLNotificationTBS: c_int = 598;
pub const NID_setct_CRLNotificationResTBS: c_int = 599;
pub const NID_setct_BCIDistributionTBS: c_int = 600;
pub const NID_setext_genCrypt: c_int = 601;
pub const NID_setext_miAuth: c_int = 602;
pub const NID_setext_pinSecure: c_int = 603;
pub const NID_setext_pinAny: c_int = 604;
pub const NID_setext_track2: c_int = 605;
pub const NID_setext_cv: c_int = 606;
pub const NID_set_policy_root: c_int = 607;
pub const NID_setCext_hashedRoot: c_int = 608;
pub const NID_setCext_certType: c_int = 609;
pub const NID_setCext_merchData: c_int = 610;
pub const NID_setCext_cCertRequired: c_int = 611;
pub const NID_setCext_tunneling: c_int = 612;
pub const NID_setCext_setExt: c_int = 613;
pub const NID_setCext_setQualf: c_int = 614;
pub const NID_setCext_PGWYcapabilities: c_int = 615;
pub const NID_setCext_TokenIdentifier: c_int = 616;
pub const NID_setCext_Track2Data: c_int = 617;
pub const NID_setCext_TokenType: c_int = 618;
pub const NID_setCext_IssuerCapabilities: c_int = 619;
pub const NID_setAttr_Cert: c_int = 620;
pub const NID_setAttr_PGWYcap: c_int = 621;
pub const NID_setAttr_TokenType: c_int = 622;
pub const NID_setAttr_IssCap: c_int = 623;
pub const NID_set_rootKeyThumb: c_int = 624;
pub const NID_set_addPolicy: c_int = 625;
pub const NID_setAttr_Token_EMV: c_int = 626;
pub const NID_setAttr_Token_B0Prime: c_int = 627;
pub const NID_setAttr_IssCap_CVM: c_int = 628;
pub const NID_setAttr_IssCap_T2: c_int = 629;
pub const NID_setAttr_IssCap_Sig: c_int = 630;
pub const NID_setAttr_GenCryptgrm: c_int = 631;
pub const NID_setAttr_T2Enc: c_int = 632;
pub const NID_setAttr_T2cleartxt: c_int = 633;
pub const NID_setAttr_TokICCsig: c_int = 634;
pub const NID_setAttr_SecDevSig: c_int = 635;
pub const NID_set_brand_IATA_ATA: c_int = 636;
pub const NID_set_brand_Diners: c_int = 637;
pub const NID_set_brand_AmericanExpress: c_int = 638;
pub const NID_set_brand_JCB: c_int = 639;
pub const NID_set_brand_Visa: c_int = 640;
pub const NID_set_brand_MasterCard: c_int = 641;
pub const NID_set_brand_Novus: c_int = 642;
pub const NID_des_cdmf: c_int = 643;
pub const NID_rsaOAEPEncryptionSET: c_int = 644;
pub const NID_ipsec3: c_int = 749;
pub const NID_ipsec4: c_int = 750;
pub const NID_whirlpool: c_int = 804;
pub const NID_cryptopro: c_int = 805;
pub const NID_cryptocom: c_int = 806;
pub const NID_id_GostR3411_94_with_GostR3410_2001: c_int = 807;
pub const NID_id_GostR3411_94_with_GostR3410_94: c_int = 808;
pub const NID_id_GostR3411_94: c_int = 809;
pub const NID_id_HMACGostR3411_94: c_int = 810;
pub const NID_id_GostR3410_2001: c_int = 811;
pub const NID_id_GostR3410_94: c_int = 812;
pub const NID_id_Gost28147_89: c_int = 813;
pub const NID_gost89_cnt: c_int = 814;
pub const NID_id_Gost28147_89_MAC: c_int = 815;
pub const NID_id_GostR3411_94_prf: c_int = 816;
pub const NID_id_GostR3410_2001DH: c_int = 817;
pub const NID_id_GostR3410_94DH: c_int = 818;
pub const NID_id_Gost28147_89_CryptoPro_KeyMeshing: c_int = 819;
pub const NID_id_Gost28147_89_None_KeyMeshing: c_int = 820;
pub const NID_id_GostR3411_94_TestParamSet: c_int = 821;
pub const NID_id_GostR3411_94_CryptoProParamSet: c_int = 822;
pub const NID_id_Gost28147_89_TestParamSet: c_int = 823;
pub const NID_id_Gost28147_89_CryptoPro_A_ParamSet: c_int = 824;
pub const NID_id_Gost28147_89_CryptoPro_B_ParamSet: c_int = 825;
pub const NID_id_Gost28147_89_CryptoPro_C_ParamSet: c_int = 826;
pub const NID_id_Gost28147_89_CryptoPro_D_ParamSet: c_int = 827;
pub const NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet: c_int = 828;
pub const NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet: c_int = 829;
pub const NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet: c_int = 830;
pub const NID_id_GostR3410_94_TestParamSet: c_int = 831;
pub const NID_id_GostR3410_94_CryptoPro_A_ParamSet: c_int = 832;
pub const NID_id_GostR3410_94_CryptoPro_B_ParamSet: c_int = 833;
pub const NID_id_GostR3410_94_CryptoPro_C_ParamSet: c_int = 834;
pub const NID_id_GostR3410_94_CryptoPro_D_ParamSet: c_int = 835;
pub const NID_id_GostR3410_94_CryptoPro_XchA_ParamSet: c_int = 836;
pub const NID_id_GostR3410_94_CryptoPro_XchB_ParamSet: c_int = 837;
pub const NID_id_GostR3410_94_CryptoPro_XchC_ParamSet: c_int = 838;
pub const NID_id_GostR3410_2001_TestParamSet: c_int = 839;
pub const NID_id_GostR3410_2001_CryptoPro_A_ParamSet: c_int = 840;
pub const NID_id_GostR3410_2001_CryptoPro_B_ParamSet: c_int = 841;
pub const NID_id_GostR3410_2001_CryptoPro_C_ParamSet: c_int = 842;
pub const NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet: c_int = 843;
pub const NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet: c_int = 844;
pub const NID_id_GostR3410_94_a: c_int = 845;
pub const NID_id_GostR3410_94_aBis: c_int = 846;
pub const NID_id_GostR3410_94_b: c_int = 847;
pub const NID_id_GostR3410_94_bBis: c_int = 848;
pub const NID_id_Gost28147_89_cc: c_int = 849;
pub const NID_id_GostR3410_94_cc: c_int = 850;
pub const NID_id_GostR3410_2001_cc: c_int = 851;
pub const NID_id_GostR3411_94_with_GostR3410_94_cc: c_int = 852;
pub const NID_id_GostR3411_94_with_GostR3410_2001_cc: c_int = 853;
pub const NID_id_GostR3410_2001_ParamSet_cc: c_int = 854;
pub const NID_camellia_128_cbc: c_int = 751;
pub const NID_camellia_192_cbc: c_int = 752;
pub const NID_camellia_256_cbc: c_int = 753;
pub const NID_id_camellia128_wrap: c_int = 907;
pub const NID_id_camellia192_wrap: c_int = 908;
pub const NID_id_camellia256_wrap: c_int = 909;
pub const NID_camellia_128_ecb: c_int = 754;
pub const NID_camellia_128_ofb128: c_int = 766;
pub const NID_camellia_128_cfb128: c_int = 757;
pub const NID_camellia_192_ecb: c_int = 755;
pub const NID_camellia_192_ofb128: c_int = 767;
pub const NID_camellia_192_cfb128: c_int = 758;
pub const NID_camellia_256_ecb: c_int = 756;
pub const NID_camellia_256_ofb128: c_int = 768;
pub const NID_camellia_256_cfb128: c_int = 759;
pub const NID_camellia_128_cfb1: c_int = 760;
pub const NID_camellia_192_cfb1: c_int = 761;
pub const NID_camellia_256_cfb1: c_int = 762;
pub const NID_camellia_128_cfb8: c_int = 763;
pub const NID_camellia_192_cfb8: c_int = 764;
pub const NID_camellia_256_cfb8: c_int = 765;
pub const NID_kisa: c_int = 773;
pub const NID_seed_ecb: c_int = 776;
pub const NID_seed_cbc: c_int = 777;
pub const NID_seed_cfb128: c_int = 779;
pub const NID_seed_ofb128: c_int = 778;
pub const NID_hmac: c_int = 855;
pub const NID_cmac: c_int = 894;
pub const NID_rc4_hmac_md5: c_int = 915;
pub const NID_aes_128_cbc_hmac_sha1: c_int = 916;
pub const NID_aes_192_cbc_hmac_sha1: c_int = 917;
pub const NID_aes_256_cbc_hmac_sha1: c_int = 918;
#[cfg(ossl111)]
pub const NID_ED25519: c_int = 1087;
#[cfg(ossl111)]
pub const NID_ED448: c_int = 1088;

View File

@ -1,18 +0,0 @@
use libc::*;
use *;
extern "C" {
pub fn OBJ_nid2ln(nid: c_int) -> *const c_char;
pub fn OBJ_nid2sn(nid: c_int) -> *const c_char;
pub fn OBJ_obj2nid(o: *const ASN1_OBJECT) -> c_int;
pub fn OBJ_obj2txt(
buf: *mut c_char,
buf_len: c_int,
a: *const ASN1_OBJECT,
no_name: c_int,
) -> c_int;
pub fn OBJ_find_sigid_algs(signid: c_int, pdig_nid: *mut c_int, ppkey_nid: *mut c_int)
-> c_int;
}

View File

@ -1,118 +0,0 @@
use libc::*;
use *;
pub const OCSP_REVOKED_STATUS_NOSTATUS: c_int = -1;
pub const OCSP_REVOKED_STATUS_UNSPECIFIED: c_int = 0;
pub const OCSP_REVOKED_STATUS_KEYCOMPROMISE: c_int = 1;
pub const OCSP_REVOKED_STATUS_CACOMPROMISE: c_int = 2;
pub const OCSP_REVOKED_STATUS_AFFILIATIONCHANGED: c_int = 3;
pub const OCSP_REVOKED_STATUS_SUPERSEDED: c_int = 4;
pub const OCSP_REVOKED_STATUS_CESSATIONOFOPERATION: c_int = 5;
pub const OCSP_REVOKED_STATUS_CERTIFICATEHOLD: c_int = 6;
pub const OCSP_REVOKED_STATUS_REMOVEFROMCRL: c_int = 8;
pub const OCSP_NOCERTS: c_ulong = 0x1;
pub const OCSP_NOINTERN: c_ulong = 0x2;
pub const OCSP_NOSIGS: c_ulong = 0x4;
pub const OCSP_NOCHAIN: c_ulong = 0x8;
pub const OCSP_NOVERIFY: c_ulong = 0x10;
pub const OCSP_NOEXPLICIT: c_ulong = 0x20;
pub const OCSP_NOCASIGN: c_ulong = 0x40;
pub const OCSP_NODELEGATED: c_ulong = 0x80;
pub const OCSP_NOCHECKS: c_ulong = 0x100;
pub const OCSP_TRUSTOTHER: c_ulong = 0x200;
pub const OCSP_RESPID_KEY: c_ulong = 0x400;
pub const OCSP_NOTIME: c_ulong = 0x800;
pub enum OCSP_CERTID {}
pub enum OCSP_ONEREQ {}
pub enum OCSP_REQUEST {}
pub const OCSP_RESPONSE_STATUS_SUCCESSFUL: c_int = 0;
pub const OCSP_RESPONSE_STATUS_MALFORMEDREQUEST: c_int = 1;
pub const OCSP_RESPONSE_STATUS_INTERNALERROR: c_int = 2;
pub const OCSP_RESPONSE_STATUS_TRYLATER: c_int = 3;
pub const OCSP_RESPONSE_STATUS_SIGREQUIRED: c_int = 5;
pub const OCSP_RESPONSE_STATUS_UNAUTHORIZED: c_int = 6;
pub const V_OCSP_CERTSTATUS_GOOD: c_int = 0;
pub const V_OCSP_CERTSTATUS_REVOKED: c_int = 1;
pub const V_OCSP_CERTSTATUS_UNKNOWN: c_int = 2;
pub enum OCSP_BASICRESP {}
cfg_if! {
if #[cfg(any(ossl110, libressl281))] {
extern "C" {
pub fn OCSP_cert_to_id(
dgst: *const EVP_MD,
subject: *const X509,
issuer: *const X509,
) -> *mut OCSP_CERTID;
}
} else {
extern "C" {
pub fn OCSP_cert_to_id(
dgst: *const EVP_MD,
subject: *mut X509,
issuer: *mut X509,
) -> *mut ::OCSP_CERTID;
}
}
}
extern "C" {
pub fn OCSP_request_add0_id(r: *mut OCSP_REQUEST, id: *mut OCSP_CERTID) -> *mut OCSP_ONEREQ;
pub fn OCSP_resp_find_status(
bs: *mut OCSP_BASICRESP,
id: *mut OCSP_CERTID,
status: *mut c_int,
reason: *mut c_int,
revtime: *mut *mut ASN1_GENERALIZEDTIME,
thisupd: *mut *mut ASN1_GENERALIZEDTIME,
nextupd: *mut *mut ASN1_GENERALIZEDTIME,
) -> c_int;
pub fn OCSP_check_validity(
thisupd: *mut ASN1_GENERALIZEDTIME,
nextupd: *mut ASN1_GENERALIZEDTIME,
sec: c_long,
maxsec: c_long,
) -> c_int;
pub fn OCSP_response_status(resp: *mut OCSP_RESPONSE) -> c_int;
pub fn OCSP_response_get1_basic(resp: *mut OCSP_RESPONSE) -> *mut OCSP_BASICRESP;
pub fn OCSP_response_create(status: c_int, bs: *mut OCSP_BASICRESP) -> *mut OCSP_RESPONSE;
pub fn OCSP_BASICRESP_new() -> *mut OCSP_BASICRESP;
pub fn OCSP_BASICRESP_free(r: *mut OCSP_BASICRESP);
pub fn OCSP_RESPONSE_new() -> *mut OCSP_RESPONSE;
pub fn OCSP_RESPONSE_free(r: *mut OCSP_RESPONSE);
pub fn i2d_OCSP_RESPONSE(a: *mut OCSP_RESPONSE, pp: *mut *mut c_uchar) -> c_int;
pub fn d2i_OCSP_RESPONSE(
a: *mut *mut OCSP_RESPONSE,
pp: *mut *const c_uchar,
length: c_long,
) -> *mut OCSP_RESPONSE;
pub fn OCSP_ONEREQ_free(r: *mut OCSP_ONEREQ);
pub fn OCSP_CERTID_free(id: *mut OCSP_CERTID);
pub fn OCSP_REQUEST_new() -> *mut OCSP_REQUEST;
pub fn OCSP_REQUEST_free(r: *mut OCSP_REQUEST);
pub fn i2d_OCSP_REQUEST(a: *mut OCSP_REQUEST, pp: *mut *mut c_uchar) -> c_int;
pub fn d2i_OCSP_REQUEST(
a: *mut *mut OCSP_REQUEST,
pp: *mut *const c_uchar,
length: c_long,
) -> *mut OCSP_REQUEST;
pub fn OCSP_basic_verify(
bs: *mut OCSP_BASICRESP,
certs: *mut stack_st_X509,
st: *mut X509_STORE,
flags: c_ulong,
) -> c_int;
}

985
openssl-sys/src/ossl10x.rs Normal file
View File

@ -0,0 +1,985 @@
use std::sync::{Mutex, MutexGuard};
use std::sync::{Once, ONCE_INIT};
use std::mem;
use std::ptr;
use std::process;
use std::io::{self, Write};
use libc::{c_int, c_char, c_void, c_long, c_uchar, size_t, c_uint, c_ulong};
#[cfg(not(ossl101))]
use libc::time_t;
#[repr(C)]
pub struct stack_st_ASN1_OBJECT {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_X509 {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_X509_NAME {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_X509_ATTRIBUTE {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_X509_EXTENSION {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_GENERAL_NAME {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_void {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_SSL_CIPHER {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_OPENSSL_STRING {
pub stack: _STACK,
}
#[repr(C)]
pub struct _STACK {
pub num: c_int,
pub data: *mut *mut c_char,
pub sorted: c_int,
pub num_alloc: c_int,
pub comp: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
}
#[repr(C)]
pub struct BIO_METHOD {
pub type_: c_int,
pub name: *const c_char,
pub bwrite: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int) -> c_int>,
pub bread: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
pub bputs: Option<unsafe extern "C" fn(*mut ::BIO, *const c_char) -> c_int>,
pub bgets: Option<unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int>,
pub ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, c_long, *mut c_void) -> c_long>,
pub create: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
pub destroy: Option<unsafe extern "C" fn(*mut ::BIO) -> c_int>,
pub callback_ctrl: Option<unsafe extern "C" fn(*mut ::BIO, c_int, ::bio_info_cb) -> c_long>,
}
#[repr(C)]
pub struct RSA {
pub pad: c_int,
pub version: c_long,
pub meth: *const ::RSA_METHOD,
pub engine: *mut ::ENGINE,
pub n: *mut ::BIGNUM,
pub e: *mut ::BIGNUM,
pub d: *mut ::BIGNUM,
pub p: *mut ::BIGNUM,
pub q: *mut ::BIGNUM,
pub dmp1: *mut ::BIGNUM,
pub dmq1: *mut ::BIGNUM,
pub iqmp: *mut ::BIGNUM,
pub ex_data: ::CRYPTO_EX_DATA,
pub references: c_int,
pub flags: c_int,
pub _method_mod_n: *mut ::BN_MONT_CTX,
pub _method_mod_p: *mut ::BN_MONT_CTX,
pub _method_mod_q: *mut ::BN_MONT_CTX,
pub bignum_data: *mut c_char,
pub blinding: *mut ::BN_BLINDING,
pub mt_blinding: *mut ::BN_BLINDING,
}
#[repr(C)]
pub struct DSA {
pub pad: c_int,
pub version: c_long,
pub write_params: c_int,
pub p: *mut ::BIGNUM,
pub q: *mut ::BIGNUM,
pub g: *mut ::BIGNUM,
pub pub_key: *mut ::BIGNUM,
pub priv_key: *mut ::BIGNUM,
pub kinv: *mut ::BIGNUM,
pub r: *mut ::BIGNUM,
pub flags: c_int,
pub method_mont_p: *mut ::BN_MONT_CTX,
pub references: c_int,
pub ex_data: ::CRYPTO_EX_DATA,
pub meth: *const ::DSA_METHOD,
pub engine: *mut ::ENGINE,
}
#[repr(C)]
pub struct EVP_PKEY {
pub type_: c_int,
pub save_type: c_int,
pub references: c_int,
pub ameth: *const ::EVP_PKEY_ASN1_METHOD,
pub engine: *mut ::ENGINE,
pub pkey: *mut c_void,
pub save_parameters: c_int,
pub attributes: *mut stack_st_X509_ATTRIBUTE,
}
#[repr(C)]
pub struct BIO {
pub method: *mut ::BIO_METHOD,
pub callback: Option<
unsafe extern "C" fn(*mut ::BIO,
c_int,
*const c_char,
c_int,
c_long,
c_long)
-> c_long,
>,
pub cb_arg: *mut c_char,
pub init: c_int,
pub shutdown: c_int,
pub flags: c_int,
pub retry_reason: c_int,
pub num: c_int,
pub ptr: *mut c_void,
pub next_bio: *mut ::BIO,
pub prev_bio: *mut ::BIO,
pub references: c_int,
pub num_read: c_ulong,
pub num_write: c_ulong,
pub ex_data: ::CRYPTO_EX_DATA,
}
#[repr(C)]
pub struct CRYPTO_EX_DATA {
pub sk: *mut ::stack_st_void,
pub dummy: c_int,
}
#[repr(C)]
pub struct EVP_MD_CTX {
digest: *mut ::EVP_MD,
engine: *mut ::ENGINE,
flags: c_ulong,
md_data: *mut c_void,
pctx: *mut ::EVP_PKEY_CTX,
update: *mut c_void,
}
#[repr(C)]
pub struct EVP_CIPHER {
pub nid: c_int,
pub block_size: c_int,
pub key_len: c_int,
pub iv_len: c_int,
pub flags: c_ulong,
pub init: Option<
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*const c_uchar,
*const c_uchar,
c_int)
-> c_int,
>,
pub do_cipher: Option<
unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX,
*mut c_uchar,
*const c_uchar,
size_t)
-> c_int,
>,
pub cleanup: Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX) -> c_int>,
pub ctx_size: c_int,
pub set_asn1_parameters:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
pub get_asn1_parameters:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, *mut ::ASN1_TYPE) -> c_int>,
pub ctrl:
Option<unsafe extern "C" fn(*mut ::EVP_CIPHER_CTX, c_int, c_int, *mut c_void) -> c_int>,
pub app_data: *mut c_void,
}
#[repr(C)]
pub struct HMAC_CTX {
md: *mut ::EVP_MD,
md_ctx: ::EVP_MD_CTX,
i_ctx: ::EVP_MD_CTX,
o_ctx: ::EVP_MD_CTX,
key_length: c_uint,
key: [c_uchar; 128],
}
#[repr(C)]
pub struct BIGNUM {
pub d: *mut ::BN_ULONG,
pub top: c_int,
pub dmax: c_int,
pub neg: c_int,
pub flags: c_int,
}
#[repr(C)]
pub struct DH {
pub pad: c_int,
pub version: c_int,
pub p: *mut ::BIGNUM,
pub g: *mut ::BIGNUM,
pub length: c_long,
pub pub_key: *mut ::BIGNUM,
pub priv_key: *mut ::BIGNUM,
pub flags: c_int,
pub method_mont_p: *mut ::BN_MONT_CTX,
pub q: *mut ::BIGNUM,
pub j: *mut ::BIGNUM,
pub seed: *mut c_uchar,
pub seedlen: c_int,
pub counter: *mut ::BIGNUM,
pub references: c_int,
pub ex_data: ::CRYPTO_EX_DATA,
pub meth: *const ::DH_METHOD,
pub engine: *mut ::ENGINE,
}
#[repr(C)]
pub struct X509 {
pub cert_info: *mut X509_CINF,
pub sig_alg: *mut ::X509_ALGOR,
pub signature: *mut ::ASN1_BIT_STRING,
pub valid: c_int,
pub references: c_int,
pub name: *mut c_char,
pub ex_data: ::CRYPTO_EX_DATA,
pub ex_pathlen: c_long,
pub ex_pcpathlen: c_long,
pub ex_flags: c_ulong,
pub ex_kusage: c_ulong,
pub ex_xkusage: c_ulong,
pub ex_nscert: c_ulong,
skid: *mut c_void,
akid: *mut c_void,
policy_cache: *mut c_void,
crldp: *mut c_void,
altname: *mut c_void,
nc: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))]
rfc3779_addr: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))]
rfc3779_asid: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_SHA"))]
sha1_hash: [c_uchar; 20],
aux: *mut c_void,
}
#[repr(C)]
pub struct X509_CINF {
version: *mut c_void,
serialNumber: *mut c_void,
signature: *mut c_void,
issuer: *mut c_void,
pub validity: *mut X509_VAL,
subject: *mut c_void,
key: *mut c_void,
issuerUID: *mut c_void,
subjectUID: *mut c_void,
pub extensions: *mut stack_st_X509_EXTENSION,
enc: ASN1_ENCODING,
}
#[repr(C)]
pub struct X509_ALGOR {
pub algorithm: *mut ::ASN1_OBJECT,
parameter: *mut c_void,
}
#[repr(C)]
pub struct ASN1_ENCODING {
pub enc: *mut c_uchar,
pub len: c_long,
pub modified: c_int,
}
#[repr(C)]
pub struct X509_VAL {
pub notBefore: *mut ::ASN1_TIME,
pub notAfter: *mut ::ASN1_TIME,
}
#[repr(C)]
pub struct X509_REQ_INFO {
pub enc: ASN1_ENCODING,
pub version: *mut ::ASN1_INTEGER,
pub subject: *mut ::X509_NAME,
pubkey: *mut c_void,
pub attributes: *mut stack_st_X509_ATTRIBUTE,
}
#[repr(C)]
pub struct X509_REQ {
pub req_info: *mut X509_REQ_INFO,
sig_alg: *mut c_void,
signature: *mut c_void,
references: c_int,
}
#[repr(C)]
pub struct SSL {
version: c_int,
type_: c_int,
method: *const ::SSL_METHOD,
rbio: *mut c_void,
wbio: *mut c_void,
bbio: *mut c_void,
rwstate: c_int,
in_handshake: c_int,
handshake_func: Option<unsafe extern "C" fn(*mut SSL) -> c_int>,
pub server: c_int,
new_session: c_int,
quiet_session: c_int,
shutdown: c_int,
state: c_int,
rstate: c_int,
init_buf: *mut c_void,
init_msg: *mut c_void,
init_num: c_int,
init_off: c_int,
packet: *mut c_uchar,
packet_length: c_uint,
s2: *mut c_void,
s3: *mut c_void,
d1: *mut c_void,
read_ahead: c_int,
msg_callback: Option<
unsafe extern "C" fn(c_int,
c_int,
c_int,
*const c_void,
size_t,
*mut SSL,
*mut c_void),
>,
msg_callback_arg: *mut c_void,
hit: c_int,
param: *mut c_void,
cipher_list: *mut stack_st_SSL_CIPHER,
cipher_list_by_id: *mut stack_st_SSL_CIPHER,
mac_flags: c_int,
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
read_hash: *mut ::EVP_MD_CTX,
expand: *mut c_void,
enc_write_ctx: *mut ::EVP_CIPHER_CTX,
write_hash: *mut ::EVP_MD_CTX,
compress: *mut c_void,
cert: *mut c_void,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
session: *mut ::SSL_SESSION,
generate_session_id: ::GEN_SESSION_CB,
verify_mode: c_int,
verify_callback: Option<unsafe extern "C" fn(c_int, *mut ::X509_STORE_CTX) -> c_int>,
info_callback: Option<unsafe extern "C" fn(*mut SSL, c_int, c_int)>,
error: c_int,
error_code: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_KRB5"))]
kssl_ctx: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_client_callback: Option<
unsafe extern "C" fn(*mut SSL,
*const c_char,
*mut c_char,
c_uint,
*mut c_uchar,
c_uint)
-> c_uint,
>,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_server_callback:
Option<unsafe extern "C" fn(*mut SSL, *const c_char, *mut c_uchar, c_uint) -> c_uint>,
ctx: *mut ::SSL_CTX,
debug: c_int,
verify_result: c_long,
ex_data: ::CRYPTO_EX_DATA,
client_CA: *mut stack_st_X509_NAME,
references: c_int,
options: c_ulong,
mode: c_ulong,
max_cert_list: c_long,
first_packet: c_int,
client_version: c_int,
max_send_fragment: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_debug_cb:
Option<unsafe extern "C" fn(*mut SSL, c_int, c_int, *mut c_uchar, c_int, *mut c_void)>,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_debug_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_hostname: *mut c_char,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
servername_done: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_status_type: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_status_expected: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ocsp_ids: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ocsp_exts: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ocsp_resp: *mut c_uchar,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ocsp_resplen: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ticket_expected: c_int,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
tlsext_ecpointformatlist_length: size_t,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
tlsext_ecpointformatlist: *mut c_uchar,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
tlsext_ellipticcurvelist_length: size_t,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
tlsext_ellipticcurvelist: *mut c_uchar,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_opaque_prf_input: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_opaque_prf_input_len: size_t,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_session_ticket: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_session_ticket_ext_cb: ::tls_session_ticket_ext_cb_fn,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tls_session_ticket_ext_cb_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tls_session_secret_cb: ::tls_session_secret_cb_fn,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tls_session_secret_cb_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
initial_ctx: *mut ::SSL_CTX,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
next_proto_negotiated: *mut c_uchar,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
next_proto_negotiated_len: c_uchar,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
srtp_profiles: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
srtp_profile: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_heartbeat: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_hb_pending: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_hb_seq: c_uint,
renegotiate: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
srp_ctx: ::SRP_CTX,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_client_proto_list: *mut c_uchar,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_client_proto_list_len: c_uint,
}
#[repr(C)]
pub struct SSL_CTX {
method: *mut c_void,
cipher_list: *mut c_void,
cipher_list_by_id: *mut c_void,
cert_store: *mut c_void,
sessions: *mut c_void,
session_cache_size: c_ulong,
session_cache_head: *mut c_void,
session_cache_tail: *mut c_void,
session_cache_mode: c_int,
session_timeout: c_long,
new_session_cb: *mut c_void,
remove_session_cb: *mut c_void,
get_session_cb: *mut c_void,
stats: [c_int; 11],
pub references: c_int,
app_verify_callback: *mut c_void,
app_verify_arg: *mut c_void,
default_passwd_callback: *mut c_void,
default_passwd_callback_userdata: *mut c_void,
client_cert_cb: *mut c_void,
app_gen_cookie_cb: *mut c_void,
app_verify_cookie_cb: *mut c_void,
ex_dat: ::CRYPTO_EX_DATA,
rsa_md5: *mut c_void,
md5: *mut c_void,
sha1: *mut c_void,
extra_certs: *mut c_void,
comp_methods: *mut c_void,
info_callback: *mut c_void,
client_CA: *mut c_void,
options: c_ulong,
mode: c_ulong,
max_cert_list: c_long,
cert: *mut c_void,
read_ahead: c_int,
msg_callback: *mut c_void,
msg_callback_arg: *mut c_void,
verify_mode: c_int,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; 32],
default_verify_callback: *mut c_void,
generate_session_id: *mut c_void,
param: *mut c_void,
quiet_shutdown: c_int,
max_send_fragment: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))]
client_cert_engine: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_servername_callback: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsect_servername_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_tick_key_name: [c_uchar; 16],
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_tick_hmac_key: [c_uchar; 16],
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_tick_aes_key: [c_uchar; 16],
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ticket_key_cb: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_status_cb: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_status_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_opaque_prf_input_callback: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_opaque_prf_input_callback_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_identity_hint: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_client_callback: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_server_callback: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
freelist_max_len: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
wbuf_freelist: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
rbuf_freelist: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
srp_ctx: SRP_CTX,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
next_protos_advertised_cb: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
next_protos_advertised_cb_arg: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
next_proto_select_cb: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))]
next_proto_select_cb_arg: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl101))]
srtp_profiles: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
srtp_profiles: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_select_cb: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_select_cb_arg: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_client_proto_list: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_client_proto_list_len: c_uint,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC"), ossl102))]
tlsext_ecpointformatlist_length: size_t,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC"), ossl102))]
tlsext_ecpointformatlist: *mut c_uchar,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC"), ossl102))]
tlsext_ellipticcurvelist_length: size_t,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC"), ossl102))]
tlsext_ellipticcurvelist: *mut c_uchar,
}
#[repr(C)]
pub struct SSL_SESSION {
ssl_version: c_int,
key_arg_length: c_uint,
key_arg: [c_uchar; SSL_MAX_KEY_ARG_LENGTH as usize],
pub master_key_length: c_int,
pub master_key: [c_uchar; 48],
session_id_length: c_uint,
session_id: [c_uchar; SSL_MAX_SSL_SESSION_ID_LENGTH as usize],
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize],
#[cfg(not(osslconf = "OPENSSL_NO_KRB5"))]
krb5_client_princ_len: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_KRB5"))]
krb5_client_princ: [c_uchar; SSL_MAX_KRB5_PRINCIPAL_LENGTH as usize],
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_identity_hint: *mut c_char,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_identity: *mut c_char,
not_resumable: c_int,
sess_cert: *mut c_void,
peer: *mut X509,
verify_result: c_long,
pub references: c_int,
timeout: c_long,
time: c_long,
compress_meth: c_uint,
cipher: *const c_void,
cipher_id: c_ulong,
ciphers: *mut c_void,
ex_data: ::CRYPTO_EX_DATA,
prev: *mut c_void,
next: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_hostname: *mut c_char,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
tlsext_ecpointformatlist_length: size_t,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
tlsext_ecpointformatlist: *mut c_uchar,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
tlsext_ellipticcurvelist_length: size_t,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
tlsext_ellipticcurvelist: *mut c_uchar,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_tick: *mut c_uchar,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ticklen: size_t,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_tick_lifetime_hint: c_long,
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
srp_username: *mut c_char,
}
#[repr(C)]
pub struct SRP_CTX {
SRP_cb_arg: *mut c_void,
TLS_ext_srp_username_callback: *mut c_void,
SRP_verify_param_callback: *mut c_void,
SRP_give_srp_client_pwd_callback: *mut c_void,
login: *mut c_void,
N: *mut c_void,
g: *mut c_void,
s: *mut c_void,
B: *mut c_void,
A: *mut c_void,
a: *mut c_void,
b: *mut c_void,
v: *mut c_void,
info: *mut c_void,
stringth: c_int,
srp_Mask: c_ulong,
}
#[repr(C)]
#[cfg(not(ossl101))]
pub struct X509_VERIFY_PARAM {
pub name: *mut c_char,
pub check_time: time_t,
pub inh_flags: c_ulong,
pub flags: c_ulong,
pub purpose: c_int,
pub trust: c_int,
pub depth: c_int,
pub policies: *mut stack_st_ASN1_OBJECT,
pub id: *mut X509_VERIFY_PARAM_ID,
}
#[cfg(not(ossl101))]
pub enum X509_VERIFY_PARAM_ID {}
pub enum PKCS12 {}
pub const SSL_CTRL_GET_SESSION_REUSED: c_int = 8;
pub const SSL_CTRL_OPTIONS: c_int = 32;
pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77;
#[cfg(ossl102)]
pub const SSL_CTRL_SET_ECDH_AUTO: c_int = 94;
pub const SSL_OP_MICROSOFT_SESS_ID_BUG: c_ulong = 0x00000001;
pub const SSL_OP_NETSCAPE_CHALLENGE_BUG: c_ulong = 0x00000002;
pub const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: c_ulong = 0x00000008;
pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: c_ulong = 0x00000020;
pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: c_ulong = 0x00000080;
pub const SSL_OP_TLS_D5_BUG: c_ulong = 0x00000100;
pub const SSL_OP_TLS_BLOCK_PADDING_BUG: c_ulong = 0x00000200;
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00080000;
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000;
pub const SSL_OP_NO_SSLv2: c_ulong = 0x01000000;
pub const SSL_MAX_SSL_SESSION_ID_LENGTH: c_int = 32;
pub const SSL_MAX_SID_CTX_LENGTH: c_int = 32;
pub const SSL_MAX_KEY_ARG_LENGTH: c_int = 8;
pub const SSL_MAX_MASTER_KEY_LENGTH: c_int = 48;
pub const SSL_MAX_KRB5_PRINCIPAL_LENGTH: c_int = 256;
pub const SSLEAY_VERSION: c_int = 0;
pub const SSLEAY_CFLAGS: c_int = 2;
pub const SSLEAY_BUILT_ON: c_int = 3;
pub const SSLEAY_PLATFORM: c_int = 4;
pub const SSLEAY_DIR: c_int = 5;
pub const CRYPTO_LOCK_X509: c_int = 3;
pub const CRYPTO_LOCK_SSL_CTX: c_int = 12;
pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14;
static mut MUTEXES: *mut Vec<Mutex<()>> = 0 as *mut Vec<Mutex<()>>;
static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> = 0 as
*mut Vec<Option<MutexGuard<'static, ()>>>;
unsafe extern "C" fn locking_function(mode: c_int, n: c_int, _file: *const c_char, _line: c_int) {
let mutex = &(*MUTEXES)[n as usize];
if mode & ::CRYPTO_LOCK != 0 {
(*GUARDS)[n as usize] = Some(mutex.lock().unwrap());
} else {
if let None = (*GUARDS)[n as usize].take() {
let _ = writeln!(
io::stderr(),
"BUG: rust-openssl lock {} already unlocked, aborting",
n
);
process::abort();
}
}
}
pub fn init() {
static INIT: Once = ONCE_INIT;
INIT.call_once(|| unsafe {
SSL_library_init();
SSL_load_error_strings();
OPENSSL_add_all_algorithms_noconf();
let num_locks = ::CRYPTO_num_locks();
let mut mutexes = Box::new(Vec::new());
for _ in 0..num_locks {
mutexes.push(Mutex::new(()));
}
MUTEXES = mem::transmute(mutexes);
let guards: Box<Vec<Option<MutexGuard<()>>>> =
Box::new((0..num_locks).map(|_| None).collect());
GUARDS = mem::transmute(guards);
CRYPTO_set_locking_callback(locking_function);
set_id_callback();
})
}
#[cfg(unix)]
fn set_id_callback() {
unsafe extern "C" fn thread_id() -> c_ulong {
::libc::pthread_self() as c_ulong
}
unsafe {
CRYPTO_set_id_callback(thread_id);
}
}
#[cfg(not(unix))]
fn set_id_callback() {}
// macros
#[cfg(ossl102)]
pub unsafe fn SSL_CTX_set_ecdh_auto(ctx: *mut SSL_CTX, onoff: c_int) -> c_int {
::SSL_CTX_ctrl(
ctx,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut(),
) as c_int
}
#[cfg(ossl102)]
pub unsafe fn SSL_set_ecdh_auto(ssl: *mut ::SSL, onoff: c_int) -> c_int {
::SSL_ctrl(
ssl,
SSL_CTRL_SET_ECDH_AUTO,
onoff as c_long,
ptr::null_mut(),
) as c_int
}
pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int {
::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int
}
extern "C" {
pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO;
pub fn BIO_s_file() -> *mut BIO_METHOD;
pub fn BIO_s_mem() -> *mut BIO_METHOD;
pub fn get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn CRYPTO_malloc(num: c_int, file: *const c_char, line: c_int) -> *mut c_void;
pub fn CRYPTO_free(buf: *mut c_void);
pub fn CRYPTO_num_locks() -> c_int;
pub fn CRYPTO_set_locking_callback(
func: unsafe extern "C" fn(mode: c_int, n: c_int, file: *const c_char, line: c_int),
);
pub fn CRYPTO_set_id_callback(func: unsafe extern "C" fn() -> c_ulong);
pub fn ERR_load_crypto_strings();
pub fn RSA_generate_key(
modsz: c_int,
e: c_ulong,
cb: Option<extern "C" fn(c_int, c_int, *mut c_void)>,
cbarg: *mut c_void,
) -> *mut RSA;
pub fn OCSP_cert_to_id(
dgst: *const ::EVP_MD,
subject: *mut ::X509,
issuer: *mut ::X509,
) -> *mut ::OCSP_CERTID;
pub fn PKCS12_create(
pass: *mut c_char,
friendly_name: *mut c_char,
pkey: *mut EVP_PKEY,
cert: *mut X509,
ca: *mut stack_st_X509,
nid_key: c_int,
nid_cert: c_int,
iter: c_int,
mac_iter: c_int,
keytype: c_int,
) -> *mut PKCS12;
pub fn SSL_library_init() -> c_int;
pub fn SSL_load_error_strings();
pub fn OPENSSL_add_all_algorithms_noconf();
pub fn HMAC_CTX_init(ctx: *mut ::HMAC_CTX);
pub fn HMAC_CTX_cleanup(ctx: *mut ::HMAC_CTX);
#[cfg(not(osslconf = "OPENSSL_NO_SSL3_METHOD"))]
pub fn SSLv3_method() -> *const ::SSL_METHOD;
pub fn TLSv1_method() -> *const ::SSL_METHOD;
pub fn SSLv23_method() -> *const ::SSL_METHOD;
pub fn TLSv1_1_method() -> *const ::SSL_METHOD;
pub fn TLSv1_2_method() -> *const ::SSL_METHOD;
pub fn DTLSv1_method() -> *const ::SSL_METHOD;
#[cfg(ossl102)]
pub fn DTLSv1_2_method() -> *const ::SSL_METHOD;
pub fn SSL_get_ex_new_index(
argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>,
) -> c_int;
pub fn SSL_set_tmp_ecdh_callback(
ssl: *mut ::SSL,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
-> *mut ::EC_KEY,
);
pub fn SSL_CIPHER_get_version(cipher: *const ::SSL_CIPHER) -> *mut c_char;
pub fn SSL_CTX_get_ex_new_index(
argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>,
) -> c_int;
pub fn SSL_CTX_set_tmp_ecdh_callback(
ctx: *mut ::SSL_CTX,
ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int)
-> *mut ::EC_KEY,
);
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_get_ext_d2i(
x: *mut ::X509,
nid: c_int,
crit: *mut c_int,
idx: *mut c_int,
) -> *mut c_void;
pub fn X509_NAME_add_entry_by_NID(
x: *mut ::X509_NAME,
field: c_int,
ty: c_int,
bytes: *mut c_uchar,
len: c_int,
loc: c_int,
set: c_int,
) -> c_int;
#[cfg(not(ossl101))]
pub fn X509_get0_signature(
psig: *mut *mut ::ASN1_BIT_STRING,
palg: *mut *mut ::X509_ALGOR,
x: *const ::X509,
);
#[cfg(not(ossl101))]
pub fn X509_get_signature_nid(x: *const X509) -> c_int;
#[cfg(not(ossl101))]
pub fn X509_ALGOR_get0(
paobj: *mut *mut ::ASN1_OBJECT,
pptype: *mut c_int,
ppval: *mut *mut c_void,
alg: *mut ::X509_ALGOR,
);
pub fn X509_NAME_get_entry(n: *mut ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
pub fn X509_NAME_ENTRY_get_data(ne: *mut ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
pub fn X509_STORE_CTX_get_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
pub fn X509V3_EXT_nconf_nid(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
ext_nid: c_int,
value: *mut c_char,
) -> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
name: *mut c_char,
value: *mut c_char,
) -> *mut ::X509_EXTENSION;
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *mut ::ASN1_STRING) -> c_int;
pub fn ASN1_STRING_data(x: *mut ::ASN1_STRING) -> *mut c_uchar;
pub fn CRYPTO_add_lock(
pointer: *mut c_int,
amount: c_int,
type_: c_int,
file: *const c_char,
line: c_int,
) -> c_int;
pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
pub fn EVP_PKEY_bits(key: *mut EVP_PKEY) -> c_int;
pub fn sk_new_null() -> *mut _STACK;
pub fn sk_num(st: *const _STACK) -> c_int;
pub fn sk_value(st: *const _STACK, n: c_int) -> *mut c_void;
pub fn sk_free(st: *mut _STACK);
pub fn sk_push(st: *mut _STACK, data: *mut c_void) -> c_int;
pub fn sk_pop_free(st: *mut _STACK, free: Option<unsafe extern "C" fn(*mut c_void)>);
pub fn sk_pop(st: *mut _STACK) -> *mut c_void;
pub fn SSLeay() -> c_ulong;
pub fn SSLeay_version(key: c_int) -> *const c_char;
}

291
openssl-sys/src/ossl110.rs Normal file
View File

@ -0,0 +1,291 @@
use libc::{c_int, c_void, c_char, c_uchar, c_ulong, c_long, c_uint, size_t};
use std::sync::{Once, ONCE_INIT};
use std::ptr;
pub enum BIGNUM {}
pub enum BIO {}
pub enum BIO_METHOD {}
pub enum CRYPTO_EX_DATA {}
pub enum DH {}
pub enum DSA {}
pub enum EVP_CIPHER {}
pub enum EVP_MD_CTX {}
pub enum EVP_PKEY {}
pub enum HMAC_CTX {}
pub enum OPENSSL_STACK {}
pub enum PKCS12 {}
pub enum RSA {}
pub enum SSL {}
pub enum SSL_CTX {}
pub enum SSL_SESSION {}
pub enum stack_st_ASN1_OBJECT {}
pub enum stack_st_GENERAL_NAME {}
pub enum stack_st_OPENSSL_STRING {}
pub enum stack_st_void {}
pub enum stack_st_X509 {}
pub enum stack_st_X509_NAME {}
pub enum stack_st_X509_ATTRIBUTE {}
pub enum stack_st_X509_EXTENSION {}
pub enum stack_st_SSL_CIPHER {}
pub enum OPENSSL_INIT_SETTINGS {}
pub enum X509 {}
pub enum X509_ALGOR {}
pub enum X509_VERIFY_PARAM {}
pub enum X509_REQ {}
pub const SSL_OP_MICROSOFT_SESS_ID_BUG: c_ulong = 0x00000000;
pub const SSL_OP_NETSCAPE_CHALLENGE_BUG: c_ulong = 0x00000000;
pub const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: c_ulong = 0x00000000;
pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: c_ulong = 0x00000000;
pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: c_ulong = 0x00000000;
pub const SSL_OP_TLS_D5_BUG: c_ulong = 0x00000000;
pub const SSL_OP_TLS_BLOCK_PADDING_BUG: c_ulong = 0x00000000;
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00000000;
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00000000;
pub const SSL_OP_NO_SSLv2: c_ulong = 0x00000000;
pub const OPENSSL_VERSION: c_int = 0;
pub const OPENSSL_CFLAGS: c_int = 1;
pub const OPENSSL_BUILT_ON: c_int = 2;
pub const OPENSSL_PLATFORM: c_int = 3;
pub const OPENSSL_DIR: c_int = 4;
pub const CRYPTO_EX_INDEX_SSL: c_int = 0;
pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 1;
pub const OPENSSL_INIT_LOAD_SSL_STRINGS: u64 = 0x00200000;
pub const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT: c_uint = 0x20;
pub fn init() {
// explicitly initialize to work around https://github.com/openssl/openssl/issues/3505
static INIT: Once = ONCE_INIT;
INIT.call_once(|| unsafe {
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, ptr::null_mut());
})
}
extern "C" {
pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO;
pub fn BIO_s_file() -> *const BIO_METHOD;
pub fn BIO_s_mem() -> *const BIO_METHOD;
pub fn BN_get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM;
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);
pub fn EVP_chacha20() -> *const ::EVP_CIPHER;
pub fn EVP_chacha20_poly1305() -> *const ::EVP_CIPHER;
pub fn HMAC_CTX_new() -> *mut HMAC_CTX;
pub fn HMAC_CTX_free(ctx: *mut HMAC_CTX);
pub fn OCSP_cert_to_id(
dgst: *const ::EVP_MD,
subject: *const ::X509,
issuer: *const ::X509,
) -> *mut ::OCSP_CERTID;
pub fn TLS_method() -> *const ::SSL_METHOD;
pub fn DTLS_method() -> *const ::SSL_METHOD;
pub fn SSL_CIPHER_get_version(cipher: *const ::SSL_CIPHER) -> *const c_char;
pub fn X509_get_subject_name(x: *const ::X509) -> *mut ::X509_NAME;
pub fn X509_set1_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set1_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_get_ext_d2i(
x: *const ::X509,
nid: c_int,
crit: *mut c_int,
idx: *mut c_int,
) -> *mut c_void;
pub fn X509_NAME_add_entry_by_NID(
x: *mut ::X509_NAME,
field: c_int,
ty: c_int,
bytes: *const c_uchar,
len: c_int,
loc: c_int,
set: c_int,
) -> c_int;
pub fn X509_get_signature_nid(x: *const X509) -> c_int;
pub fn X509_ALGOR_get0(
paobj: *mut *const ::ASN1_OBJECT,
pptype: *mut c_int,
ppval: *mut *const c_void,
alg: *const ::X509_ALGOR,
);
pub fn X509_NAME_get_entry(n: *const ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
pub fn X509_NAME_ENTRY_get_data(ne: *const ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
pub fn X509V3_EXT_nconf_nid(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
ext_nid: c_int,
value: *const c_char,
) -> *mut ::X509_EXTENSION;
pub fn X509V3_EXT_nconf(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
name: *const c_char,
value: *const c_char,
) -> *mut ::X509_EXTENSION;
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *const ::ASN1_STRING) -> c_int;
pub fn BN_is_negative(b: *const ::BIGNUM) -> c_int;
pub fn EVP_CIPHER_key_length(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_block_size(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_CIPHER_iv_length(cipher: *const EVP_CIPHER) -> c_int;
pub fn EVP_PBE_scrypt(
pass: *const c_char,
passlen: size_t,
salt: *const c_uchar,
saltlen: size_t,
N: u64,
r: u64,
p: u64,
maxmem: u64,
key: *mut c_uchar,
keylen: size_t,
) -> c_int;
pub fn DSA_get0_pqg(
d: *const ::DSA,
p: *mut *const ::BIGNUM,
q: *mut *const ::BIGNUM,
q: *mut *const ::BIGNUM,
);
pub fn DSA_get0_key(
d: *const ::DSA,
pub_key: *mut *const ::BIGNUM,
priv_key: *mut *const ::BIGNUM,
);
pub fn RSA_get0_key(
r: *const ::RSA,
n: *mut *const ::BIGNUM,
e: *mut *const ::BIGNUM,
d: *mut *const ::BIGNUM,
);
pub fn RSA_get0_factors(r: *const ::RSA, p: *mut *const ::BIGNUM, q: *mut *const ::BIGNUM);
pub fn RSA_get0_crt_params(
r: *const ::RSA,
dmp1: *mut *const ::BIGNUM,
dmq1: *mut *const ::BIGNUM,
iqmp: *mut *const ::BIGNUM,
);
pub fn RSA_set0_key(
r: *mut ::RSA,
n: *mut ::BIGNUM,
e: *mut ::BIGNUM,
d: *mut ::BIGNUM,
) -> c_int;
pub fn RSA_set0_factors(r: *mut ::RSA, p: *mut ::BIGNUM, q: *mut ::BIGNUM) -> c_int;
pub fn RSA_set0_crt_params(
r: *mut ::RSA,
dmp1: *mut ::BIGNUM,
dmq1: *mut ::BIGNUM,
iqmp: *mut ::BIGNUM,
) -> c_int;
pub fn ASN1_STRING_get0_data(x: *const ::ASN1_STRING) -> *const c_uchar;
pub fn OPENSSL_sk_num(stack: *const ::OPENSSL_STACK) -> c_int;
pub fn OPENSSL_sk_value(stack: *const ::OPENSSL_STACK, idx: c_int) -> *mut c_void;
pub fn SSL_CTX_get_options(ctx: *const ::SSL_CTX) -> c_ulong;
pub fn SSL_CTX_set_options(ctx: *mut ::SSL_CTX, op: c_ulong) -> c_ulong;
pub fn SSL_CTX_clear_options(ctx: *mut ::SSL_CTX, op: c_ulong) -> c_ulong;
pub fn X509_getm_notAfter(x: *const ::X509) -> *mut ::ASN1_TIME;
pub fn X509_getm_notBefore(x: *const ::X509) -> *mut ::ASN1_TIME;
pub fn X509_get0_signature(
psig: *mut *const ::ASN1_BIT_STRING,
palg: *mut *const ::X509_ALGOR,
x: *const ::X509,
);
pub fn DH_set0_pqg(
dh: *mut ::DH,
p: *mut ::BIGNUM,
q: *mut ::BIGNUM,
g: *mut ::BIGNUM,
) -> c_int;
pub fn BIO_set_init(a: *mut ::BIO, init: c_int);
pub fn BIO_set_data(a: *mut ::BIO, data: *mut c_void);
pub fn BIO_get_data(a: *mut ::BIO) -> *mut c_void;
pub fn BIO_meth_new(type_: c_int, name: *const c_char) -> *mut ::BIO_METHOD;
pub fn BIO_meth_free(biom: *mut ::BIO_METHOD);
pub fn BIO_meth_set_write(
biom: *mut ::BIO_METHOD,
write: unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int) -> c_int,
) -> c_int;
pub fn BIO_meth_set_read(
biom: *mut ::BIO_METHOD,
read: unsafe extern "C" fn(*mut ::BIO, *mut c_char, c_int) -> c_int,
) -> c_int;
pub fn BIO_meth_set_puts(
biom: *mut ::BIO_METHOD,
read: unsafe extern "C" fn(*mut ::BIO, *const c_char) -> c_int,
) -> c_int;
pub fn BIO_meth_set_ctrl(
biom: *mut ::BIO_METHOD,
read: unsafe extern "C" fn(*mut ::BIO, c_int, c_long, *mut c_void) -> c_long,
) -> c_int;
pub fn BIO_meth_set_create(
biom: *mut ::BIO_METHOD,
create: unsafe extern "C" fn(*mut ::BIO) -> c_int,
) -> c_int;
pub fn BIO_meth_set_destroy(
biom: *mut ::BIO_METHOD,
destroy: unsafe extern "C" fn(*mut ::BIO) -> c_int,
) -> c_int;
pub fn CRYPTO_get_ex_new_index(
class_index: c_int,
argl: c_long,
argp: *mut c_void,
new_func: Option<::CRYPTO_EX_new>,
dup_func: Option<::CRYPTO_EX_dup>,
free_func: Option<::CRYPTO_EX_free>,
) -> c_int;
pub fn X509_up_ref(x: *mut X509) -> c_int;
pub fn SSL_CTX_up_ref(x: *mut SSL_CTX) -> c_int;
pub fn SSL_session_reused(ssl: *mut SSL) -> c_int;
pub fn SSL_SESSION_get_master_key(
session: *const SSL_SESSION,
out: *mut c_uchar,
outlen: size_t,
) -> size_t;
pub fn SSL_SESSION_up_ref(ses: *mut SSL_SESSION) -> c_int;
pub fn X509_get0_extensions(req: *const ::X509) -> *const stack_st_X509_EXTENSION;
pub fn X509_STORE_CTX_get0_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
pub fn EVP_MD_CTX_new() -> *mut EVP_MD_CTX;
pub fn EVP_MD_CTX_free(ctx: *mut EVP_MD_CTX);
pub fn EVP_PKEY_bits(key: *const EVP_PKEY) -> c_int;
pub fn OpenSSL_version_num() -> c_ulong;
pub fn OpenSSL_version(key: c_int) -> *const c_char;
pub fn OPENSSL_init_ssl(opts: u64, settings: *const OPENSSL_INIT_SETTINGS) -> c_int;
pub fn OPENSSL_sk_new_null() -> *mut ::OPENSSL_STACK;
pub fn OPENSSL_sk_free(st: *mut ::OPENSSL_STACK);
pub fn OPENSSL_sk_pop_free(
st: *mut ::OPENSSL_STACK,
free: Option<unsafe extern "C" fn(*mut c_void)>,
);
pub fn OPENSSL_sk_push(st: *mut ::OPENSSL_STACK, data: *const c_void) -> c_int;
pub fn OPENSSL_sk_pop(st: *mut ::OPENSSL_STACK) -> *mut c_void;
pub fn PKCS12_create(
pass: *const c_char,
friendly_name: *const c_char,
pkey: *mut EVP_PKEY,
cert: *mut X509,
ca: *mut stack_st_X509,
nid_key: c_int,
nid_cert: c_int,
iter: c_int,
mac_iter: c_int,
keytype: c_int,
) -> *mut PKCS12;
pub fn X509_REQ_get_version(req: *const X509_REQ) -> c_long;
pub fn X509_REQ_get_subject_name(req: *const X509_REQ) -> *mut ::X509_NAME;
}

View File

@ -1,991 +0,0 @@
use libc::*;
#[allow(unused_imports)]
use *;
pub enum ASN1_INTEGER {}
pub enum ASN1_GENERALIZEDTIME {}
pub enum ASN1_STRING {}
pub enum ASN1_BIT_STRING {}
pub enum ASN1_TIME {}
pub enum ASN1_TYPE {}
pub enum ASN1_OBJECT {}
pub enum ASN1_OCTET_STRING {}
pub enum bio_st {} // FIXME remove
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum BIO {}
} else {
#[repr(C)]
pub struct BIO {
pub method: *mut BIO_METHOD,
pub callback: Option<
unsafe extern "C" fn(*mut BIO, c_int, *const c_char, c_int, c_long, c_long) -> c_long,
>,
pub cb_arg: *mut c_char,
pub init: c_int,
pub shutdown: c_int,
pub flags: c_int,
pub retry_reason: c_int,
pub num: c_int,
pub ptr: *mut c_void,
pub next_bio: *mut BIO,
pub prev_bio: *mut BIO,
pub references: c_int,
pub num_read: c_ulong,
pub num_write: c_ulong,
pub ex_data: CRYPTO_EX_DATA,
}
}
}
cfg_if! {
if #[cfg(ossl110)] {
pub enum BIGNUM {}
} else {
#[repr(C)]
pub struct BIGNUM {
pub d: *mut BN_ULONG,
pub top: c_int,
pub dmax: c_int,
pub neg: c_int,
pub flags: c_int,
}
}
}
pub enum BN_BLINDING {}
pub enum BN_MONT_CTX {}
pub enum BN_CTX {}
pub enum BN_GENCB {}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum EVP_CIPHER {}
} else {
#[repr(C)]
pub struct EVP_CIPHER {
pub nid: c_int,
pub block_size: c_int,
pub key_len: c_int,
pub iv_len: c_int,
pub flags: c_ulong,
pub init: Option<
unsafe extern "C" fn(*mut EVP_CIPHER_CTX, *const c_uchar, *const c_uchar, c_int) -> c_int,
>,
pub do_cipher: Option<
unsafe extern "C" fn(*mut EVP_CIPHER_CTX, *mut c_uchar, *const c_uchar, size_t) -> c_int,
>,
pub cleanup: Option<unsafe extern "C" fn(*mut EVP_CIPHER_CTX) -> c_int>,
pub ctx_size: c_int,
pub set_asn1_parameters:
Option<unsafe extern "C" fn(*mut EVP_CIPHER_CTX, *mut ASN1_TYPE) -> c_int>,
pub get_asn1_parameters:
Option<unsafe extern "C" fn(*mut EVP_CIPHER_CTX, *mut ASN1_TYPE) -> c_int>,
pub ctrl:
Option<unsafe extern "C" fn(*mut EVP_CIPHER_CTX, c_int, c_int, *mut c_void) -> c_int>,
pub app_data: *mut c_void,
}
}
}
pub enum EVP_CIPHER_CTX {}
pub enum EVP_MD {}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum EVP_MD_CTX {}
} else {
#[repr(C)]
pub struct EVP_MD_CTX {
digest: *mut EVP_MD,
engine: *mut ENGINE,
flags: c_ulong,
md_data: *mut c_void,
pctx: *mut EVP_PKEY_CTX,
update: *mut c_void,
}
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum EVP_PKEY {}
} else {
#[repr(C)]
pub struct EVP_PKEY {
pub type_: c_int,
pub save_type: c_int,
pub references: c_int,
pub ameth: *const EVP_PKEY_ASN1_METHOD,
pub engine: *mut ENGINE,
pub pkey: *mut c_void,
pub save_parameters: c_int,
pub attributes: *mut stack_st_X509_ATTRIBUTE,
}
}
}
pub enum EVP_PKEY_ASN1_METHOD {}
pub enum EVP_PKEY_CTX {}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum HMAC_CTX {}
} else {
#[repr(C)]
pub struct HMAC_CTX {
md: *mut EVP_MD,
md_ctx: EVP_MD_CTX,
i_ctx: EVP_MD_CTX,
o_ctx: EVP_MD_CTX,
key_length: c_uint,
key: [c_uchar; 128],
}
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum DH {}
} else {
#[repr(C)]
pub struct DH {
pub pad: c_int,
pub version: c_int,
pub p: *mut ::BIGNUM,
pub g: *mut ::BIGNUM,
pub length: c_long,
pub pub_key: *mut ::BIGNUM,
pub priv_key: *mut ::BIGNUM,
pub flags: c_int,
pub method_mont_p: *mut ::BN_MONT_CTX,
pub q: *mut ::BIGNUM,
pub j: *mut ::BIGNUM,
pub seed: *mut c_uchar,
pub seedlen: c_int,
pub counter: *mut ::BIGNUM,
pub references: c_int,
pub ex_data: ::CRYPTO_EX_DATA,
pub meth: *const ::DH_METHOD,
pub engine: *mut ::ENGINE,
}
}
}
pub enum DH_METHOD {}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum DSA {}
} else {
#[repr(C)]
pub struct DSA {
pub pad: c_int,
pub version: c_long,
pub write_params: c_int,
pub p: *mut BIGNUM,
pub q: *mut BIGNUM,
pub g: *mut BIGNUM,
pub pub_key: *mut BIGNUM,
pub priv_key: *mut BIGNUM,
pub kinv: *mut BIGNUM,
pub r: *mut BIGNUM,
pub flags: c_int,
pub method_mont_p: *mut BN_MONT_CTX,
pub references: c_int,
pub ex_data: CRYPTO_EX_DATA,
pub meth: *const DSA_METHOD,
pub engine: *mut ENGINE,
}
}
}
pub enum DSA_METHOD {}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum RSA {}
} else if #[cfg(libressl)] {
#[repr(C)]
pub struct RSA {
pub pad: c_int,
pub version: c_long,
pub meth: *const ::RSA_METHOD,
pub engine: *mut ::ENGINE,
pub n: *mut ::BIGNUM,
pub e: *mut ::BIGNUM,
pub d: *mut ::BIGNUM,
pub p: *mut ::BIGNUM,
pub q: *mut ::BIGNUM,
pub dmp1: *mut ::BIGNUM,
pub dmq1: *mut ::BIGNUM,
pub iqmp: *mut ::BIGNUM,
pub ex_data: ::CRYPTO_EX_DATA,
pub references: c_int,
pub flags: c_int,
pub _method_mod_n: *mut ::BN_MONT_CTX,
pub _method_mod_p: *mut ::BN_MONT_CTX,
pub _method_mod_q: *mut ::BN_MONT_CTX,
pub blinding: *mut ::BN_BLINDING,
pub mt_blinding: *mut ::BN_BLINDING,
}
} else {
#[repr(C)]
pub struct RSA {
pub pad: c_int,
pub version: c_long,
pub meth: *const ::RSA_METHOD,
pub engine: *mut ::ENGINE,
pub n: *mut ::BIGNUM,
pub e: *mut ::BIGNUM,
pub d: *mut ::BIGNUM,
pub p: *mut ::BIGNUM,
pub q: *mut ::BIGNUM,
pub dmp1: *mut ::BIGNUM,
pub dmq1: *mut ::BIGNUM,
pub iqmp: *mut ::BIGNUM,
pub ex_data: ::CRYPTO_EX_DATA,
pub references: c_int,
pub flags: c_int,
pub _method_mod_n: *mut ::BN_MONT_CTX,
pub _method_mod_p: *mut ::BN_MONT_CTX,
pub _method_mod_q: *mut ::BN_MONT_CTX,
pub bignum_data: *mut c_char,
pub blinding: *mut ::BN_BLINDING,
pub mt_blinding: *mut ::BN_BLINDING,
}
}
}
pub enum RSA_METHOD {}
pub enum EC_KEY {}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum X509 {}
} else if #[cfg(libressl)] {
#[repr(C)]
pub struct X509 {
pub cert_info: *mut X509_CINF,
pub sig_alg: *mut ::X509_ALGOR,
pub signature: *mut ::ASN1_BIT_STRING,
pub valid: c_int,
pub references: c_int,
pub name: *mut c_char,
pub ex_data: ::CRYPTO_EX_DATA,
pub ex_pathlen: c_long,
pub ex_pcpathlen: c_long,
pub ex_flags: c_ulong,
pub ex_kusage: c_ulong,
pub ex_xkusage: c_ulong,
pub ex_nscert: c_ulong,
skid: *mut c_void,
akid: *mut c_void,
policy_cache: *mut c_void,
crldp: *mut c_void,
altname: *mut c_void,
nc: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_SHA"))]
sha1_hash: [c_uchar; 20],
aux: *mut c_void,
}
} else {
#[repr(C)]
pub struct X509 {
pub cert_info: *mut X509_CINF,
pub sig_alg: *mut X509_ALGOR,
pub signature: *mut ASN1_BIT_STRING,
pub valid: c_int,
pub references: c_int,
pub name: *mut c_char,
pub ex_data: CRYPTO_EX_DATA,
pub ex_pathlen: c_long,
pub ex_pcpathlen: c_long,
pub ex_flags: c_ulong,
pub ex_kusage: c_ulong,
pub ex_xkusage: c_ulong,
pub ex_nscert: c_ulong,
skid: *mut c_void,
akid: *mut c_void,
policy_cache: *mut c_void,
crldp: *mut c_void,
altname: *mut c_void,
nc: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))]
rfc3779_addr: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))]
rfc3779_asid: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_SHA"))]
sha1_hash: [c_uchar; 20],
aux: *mut c_void,
}
}
}
cfg_if! {
if #[cfg(ossl110)] {
pub enum X509_ALGOR {}
} else {
#[repr(C)]
pub struct X509_ALGOR {
pub algorithm: *mut ::ASN1_OBJECT,
parameter: *mut c_void,
}
}
}
pub enum X509_CRL {}
pub enum X509_NAME {}
pub enum X509_STORE {}
pub enum X509_STORE_CTX {}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum X509_VERIFY_PARAM {}
} else if #[cfg(libressl251)] {
#[repr(C)]
pub struct X509_VERIFY_PARAM {
pub name: *mut c_char,
pub check_time: time_t,
pub inh_flags: c_ulong,
pub flags: c_ulong,
pub purpose: c_int,
pub trust: c_int,
pub depth: c_int,
pub policies: *mut stack_st_ASN1_OBJECT,
id: *mut c_void,
}
} else if #[cfg(libressl)] {
#[repr(C)]
pub struct X509_VERIFY_PARAM {
pub name: *mut c_char,
pub check_time: time_t,
pub inh_flags: c_ulong,
pub flags: c_ulong,
pub purpose: c_int,
pub trust: c_int,
pub depth: c_int,
pub policies: *mut stack_st_ASN1_OBJECT,
//pub id: *mut X509_VERIFY_PARAM_ID,
}
} else if #[cfg(ossl102)] {
#[repr(C)]
pub struct X509_VERIFY_PARAM {
pub name: *mut c_char,
pub check_time: time_t,
pub inh_flags: c_ulong,
pub flags: c_ulong,
pub purpose: c_int,
pub trust: c_int,
pub depth: c_int,
pub policies: *mut stack_st_ASN1_OBJECT,
pub id: *mut X509_VERIFY_PARAM_ID,
}
}
}
#[repr(C)]
pub struct X509V3_CTX {
flags: c_int,
issuer_cert: *mut c_void,
subject_cert: *mut c_void,
subject_req: *mut c_void,
crl: *mut c_void,
db_meth: *mut c_void,
db: *mut c_void,
// I like the last comment line, it is copied from OpenSSL sources:
// Maybe more here
}
pub enum CONF {}
#[cfg(ossl110)]
pub enum OPENSSL_INIT_SETTINGS {}
pub enum ENGINE {}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum SSL {}
} else if #[cfg(libressl251)] {
#[repr(C)]
pub struct SSL {
version: c_int,
method: *const ::SSL_METHOD,
rbio: *mut ::BIO,
wbio: *mut ::BIO,
bbio: *mut ::BIO,
pub server: c_int,
s3: *mut c_void,
d1: *mut c_void,
param: *mut c_void,
cipher_list: *mut stack_st_SSL_CIPHER,
cert: *mut c_void,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
session: *mut ::SSL_SESSION,
verify_mode: c_int,
error: c_int,
error_code: c_int,
ctx: *mut ::SSL_CTX,
verify_result: c_long,
references: c_int,
client_version: c_int,
max_send_fragment: c_uint,
tlsext_hostname: *mut c_char,
tlsext_status_type: c_int,
initial_ctx: *mut ::SSL_CTX,
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
read_hash: *mut EVP_MD_CTX,
internal: *mut c_void,
}
} else if #[cfg(libressl)] {
#[repr(C)]
pub struct SSL {
version: c_int,
type_: c_int,
method: *const ::SSL_METHOD,
rbio: *mut c_void,
wbio: *mut c_void,
bbio: *mut c_void,
rwstate: c_int,
in_handshake: c_int,
handshake_func: Option<unsafe extern "C" fn(*mut SSL) -> c_int>,
pub server: c_int,
new_session: c_int,
quiet_shutdown: c_int,
shutdown: c_int,
state: c_int,
rstate: c_int,
init_buf: *mut c_void,
init_msg: *mut c_void,
init_num: c_int,
init_off: c_int,
packet: *mut c_uchar,
packet_length: c_uint,
s3: *mut c_void,
d1: *mut c_void,
read_ahead: c_int,
msg_callback: Option<
unsafe extern "C" fn(c_int,
c_int,
c_int,
*const c_void,
size_t,
*mut SSL,
*mut c_void),
>,
msg_callback_arg: *mut c_void,
hit: c_int,
param: *mut c_void,
cipher_list: *mut stack_st_SSL_CIPHER,
cipher_list_by_id: *mut stack_st_SSL_CIPHER,
mac_flags: c_int,
aead_read_ctx: *mut c_void,
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
read_hash: *mut ::EVP_MD_CTX,
aead_write_ctx: *mut c_void,
enc_write_ctx: *mut ::EVP_CIPHER_CTX,
write_hash: *mut ::EVP_MD_CTX,
cert: *mut c_void,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
session: *mut ::SSL_SESSION,
generate_session_id: ::GEN_SESSION_CB,
verify_mode: c_int,
verify_callback: Option<unsafe extern "C" fn(c_int, *mut ::X509_STORE_CTX) -> c_int>,
info_callback: Option<unsafe extern "C" fn(*mut SSL, c_int, c_int)>,
error: c_int,
error_code: c_int,
ctx: *mut ::SSL_CTX,
debug: c_int,
verify_result: c_long,
ex_data: ::CRYPTO_EX_DATA,
client_CA: *mut stack_st_X509_NAME,
references: c_int,
options: c_ulong,
mode: c_ulong,
max_cert_list: c_long,
first_packet: c_int,
client_version: c_int,
max_send_fragment: c_uint,
tlsext_debug_cb:
Option<unsafe extern "C" fn(*mut SSL, c_int, c_int, *mut c_uchar, c_int, *mut c_void)>,
tlsext_debug_arg: *mut c_void,
tlsext_hostname: *mut c_char,
servername_done: c_int,
tlsext_status_type: c_int,
tlsext_status_expected: c_int,
tlsext_ocsp_ids: *mut c_void,
tlsext_ocsp_exts: *mut c_void,
tlsext_ocsp_resp: *mut c_uchar,
tlsext_ocsp_resplen: c_int,
tlsext_ticket_expected: c_int,
tlsext_ecpointformatlist_length: size_t,
tlsext_ecpointformatlist: *mut c_uchar,
tlsext_ellipticcurvelist_length: size_t,
tlsext_ellipticcurvelist: *mut c_uchar,
tlsext_session_ticket: *mut c_void,
tlsext_session_ticket_ext_cb: ::tls_session_ticket_ext_cb_fn,
tls_session_ticket_ext_cb_arg: *mut c_void,
tls_session_secret_cb: ::tls_session_secret_cb_fn,
tls_session_secret_cb_arg: *mut c_void,
initial_ctx: *mut ::SSL_CTX,
next_proto_negotiated: *mut c_uchar,
next_proto_negotiated_len: c_uchar,
srtp_profiles: *mut c_void,
srtp_profile: *mut c_void,
tlsext_heartbeat: c_uint,
tlsext_hb_pending: c_uint,
tlsext_hb_seq: c_uint,
alpn_client_proto_list: *mut c_uchar,
alpn_client_proto_list_len: c_uint,
renegotiate: c_int,
}
} else {
#[repr(C)]
pub struct SSL {
version: c_int,
type_: c_int,
method: *const ::SSL_METHOD,
rbio: *mut c_void,
wbio: *mut c_void,
bbio: *mut c_void,
rwstate: c_int,
in_handshake: c_int,
handshake_func: Option<unsafe extern "C" fn(*mut SSL) -> c_int>,
pub server: c_int,
new_session: c_int,
quiet_session: c_int,
shutdown: c_int,
state: c_int,
rstate: c_int,
init_buf: *mut c_void,
init_msg: *mut c_void,
init_num: c_int,
init_off: c_int,
packet: *mut c_uchar,
packet_length: c_uint,
s2: *mut c_void,
s3: *mut c_void,
d1: *mut c_void,
read_ahead: c_int,
msg_callback: Option<
unsafe extern "C" fn(c_int, c_int, c_int, *const c_void, size_t, *mut SSL, *mut c_void),
>,
msg_callback_arg: *mut c_void,
hit: c_int,
param: *mut c_void,
cipher_list: *mut stack_st_SSL_CIPHER,
cipher_list_by_id: *mut stack_st_SSL_CIPHER,
mac_flags: c_int,
enc_read_ctx: *mut ::EVP_CIPHER_CTX,
read_hash: *mut ::EVP_MD_CTX,
expand: *mut c_void,
enc_write_ctx: *mut ::EVP_CIPHER_CTX,
write_hash: *mut ::EVP_MD_CTX,
compress: *mut c_void,
cert: *mut c_void,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
session: *mut ::SSL_SESSION,
generate_session_id: ::GEN_SESSION_CB,
verify_mode: c_int,
verify_callback: Option<unsafe extern "C" fn(c_int, *mut ::X509_STORE_CTX) -> c_int>,
info_callback: Option<unsafe extern "C" fn(*mut SSL, c_int, c_int)>,
error: c_int,
error_code: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_KRB5"))]
kssl_ctx: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_client_callback: Option<
unsafe extern "C" fn(*mut SSL, *const c_char, *mut c_char, c_uint, *mut c_uchar, c_uint)
-> c_uint,
>,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_server_callback:
Option<unsafe extern "C" fn(*mut SSL, *const c_char, *mut c_uchar, c_uint) -> c_uint>,
ctx: *mut ::SSL_CTX,
debug: c_int,
verify_result: c_long,
ex_data: ::CRYPTO_EX_DATA,
client_CA: *mut stack_st_X509_NAME,
references: c_int,
options: c_ulong,
mode: c_ulong,
max_cert_list: c_long,
first_packet: c_int,
client_version: c_int,
max_send_fragment: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_debug_cb:
Option<unsafe extern "C" fn(*mut SSL, c_int, c_int, *mut c_uchar, c_int, *mut c_void)>,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_debug_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_hostname: *mut c_char,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
servername_done: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_status_type: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_status_expected: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ocsp_ids: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ocsp_exts: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ocsp_resp: *mut c_uchar,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ocsp_resplen: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ticket_expected: c_int,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_EC")
))]
tlsext_ecpointformatlist_length: size_t,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_EC")
))]
tlsext_ecpointformatlist: *mut c_uchar,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_EC")
))]
tlsext_ellipticcurvelist_length: size_t,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_EC")
))]
tlsext_ellipticcurvelist: *mut c_uchar,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_opaque_prf_input: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_opaque_prf_input_len: size_t,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_session_ticket: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_session_ticket_ext_cb: ::tls_session_ticket_ext_cb_fn,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tls_session_ticket_ext_cb_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tls_session_secret_cb: ::tls_session_secret_cb_fn,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tls_session_secret_cb_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
initial_ctx: *mut ::SSL_CTX,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
))]
next_proto_negotiated: *mut c_uchar,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
))]
next_proto_negotiated_len: c_uchar,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
srtp_profiles: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
srtp_profile: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_heartbeat: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_hb_pending: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_hb_seq: c_uint,
renegotiate: c_int,
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
srp_ctx: ::SRP_CTX,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_client_proto_list: *mut c_uchar,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_client_proto_list_len: c_uint,
}
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum SSL_CTX {}
} else if #[cfg(libressl251)] {
#[repr(C)]
pub struct SSL_CTX {
method: *const ::SSL_METHOD,
cipher_list: *mut stack_st_SSL_CIPHER,
cert_store: *mut c_void,
session_timeout: c_long,
pub references: c_int,
extra_certs: *mut stack_st_X509,
verify_mode: c_int,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; ::SSL_MAX_SID_CTX_LENGTH as usize],
param: *mut ::X509_VERIFY_PARAM,
default_passwd_callback: *mut c_void,
default_passwd_callback_userdata: *mut c_void,
internal: *mut c_void,
}
} else if #[cfg(libressl)] {
#[repr(C)]
pub struct SSL_CTX {
method: *mut c_void,
cipher_list: *mut c_void,
cipher_list_by_id: *mut c_void,
cert_store: *mut c_void,
sessions: *mut c_void,
session_cache_size: c_ulong,
session_cache_head: *mut c_void,
session_cache_tail: *mut c_void,
session_cache_mode: c_int,
session_timeout: c_long,
new_session_cb: *mut c_void,
remove_session_cb: *mut c_void,
get_session_cb: *mut c_void,
stats: [c_int; 11],
pub references: c_int,
app_verify_callback: *mut c_void,
app_verify_arg: *mut c_void,
default_passwd_callback: *mut c_void,
default_passwd_callback_userdata: *mut c_void,
client_cert_cb: *mut c_void,
app_gen_cookie_cb: *mut c_void,
app_verify_cookie_cb: *mut c_void,
ex_dat: ::CRYPTO_EX_DATA,
rsa_md5: *mut c_void,
md5: *mut c_void,
sha1: *mut c_void,
extra_certs: *mut c_void,
comp_methods: *mut c_void,
info_callback: *mut c_void,
client_CA: *mut c_void,
options: c_ulong,
mode: c_ulong,
max_cert_list: c_long,
cert: *mut c_void,
read_ahead: c_int,
msg_callback: *mut c_void,
msg_callback_arg: *mut c_void,
verify_mode: c_int,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; 32],
default_verify_callback: *mut c_void,
generate_session_id: *mut c_void,
param: *mut c_void,
quiet_shutdown: c_int,
max_send_fragment: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))]
client_cert_engine: *mut c_void,
tlsext_servername_callback: *mut c_void,
tlsect_servername_arg: *mut c_void,
tlsext_tick_key_name: [c_uchar; 16],
tlsext_tick_hmac_key: [c_uchar; 16],
tlsext_tick_aes_key: [c_uchar; 16],
tlsext_ticket_key_cb: *mut c_void,
tlsext_status_cb: *mut c_void,
tlsext_status_arg: *mut c_void,
tlsext_opaque_prf_input_callback: *mut c_void,
tlsext_opaque_prf_input_callback_arg: *mut c_void,
next_protos_advertised_cb: *mut c_void,
next_protos_advertised_cb_arg: *mut c_void,
next_proto_select_cb: *mut c_void,
next_proto_select_cb_arg: *mut c_void,
srtp_profiles: *mut c_void,
}
} else {
#[repr(C)]
pub struct SSL_CTX {
method: *mut c_void,
cipher_list: *mut c_void,
cipher_list_by_id: *mut c_void,
cert_store: *mut c_void,
sessions: *mut c_void,
session_cache_size: c_ulong,
session_cache_head: *mut c_void,
session_cache_tail: *mut c_void,
session_cache_mode: c_int,
session_timeout: c_long,
new_session_cb: *mut c_void,
remove_session_cb: *mut c_void,
get_session_cb: *mut c_void,
stats: [c_int; 11],
pub references: c_int,
app_verify_callback: *mut c_void,
app_verify_arg: *mut c_void,
default_passwd_callback: *mut c_void,
default_passwd_callback_userdata: *mut c_void,
client_cert_cb: *mut c_void,
app_gen_cookie_cb: *mut c_void,
app_verify_cookie_cb: *mut c_void,
ex_dat: ::CRYPTO_EX_DATA,
rsa_md5: *mut c_void,
md5: *mut c_void,
sha1: *mut c_void,
extra_certs: *mut c_void,
comp_methods: *mut c_void,
info_callback: *mut c_void,
client_CA: *mut c_void,
options: c_ulong,
mode: c_ulong,
max_cert_list: c_long,
cert: *mut c_void,
read_ahead: c_int,
msg_callback: *mut c_void,
msg_callback_arg: *mut c_void,
verify_mode: c_int,
sid_ctx_length: c_uint,
sid_ctx: [c_uchar; 32],
default_verify_callback: *mut c_void,
generate_session_id: *mut c_void,
param: *mut c_void,
quiet_shutdown: c_int,
max_send_fragment: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))]
client_cert_engine: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_servername_callback: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsect_servername_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_tick_key_name: [c_uchar; 16],
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_tick_hmac_key: [c_uchar; 16],
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_tick_aes_key: [c_uchar; 16],
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_ticket_key_cb: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_status_cb: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_status_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_opaque_prf_input_callback: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
tlsext_opaque_prf_input_callback_arg: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_identity_hint: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_client_callback: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
psk_server_callback: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
freelist_max_len: c_uint,
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
wbuf_freelist: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))]
rbuf_freelist: *mut c_void,
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
srp_ctx: SRP_CTX,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
))]
next_protos_advertised_cb: *mut c_void,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
))]
next_protos_advertised_cb_arg: *mut c_void,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
))]
next_proto_select_cb: *mut c_void,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_NEXTPROTONEG")
))]
next_proto_select_cb_arg: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl101))]
srtp_profiles: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_select_cb: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_select_cb_arg: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_client_proto_list: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_client_proto_list_len: c_uint,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_EC"),
ossl102
))]
tlsext_ecpointformatlist_length: size_t,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_EC"),
ossl102
))]
tlsext_ecpointformatlist: *mut c_uchar,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_EC"),
ossl102
))]
tlsext_ellipticcurvelist_length: size_t,
#[cfg(all(
not(osslconf = "OPENSSL_NO_TLSEXT"),
not(osslconf = "OPENSSL_NO_EC"),
ossl102
))]
tlsext_ellipticcurvelist: *mut c_uchar,
}
#[repr(C)]
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
pub struct SRP_CTX {
SRP_cb_arg: *mut c_void,
TLS_ext_srp_username_callback: *mut c_void,
SRP_verify_param_callback: *mut c_void,
SRP_give_srp_client_pwd_callback: *mut c_void,
login: *mut c_void,
N: *mut c_void,
g: *mut c_void,
s: *mut c_void,
B: *mut c_void,
A: *mut c_void,
a: *mut c_void,
b: *mut c_void,
v: *mut c_void,
info: *mut c_void,
stringth: c_int,
srp_Mask: c_ulong,
}
}
}
pub enum COMP_METHOD {}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
pub enum CRYPTO_EX_DATA {}
} else if #[cfg(libressl)] {
#[repr(C)]
pub struct CRYPTO_EX_DATA {
pub sk: *mut ::stack_st_void,
}
} else {
#[repr(C)]
pub struct CRYPTO_EX_DATA {
pub sk: *mut stack_st_void,
pub dummy: c_int,
}
}
}
pub enum OCSP_RESPONSE {}

View File

@ -1,161 +0,0 @@
use libc::*;
use *;
pub type pem_password_cb = Option<
unsafe extern "C" fn(
buf: *mut c_char,
size: c_int,
rwflag: c_int,
user_data: *mut c_void,
) -> c_int,
>;
extern "C" {
pub fn PEM_read_bio_X509(
bio: *mut BIO,
out: *mut *mut X509,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut X509;
pub fn PEM_write_bio_X509(bio: *mut BIO, x509: *mut X509) -> c_int;
pub fn PEM_read_bio_X509_REQ(
bio: *mut BIO,
out: *mut *mut X509_REQ,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut X509_REQ;
pub fn PEM_write_bio_X509_REQ(bio: *mut BIO, x509: *mut X509_REQ) -> c_int;
pub fn PEM_read_bio_RSAPrivateKey(
bio: *mut BIO,
rsa: *mut *mut RSA,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut RSA;
pub fn PEM_write_bio_RSAPrivateKey(
bp: *mut BIO,
rsa: *mut RSA,
cipher: *const EVP_CIPHER,
kstr: *mut c_uchar,
klen: c_int,
callback: pem_password_cb,
user_data: *mut c_void,
) -> c_int;
pub fn PEM_read_bio_RSAPublicKey(
bio: *mut BIO,
rsa: *mut *mut RSA,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut RSA;
pub fn PEM_write_bio_RSAPublicKey(bp: *mut BIO, rsa: *const RSA) -> c_int;
pub fn PEM_read_bio_RSA_PUBKEY(
bio: *mut BIO,
rsa: *mut *mut RSA,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut RSA;
pub fn PEM_write_bio_RSA_PUBKEY(bp: *mut BIO, rsa: *mut RSA) -> c_int;
pub fn PEM_read_bio_DSAPrivateKey(
bp: *mut BIO,
dsa: *mut *mut DSA,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut DSA;
pub fn PEM_write_bio_DSAPrivateKey(
bp: *mut BIO,
dsa: *mut DSA,
cipher: *const EVP_CIPHER,
kstr: *mut c_uchar,
klen: c_int,
callback: pem_password_cb,
user_data: *mut c_void,
) -> c_int;
pub fn PEM_read_bio_DSA_PUBKEY(
bp: *mut BIO,
dsa: *mut *mut DSA,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut DSA;
pub fn PEM_write_bio_DSA_PUBKEY(bp: *mut BIO, dsa: *mut DSA) -> c_int;
pub fn PEM_read_bio_ECPrivateKey(
bio: *mut BIO,
key: *mut *mut EC_KEY,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut EC_KEY;
pub fn PEM_write_bio_ECPrivateKey(
bio: *mut BIO,
key: *mut EC_KEY,
cipher: *const EVP_CIPHER,
kstr: *mut c_uchar,
klen: c_int,
callback: pem_password_cb,
user_data: *mut c_void,
) -> c_int;
pub fn PEM_read_bio_DHparams(
bio: *mut BIO,
out: *mut *mut DH,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut DH;
pub fn PEM_write_bio_DHparams(bio: *mut BIO, x: *const DH) -> c_int;
pub fn PEM_read_bio_PrivateKey(
bio: *mut BIO,
out: *mut *mut EVP_PKEY,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut EVP_PKEY;
pub fn PEM_write_bio_PrivateKey(
bio: *mut BIO,
pkey: *mut EVP_PKEY,
cipher: *const EVP_CIPHER,
kstr: *mut c_uchar,
klen: c_int,
callback: pem_password_cb,
user_data: *mut c_void,
) -> c_int;
pub fn PEM_read_bio_PUBKEY(
bio: *mut BIO,
out: *mut *mut EVP_PKEY,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut EVP_PKEY;
pub fn PEM_write_bio_PUBKEY(bp: *mut BIO, x: *mut EVP_PKEY) -> c_int;
pub fn PEM_write_bio_PKCS8PrivateKey(
bio: *mut BIO,
pkey: *mut EVP_PKEY,
cipher: *const EVP_CIPHER,
kstr: *mut c_char,
klen: c_int,
callback: pem_password_cb,
user_data: *mut c_void,
) -> c_int;
pub fn d2i_PKCS8PrivateKey_bio(
bp: *mut BIO,
x: *mut *mut EVP_PKEY,
cb: pem_password_cb,
u: *mut c_void,
) -> *mut EVP_PKEY;
pub fn PEM_read_bio_PKCS7(
bio: *mut BIO,
out: *mut *mut PKCS7,
cb: pem_password_cb,
u: *mut c_void,
) -> *mut PKCS7;
pub fn PEM_write_bio_PKCS7(bp: *mut BIO, x: *mut PKCS7) -> c_int;
#[cfg(ossl101)]
pub fn PEM_read_bio_CMS(
bio: *mut BIO,
out: *mut *mut CMS_ContentInfo,
callback: pem_password_cb,
user_data: *mut c_void,
) -> *mut CMS_ContentInfo;
#[cfg(ossl101)]
pub fn PEM_write_bio_CMS(bio: *mut BIO, cms: *const CMS_ContentInfo) -> c_int;
}
pub const PEM_R_NO_START_LINE: c_int = 108;

View File

@ -1,56 +0,0 @@
use libc::*;
use *;
pub enum PKCS12 {}
extern "C" {
pub fn PKCS12_free(p12: *mut PKCS12);
pub fn i2d_PKCS12(a: *mut PKCS12, buf: *mut *mut u8) -> c_int;
pub fn d2i_PKCS12(a: *mut *mut PKCS12, pp: *mut *const u8, length: c_long) -> *mut PKCS12;
pub fn PKCS12_parse(
p12: *mut PKCS12,
pass: *const c_char,
pkey: *mut *mut EVP_PKEY,
cert: *mut *mut X509,
ca: *mut *mut stack_st_X509,
) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
extern "C" {
pub fn PKCS12_create(
pass: *const c_char,
friendly_name: *const c_char,
pkey: *mut EVP_PKEY,
cert: *mut X509,
ca: *mut stack_st_X509,
nid_key: c_int,
nid_cert: c_int,
iter: c_int,
mac_iter: c_int,
keytype: c_int,
) -> *mut PKCS12;
}
} else {
extern "C" {
pub fn PKCS12_create(
pass: *mut c_char,
friendly_name: *mut c_char,
pkey: *mut EVP_PKEY,
cert: *mut X509,
ca: *mut stack_st_X509,
nid_key: c_int,
nid_cert: c_int,
iter: c_int,
mac_iter: c_int,
keytype: c_int,
) -> *mut PKCS12;
}
}
}
extern "C" {
pub fn i2d_PKCS12_bio(b: *mut BIO, a: *mut PKCS12) -> c_int;
}

View File

@ -1,74 +0,0 @@
use libc::*;
use *;
pub enum PKCS7_SIGNED {}
pub enum PKCS7_ENVELOPE {}
pub enum PKCS7_SIGN_ENVELOPE {}
pub enum PKCS7_DIGEST {}
pub enum PKCS7_ENCRYPT {}
pub enum PKCS7 {}
pub const PKCS7_TEXT: c_int = 0x1;
pub const PKCS7_NOCERTS: c_int = 0x2;
pub const PKCS7_NOSIGS: c_int = 0x4;
pub const PKCS7_NOCHAIN: c_int = 0x8;
pub const PKCS7_NOINTERN: c_int = 0x10;
pub const PKCS7_NOVERIFY: c_int = 0x20;
pub const PKCS7_DETACHED: c_int = 0x40;
pub const PKCS7_BINARY: c_int = 0x80;
pub const PKCS7_NOATTR: c_int = 0x100;
pub const PKCS7_NOSMIMECAP: c_int = 0x200;
pub const PKCS7_NOOLDMIMETYPE: c_int = 0x400;
pub const PKCS7_CRLFEOL: c_int = 0x800;
pub const PKCS7_STREAM: c_int = 0x1000;
pub const PKCS7_NOCRL: c_int = 0x2000;
pub const PKCS7_PARTIAL: c_int = 0x4000;
pub const PKCS7_REUSE_DIGEST: c_int = 0x8000;
#[cfg(not(any(ossl101, ossl102, libressl)))]
pub const PKCS7_NO_DUAL_CONTENT: c_int = 0x10000;
extern "C" {
pub fn PKCS7_encrypt(
certs: *mut stack_st_X509,
b: *mut BIO,
cipher: *const EVP_CIPHER,
flags: c_int,
) -> *mut PKCS7;
pub fn PKCS7_verify(
pkcs7: *mut PKCS7,
certs: *mut stack_st_X509,
store: *mut X509_STORE,
indata: *mut BIO,
out: *mut BIO,
flags: c_int,
) -> c_int;
pub fn PKCS7_sign(
signcert: *mut X509,
pkey: *mut EVP_PKEY,
certs: *mut stack_st_X509,
data: *mut BIO,
flags: c_int,
) -> *mut PKCS7;
pub fn PKCS7_decrypt(
pkcs7: *mut PKCS7,
pkey: *mut EVP_PKEY,
cert: *mut X509,
data: *mut BIO,
flags: c_int,
) -> c_int;
pub fn PKCS7_free(pkcs7: *mut PKCS7);
pub fn SMIME_write_PKCS7(
out: *mut BIO,
pkcs7: *mut PKCS7,
data: *mut BIO,
flags: c_int,
) -> c_int;
pub fn SMIME_read_PKCS7(bio: *mut BIO, bcont: *mut *mut BIO) -> *mut PKCS7;
}

View File

@ -1,10 +0,0 @@
use libc::*;
extern "C" {
pub fn RAND_bytes(buf: *mut u8, num: c_int) -> c_int;
#[cfg(ossl111)]
pub fn RAND_keep_random_devices_open(keep: c_int);
pub fn RAND_status() -> c_int;
}

View File

@ -1,179 +0,0 @@
use libc::*;
use std::ptr;
use *;
pub const RSA_F4: c_long = 0x10001;
pub unsafe fn EVP_PKEY_CTX_set_rsa_padding(ctx: *mut EVP_PKEY_CTX, pad: c_int) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
EVP_PKEY_RSA,
-1,
EVP_PKEY_CTRL_RSA_PADDING,
pad,
ptr::null_mut(),
)
}
pub unsafe fn EVP_PKEY_CTX_get_rsa_padding(ctx: *mut EVP_PKEY_CTX, ppad: *mut c_int) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
EVP_PKEY_RSA,
-1,
EVP_PKEY_CTRL_GET_RSA_PADDING,
0,
ppad as *mut c_void,
)
}
pub unsafe fn EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx: *mut EVP_PKEY_CTX, len: c_int) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
EVP_PKEY_RSA,
EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY,
EVP_PKEY_CTRL_RSA_PSS_SALTLEN,
len,
ptr::null_mut(),
)
}
pub unsafe fn EVP_PKEY_CTX_set_rsa_mgf1_md(ctx: *mut EVP_PKEY_CTX, md: *mut EVP_MD) -> c_int {
EVP_PKEY_CTX_ctrl(
ctx,
EVP_PKEY_RSA,
EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
EVP_PKEY_CTRL_RSA_MGF1_MD,
0,
md as *mut c_void,
)
}
pub const EVP_PKEY_CTRL_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 1;
pub const EVP_PKEY_CTRL_RSA_PSS_SALTLEN: c_int = EVP_PKEY_ALG_CTRL + 2;
pub const EVP_PKEY_CTRL_RSA_MGF1_MD: c_int = EVP_PKEY_ALG_CTRL + 5;
pub const EVP_PKEY_CTRL_GET_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 6;
pub const RSA_PKCS1_PADDING: c_int = 1;
pub const RSA_SSLV23_PADDING: c_int = 2;
pub const RSA_NO_PADDING: c_int = 3;
pub const RSA_PKCS1_OAEP_PADDING: c_int = 4;
pub const RSA_X931_PADDING: c_int = 5;
pub const RSA_PKCS1_PSS_PADDING: c_int = 6;
extern "C" {
pub fn RSA_new() -> *mut RSA;
pub fn RSA_size(k: *const RSA) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn RSA_set0_key(
r: *mut ::RSA,
n: *mut ::BIGNUM,
e: *mut ::BIGNUM,
d: *mut ::BIGNUM,
) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn RSA_set0_factors(r: *mut ::RSA, p: *mut ::BIGNUM, q: *mut ::BIGNUM) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn RSA_set0_crt_params(
r: *mut ::RSA,
dmp1: *mut ::BIGNUM,
dmq1: *mut ::BIGNUM,
iqmp: *mut ::BIGNUM,
) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn RSA_get0_key(
r: *const ::RSA,
n: *mut *const ::BIGNUM,
e: *mut *const ::BIGNUM,
d: *mut *const ::BIGNUM,
);
#[cfg(any(ossl110, libressl273))]
pub fn RSA_get0_factors(r: *const ::RSA, p: *mut *const ::BIGNUM, q: *mut *const ::BIGNUM);
#[cfg(any(ossl110, libressl273))]
pub fn RSA_get0_crt_params(
r: *const ::RSA,
dmp1: *mut *const ::BIGNUM,
dmq1: *mut *const ::BIGNUM,
iqmp: *mut *const ::BIGNUM,
);
#[cfg(not(ossl110))]
pub fn RSA_generate_key(
modsz: c_int,
e: c_ulong,
cb: Option<extern "C" fn(c_int, c_int, *mut c_void)>,
cbarg: *mut c_void,
) -> *mut RSA;
pub fn RSA_generate_key_ex(
rsa: *mut RSA,
bits: c_int,
e: *mut BIGNUM,
cb: *mut BN_GENCB,
) -> c_int;
pub fn RSA_public_encrypt(
flen: c_int,
from: *const u8,
to: *mut u8,
k: *mut RSA,
pad: c_int,
) -> c_int;
pub fn RSA_private_encrypt(
flen: c_int,
from: *const u8,
to: *mut u8,
k: *mut RSA,
pad: c_int,
) -> c_int;
pub fn RSA_public_decrypt(
flen: c_int,
from: *const u8,
to: *mut u8,
k: *mut RSA,
pad: c_int,
) -> c_int;
pub fn RSA_private_decrypt(
flen: c_int,
from: *const u8,
to: *mut u8,
k: *mut RSA,
pad: c_int,
) -> c_int;
pub fn RSA_check_key(r: *const ::RSA) -> c_int;
pub fn RSA_free(rsa: *mut RSA);
pub fn RSA_up_ref(rsa: *mut RSA) -> c_int;
pub fn i2d_RSAPublicKey(k: *const RSA, buf: *mut *mut u8) -> c_int;
pub fn d2i_RSAPublicKey(k: *mut *mut RSA, buf: *mut *const u8, len: c_long) -> *mut RSA;
pub fn i2d_RSAPrivateKey(k: *const RSA, buf: *mut *mut u8) -> c_int;
pub fn d2i_RSAPrivateKey(k: *mut *mut RSA, buf: *mut *const u8, len: c_long) -> *mut RSA;
pub fn RSA_sign(
t: c_int,
m: *const u8,
mlen: c_uint,
sig: *mut u8,
siglen: *mut c_uint,
k: *mut RSA,
) -> c_int;
pub fn RSA_verify(
t: c_int,
m: *const u8,
mlen: c_uint,
sig: *const u8,
siglen: c_uint,
k: *mut RSA,
) -> c_int;
pub fn RSA_padding_check_PKCS1_type_2(
to: *mut c_uchar,
tlen: c_int,
f: *const c_uchar,
fl: c_int,
rsa_len: c_int,
) -> c_int;
}

View File

@ -1 +0,0 @@
stack!(stack_st_OPENSSL_STRING);

View File

@ -1,70 +0,0 @@
use libc::*;
pub type SHA_LONG = c_uint;
pub const SHA_LBLOCK: c_int = 16;
#[repr(C)]
pub struct SHA_CTX {
pub h0: SHA_LONG,
pub h1: SHA_LONG,
pub h2: SHA_LONG,
pub h3: SHA_LONG,
pub h4: SHA_LONG,
pub Nl: SHA_LONG,
pub Nh: SHA_LONG,
pub data: [SHA_LONG; SHA_LBLOCK as usize],
pub num: c_uint,
}
extern "C" {
pub fn SHA1_Init(c: *mut SHA_CTX) -> c_int;
pub fn SHA1_Update(c: *mut SHA_CTX, data: *const c_void, len: size_t) -> c_int;
pub fn SHA1_Final(md: *mut c_uchar, c: *mut SHA_CTX) -> c_int;
pub fn SHA1(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar;
}
#[repr(C)]
pub struct SHA256_CTX {
pub h: [SHA_LONG; 8],
pub Nl: SHA_LONG,
pub Nh: SHA_LONG,
pub data: [SHA_LONG; SHA_LBLOCK as usize],
pub num: c_uint,
pub md_len: c_uint,
}
extern "C" {
pub fn SHA224_Init(c: *mut SHA256_CTX) -> c_int;
pub fn SHA224_Update(c: *mut SHA256_CTX, data: *const c_void, len: size_t) -> c_int;
pub fn SHA224_Final(md: *mut c_uchar, c: *mut SHA256_CTX) -> c_int;
pub fn SHA224(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar;
pub fn SHA256_Init(c: *mut SHA256_CTX) -> c_int;
pub fn SHA256_Update(c: *mut SHA256_CTX, data: *const c_void, len: size_t) -> c_int;
pub fn SHA256_Final(md: *mut c_uchar, c: *mut SHA256_CTX) -> c_int;
pub fn SHA256(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar;
}
pub type SHA_LONG64 = u64;
#[repr(C)]
pub struct SHA512_CTX {
pub h: [SHA_LONG64; 8],
pub Nl: SHA_LONG64,
pub Nh: SHA_LONG64,
// this is a union but we don't want to require 1.19
u: [SHA_LONG64; SHA_LBLOCK as usize],
pub num: c_uint,
pub md_len: c_uint,
}
extern "C" {
pub fn SHA384_Init(c: *mut SHA512_CTX) -> c_int;
pub fn SHA384_Update(c: *mut SHA512_CTX, data: *const c_void, len: size_t) -> c_int;
pub fn SHA384_Final(md: *mut c_uchar, c: *mut SHA512_CTX) -> c_int;
pub fn SHA384(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar;
pub fn SHA512_Init(c: *mut SHA512_CTX) -> c_int;
pub fn SHA512_Update(c: *mut SHA512_CTX, data: *const c_void, len: size_t) -> c_int;
pub fn SHA512_Final(md: *mut c_uchar, c: *mut SHA512_CTX) -> c_int;
pub fn SHA512(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar;
}

View File

@ -1,18 +0,0 @@
use libc::*;
use *;
pub const SRTP_AES128_CM_SHA1_80: c_ulong = 0x0001;
pub const SRTP_AES128_CM_SHA1_32: c_ulong = 0x0002;
pub const SRTP_AES128_F8_SHA1_80: c_ulong = 0x0003;
pub const SRTP_AES128_F8_SHA1_32: c_ulong = 0x0004;
pub const SRTP_NULL_SHA1_80: c_ulong = 0x0005;
pub const SRTP_NULL_SHA1_32: c_ulong = 0x0006;
extern "C" {
pub fn SSL_CTX_set_tlsext_use_srtp(ctx: *mut SSL_CTX, profiles: *const c_char) -> c_int;
pub fn SSL_set_tlsext_use_srtp(ssl: *mut SSL, profiles: *const c_char) -> c_int;
pub fn SSL_get_srtp_profiles(ssl: *mut SSL) -> *mut stack_st_SRTP_PROTECTION_PROFILE;
pub fn SSL_get_selected_srtp_profile(ssl: *mut SSL) -> *mut SRTP_PROTECTION_PROFILE;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
use libc::*;
pub const SSL3_VERSION: c_int = 0x300;
pub const SSL3_AD_ILLEGAL_PARAMETER: c_int = 47;

View File

@ -1,45 +0,0 @@
use libc::*;
cfg_if! {
if #[cfg(ossl110)] {
pub enum OPENSSL_STACK {}
} else {
#[repr(C)]
pub struct _STACK {
pub num: c_int,
pub data: *mut *mut c_char,
pub sorted: c_int,
pub num_alloc: c_int,
pub comp: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
}
}
}
cfg_if! {
if #[cfg(ossl110)] {
extern "C" {
pub fn OPENSSL_sk_num(stack: *const OPENSSL_STACK) -> c_int;
pub fn OPENSSL_sk_value(stack: *const OPENSSL_STACK, idx: c_int) -> *mut c_void;
pub fn OPENSSL_sk_new_null() -> *mut OPENSSL_STACK;
pub fn OPENSSL_sk_free(st: *mut OPENSSL_STACK);
pub fn OPENSSL_sk_pop_free(
st: *mut OPENSSL_STACK,
free: Option<unsafe extern "C" fn(*mut c_void)>,
);
pub fn OPENSSL_sk_push(st: *mut OPENSSL_STACK, data: *const c_void) -> c_int;
pub fn OPENSSL_sk_pop(st: *mut OPENSSL_STACK) -> *mut c_void;
}
} else {
extern "C" {
pub fn sk_num(st: *const _STACK) -> c_int;
pub fn sk_value(st: *const _STACK, n: c_int) -> *mut c_void;
pub fn sk_new_null() -> *mut _STACK;
pub fn sk_free(st: *mut _STACK);
pub fn sk_pop_free(st: *mut _STACK, free: Option<unsafe extern "C" fn(*mut c_void)>);
pub fn sk_push(st: *mut _STACK, data: *mut c_void) -> c_int;
pub fn sk_pop(st: *mut _STACK) -> *mut c_void;
}
}
}

View File

@ -1,111 +0,0 @@
use libc::*;
use std::mem;
use std::ptr;
use *;
pub const TLS1_VERSION: c_int = 0x301;
pub const TLS1_1_VERSION: c_int = 0x302;
pub const TLS1_2_VERSION: c_int = 0x303;
#[cfg(ossl111)]
pub const TLS1_3_VERSION: c_int = 0x304;
pub const TLS1_AD_DECODE_ERROR: c_int = 50;
pub const TLS1_AD_UNRECOGNIZED_NAME: c_int = 112;
pub const TLSEXT_NAMETYPE_host_name: c_int = 0;
pub const TLSEXT_STATUSTYPE_ocsp: c_int = 1;
extern "C" {
pub fn SSL_get_servername(ssl: *const SSL, name_type: c_int) -> *const c_char;
pub fn SSL_export_keying_material(
s: *mut SSL,
out: *mut c_uchar,
olen: size_t,
label: *const c_char,
llen: size_t,
context: *const c_uchar,
contextlen: size_t,
use_context: c_int,
) -> c_int;
#[cfg(ossl111)]
pub fn SSL_export_keying_material_early(
s: *mut ::SSL,
out: *mut c_uchar,
olen: size_t,
label: *const c_char,
llen: size_t,
context: *const c_uchar,
contextlen: size_t,
) -> c_int;
}
pub unsafe fn SSL_set_tlsext_host_name(s: *mut SSL, name: *mut c_char) -> c_long {
SSL_ctrl(
s,
SSL_CTRL_SET_TLSEXT_HOSTNAME,
TLSEXT_NAMETYPE_host_name as c_long,
name as *mut c_void,
)
}
pub unsafe fn SSL_set_tlsext_status_type(s: *mut SSL, type_: c_int) -> c_long {
SSL_ctrl(
s,
SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,
type_ as c_long,
ptr::null_mut(),
)
}
pub unsafe fn SSL_get_tlsext_status_ocsp_resp(ssl: *mut SSL, resp: *mut *mut c_uchar) -> c_long {
SSL_ctrl(
ssl,
SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,
0,
resp as *mut c_void,
)
}
pub unsafe fn SSL_set_tlsext_status_ocsp_resp(
ssl: *mut SSL,
resp: *mut c_uchar,
len: c_long,
) -> c_long {
SSL_ctrl(
ssl,
SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,
len,
resp as *mut c_void,
)
}
pub unsafe fn SSL_CTX_set_tlsext_servername_callback(
ctx: *mut SSL_CTX,
// FIXME should have the right signature
cb: Option<extern "C" fn()>,
) -> c_long {
SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TLSEXT_SERVERNAME_CB, cb)
}
pub const SSL_TLSEXT_ERR_OK: c_int = 0;
pub const SSL_TLSEXT_ERR_ALERT_WARNING: c_int = 1;
pub const SSL_TLSEXT_ERR_ALERT_FATAL: c_int = 2;
pub const SSL_TLSEXT_ERR_NOACK: c_int = 3;
pub unsafe fn SSL_CTX_set_tlsext_servername_arg(ctx: *mut SSL_CTX, arg: *mut c_void) -> c_long {
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG, 0, arg)
}
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(ctx, SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB, mem::transmute(cb))
}
pub unsafe fn SSL_CTX_set_tlsext_status_arg(ctx: *mut SSL_CTX, arg: *mut c_void) -> c_long {
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG, 0, arg)
}

View File

@ -1,349 +0,0 @@
use libc::*;
use *;
pub const X509_FILETYPE_PEM: c_int = 1;
pub const X509_FILETYPE_ASN1: c_int = 2;
pub const X509_FILETYPE_DEFAULT: c_int = 3;
#[repr(C)]
pub struct X509_VAL {
pub notBefore: *mut ASN1_TIME,
pub notAfter: *mut ASN1_TIME,
}
pub enum X509_NAME_ENTRY {}
stack!(stack_st_X509_NAME);
pub enum X509_EXTENSION {}
stack!(stack_st_X509_EXTENSION);
stack!(stack_st_X509_ATTRIBUTE);
cfg_if! {
if #[cfg(ossl110)] {
pub enum X509_REQ_INFO {}
} else {
#[repr(C)]
pub struct X509_REQ_INFO {
pub enc: ASN1_ENCODING,
pub version: *mut ::ASN1_INTEGER,
pub subject: *mut ::X509_NAME,
pubkey: *mut c_void,
pub attributes: *mut stack_st_X509_ATTRIBUTE,
}
}
}
cfg_if! {
if #[cfg(ossl110)] {
pub enum X509_REQ {}
} else {
#[repr(C)]
pub struct X509_REQ {
pub req_info: *mut X509_REQ_INFO,
sig_alg: *mut c_void,
signature: *mut c_void,
references: c_int,
}
}
}
cfg_if! {
if #[cfg(ossl110)] {
pub enum X509_CINF {}
} else {
#[repr(C)]
pub struct X509_CINF {
version: *mut c_void,
serialNumber: *mut c_void,
signature: *mut c_void,
issuer: *mut c_void,
pub validity: *mut X509_VAL,
subject: *mut c_void,
key: *mut c_void,
issuerUID: *mut c_void,
subjectUID: *mut c_void,
pub extensions: *mut stack_st_X509_EXTENSION,
enc: ASN1_ENCODING,
}
}
}
stack!(stack_st_X509);
extern "C" {
pub fn X509_verify_cert_error_string(n: c_long) -> *const c_char;
pub fn X509_sign(x: *mut X509, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int;
pub fn X509_digest(
x: *const X509,
digest: *const EVP_MD,
buf: *mut c_uchar,
len: *mut c_uint,
) -> c_int;
pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int;
pub fn i2d_X509_bio(b: *mut BIO, x: *mut X509) -> c_int;
pub fn i2d_X509_REQ_bio(b: *mut BIO, x: *mut X509_REQ) -> c_int;
pub fn i2d_PrivateKey_bio(b: *mut BIO, x: *mut EVP_PKEY) -> c_int;
pub fn i2d_PUBKEY_bio(b: *mut BIO, x: *mut EVP_PKEY) -> c_int;
pub fn i2d_PUBKEY(k: *mut EVP_PKEY, buf: *mut *mut u8) -> c_int;
pub fn d2i_PUBKEY(k: *mut *mut EVP_PKEY, buf: *mut *const u8, len: c_long) -> *mut EVP_PKEY;
pub fn d2i_RSA_PUBKEY(k: *mut *mut RSA, buf: *mut *const u8, len: c_long) -> *mut RSA;
pub fn i2d_RSA_PUBKEY(k: *mut RSA, buf: *mut *mut u8) -> c_int;
pub fn d2i_DSA_PUBKEY(k: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long) -> *mut DSA;
pub fn i2d_DSA_PUBKEY(a: *mut DSA, pp: *mut *mut c_uchar) -> c_int;
pub fn i2d_PrivateKey(k: *mut EVP_PKEY, buf: *mut *mut u8) -> c_int;
pub fn d2i_ECPrivateKey(
k: *mut *mut EC_KEY,
pp: *mut *const c_uchar,
length: c_long,
) -> *mut EC_KEY;
pub fn i2d_ECPrivateKey(ec_key: *mut EC_KEY, pp: *mut *mut c_uchar) -> c_int;
}
cfg_if! {
if #[cfg(ossl110)] {
extern "C" {
pub fn X509_ALGOR_get0(
paobj: *mut *const ASN1_OBJECT,
pptype: *mut c_int,
ppval: *mut *const c_void,
alg: *const X509_ALGOR,
);
}
} else if #[cfg(ossl102)] {
extern "C" {
pub fn X509_ALGOR_get0(
paobj: *mut *mut ASN1_OBJECT,
pptype: *mut c_int,
ppval: *mut *mut c_void,
alg: *mut X509_ALGOR,
);
}
}
}
extern "C" {
pub fn X509_gmtime_adj(time: *mut ASN1_TIME, adj: c_long) -> *mut ASN1_TIME;
pub fn X509_to_X509_REQ(x: *mut X509, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> *mut X509_REQ;
pub fn X509_ALGOR_free(x: *mut X509_ALGOR);
pub fn X509_REQ_new() -> *mut X509_REQ;
pub fn X509_REQ_free(x: *mut X509_REQ);
pub fn d2i_X509_REQ(
a: *mut *mut X509_REQ,
pp: *mut *const c_uchar,
length: c_long,
) -> *mut X509_REQ;
pub fn i2d_X509_REQ(x: *mut X509_REQ, buf: *mut *mut u8) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
extern "C" {
pub fn X509_get0_signature(
psig: *mut *const ASN1_BIT_STRING,
palg: *mut *const X509_ALGOR,
x: *const X509,
);
}
} else if #[cfg(ossl102)] {
extern "C" {
pub fn X509_get0_signature(
psig: *mut *mut ASN1_BIT_STRING,
palg: *mut *mut X509_ALGOR,
x: *const X509,
);
}
}
}
extern "C" {
#[cfg(ossl102)]
pub fn X509_get_signature_nid(x: *const X509) -> c_int;
pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION);
pub fn X509_NAME_ENTRY_free(x: *mut X509_NAME_ENTRY);
pub fn X509_NAME_new() -> *mut X509_NAME;
pub fn X509_NAME_free(x: *mut X509_NAME);
pub fn X509_new() -> *mut X509;
pub fn X509_free(x: *mut X509);
pub fn i2d_X509(x: *mut X509, buf: *mut *mut u8) -> c_int;
pub fn d2i_X509(a: *mut *mut X509, pp: *mut *const c_uchar, length: c_long) -> *mut X509;
pub fn X509_get_pubkey(x: *mut X509) -> *mut EVP_PKEY;
pub fn X509_set_version(x: *mut X509, version: c_long) -> c_int;
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_set_issuer_name(x: *mut X509, name: *mut X509_NAME) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
extern "C" {
pub fn X509_get_issuer_name(x: *const ::X509) -> *mut ::X509_NAME;
}
} else {
extern "C" {
pub fn X509_get_issuer_name(x: *mut ::X509) -> *mut ::X509_NAME;
}
}
}
extern "C" {
pub fn X509_set_subject_name(x: *mut X509, name: *mut X509_NAME) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
extern "C" {
pub fn X509_get_subject_name(x: *const ::X509) -> *mut ::X509_NAME;
}
} else {
extern "C" {
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
}
}
}
cfg_if! {
if #[cfg(ossl110)] {
extern "C" {
pub fn X509_set1_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set1_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
}
} else {
extern "C" {
pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
}
}
}
extern "C" {
#[cfg(ossl110)]
pub fn X509_REQ_get_version(req: *const X509_REQ) -> c_long;
pub fn X509_REQ_set_version(req: *mut X509_REQ, version: c_long) -> c_int;
#[cfg(ossl110)]
pub fn X509_REQ_get_subject_name(req: *const X509_REQ) -> *mut X509_NAME;
pub fn X509_REQ_set_subject_name(req: *mut X509_REQ, name: *mut X509_NAME) -> c_int;
pub fn X509_REQ_set_pubkey(req: *mut X509_REQ, pkey: *mut EVP_PKEY) -> c_int;
pub fn X509_REQ_get_pubkey(req: *mut X509_REQ) -> *mut EVP_PKEY;
pub fn X509_REQ_get_extensions(req: *mut X509_REQ) -> *mut stack_st_X509_EXTENSION;
pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: *mut stack_st_X509_EXTENSION)
-> c_int;
pub fn X509_set_pubkey(x: *mut X509, pkey: *mut EVP_PKEY) -> c_int;
pub fn X509_REQ_verify(req: *mut X509_REQ, pkey: *mut EVP_PKEY) -> c_int;
#[cfg(any(ossl110, libressl273))]
pub fn X509_getm_notBefore(x: *const X509) -> *mut ASN1_TIME;
#[cfg(any(ossl110, libressl273))]
pub fn X509_getm_notAfter(x: *const X509) -> *mut ASN1_TIME;
#[cfg(any(ossl110, libressl273))]
pub fn X509_up_ref(x: *mut X509) -> c_int;
#[cfg(ossl110)]
pub fn X509_get0_extensions(req: *const ::X509) -> *const stack_st_X509_EXTENSION;
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
extern "C" {
pub fn X509_NAME_entry_count(n: *const X509_NAME) -> c_int;
}
} else {
extern "C" {
pub fn X509_NAME_entry_count(n: *mut X509_NAME) -> c_int;
}
}
}
cfg_if! {
if #[cfg(libressl280)] {
extern "C" {
pub fn X509_NAME_get_index_by_NID(n: *const X509_NAME, nid: c_int, last_pos: c_int) -> c_int;
}
} else {
extern "C" {
pub fn X509_NAME_get_index_by_NID(n: *mut X509_NAME, nid: c_int, last_pos: c_int) -> c_int;
}
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
extern "C" {
pub fn X509_NAME_get_entry(n: *const X509_NAME, loc: c_int) -> *mut X509_NAME_ENTRY;
pub fn X509_NAME_add_entry_by_NID(
x: *mut X509_NAME,
field: c_int,
ty: c_int,
bytes: *const c_uchar,
len: c_int,
loc: c_int,
set: c_int,
) -> c_int;
pub fn X509_NAME_ENTRY_get_object(ne: *const X509_NAME_ENTRY) -> *mut ASN1_OBJECT;
pub fn X509_NAME_ENTRY_get_data(ne: *const X509_NAME_ENTRY) -> *mut ASN1_STRING;
}
} else {
extern "C" {
pub fn X509_NAME_get_entry(n: *mut X509_NAME, loc: c_int) -> *mut X509_NAME_ENTRY;
pub fn X509_NAME_add_entry_by_NID(
x: *mut X509_NAME,
field: c_int,
ty: c_int,
bytes: *mut c_uchar,
len: c_int,
loc: c_int,
set: c_int,
) -> c_int;
pub fn X509_NAME_ENTRY_get_object(ne: *mut X509_NAME_ENTRY) -> *mut ASN1_OBJECT;
pub fn X509_NAME_ENTRY_get_data(ne: *mut X509_NAME_ENTRY) -> *mut ASN1_STRING;
}
}
}
extern "C" {
pub fn X509_NAME_add_entry_by_txt(
x: *mut X509_NAME,
field: *const c_char,
ty: c_int,
bytes: *const c_uchar,
len: c_int,
loc: c_int,
set: c_int,
) -> c_int;
pub fn X509_add_ext(x: *mut X509, ext: *mut X509_EXTENSION, loc: c_int) -> c_int;
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
extern "C" {
pub fn X509_get_ext_d2i(
x: *const ::X509,
nid: c_int,
crit: *mut c_int,
idx: *mut c_int,
) -> *mut c_void;
}
} else {
extern "C" {
pub fn X509_get_ext_d2i(
x: *mut ::X509,
nid: c_int,
crit: *mut c_int,
idx: *mut c_int,
) -> *mut c_void;
}
}
}
extern "C" {
pub fn X509_verify_cert(ctx: *mut X509_STORE_CTX) -> c_int;
}

View File

@ -1,153 +0,0 @@
use libc::*;
use *;
#[cfg(any(libressl, all(ossl102, not(ossl110))))]
pub enum X509_VERIFY_PARAM_ID {}
pub const X509_V_OK: c_int = 0;
#[cfg(ossl102f)]
pub const X509_V_ERR_UNSPECIFIED: c_int = 1;
pub const X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: c_int = 2;
pub const X509_V_ERR_UNABLE_TO_GET_CRL: c_int = 3;
pub const X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: c_int = 4;
pub const X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: c_int = 5;
pub const X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: c_int = 6;
pub const X509_V_ERR_CERT_SIGNATURE_FAILURE: c_int = 7;
pub const X509_V_ERR_CRL_SIGNATURE_FAILURE: c_int = 8;
pub const X509_V_ERR_CERT_NOT_YET_VALID: c_int = 9;
pub const X509_V_ERR_CERT_HAS_EXPIRED: c_int = 10;
pub const X509_V_ERR_CRL_NOT_YET_VALID: c_int = 11;
pub const X509_V_ERR_CRL_HAS_EXPIRED: c_int = 12;
pub const X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: c_int = 13;
pub const X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: c_int = 14;
pub const X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: c_int = 15;
pub const X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: c_int = 16;
pub const X509_V_ERR_OUT_OF_MEM: c_int = 17;
pub const X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: c_int = 18;
pub const X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: c_int = 19;
pub const X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: c_int = 20;
pub const X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: c_int = 21;
pub const X509_V_ERR_CERT_CHAIN_TOO_LONG: c_int = 22;
pub const X509_V_ERR_CERT_REVOKED: c_int = 23;
pub const X509_V_ERR_INVALID_CA: c_int = 24;
pub const X509_V_ERR_PATH_LENGTH_EXCEEDED: c_int = 25;
pub const X509_V_ERR_INVALID_PURPOSE: c_int = 26;
pub const X509_V_ERR_CERT_UNTRUSTED: c_int = 27;
pub const X509_V_ERR_CERT_REJECTED: c_int = 28;
pub const X509_V_ERR_SUBJECT_ISSUER_MISMATCH: c_int = 29;
pub const X509_V_ERR_AKID_SKID_MISMATCH: c_int = 30;
pub const X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: c_int = 31;
pub const X509_V_ERR_KEYUSAGE_NO_CERTSIGN: c_int = 32;
pub const X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: c_int = 33;
pub const X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: c_int = 34;
pub const X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: c_int = 35;
pub const X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: c_int = 36;
pub const X509_V_ERR_INVALID_NON_CA: c_int = 37;
pub const X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: c_int = 38;
pub const X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: c_int = 39;
pub const X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: c_int = 40;
pub const X509_V_ERR_INVALID_EXTENSION: c_int = 41;
pub const X509_V_ERR_INVALID_POLICY_EXTENSION: c_int = 42;
pub const X509_V_ERR_NO_EXPLICIT_POLICY: c_int = 43;
pub const X509_V_ERR_DIFFERENT_CRL_SCOPE: c_int = 44;
pub const X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: c_int = 45;
pub const X509_V_ERR_UNNESTED_RESOURCE: c_int = 46;
pub const X509_V_ERR_PERMITTED_VIOLATION: c_int = 47;
pub const X509_V_ERR_EXCLUDED_VIOLATION: c_int = 48;
pub const X509_V_ERR_SUBTREE_MINMAX: c_int = 49;
pub const X509_V_ERR_APPLICATION_VERIFICATION: c_int = 50;
pub const X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: c_int = 51;
pub const X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: c_int = 52;
pub const X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53;
pub const X509_V_ERR_CRL_PATH_VALIDATION_ERROR: c_int = 54;
#[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_INVALID_VERSION: c_int = 56;
#[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_INVALID_ALGORITHM: c_int = 57;
#[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_INVALID_CURVE: c_int = 58;
#[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: c_int = 59;
#[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: c_int = 60;
#[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: c_int = 61;
#[cfg(ossl102)]
pub const X509_V_ERR_HOSTNAME_MISMATCH: c_int = 62;
#[cfg(ossl102)]
pub const X509_V_ERR_EMAIL_MISMATCH: c_int = 63;
#[cfg(ossl102)]
pub const X509_V_ERR_IP_ADDRESS_MISMATCH: c_int = 64;
cfg_if! {
if #[cfg(ossl110)] {
pub const X509_V_ERR_DANE_NO_MATCH: c_int = 65;
pub const X509_V_ERR_EE_KEY_TOO_SMALL: c_int = 66;
pub const X509_V_ERR_CA_KEY_TOO_SMALL: c_int = 67;
pub const X509_V_ERR_CA_MD_TOO_WEAK: c_int = 68;
pub const X509_V_ERR_INVALID_CALL: c_int = 69;
pub const X509_V_ERR_STORE_LOOKUP: c_int = 70;
pub const X509_V_ERR_NO_VALID_SCTS: c_int = 71;
} else if #[cfg(ossl102h)] {
pub const X509_V_ERR_INVALID_CALL: c_int = 65;
pub const X509_V_ERR_STORE_LOOKUP: c_int = 66;
pub const X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION: c_int = 67;
}
}
extern "C" {
pub fn X509_STORE_new() -> *mut X509_STORE;
pub fn X509_STORE_free(store: *mut X509_STORE);
pub fn X509_STORE_CTX_new() -> *mut X509_STORE_CTX;
pub fn X509_STORE_CTX_free(ctx: *mut X509_STORE_CTX);
pub fn X509_STORE_CTX_init(
ctx: *mut X509_STORE_CTX,
store: *mut X509_STORE,
x509: *mut X509,
chain: *mut stack_st_X509,
) -> c_int;
pub fn X509_STORE_CTX_cleanup(ctx: *mut X509_STORE_CTX);
pub fn X509_STORE_add_cert(store: *mut X509_STORE, x: *mut X509) -> c_int;
pub fn X509_STORE_set_default_paths(store: *mut X509_STORE) -> c_int;
pub fn X509_STORE_CTX_get_ex_data(ctx: *mut X509_STORE_CTX, idx: c_int) -> *mut c_void;
pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int;
pub fn X509_STORE_CTX_set_error(ctx: *mut X509_STORE_CTX, error: c_int);
pub fn X509_STORE_CTX_get_error_depth(ctx: *mut X509_STORE_CTX) -> c_int;
pub fn X509_STORE_CTX_get_current_cert(ctx: *mut X509_STORE_CTX) -> *mut X509;
}
cfg_if! {
if #[cfg(ossl110)] {
extern "C" {
pub fn X509_STORE_CTX_get0_chain(ctx: *mut X509_STORE_CTX) -> *mut stack_st_X509;
}
} else {
extern "C" {
pub fn X509_STORE_CTX_get_chain(ctx: *mut X509_STORE_CTX) -> *mut stack_st_X509;
}
}
}
extern "C" {
#[cfg(any(ossl102, libressl261))]
pub fn X509_VERIFY_PARAM_free(param: *mut X509_VERIFY_PARAM);
#[cfg(any(ossl102, libressl261))]
pub fn X509_VERIFY_PARAM_set1_host(
param: *mut X509_VERIFY_PARAM,
name: *const c_char,
namelen: size_t,
) -> c_int;
#[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_ip(
param: *mut X509_VERIFY_PARAM,
ip: *const c_uchar,
iplen: size_t,
) -> c_int;
}

View File

@ -1,93 +0,0 @@
use libc::*;
use *;
pub enum CONF_METHOD {}
pub const GEN_OTHERNAME: c_int = 0;
pub const GEN_EMAIL: c_int = 1;
pub const GEN_DNS: c_int = 2;
pub const GEN_X400: c_int = 3;
pub const GEN_DIRNAME: c_int = 4;
pub const GEN_EDIPARTY: c_int = 5;
pub const GEN_URI: c_int = 6;
pub const GEN_IPADD: c_int = 7;
pub const GEN_RID: c_int = 8;
#[repr(C)]
pub struct GENERAL_NAME {
pub type_: c_int,
// FIXME should be a union
pub d: *mut c_void,
}
stack!(stack_st_GENERAL_NAME);
extern "C" {
pub fn GENERAL_NAME_free(name: *mut GENERAL_NAME);
}
#[cfg(any(ossl102, libressl261))]
pub const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT: c_uint = 0x1;
#[cfg(any(ossl102, libressl261))]
pub const X509_CHECK_FLAG_NO_WILDCARDS: c_uint = 0x2;
#[cfg(any(ossl102, libressl261))]
pub const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS: c_uint = 0x4;
#[cfg(any(ossl102, libressl261))]
pub const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS: c_uint = 0x8;
#[cfg(any(ossl102, libressl261))]
pub const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS: c_uint = 0x10;
#[cfg(ossl110)]
pub const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT: c_uint = 0x20;
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
extern "C" {
pub fn X509V3_EXT_nconf_nid(
conf: *mut CONF,
ctx: *mut X509V3_CTX,
ext_nid: c_int,
value: *const c_char,
) -> *mut X509_EXTENSION;
pub fn X509V3_EXT_nconf(
conf: *mut CONF,
ctx: *mut X509V3_CTX,
name: *const c_char,
value: *const c_char,
) -> *mut X509_EXTENSION;
}
} else {
extern "C" {
pub fn X509V3_EXT_nconf_nid(
conf: *mut CONF,
ctx: *mut X509V3_CTX,
ext_nid: c_int,
value: *mut c_char,
) -> *mut X509_EXTENSION;
pub fn X509V3_EXT_nconf(
conf: *mut CONF,
ctx: *mut X509V3_CTX,
name: *mut c_char,
value: *mut c_char,
) -> *mut X509_EXTENSION;
}
}
}
extern "C" {
pub fn X509_check_issued(issuer: *mut X509, subject: *mut X509) -> c_int;
pub fn X509_verify(req: *mut X509, pkey: *mut EVP_PKEY) -> c_int;
pub fn X509V3_set_nconf(ctx: *mut X509V3_CTX, conf: *mut CONF);
pub fn X509V3_set_ctx(
ctx: *mut X509V3_CTX,
issuer: *mut X509,
subject: *mut X509,
req: *mut X509_REQ,
crl: *mut X509_CRL,
flags: c_int,
);
pub fn X509_get1_ocsp(x: *mut X509) -> *mut stack_st_OPENSSL_STRING;
}

View File

@ -1,427 +0,0 @@
# Change Log
## [Unreleased]
## [v0.10.25] - 2019-10-02
### Fixed
* Fixed a memory leak in `EcdsaSig::from_private_components` when using OpenSSL 1.0.x.
### Added
* Added support for Ed25519 and Ed448 keys.
* Implemented `ToOwned` for `PKeyRef` and `Clone` for `PKey`.
## [v0.10.24] - 2019-07-19
### Fixed
* Worked around an OpenSSL 1.0.x bug triggered by code calling `SSL_set_app_data`.
### Added
* Added `aes::{wrap_key, unwrap_key}`.
* Added `CmsContentInfoRef::to_pem` and `CmsContentInfo::from_pem`.
* Added `DsaRef::private_key_to_pem`.
* Added `EcGroupRef::{cofactor, generator}`.
* Added `EcPointRef::to_owned`.
* Added a `Debug` implementation for `EcKey`.
* Added `SslAcceptor::{mozilla_intermediate_v5, mozilla_modern_v5}`.
* Added `Cipher::{aes_128_ofb, aes_192_ecb, aes_192_cbc, aes_192_ctr, aes_192_cfb1, aes_192_cfb128, aes_192_cfb8,
aes_192_gcm, aes_192_ccm, aes_192_ofb, aes_256_ofb}`.
## [v0.10.23] - 2019-05-18
### Fixed
* Fixed session callbacks when an `Ssl`'s context is replaced.
### Added
* Added `SslContextBuilder::add_client_ca`.
## [v0.10.22] - 2019-05-08
### Added
* Added support for the LibreSSL 2.9.x series.
## [v0.10.21] - 2019-04-30
### Fixed
* Fixed overly conservatifve buffer size checks in `Crypter` when using stream ciphers.
### Added
* Added bindings to envelope encryption APIs.
* Added `PkeyRef::size`.
## [v0.10.20] - 2019-03-20
### Added
* Added `CmsContentInfo::from_der` and `CmsContentInfo::encrypt`.
* Added `X509Ref::verify` and `X509ReqRef::verify`.
* Implemented `PartialEq` and `Eq` for `MessageDigest`.
* Added `MessageDigest::type_` and `EcGroupRef::curve_name`.
## [v0.10.19] - 2019-03-01
### Added
* The openssl-sys build script now logs the values of environment variables.
* Added `ERR_PACK` to openssl-sys.
* The `ERR_*` functions in openssl-sys are const functions when building against newer Rust versions.
* Implemented `Clone` for `Dsa`.
* Added `SslContextRef::add_session` and `SslContextRef::remove_session`.
* Added `SslSessionRef::time`, `SslSessionRef::timeout`, and `SslSessionRef::protocol_version`.
* Added `SslContextBuilder::set_session_cache_size` and `SslContextRef::session_cache_size`.
## [v0.10.18] - 2019-02-22
### Fixed
* Fixed the return type of `ssl::cipher_name`.
## [v0.10.17] - 2019-02-22
### Added
* Implemented `AsRef<str>` and `AsRef<[u8]>` for `OpenSslString`.
* Added `Asn1Integer::from_bn`.
* Added `RsaRef::check_key`.
* Added `Asn1Time::from_str` and `Asn1Time::from_str_x509`.
* Added `Rsa::generate_with_e`.
* Added `Cipher::des_ede3_cfb64`.
* Added `SslCipherRef::standard_name` and `ssl::cipher_name`.
## [v0.10.16] - 2018-12-16
### Added
* Added SHA3 and SHAKE to `MessageDigest`.
* Added `rand::keep_random_devices_open`.
* Added support for LibreSSL 2.9.0.
## [v0.10.15] - 2018-10-22
### Added
* Implemented `DoubleEndedIterator` for stack iterators.
## [v0.10.14] - 2018-10-18
### Fixed
* Made some accidentally exposed internal functions private.
### Added
* Added support for LibreSSL 2.8.
### Changed
* The OpenSSL version used with the `vendored` feature has been upgraded from 1.1.0 to 1.1.1.
## [v0.10.13] - 2018-10-14
### Fixed
* Fixed a double-free in the `SslContextBuilder::set_get_session_callback` API.
### Added
* Added `SslContextBuilder::set_client_hello_callback`.
* Added support for LibreSSL 2.8.1.
* Added `EcdsaSig::from_der` and `EcdsaSig::to_der`.
* Added PKCS#7 support.
## [v0.10.12] - 2018-09-13
### Fixed
* Fixed handling of SNI callbacks during renegotiation.
### Added
* Added `SslRef::get_shutdown` and `SslRef::set_shutdown`.
* Added support for SRTP in DTLS sessions.
* Added support for LibreSSL 2.8.0.
## [v0.10.11] - 2018-08-04
### Added
* The new `vendored` cargo feature will cause openssl-sys to compile and statically link to a
vendored copy of OpenSSL.
* Added `SslContextBuilder::set_psk_server_callback`.
* Added `DsaRef::pub_key` and `DsaRef::priv_key`.
* Added `Dsa::from_private_components` and `Dsa::from_public_components`.
* Added `X509NameRef::entries`.
### Deprecated
* `SslContextBuilder::set_psk_callback` has been renamed to
`SslContextBuilder::set_psk_client_callback` and deprecated.
## [v0.10.10] - 2018-06-06
### Added
* Added `SslRef::set_alpn_protos`.
* Added `SslContextBuilder::set_ciphersuites`.
## [v0.10.9] - 2018-06-01
### Fixed
* Fixed a use-after-free in `CmsContentInfo::sign`.
* `SslRef::servername` now returns `None` rather than panicking on a non-UTF8 name.
### Added
* Added `MessageDigest::from_nid`.
* Added `Nid::signature_algorithms`, `Nid::long_name`, and `Nid::short_name`.
* Added early data and early keying material export support for TLS 1.3.
* Added `SslRef::verified_chain`.
* Added `SslRef::servername_raw` which returns a `&[u8]` rather than `&str`.
* Added `SslRef::finished` and `SslRef::peer_finished`.
* Added `X509Ref::digest` to replace `X509Ref::fingerprint`.
* `X509StoreBuilder` and `X509Store` now implement `Sync` and `Send`.
### Deprecated
* `X509Ref::fingerprint` has been deprecated in favor of `X509Ref::digest`.
## [v0.10.8] - 2018-05-20
### Fixed
* `openssl-sys` will now detect Homebrew-installed OpenSSL when installed to a non-default
directory.
* The `X509_V_ERR_INVALID_CALL`, `X509_V_ERR_STORE_LOOKUP`, and
`X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION` constants in `openssl-sys` are now only present when
building against 1.1.0g and up rather than 1.1.0.
* `SslContextBuilder::max_proto_version` and `SslContextBuilder::min_proto_version` are only present
when building against 1.1.0g and up rather than 1.1.0.
### Added
* Added `CmsContentInfo::sign`.
* Added `Clone` and `ToOwned` implementations to `Rsa` and `RsaRef` respectively.
* The `min_proto_version` and `max_proto_version` methods are available when linking against
LibreSSL 2.6.1 and up in addition to OpenSSL.
* `X509VerifyParam` is available when linking against LibreSSL 2.6.1 and up in addition to OpenSSL.
* ALPN support is available when linking against LibreSSL 2.6.1 and up in addition to OpenSSL.
* `Stack` and `StackRef` are now `Sync` and `Send`.
## [v0.10.7] - 2018-04-30
### Added
* Added `X509Req::public_key` and `X509Req::extensions`.
* Added `RsaPrivateKeyBuilder` to allow control over initialization of optional components of an RSA
private key.
* Added DER encode/decode support to `SslSession`.
* openssl-sys now provides the `DEP_OPENSSL_VERSION_NUMBER` and
`DEP_OPENSSL_LIBRESSL_VERSION_NUMBER` environment variables to downstream build scripts which
contains the hex-encoded version number of the OpenSSL or LibreSSL distribution being built
against. The other variables are deprecated.
## [v0.10.6] - 2018-03-05
### Added
* Added `SslOptions::ENABLE_MIDDLEBOX_COMPAT`.
* Added more `Sync` and `Send` implementations.
* Added `PKeyRef::id`.
* Added `Padding::PKCS1_PSS`.
* Added `Signer::set_rsa_pss_saltlen`, `Signer::set_rsa_mgf1_md`, `Signer::set_rsa_pss_saltlen`, and
`Signer::set_rsa_mgf1_md`
* Added `X509StoreContextRef::verify` to directly verify certificates.
* Added low level ECDSA support.
* Added support for TLSv1.3 custom extensions. (OpenSSL 1.1.1 only)
* Added AES-CCM support.
* Added `EcKey::from_private_components`.
* Added CMAC support.
* Added support for LibreSSL 2.7.
* Added `X509Ref::serial_number`.
* Added `Asn1IntegerRef::to_bn`.
* Added support for TLSv1.3 stateless handshakes. (OpenSSL 1.1.1 only)
### Changed
* The Cargo features previously used to gate access to version-specific OpenSSL APIs have been
removed. Those APIs will be available automatically when building against an appropriate OpenSSL
version.
* Fixed `PKey::private_key_from_der` to return a `PKey<Private>` rather than a `PKey<Public>`. This
is technically a breaking change but the function was pretty useless previously.
### Deprecated
* `X509CheckFlags::FLAG_NO_WILDCARDS` has been renamed to `X509CheckFlags::NO_WILDCARDS` and the old
name deprecated.
## [v0.10.5] - 2018-02-28
### Fixed
* `ErrorStack`'s `Display` implementation no longer writes an empty string if it contains no errors.
### Added
* Added `SslRef::version2`.
* Added `Cipher::des_ede3_cbc`.
* Added `SslRef::export_keying_material`.
* Added the ability to push an `Error` or `ErrorStack` back onto OpenSSL's error stack. Various
callback bindings use this to propagate errors properly.
* Added `SslContextBuilder::set_cookie_generate_cb` and `SslContextBuilder::set_cookie_verify_cb`.
* Added `SslContextBuilder::set_max_proto_version`, `SslContextBuilder::set_min_proto_version`,
`SslContextBuilder::max_proto_version`, and `SslContextBuilder::min_proto_version`.
### Changed
* Updated `SslConnector`'s default cipher list to match Python's.
### Deprecated
* `SslRef::version` has been deprecated. Use `SslRef::version_str` instead.
## [v0.10.4] - 2018-02-18
### Added
* Added OpenSSL 1.1.1 support.
* Added `Rsa::public_key_from_pem_pkcs1`.
* Added `SslOptions::NO_TLSV1_3`. (OpenSSL 1.1.1 only)
* Added `SslVersion`.
* Added `SslSessionCacheMode` and `SslContextBuilder::set_session_cache_mode`.
* Added `SslContextBuilder::set_new_session_callback`,
`SslContextBuilder::set_remove_session_callback`, and
`SslContextBuilder::set_get_session_callback`.
* Added `SslContextBuilder::set_keylog_callback`. (OpenSSL 1.1.1 only)
* Added `SslRef::client_random` and `SslRef::server_random`. (OpenSSL 1.1.0+ only)
### Fixed
* The `SslAcceptorBuilder::mozilla_modern` constructor now disables TLSv1.0 and TLSv1.1 in
accordance with Mozilla's recommendations.
## [v0.10.3] - 2018-02-12
### Added
* OpenSSL is now automatically detected on FreeBSD systems.
* Added `GeneralName` accessors for `rfc822Name` and `uri` variants.
* Added DES-EDE3 support.
### Fixed
* Fixed a memory leak in `X509StoreBuilder::add_cert`.
## [v0.10.2] - 2018-01-11
### Added
* Added `ConnectConfiguration::set_use_server_name_indication` and
`ConnectConfiguration::set_verify_hostname` for use in contexts where you don't have ownership
of the `ConnectConfiguration`.
## [v0.10.1] - 2018-01-10
### Added
* Added a `From<ErrorStack> for ssl::Error` implementation.
## [v0.10.0] - 2018-01-10
### Compatibility
* openssl 0.10 still uses openssl-sys 0.9, so openssl 0.9 and 0.10 can coexist without issue.
### Added
* The `ssl::select_next_proto` function can be used to easily implement the ALPN selection callback
in a "standard" way.
* FIPS mode support is available in the `fips` module.
* Accessors for the Issuer and Issuer Alternative Name fields of X509 certificates have been added.
* The `X509VerifyResult` can now be set in the certificate verification callback via
`X509StoreContextRef::set_error`.
### Changed
* All constants have been moved to associated constants of their type. For example, `bn::MSB_ONE`
is now `bn::MsbOption::ONE`.
* Asymmetric key types are now parameterized over what they contain. In OpenSSL, the same type is
used for key parameters, public keys, and private keys. Unfortunately, some APIs simply assume
that certain components are present and will segfault trying to use things that aren't there.
The `pkey` module contains new tag types named `Params`, `Public`, and `Private`, and the
`Dh`, `Dsa`, `EcKey`, `Rsa`, and `PKey` have a type parameter set to one of those values. This
allows the `Signer` constructor to indicate that it requires a private key at compile time for
example. Previously, `Signer` would simply segfault if provided a key without private
components.
* ALPN support has been changed to more directly model OpenSSL's own APIs. Instead of a single
method used for both the server and client sides which performed everything automatically, the
`SslContextBuilder::set_alpn_protos` and `SslContextBuilder::set_alpn_select_callback` handle
the client and server sides respectively.
* `SslConnector::danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication`
has been removed in favor of new methods which provide more control. The
`ConnectConfiguration::use_server_name_indication` method controls the use of Server Name
Indication (SNI), and the `ConnectConfiguration::verify_hostname` method controls the use of
hostname verification. These can be controlled independently, and if both are disabled, the
domain argument to `ConnectConfiguration::connect` is ignored.
* Shared secret derivation is now handled by the new `derive::Deriver` type rather than
`pkey::PKeyContext`, which has been removed.
* `ssl::Error` is now no longer an enum, and provides more direct access to the relevant state.
* `SslConnectorBuilder::new` has been moved and renamed to `SslConnector::builder`.
* `SslAcceptorBuilder::mozilla_intermediate` and `SslAcceptorBuilder::mozilla_modern` have been
moved to `SslAcceptor` and no longer take the private key and certificate chain. Install those
manually after creating the builder.
* `X509VerifyError` is now `X509VerifyResult` and can now have the "ok" value in addition to error
values.
* `x509::X509FileType` is now `ssl::SslFiletype`.
* Asymmetric key serialization and deserialization methods now document the formats that they
correspond to, and some have been renamed to better indicate that.
### Removed
* All deprecated APIs have been removed.
* NPN support has been removed. It has been supersceded by ALPN, and is hopefully no longer being
used in practice. If you still depend on it, please file an issue!
* `SslRef::compression` has been removed.
* Some `ssl::SslOptions` flags have been removed as they no longer do anything.
## Older
Look at the [release tags] for information about older releases.
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.24...master
[v0.10.24]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.23...openssl-v0.10.24
[v0.10.23]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.22...openssl-v0.10.23
[v0.10.22]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.21...openssl-v0.10.22
[v0.10.21]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.20...openssl-v0.10.21
[v0.10.20]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.19...openssl-v0.10.20
[v0.10.19]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.18...openssl-v0.10.19
[v0.10.18]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.17...openssl-v0.10.18
[v0.10.17]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.16...openssl-v0.10.17
[v0.10.16]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.15...openssl-v0.10.16
[v0.10.15]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.14...openssl-v0.10.15
[v0.10.14]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.13...openssl-v0.10.14
[v0.10.13]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.12...openssl-v0.10.13
[v0.10.12]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.11...openssl-v0.10.12
[v0.10.11]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.10...openssl-v0.10.11
[v0.10.10]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.9...openssl-v0.10.10
[v0.10.9]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.8...openssl-v0.10.9
[v0.10.8]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.7...openssl-v0.10.8
[v0.10.7]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.6...openssl-v0.10.7
[v0.10.6]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.5...openssl-v0.10.6
[v0.10.5]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.4...openssl-v0.10.5
[v0.10.4]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.3...openssl-v0.10.4
[v0.10.3]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.2...openssl-v0.10.3
[v0.10.2]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.1...openssl-v0.10.2
[v0.10.1]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.0...openssl-v0.10.1
[v0.10.0]: https://github.com/sfackler/rust-openssl/compare/v0.9.23...openssl-v0.10.0
[release tags]: https://github.com/sfackler/rust-openssl/releases

View File

@ -1,6 +1,6 @@
[package]
name = "openssl"
version = "0.10.25"
version = "0.9.24"
authors = ["Steven Fackler <sfackler@gmail.com>"]
license = "Apache-2.0"
description = "OpenSSL bindings"
@ -8,25 +8,26 @@ repository = "https://github.com/sfackler/rust-openssl"
readme = "README.md"
keywords = ["crypto", "tls", "ssl", "dtls"]
categories = ["cryptography", "api-bindings"]
build = "build.rs"
[package.metadata.docs.rs]
all-features = true
# these are deprecated and don't do anything anymore
[features]
v101 = []
v102 = []
v110 = []
v111 = []
vendored = ['openssl-sys/vendored']
[dependencies]
bitflags = "1.0"
cfg-if = "0.1"
bitflags = "0.9"
foreign-types = "0.3.1"
lazy_static = "1"
libc = "0.2"
openssl-sys = { version = "0.9.50", path = "../openssl-sys" }
openssl-sys = { version = "0.9.23", path = "../openssl-sys" }
[dev-dependencies]
tempdir = "0.3"
hex = "0.3"
winapi = "0.2"
ws2_32-sys = "0.2"
hex = "0.2"
data-encoding = "2.0"

View File

@ -1,6 +1,21 @@
use std::env;
fn main() {
match env::var("DEP_OPENSSL_VERSION") {
Ok(ref v) if v == "101" => {
println!("cargo:rustc-cfg=ossl101");
println!("cargo:rustc-cfg=ossl10x");
}
Ok(ref v) if v == "102" => {
println!("cargo:rustc-cfg=ossl102");
println!("cargo:rustc-cfg=ossl10x");
}
Ok(ref v) if v == "110" => {
println!("cargo:rustc-cfg=ossl110");
}
_ => panic!("Unable to detect OpenSSL version"),
}
if let Ok(_) = env::var("DEP_OPENSSL_LIBRESSL") {
println!("cargo:rustc-cfg=libressl");
}
@ -14,52 +29,4 @@ fn main() {
println!("cargo:rustc-cfg=osslconf=\"{}\"", var);
}
}
if let Ok(version) = env::var("DEP_OPENSSL_VERSION_NUMBER") {
let version = u64::from_str_radix(&version, 16).unwrap();
if version >= 0x1_00_01_00_0 {
println!("cargo:rustc-cfg=ossl101");
}
if version >= 0x1_00_02_00_0 {
println!("cargo:rustc-cfg=ossl102");
}
if version >= 0x1_01_00_00_0 {
println!("cargo:rustc-cfg=ossl110");
}
if version >= 0x1_01_00_07_0 {
println!("cargo:rustc-cfg=ossl110g");
}
if version >= 0x1_01_01_00_0 {
println!("cargo:rustc-cfg=ossl111");
}
}
if let Ok(version) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") {
let version = u64::from_str_radix(&version, 16).unwrap();
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");
}
}
}

View File

@ -4,19 +4,18 @@
extern crate openssl;
use openssl::asn1::Asn1Time;
use openssl::bn::{BigNum, MsbOption};
use openssl::bn::{BigNum, MSB_MAYBE_ZERO};
use openssl::error::ErrorStack;
use openssl::hash::MessageDigest;
use openssl::pkey::{PKey, PKeyRef, Private};
use openssl::pkey::{PKey, PKeyRef};
use openssl::rsa::Rsa;
use openssl::x509::extension::{
AuthorityKeyIdentifier, BasicConstraints, KeyUsage, SubjectAlternativeName,
SubjectKeyIdentifier,
};
use openssl::x509::{X509NameBuilder, X509Ref, X509Req, X509ReqBuilder, X509VerifyResult, X509};
use openssl::x509::{X509, X509Ref};
use openssl::x509::{X509NameBuilder, X509Req, X509ReqBuilder};
use openssl::x509::extension::{AuthorityKeyIdentifier, BasicConstraints, KeyUsage,
SubjectAlternativeName, SubjectKeyIdentifier};
/// Make a CA certificate and private key
fn mk_ca_cert() -> Result<(X509, PKey<Private>), ErrorStack> {
fn mk_ca_cert() -> Result<(X509, PKey), ErrorStack> {
let rsa = Rsa::generate(2048)?;
let privkey = PKey::from_rsa(rsa)?;
@ -31,7 +30,7 @@ fn mk_ca_cert() -> Result<(X509, PKey<Private>), ErrorStack> {
cert_builder.set_version(2)?;
let serial_number = {
let mut serial = BigNum::new()?;
serial.rand(159, MsbOption::MAYBE_ZERO, false)?;
serial.rand(159, MSB_MAYBE_ZERO, false)?;
serial.to_asn1_integer()?
};
cert_builder.set_serial_number(&serial_number)?;
@ -44,13 +43,11 @@ fn mk_ca_cert() -> Result<(X509, PKey<Private>), ErrorStack> {
cert_builder.set_not_after(&not_after)?;
cert_builder.append_extension(BasicConstraints::new().critical().ca().build()?)?;
cert_builder.append_extension(
KeyUsage::new()
.critical()
.key_cert_sign()
.crl_sign()
.build()?,
)?;
cert_builder.append_extension(KeyUsage::new()
.critical()
.key_cert_sign()
.crl_sign()
.build()?)?;
let subject_key_identifier =
SubjectKeyIdentifier::new().build(&cert_builder.x509v3_context(None, None))?;
@ -63,7 +60,7 @@ fn mk_ca_cert() -> Result<(X509, PKey<Private>), ErrorStack> {
}
/// Make a X509 request with the given private key
fn mk_request(privkey: &PKey<Private>) -> Result<X509Req, ErrorStack> {
fn mk_request(privkey: &PKey) -> Result<(X509Req), ErrorStack> {
let mut req_builder = X509ReqBuilder::new()?;
req_builder.set_pubkey(&privkey)?;
@ -81,10 +78,7 @@ fn mk_request(privkey: &PKey<Private>) -> Result<X509Req, ErrorStack> {
}
/// Make a certificate and private key signed by the given CA cert and private key
fn mk_ca_signed_cert(
ca_cert: &X509Ref,
ca_privkey: &PKeyRef<Private>,
) -> Result<(X509, PKey<Private>), ErrorStack> {
fn mk_ca_signed_cert(ca_cert: &X509Ref, ca_privkey: &PKeyRef) -> Result<(X509, PKey), ErrorStack> {
let rsa = Rsa::generate(2048)?;
let privkey = PKey::from_rsa(rsa)?;
@ -94,7 +88,7 @@ fn mk_ca_signed_cert(
cert_builder.set_version(2)?;
let serial_number = {
let mut serial = BigNum::new()?;
serial.rand(159, MsbOption::MAYBE_ZERO, false)?;
serial.rand(159, MSB_MAYBE_ZERO, false)?;
serial.to_asn1_integer()?
};
cert_builder.set_serial_number(&serial_number)?;
@ -108,17 +102,15 @@ fn mk_ca_signed_cert(
cert_builder.append_extension(BasicConstraints::new().build()?)?;
cert_builder.append_extension(
KeyUsage::new()
.critical()
.non_repudiation()
.digital_signature()
.key_encipherment()
.build()?,
)?;
cert_builder.append_extension(KeyUsage::new()
.critical()
.non_repudiation()
.digital_signature()
.key_encipherment()
.build()?)?;
let subject_key_identifier =
SubjectKeyIdentifier::new().build(&cert_builder.x509v3_context(Some(ca_cert), None))?;
let subject_key_identifier = SubjectKeyIdentifier::new()
.build(&cert_builder.x509v3_context(Some(ca_cert), None))?;
cert_builder.append_extension(subject_key_identifier)?;
let auth_key_identifier = AuthorityKeyIdentifier::new()
@ -145,8 +137,8 @@ fn real_main() -> Result<(), ErrorStack> {
// Verify that this cert was issued by this ca
match ca_cert.issued(&cert) {
X509VerifyResult::OK => println!("Certificate verified!"),
ver_err => println!("Failed to verify certificate: {}", ver_err),
Err(ver_err) => println!("Failed to verify certificate: {}", ver_err),
Ok(()) => println!("Certificate verified!"),
};
Ok(())

View File

@ -1,7 +1,7 @@
//! Low level AES IGE and key wrapping functionality
//! Low level AES IGE functionality
//!
//! AES ECB, CBC, XTS, CTR, CFB, GCM and other conventional symmetric encryption
//! modes are found in [`symm`]. This is the implementation of AES IGE and key wrapping
//! modes are found in [`symm`]. This is the implementation of AES IGE.
//!
//! Advanced Encryption Standard (AES) provides symmetric key cipher that
//! the same key is used to encrypt and decrypt data. This implementation
@ -22,42 +22,33 @@
//!
//! # Examples
//!
//! ## AES IGE
//! ```rust
//! use openssl::aes::{AesKey, aes_ige};
//! # extern crate openssl;
//! extern crate hex;
//! use openssl::aes::{AesKey, KeyError, aes_ige};
//! use openssl::symm::Mode;
//! use hex::{FromHex, ToHex};
//!
//! let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
//! let plaintext = b"\x12\x34\x56\x78\x90\x12\x34\x56\x12\x34\x56\x78\x90\x12\x34\x56";
//! let mut iv = *b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\
//! \x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
//!
//! let key = AesKey::new_encrypt(key).unwrap();
//! let mut output = [0u8; 16];
//! aes_ige(plaintext, &mut output, &key, &mut iv, Mode::Encrypt);
//! assert_eq!(output, *b"\xa6\xad\x97\x4d\x5c\xea\x1d\x36\xd2\xf3\x67\x98\x09\x07\xed\x32");
//! ```
//!
//! ## Key wrapping
//! ```rust
//! use openssl::aes::{AesKey, unwrap_key, wrap_key};
//!
//! let kek = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
//! let key_to_wrap = b"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF";
//!
//! let enc_key = AesKey::new_encrypt(kek).unwrap();
//! let mut ciphertext = [0u8; 24];
//! wrap_key(&enc_key, None, &mut ciphertext, &key_to_wrap[..]).unwrap();
//! let dec_key = AesKey::new_decrypt(kek).unwrap();
//! let mut orig_key = [0u8; 16];
//! unwrap_key(&dec_key, None, &mut orig_key, &ciphertext[..]).unwrap();
//!
//! assert_eq!(&orig_key[..], &key_to_wrap[..]);
//! ```
//! fn decrypt() -> Result<(), KeyError> {
//! let raw_key = "000102030405060708090A0B0C0D0E0F";
//! let hex_cipher = "12345678901234561234567890123456";
//! let randomness = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
//! if let (Ok(key_as_u8), Ok(cipher_as_u8), Ok(mut iv_as_u8)) =
//! (Vec::from_hex(raw_key), Vec::from_hex(hex_cipher), Vec::from_hex(randomness)) {
//! let key = AesKey::new_encrypt(&key_as_u8)?;
//! let mut output = vec![0u8; cipher_as_u8.len()];
//! aes_ige(&cipher_as_u8, &mut output, &key, &mut iv_as_u8, Mode::Encrypt);
//! assert_eq!(output.to_hex(), "a6ad974d5cea1d36d2f367980907ed32");
//! }
//! Ok(())
//! }
//!
//! # fn main() {
//! # decrypt();
//! # }
use ffi;
use libc::{c_int, c_uint};
use std::{mem, ptr};
use std::mem;
use libc::c_int;
use symm::Mode;
@ -156,87 +147,12 @@ pub fn aes_ige(in_: &[u8], out: &mut [u8], key: &AesKey, iv: &mut [u8], mode: Mo
}
}
/// Wrap a key, according to [RFC 3394](https://tools.ietf.org/html/rfc3394)
///
/// * `key`: The key-encrypting-key to use. Must be a encrypting key
/// * `iv`: The IV to use. You must use the same IV for both wrapping and unwrapping
/// * `out`: The output buffer to store the ciphertext
/// * `in_`: The input buffer, storing the key to be wrapped
///
/// Returns the number of bytes written into `out`
///
/// # Panics
///
/// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or if
/// `out` is not 8 bytes longer than `in_`
pub fn wrap_key(
key: &AesKey,
iv: Option<[u8; 8]>,
out: &mut [u8],
in_: &[u8],
) -> Result<usize, KeyError> {
unsafe {
assert!(out.len() >= in_.len() + 8); // Ciphertext is 64 bits longer (see 2.2.1)
let written = ffi::AES_wrap_key(
&key.0 as *const _ as *mut _, // this is safe, the implementation only uses the key as a const pointer.
iv.as_ref().map_or(ptr::null(), |iv| iv.as_ptr() as *const _),
out.as_ptr() as *mut _,
in_.as_ptr() as *const _,
in_.len() as c_uint,
);
if written <= 0 {
Err(KeyError(()))
} else {
Ok(written as usize)
}
}
}
/// Unwrap a key, according to [RFC 3394](https://tools.ietf.org/html/rfc3394)
///
/// * `key`: The key-encrypting-key to decrypt the wrapped key. Must be a decrypting key
/// * `iv`: The same IV used for wrapping the key
/// * `out`: The buffer to write the unwrapped key to
/// * `in_`: The input ciphertext
///
/// Returns the number of bytes written into `out`
///
/// # Panics
///
/// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or
/// if `in` is not 8 bytes longer than `in_`
pub fn unwrap_key(
key: &AesKey,
iv: Option<[u8; 8]>,
out: &mut [u8],
in_: &[u8],
) -> Result<usize, KeyError> {
unsafe {
assert!(out.len() + 8 <= in_.len());
let written = ffi::AES_unwrap_key(
&key.0 as *const _ as *mut _, // this is safe, the implementation only uses the key as a const pointer.
iv.as_ref().map_or(ptr::null(), |iv| iv.as_ptr() as *const _),
out.as_ptr() as *mut _,
in_.as_ptr() as *const _,
in_.len() as c_uint,
);
if written <= 0 {
Err(KeyError(()))
} else {
Ok(written as usize)
}
}
}
#[cfg(test)]
mod test {
use hex::FromHex;
use super::*;
use symm::Mode;
use super::*;
// From https://www.mgp25.com/AESIGE/
#[test]
@ -261,30 +177,4 @@ mod test {
aes_ige(&ct, &mut pt_actual, &key, &mut iv, Mode::Decrypt);
assert_eq!(pt_actual, pt);
}
// from the RFC https://tools.ietf.org/html/rfc3394#section-2.2.3
#[test]
fn test_wrap_unwrap() {
let raw_key = Vec::from_hex("000102030405060708090A0B0C0D0E0F").unwrap();
let key_data = Vec::from_hex("00112233445566778899AABBCCDDEEFF").unwrap();
let expected_ciphertext =
Vec::from_hex("1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5").unwrap();
let enc_key = AesKey::new_encrypt(&raw_key).unwrap();
let mut wrapped = [0; 24];
assert_eq!(
wrap_key(&enc_key, None, &mut wrapped, &key_data).unwrap(),
24
);
assert_eq!(&wrapped[..], &expected_ciphertext[..]);
let dec_key = AesKey::new_decrypt(&raw_key).unwrap();
let mut unwrapped = [0; 16];
assert_eq!(
unwrap_key(&dec_key, None, &mut unwrapped, &wrapped).unwrap(),
16
);
assert_eq!(&unwrapped[..], &key_data[..]);
}
}

View File

@ -26,19 +26,17 @@
//! ```
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_char, c_int, c_long};
use std::ffi::CString;
use libc::{c_long, c_char, c_int};
use std::fmt;
use std::ptr;
use std::slice;
use std::str;
use {cvt, cvt_p};
use bio::MemBio;
use bn::{BigNum, BigNumRef};
use error::ErrorStack;
use nid::Nid;
use string::OpensslString;
use {cvt, cvt_p};
foreign_type_and_impl_send_sync! {
type CType = ffi::ASN1_GENERALIZEDTIME;
@ -106,15 +104,6 @@ impl fmt::Display for Asn1TimeRef {
}
impl Asn1Time {
fn new() -> Result<Asn1Time, ErrorStack> {
ffi::init();
unsafe {
let handle = cvt_p(ffi::ASN1_TIME_new())?;
Ok(Asn1Time::from_ptr(handle))
}
}
fn from_period(period: c_long) -> Result<Asn1Time, ErrorStack> {
ffi::init();
@ -128,41 +117,6 @@ impl Asn1Time {
pub fn days_from_now(days: u32) -> Result<Asn1Time, ErrorStack> {
Asn1Time::from_period(days as c_long * 60 * 60 * 24)
}
/// Creates a new time corresponding to the specified ASN1 time string.
///
/// This corresponds to [`ASN1_TIME_set_string`].
///
/// [`ASN1_TIME_set_string`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html
pub fn from_str(s: &str) -> Result<Asn1Time, ErrorStack> {
unsafe {
let s = CString::new(s).unwrap();
let time = Asn1Time::new()?;
cvt(ffi::ASN1_TIME_set_string(time.as_ptr(), s.as_ptr()))?;
Ok(time)
}
}
/// Creates a new time corresponding to the specified X509 time string.
///
/// This corresponds to [`ASN1_TIME_set_string_X509`].
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// [`ASN1_TIME_set_string_X509`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html
#[cfg(ossl111)]
pub fn from_str_x509(s: &str) -> Result<Asn1Time, ErrorStack> {
unsafe {
let s = CString::new(s).unwrap();
let time = Asn1Time::new()?;
cvt(ffi::ASN1_TIME_set_string_X509(time.as_ptr(), s.as_ptr()))?;
Ok(time)
}
}
}
foreign_type_and_impl_send_sync! {
@ -207,7 +161,7 @@ impl Asn1StringRef {
///
/// [`as_utf8`]: struct.Asn1String.html#method.as_utf8
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr()), self.len()) }
unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr()), self.len()) }
}
/// Return the length of the Asn1String (number of bytes)
@ -236,38 +190,15 @@ foreign_type_and_impl_send_sync! {
pub struct Asn1IntegerRef;
}
impl Asn1Integer {
/// Converts a bignum to an `Asn1Integer`.
///
/// Corresponds to [`BN_to_ASN1_INTEGER`]. Also see
/// [`BigNumRef::to_asn1_integer`].
///
/// [`BN_to_ASN1_INTEGER`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_to_ASN1_INTEGER.html
/// [`BigNumRef::to_asn1_integer`]: ../bn/struct.BigNumRef.html#method.to_asn1_integer
pub fn from_bn(bn: &BigNumRef) -> Result<Self, ErrorStack> {
bn.to_asn1_integer()
}
}
impl Asn1IntegerRef {
#[allow(missing_docs)]
#[deprecated(since = "0.10.6", note = "use to_bn instead")]
/// Returns value of ASN.1 integer, or -1 if there is an error, and 0 if the integer is Null.
///
/// OpenSSL documentation at [`ASN1_INTEGER_get`].
///
/// [`ASN1_INTEGER_get`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_get.html
pub fn get(&self) -> i64 {
unsafe { ::ffi::ASN1_INTEGER_get(self.as_ptr()) as i64 }
}
/// Converts the integer to a `BigNum`.
///
/// This corresponds to [`ASN1_INTEGER_to_BN`].
///
/// [`ASN1_INTEGER_to_BN`]: https://www.openssl.org/docs/man1.1.0/crypto/ASN1_INTEGER_get.html
pub fn to_bn(&self) -> Result<BigNum, ErrorStack> {
unsafe {
cvt_p(::ffi::ASN1_INTEGER_to_BN(self.as_ptr(), ptr::null_mut()))
.map(|p| BigNum::from_ptr(p))
}
}
/// Sets the ASN.1 value to the value of a signed 32-bit integer, for larger numbers
/// see [`bn`].
///
@ -299,11 +230,11 @@ foreign_type_and_impl_send_sync! {
impl Asn1BitStringRef {
/// Returns the Asn1BitString as a slice
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) }
unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr() as *mut _), self.len()) }
}
/// Length of Asn1BitString in number of bytes.
pub fn len(&self) -> usize {
unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *const _) as usize }
unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *mut _) as usize }
}
}
@ -354,41 +285,11 @@ impl fmt::Display for Asn1ObjectRef {
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
use ffi::ASN1_STRING_get0_data;
} else {
#[allow(bad_style)]
unsafe fn ASN1_STRING_get0_data(s: *mut ffi::ASN1_STRING) -> *const ::libc::c_uchar {
ffi::ASN1_STRING_data(s)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use bn::BigNum;
/// Tests conversion between BigNum and Asn1Integer.
#[test]
fn bn_cvt() {
fn roundtrip(bn: BigNum) {
let large = Asn1Integer::from_bn(&bn).unwrap();
assert_eq!(large.to_bn().unwrap(), bn);
}
roundtrip(BigNum::from_dec_str("1000000000000000000000000000000000").unwrap());
roundtrip(-BigNum::from_dec_str("1000000000000000000000000000000000").unwrap());
roundtrip(BigNum::from_u32(1234).unwrap());
roundtrip(-BigNum::from_u32(1234).unwrap());
}
#[test]
fn time_from_str() {
Asn1Time::from_str("99991231235959Z").unwrap();
#[cfg(ossl111)]
Asn1Time::from_str_x509("99991231235959Z").unwrap();
}
#[cfg(any(ossl101, ossl102))]
use ffi::ASN1_STRING_data;
#[cfg(ossl110)]
#[allow(bad_style)]
unsafe fn ASN1_STRING_data(s: *mut ffi::ASN1_STRING) -> *mut ::libc::c_uchar {
ffi::ASN1_STRING_get0_data(s) as *mut _
}

View File

@ -1,8 +1,8 @@
use ffi;
use libc::c_int;
use std::marker::PhantomData;
use std::ptr;
use std::slice;
use libc::c_int;
use ffi;
use cvt_p;
use error::ErrorStack;
@ -66,19 +66,13 @@ impl MemBio {
slice::from_raw_parts(ptr as *const _ as *const _, len as usize)
}
}
pub unsafe fn from_ptr(bio: *mut ffi::BIO) -> MemBio {
MemBio(bio)
}
}
cfg_if! {
if #[cfg(ossl102)] {
use ffi::BIO_new_mem_buf;
} else {
#[allow(bad_style)]
unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO {
ffi::BIO_new_mem_buf(buf as *mut _, len)
}
}
#[cfg(not(ossl101))]
use ffi::BIO_new_mem_buf;
#[cfg(ossl101)]
#[allow(bad_style)]
unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO {
ffi::BIO_new_mem_buf(buf as *mut _, len)
}

View File

@ -12,17 +12,16 @@
//! use openssl::bn::BigNum;
//! use openssl::error::ErrorStack;
//!
//! fn bignums() -> Result<(), ErrorStack> {
//! fn bignums() -> Result< (), ErrorStack > {
//! let a = BigNum::new()?; // a = 0
//! let b = BigNum::from_dec_str("1234567890123456789012345")?;
//! let c = &a * &b;
//! assert_eq!(a, c);
//! assert_eq!(a,c);
//! Ok(())
//! }
//! # fn main() {
//! # bignums();
//! # }
//! ```
//!
//! [`BIGNUM`]: https://wiki.openssl.org/index.php/Manual:Bn_internal(3)
use ffi;
@ -30,56 +29,43 @@ use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use std::cmp::Ordering;
use std::ffi::CString;
use std::ops::{Add, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub};
use std::{fmt, ptr};
use std::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub, Deref};
use {cvt, cvt_p, cvt_n};
use asn1::Asn1Integer;
use error::ErrorStack;
use string::OpensslString;
use {cvt, cvt_n, cvt_p};
cfg_if! {
if #[cfg(ossl110)] {
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_6144, BN_get_rfc3526_prime_8192, 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,
get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096,
get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144,
get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192,
};
#[cfg(ossl10x)]
use ffi::{get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
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,
get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096,
get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144,
get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192};
#[allow(bad_style)]
unsafe fn BN_is_negative(bn: *const ffi::BIGNUM) -> c_int {
(*bn).neg
}
}
}
#[cfg(ossl110)]
use ffi::{BN_get_rfc2409_prime_768, BN_get_rfc2409_prime_1024, 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};
/// Options for the most significant bits of a randomly generated `BigNum`.
pub struct MsbOption(c_int);
impl MsbOption {
/// The most significant bit of the number may be 0.
pub const MAYBE_ZERO: MsbOption = MsbOption(-1);
/// The most significant bit of the number may be 0.
pub const MSB_MAYBE_ZERO: MsbOption = MsbOption(-1);
/// The most significant bit of the number must be 1.
pub const ONE: MsbOption = MsbOption(0);
/// The most significant bit of the number must be 1.
pub const MSB_ONE: MsbOption = MsbOption(0);
/// The most significant two bits of the number must be 1.
///
/// The number of bits in the product of two such numbers will always be exactly twice the
/// number of bits in the original numbers.
pub const TWO_ONES: MsbOption = MsbOption(1);
}
/// The most significant two bits of the number must be 1.
///
/// The number of bits in the product of two such numbers will always be exactly twice the number
/// of bits in the original numbers.
pub const TWO_MSB_ONE: MsbOption = MsbOption(1);
foreign_type_and_impl_send_sync! {
type CType = ffi::BN_CTX;
@ -120,7 +106,7 @@ foreign_type_and_impl_send_sync! {
/// Dynamically sized large number impelementation
///
/// Perform large number mathematics. Create a new BigNum
/// with [`new`]. Perform standard mathematics on large numbers using
/// with [`new`]. Perform stanard mathematics on large numbers using
/// methods from [`Dref<Target = BigNumRef>`]
///
/// OpenSSL documenation at [`BN_new`].
@ -372,7 +358,17 @@ impl BigNumRef {
/// Returns `true` if `self` is negative.
pub fn is_negative(&self) -> bool {
unsafe { BN_is_negative(self.as_ptr()) == 1 }
self._is_negative()
}
#[cfg(ossl10x)]
fn _is_negative(&self) -> bool {
unsafe { (*self.as_ptr()).neg == 1 }
}
#[cfg(ossl110)]
fn _is_negative(&self) -> bool {
unsafe { ffi::BN_is_negative(self.as_ptr()) == 1 }
}
/// Returns the number of significant bits in `self`.
@ -400,14 +396,14 @@ impl BigNumRef {
/// # Examples
///
/// ```
/// use openssl::bn::{BigNum, MsbOption};
/// use openssl::bn::{BigNum,MSB_MAYBE_ZERO};
/// use openssl::error::ErrorStack;
///
/// fn generate_random() -> Result< BigNum, ErrorStack > {
/// let mut big = BigNum::new()?;
///
/// // Generates a 128-bit odd random number
/// big.rand(128, MsbOption::MAYBE_ZERO, true);
/// big.rand(128, MSB_MAYBE_ZERO, true);
/// Ok((big))
/// }
/// ```
@ -423,8 +419,7 @@ impl BigNumRef {
bits.into(),
msb.0,
odd as c_int,
))
.map(|_| ())
)).map(|_| ())
}
}
@ -440,8 +435,7 @@ impl BigNumRef {
bits.into(),
msb.0,
odd as c_int,
))
.map(|_| ())
)).map(|_| ())
}
}
@ -487,8 +481,7 @@ impl BigNumRef {
add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
ptr::null_mut(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -511,8 +504,7 @@ impl BigNumRef {
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -536,8 +528,7 @@ impl BigNumRef {
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -559,8 +550,7 @@ impl BigNumRef {
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -583,8 +573,7 @@ impl BigNumRef {
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -615,8 +604,7 @@ impl BigNumRef {
a.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -639,8 +627,7 @@ impl BigNumRef {
b.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -663,8 +650,7 @@ impl BigNumRef {
b.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -687,8 +673,7 @@ impl BigNumRef {
b.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -709,8 +694,7 @@ impl BigNumRef {
a.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -731,8 +715,7 @@ impl BigNumRef {
a.as_ptr(),
p.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -755,8 +738,7 @@ impl BigNumRef {
p.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -773,8 +755,7 @@ impl BigNumRef {
a.as_ptr(),
n.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -795,8 +776,7 @@ impl BigNumRef {
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -819,8 +799,7 @@ impl BigNumRef {
checks.into(),
ctx.as_ptr(),
ptr::null_mut(),
))
.map(|r| r != 0)
)).map(|r| r != 0)
}
}
@ -850,8 +829,7 @@ impl BigNumRef {
ctx.as_ptr(),
do_trial_division as c_int,
ptr::null_mut(),
))
.map(|r| r != 0)
)).map(|r| r != 0)
}
}
@ -1107,8 +1085,7 @@ impl BigNum {
n.as_ptr(),
n.len() as c_int,
ptr::null_mut(),
))
.map(|p| BigNum::from_ptr(p))
)).map(|p| BigNum::from_ptr(p))
}
}
}
@ -1238,7 +1215,7 @@ macro_rules! delegate {
$t::$m(self.deref(), oth.deref())
}
}
};
}
}
impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
@ -1368,7 +1345,7 @@ impl Neg for BigNum {
#[cfg(test)]
mod tests {
use bn::{BigNum, BigNumContext};
use bn::{BigNumContext, BigNum};
#[test]
fn test_to_from_slice() {

View File

@ -8,44 +8,15 @@
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use std::ptr;
use error::ErrorStack;
use bio::{MemBio, MemBioSlice};
use error::ErrorStack;
use libc::c_uint;
use pkey::{HasPrivate, PKeyRef};
use stack::StackRef;
use x509::{X509Ref, X509};
use symm::Cipher;
use {cvt, cvt_p};
bitflags! {
pub struct CMSOptions : c_uint {
const TEXT = ffi::CMS_TEXT;
const CMS_NOCERTS = ffi::CMS_NOCERTS;
const NO_CONTENT_VERIFY = ffi::CMS_NO_CONTENT_VERIFY;
const NO_ATTR_VERIFY = ffi::CMS_NO_ATTR_VERIFY;
const NOSIGS = ffi::CMS_NOSIGS;
const NOINTERN = ffi::CMS_NOINTERN;
const NO_SIGNER_CERT_VERIFY = ffi::CMS_NO_SIGNER_CERT_VERIFY;
const NOVERIFY = ffi::CMS_NOVERIFY;
const DETACHED = ffi::CMS_DETACHED;
const BINARY = ffi::CMS_BINARY;
const NOATTR = ffi::CMS_NOATTR;
const NOSMIMECAP = ffi::CMS_NOSMIMECAP;
const NOOLDMIMETYPE = ffi::CMS_NOOLDMIMETYPE;
const CRLFEOL = ffi::CMS_CRLFEOL;
const STREAM = ffi::CMS_STREAM;
const NOCRL = ffi::CMS_NOCRL;
const PARTIAL = ffi::CMS_PARTIAL;
const REUSE_DIGEST = ffi::CMS_REUSE_DIGEST;
const USE_KEYID = ffi::CMS_USE_KEYID;
const DEBUG_DECRYPT = ffi::CMS_DEBUG_DECRYPT;
#[cfg(all(not(libressl), not(ossl101)))]
const KEY_PARAM = ffi::CMS_KEY_PARAM;
#[cfg(all(not(libressl), not(ossl101), not(ossl102)))]
const ASCIICRLF = ffi::CMS_ASCIICRLF;
}
}
use x509::X509;
use pkey::PKeyRef;
use cvt;
use cvt_p;
foreign_type_and_impl_send_sync! {
type CType = ffi::CMS_ContentInfo;
@ -73,10 +44,7 @@ impl CmsContentInfoRef {
/// OpenSSL documentation at [`CMS_decrypt`]
///
/// [`CMS_decrypt`]: https://www.openssl.org/docs/man1.1.0/crypto/CMS_decrypt.html
pub fn decrypt<T>(&self, pkey: &PKeyRef<T>, cert: &X509) -> Result<Vec<u8>, ErrorStack>
where
T: HasPrivate,
{
pub fn decrypt(&self, pkey: &PKeyRef, cert: &X509) -> Result<Vec<u8>, ErrorStack> {
unsafe {
let pkey = pkey.as_ptr();
let cert = cert.as_ptr();
@ -96,25 +64,6 @@ impl CmsContentInfoRef {
}
}
to_der! {
/// Serializes this CmsContentInfo using DER.
///
/// OpenSSL documentation at [`i2d_CMS_ContentInfo`]
///
/// [`i2d_CMS_ContentInfo`]: https://www.openssl.org/docs/man1.0.2/crypto/i2d_CMS_ContentInfo.html
to_der,
ffi::i2d_CMS_ContentInfo
}
to_pem! {
/// Serializes this CmsContentInfo using DER.
///
/// OpenSSL documentation at [`PEM_write_bio_CMS`]
///
/// [`PEM_write_bio_CMS`]: https://www.openssl.org/docs/man1.1.0/man3/PEM_write_bio_CMS.html
to_pem,
ffi::PEM_write_bio_CMS
}
}
impl CmsContentInfo {
@ -127,144 +76,12 @@ impl CmsContentInfo {
unsafe {
let bio = MemBioSlice::new(smime)?;
let cms = cvt_p(ffi::SMIME_read_CMS(bio.as_ptr(), ptr::null_mut()))?;
Ok(CmsContentInfo::from_ptr(cms))
}
}
from_der! {
/// Deserializes a DER-encoded ContentInfo structure.
///
/// This corresponds to [`d2i_CMS_ContentInfo`].
///
/// [`d2i_CMS_ContentInfo`]: https://www.openssl.org/docs/manmaster/man3/d2i_X509.html
from_der,
CmsContentInfo,
ffi::d2i_CMS_ContentInfo
}
from_pem! {
/// Deserializes a PEM-encoded ContentInfo structure.
///
/// This corresponds to [`PEM_read_bio_CMS`].
///
/// [`PEM_read_bio_CMS`]: https://www.openssl.org/docs/man1.1.0/man3/PEM_read_bio_CMS.html
from_pem,
CmsContentInfo,
ffi::PEM_read_bio_CMS
}
/// Given a signing cert `signcert`, private key `pkey`, a certificate stack `certs`,
/// data `data` and flags `flags`, create a CmsContentInfo struct.
///
/// All arguments are optional.
///
/// OpenSSL documentation at [`CMS_sign`]
///
/// [`CMS_sign`]: https://www.openssl.org/docs/manmaster/man3/CMS_sign.html
pub fn sign<T>(
signcert: Option<&X509Ref>,
pkey: Option<&PKeyRef<T>>,
certs: Option<&StackRef<X509>>,
data: Option<&[u8]>,
flags: CMSOptions,
) -> Result<CmsContentInfo, ErrorStack>
where
T: HasPrivate,
{
unsafe {
let signcert = signcert.map_or(ptr::null_mut(), |p| p.as_ptr());
let pkey = pkey.map_or(ptr::null_mut(), |p| p.as_ptr());
let data_bio = match data {
Some(data) => Some(MemBioSlice::new(data)?),
None => None,
};
let data_bio_ptr = data_bio.as_ref().map_or(ptr::null_mut(), |p| p.as_ptr());
let certs = certs.map_or(ptr::null_mut(), |p| p.as_ptr());
let cms = cvt_p(ffi::CMS_sign(
signcert,
pkey,
certs,
data_bio_ptr,
flags.bits(),
))?;
Ok(CmsContentInfo::from_ptr(cms))
}
}
/// Given a certificate stack `certs`, data `data`, cipher `cipher` and flags `flags`,
/// create a CmsContentInfo struct.
///
/// OpenSSL documentation at [`CMS_encrypt`]
///
/// [`CMS_encrypt`]: https://www.openssl.org/docs/manmaster/man3/CMS_encrypt.html
pub fn encrypt(
certs: &StackRef<X509>,
data: &[u8],
cipher: Cipher,
flags: CMSOptions,
) -> Result<CmsContentInfo, ErrorStack>
{
unsafe {
let data_bio = MemBioSlice::new(data)?;
let cms = cvt_p(ffi::CMS_encrypt(
certs.as_ptr(),
data_bio.as_ptr(),
cipher.as_ptr(),
flags.bits(),
let cms = cvt_p(ffi::SMIME_read_CMS(
bio.as_ptr(),
ptr::null_mut(),
))?;
Ok(CmsContentInfo::from_ptr(cms))
}
}
}
#[cfg(test)]
mod test {
use super::*;
use stack::Stack;
use x509::X509;
use pkcs12::Pkcs12;
#[test]
fn cms_encrypt_decrypt() {
// load cert with public key only
let pub_cert_bytes = include_bytes!("../test/cms_pubkey.der");
let pub_cert = X509::from_der(pub_cert_bytes).expect("failed to load pub cert");
// load cert with private key
let priv_cert_bytes = include_bytes!("../test/cms.p12");
let priv_cert = Pkcs12::from_der(priv_cert_bytes).expect("failed to load priv cert");
let priv_cert = priv_cert.parse("mypass").expect("failed to parse priv cert");
// encrypt cms message using public key cert
let input = String::from("My Message");
let mut cert_stack = Stack::new().expect("failed to create stack");
cert_stack.push(pub_cert).expect("failed to add pub cert to stack");
let encrypt = CmsContentInfo::encrypt(&cert_stack, &input.as_bytes(), Cipher::des_ede3_cbc(), CMSOptions::empty())
.expect("failed create encrypted cms");
// decrypt cms message using private key cert (DER)
{
let encrypted_der = encrypt.to_der().expect("failed to create der from cms");
let decrypt = CmsContentInfo::from_der(&encrypted_der).expect("failed read cms from der");
let decrypt = decrypt.decrypt(&priv_cert.pkey, &priv_cert.cert).expect("failed to decrypt cms");
let decrypt = String::from_utf8(decrypt).expect("failed to create string from cms content");
assert_eq!(input, decrypt);
}
// decrypt cms message using private key cert (PEM)
{
let encrypted_pem = encrypt.to_pem().expect("failed to create pem from cms");
let decrypt = CmsContentInfo::from_pem(&encrypted_pem).expect("failed read cms from pem");
let decrypt = decrypt.decrypt(&priv_cert.pkey, &priv_cert.cert).expect("failed to decrypt cms");
let decrypt = String::from_utf8(decrypt).expect("failed to create string from cms content");
assert_eq!(input, decrypt);
}
}
}

6
openssl/src/crypto.rs Normal file
View File

@ -0,0 +1,6 @@
#![doc(hidden)]
#![deprecated(since = "0.9.20")]
use string::OpensslString;
#[deprecated(note = "renamed to OpensslString", since = "0.9.7")]
pub type CryptoString = OpensslString;

View File

@ -1,124 +0,0 @@
//! Shared secret derivation.
use ffi;
use foreign_types::ForeignTypeRef;
use std::marker::PhantomData;
use std::ptr;
use error::ErrorStack;
use pkey::{HasPrivate, HasPublic, PKeyRef};
use {cvt, cvt_p};
/// 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> {}
impl<'a> Deriver<'a> {
/// Creates a new `Deriver` using the provided private key.
///
/// This corresponds to [`EVP_PKEY_derive_init`].
///
/// [`EVP_PKEY_derive_init`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_derive_init.html
pub fn new<T>(key: &'a PKeyRef<T>) -> Result<Deriver<'a>, ErrorStack>
where
T: HasPrivate,
{
unsafe {
cvt_p(ffi::EVP_PKEY_CTX_new(key.as_ptr(), ptr::null_mut()))
.map(|p| Deriver(p, PhantomData))
.and_then(|ctx| cvt(ffi::EVP_PKEY_derive_init(ctx.0)).map(|_| ctx))
}
}
/// Sets the peer key used for secret derivation.
///
/// This corresponds to [`EVP_PKEY_derive_set_peer`]:
///
/// [`EVP_PKEY_derive_set_peer`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_derive_init.html
pub fn set_peer<T>(&mut self, key: &'a PKeyRef<T>) -> Result<(), ErrorStack>
where
T: HasPublic,
{
unsafe { cvt(ffi::EVP_PKEY_derive_set_peer(self.0, key.as_ptr())).map(|_| ()) }
}
/// Returns the size of the shared secret.
///
/// It can be used to size the buffer passed to [`Deriver::derive`].
///
/// This corresponds to [`EVP_PKEY_derive`].
///
/// [`Deriver::derive`]: #method.derive
/// [`EVP_PKEY_derive`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_derive_init.html
pub fn len(&mut self) -> Result<usize, ErrorStack> {
unsafe {
let mut len = 0;
cvt(ffi::EVP_PKEY_derive(self.0, ptr::null_mut(), &mut len)).map(|_| len)
}
}
/// Derives a shared secret between the two keys, writing it into the buffer.
///
/// Returns the number of bytes written.
///
/// This corresponds to [`EVP_PKEY_derive`].
///
/// [`EVP_PKEY_derive`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_PKEY_derive_init.html
pub fn derive(&mut self, buf: &mut [u8]) -> Result<usize, ErrorStack> {
let mut len = buf.len();
unsafe {
cvt(ffi::EVP_PKEY_derive(
self.0,
buf.as_mut_ptr() as *mut _,
&mut len,
))
.map(|_| len)
}
}
/// A convenience function which derives a shared secret and returns it in a new buffer.
///
/// This simply wraps [`Deriver::len`] and [`Deriver::derive`].
///
/// [`Deriver::len`]: #method.len
/// [`Deriver::derive`]: #method.derive
pub fn derive_to_vec(&mut self) -> Result<Vec<u8>, ErrorStack> {
let len = self.len()?;
let mut buf = vec![0; len];
let len = self.derive(&mut buf)?;
buf.truncate(len);
Ok(buf)
}
}
#[cfg(test)]
mod test {
use super::*;
use ec::{EcGroup, EcKey};
use nid::Nid;
use pkey::PKey;
#[test]
fn derive_without_peer() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let ec_key = EcKey::generate(&group).unwrap();
let pkey = PKey::from_ec_key(ec_key).unwrap();
let mut deriver = Deriver::new(&pkey).unwrap();
deriver.derive_to_vec().unwrap_err();
}
#[test]
fn test_ec_key_derive() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let ec_key = EcKey::generate(&group).unwrap();
let ec_key2 = EcKey::generate(&group).unwrap();
let pkey = PKey::from_ec_key(ec_key).unwrap();
let pkey2 = PKey::from_ec_key(ec_key2).unwrap();
let mut deriver = Deriver::new(&pkey).unwrap();
deriver.set_peer(&pkey2).unwrap();
let shared = deriver.derive_to_vec().unwrap();
assert!(!shared.is_empty());
}
}

View File

@ -1,138 +1,104 @@
use error::ErrorStack;
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use foreign_types::ForeignTypeRef;
use std::mem;
use std::ptr;
use bn::BigNum;
use pkey::{HasParams, Params};
use {cvt, cvt_p};
use bn::BigNum;
generic_foreign_type_and_impl_send_sync! {
foreign_type_and_impl_send_sync! {
type CType = ffi::DH;
fn drop = ffi::DH_free;
pub struct Dh<T>;
pub struct Dh;
pub struct DhRef<T>;
pub struct DhRef;
}
impl<T> DhRef<T>
where
T: HasParams,
{
to_pem! {
/// Serializes the parameters into a PEM-encoded PKCS#3 DHparameter structure.
///
/// The output will have a header of `-----BEGIN DH PARAMETERS-----`.
///
/// This corresponds to [`PEM_write_bio_DHparams`].
///
/// [`PEM_write_bio_DHparams`]: https://www.openssl.org/docs/manmaster/man3/PEM_write_bio_DHparams.html
params_to_pem,
ffi::PEM_write_bio_DHparams
}
to_der! {
/// Serializes the parameters into a DER-encoded PKCS#3 DHparameter structure.
///
/// This corresponds to [`i2d_DHparams`].
///
/// [`i2d_DHparams`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_DHparams.html
params_to_der,
ffi::i2d_DHparams
}
impl DhRef {
to_pem!(ffi::PEM_write_bio_DHparams);
to_der!(ffi::i2d_DHparams);
}
impl Dh<Params> {
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<Dh<Params>, ErrorStack> {
impl Dh {
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<Dh, ErrorStack> {
unsafe {
let dh = Dh::from_ptr(cvt_p(ffi::DH_new())?);
cvt(DH_set0_pqg(dh.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
let dh = Dh(cvt_p(ffi::DH_new())?);
cvt(compat::DH_set0_pqg(
dh.0,
p.as_ptr(),
q.as_ptr(),
g.as_ptr(),
))?;
mem::forget((p, g, q));
Ok(dh)
}
}
from_pem! {
/// Deserializes a PEM-encoded PKCS#3 DHpararameters structure.
///
/// The input should have a header of `-----BEGIN DH PARAMETERS-----`.
///
/// This corresponds to [`PEM_read_bio_DHparams`].
///
/// [`PEM_read_bio_DHparams`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_read_bio_DHparams.html
params_from_pem,
Dh<Params>,
ffi::PEM_read_bio_DHparams
}
from_pem!(Dh, ffi::PEM_read_bio_DHparams);
from_der!(Dh, ffi::d2i_DHparams);
from_der! {
/// Deserializes a DER-encoded PKCS#3 DHparameters structure.
///
/// This corresponds to [`d2i_DHparams`].
///
/// [`d2i_DHparams`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_DHparams.html
params_from_der,
Dh<Params>,
ffi::d2i_DHparams
}
/// Requires OpenSSL 1.0.2 or newer.
#[cfg(any(ossl102, ossl110))]
pub fn get_1024_160() -> Result<Dh<Params>, ErrorStack> {
/// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0.
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
pub fn get_1024_160() -> Result<Dh, ErrorStack> {
unsafe {
ffi::init();
cvt_p(ffi::DH_get_1024_160()).map(|p| Dh::from_ptr(p))
cvt_p(ffi::DH_get_1024_160()).map(Dh)
}
}
/// Requires OpenSSL 1.0.2 or newer.
#[cfg(any(ossl102, ossl110))]
pub fn get_2048_224() -> Result<Dh<Params>, ErrorStack> {
/// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0.
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
pub fn get_2048_224() -> Result<Dh, ErrorStack> {
unsafe {
ffi::init();
cvt_p(ffi::DH_get_2048_224()).map(|p| Dh::from_ptr(p))
cvt_p(ffi::DH_get_2048_224()).map(Dh)
}
}
/// Requires OpenSSL 1.0.2 or newer.
#[cfg(any(ossl102, ossl110))]
pub fn get_2048_256() -> Result<Dh<Params>, ErrorStack> {
/// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0.
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
pub fn get_2048_256() -> Result<Dh, ErrorStack> {
unsafe {
ffi::init();
cvt_p(ffi::DH_get_2048_256()).map(|p| Dh::from_ptr(p))
cvt_p(ffi::DH_get_2048_256()).map(Dh)
}
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
use ffi::DH_set0_pqg;
} else {
#[allow(bad_style)]
unsafe fn DH_set0_pqg(
dh: *mut ffi::DH,
p: *mut ffi::BIGNUM,
q: *mut ffi::BIGNUM,
g: *mut ffi::BIGNUM,
) -> ::libc::c_int {
(*dh).p = p;
(*dh).q = q;
(*dh).g = g;
1
}
#[cfg(ossl110)]
mod compat {
pub use ffi::DH_set0_pqg;
}
#[cfg(ossl10x)]
#[allow(bad_style)]
mod compat {
use ffi;
use libc::c_int;
pub unsafe fn DH_set0_pqg(
dh: *mut ffi::DH,
p: *mut ffi::BIGNUM,
q: *mut ffi::BIGNUM,
g: *mut ffi::BIGNUM,
) -> c_int {
(*dh).p = p;
(*dh).q = q;
(*dh).g = g;
1
}
}
#[cfg(test)]
mod tests {
use bn::BigNum;
use dh::Dh;
use ssl::{SslContext, SslMethod};
use bn::BigNum;
use ssl::{SslMethod, SslContext};
#[test]
#[cfg(any(ossl102, ossl110))]
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
fn test_dh_rfc5114() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
let dh1 = Dh::get_1024_160().unwrap();
@ -147,25 +113,31 @@ mod tests {
fn test_dh() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
let p = BigNum::from_hex_str(
"87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF\
4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B47\
58C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B6\
3ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5\
140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710\
C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597",
"87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435\
E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF429\
6D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C02\
2E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF1230\
7F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9\
A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251C\
CACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE\
621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D227\
6E11715F693877FAD7EF09CADB094AE91E1A1597",
).unwrap();
let g = BigNum::from_hex_str(
"3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED\
4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A\
57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5\
045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E\
052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67E\
B6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659",
"3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0\
BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773\
BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2D\
DF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428E\
BC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BF\
FE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7\
D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92\
B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148\
D47954515E2327CFEF98C582664B4C0F6CC41659",
).unwrap();
let q = BigNum::from_hex_str(
"8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3",
)
.unwrap();
"8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F\
5FBD3",
).unwrap();
let dh = Dh::from_params(p, g, q).unwrap();
ctx.set_tmp_dh(&dh).unwrap();
}
@ -174,15 +146,15 @@ mod tests {
fn test_dh_from_pem() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
let params = include_bytes!("../test/dhparams.pem");
let dh = Dh::params_from_pem(params).unwrap();
let dh = Dh::from_pem(params).unwrap();
ctx.set_tmp_dh(&dh).unwrap();
}
#[test]
fn test_dh_from_der() {
let params = include_bytes!("../test/dhparams.pem");
let dh = Dh::params_from_pem(params).unwrap();
let der = dh.params_to_der().unwrap();
Dh::params_from_der(&der).unwrap();
let dh = Dh::from_pem(params).unwrap();
let der = dh.to_der().unwrap();
Dh::from_der(&der).unwrap();
}
}

View File

@ -6,18 +6,18 @@
//! without the private key.
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use foreign_types::ForeignTypeRef;
use libc::{c_int, c_char, c_void};
use std::fmt;
use std::mem;
use std::ptr;
use bn::{BigNum, BigNumRef};
use error::ErrorStack;
use pkey::{HasParams, HasPrivate, HasPublic, Private, Public};
use {cvt, cvt_p};
use bio::MemBioSlice;
use bn::BigNumRef;
use error::ErrorStack;
use util::{CallbackState, invoke_passwd_cb_old};
generic_foreign_type_and_impl_send_sync! {
foreign_type_and_impl_send_sync! {
type CType = ffi::DSA;
fn drop = ffi::DSA_free;
@ -42,9 +42,7 @@ generic_foreign_type_and_impl_send_sync! {
/// ```
/// use openssl::dsa::Dsa;
/// use openssl::error::ErrorStack;
/// use openssl::pkey::Private;
///
/// fn create_dsa() -> Result<Dsa<Private>, ErrorStack> {
/// fn create_dsa() -> Result< Dsa, ErrorStack > {
/// let sign = Dsa::generate(2048)?;
/// Ok(sign)
/// }
@ -52,155 +50,98 @@ generic_foreign_type_and_impl_send_sync! {
/// # create_dsa();
/// # }
/// ```
pub struct Dsa<T>;
pub struct Dsa;
/// Reference to [`Dsa`].
///
/// [`Dsa`]: struct.Dsa.html
pub struct DsaRef<T>;
pub struct DsaRef;
}
impl<T> Clone for Dsa<T> {
fn clone(&self) -> Dsa<T> {
(**self).to_owned()
}
}
impl DsaRef {
private_key_to_pem!(ffi::PEM_write_bio_DSAPrivateKey);
public_key_to_pem!(ffi::PEM_write_bio_DSA_PUBKEY);
impl<T> ToOwned for DsaRef<T> {
type Owned = Dsa<T>;
private_key_to_der!(ffi::i2d_DSAPrivateKey);
public_key_to_der!(ffi::i2d_DSAPublicKey);
fn to_owned(&self) -> Dsa<T> {
unsafe {
ffi::DSA_up_ref(self.as_ptr());
Dsa::from_ptr(self.as_ptr())
}
}
}
impl<T> DsaRef<T>
where
T: HasPublic,
{
private_key_to_pem! {
/// Serializes the private key to a PEM-encoded DSAPrivateKey structure.
///
/// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`.
///
/// This corresponds to [`PEM_write_bio_DSAPrivateKey`].
///
/// [`PEM_write_bio_DSAPrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_DSAPrivateKey.html
private_key_to_pem,
/// Serializes the private key to a PEM-encoded encrypted DSAPrivateKey structure.
///
/// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`.
///
/// This corresponds to [`PEM_write_bio_DSAPrivateKey`].
///
/// [`PEM_write_bio_DSAPrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_DSAPrivateKey.html
private_key_to_pem_passphrase,
ffi::PEM_write_bio_DSAPrivateKey
}
to_pem! {
/// Serialies the public key into a PEM-encoded SubjectPublicKeyInfo structure.
///
/// The output will have a header of `-----BEGIN PUBLIC KEY-----`.
///
/// This corresponds to [`PEM_write_bio_DSA_PUBKEY`].
///
/// [`PEM_write_bio_DSA_PUBKEY`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_DSA_PUBKEY.html
public_key_to_pem,
ffi::PEM_write_bio_DSA_PUBKEY
}
to_der! {
/// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure.
///
/// This corresponds to [`i2d_DSA_PUBKEY`].
///
/// [`i2d_DSA_PUBKEY`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_DSA_PUBKEY.html
public_key_to_der,
ffi::i2d_DSA_PUBKEY
}
/// Returns a reference to the public key component of `self`.
pub fn pub_key(&self) -> &BigNumRef {
unsafe {
let mut pub_key = ptr::null();
DSA_get0_key(self.as_ptr(), &mut pub_key, ptr::null_mut());
BigNumRef::from_ptr(pub_key as *mut _)
}
}
}
impl<T> DsaRef<T>
where
T: HasPrivate,
{
/// Returns a reference to the private key component of `self`.
pub fn priv_key(&self) -> &BigNumRef {
unsafe {
let mut priv_key = ptr::null();
DSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut priv_key);
BigNumRef::from_ptr(priv_key as *mut _)
}
}
}
impl<T> DsaRef<T>
where
T: HasParams,
{
/// Returns the maximum size of the signature output by `self` in bytes.
/// Returns the maximum size of the signature output by `self` in bytes. Returns
/// None if the keys are uninitialized.
///
/// OpenSSL documentation at [`DSA_size`]
///
/// [`DSA_size`]: https://www.openssl.org/docs/man1.1.0/crypto/DSA_size.html
pub fn size(&self) -> u32 {
unsafe { ffi::DSA_size(self.as_ptr()) as u32 }
// FIXME should return u32
pub fn size(&self) -> Option<u32> {
if self.q().is_some() {
unsafe { Some(ffi::DSA_size(self.as_ptr()) as u32) }
} else {
None
}
}
/// Returns the DSA prime parameter of `self`.
pub fn p(&self) -> &BigNumRef {
pub fn p(&self) -> Option<&BigNumRef> {
unsafe {
let mut p = ptr::null();
DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut());
BigNumRef::from_ptr(p as *mut _)
let p = compat::pqg(self.as_ptr())[0];
if p.is_null() {
None
} else {
Some(BigNumRef::from_ptr(p as *mut _))
}
}
}
/// Returns the DSA sub-prime parameter of `self`.
pub fn q(&self) -> &BigNumRef {
pub fn q(&self) -> Option<&BigNumRef> {
unsafe {
let mut q = ptr::null();
DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut());
BigNumRef::from_ptr(q as *mut _)
let q = compat::pqg(self.as_ptr())[1];
if q.is_null() {
None
} else {
Some(BigNumRef::from_ptr(q as *mut _))
}
}
}
/// Returns the DSA base parameter of `self`.
pub fn g(&self) -> &BigNumRef {
pub fn g(&self) -> Option<&BigNumRef> {
unsafe {
let mut g = ptr::null();
DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g);
BigNumRef::from_ptr(g as *mut _)
let g = compat::pqg(self.as_ptr())[2];
if g.is_null() {
None
} else {
Some(BigNumRef::from_ptr(g as *mut _))
}
}
}
/// Returns whether the DSA includes a public key, used to confirm the authenticity
/// of the message.
pub fn has_public_key(&self) -> bool {
unsafe { !compat::keys(self.as_ptr())[0].is_null() }
}
/// Returns whether the DSA includes a private key, used to prove the authenticity
/// of a message.
pub fn has_private_key(&self) -> bool {
unsafe { !compat::keys(self.as_ptr())[1].is_null() }
}
}
impl Dsa<Private> {
impl Dsa {
/// Generate a DSA key pair.
///
/// Calls [`DSA_generate_parameters_ex`] to populate the `p`, `g`, and `q` values.
/// These values are used to generate the key pair with [`DSA_generate_key`].
///
/// The `bits` parameter corresponds to the length of the prime `p`.
/// The `bits` parameter coresponds to the length of the prime `p`.
///
/// [`DSA_generate_parameters_ex`]: https://www.openssl.org/docs/man1.1.0/crypto/DSA_generate_parameters_ex.html
/// [`DSA_generate_key`]: https://www.openssl.org/docs/man1.1.0/crypto/DSA_generate_key.html
pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
pub fn generate(bits: u32) -> Result<Dsa, ErrorStack> {
ffi::init();
unsafe {
let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
let dsa = Dsa(cvt_p(ffi::DSA_new())?);
cvt(ffi::DSA_generate_parameters_ex(
dsa.0,
bits as c_int,
@ -215,152 +156,75 @@ impl Dsa<Private> {
}
}
/// Create a DSA key pair with the given parameters
///
/// `p`, `q` and `g` are the common parameters.
/// `priv_key` is the private component of the key pair.
/// `pub_key` is the public component of the key. Can be computed via `g^(priv_key) mod p`
pub fn from_private_components(
p: BigNum,
q: BigNum,
g: BigNum,
priv_key: BigNum,
pub_key: BigNum,
) -> Result<Dsa<Private>, ErrorStack> {
private_key_from_pem!(Dsa, ffi::PEM_read_bio_DSAPrivateKey);
private_key_from_der!(Dsa, ffi::d2i_DSAPrivateKey);
public_key_from_pem!(Dsa, ffi::PEM_read_bio_DSA_PUBKEY);
public_key_from_der!(Dsa, ffi::d2i_DSAPublicKey);
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Dsa, ErrorStack>
where
F: FnOnce(&mut [c_char]) -> usize,
{
ffi::init();
let mut cb = CallbackState::new(pass_cb);
let mem_bio = MemBioSlice::new(buf)?;
unsafe {
let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
mem::forget((p, q, g));
cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), priv_key.as_ptr()))?;
mem::forget((pub_key, priv_key));
Ok(dsa)
let cb_ptr = &mut cb as *mut _ as *mut c_void;
let dsa = cvt_p(ffi::PEM_read_bio_DSAPrivateKey(
mem_bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb_old::<F>),
cb_ptr,
))?;
Ok(Dsa(dsa))
}
}
}
impl Dsa<Public> {
from_pem! {
/// Decodes a PEM-encoded SubjectPublicKeyInfo structure containing a DSA key.
///
/// The input should have a header of `-----BEGIN PUBLIC KEY-----`.
///
/// This corresponds to [`PEM_read_bio_DSA_PUBKEY`].
///
/// [`PEM_read_bio_DSA_PUBKEY`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_read_bio_DSA_PUBKEY.html
public_key_from_pem,
Dsa<Public>,
ffi::PEM_read_bio_DSA_PUBKEY
}
from_der! {
/// Decodes a DER-encoded SubjectPublicKeyInfo structure containing a DSA key.
///
/// This corresponds to [`d2i_DSA_PUBKEY`].
///
/// [`d2i_DSA_PUBKEY`]: https://www.openssl.org/docs/man1.0.2/crypto/d2i_DSA_PUBKEY.html
public_key_from_der,
Dsa<Public>,
ffi::d2i_DSA_PUBKEY
}
/// Create a new DSA key with only public components.
///
/// `p`, `q` and `g` are the common parameters.
/// `pub_key` is the public component of the key.
pub fn from_public_components(
p: BigNum,
q: BigNum,
g: BigNum,
pub_key: BigNum,
) -> Result<Dsa<Public>, ErrorStack> {
ffi::init();
unsafe {
let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
mem::forget((p, q, g));
cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), ptr::null_mut()))?;
mem::forget(pub_key);
Ok(dsa)
}
}
}
impl<T> fmt::Debug for Dsa<T> {
impl fmt::Debug for Dsa {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "DSA")
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg};
} else {
#[allow(bad_style)]
unsafe fn DSA_get0_pqg(
d: *mut ffi::DSA,
p: *mut *const ffi::BIGNUM,
q: *mut *const ffi::BIGNUM,
g: *mut *const ffi::BIGNUM)
{
if !p.is_null() {
*p = (*d).p;
}
if !q.is_null() {
*q = (*d).q;
}
if !g.is_null() {
*g = (*d).g;
}
}
#[cfg(ossl110)]
mod compat {
use std::ptr;
use ffi::{self, BIGNUM, DSA};
#[allow(bad_style)]
unsafe fn DSA_get0_key(
d: *mut ffi::DSA,
pub_key: *mut *const ffi::BIGNUM,
priv_key: *mut *const ffi::BIGNUM)
{
if !pub_key.is_null() {
*pub_key = (*d).pub_key;
}
if !priv_key.is_null() {
*priv_key = (*d).priv_key;
}
}
pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] {
let (mut p, mut q, mut g) = (ptr::null(), ptr::null(), ptr::null());
ffi::DSA_get0_pqg(d, &mut p, &mut q, &mut g);
[p, q, g]
}
#[allow(bad_style)]
unsafe fn DSA_set0_key(
d: *mut ffi::DSA,
pub_key: *mut ffi::BIGNUM,
priv_key: *mut ffi::BIGNUM) -> c_int
{
(*d).pub_key = pub_key;
(*d).priv_key = priv_key;
1
}
pub unsafe fn keys(d: *const DSA) -> [*const BIGNUM; 2] {
let (mut pub_key, mut priv_key) = (ptr::null(), ptr::null());
ffi::DSA_get0_key(d, &mut pub_key, &mut priv_key);
[pub_key, priv_key]
}
}
#[allow(bad_style)]
unsafe fn DSA_set0_pqg(
d: *mut ffi::DSA,
p: *mut ffi::BIGNUM,
q: *mut ffi::BIGNUM,
g: *mut ffi::BIGNUM) -> c_int
{
(*d).p = p;
(*d).q = q;
(*d).g = g;
1
}
#[cfg(ossl10x)]
mod compat {
use ffi::{BIGNUM, DSA};
pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] {
[(*d).p, (*d).q, (*d).g]
}
pub unsafe fn keys(d: *const DSA) -> [*const BIGNUM; 2] {
[(*d).pub_key, (*d).priv_key]
}
}
#[cfg(test)]
mod test {
use symm::Cipher;
use super::*;
use bn::BigNumContext;
use hash::MessageDigest;
use pkey::PKey;
use sign::{Signer, Verifier};
#[test]
pub fn test_generate() {
@ -368,91 +232,30 @@ mod test {
}
#[test]
fn test_pubkey_generation() {
let dsa = Dsa::generate(1024).unwrap();
let p = dsa.p();
let g = dsa.g();
let priv_key = dsa.priv_key();
let pub_key = dsa.pub_key();
let mut ctx = BigNumContext::new().unwrap();
let mut calc = BigNum::new().unwrap();
calc.mod_exp(g, priv_key, p, &mut ctx).unwrap();
assert_eq!(&calc, pub_key)
pub fn test_password() {
let key = include_bytes!("../test/dsa-encrypted.pem");
Dsa::private_key_from_pem_passphrase(key, b"mypass").unwrap();
}
#[test]
fn test_priv_key_from_parts() {
let p = BigNum::from_u32(283).unwrap();
let q = BigNum::from_u32(47).unwrap();
let g = BigNum::from_u32(60).unwrap();
let priv_key = BigNum::from_u32(15).unwrap();
let pub_key = BigNum::from_u32(207).unwrap();
let dsa = Dsa::from_private_components(p, q, g, priv_key, pub_key).unwrap();
assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
assert_eq!(dsa.priv_key(), &BigNum::from_u32(15).unwrap());
assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
}
#[test]
fn test_pub_key_from_parts() {
let p = BigNum::from_u32(283).unwrap();
let q = BigNum::from_u32(47).unwrap();
let g = BigNum::from_u32(60).unwrap();
let pub_key = BigNum::from_u32(207).unwrap();
let dsa = Dsa::from_public_components(p, q, g, pub_key).unwrap();
assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap());
assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap());
assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap());
assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap());
}
#[test]
fn test_signature() {
const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let dsa_ref = Dsa::generate(1024).unwrap();
let p = dsa_ref.p();
let q = dsa_ref.q();
let g = dsa_ref.g();
let pub_key = dsa_ref.pub_key();
let priv_key = dsa_ref.priv_key();
let priv_key = Dsa::from_private_components(
BigNumRef::to_owned(p).unwrap(),
BigNumRef::to_owned(q).unwrap(),
BigNumRef::to_owned(g).unwrap(),
BigNumRef::to_owned(priv_key).unwrap(),
BigNumRef::to_owned(pub_key).unwrap(),
)
.unwrap();
let priv_key = PKey::from_dsa(priv_key).unwrap();
let pub_key = Dsa::from_public_components(
BigNumRef::to_owned(p).unwrap(),
BigNumRef::to_owned(q).unwrap(),
BigNumRef::to_owned(g).unwrap(),
BigNumRef::to_owned(pub_key).unwrap(),
)
.unwrap();
let pub_key = PKey::from_dsa(pub_key).unwrap();
let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap();
signer.update(TEST_DATA).unwrap();
let signature = signer.sign_to_vec().unwrap();
let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap();
verifier.update(TEST_DATA).unwrap();
assert!(verifier.verify(&signature[..]).unwrap());
}
#[test]
fn clone() {
fn test_to_password() {
let key = Dsa::generate(2048).unwrap();
drop(key.clone());
let pem = key.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
.unwrap();
Dsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
assert!(Dsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
}
#[test]
pub fn test_password_callback() {
let mut password_queried = false;
let key = include_bytes!("../test/dsa-encrypted.pem");
Dsa::private_key_from_pem_callback(key, |password| {
password_queried = true;
password[..6].copy_from_slice(b"mypass");
Ok(6)
}).unwrap();
assert!(password_queried);
}
}

View File

@ -20,10 +20,10 @@
//!
//! ```
//! use openssl::ec::{EcGroup, EcPoint};
//! use openssl::nid::Nid;
//! use openssl::nid;
//! use openssl::error::ErrorStack;
//! fn get_ec_point() -> Result<EcPoint, ErrorStack> {
//! let group = EcGroup::from_curve_name(Nid::SECP224R1)?;
//! fn get_ec_point() -> Result< EcPoint, ErrorStack > {
//! let group = EcGroup::from_curve_name(nid::SECP224R1)?;
//! let point = EcPoint::new(&group)?;
//! Ok(point)
//! }
@ -33,15 +33,51 @@
//! ```
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use std::fmt;
use std::ptr;
use std::mem;
use libc::c_int;
use bn::{BigNumContextRef, BigNumRef};
use {cvt, cvt_n, cvt_p, init};
use bn::{BigNumRef, BigNumContextRef};
use error::ErrorStack;
use nid::Nid;
use pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
use {cvt, cvt_n, cvt_p, init};
/// Compressed conversion from point value (Default)
pub const POINT_CONVERSION_COMPRESSED: PointConversionForm =
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_COMPRESSED);
/// Uncompressed conversion from point value (Binary curve default)
pub const POINT_CONVERSION_UNCOMPRESSED: PointConversionForm =
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_UNCOMPRESSED);
/// Performs both compressed and uncompressed conversions
pub const POINT_CONVERSION_HYBRID: PointConversionForm =
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_HYBRID);
/// Curve defined using polynomial parameters
///
/// Most applications use a named EC_GROUP curve, however, support
/// is included to explicitly define the curve used to calculate keys
/// This information would need to be known by both endpoint to make communication
/// effective.
///
/// OPENSSL_EC_EXPLICIT_CURVE, but that was only added in 1.1.
/// Man page documents that 0 can be used in older versions.
///
/// OpenSSL documentation at [`EC_GROUP`]
///
/// [`EC_GROUP`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_GROUP_get_seed_len.html
pub const EXPLICIT_CURVE: Asn1Flag = Asn1Flag(0);
/// Standard Curves
///
/// Curves that make up the typical encryption use cases. The collection of curves
/// are well known but extensible.
///
/// OpenSSL documentation at [`EC_GROUP`]
///
/// [`EC_GROUP`]: https://www.openssl.org/docs/manmaster/man3/EC_GROUP_order_bits.html
pub const NAMED_CURVE: Asn1Flag = Asn1Flag(ffi::OPENSSL_EC_NAMED_CURVE);
/// Compressed or Uncompressed conversion
///
@ -55,53 +91,13 @@ use {cvt, cvt_n, cvt_p, init};
#[derive(Copy, Clone)]
pub struct PointConversionForm(ffi::point_conversion_form_t);
impl PointConversionForm {
/// Compressed conversion from point value.
pub const COMPRESSED: PointConversionForm =
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_COMPRESSED);
/// Uncompressed conversion from point value.
pub const UNCOMPRESSED: PointConversionForm =
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_UNCOMPRESSED);
/// Performs both compressed and uncompressed conversions.
pub const HYBRID: PointConversionForm =
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_HYBRID);
}
/// Named Curve or Explicit
///
/// This type acts as a boolean as to whether the `EcGroup` is named or explicit.
/// This type acts as a boolean as to whether the EC_Group is named or
/// explicit.
#[derive(Copy, Clone)]
pub struct Asn1Flag(c_int);
impl Asn1Flag {
/// Curve defined using polynomial parameters
///
/// Most applications use a named EC_GROUP curve, however, support
/// is included to explicitly define the curve used to calculate keys
/// This information would need to be known by both endpoint to make communication
/// effective.
///
/// OPENSSL_EC_EXPLICIT_CURVE, but that was only added in 1.1.
/// Man page documents that 0 can be used in older versions.
///
/// OpenSSL documentation at [`EC_GROUP`]
///
/// [`EC_GROUP`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_GROUP_get_seed_len.html
pub const EXPLICIT_CURVE: Asn1Flag = Asn1Flag(0);
/// Standard Curves
///
/// Curves that make up the typical encryption use cases. The collection of curves
/// are well known but extensible.
///
/// OpenSSL documentation at [`EC_GROUP`]
///
/// [`EC_GROUP`]: https://www.openssl.org/docs/manmaster/man3/EC_GROUP_order_bits.html
pub const NAMED_CURVE: Asn1Flag = Asn1Flag(ffi::OPENSSL_EC_NAMED_CURVE);
}
foreign_type_and_impl_send_sync! {
type CType = ffi::EC_GROUP;
fn drop = ffi::EC_GROUP_free;
@ -164,8 +160,7 @@ impl EcGroupRef {
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -194,28 +189,7 @@ impl EcGroupRef {
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
}
}
/// Places the cofactor of the group in the provided `BigNum`.
///
/// OpenSSL documentation at [`EC_GROUP_get_cofactor`]
///
/// [`EC_GROUP_get_cofactor`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_GROUP_get_cofactor.html
pub fn cofactor(
&self,
cofactor: &mut BigNumRef,
ctx: &mut BigNumContextRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EC_GROUP_get_cofactor(
self.as_ptr(),
cofactor.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -228,18 +202,6 @@ impl EcGroupRef {
unsafe { ffi::EC_GROUP_get_degree(self.as_ptr()) as u32 }
}
/// Returns the generator for the given curve as a [`EcPoint`].
///
/// OpenSSL documentation at [`EC_GROUP_get0_generator`]
///
/// [`EC_GROUP_get0_generator`]: https://www.openssl.org/docs/man1.1.0/man3/EC_GROUP_get0_generator.html
pub fn generator(&self) -> &EcPointRef {
unsafe {
let ptr = ffi::EC_GROUP_get0_generator(self.as_ptr());
EcPointRef::from_ptr(ptr as *mut _)
}
}
/// Places the order of the curve in the provided `BigNum`.
///
/// OpenSSL documentation at [`EC_GROUP_get_order`]
@ -255,8 +217,7 @@ impl EcGroupRef {
self.as_ptr(),
order.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -270,16 +231,6 @@ impl EcGroupRef {
ffi::EC_GROUP_set_asn1_flag(self.as_ptr(), flag.0);
}
}
/// Returns the name of the curve, if a name is associated.
///
/// OpenSSL documentation at [`EC_GROUP_get_curve_name`]
///
/// [`EC_GROUP_get_curve_name`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_GROUP_get_curve_name.html
pub fn curve_name(&self) -> Option<Nid> {
let nid = unsafe { ffi::EC_GROUP_get_curve_name(self.as_ptr()) };
if nid > 0 { Some(Nid::from_raw(nid)) } else { None }
}
}
foreign_type_and_impl_send_sync! {
@ -318,8 +269,7 @@ impl EcPointRef {
a.as_ptr(),
b.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -343,12 +293,11 @@ impl EcPointRef {
q.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
/// Computes `generator * n`, storing the result in `self`.
/// Computes `generator * n`, storing the result ing `self`.
pub fn mul_generator(
&mut self,
group: &EcGroupRef,
@ -363,8 +312,7 @@ impl EcPointRef {
ptr::null(),
ptr::null(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -385,8 +333,7 @@ impl EcPointRef {
q.as_ptr(),
m.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -401,8 +348,7 @@ impl EcPointRef {
group.as_ptr(),
self.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -446,20 +392,6 @@ impl EcPointRef {
}
}
/// Creates a new point on the specified curve with the same value.
///
/// OpenSSL documentation at [`EC_POINT_dup`]
///
/// [`EC_POINT_dup`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_POINT_dup.html
pub fn to_owned(
&self,
group: &EcGroupRef,
) -> Result<EcPoint, ErrorStack> {
unsafe {
cvt_p(ffi::EC_POINT_dup(self.as_ptr(), group.as_ptr())).map(EcPoint)
}
}
/// Determines if this point is equal to another.
///
/// OpenSSL doucmentation at [`EC_POINT_cmp`]
@ -502,8 +434,7 @@ impl EcPointRef {
x.as_ptr(),
y.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -528,8 +459,7 @@ impl EcPointRef {
x.as_ptr(),
y.as_ptr(),
ctx.as_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
}
@ -568,7 +498,7 @@ impl EcPoint {
}
}
generic_foreign_type_and_impl_send_sync! {
foreign_type_and_impl_send_sync! {
type CType = ffi::EC_KEY;
fn drop = ffi::EC_KEY_free;
@ -577,46 +507,47 @@ generic_foreign_type_and_impl_send_sync! {
/// OpenSSL documentation at [`EC_KEY_new`]
///
/// [`EC_KEY_new`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_new.html
pub struct EcKey<T>;
pub struct EcKey;
/// Reference to [`EcKey`]
///
/// [`EcKey`]: struct.EcKey.html
pub struct EcKeyRef<T>;
pub struct EcKeyRef;
}
impl<T> EcKeyRef<T>
where
T: HasPrivate,
{
private_key_to_pem! {
/// Serializes the private key to a PEM-encoded ECPrivateKey structure.
///
/// The output will have a header of `-----BEGIN EC PRIVATE KEY-----`.
///
/// This corresponds to [`PEM_write_bio_ECPrivateKey`].
///
/// [`PEM_write_bio_ECPrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_ECPrivateKey.html
private_key_to_pem,
/// Serializes the private key to a PEM-encoded encrypted ECPrivateKey structure.
///
/// The output will have a header of `-----BEGIN EC PRIVATE KEY-----`.
///
/// This corresponds to [`PEM_write_bio_ECPrivateKey`].
///
/// [`PEM_write_bio_ECPrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_ECPrivateKey.html
private_key_to_pem_passphrase,
ffi::PEM_write_bio_ECPrivateKey
impl EcKeyRef {
private_key_to_pem!(ffi::PEM_write_bio_ECPrivateKey);
private_key_to_der!(ffi::i2d_ECPrivateKey);
/// Return [`EcGroup`] of the `EcKey`
///
/// OpenSSL documentation at [`EC_KEY_get0_group`]
///
/// [`EC_KEY_get0_group`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_get0_group.html
pub fn group(&self) -> Option<&EcGroupRef> {
unsafe {
let ptr = ffi::EC_KEY_get0_group(self.as_ptr());
if ptr.is_null() {
None
} else {
Some(EcGroupRef::from_ptr(ptr as *mut _))
}
}
}
to_der! {
/// Serializes the private key into a DER-encoded ECPrivateKey structure.
///
/// This corresponds to [`i2d_ECPrivateKey`].
///
/// [`i2d_ECPrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/d2i_ECPrivate_key.html
private_key_to_der,
ffi::i2d_ECPrivateKey
/// Return [`EcPoint`] associated with the public key
///
/// OpenSSL documentation at [`EC_KEY_get0_pubic_key`]
///
/// [`EC_KEY_get0_pubic_key`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_get0_public_key.html
pub fn public_key(&self) -> Option<&EcPointRef> {
unsafe {
let ptr = ffi::EC_KEY_get0_public_key(self.as_ptr());
if ptr.is_null() {
None
} else {
Some(EcPointRef::from_ptr(ptr as *mut _))
}
}
}
/// Return [`EcPoint`] associated with the private key
@ -624,44 +555,14 @@ where
/// OpenSSL documentation at [`EC_KEY_get0_private_key`]
///
/// [`EC_KEY_get0_private_key`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_get0_private_key.html
pub fn private_key(&self) -> &BigNumRef {
pub fn private_key(&self) -> Option<&BigNumRef> {
unsafe {
let ptr = ffi::EC_KEY_get0_private_key(self.as_ptr());
BigNumRef::from_ptr(ptr as *mut _)
}
}
}
impl<T> EcKeyRef<T>
where
T: HasPublic,
{
/// Returns the public key.
///
/// OpenSSL documentation at [`EC_KEY_get0_pubic_key`]
///
/// [`EC_KEY_get0_pubic_key`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_get0_public_key.html
pub fn public_key(&self) -> &EcPointRef {
unsafe {
let ptr = ffi::EC_KEY_get0_public_key(self.as_ptr());
EcPointRef::from_ptr(ptr as *mut _)
}
}
}
impl<T> EcKeyRef<T>
where
T: HasParams,
{
/// Return [`EcGroup`] of the `EcKey`
///
/// OpenSSL documentation at [`EC_KEY_get0_group`]
///
/// [`EC_KEY_get0_group`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_get0_group.html
pub fn group(&self) -> &EcGroupRef {
unsafe {
let ptr = ffi::EC_KEY_get0_group(self.as_ptr());
EcGroupRef::from_ptr(ptr as *mut _)
if ptr.is_null() {
None
} else {
Some(BigNumRef::from_ptr(ptr as *mut _))
}
}
}
@ -673,21 +574,14 @@ where
pub fn check_key(&self) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::EC_KEY_check_key(self.as_ptr())).map(|_| ()) }
}
}
impl<T> ToOwned for EcKeyRef<T> {
type Owned = EcKey<T>;
fn to_owned(&self) -> EcKey<T> {
unsafe {
let r = ffi::EC_KEY_up_ref(self.as_ptr());
assert!(r == 1);
EcKey::from_ptr(self.as_ptr())
}
/// Create a copy of the `EcKey` to allow modification
pub fn to_owned(&self) -> Result<EcKey, ErrorStack> {
unsafe { cvt_p(ffi::EC_KEY_dup(self.as_ptr())).map(EcKey) }
}
}
impl EcKey<Params> {
impl EcKey {
/// Constructs an `EcKey` corresponding to a known curve.
///
/// It will not have an associated public or private key. This kind of key is primarily useful
@ -696,30 +590,13 @@ impl EcKey<Params> {
/// OpenSSL documenation at [`EC_KEY_new_by_curve_name`]
///
/// [`EC_KEY_new_by_curve_name`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_new_by_curve_name.html
pub fn from_curve_name(nid: Nid) -> Result<EcKey<Params>, ErrorStack> {
pub fn from_curve_name(nid: Nid) -> Result<EcKey, ErrorStack> {
unsafe {
init();
cvt_p(ffi::EC_KEY_new_by_curve_name(nid.as_raw())).map(|p| EcKey::from_ptr(p))
cvt_p(ffi::EC_KEY_new_by_curve_name(nid.as_raw())).map(EcKey)
}
}
/// Constructs an `EcKey` corresponding to a curve.
///
/// This corresponds to [`EC_KEY_set_group`].
///
/// [`EC_KEY_set_group`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_KEY_new.html
pub fn from_group(group: &EcGroupRef) -> Result<EcKey<Params>, ErrorStack> {
unsafe {
cvt_p(ffi::EC_KEY_new())
.map(|p| EcKey::from_ptr(p))
.and_then(|key| {
cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key)
})
}
}
}
impl EcKey<Public> {
/// Constructs an `EcKey` from the specified group with the associated `EcPoint`, public_key.
///
/// This will only have the associated public_key.
@ -729,14 +606,14 @@ impl EcKey<Public> {
/// ```no_run
/// use openssl::bn::BigNumContext;
/// use openssl::ec::*;
/// use openssl::nid::Nid;
/// use openssl::nid;
/// use openssl::pkey::PKey;
///
/// // get bytes from somewhere, i.e. this will not produce a valid key
/// let public_key: Vec<u8> = vec![];
///
/// // create an EcKey from the binary form of a EcPoint
/// let group = EcGroup::from_curve_name(Nid::SECP256K1).unwrap();
/// let group = EcGroup::from_curve_name(nid::SECP256K1).unwrap();
/// let mut ctx = BigNumContext::new().unwrap();
/// let point = EcPoint::from_bytes(&group, &public_key, &mut ctx).unwrap();
/// let key = EcKey::from_public_key(&group, &point);
@ -744,289 +621,259 @@ impl EcKey<Public> {
pub fn from_public_key(
group: &EcGroupRef,
public_key: &EcPointRef,
) -> Result<EcKey<Public>, ErrorStack> {
) -> Result<EcKey, ErrorStack> {
let mut builder = EcKeyBuilder::new()?;
builder.set_group(group)?;
builder.set_public_key(public_key)?;
Ok(builder.build())
}
/// Generates a new public/private key pair on the specified curve.
pub fn generate(group: &EcGroupRef) -> Result<EcKey, ErrorStack> {
let mut builder = EcKeyBuilder::new()?;
builder.set_group(group)?;
builder.generate_key()?;
Ok(builder.build())
}
#[deprecated(since = "0.9.2", note = "use from_curve_name")]
pub fn new_by_curve_name(nid: Nid) -> Result<EcKey, ErrorStack> {
EcKey::from_curve_name(nid)
}
private_key_from_pem!(EcKey, ffi::PEM_read_bio_ECPrivateKey);
private_key_from_der!(EcKey, ffi::d2i_ECPrivateKey);
}
foreign_type_and_impl_send_sync! {
type CType = ffi::EC_KEY;
fn drop = ffi::EC_KEY_free;
/// Builder pattern for key generation
///
/// Returns a `EcKeyBuilder` to be consumed by `build`
pub struct EcKeyBuilder;
/// Reference to [`EcKeyBuilder`]
///
/// [`EcKeyBuilder`]: struct.EcKeyBuilder.html
pub struct EcKeyBuilderRef;
}
impl EcKeyBuilder {
/// Creates an empty `EcKeyBuilder` to be chained with additonal methods
pub fn new() -> Result<EcKeyBuilder, ErrorStack> {
unsafe {
cvt_p(ffi::EC_KEY_new())
.map(|p| EcKey::from_ptr(p))
.and_then(|key| {
cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key)
})
.and_then(|key| {
cvt(ffi::EC_KEY_set_public_key(
key.as_ptr(),
public_key.as_ptr(),
))
.map(|_| key)
})
init();
cvt_p(ffi::EC_KEY_new()).map(EcKeyBuilder)
}
}
/// Constructs a public key from its affine coordinates.
pub fn from_public_key_affine_coordinates(
group: &EcGroupRef,
/// Consume the `EcKeyBuilder` and return [`EcKey`]
///
/// [`EcKey`]: struct.EcKey.html
pub fn build(self) -> EcKey {
unsafe {
let key = EcKey::from_ptr(self.as_ptr());
mem::forget(self);
key
}
}
}
impl EcKeyBuilderRef {
/// Set the [`EcGroup`] explicitly
///
/// [`EcGroup`]: struct.EcGroup.html
pub fn set_group(&mut self, group: &EcGroupRef) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
unsafe { cvt(ffi::EC_KEY_set_group(self.as_ptr(), group.as_ptr())).map(|_| self) }
}
/// Set public key to given `EcPoint`
pub fn set_public_key(
&mut self,
public_key: &EcPointRef,
) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
unsafe {
cvt(ffi::EC_KEY_set_public_key(
self.as_ptr(),
public_key.as_ptr(),
)).map(|_| self)
}
}
/// Generate public and private keys.
pub fn generate_key(&mut self) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
unsafe { cvt(ffi::EC_KEY_generate_key(self.as_ptr())).map(|_| self) }
}
/// Sets the public key based on affine coordinates.
pub fn set_public_key_affine_coordinates(
&mut self,
x: &BigNumRef,
y: &BigNumRef,
) -> Result<EcKey<Public>, ErrorStack> {
) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
unsafe {
cvt_p(ffi::EC_KEY_new())
.map(|p| EcKey::from_ptr(p))
.and_then(|key| {
cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key)
})
.and_then(|key| {
cvt(ffi::EC_KEY_set_public_key_affine_coordinates(
key.as_ptr(),
x.as_ptr(),
y.as_ptr(),
))
.map(|_| key)
})
}
}
}
impl EcKey<Private> {
/// Generates a new public/private key pair on the specified curve.
pub fn generate(group: &EcGroupRef) -> Result<EcKey<Private>, ErrorStack> {
unsafe {
cvt_p(ffi::EC_KEY_new())
.map(|p| EcKey::from_ptr(p))
.and_then(|key| {
cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key)
})
.and_then(|key| cvt(ffi::EC_KEY_generate_key(key.as_ptr())).map(|_| key))
cvt(ffi::EC_KEY_set_public_key_affine_coordinates(
self.as_ptr(),
x.as_ptr(),
y.as_ptr(),
)).map(|_| self)
}
}
/// Constructs an public/private key pair given a curve, a private key and a public key point.
pub fn from_private_components(
group: &EcGroupRef,
private_number: &BigNumRef,
public_key: &EcPointRef,
) -> Result<EcKey<Private>, ErrorStack> {
unsafe {
cvt_p(ffi::EC_KEY_new())
.map(|p| EcKey::from_ptr(p))
.and_then(|key| {
cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key)
})
.and_then(|key| {
cvt(ffi::EC_KEY_set_private_key(
key.as_ptr(),
private_number.as_ptr(),
))
.map(|_| key)
})
.and_then(|key| {
cvt(ffi::EC_KEY_set_public_key(
key.as_ptr(),
public_key.as_ptr(),
))
.map(|_| key)
})
}
}
private_key_from_pem! {
/// Deserializes a private key from a PEM-encoded ECPrivateKey structure.
///
/// The input should have a header of `-----BEGIN EC PRIVATE KEY-----`.
///
/// This corresponds to `PEM_read_bio_ECPrivateKey`.
private_key_from_pem,
/// Deserializes a private key from a PEM-encoded encrypted ECPrivateKey structure.
///
/// The input should have a header of `-----BEGIN EC PRIVATE KEY-----`.
///
/// This corresponds to `PEM_read_bio_ECPrivateKey`.
private_key_from_pem_passphrase,
/// Deserializes a private key from a PEM-encoded encrypted ECPrivateKey structure.
///
/// The callback should fill the password into the provided buffer and return its length.
///
/// The input should have a header of `-----BEGIN EC PRIVATE KEY-----`.
///
/// This corresponds to `PEM_read_bio_ECPrivateKey`.
private_key_from_pem_callback,
EcKey<Private>,
ffi::PEM_read_bio_ECPrivateKey
}
from_der! {
/// Decodes a DER-encoded elliptic curve private key structure.
///
/// This corresponds to [`d2i_ECPrivateKey`].
///
/// [`d2i_ECPrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/d2i_ECPrivate_key.html
private_key_from_der,
EcKey<Private>,
ffi::d2i_ECPrivateKey
}
}
impl<T> Clone for EcKey<T> {
fn clone(&self) -> EcKey<T> {
(**self).to_owned()
}
}
impl<T> fmt::Debug for EcKey<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "EcKey")
/// Sets the private key.
pub fn set_private_key(&mut self, key: &BigNumRef) -> Result<&mut EcKeyBuilderRef, ErrorStack> {
unsafe { cvt(ffi::EC_KEY_set_private_key(self.as_ptr(), key.as_ptr())).map(|_| self) }
}
}
#[cfg(test)]
mod test {
use hex::FromHex;
use super::*;
use bn::{BigNum, BigNumContext};
use nid::Nid;
use nid;
use data_encoding::BASE64URL_NOPAD;
use super::*;
#[test]
fn key_new_by_curve_name() {
EcKey::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
EcKey::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
}
#[test]
fn generate() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
EcKey::generate(&group).unwrap();
}
#[test]
fn cofactor() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let mut ctx = BigNumContext::new().unwrap();
let mut cofactor = BigNum::new().unwrap();
group.cofactor(&mut cofactor, &mut ctx).unwrap();
let one = BigNum::from_u32(1).unwrap();
assert_eq!(cofactor, one);
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
key.public_key().unwrap();
key.private_key().unwrap();
}
#[test]
fn dup() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
drop(key.clone());
key.to_owned().unwrap();
}
#[test]
fn point_new() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
EcPoint::new(&group).unwrap();
}
#[test]
fn point_bytes() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
let point = key.public_key();
let point = key.public_key().unwrap();
let mut ctx = BigNumContext::new().unwrap();
let bytes = point
.to_bytes(&group, PointConversionForm::COMPRESSED, &mut ctx)
.to_bytes(&group, POINT_CONVERSION_COMPRESSED, &mut ctx)
.unwrap();
let point2 = EcPoint::from_bytes(&group, &bytes, &mut ctx).unwrap();
assert!(point.eq(&group, &point2, &mut ctx).unwrap());
}
#[test]
fn point_owned() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
let point = key.public_key();
let owned = point.to_owned(&group).unwrap();
let mut ctx = BigNumContext::new().unwrap();
assert!(owned.eq(&group, point, &mut ctx).unwrap());
}
#[test]
fn mul_generator() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
let mut ctx = BigNumContext::new().unwrap();
let mut public_key = EcPoint::new(&group).unwrap();
public_key
.mul_generator(&group, key.private_key(), &mut ctx)
.mul_generator(&group, key.private_key().unwrap(), &mut ctx)
.unwrap();
assert!(public_key.eq(&group, key.public_key(), &mut ctx).unwrap());
}
#[test]
fn generator() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let gen = group.generator();
let one = BigNum::from_u32(1).unwrap();
let mut ctx = BigNumContext::new().unwrap();
let mut ecp = EcPoint::new(&group).unwrap();
ecp.mul_generator(&group, &one, &mut ctx).unwrap();
assert!(ecp.eq(&group, gen, &mut ctx).unwrap());
assert!(
public_key
.eq(&group, key.public_key().unwrap(), &mut ctx)
.unwrap()
);
}
#[test]
fn key_from_public_key() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
let mut ctx = BigNumContext::new().unwrap();
let bytes = key
.public_key()
.to_bytes(&group, PointConversionForm::COMPRESSED, &mut ctx)
let bytes = key.public_key()
.unwrap()
.to_bytes(&group, POINT_CONVERSION_COMPRESSED, &mut ctx)
.unwrap();
drop(key);
let public_key = EcPoint::from_bytes(&group, &bytes, &mut ctx).unwrap();
let ec_key = EcKey::from_public_key(&group, &public_key).unwrap();
assert!(ec_key.check_key().is_ok());
}
#[test]
fn key_from_private_components() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
let dup_key =
EcKey::from_private_components(&group, key.private_key(), key.public_key()).unwrap();
let res = dup_key.check_key().unwrap();
assert!(res == ());
assert!(key.private_key() == dup_key.private_key());
assert!(ec_key.public_key().is_some());
assert!(ec_key.private_key().is_none());
}
#[test]
fn key_from_affine_coordinates() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let x = Vec::from_hex("30a0424cd21c2944838a2d75c92b37e76ea20d9f00893a3b4eee8a3c0aafec3e")
.unwrap();
let y = Vec::from_hex("e04b65e92456d9888b52b379bdfbd51ee869ef1f0fc65b6659695b6cce081723")
.unwrap();
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let x = BASE64URL_NOPAD.decode(
"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4".as_bytes(),
).unwrap();
let y = BASE64URL_NOPAD.decode(
"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM".as_bytes(),
).unwrap();
let xbn = BigNum::from_slice(&x).unwrap();
let ybn = BigNum::from_slice(&y).unwrap();
let ec_key = EcKey::from_public_key_affine_coordinates(&group, &xbn, &ybn).unwrap();
let mut builder = EcKeyBuilder::new().unwrap();
builder.set_group(&group).unwrap();
builder
.set_public_key_affine_coordinates(&xbn, &ybn)
.unwrap();
let ec_key = builder.build();
assert!(ec_key.check_key().is_ok());
assert!(ec_key.public_key().is_some());
}
#[test]
fn set_private_key() {
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let d = BASE64URL_NOPAD.decode(
"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE".as_bytes(),
).unwrap();
let dbn = BigNum::from_slice(&d).unwrap();
let mut builder = EcKeyBuilder::new().unwrap();
builder.set_group(&group).unwrap();
builder.set_private_key(&dbn).unwrap();
let ec_key = builder.build();
assert!(ec_key.private_key().is_some());
}
#[test]
fn get_affine_coordinates() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let x = Vec::from_hex("30a0424cd21c2944838a2d75c92b37e76ea20d9f00893a3b4eee8a3c0aafec3e")
.unwrap();
let y = Vec::from_hex("e04b65e92456d9888b52b379bdfbd51ee869ef1f0fc65b6659695b6cce081723")
.unwrap();
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let x = BASE64URL_NOPAD.decode(
"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4".as_bytes(),
).unwrap();
let y = BASE64URL_NOPAD.decode(
"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM".as_bytes(),
).unwrap();
let xbn = BigNum::from_slice(&x).unwrap();
let ybn = BigNum::from_slice(&y).unwrap();
let ec_key = EcKey::from_public_key_affine_coordinates(&group, &xbn, &ybn).unwrap();
let mut builder = EcKeyBuilder::new().unwrap();
builder.set_group(&group).unwrap();
builder
.set_public_key_affine_coordinates(&xbn, &ybn)
.unwrap();
let ec_key = builder.build();
let mut xbn2 = BigNum::new().unwrap();
let mut ybn2 = BigNum::new().unwrap();
let mut ctx = BigNumContext::new().unwrap();
let ec_key_pk = ec_key.public_key();
let ec_key_pk = ec_key.public_key().unwrap();
ec_key_pk
.affine_coordinates_gfp(&group, &mut xbn2, &mut ybn2, &mut ctx)
.unwrap();

4
openssl/src/ec_key.rs Normal file
View File

@ -0,0 +1,4 @@
#![doc(hidden)]
#![deprecated(since = "0.9.2", note = "renamed to `ec`")]
pub use ec::{EcKey, EcKeyRef};

View File

@ -1,243 +0,0 @@
//! Low level Elliptic Curve Digital Signature Algorithm (ECDSA) functions.
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use std::mem;
use std::ptr;
use bn::{BigNum, BigNumRef};
use ec::EcKeyRef;
use error::ErrorStack;
use pkey::{Private, Public};
use {cvt_n, cvt_p};
foreign_type_and_impl_send_sync! {
type CType = ffi::ECDSA_SIG;
fn drop = ffi::ECDSA_SIG_free;
/// A low level interface to ECDSA
///
/// OpenSSL documentation at [`ECDSA_sign`]
///
/// [`ECDSA_sign`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_sign.html
pub struct EcdsaSig;
/// Reference to [`EcdsaSig`]
///
/// [`EcdsaSig`]: struct.EcdsaSig.html
pub struct EcdsaSigRef;
}
impl EcdsaSig {
/// Computes a digital signature of the hash value `data` using the private EC key eckey.
///
/// OpenSSL documentation at [`ECDSA_do_sign`]
///
/// [`ECDSA_do_sign`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_do_sign.html
pub fn sign(data: &[u8], eckey: &EcKeyRef<Private>) -> Result<EcdsaSig, ErrorStack> {
unsafe {
assert!(data.len() <= c_int::max_value() as usize);
let sig = cvt_p(ffi::ECDSA_do_sign(
data.as_ptr(),
data.len() as c_int,
eckey.as_ptr(),
))?;
Ok(EcdsaSig::from_ptr(sig as *mut _))
}
}
/// Returns a new `EcdsaSig` by setting the `r` and `s` values associated with a
/// ECDSA signature.
///
/// OpenSSL documentation at [`ECDSA_SIG_set0`]
///
/// [`ECDSA_SIG_set0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_set0.html
pub fn from_private_components(r: BigNum, s: BigNum) -> Result<EcdsaSig, ErrorStack> {
unsafe {
let sig = cvt_p(ffi::ECDSA_SIG_new())?;
ECDSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
mem::forget((r, s));
Ok(EcdsaSig::from_ptr(sig as *mut _))
}
}
/// Verifies if the signature is a valid ECDSA signature using the given public key.
///
/// OpenSSL documentation at [`ECDSA_do_verify`]
///
/// [`ECDSA_do_verify`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_do_verify.html
pub fn verify(&self, data: &[u8], eckey: &EcKeyRef<Public>) -> Result<bool, ErrorStack> {
unsafe {
assert!(data.len() <= c_int::max_value() as usize);
cvt_n(ffi::ECDSA_do_verify(
data.as_ptr(),
data.len() as c_int,
self.as_ptr(),
eckey.as_ptr(),
))
.map(|x| x == 1)
}
}
/// Returns internal component: `r` of a `EcdsaSig`. (See X9.62 or FIPS 186-2)
///
/// OpenSSL documentation at [`ECDSA_SIG_get0`]
///
/// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html
pub fn r(&self) -> &BigNumRef {
unsafe {
let mut r = ptr::null();
ECDSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
BigNumRef::from_ptr(r as *mut _)
}
}
/// Returns internal components: `s` of a `EcdsaSig`. (See X9.62 or FIPS 186-2)
///
/// OpenSSL documentation at [`ECDSA_SIG_get0`]
///
/// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html
pub fn s(&self) -> &BigNumRef {
unsafe {
let mut s = ptr::null();
ECDSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
BigNumRef::from_ptr(s as *mut _)
}
}
from_der! {
/// Decodes a DER-encoded ECDSA signature.
///
/// This corresponds to [`d2i_ECDSA_SIG`].
///
/// [`d2i_ECDSA_SIG`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_ECDSA_SIG.html
from_der,
EcdsaSig,
ffi::d2i_ECDSA_SIG
}
}
impl EcdsaSigRef {
to_der! {
/// Serializes the ECDSA signature into a DER-encoded ECDSASignature structure.
///
/// This corresponds to [`i2d_ECDSA_SIG`].
///
/// [`i2d_ECDSA_SIG`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_ECDSA_SIG.html
to_der,
ffi::i2d_ECDSA_SIG
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
use ffi::{ECDSA_SIG_set0, ECDSA_SIG_get0};
} else {
#[allow(bad_style)]
unsafe fn ECDSA_SIG_set0(
sig: *mut ffi::ECDSA_SIG,
r: *mut ffi::BIGNUM,
s: *mut ffi::BIGNUM,
) -> c_int {
if r.is_null() || s.is_null() {
return 0;
}
ffi::BN_clear_free((*sig).r);
ffi::BN_clear_free((*sig).s);
(*sig).r = r;
(*sig).s = s;
1
}
#[allow(bad_style)]
unsafe fn ECDSA_SIG_get0(
sig: *const ffi::ECDSA_SIG,
pr: *mut *const ffi::BIGNUM,
ps: *mut *const ffi::BIGNUM)
{
if !pr.is_null() {
(*pr) = (*sig).r;
}
if !ps.is_null() {
(*ps) = (*sig).s;
}
}
}
}
#[cfg(test)]
mod test {
use super::*;
use ec::EcGroup;
use ec::EcKey;
use nid::Nid;
fn get_public_key(group: &EcGroup, x: &EcKey<Private>) -> Result<EcKey<Public>, ErrorStack> {
let public_key_point = x.public_key();
Ok(EcKey::from_public_key(group, public_key_point)?)
}
#[test]
#[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)]
fn sign_and_verify() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME192V1).unwrap();
let private_key = EcKey::generate(&group).unwrap();
let public_key = get_public_key(&group, &private_key).unwrap();
let private_key2 = EcKey::generate(&group).unwrap();
let public_key2 = get_public_key(&group, &private_key2).unwrap();
let data = String::from("hello");
let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap();
// Signature can be verified using the correct data & correct public key
let verification = res.verify(data.as_bytes(), &public_key).unwrap();
assert!(verification);
// Signature will not be verified using the incorrect data but the correct public key
let verification2 = res
.verify(String::from("hello2").as_bytes(), &public_key)
.unwrap();
assert!(verification2 == false);
// Signature will not be verified using the correct data but the incorrect public key
let verification3 = res.verify(data.as_bytes(), &public_key2).unwrap();
assert!(verification3 == false);
}
#[test]
#[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)]
fn check_private_components() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME192V1).unwrap();
let private_key = EcKey::generate(&group).unwrap();
let public_key = get_public_key(&group, &private_key).unwrap();
let data = String::from("hello");
let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap();
let verification = res.verify(data.as_bytes(), &public_key).unwrap();
assert!(verification);
let r = res.r().to_owned().unwrap();
let s = res.s().to_owned().unwrap();
let res2 = EcdsaSig::from_private_components(r, s).unwrap();
let verification2 = res2.verify(data.as_bytes(), &public_key).unwrap();
assert!(verification2);
}
#[test]
#[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)]
fn serialize_deserialize() {
let group = EcGroup::from_curve_name(Nid::SECP256K1).unwrap();
let private_key = EcKey::generate(&group).unwrap();
let public_key = get_public_key(&group, &private_key).unwrap();
let data = String::from("hello");
let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap();
let der = res.to_der().unwrap();
let sig = EcdsaSig::from_der(&der).unwrap();
let verification = sig.verify(data.as_bytes(), &public_key).unwrap();
assert!(verification);
}
}

View File

@ -1,282 +0,0 @@
//! Envelope encryption.
//!
//! # Example
//!
//! ```rust
//!
//! extern crate openssl;
//!
//! use openssl::rsa::Rsa;
//! use openssl::envelope::Seal;
//! use openssl::pkey::PKey;
//! use openssl::symm::Cipher;
//!
//! fn main() {
//! let rsa = Rsa::generate(2048).unwrap();
//! let key = PKey::from_rsa(rsa).unwrap();
//!
//! let cipher = Cipher::aes_256_cbc();
//! let mut seal = Seal::new(cipher, &[key]).unwrap();
//!
//! let secret = b"My secret message";
//! let mut encrypted = vec![0; secret.len() + cipher.block_size()];
//!
//! let mut enc_len = seal.update(secret, &mut encrypted).unwrap();
//! enc_len += seal.finalize(&mut encrypted[enc_len..]).unwrap();
//! encrypted.truncate(enc_len);
//! }
//! ```
use error::ErrorStack;
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use pkey::{HasPrivate, HasPublic, PKey, PKeyRef};
use std::cmp;
use std::ptr;
use symm::Cipher;
use {cvt, cvt_p};
/// Represents an EVP_Seal context.
pub struct Seal {
ctx: *mut ffi::EVP_CIPHER_CTX,
block_size: usize,
iv: Option<Vec<u8>>,
enc_keys: Vec<Vec<u8>>,
}
impl Seal {
/// Creates a new `Seal`.
pub fn new<T>(cipher: Cipher, pub_keys: &[PKey<T>]) -> Result<Seal, ErrorStack>
where
T: HasPublic,
{
unsafe {
assert!(pub_keys.len() <= c_int::max_value() as usize);
let ctx = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
let mut enc_key_ptrs = vec![];
let mut pub_key_ptrs = vec![];
let mut enc_keys = vec![];
for key in pub_keys {
let mut enc_key = vec![0; key.size()];
let enc_key_ptr = enc_key.as_mut_ptr();
enc_keys.push(enc_key);
enc_key_ptrs.push(enc_key_ptr);
pub_key_ptrs.push(key.as_ptr());
}
let mut iv = cipher.iv_len().map(|len| Vec::with_capacity(len));
let iv_ptr = iv.as_mut().map_or(ptr::null_mut(), |v| v.as_mut_ptr());
let mut enc_key_lens = vec![0; enc_keys.len()];
cvt(ffi::EVP_SealInit(
ctx,
cipher.as_ptr(),
enc_key_ptrs.as_mut_ptr(),
enc_key_lens.as_mut_ptr(),
iv_ptr,
pub_key_ptrs.as_mut_ptr(),
pub_key_ptrs.len() as c_int,
))?;
for (buf, len) in enc_keys.iter_mut().zip(&enc_key_lens) {
buf.truncate(*len as usize);
}
Ok(Seal {
ctx,
block_size: cipher.block_size(),
iv,
enc_keys,
})
}
}
/// Returns the initialization vector, if the cipher uses one.
pub fn iv(&self) -> Option<&[u8]> {
self.iv.as_ref().map(|v| &**v)
}
/// Returns the encrypted keys.
pub fn encrypted_keys(&self) -> &[Vec<u8>] {
&self.enc_keys
}
/// Feeds data from `input` through the cipher, writing encrypted bytes into `output`.
///
/// The number of bytes written to `output` is returned. Note that this may
/// not be equal to the length of `input`.
///
/// # Panics
///
/// 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()`.
pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
unsafe {
assert!(output.len() >= input.len() + self.block_size);
assert!(output.len() <= c_int::max_value() as usize);
let mut outl = output.len() as c_int;
let inl = input.len() as c_int;
cvt(ffi::EVP_EncryptUpdate(
self.ctx,
output.as_mut_ptr(),
&mut outl,
input.as_ptr(),
inl,
))?;
Ok(outl as usize)
}
}
/// Finishes the encryption process, writing any remaining data to `output`.
///
/// The number of bytes written to `output` is returned.
///
/// `update` should not be called after this method.
///
/// # Panics
///
/// Panics if `output` is less than the cipher's block size.
pub fn finalize(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
unsafe {
assert!(output.len() >= self.block_size);
let mut outl = cmp::min(output.len(), c_int::max_value() as usize) as c_int;
cvt(ffi::EVP_SealFinal(self.ctx, output.as_mut_ptr(), &mut outl))?;
Ok(outl as usize)
}
}
}
impl Drop for Seal {
fn drop(&mut self) {
unsafe {
ffi::EVP_CIPHER_CTX_free(self.ctx);
}
}
}
/// Represents an EVP_Open context.
pub struct Open {
ctx: *mut ffi::EVP_CIPHER_CTX,
block_size: usize,
}
impl Open {
/// Creates a new `Open`.
pub fn new<T>(
cipher: Cipher,
priv_key: &PKeyRef<T>,
iv: Option<&[u8]>,
encrypted_key: &[u8],
) -> Result<Open, ErrorStack>
where
T: HasPrivate,
{
unsafe {
assert!(encrypted_key.len() <= c_int::max_value() as usize);
assert!(cipher.iv_len().is_none() || iv.is_some());
let ctx = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
cvt(ffi::EVP_OpenInit(
ctx,
cipher.as_ptr(),
encrypted_key.as_ptr(),
encrypted_key.len() as c_int,
iv.map_or(ptr::null(), |v| v.as_ptr()),
priv_key.as_ptr(),
))?;
Ok(Open {
ctx,
block_size: cipher.block_size(),
})
}
}
/// Feeds data from `input` through the cipher, writing 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`.
///
/// # Panics
///
/// 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()`.
pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
unsafe {
assert!(output.len() >= input.len() + self.block_size);
assert!(output.len() <= c_int::max_value() as usize);
let mut outl = output.len() as c_int;
let inl = input.len() as c_int;
cvt(ffi::EVP_DecryptUpdate(
self.ctx,
output.as_mut_ptr(),
&mut outl,
input.as_ptr(),
inl,
))?;
Ok(outl as usize)
}
}
/// Finishes the decryption process, writing any remaining data to `output`.
///
/// The number of bytes written to `output` is returned.
///
/// `update` should not be called after this method.
///
/// # Panics
///
/// Panics if `output` is less than the cipher's block size.
pub fn finalize(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
unsafe {
assert!(output.len() >= self.block_size);
let mut outl = cmp::min(output.len(), c_int::max_value() as usize) as c_int;
cvt(ffi::EVP_OpenFinal(self.ctx, output.as_mut_ptr(), &mut outl))?;
Ok(outl as usize)
}
}
}
impl Drop for Open {
fn drop(&mut self) {
unsafe {
ffi::EVP_CIPHER_CTX_free(self.ctx);
}
}
}
#[cfg(test)]
mod test {
use super::*;
use pkey::PKey;
use symm::Cipher;
#[test]
fn public_encrypt_private_decrypt() {
let private_pem = include_bytes!("../test/rsa.pem");
let public_pem = include_bytes!("../test/rsa.pem.pub");
let private_key = PKey::private_key_from_pem(private_pem).unwrap();
let public_key = PKey::public_key_from_pem(public_pem).unwrap();
let cipher = Cipher::aes_256_cbc();
let secret = b"My secret message";
let mut seal = Seal::new(cipher, &[public_key]).unwrap();
let mut encrypted = vec![0; secret.len() + cipher.block_size()];
let mut enc_len = seal.update(secret, &mut encrypted).unwrap();
enc_len += seal.finalize(&mut encrypted[enc_len..]).unwrap();
let iv = seal.iv();
let encrypted_key = &seal.encrypted_keys()[0];
let mut open = Open::new(cipher, &private_key, iv, &encrypted_key).unwrap();
let mut decrypted = vec![0; enc_len + cipher.block_size()];
let mut dec_len = open.update(&encrypted[..enc_len], &mut decrypted).unwrap();
dec_len += open.finalize(&mut decrypted[dec_len..]).unwrap();
assert_eq!(&secret[..], &decrypted[..dec_len]);
}
}

View File

@ -15,14 +15,14 @@
//! Err(e) => println!("Parsing Error: {:?}", e),
//! }
//! ```
use libc::{c_char, c_int, c_ulong};
use std::borrow::Cow;
use libc::{c_ulong, c_char, c_int};
use std::fmt;
use std::error;
use std::ffi::CStr;
use std::fmt;
use std::io;
use std::ptr;
use std::str;
use std::ptr;
use std::borrow::Cow;
use ffi;
@ -41,13 +41,6 @@ impl ErrorStack {
}
ErrorStack(vec)
}
/// Pushes the errors back onto the OpenSSL error stack.
pub fn put(&self) {
for error in self.errors() {
error.put();
}
}
}
impl ErrorStack {
@ -59,10 +52,6 @@ impl ErrorStack {
impl fmt::Display for ErrorStack {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
if self.0.is_empty() {
return fmt.write_str("OpenSSL error");
}
let mut first = true;
for err in &self.0 {
if !first {
@ -133,50 +122,16 @@ impl Error {
None
};
Some(Error {
code,
file,
line,
data,
code: code,
file: file,
line: line,
data: data,
})
}
}
}
}
/// Pushes the error back onto the OpenSSL error stack.
pub fn put(&self) {
unsafe {
ffi::ERR_put_error(
ffi::ERR_GET_LIB(self.code),
ffi::ERR_GET_FUNC(self.code),
ffi::ERR_GET_REASON(self.code),
self.file,
self.line,
);
let data = match self.data {
Some(Cow::Borrowed(data)) => Some((data.as_ptr() as *mut c_char, 0)),
Some(Cow::Owned(ref data)) => {
let ptr = ffi::CRYPTO_malloc(
(data.len() + 1) as _,
concat!(file!(), "\0").as_ptr() as _,
line!() as _,
) as *mut c_char;
if ptr.is_null() {
None
} else {
ptr::copy_nonoverlapping(data.as_ptr(), ptr as *mut u8, data.len());
*ptr.offset(data.len() as isize) = 0;
Some((ptr, ffi::ERR_TXT_MALLOCED))
}
}
None => None,
};
if let Some((ptr, flags)) = data {
ffi::ERR_set_error_data(ptr, flags | ffi::ERR_TXT_STRING);
}
}
}
/// Returns the raw OpenSSL error code for this error.
pub fn code(&self) -> c_ulong {
self.code
@ -228,8 +183,8 @@ impl Error {
}
/// Returns the line in the source file which encountered the error.
pub fn line(&self) -> u32 {
self.line as u32
pub fn line(&self) -> c_int {
self.line
}
/// Returns additional data describing the error.
@ -273,7 +228,7 @@ impl fmt::Display for Error {
}
match self.reason() {
Some(r) => write!(fmt, ":{}", r)?,
None => write!(fmt, ":reason({})", ffi::ERR_GET_REASON(self.code()))?,
None => write!(fmt, ":reason({})", ffi::ERR_GET_FUNC(self.code()))?,
}
write!(
fmt,

View File

@ -1,22 +0,0 @@
//! FIPS 140-2 support.
//!
//! See [OpenSSL's documentation] for details.
//!
//! [OpenSSL's documentation]: https://www.openssl.org/docs/fips/UserGuide-2.0.pdf
use cvt;
use error::ErrorStack;
use ffi;
/// Moves the library into or out of the FIPS 140-2 mode of operation.
///
/// This corresponds to `FIPS_mode_set`.
pub fn enable(enabled: bool) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::FIPS_mode_set(enabled as _)).map(|_| ()) }
}
/// Determines if the library is running in the FIPS 140-2 mode of operation.
///
/// This corresponds to `FIPS_mode`.
pub fn enabled() -> bool {
unsafe { ffi::FIPS_mode() != 0 }
}

View File

@ -1,45 +1,21 @@
use ffi;
use std::fmt;
use std::io;
use std::io::prelude::*;
use std::io;
use std::ops::{Deref, DerefMut};
use std::fmt;
use ffi;
#[cfg(ossl110)]
use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free};
#[cfg(any(ossl101, ossl102))]
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
use error::ErrorStack;
use nid::Nid;
use {cvt, cvt_p};
use error::ErrorStack;
cfg_if! {
if #[cfg(ossl110)] {
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};
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
#[derive(Copy, Clone)]
pub struct MessageDigest(*const ffi::EVP_MD);
impl MessageDigest {
pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self {
MessageDigest(x)
}
/// Returns the `MessageDigest` corresponding to an `Nid`.
///
/// This corresponds to [`EVP_get_digestbynid`].
///
/// [`EVP_get_digestbynid`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestInit.html
pub fn from_nid(type_: Nid) -> Option<MessageDigest> {
unsafe {
let ptr = ffi::EVP_get_digestbynid(type_.as_raw());
if ptr.is_null() {
None
} else {
Some(MessageDigest(ptr))
}
}
}
pub fn md5() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_md5()) }
}
@ -64,36 +40,6 @@ impl MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha512()) }
}
#[cfg(ossl111)]
pub fn sha3_224() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_224()) }
}
#[cfg(ossl111)]
pub fn sha3_256() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_256()) }
}
#[cfg(ossl111)]
pub fn sha3_384() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_384()) }
}
#[cfg(ossl111)]
pub fn sha3_512() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_512()) }
}
#[cfg(ossl111)]
pub fn shake_128() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_shake128()) }
}
#[cfg(ossl111)]
pub fn shake_256() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_shake256()) }
}
pub fn ripemd160() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_ripemd160()) }
}
@ -101,21 +47,8 @@ impl MessageDigest {
pub fn as_ptr(&self) -> *const ffi::EVP_MD {
self.0
}
/// The size of the digest in bytes
pub fn size(&self) -> usize {
unsafe { ffi::EVP_MD_size(self.0) as usize }
}
/// The name of the digest
pub fn type_(&self) -> Nid {
Nid::from_raw(unsafe { ffi::EVP_MD_type(self.0) })
}
}
unsafe impl Sync for MessageDigest {}
unsafe impl Send for MessageDigest {}
#[derive(PartialEq, Copy, Clone)]
enum State {
Reset,
@ -137,7 +70,7 @@ use self::State::*;
/// let data = b"\x42\xF4\x97\xE0";
/// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2";
/// let res = hash(MessageDigest::md5(), data).unwrap();
/// assert_eq!(&*res, spec);
/// assert_eq!(res, spec);
/// ```
///
/// Supply the input in chunks:
@ -151,22 +84,7 @@ use self::State::*;
/// h.update(data[0]).unwrap();
/// h.update(data[1]).unwrap();
/// let res = h.finish().unwrap();
/// assert_eq!(&*res, spec);
/// ```
///
/// Use an XOF hasher (OpenSSL 1.1.1+):
///
/// ```
/// #[cfg(ossl111)]
/// {
/// use openssl::hash::{hash_xof, MessageDigest};
///
/// let data = b"\x41\x6c\x6c\x20\x79\x6f\x75\x72\x20\x62\x61\x73\x65\x20\x61\x72\x65\x20\x62\x65\x6c\x6f\x6e\x67\x20\x74\x6f\x20\x75\x73";
/// let spec = b"\x49\xd0\x69\x7f\xf5\x08\x11\x1d\x8b\x84\xf1\x5e\x46\xda\xf1\x35";
/// let mut buf = vec![0; 16];
/// hash_xof(MessageDigest::shake_128(), data, buf.as_mut_slice()).unwrap();
/// assert_eq!(buf, spec);
/// }
/// assert_eq!(res, spec);
/// ```
///
/// # Warning
@ -174,9 +92,6 @@ use self::State::*;
/// Don't actually use MD5 and SHA-1 hashes, they're not secure anymore.
///
/// Don't ever hash passwords, use the functions in the `pkcs5` module or bcrypt/scrypt instead.
///
/// For extendable output functions (XOFs, i.e. SHAKE128/SHAKE256), you must use finish_xof instead
/// of finish and provide a buf to store the hash. The hash will be as long as the buf.
pub struct Hasher {
ctx: *mut ffi::EVP_MD_CTX,
md: *const ffi::EVP_MD,
@ -184,9 +99,6 @@ pub struct Hasher {
state: State,
}
unsafe impl Sync for Hasher {}
unsafe impl Send for Hasher {}
impl Hasher {
/// Creates a new `Hasher` with the specified hash type.
pub fn new(ty: MessageDigest) -> Result<Hasher, ErrorStack> {
@ -208,7 +120,7 @@ impl Hasher {
match self.state {
Reset => return Ok(()),
Updated => {
self.finish()?;
self.finish2()?;
}
Finalized => (),
}
@ -235,8 +147,15 @@ impl Hasher {
Ok(())
}
/// Returns the hash of the data written and resets the non-XOF hasher.
pub fn finish(&mut self) -> Result<DigestBytes, ErrorStack> {
#[deprecated(note = "use finish2 instead", since = "0.9.11")]
pub fn finish(&mut self) -> Result<Vec<u8>, ErrorStack> {
self.finish2().map(|b| b.to_vec())
}
/// Returns the hash of the data written and resets the hasher.
///
/// Unlike `finish`, this method does not allocate.
pub fn finish2(&mut self) -> Result<DigestBytes, ErrorStack> {
if self.state == Finalized {
self.init()?;
}
@ -255,24 +174,6 @@ 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)]
pub fn finish_xof(&mut self, buf: &mut [u8]) -> Result<(), ErrorStack> {
if self.state == Finalized {
self.init()?;
}
unsafe {
cvt(ffi::EVP_DigestFinalXOF(
self.ctx,
buf.as_mut_ptr(),
buf.len(),
))?;
self.state = Finalized;
Ok(())
}
}
}
impl Write for Hasher {
@ -309,7 +210,7 @@ impl Drop for Hasher {
fn drop(&mut self) {
unsafe {
if self.state != Finalized {
drop(self.finish());
drop(self.finish2());
}
EVP_MD_CTX_free(self.ctx);
}
@ -322,8 +223,8 @@ impl Drop for Hasher {
/// store the digest data.
#[derive(Copy)]
pub struct DigestBytes {
pub(crate) buf: [u8; ffi::EVP_MAX_MD_SIZE as usize],
pub(crate) len: usize,
buf: [u8; ffi::EVP_MAX_MD_SIZE as usize],
len: usize,
}
impl Clone for DigestBytes {
@ -362,72 +263,59 @@ impl fmt::Debug for DigestBytes {
}
}
/// Computes the hash of the `data` with the non-XOF hasher `t`.
pub fn hash(t: MessageDigest, data: &[u8]) -> Result<DigestBytes, ErrorStack> {
let mut h = Hasher::new(t)?;
h.update(data)?;
h.finish()
#[deprecated(note = "use hash2 instead", since = "0.9.11")]
pub fn hash(t: MessageDigest, data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
hash2(t, data).map(|b| b.to_vec())
}
/// Computes the hash of the `data` with the XOF hasher `t` and stores it in `buf`.
#[cfg(ossl111)]
pub fn hash_xof(t: MessageDigest, data: &[u8], buf: &mut [u8]) -> Result<(), ErrorStack> {
/// Computes the hash of the `data` with the hash `t`.
///
/// Unlike `hash`, this function does not allocate the return value.
pub fn hash2(t: MessageDigest, data: &[u8]) -> Result<DigestBytes, ErrorStack> {
let mut h = Hasher::new(t)?;
h.update(data)?;
h.finish_xof(buf)
h.finish2()
}
#[cfg(test)]
mod tests {
use hex::{self, FromHex};
use hex::{FromHex, ToHex};
use std::io::prelude::*;
use super::*;
fn hash_test(hashtype: MessageDigest, hashtest: &(&str, &str)) {
let res = hash(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap();
assert_eq!(hex::encode(res), hashtest.1);
}
#[cfg(ossl111)]
fn hash_xof_test(hashtype: MessageDigest, hashtest: &(&str, &str)) {
let expected = Vec::from_hex(hashtest.1).unwrap();
let mut buf = vec![0; expected.len()];
hash_xof(
hashtype,
&Vec::from_hex(hashtest.0).unwrap(),
buf.as_mut_slice(),
)
.unwrap();
assert_eq!(buf, expected);
let res = hash2(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap();
assert_eq!(res.to_hex(), hashtest.1);
}
fn hash_recycle_test(h: &mut Hasher, hashtest: &(&str, &str)) {
let _ = h.write_all(&Vec::from_hex(hashtest.0).unwrap()).unwrap();
let res = h.finish().unwrap();
assert_eq!(hex::encode(res), hashtest.1);
let res = h.finish2().unwrap();
assert_eq!(res.to_hex(), hashtest.1);
}
// Test vectors from http://www.nsrl.nist.gov/testdata/
#[allow(non_upper_case_globals)]
const md5_tests: [(&'static str, &'static str); 13] = [
("", "d41d8cd98f00b204e9800998ecf8427e"),
("7F", "83acb6e67e50e31db6ed341dd2de1595"),
("EC9C", "0b07f0d4ca797d8ac58874f887cb0b68"),
("FEE57A", "e0d583171eb06d56198fc0ef22173907"),
("42F497E0", "7c430f178aefdf1487fee7144e9641e2"),
("C53B777F1C", "75ef141d64cb37ec423da2d9d440c925"),
("89D5B576327B", "ebbaf15eb0ed784c6faa9dc32831bf33"),
("5D4CCE781EB190", "ce175c4b08172019f05e6b5279889f2c"),
("81901FE94932D7B9", "cd4d2f62b8cdb3a0cf968a735a239281"),
("C9FFDEE7788EFB4EC9", "e0841a231ab698db30c6c0f3f246c014"),
("66AC4B7EBA95E53DC10B", "a3b3cea71910d9af56742aa0bb2fe329"),
("A510CD18F7A56852EB0319", "577e216843dd11573574d3fb209b97d8"),
(
"AAED18DBE8938C19ED734A8D",
"6f80fb775f27e0a4ce5c2f42fc72c5f1",
),
];
const md5_tests: [(&'static str, &'static str); 13] =
[
("", "d41d8cd98f00b204e9800998ecf8427e"),
("7F", "83acb6e67e50e31db6ed341dd2de1595"),
("EC9C", "0b07f0d4ca797d8ac58874f887cb0b68"),
("FEE57A", "e0d583171eb06d56198fc0ef22173907"),
("42F497E0", "7c430f178aefdf1487fee7144e9641e2"),
("C53B777F1C", "75ef141d64cb37ec423da2d9d440c925"),
("89D5B576327B", "ebbaf15eb0ed784c6faa9dc32831bf33"),
("5D4CCE781EB190", "ce175c4b08172019f05e6b5279889f2c"),
("81901FE94932D7B9", "cd4d2f62b8cdb3a0cf968a735a239281"),
("C9FFDEE7788EFB4EC9", "e0841a231ab698db30c6c0f3f246c014"),
("66AC4B7EBA95E53DC10B", "a3b3cea71910d9af56742aa0bb2fe329"),
("A510CD18F7A56852EB0319", "577e216843dd11573574d3fb209b97d8"),
(
"AAED18DBE8938C19ED734A8D",
"6f80fb775f27e0a4ce5c2f42fc72c5f1",
),
];
#[test]
fn test_md5() {
@ -449,9 +337,9 @@ mod tests {
let mut h = Hasher::new(MessageDigest::md5()).unwrap();
h.write_all(&Vec::from_hex(md5_tests[6].0).unwrap())
.unwrap();
h.finish().unwrap();
let res = h.finish().unwrap();
let null = hash(MessageDigest::md5(), &[]).unwrap();
h.finish2().unwrap();
let res = h.finish2().unwrap();
let null = hash2(MessageDigest::md5(), &[]).unwrap();
assert_eq!(&*res, &*null);
}
@ -470,19 +358,19 @@ mod tests {
println!("Clone an updated hasher");
let mut h2 = h1.clone();
h2.write_all(&inp[p..]).unwrap();
let res = h2.finish().unwrap();
assert_eq!(hex::encode(res), md5_tests[i].1);
let res = h2.finish2().unwrap();
assert_eq!(res.to_hex(), md5_tests[i].1);
}
h1.write_all(&inp[p..]).unwrap();
let res = h1.finish().unwrap();
assert_eq!(hex::encode(res), md5_tests[i].1);
let res = h1.finish2().unwrap();
assert_eq!(res.to_hex(), md5_tests[i].1);
println!("Clone a finished hasher");
let mut h3 = h1.clone();
h3.write_all(&Vec::from_hex(md5_tests[i + 1].0).unwrap())
.unwrap();
let res = h3.finish().unwrap();
assert_eq!(hex::encode(res), md5_tests[i + 1].1);
let res = h3.finish2().unwrap();
assert_eq!(res.to_hex(), md5_tests[i + 1].1);
}
#[test]
@ -496,94 +384,18 @@ mod tests {
#[test]
fn test_sha256() {
let tests = [(
"616263",
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
)];
let tests = [
(
"616263",
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
),
];
for test in tests.iter() {
hash_test(MessageDigest::sha256(), test);
}
}
#[cfg(ossl111)]
#[test]
fn test_sha3_224() {
let tests = [(
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"1de092dd9fbcbbf450f26264f4778abd48af851f2832924554c56913",
)];
for test in tests.iter() {
hash_test(MessageDigest::sha3_224(), test);
}
}
#[cfg(ossl111)]
#[test]
fn test_sha3_256() {
let tests = [(
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"b38e38f08bc1c0091ed4b5f060fe13e86aa4179578513ad11a6e3abba0062f61",
)];
for test in tests.iter() {
hash_test(MessageDigest::sha3_256(), test);
}
}
#[cfg(ossl111)]
#[test]
fn test_sha3_384() {
let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"966ee786ab3482dd811bf7c8fa8db79aa1f52f6c3c369942ef14240ebd857c6ff626ec35d9e131ff64d328\
ef2008ff16"
)];
for test in tests.iter() {
hash_test(MessageDigest::sha3_384(), test);
}
}
#[cfg(ossl111)]
#[test]
fn test_sha3_512() {
let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"c072288ef728cd53a029c47687960b9225893532f42b923156e37020bdc1eda753aafbf30af859d4f4c3a1\
807caee3a79f8eb02dcd61589fbbdf5f40c8787a72"
)];
for test in tests.iter() {
hash_test(MessageDigest::sha3_512(), test);
}
}
#[cfg(ossl111)]
#[test]
fn test_shake_128() {
let tests = [(
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"49d0697ff508111d8b84f15e46daf135",
)];
for test in tests.iter() {
hash_xof_test(MessageDigest::shake_128(), test);
}
}
#[cfg(ossl111)]
#[test]
fn test_shake_256() {
let tests = [(
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"4e2dfdaa75d1e049d0eaeffe28e76b17cea47b650fb8826fe48b94664326a697",
)];
for test in tests.iter() {
hash_xof_test(MessageDigest::shake_256(), test);
}
}
#[test]
fn test_ripemd160() {
let tests = [("616263", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc")];
@ -592,12 +404,4 @@ mod tests {
hash_test(MessageDigest::ripemd160(), test);
}
}
#[test]
fn from_nid() {
assert_eq!(
MessageDigest::from_nid(Nid::SHA256).unwrap().as_ptr(),
MessageDigest::sha256().as_ptr()
);
}
}

View File

@ -1,129 +1,20 @@
//! Bindings to OpenSSL
//!
//! This crate provides a safe interface to the popular OpenSSL cryptography library. OpenSSL versions 1.0.1 through
//! 1.1.1 and LibreSSL versions 2.5 through 2.8 are supported.
//!
//! # Building
//!
//! Both OpenSSL libraries and headers are required to build this crate. There are multiple options available to locate
//! OpenSSL.
//!
//! ## Vendored
//!
//! If the `vendored` Cargo feature is enabled, the `openssl-src` crate will be used to compile and statically link to
//! a copy of OpenSSL. The build process requires a C compiler, perl, and make. The OpenSSL version will generally track
//! the newest OpenSSL release, and changes to the version are *not* considered breaking changes.
//!
//! ```toml
//! [dependencies]
//! 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.
//!
//! ## Automatic
//!
//! The `openssl-sys` crate will automatically detect OpenSSL installations via Homebrew on macOS and vcpkg on Windows.
//! Additionally, it will use `pkg-config` on Unix-like systems to find the system installation.
//!
//! ```not_rust
//! # macOS
//! $ brew install openssl@1.1
//!
//! # Arch Linux
//! $ sudo pacman -S pkg-config openssl
//!
//! # Debian and Ubuntu
//! $ sudo apt-get install pkg-config libssl-dev
//!
//! # Fedora
//! $ sudo dnf install pkg-config openssl-devel
//! ```
//!
//! ## Manual
//!
//! A set of environment variables can be used to point `openssl-sys` towards an OpenSSL installation. They will
//! 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.
//! * `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.
//! * `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.
//!
//! 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.
//!
//! # Feature Detection
//!
//! APIs have been added to and removed from the various supported OpenSSL versions, and this library exposes the
//! functionality available in the version being linked against. This means that methods, constants, and even modules
//! will be present when building against one version of OpenSSL but not when building against another! APIs will
//! document any version-specific availability restrictions.
//!
//! A build script can be used to detect the OpenSSL or LibreSSL version at compile time if needed. The `openssl-sys`
//! crate propagates the version via the `DEP_OPENSSL_VERSION_NUMBER` and `DEP_OPENSSL_LIBRESSL_VERSION_NUMBER`
//! environment variables to build scripts. The version format is a hex-encoding of the OpenSSL release version:
//! `0xMNNFFPPS`. For example, version 1.0.2g's encoding is `0x1_00_02_07_0`.
//!
//! For example, let's say we want to adjust the TLSv1.3 cipher suites used by a client, but also want to compile
//! against OpenSSL versions that don't support TLSv1.3:
//!
//! Cargo.toml:
//!
//! ```toml
//! [dependencies]
//! openssl-sys = "0.9"
//! openssl = "0.10"
//! ```
//!
//! build.rs:
//!
//! ```
//! use std::env;
//!
//! fn main() {
//! if let Ok(v) = env::var("DEP_OPENSSL_VERSION_NUMBER") {
//! let version = u64::from_str_radix(&v, 16).unwrap();
//!
//! if version >= 0x1_01_01_00_0 {
//! println!("cargo:rustc-cfg=openssl111");
//! }
//! }
//! }
//! ```
//!
//! lib.rs:
//!
//! ```
//! use openssl::ssl::{SslConnector, SslMethod};
//!
//! let mut ctx = SslConnector::builder(SslMethod::tls()).unwrap();
//!
//! // set_ciphersuites was added in OpenSSL 1.1.1, so we can only call it when linking against that version
//! #[cfg(openssl111)]
//! ctx.set_ciphersuites("TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256").unwrap();
//! ```
#![doc(html_root_url = "https://docs.rs/openssl/0.10")]
#![doc(html_root_url="https://docs.rs/openssl/0.9")]
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate cfg_if;
#[macro_use]
extern crate foreign_types;
extern crate libc;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate openssl_sys as ffi;
#[cfg(test)]
extern crate hex;
#[cfg(test)]
extern crate tempdir;
#[cfg(test)]
extern crate data_encoding;
#[doc(inline)]
pub use ffi::init;
@ -144,35 +35,33 @@ pub mod bn;
#[cfg(not(libressl))]
pub mod cms;
pub mod conf;
pub mod derive;
pub mod crypto;
pub mod dh;
pub mod dsa;
pub mod ec;
pub mod ecdsa;
pub mod envelope;
pub mod ec_key;
pub mod error;
pub mod ex_data;
#[cfg(not(libressl))]
pub mod fips;
pub mod hash;
pub mod memcmp;
pub mod nid;
pub mod ocsp;
pub mod pkcs12;
pub mod pkcs5;
pub mod pkcs7;
pub mod pkey;
pub mod rand;
pub mod rsa;
pub mod sha;
pub mod sign;
pub mod srtp;
pub mod sha;
pub mod ssl;
pub mod stack;
pub mod string;
pub mod symm;
pub mod types;
pub mod version;
pub mod x509;
#[cfg(any(ossl102, ossl110))]
mod verify;
fn cvt_p<T>(r: *mut T) -> Result<*mut T, ErrorStack> {
if r.is_null() {
@ -191,9 +80,5 @@ fn cvt(r: c_int) -> Result<c_int, ErrorStack> {
}
fn cvt_n(r: c_int) -> Result<c_int, ErrorStack> {
if r < 0 {
Err(ErrorStack::get())
} else {
Ok(r)
}
if r < 0 { Err(ErrorStack::get()) } else { Ok(r) }
}

View File

@ -1,9 +1,18 @@
macro_rules! private_key_from_pem {
($(#[$m:meta])* $n:ident, $(#[$m2:meta])* $n2:ident, $(#[$m3:meta])* $n3:ident, $t:ty, $f:path) => {
from_pem!($(#[$m])* $n, $t, $f);
$(#[$m2])*
pub fn $n2(pem: &[u8], passphrase: &[u8]) -> Result<$t, ::error::ErrorStack> {
macro_rules! private_key_from_pem {
($t:ident, $f:path) => {
from_pem_inner!(/// Deserializes a PEM-formatted private key.
private_key_from_pem, $t, $f);
/// Deserializes a PEM-formatted private key, using the supplied password if the key is
/// encrypted.
///
/// # Panics
///
/// Panics if `passphrase` contains an embedded null.
pub fn private_key_from_pem_passphrase(pem: &[u8],
passphrase: &[u8])
-> Result<$t, ::error::ErrorStack> {
unsafe {
ffi::init();
let bio = try!(::bio::MemBioSlice::new(pem));
@ -12,12 +21,18 @@ macro_rules! private_key_from_pem {
ptr::null_mut(),
None,
passphrase.as_ptr() as *const _ as *mut _))
.map(|p| ::foreign_types::ForeignType::from_ptr(p))
.map($t)
}
}
$(#[$m3])*
pub fn $n3<F>(pem: &[u8], callback: F) -> Result<$t, ::error::ErrorStack>
/// Deserializes a PEM-formatted private key, using a callback to retrieve a password if the
/// key is encrypted.
///
/// The callback should copy the password into the provided buffer and return the number of
/// bytes written.
pub fn private_key_from_pem_callback<F>(pem: &[u8],
callback: F)
-> Result<$t, ::error::ErrorStack>
where F: FnOnce(&mut [u8]) -> Result<usize, ::error::ErrorStack>
{
unsafe {
@ -28,16 +43,16 @@ macro_rules! private_key_from_pem {
ptr::null_mut(),
Some(::util::invoke_passwd_cb::<F>),
&mut cb as *mut _ as *mut _))
.map(|p| ::foreign_types::ForeignType::from_ptr(p))
.map($t)
}
}
}
}
macro_rules! private_key_to_pem {
($(#[$m:meta])* $n:ident, $(#[$m2:meta])* $n2:ident, $f:path) => {
$(#[$m])*
pub fn $n(&self) -> Result<Vec<u8>, ::error::ErrorStack> {
($f:path) => {
/// Serializes the private key to PEM.
pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ::error::ErrorStack> {
unsafe {
let bio = try!(::bio::MemBio::new());
try!(cvt($f(bio.as_ptr(),
@ -51,12 +66,12 @@ macro_rules! private_key_to_pem {
}
}
$(#[$m2])*
pub fn $n2(
&self,
cipher: ::symm::Cipher,
passphrase: &[u8]
) -> Result<Vec<u8>, ::error::ErrorStack> {
/// Serializes the private key to PEM, encrypting it with the specified symmetric cipher and
/// passphrase.
pub fn private_key_to_pem_passphrase(&self,
cipher: ::symm::Cipher,
passphrase: &[u8])
-> Result<Vec<u8>, ::error::ErrorStack> {
unsafe {
let bio = try!(::bio::MemBio::new());
assert!(passphrase.len() <= ::libc::c_int::max_value() as usize);
@ -73,9 +88,9 @@ macro_rules! private_key_to_pem {
}
}
macro_rules! to_pem {
($(#[$m:meta])* $n:ident, $f:path) => {
$(#[$m])*
macro_rules! to_pem_inner {
(#[$m:meta] $n:ident, $f:path) => {
#[$m]
pub fn $n(&self) -> Result<Vec<u8>, ::error::ErrorStack> {
unsafe {
let bio = try!(::bio::MemBio::new());
@ -86,9 +101,23 @@ macro_rules! to_pem {
}
}
macro_rules! to_der {
($(#[$m:meta])* $n:ident, $f:path) => {
$(#[$m])*
macro_rules! public_key_to_pem {
($f:path) => {
to_pem_inner!(/// Serializes a public key to PEM.
public_key_to_pem, $f);
}
}
macro_rules! to_pem {
($f:path) => {
to_pem_inner!(/// Serializes this value to PEM.
to_pem, $f);
}
}
macro_rules! to_der_inner {
(#[$m:meta] $n:ident, $f:path) => {
#[$m]
pub fn $n(&self) -> Result<Vec<u8>, ::error::ErrorStack> {
unsafe {
let len = try!(::cvt($f(::foreign_types::ForeignTypeRef::as_ptr(self),
@ -102,34 +131,91 @@ macro_rules! to_der {
};
}
macro_rules! from_der {
($(#[$m:meta])* $n:ident, $t:ty, $f:path) => {
$(#[$m])*
macro_rules! to_der {
($f:path) => {
to_der_inner!(/// Serializes this value to DER.
to_der, $f);
}
}
macro_rules! private_key_to_der {
($f:path) => {
to_der_inner!(/// Serializes the private key to DER.
private_key_to_der, $f);
}
}
macro_rules! public_key_to_der {
($f:path) => {
to_der_inner!(/// Serializes the public key to DER.
public_key_to_der, $f);
}
}
macro_rules! from_der_inner {
(#[$m:meta] $n:ident, $t:ident, $f:path) => {
#[$m]
pub fn $n(der: &[u8]) -> Result<$t, ::error::ErrorStack> {
unsafe {
::ffi::init();
let len = ::std::cmp::min(der.len(), ::libc::c_long::max_value() as usize) as ::libc::c_long;
::cvt_p($f(::std::ptr::null_mut(), &mut der.as_ptr(), len))
.map(|p| ::foreign_types::ForeignType::from_ptr(p))
.map($t)
}
}
}
}
macro_rules! from_pem {
($(#[$m:meta])* $n:ident, $t:ty, $f:path) => {
$(#[$m])*
macro_rules! from_der {
($t:ident, $f:path) => {
from_der_inner!(/// Deserializes a value from DER-formatted data.
from_der, $t, $f);
}
}
macro_rules! private_key_from_der {
($t:ident, $f:path) => {
from_der_inner!(/// Deserializes a private key from DER-formatted data.
private_key_from_der, $t, $f);
}
}
macro_rules! public_key_from_der {
($t:ident, $f:path) => {
from_der_inner!(/// Deserializes a public key from DER-formatted data.
public_key_from_der, $t, $f);
}
}
macro_rules! from_pem_inner {
(#[$m:meta] $n:ident, $t:ident, $f:path) => {
#[$m]
pub fn $n(pem: &[u8]) -> Result<$t, ::error::ErrorStack> {
unsafe {
::init();
let bio = try!(::bio::MemBioSlice::new(pem));
cvt_p($f(bio.as_ptr(), ::std::ptr::null_mut(), None, ::std::ptr::null_mut()))
.map(|p| ::foreign_types::ForeignType::from_ptr(p))
.map($t)
}
}
}
}
macro_rules! public_key_from_pem {
($t:ident, $f:path) => {
from_pem_inner!(/// Deserializes a public key from PEM-formatted data.
public_key_from_pem, $t, $f);
}
}
macro_rules! from_pem {
($t:ident, $f:path) => {
from_pem_inner!(/// Deserializes a value from PEM-formatted data.
from_pem, $t, $f);
}
}
macro_rules! foreign_type_and_impl_send_sync {
(
$(#[$impl_attr:meta])*
@ -160,110 +246,3 @@ macro_rules! foreign_type_and_impl_send_sync {
unsafe impl Sync for $borrowed{}
};
}
macro_rules! generic_foreign_type_and_impl_send_sync {
(
$(#[$impl_attr:meta])*
type CType = $ctype:ty;
fn drop = $drop:expr;
$(fn clone = $clone:expr;)*
$(#[$owned_attr:meta])*
pub struct $owned:ident<T>;
$(#[$borrowed_attr:meta])*
pub struct $borrowed:ident<T>;
) => {
$(#[$owned_attr])*
pub struct $owned<T>(*mut $ctype, ::std::marker::PhantomData<T>);
$(#[$impl_attr])*
impl<T> ::foreign_types::ForeignType for $owned<T> {
type CType = $ctype;
type Ref = $borrowed<T>;
#[inline]
unsafe fn from_ptr(ptr: *mut $ctype) -> $owned<T> {
$owned(ptr, ::std::marker::PhantomData)
}
#[inline]
fn as_ptr(&self) -> *mut $ctype {
self.0
}
}
impl<T> Drop for $owned<T> {
#[inline]
fn drop(&mut self) {
unsafe { $drop(self.0) }
}
}
$(
impl<T> Clone for $owned<T> {
#[inline]
fn clone(&self) -> $owned<T> {
unsafe {
let handle: *mut $ctype = $clone(self.0);
::foreign_types::ForeignType::from_ptr(handle)
}
}
}
impl<T> ::std::borrow::ToOwned for $borrowed<T> {
type Owned = $owned<T>;
#[inline]
fn to_owned(&self) -> $owned<T> {
unsafe {
let handle: *mut $ctype =
$clone(::foreign_types::ForeignTypeRef::as_ptr(self));
$crate::ForeignType::from_ptr(handle)
}
}
}
)*
impl<T> ::std::ops::Deref for $owned<T> {
type Target = $borrowed<T>;
#[inline]
fn deref(&self) -> &$borrowed<T> {
unsafe { ::foreign_types::ForeignTypeRef::from_ptr(self.0) }
}
}
impl<T> ::std::ops::DerefMut for $owned<T> {
#[inline]
fn deref_mut(&mut self) -> &mut $borrowed<T> {
unsafe { ::foreign_types::ForeignTypeRef::from_ptr_mut(self.0) }
}
}
impl<T> ::std::borrow::Borrow<$borrowed<T>> for $owned<T> {
#[inline]
fn borrow(&self) -> &$borrowed<T> {
&**self
}
}
impl<T> ::std::convert::AsRef<$borrowed<T>> for $owned<T> {
#[inline]
fn as_ref(&self) -> &$borrowed<T> {
&**self
}
}
$(#[$borrowed_attr])*
pub struct $borrowed<T>(::foreign_types::Opaque, ::std::marker::PhantomData<T>);
$(#[$impl_attr])*
impl<T> ::foreign_types::ForeignTypeRef for $borrowed<T> {
type CType = $ctype;
}
unsafe impl<T> Send for $owned<T>{}
unsafe impl<T> Send for $borrowed<T>{}
unsafe impl<T> Sync for $owned<T>{}
unsafe impl<T> Sync for $borrowed<T>{}
};
}

View File

@ -29,8 +29,8 @@
//! assert!(!eq(&a, &b));
//! assert!(!eq(&a, &c));
//! ```
use ffi;
use libc::size_t;
use ffi;
/// Returns `true` iff `a` and `b` contain the same bytes.
///

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +1,69 @@
use ffi;
use foreign_types::ForeignTypeRef;
use libc::{c_int, c_long, c_ulong};
use std::mem;
use std::ptr;
use std::mem;
use {cvt, cvt_p};
use asn1::Asn1GeneralizedTimeRef;
use error::ErrorStack;
use hash::MessageDigest;
use stack::StackRef;
use x509::store::X509StoreRef;
use x509::{X509Ref, X509};
use {cvt, cvt_p};
use x509::{X509, X509Ref};
bitflags! {
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;
pub struct Flag: c_ulong {
const FLAG_NO_CERTS = ffi::OCSP_NOCERTS;
const FLAG_NO_INTERN = ffi::OCSP_NOINTERN;
const FLAG_NO_CHAIN = ffi::OCSP_NOCHAIN;
const FLAG_NO_VERIFY = ffi::OCSP_NOVERIFY;
const FLAG_NO_EXPLICIT = ffi::OCSP_NOEXPLICIT;
const FLAG_NO_CA_SIGN = ffi::OCSP_NOCASIGN;
const FLAG_NO_DELEGATED = ffi::OCSP_NODELEGATED;
const FLAG_NO_CHECKS = ffi::OCSP_NOCHECKS;
const FLAG_TRUST_OTHER = ffi::OCSP_TRUSTOTHER;
const FLAG_RESPID_KEY = ffi::OCSP_RESPID_KEY;
const FLAG_NO_TIME = ffi::OCSP_NOTIME;
}
}
pub const RESPONSE_STATUS_SUCCESSFUL: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SUCCESSFUL);
pub const RESPONSE_STATUS_MALFORMED_REQUEST: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_MALFORMEDREQUEST);
pub const RESPONSE_STATUS_INTERNAL_ERROR: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_INTERNALERROR);
pub const RESPONSE_STATUS_TRY_LATER: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_TRYLATER);
pub const RESPONSE_STATUS_SIG_REQUIRED: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SIGREQUIRED);
pub const RESPONSE_STATUS_UNAUTHORIZED: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_UNAUTHORIZED);
pub const CERT_STATUS_GOOD: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_GOOD);
pub const CERT_STATUS_REVOKED: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_REVOKED);
pub const CERT_STATUS_UNKNOWN: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_UNKNOWN);
pub const REVOKED_STATUS_NO_STATUS: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_NOSTATUS);
pub const REVOKED_STATUS_UNSPECIFIED: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_UNSPECIFIED);
pub const REVOKED_STATUS_KEY_COMPROMISE: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_KEYCOMPROMISE);
pub const REVOKED_STATUS_CA_COMPROMISE: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CACOMPROMISE);
pub const REVOKED_STATUS_AFFILIATION_CHANGED: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_AFFILIATIONCHANGED);
pub const REVOKED_STATUS_SUPERSEDED: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_SUPERSEDED);
pub const REVOKED_STATUS_CESSATION_OF_OPERATION: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CESSATIONOFOPERATION);
pub const REVOKED_STATUS_CERTIFICATE_HOLD: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CERTIFICATEHOLD);
pub const REVOKED_STATUS_REMOVE_FROM_CRL: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_REMOVEFROMCRL);
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct OcspResponseStatus(c_int);
@ -39,19 +75,6 @@ impl OcspResponseStatus {
pub fn as_raw(&self) -> c_int {
self.0
}
pub const SUCCESSFUL: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SUCCESSFUL);
pub const MALFORMED_REQUEST: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_MALFORMEDREQUEST);
pub const INTERNAL_ERROR: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_INTERNALERROR);
pub const TRY_LATER: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_TRYLATER);
pub const SIG_REQUIRED: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SIGREQUIRED);
pub const UNAUTHORIZED: OcspResponseStatus =
OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_UNAUTHORIZED);
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@ -65,10 +88,6 @@ impl OcspCertStatus {
pub fn as_raw(&self) -> c_int {
self.0
}
pub const GOOD: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_GOOD);
pub const REVOKED: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_REVOKED);
pub const UNKNOWN: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_UNKNOWN);
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@ -82,27 +101,9 @@ impl OcspRevokedStatus {
pub fn as_raw(&self) -> c_int {
self.0
}
pub const NO_STATUS: OcspRevokedStatus = OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_NOSTATUS);
pub const UNSPECIFIED: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_UNSPECIFIED);
pub const KEY_COMPROMISE: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_KEYCOMPROMISE);
pub const CA_COMPROMISE: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CACOMPROMISE);
pub const AFFILIATION_CHANGED: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_AFFILIATIONCHANGED);
pub const STATUS_SUPERSEDED: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_SUPERSEDED);
pub const STATUS_CESSATION_OF_OPERATION: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CESSATIONOFOPERATION);
pub const STATUS_CERTIFICATE_HOLD: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CERTIFICATEHOLD);
pub const REMOVE_FROM_CRL: OcspRevokedStatus =
OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_REMOVEFROMCRL);
}
pub struct OcspStatus<'a> {
pub struct Status<'a> {
/// The overall status of the response.
pub status: OcspCertStatus,
/// If `status` is `CERT_STATUS_REVOKED`, the reason for the revocation.
@ -115,7 +116,7 @@ pub struct OcspStatus<'a> {
pub next_update: &'a Asn1GeneralizedTimeRef,
}
impl<'a> OcspStatus<'a> {
impl<'a> Status<'a> {
/// 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
@ -130,8 +131,7 @@ impl<'a> OcspStatus<'a> {
self.next_update.as_ptr(),
nsec as c_long,
maxsec.map(|n| n as c_long).unwrap_or(-1),
))
.map(|_| ())
)).map(|_| ())
}
}
}
@ -153,7 +153,7 @@ impl OcspBasicResponseRef {
&self,
certs: &StackRef<X509>,
store: &X509StoreRef,
flags: OcspFlag,
flags: Flag,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::OCSP_basic_verify(
@ -161,13 +161,12 @@ impl OcspBasicResponseRef {
certs.as_ptr(),
store.as_ptr(),
flags.bits(),
))
.map(|_| ())
)).map(|_| ())
}
}
/// Looks up the status for the specified certificate ID.
pub fn find_status<'a>(&'a self, id: &OcspCertIdRef) -> Option<OcspStatus<'a>> {
pub fn find_status<'a>(&'a self, id: &OcspCertIdRef) -> Option<Status<'a>> {
unsafe {
let mut status = ffi::V_OCSP_CERTSTATUS_UNKNOWN;
let mut reason = ffi::OCSP_REVOKED_STATUS_NOSTATUS;
@ -190,7 +189,7 @@ impl OcspBasicResponseRef {
} else {
Some(Asn1GeneralizedTimeRef::from_ptr(revocation_time))
};
Some(OcspStatus {
Some(Status {
status: OcspCertStatus(status),
reason: OcspRevokedStatus(status),
revocation_time: revocation_time,
@ -224,8 +223,7 @@ impl OcspCertId {
digest.as_ptr(),
subject.as_ptr(),
issuer.as_ptr(),
))
.map(OcspCertId)
)).map(OcspCertId)
}
}
}
@ -252,33 +250,15 @@ impl OcspResponse {
cvt_p(ffi::OCSP_response_create(
status.as_raw(),
body.map(|r| r.as_ptr()).unwrap_or(ptr::null_mut()),
))
.map(OcspResponse)
)).map(OcspResponse)
}
}
from_der! {
/// Deserializes a DER-encoded OCSP response.
///
/// This corresponds to [`d2i_OCSP_RESPONSE`].
///
/// [`d2i_OCSP_RESPONSE`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_OCSP_RESPONSE.html
from_der,
OcspResponse,
ffi::d2i_OCSP_RESPONSE
}
from_der!(OcspResponse, ffi::d2i_OCSP_RESPONSE);
}
impl OcspResponseRef {
to_der! {
/// Serializes the response to its standard DER encoding.
///
/// This corresponds to [`i2d_OCSP_RESPONSE`].
///
/// [`i2d_OCSP_RESPONSE`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_OCSP_RESPONSE.html
to_der,
ffi::i2d_OCSP_RESPONSE
}
to_der!(ffi::i2d_OCSP_RESPONSE);
/// Returns the status of the response.
pub fn status(&self) -> OcspResponseStatus {
@ -310,28 +290,11 @@ impl OcspRequest {
}
}
from_der! {
/// Deserializes a DER-encoded OCSP request.
///
/// This corresponds to [`d2i_OCSP_REQUEST`].
///
/// [`d2i_OCSP_REQUEST`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_OCSP_REQUEST.html
from_der,
OcspRequest,
ffi::d2i_OCSP_REQUEST
}
from_der!(OcspRequest, ffi::d2i_OCSP_REQUEST);
}
impl OcspRequestRef {
to_der! {
/// Serializes the request to its standard DER encoding.
///
/// This corresponds to [`i2d_OCSP_REQUEST`].
///
/// [`i2d_OCSP_REQUEST`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_OCSP_REQUEST.html
to_der,
ffi::i2d_OCSP_REQUEST
}
to_der!(ffi::i2d_OCSP_REQUEST);
pub fn add_id(&mut self, id: OcspCertId) -> Result<&mut OcspOneReqRef, ErrorStack> {
unsafe {

View File

@ -3,15 +3,15 @@
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use std::ffi::CString;
use std::ptr;
use std::ffi::CString;
use error::ErrorStack;
use nid::Nid;
use pkey::{HasPrivate, PKey, PKeyRef, Private};
use stack::Stack;
use x509::{X509Ref, X509};
use {cvt, cvt_p};
use pkey::{PKey, PKeyRef};
use error::ErrorStack;
use x509::X509;
use stack::Stack;
use nid;
foreign_type_and_impl_send_sync! {
type CType = ffi::PKCS12;
@ -22,20 +22,13 @@ foreign_type_and_impl_send_sync! {
}
impl Pkcs12Ref {
to_der! {
/// Serializes the `Pkcs12` to its standard DER encoding.
///
/// This corresponds to [`i2d_PKCS12`].
///
/// [`i2d_PKCS12`]: https://www.openssl.org/docs/manmaster/man3/i2d_PKCS12.html
to_der,
ffi::i2d_PKCS12
}
to_der!(ffi::i2d_PKCS12);
/// Extracts the contents of the `Pkcs12`.
// FIXME should take an &[u8]
pub fn parse(&self, pass: &str) -> Result<ParsedPkcs12, ErrorStack> {
unsafe {
let pass = CString::new(pass.as_bytes()).unwrap();
let pass = CString::new(pass).unwrap();
let mut pkey = ptr::null_mut();
let mut cert = ptr::null_mut();
@ -53,9 +46,9 @@ impl Pkcs12Ref {
let cert = X509::from_ptr(cert);
let chain = if chain.is_null() {
None
Stack::new()?
} else {
Some(Stack::from_ptr(chain))
Stack::from_ptr(chain)
};
Ok(ParsedPkcs12 {
@ -68,16 +61,7 @@ impl Pkcs12Ref {
}
impl Pkcs12 {
from_der! {
/// Deserializes a DER-encoded PKCS#12 archive.
///
/// This corresponds to [`d2i_PKCS12`].
///
/// [`d2i_PKCS12`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_PKCS12.html
from_der,
Pkcs12,
ffi::d2i_PKCS12
}
from_der!(Pkcs12, ffi::d2i_PKCS12);
/// Creates a new builder for a protected pkcs12 certificate.
///
@ -91,8 +75,8 @@ impl Pkcs12 {
ffi::init();
Pkcs12Builder {
nid_key: Nid::UNDEF, //nid::PBE_WITHSHA1AND3_KEY_TRIPLEDES_CBC,
nid_cert: Nid::UNDEF, //nid::PBE_WITHSHA1AND40BITRC2_CBC,
nid_key: nid::UNDEF, //nid::PBE_WITHSHA1AND3_KEY_TRIPLEDES_CBC,
nid_cert: nid::UNDEF, //nid::PBE_WITHSHA1AND40BITRC2_CBC,
iter: ffi::PKCS12_DEFAULT_ITER,
mac_iter: ffi::PKCS12_DEFAULT_ITER,
ca: None,
@ -101,14 +85,15 @@ impl Pkcs12 {
}
pub struct ParsedPkcs12 {
pub pkey: PKey<Private>,
pub pkey: PKey,
pub cert: X509,
pub chain: Option<Stack<X509>>,
// FIXME Make this Option<Stack> in the next breaking release
pub chain: Stack<X509>,
}
pub struct Pkcs12Builder {
nid_key: Nid,
nid_cert: Nid,
nid_key: nid::Nid,
nid_cert: nid::Nid,
iter: c_int,
mac_iter: c_int,
ca: Option<Stack<X509>>,
@ -116,13 +101,13 @@ pub struct Pkcs12Builder {
impl Pkcs12Builder {
/// The encryption algorithm that should be used for the key
pub fn key_algorithm(&mut self, nid: Nid) -> &mut Self {
pub fn key_algorithm(&mut self, nid: nid::Nid) -> &mut Self {
self.nid_key = nid;
self
}
/// The encryption algorithm that should be used for the cert
pub fn cert_algorithm(&mut self, nid: Nid) -> &mut Self {
pub fn cert_algorithm(&mut self, nid: nid::Nid) -> &mut Self {
self.nid_cert = nid;
self
}
@ -157,26 +142,21 @@ impl Pkcs12Builder {
/// * `friendly_name` - user defined name for the certificate
/// * `pkey` - key to store
/// * `cert` - certificate to store
pub fn build<T>(
pub fn build(
self,
password: &str,
friendly_name: &str,
pkey: &PKeyRef<T>,
cert: &X509Ref,
) -> Result<Pkcs12, ErrorStack>
where
T: HasPrivate,
{
pkey: &PKeyRef,
cert: &X509,
) -> Result<Pkcs12, ErrorStack> {
unsafe {
let pass = CString::new(password).unwrap();
let friendly_name = CString::new(friendly_name).unwrap();
let pkey = pkey.as_ptr();
let cert = cert.as_ptr();
let ca = self
.ca
.as_ref()
.map(|ca| ca.as_ptr())
.unwrap_or(ptr::null_mut());
let ca = self.ca.as_ref().map(|ca| ca.as_ptr()).unwrap_or(
ptr::null_mut(),
);
let nid_key = self.nid_key.as_raw();
let nid_cert = self.nid_cert.as_raw();
@ -196,8 +176,7 @@ impl Pkcs12Builder {
self.iter,
self.mac_iter,
keytype,
))
.map(Pkcs12)
)).map(Pkcs12)
}
}
}
@ -205,14 +184,14 @@ impl Pkcs12Builder {
#[cfg(test)]
mod test {
use hash::MessageDigest;
use hex;
use hex::ToHex;
use asn1::Asn1Time;
use nid::Nid;
use pkey::PKey;
use rsa::Rsa;
use pkey::PKey;
use nid;
use x509::{X509, X509Name};
use x509::extension::KeyUsage;
use x509::{X509Name, X509};
use super::*;
@ -223,14 +202,20 @@ mod test {
let parsed = pkcs12.parse("mypass").unwrap();
assert_eq!(
hex::encode(parsed.cert.digest(MessageDigest::sha1()).unwrap()),
parsed
.cert
.fingerprint(MessageDigest::sha1())
.unwrap()
.to_hex(),
"59172d9313e84459bcff27f967e79e6e9217e584"
);
let chain = parsed.chain.unwrap();
assert_eq!(chain.len(), 1);
assert_eq!(parsed.chain.len(), 1);
assert_eq!(
hex::encode(chain[0].digest(MessageDigest::sha1()).unwrap()),
parsed.chain[0]
.fingerprint(MessageDigest::sha1())
.unwrap()
.to_hex(),
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
);
}
@ -240,7 +225,9 @@ mod test {
let der = include_bytes!("../test/keystore-empty-chain.p12");
let pkcs12 = Pkcs12::from_der(der).unwrap();
let parsed = pkcs12.parse("cassandra").unwrap();
assert!(parsed.chain.is_none());
assert_eq!(parsed.chain.len(), 0);
assert_eq!(parsed.chain.into_iter().collect::<Vec<_>>().len(), 0);
}
#[test]
@ -250,7 +237,7 @@ mod test {
let pkey = PKey::from_rsa(rsa).unwrap();
let mut name = X509Name::builder().unwrap();
name.append_entry_by_nid(Nid::COMMONNAME, subject_name)
name.append_entry_by_nid(nid::COMMONNAME, subject_name)
.unwrap();
let name = name.build();
@ -281,8 +268,8 @@ mod test {
let parsed = pkcs12.parse("mypass").unwrap();
assert_eq!(
&*parsed.cert.digest(MessageDigest::sha1()).unwrap(),
&*cert.digest(MessageDigest::sha1()).unwrap()
parsed.cert.fingerprint(MessageDigest::sha1()).unwrap(),
cert.fingerprint(MessageDigest::sha1()).unwrap()
);
assert!(parsed.pkey.public_eq(&pkey));
}

View File

@ -1,11 +1,11 @@
use ffi;
use libc::c_int;
use std::ptr;
use ffi;
use cvt;
use error::ErrorStack;
use hash::MessageDigest;
use symm::Cipher;
use error::ErrorStack;
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct KeyIvPair {
@ -59,10 +59,9 @@ pub fn bytes_to_key(
))?;
let mut key = vec![0; len as usize];
let iv_ptr = iv
.as_mut()
.map(|v| v.as_mut_ptr())
.unwrap_or(ptr::null_mut());
let iv_ptr = iv.as_mut().map(|v| v.as_mut_ptr()).unwrap_or(
ptr::null_mut(),
);
cvt(ffi::EVP_BytesToKey(
cipher,
@ -102,15 +101,14 @@ pub fn pbkdf2_hmac(
hash.as_ptr(),
key.len() as c_int,
key.as_mut_ptr(),
))
.map(|_| ())
)).map(|_| ())
}
}
/// Derives a key from a password and salt using the scrypt algorithm.
///
/// Requires OpenSSL 1.1.0 or newer.
#[cfg(any(ossl110))]
/// Requires the `v110` feature and OpenSSL 1.1.0.
#[cfg(all(feature = "v110", ossl110))]
pub fn scrypt(
pass: &[u8],
salt: &[u8],
@ -133,8 +131,7 @@ pub fn scrypt(
maxmem,
key.as_mut_ptr() as *mut _,
key.len(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -153,9 +150,24 @@ mod tests {
assert_eq!(
buf,
&[
0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8, 0xec_u8,
0x16_u8, 0x91_u8, 0xc2_u8, 0x25_u8, 0x44_u8, 0xb6_u8, 0x05_u8,
][..]
0x55_u8,
0xac_u8,
0x04_u8,
0x6e_u8,
0x56_u8,
0xe3_u8,
0x08_u8,
0x9f_u8,
0xec_u8,
0x16_u8,
0x91_u8,
0xc2_u8,
0x25_u8,
0x44_u8,
0xb6_u8,
0x05_u8,
]
[..]
);
super::pbkdf2_hmac(
@ -164,14 +176,28 @@ mod tests {
80000,
MessageDigest::sha256(),
&mut buf,
)
.unwrap();
).unwrap();
assert_eq!(
buf,
&[
0x4d_u8, 0xdc_u8, 0xd8_u8, 0xf6_u8, 0x0b_u8, 0x98_u8, 0xbe_u8, 0x21_u8, 0x83_u8,
0x0c_u8, 0xee_u8, 0x5e_u8, 0xf2_u8, 0x27_u8, 0x01_u8, 0xf9_u8,
][..]
0x4d_u8,
0xdc_u8,
0xd8_u8,
0xf6_u8,
0x0b_u8,
0x98_u8,
0xbe_u8,
0x21_u8,
0x83_u8,
0x0c_u8,
0xee_u8,
0x5e_u8,
0xf2_u8,
0x27_u8,
0x01_u8,
0xf9_u8,
]
[..]
);
}
@ -185,15 +211,72 @@ mod tests {
assert_eq!(
&buf[..],
&[
0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8, 0x94_u8,
0x77_u8, 0x1a_u8, 0x75_u8, 0x73_u8, 0x6b_u8, 0xb8_u8, 0x8b_u8, 0xd3_u8, 0xc7_u8,
0xb3_u8, 0x82_u8, 0x70_u8, 0xcf_u8, 0xb5_u8, 0x0c_u8, 0xb3_u8, 0x90_u8, 0xed_u8,
0x78_u8, 0xb3_u8, 0x05_u8, 0x65_u8, 0x6a_u8, 0xf8_u8, 0x14_u8, 0x8e_u8, 0x52_u8,
0x45_u8, 0x2b_u8, 0x22_u8, 0x16_u8, 0xb2_u8, 0xb8_u8, 0x09_u8, 0x8b_u8, 0x76_u8,
0x1f_u8, 0xc6_u8, 0x33_u8, 0x60_u8, 0x60_u8, 0xa0_u8, 0x9f_u8, 0x76_u8, 0x41_u8,
0x5e_u8, 0x9f_u8, 0x71_u8, 0xea_u8, 0x47_u8, 0xf9_u8, 0xe9_u8, 0x06_u8, 0x43_u8,
0x73_u8,
0xde_u8,
0xcf_u8,
0xa5_u8,
0x8a_u8,
0xa2_u8,
0xe8_u8,
0x4f_u8,
0x94_u8,
0x77_u8,
0x1a_u8,
0x75_u8,
0x73_u8,
0x6b_u8,
0xb8_u8,
0x8b_u8,
0xd3_u8,
0xc7_u8,
0xb3_u8,
0x82_u8,
0x70_u8,
0xcf_u8,
0xb5_u8,
0x0c_u8,
0xb3_u8,
0x90_u8,
0xed_u8,
0x78_u8,
0xb3_u8,
0x05_u8,
0x65_u8,
0x6a_u8,
0xf8_u8,
0x14_u8,
0x8e_u8,
0x52_u8,
0x45_u8,
0x2b_u8,
0x22_u8,
0x16_u8,
0xb2_u8,
0xb8_u8,
0x09_u8,
0x8b_u8,
0x76_u8,
0x1f_u8,
0xc6_u8,
0x33_u8,
0x60_u8,
0x60_u8,
0xa0_u8,
0x9f_u8,
0x76_u8,
0x41_u8,
0x5e_u8,
0x9f_u8,
0x71_u8,
0xea_u8,
0x47_u8,
0xf9_u8,
0xe9_u8,
0x06_u8,
][..]
0x43_u8,
0x06_u8,
]
[..]
);
super::pbkdf2_hmac(
@ -202,20 +285,76 @@ mod tests {
1,
MessageDigest::sha512(),
&mut buf,
)
.unwrap();
).unwrap();
assert_eq!(
&buf[..],
&[
0x71_u8, 0xa0_u8, 0xec_u8, 0x84_u8, 0x2a_u8, 0xbd_u8, 0x5c_u8, 0x67_u8, 0x8b_u8,
0xcf_u8, 0xd1_u8, 0x45_u8, 0xf0_u8, 0x9d_u8, 0x83_u8, 0x52_u8, 0x2f_u8, 0x93_u8,
0x36_u8, 0x15_u8, 0x60_u8, 0x56_u8, 0x3c_u8, 0x4d_u8, 0x0d_u8, 0x63_u8, 0xb8_u8,
0x83_u8, 0x29_u8, 0x87_u8, 0x10_u8, 0x90_u8, 0xe7_u8, 0x66_u8, 0x04_u8, 0xa4_u8,
0x9a_u8, 0xf0_u8, 0x8f_u8, 0xe7_u8, 0xc9_u8, 0xf5_u8, 0x71_u8, 0x56_u8, 0xc8_u8,
0x79_u8, 0x09_u8, 0x96_u8, 0xb2_u8, 0x0f_u8, 0x06_u8, 0xbc_u8, 0x53_u8, 0x5e_u8,
0x5a_u8, 0xb5_u8, 0x44_u8, 0x0d_u8, 0xf7_u8, 0xe8_u8, 0x78_u8, 0x29_u8, 0x6f_u8,
0x71_u8,
0xa0_u8,
0xec_u8,
0x84_u8,
0x2a_u8,
0xbd_u8,
0x5c_u8,
0x67_u8,
0x8b_u8,
0xcf_u8,
0xd1_u8,
0x45_u8,
0xf0_u8,
0x9d_u8,
0x83_u8,
0x52_u8,
0x2f_u8,
0x93_u8,
0x36_u8,
0x15_u8,
0x60_u8,
0x56_u8,
0x3c_u8,
0x4d_u8,
0x0d_u8,
0x63_u8,
0xb8_u8,
0x83_u8,
0x29_u8,
0x87_u8,
0x10_u8,
0x90_u8,
0xe7_u8,
0x66_u8,
0x04_u8,
0xa4_u8,
0x9a_u8,
0xf0_u8,
0x8f_u8,
0xe7_u8,
0xc9_u8,
0xf5_u8,
0x71_u8,
0x56_u8,
0xc8_u8,
0x79_u8,
0x09_u8,
0x96_u8,
0xb2_u8,
0x0f_u8,
0x06_u8,
0xbc_u8,
0x53_u8,
0x5e_u8,
0x5a_u8,
0xb5_u8,
0x44_u8,
0x0d_u8,
0xf7_u8,
0xe8_u8,
0x78_u8,
0x29_u8,
0x6f_u8,
0xa7_u8,
][..]
]
[..]
);
super::pbkdf2_hmac(
@ -224,20 +363,76 @@ mod tests {
50,
MessageDigest::sha512(),
&mut buf,
)
.unwrap();
).unwrap();
assert_eq!(
&buf[..],
&[
0x01_u8, 0x68_u8, 0x71_u8, 0xa4_u8, 0xc4_u8, 0xb7_u8, 0x5f_u8, 0x96_u8, 0x85_u8,
0x7f_u8, 0xd2_u8, 0xb9_u8, 0xf8_u8, 0xca_u8, 0x28_u8, 0x02_u8, 0x3b_u8, 0x30_u8,
0xee_u8, 0x2a_u8, 0x39_u8, 0xf5_u8, 0xad_u8, 0xca_u8, 0xc8_u8, 0xc9_u8, 0x37_u8,
0x5f_u8, 0x9b_u8, 0xda_u8, 0x1c_u8, 0xcd_u8, 0x1b_u8, 0x6f_u8, 0x0b_u8, 0x2f_u8,
0xc3_u8, 0xad_u8, 0xda_u8, 0x50_u8, 0x54_u8, 0x12_u8, 0xe7_u8, 0x9d_u8, 0x89_u8,
0x00_u8, 0x56_u8, 0xc6_u8, 0x2e_u8, 0x52_u8, 0x4c_u8, 0x7d_u8, 0x51_u8, 0x15_u8,
0x4b_u8, 0x1a_u8, 0x85_u8, 0x34_u8, 0x57_u8, 0x5b_u8, 0xd0_u8, 0x2d_u8, 0xee_u8,
0x01_u8,
0x68_u8,
0x71_u8,
0xa4_u8,
0xc4_u8,
0xb7_u8,
0x5f_u8,
0x96_u8,
0x85_u8,
0x7f_u8,
0xd2_u8,
0xb9_u8,
0xf8_u8,
0xca_u8,
0x28_u8,
0x02_u8,
0x3b_u8,
0x30_u8,
0xee_u8,
0x2a_u8,
0x39_u8,
][..]
0xf5_u8,
0xad_u8,
0xca_u8,
0xc8_u8,
0xc9_u8,
0x37_u8,
0x5f_u8,
0x9b_u8,
0xda_u8,
0x1c_u8,
0xcd_u8,
0x1b_u8,
0x6f_u8,
0x0b_u8,
0x2f_u8,
0xc3_u8,
0xad_u8,
0xda_u8,
0x50_u8,
0x54_u8,
0x12_u8,
0xe7_u8,
0x9d_u8,
0x89_u8,
0x00_u8,
0x56_u8,
0xc6_u8,
0x2e_u8,
0x52_u8,
0x4c_u8,
0x7d_u8,
0x51_u8,
0x15_u8,
0x4b_u8,
0x1a_u8,
0x85_u8,
0x34_u8,
0x57_u8,
0x5b_u8,
0xd0_u8,
0x2d_u8,
0xee_u8,
0x39_u8,
]
[..]
);
}
@ -246,19 +441,93 @@ mod tests {
let salt = [16_u8, 34_u8, 19_u8, 23_u8, 141_u8, 4_u8, 207_u8, 221_u8];
let data = [
143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8, 154_u8,
56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8, 55_u8, 119_u8,
233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8, 65_u8, 207_u8,
143_u8,
210_u8,
75_u8,
63_u8,
214_u8,
179_u8,
155_u8,
241_u8,
242_u8,
31_u8,
154_u8,
56_u8,
198_u8,
145_u8,
192_u8,
64_u8,
2_u8,
245_u8,
167_u8,
220_u8,
55_u8,
119_u8,
233_u8,
136_u8,
139_u8,
27_u8,
71_u8,
242_u8,
119_u8,
175_u8,
65_u8,
207_u8,
];
let expected_key = vec![
249_u8, 115_u8, 114_u8, 97_u8, 32_u8, 213_u8, 165_u8, 146_u8, 58_u8, 87_u8, 234_u8,
3_u8, 43_u8, 250_u8, 97_u8, 114_u8, 26_u8, 98_u8, 245_u8, 246_u8, 238_u8, 177_u8,
229_u8, 161_u8, 183_u8, 224_u8, 174_u8, 3_u8, 6_u8, 244_u8, 236_u8, 255_u8,
249_u8,
115_u8,
114_u8,
97_u8,
32_u8,
213_u8,
165_u8,
146_u8,
58_u8,
87_u8,
234_u8,
3_u8,
43_u8,
250_u8,
97_u8,
114_u8,
26_u8,
98_u8,
245_u8,
246_u8,
238_u8,
177_u8,
229_u8,
161_u8,
183_u8,
224_u8,
174_u8,
3_u8,
6_u8,
244_u8,
236_u8,
255_u8,
];
let expected_iv = vec![
4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8, 98_u8,
107_u8, 208_u8, 14_u8, 236_u8, 60_u8,
4_u8,
223_u8,
153_u8,
219_u8,
28_u8,
142_u8,
234_u8,
68_u8,
227_u8,
69_u8,
98_u8,
107_u8,
208_u8,
14_u8,
236_u8,
60_u8,
];
assert_eq!(
@ -268,8 +537,7 @@ mod tests {
&data,
Some(&salt),
1,
)
.unwrap(),
).unwrap(),
super::KeyIvPair {
key: expected_key,
iv: Some(expected_iv),
@ -278,15 +546,14 @@ mod tests {
}
#[test]
#[cfg(any(ossl110))]
#[cfg(all(feature = "v110", ossl110))]
fn scrypt() {
use hex;
use hex::ToHex;
let pass = "pleaseletmein";
let salt = "SodiumChloride";
let expected =
"7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613\
f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887";
let expected = "7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613\
f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887";
let mut actual = [0; 64];
super::scrypt(
@ -297,8 +564,7 @@ mod tests {
1,
0,
&mut actual,
)
.unwrap();
assert_eq!(hex::encode(&actual[..]), expected);
).unwrap();
assert_eq!((&actual[..]).to_hex(), expected);
}
}

View File

@ -1,389 +0,0 @@
use bio::{MemBio, MemBioSlice};
use error::ErrorStack;
use ffi;
use foreign_types::ForeignTypeRef;
use libc::c_int;
use pkey::{HasPrivate, PKeyRef};
use stack::StackRef;
use std::ptr;
use symm::Cipher;
use x509::store::X509StoreRef;
use x509::{X509Ref, X509};
use {cvt, cvt_p};
foreign_type_and_impl_send_sync! {
type CType = ffi::PKCS7;
fn drop = ffi::PKCS7_free;
/// A PKCS#7 structure.
///
/// Contains signed and/or encrypted data.
pub struct Pkcs7;
/// Reference to `Pkcs7`
pub struct Pkcs7Ref;
}
bitflags! {
pub struct Pkcs7Flags: c_int {
const TEXT = ffi::PKCS7_TEXT;
const NOCERTS = ffi::PKCS7_NOCERTS;
const NOSIGS = ffi::PKCS7_NOSIGS;
const NOCHAIN = ffi::PKCS7_NOCHAIN;
const NOINTERN = ffi::PKCS7_NOINTERN;
const NOVERIFY = ffi::PKCS7_NOVERIFY;
const DETACHED = ffi::PKCS7_DETACHED;
const BINARY = ffi::PKCS7_BINARY;
const NOATTR = ffi::PKCS7_NOATTR;
const NOSMIMECAP = ffi::PKCS7_NOSMIMECAP;
const NOOLDMIMETYPE = ffi::PKCS7_NOOLDMIMETYPE;
const CRLFEOL = ffi::PKCS7_CRLFEOL;
const STREAM = ffi::PKCS7_STREAM;
const NOCRL = ffi::PKCS7_NOCRL;
const PARTIAL = ffi::PKCS7_PARTIAL;
const REUSE_DIGEST = ffi::PKCS7_REUSE_DIGEST;
#[cfg(not(any(ossl101, ossl102, libressl)))]
const NO_DUAL_CONTENT = ffi::PKCS7_NO_DUAL_CONTENT;
}
}
impl Pkcs7 {
from_pem! {
/// Deserializes a PEM-encoded PKCS#7 signature
///
/// The input should have a header of `-----BEGIN PKCS7-----`.
///
/// This corresponds to [`PEM_read_bio_PKCS7`].
///
/// [`PEM_read_bio_PKCS7`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_read_bio_PKCS7.html
from_pem,
Pkcs7,
ffi::PEM_read_bio_PKCS7
}
/// Parses a message in S/MIME format.
///
/// Returns the loaded signature, along with the cleartext message (if
/// available).
///
/// This corresponds to [`SMIME_read_PKCS7`].
///
/// [`SMIME_read_PKCS7`]: https://www.openssl.org/docs/man1.1.0/crypto/SMIME_read_PKCS7.html
pub fn from_smime(input: &[u8]) -> Result<(Pkcs7, Option<Vec<u8>>), ErrorStack> {
ffi::init();
let input_bio = MemBioSlice::new(input)?;
let mut bcont_bio = ptr::null_mut();
unsafe {
let pkcs7 =
cvt_p(ffi::SMIME_read_PKCS7(input_bio.as_ptr(), &mut bcont_bio)).map(Pkcs7)?;
let out = if !bcont_bio.is_null() {
let bcont_bio = MemBio::from_ptr(bcont_bio);
Some(bcont_bio.get_buf().to_vec())
} else {
None
};
Ok((pkcs7, out))
}
}
/// Creates and returns a PKCS#7 `envelopedData` structure.
///
/// `certs` is a list of recipient certificates. `input` is the content to be
/// encrypted. `cipher` is the symmetric cipher to use. `flags` is an optional
/// set of flags.
///
/// This corresponds to [`PKCS7_encrypt`].
///
/// [`PKCS7_encrypt`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_encrypt.html
pub fn encrypt(
certs: &StackRef<X509>,
input: &[u8],
cipher: Cipher,
flags: Pkcs7Flags,
) -> Result<Pkcs7, ErrorStack> {
let input_bio = MemBioSlice::new(input)?;
unsafe {
cvt_p(ffi::PKCS7_encrypt(
certs.as_ptr(),
input_bio.as_ptr(),
cipher.as_ptr(),
flags.bits,
))
.map(Pkcs7)
}
}
/// Creates and returns a PKCS#7 `signedData` structure.
///
/// `signcert` is the certificate to sign with, `pkey` is the corresponding
/// private key. `certs` is an optional additional set of certificates to
/// include in the PKCS#7 structure (for example any intermediate CAs in the
/// chain).
///
/// This corresponds to [`PKCS7_sign`].
///
/// [`PKCS7_sign`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_sign.html
pub fn sign<PT>(
signcert: &X509Ref,
pkey: &PKeyRef<PT>,
certs: &StackRef<X509>,
input: &[u8],
flags: Pkcs7Flags,
) -> Result<Pkcs7, ErrorStack>
where
PT: HasPrivate,
{
let input_bio = MemBioSlice::new(input)?;
unsafe {
cvt_p(ffi::PKCS7_sign(
signcert.as_ptr(),
pkey.as_ptr(),
certs.as_ptr(),
input_bio.as_ptr(),
flags.bits,
))
.map(Pkcs7)
}
}
}
impl Pkcs7Ref {
/// Converts PKCS#7 structure to S/MIME format
///
/// This corresponds to [`SMIME_write_PKCS7`].
///
/// [`SMIME_write_PKCS7`]: https://www.openssl.org/docs/man1.1.0/crypto/SMIME_write_PKCS7.html
pub fn to_smime(&self, input: &[u8], flags: Pkcs7Flags) -> Result<Vec<u8>, ErrorStack> {
let input_bio = MemBioSlice::new(input)?;
let output = MemBio::new()?;
unsafe {
cvt(ffi::SMIME_write_PKCS7(
output.as_ptr(),
self.as_ptr(),
input_bio.as_ptr(),
flags.bits,
))
.map(|_| output.get_buf().to_owned())
}
}
to_pem! {
/// Serializes the data into a PEM-encoded PKCS#7 structure.
///
/// The output will have a header of `-----BEGIN PKCS7-----`.
///
/// This corresponds to [`PEM_write_bio_PKCS7`].
///
/// [`PEM_write_bio_PKCS7`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_write_bio_PKCS7.html
to_pem,
ffi::PEM_write_bio_PKCS7
}
/// Decrypts data using the provided private key.
///
/// `pkey` is the recipient's private key, and `cert` is the recipient's
/// certificate.
///
/// Returns the decrypted message.
///
/// This corresponds to [`PKCS7_decrypt`].
///
/// [`PKCS7_decrypt`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_decrypt.html
pub fn decrypt<PT>(
&self,
pkey: &PKeyRef<PT>,
cert: &X509Ref,
flags: Pkcs7Flags,
) -> Result<Vec<u8>, ErrorStack>
where
PT: HasPrivate,
{
let output = MemBio::new()?;
unsafe {
cvt(ffi::PKCS7_decrypt(
self.as_ptr(),
pkey.as_ptr(),
cert.as_ptr(),
output.as_ptr(),
flags.bits,
))
.map(|_| output.get_buf().to_owned())
}
}
/// Verifies the PKCS#7 `signedData` structure contained by `&self`.
///
/// `certs` is a set of certificates in which to search for the signer's
/// certificate. `store` is a trusted certificate store (used for chain
/// verification). `indata` is the signed data if the content is not present
/// in `&self`. The content is written to `out` if it is not `None`.
///
/// This corresponds to [`PKCS7_verify`].
///
/// [`PKCS7_verify`]: https://www.openssl.org/docs/man1.0.2/crypto/PKCS7_verify.html
pub fn verify(
&self,
certs: &StackRef<X509>,
store: &X509StoreRef,
indata: Option<&[u8]>,
out: Option<&mut Vec<u8>>,
flags: Pkcs7Flags,
) -> Result<(), ErrorStack> {
let out_bio = MemBio::new()?;
let indata_bio = match indata {
Some(data) => Some(MemBioSlice::new(data)?),
None => None,
};
let indata_bio_ptr = indata_bio.as_ref().map_or(ptr::null_mut(), |p| p.as_ptr());
unsafe {
cvt(ffi::PKCS7_verify(
self.as_ptr(),
certs.as_ptr(),
store.as_ptr(),
indata_bio_ptr,
out_bio.as_ptr(),
flags.bits,
))
.map(|_| ())?
}
if let Some(data) = out {
data.clear();
data.extend_from_slice(out_bio.get_buf());
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use pkcs7::{Pkcs7, Pkcs7Flags};
use pkey::PKey;
use stack::Stack;
use symm::Cipher;
use x509::store::X509StoreBuilder;
use x509::X509;
#[test]
fn encrypt_decrypt_test() {
let cert = include_bytes!("../test/certs.pem");
let cert = X509::from_pem(cert).unwrap();
let mut certs = Stack::new().unwrap();
certs.push(cert.clone()).unwrap();
let message: String = String::from("foo");
let cypher = Cipher::des_ede3_cbc();
let flags = Pkcs7Flags::STREAM;
let pkey = include_bytes!("../test/key.pem");
let pkey = PKey::private_key_from_pem(pkey).unwrap();
let pkcs7 =
Pkcs7::encrypt(&certs, message.as_bytes(), cypher, flags).expect("should succeed");
let encrypted = pkcs7
.to_smime(message.as_bytes(), flags)
.expect("should succeed");
let (pkcs7_decoded, _) = Pkcs7::from_smime(encrypted.as_slice()).expect("should succeed");
let decoded = pkcs7_decoded
.decrypt(&pkey, &cert, Pkcs7Flags::empty())
.expect("should succeed");
assert_eq!(decoded, message.into_bytes());
}
#[test]
fn sign_verify_test_detached() {
let cert = include_bytes!("../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
let certs = Stack::new().unwrap();
let message: String = String::from("foo");
let flags = Pkcs7Flags::STREAM | Pkcs7Flags::DETACHED;
let pkey = include_bytes!("../test/key.pem");
let pkey = PKey::private_key_from_pem(pkey).unwrap();
let mut store_builder = X509StoreBuilder::new().expect("should succeed");
let root_ca = include_bytes!("../test/root-ca.pem");
let root_ca = X509::from_pem(root_ca).unwrap();
store_builder.add_cert(root_ca).expect("should succeed");
let store = store_builder.build();
let pkcs7 =
Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed");
let signed = pkcs7
.to_smime(message.as_bytes(), flags)
.expect("should succeed");
println!("{:?}", String::from_utf8(signed.clone()).unwrap());
let (pkcs7_decoded, content) =
Pkcs7::from_smime(signed.as_slice()).expect("should succeed");
let mut output = Vec::new();
pkcs7_decoded
.verify(
&certs,
&store,
Some(message.as_bytes()),
Some(&mut output),
flags,
)
.expect("should succeed");
assert_eq!(message.clone().into_bytes(), output);
assert_eq!(
message.clone().into_bytes(),
content.expect("should be non-empty")
);
}
#[test]
fn sign_verify_test_normal() {
let cert = include_bytes!("../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
let certs = Stack::new().unwrap();
let message: String = String::from("foo");
let flags = Pkcs7Flags::STREAM;
let pkey = include_bytes!("../test/key.pem");
let pkey = PKey::private_key_from_pem(pkey).unwrap();
let mut store_builder = X509StoreBuilder::new().expect("should succeed");
let root_ca = include_bytes!("../test/root-ca.pem");
let root_ca = X509::from_pem(root_ca).unwrap();
store_builder.add_cert(root_ca).expect("should succeed");
let store = store_builder.build();
let pkcs7 =
Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed");
let signed = pkcs7
.to_smime(message.as_bytes(), flags)
.expect("should succeed");
let (pkcs7_decoded, content) =
Pkcs7::from_smime(signed.as_slice()).expect("should succeed");
let mut output = Vec::new();
pkcs7_decoded
.verify(&certs, &store, None, Some(&mut output), flags)
.expect("should succeed");
assert_eq!(message.clone().into_bytes(), output);
assert!(content.is_none());
}
#[test]
fn invalid_from_smime() {
let input = String::from("Invalid SMIME Message");
let result = Pkcs7::from_smime(input.as_bytes());
assert_eq!(result.is_err(), true)
}
}

View File

@ -1,149 +1,30 @@
//! Public/private key processing.
//!
//! Asymmetric public key algorithms solve the problem of establishing and sharing
//! secret keys to securely send and receive messages.
//! This system uses a pair of keys: a public key, which can be freely
//! distributed, and a private key, which is kept to oneself. An entity may
//! encrypt information using a user's public key. The encrypted information can
//! only be deciphered using that user's private key.
//!
//! This module offers support for five popular algorithms:
//!
//! * RSA
//!
//! * DSA
//!
//! * Diffie-Hellman
//!
//! * Elliptic Curves
//!
//! * HMAC
//!
//! These algorithms rely on hard mathematical problems - namely integer factorization,
//! discrete logarithms, and elliptic curve relationships - that currently do not
//! yield efficient solutions. This property ensures the security of these
//! cryptographic algorithms.
//!
//! # Example
//!
//! Generate a 2048-bit RSA public/private key pair and print the public key.
//!
//! ```rust
//!
//! extern crate openssl;
//!
//! use openssl::rsa::Rsa;
//! use openssl::pkey::PKey;
//! use std::str;
//!
//! fn main() {
//! let rsa = Rsa::generate(2048).unwrap();
//! let pkey = PKey::from_rsa(rsa).unwrap();
//!
//! let pub_key: Vec<u8> = pkey.public_key_to_pem().unwrap();
//! println!("{:?}", str::from_utf8(pub_key.as_slice()).unwrap());
//! }
//! ```
use libc::{c_void, c_char, c_int, size_t};
use std::ptr;
use std::mem;
use std::ffi::CString;
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int;
use std::ffi::CString;
use std::mem;
use std::ptr;
use {cvt, cvt_p};
use bio::MemBioSlice;
use dh::Dh;
use dsa::Dsa;
use ec::EcKey;
use rsa::{Rsa, Padding};
use error::ErrorStack;
use rsa::Rsa;
use util::{invoke_passwd_cb, CallbackState};
use {cvt, cvt_p};
use util::{CallbackState, invoke_passwd_cb, invoke_passwd_cb_old};
/// A tag type indicating that a key only has parameters.
pub enum Params {}
/// A tag type indicating that a key only has public components.
pub enum Public {}
/// A tag type indicating that a key has private components.
pub enum Private {}
/// An identifier of a kind of key.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Id(c_int);
impl Id {
/// Creates a `Id` from an integer representation.
pub fn from_raw(value: c_int) -> Id {
Id(value)
}
/// Returns the integer representation of the `Id`.
pub fn as_raw(&self) -> c_int {
self.0
}
pub const RSA: Id = Id(ffi::EVP_PKEY_RSA);
pub const HMAC: Id = Id(ffi::EVP_PKEY_HMAC);
pub const DSA: Id = Id(ffi::EVP_PKEY_DSA);
pub const DH: Id = Id(ffi::EVP_PKEY_DH);
pub const EC: Id = Id(ffi::EVP_PKEY_EC);
#[cfg(ossl111)]
pub const ED25519: Id = Id(ffi::EVP_PKEY_ED25519);
#[cfg(ossl111)]
pub const ED448: Id = Id(ffi::EVP_PKEY_ED448);
}
/// A trait indicating that a key has parameters.
pub unsafe trait HasParams {}
unsafe impl HasParams for Params {}
unsafe impl<T> HasParams for T where T: HasPublic {}
/// A trait indicating that a key has public components.
pub unsafe trait HasPublic {}
unsafe impl HasPublic for Public {}
unsafe impl<T> HasPublic for T where T: HasPrivate {}
/// A trait indicating that a key has private components.
pub unsafe trait HasPrivate {}
unsafe impl HasPrivate for Private {}
generic_foreign_type_and_impl_send_sync! {
foreign_type_and_impl_send_sync! {
type CType = ffi::EVP_PKEY;
fn drop = ffi::EVP_PKEY_free;
/// A public or private key.
pub struct PKey<T>;
/// Reference to `PKey`.
pub struct PKeyRef<T>;
pub struct PKey;
pub struct PKeyRef;
}
impl<T> ToOwned for PKeyRef<T> {
type Owned = PKey<T>;
fn to_owned(&self) -> PKey<T> {
unsafe {
EVP_PKEY_up_ref(self.as_ptr());
PKey::from_ptr(self.as_ptr())
}
}
}
impl<T> PKeyRef<T> {
impl PKeyRef {
/// Returns a copy of the internal RSA key.
///
/// This corresponds to [`EVP_PKEY_get1_RSA`].
///
/// [`EVP_PKEY_get1_RSA`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_get1_RSA.html
pub fn rsa(&self) -> Result<Rsa<T>, ErrorStack> {
pub fn rsa(&self) -> Result<Rsa, ErrorStack> {
unsafe {
let rsa = cvt_p(ffi::EVP_PKEY_get1_RSA(self.as_ptr()))?;
Ok(Rsa::from_ptr(rsa))
@ -151,11 +32,7 @@ impl<T> PKeyRef<T> {
}
/// Returns a copy of the internal DSA key.
///
/// This corresponds to [`EVP_PKEY_get1_DSA`].
///
/// [`EVP_PKEY_get1_DSA`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_get1_DSA.html
pub fn dsa(&self) -> Result<Dsa<T>, ErrorStack> {
pub fn dsa(&self) -> Result<Dsa, ErrorStack> {
unsafe {
let dsa = cvt_p(ffi::EVP_PKEY_get1_DSA(self.as_ptr()))?;
Ok(Dsa::from_ptr(dsa))
@ -163,11 +40,7 @@ impl<T> PKeyRef<T> {
}
/// Returns a copy of the internal DH key.
///
/// This corresponds to [`EVP_PKEY_get1_DH`].
///
/// [`EVP_PKEY_get1_DH`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_get1_DH.html
pub fn dh(&self) -> Result<Dh<T>, ErrorStack> {
pub fn dh(&self) -> Result<Dh, ErrorStack> {
unsafe {
let dh = cvt_p(ffi::EVP_PKEY_get1_DH(self.as_ptr()))?;
Ok(Dh::from_ptr(dh))
@ -175,61 +48,18 @@ impl<T> PKeyRef<T> {
}
/// Returns a copy of the internal elliptic curve key.
///
/// This corresponds to [`EVP_PKEY_get1_EC_KEY`].
///
/// [`EVP_PKEY_get1_EC_KEY`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_get1_EC_KEY.html
pub fn ec_key(&self) -> Result<EcKey<T>, ErrorStack> {
pub fn ec_key(&self) -> Result<EcKey, ErrorStack> {
unsafe {
let ec_key = cvt_p(ffi::EVP_PKEY_get1_EC_KEY(self.as_ptr()))?;
Ok(EcKey::from_ptr(ec_key))
}
}
/// Returns the `Id` that represents the type of this key.
///
/// This corresponds to [`EVP_PKEY_id`].
///
/// [`EVP_PKEY_id`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_id.html
pub fn id(&self) -> Id {
unsafe { Id::from_raw(ffi::EVP_PKEY_id(self.as_ptr())) }
}
public_key_to_pem!(ffi::PEM_write_bio_PUBKEY);
private_key_to_pem!(ffi::PEM_write_bio_PKCS8PrivateKey);
/// Returns the maximum size of a signature in bytes.
///
/// This corresponds to [`EVP_PKEY_size`].
///
/// [`EVP_PKEY_size`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_size.html
pub fn size(&self) -> usize {
unsafe { ffi::EVP_PKEY_size(self.as_ptr()) as usize }
}
}
impl<T> PKeyRef<T>
where
T: HasPublic,
{
to_pem! {
/// Serializes the public key into a PEM-encoded SubjectPublicKeyInfo structure.
///
/// The output will have a header of `-----BEGIN PUBLIC KEY-----`.
///
/// This corresponds to [`PEM_write_bio_PUBKEY`].
///
/// [`PEM_write_bio_PUBKEY`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_write_bio_PUBKEY.html
public_key_to_pem,
ffi::PEM_write_bio_PUBKEY
}
to_der! {
/// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure.
///
/// This corresponds to [`i2d_PUBKEY`].
///
/// [`i2d_PUBKEY`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_PUBKEY.html
public_key_to_der,
ffi::i2d_PUBKEY
}
private_key_to_der!(ffi::i2d_PrivateKey);
public_key_to_der!(ffi::i2d_PUBKEY);
/// Returns the size of the key.
///
@ -240,65 +70,17 @@ where
}
/// Compares the public component of this key with another.
pub fn public_eq<U>(&self, other: &PKeyRef<U>) -> bool
where
U: HasPublic,
{
pub fn public_eq(&self, other: &PKeyRef) -> bool {
unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 }
}
}
impl<T> PKeyRef<T>
where
T: HasPrivate,
{
private_key_to_pem! {
/// Serializes the private key to a PEM-encoded PKCS#8 PrivateKeyInfo structure.
///
/// The output will have a header of `-----BEGIN PRIVATE KEY-----`.
///
/// This corresponds to [`PEM_write_bio_PKCS8PrivateKey`].
///
/// [`PEM_write_bio_PKCS8PrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_write_bio_PKCS8PrivateKey.html
private_key_to_pem_pkcs8,
/// Serializes the private key to a PEM-encoded PKCS#8 EncryptedPrivateKeyInfo structure.
///
/// The output will have a header of `-----BEGIN ENCRYPTED PRIVATE KEY-----`.
///
/// This corresponds to [`PEM_write_bio_PKCS8PrivateKey`].
///
/// [`PEM_write_bio_PKCS8PrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_write_bio_PKCS8PrivateKey.html
private_key_to_pem_pkcs8_passphrase,
ffi::PEM_write_bio_PKCS8PrivateKey
}
to_der! {
/// Serializes the private key to a DER-encoded key type specific format.
///
/// This corresponds to [`i2d_PrivateKey`].
///
/// [`i2d_PrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/i2d_PrivateKey.html
private_key_to_der,
ffi::i2d_PrivateKey
}
}
impl<T> Clone for PKey<T> {
fn clone(&self) -> PKey<T> {
PKeyRef::to_owned(self)
}
}
impl<T> PKey<T> {
impl PKey {
/// Creates a new `PKey` containing an RSA key.
///
/// This corresponds to [`EVP_PKEY_assign_RSA`].
///
/// [`EVP_PKEY_assign_RSA`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_assign_RSA.html
pub fn from_rsa(rsa: Rsa<T>) -> Result<PKey<T>, ErrorStack> {
pub fn from_rsa(rsa: Rsa) -> Result<PKey, ErrorStack> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
let pkey = PKey(evp);
cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_RSA,
@ -310,14 +92,10 @@ impl<T> PKey<T> {
}
/// Creates a new `PKey` containing a DSA key.
///
/// This corresponds to [`EVP_PKEY_assign_DSA`].
///
/// [`EVP_PKEY_assign_DSA`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_assign_DSA.html
pub fn from_dsa(dsa: Dsa<T>) -> Result<PKey<T>, ErrorStack> {
pub fn from_dsa(dsa: Dsa) -> Result<PKey, ErrorStack> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
let pkey = PKey(evp);
cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_DSA,
@ -329,14 +107,10 @@ impl<T> PKey<T> {
}
/// Creates a new `PKey` containing a Diffie-Hellman key.
///
/// This corresponds to [`EVP_PKEY_assign_DH`].
///
/// [`EVP_PKEY_assign_DH`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_assign_DH.html
pub fn from_dh(dh: Dh<T>) -> Result<PKey<T>, ErrorStack> {
pub fn from_dh(dh: Dh) -> Result<PKey, ErrorStack> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
let pkey = PKey(evp);
cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_DH,
@ -348,14 +122,10 @@ impl<T> PKey<T> {
}
/// Creates a new `PKey` containing an elliptic curve key.
///
/// This corresponds to [`EVP_PKEY_assign_EC_KEY`].
///
/// [`EVP_PKEY_assign_EC_KEY`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_assign_EC_KEY.html
pub fn from_ec_key(ec_key: EcKey<T>) -> Result<PKey<T>, ErrorStack> {
pub fn from_ec_key(ec_key: EcKey) -> Result<PKey, ErrorStack> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
let pkey = PKey(evp);
cvt(ffi::EVP_PKEY_assign(
pkey.0,
ffi::EVP_PKEY_EC,
@ -365,15 +135,12 @@ impl<T> PKey<T> {
Ok(pkey)
}
}
}
impl PKey<Private> {
/// Creates a new `PKey` containing an HMAC key.
///
/// # Note
///
/// To compute HMAC values, use the `sign` module.
pub fn hmac(key: &[u8]) -> Result<PKey<Private>, ErrorStack> {
pub fn hmac(key: &[u8]) -> Result<PKey, ErrorStack> {
unsafe {
assert!(key.len() <= c_int::max_value() as usize);
let key = cvt_p(ffi::EVP_PKEY_new_mac_key(
@ -382,157 +149,21 @@ impl PKey<Private> {
key.as_ptr() as *const _,
key.len() as c_int,
))?;
Ok(PKey::from_ptr(key))
Ok(PKey(key))
}
}
/// Creates a new `PKey` containing a CMAC key.
///
/// Requires OpenSSL 1.1.0 or newer.
///
/// # Note
///
/// To compute CMAC values, use the `sign` module.
#[cfg(ossl110)]
pub fn cmac(cipher: &::symm::Cipher, key: &[u8]) -> Result<PKey<Private>, ErrorStack> {
unsafe {
assert!(key.len() <= c_int::max_value() as usize);
let kctx = cvt_p(ffi::EVP_PKEY_CTX_new_id(
ffi::EVP_PKEY_CMAC,
ptr::null_mut(),
))?;
let ret = (|| {
cvt(ffi::EVP_PKEY_keygen_init(kctx))?;
// Set cipher for cmac
cvt(ffi::EVP_PKEY_CTX_ctrl(
kctx,
-1,
ffi::EVP_PKEY_OP_KEYGEN,
ffi::EVP_PKEY_CTRL_CIPHER,
0,
cipher.as_ptr() as *mut _,
))?;
// Set the key data
cvt(ffi::EVP_PKEY_CTX_ctrl(
kctx,
-1,
ffi::EVP_PKEY_OP_KEYGEN,
ffi::EVP_PKEY_CTRL_SET_MAC_KEY,
key.len() as c_int,
key.as_ptr() as *mut _,
))?;
Ok(())
})();
if let Err(e) = ret {
// Free memory
ffi::EVP_PKEY_CTX_free(kctx);
return Err(e);
}
// Generate key
let mut key = ptr::null_mut();
let ret = cvt(ffi::EVP_PKEY_keygen(kctx, &mut key));
// Free memory
ffi::EVP_PKEY_CTX_free(kctx);
if let Err(e) = ret {
return Err(e);
}
Ok(PKey::from_ptr(key))
}
}
#[cfg(ossl110)]
fn generate_eddsa(nid: c_int) -> Result<PKey<Private>, ErrorStack> {
unsafe {
let kctx = cvt_p(ffi::EVP_PKEY_CTX_new_id(nid, ptr::null_mut()))?;
let ret = cvt(ffi::EVP_PKEY_keygen_init(kctx));
if let Err(e) = ret {
ffi::EVP_PKEY_CTX_free(kctx);
return Err(e);
}
let mut key = ptr::null_mut();
let ret = cvt(ffi::EVP_PKEY_keygen(kctx, &mut key));
ffi::EVP_PKEY_CTX_free(kctx);
if let Err(e) = ret {
return Err(e);
}
Ok(PKey::from_ptr(key))
}
}
/// Generates a new private Ed25519 key
#[cfg(ossl111)]
pub fn generate_ed25519() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(ffi::EVP_PKEY_ED25519)
}
/// Generates a new private Ed448 key
#[cfg(ossl111)]
pub fn generate_ed448() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(ffi::EVP_PKEY_ED448)
}
private_key_from_pem! {
/// Deserializes a private key from a PEM-encoded key type specific format.
///
/// This corresponds to [`PEM_read_bio_PrivateKey`].
///
/// [`PEM_read_bio_PrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_read_bio_PrivateKey.html
private_key_from_pem,
/// Deserializes a private key from a PEM-encoded encrypted key type specific format.
///
/// This corresponds to [`PEM_read_bio_PrivateKey`].
///
/// [`PEM_read_bio_PrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_read_bio_PrivateKey.html
private_key_from_pem_passphrase,
/// Deserializes a private key from a PEM-encoded encrypted key type specific format.
///
/// The callback should fill the password into the provided buffer and return its length.
///
/// This corresponds to [`PEM_read_bio_PrivateKey`].
///
/// [`PEM_read_bio_PrivateKey`]: https://www.openssl.org/docs/man1.1.0/crypto/PEM_read_bio_PrivateKey.html
private_key_from_pem_callback,
PKey<Private>,
ffi::PEM_read_bio_PrivateKey
}
from_der! {
/// Decodes a DER-encoded private key.
///
/// This function will automatically attempt to detect the underlying key format, and
/// supports the unencrypted PKCS#8 PrivateKeyInfo structures as well as key type specific
/// formats.
///
/// This corresponds to [`d2i_AutoPrivateKey`].
///
/// [`d2i_AutoPrivateKey`]: https://www.openssl.org/docs/man1.0.2/crypto/d2i_AutoPrivateKey.html
private_key_from_der,
PKey<Private>,
ffi::d2i_AutoPrivateKey
}
private_key_from_pem!(PKey, ffi::PEM_read_bio_PrivateKey);
public_key_from_pem!(PKey, ffi::PEM_read_bio_PUBKEY);
public_key_from_der!(PKey, ffi::d2i_PUBKEY);
private_key_from_der!(PKey, ffi::d2i_AutoPrivateKey);
/// Deserializes a DER-formatted PKCS#8 private key, using a callback to retrieve the password
/// if the key is encrpyted.
///
/// The callback should copy the password into the provided buffer and return the number of
/// bytes written.
pub fn private_key_from_pkcs8_callback<F>(
der: &[u8],
callback: F,
) -> Result<PKey<Private>, ErrorStack>
pub fn private_key_from_pkcs8_callback<F>(der: &[u8], callback: F) -> Result<PKey, ErrorStack>
where
F: FnOnce(&mut [u8]) -> Result<usize, ErrorStack>,
{
@ -545,8 +176,7 @@ impl PKey<Private> {
ptr::null_mut(),
Some(invoke_passwd_cb::<F>),
&mut cb as *mut _ as *mut _,
))
.map(|p| PKey::from_ptr(p))
)).map(PKey)
}
}
@ -559,7 +189,7 @@ impl PKey<Private> {
pub fn private_key_from_pkcs8_passphrase(
der: &[u8],
passphrase: &[u8],
) -> Result<PKey<Private>, ErrorStack> {
) -> Result<PKey, ErrorStack> {
unsafe {
ffi::init();
let bio = MemBioSlice::new(der)?;
@ -569,62 +199,114 @@ impl PKey<Private> {
ptr::null_mut(),
None,
passphrase.as_ptr() as *const _ as *mut _,
))
.map(|p| PKey::from_ptr(p))
)).map(PKey)
}
}
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<PKey, ErrorStack>
where
F: FnOnce(&mut [c_char]) -> usize,
{
ffi::init();
let mut cb = CallbackState::new(pass_cb);
let mem_bio = MemBioSlice::new(buf)?;
unsafe {
let evp = cvt_p(ffi::PEM_read_bio_PrivateKey(
mem_bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb_old::<F>),
&mut cb as *mut _ as *mut c_void,
))?;
Ok(PKey::from_ptr(evp))
}
}
}
impl PKey<Public> {
from_pem! {
/// Decodes a PEM-encoded SubjectPublicKeyInfo structure.
///
/// The input should have a header of `-----BEGIN PUBLIC KEY-----`.
///
/// This corresponds to [`PEM_read_bio_PUBKEY`].
///
/// [`PEM_read_bio_PUBKEY`]: https://www.openssl.org/docs/man1.0.2/crypto/PEM_read_bio_PUBKEY.html
public_key_from_pem,
PKey<Public>,
ffi::PEM_read_bio_PUBKEY
}
foreign_type_and_impl_send_sync! {
type CType = ffi::EVP_PKEY_CTX;
fn drop = ffi::EVP_PKEY_CTX_free;
from_der! {
/// Decodes a DER-encoded SubjectPublicKeyInfo structure.
///
/// This corresponds to [`d2i_PUBKEY`].
///
/// [`d2i_PUBKEY`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_PUBKEY.html
public_key_from_der,
PKey<Public>,
ffi::d2i_PUBKEY
pub struct PKeyCtx;
pub struct PKeyCtxRef;
}
impl PKeyCtx {
pub fn from_pkey(pkey: &PKeyRef) -> Result<PKeyCtx, ErrorStack> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
Ok(PKeyCtx(evp))
}
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl270))] {
use ffi::EVP_PKEY_up_ref;
} else {
unsafe extern "C" fn EVP_PKEY_up_ref(pkey: *mut ffi::EVP_PKEY) {
ffi::CRYPTO_add_lock(
&mut (*pkey).references,
1,
ffi::CRYPTO_LOCK_EVP_PKEY,
"pkey.rs\0".as_ptr() as *const _,
line!() as c_int,
);
impl PKeyCtxRef {
pub fn set_rsa_padding(&mut self, pad: Padding) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
self.as_ptr(),
pad.as_raw(),
))?;
}
Ok(())
}
pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
let mut pad: c_int = 0;
unsafe {
cvt(
ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad),
)?;
};
Ok(Padding::from_raw(pad))
}
pub fn derive_init(&mut self) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_derive_init(self.as_ptr()))?;
}
Ok(())
}
pub fn derive_set_peer(&mut self, peer: &PKeyRef) -> Result<(), ErrorStack> {
unsafe {
cvt(
ffi::EVP_PKEY_derive_set_peer(self.as_ptr(), peer.as_ptr()),
)?;
}
Ok(())
}
pub fn derive(&mut self) -> Result<Vec<u8>, ErrorStack> {
let mut len: size_t = 0;
unsafe {
cvt(ffi::EVP_PKEY_derive(
self.as_ptr(),
ptr::null_mut(),
&mut len,
))?;
}
let mut key = vec![0u8; len];
unsafe {
cvt(ffi::EVP_PKEY_derive(
self.as_ptr(),
key.as_mut_ptr(),
&mut len,
))?;
}
Ok(key)
}
}
#[cfg(test)]
mod tests {
use symm::Cipher;
use dh::Dh;
use dsa::Dsa;
use ec::EcKey;
use nid::Nid;
use ec::{EcGroup, EcKey};
use rsa::Rsa;
use symm::Cipher;
use nid;
use super::*;
@ -632,8 +314,7 @@ mod tests {
fn test_to_password() {
let rsa = Rsa::generate(2048).unwrap();
let pkey = PKey::from_rsa(rsa).unwrap();
let pem = pkey
.private_key_to_pem_pkcs8_passphrase(Cipher::aes_128_cbc(), b"foobar")
let pem = pkey.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
.unwrap();
PKey::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
assert!(PKey::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
@ -653,8 +334,7 @@ mod tests {
password_queried = true;
password[..6].copy_from_slice(b"mypass");
Ok(6)
})
.unwrap();
}).unwrap();
assert!(password_queried);
}
@ -687,7 +367,7 @@ mod tests {
let key = include_bytes!("../test/key.pem");
let key = PKey::private_key_from_pem(key).unwrap();
let priv_key = key.private_key_to_pem_pkcs8().unwrap();
let priv_key = key.private_key_to_pem().unwrap();
let pub_key = key.public_key_to_pem().unwrap();
// As a super-simple verification, just check that the buffers contain
@ -701,7 +381,6 @@ mod tests {
let rsa = Rsa::generate(2048).unwrap();
let pkey = PKey::from_rsa(rsa).unwrap();
pkey.rsa().unwrap();
assert_eq!(pkey.id(), Id::RSA);
assert!(pkey.dsa().is_err());
}
@ -710,26 +389,37 @@ mod tests {
let dsa = Dsa::generate(2048).unwrap();
let pkey = PKey::from_dsa(dsa).unwrap();
pkey.dsa().unwrap();
assert_eq!(pkey.id(), Id::DSA);
assert!(pkey.rsa().is_err());
}
#[test]
fn test_dh_accessor() {
let dh = include_bytes!("../test/dhparams.pem");
let dh = Dh::params_from_pem(dh).unwrap();
let dh = Dh::from_pem(dh).unwrap();
let pkey = PKey::from_dh(dh).unwrap();
pkey.dh().unwrap();
assert_eq!(pkey.id(), Id::DH);
assert!(pkey.rsa().is_err());
}
#[test]
fn test_ec_key_accessor() {
let ec_key = EcKey::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let ec_key = EcKey::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let pkey = PKey::from_ec_key(ec_key).unwrap();
pkey.ec_key().unwrap();
assert_eq!(pkey.id(), Id::EC);
assert!(pkey.rsa().is_err());
}
#[test]
fn test_ec_key_derive() {
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let ec_key = EcKey::generate(&group).unwrap();
let ec_key2 = EcKey::generate(&group).unwrap();
let pkey = PKey::from_ec_key(ec_key).unwrap();
let pkey2 = PKey::from_ec_key(ec_key2).unwrap();
let mut pkey_ctx = PKeyCtx::from_pkey(&pkey).unwrap();
pkey_ctx.derive_init().unwrap();
pkey_ctx.derive_set_peer(&pkey2).unwrap();
let shared = pkey_ctx.derive().unwrap();
assert!(!shared.is_empty());
}
}

View File

@ -10,16 +10,14 @@
//! let mut buf = [0; 256];
//! rand_bytes(&mut buf).unwrap();
//! ```
use ffi;
use libc::c_int;
use ffi;
use cvt;
use error::ErrorStack;
/// Fill buffer with cryptographically strong pseudo-random bytes.
///
/// This corresponds to [`RAND_bytes`].
///
/// # Examples
///
/// To generate a buffer with cryptographically strong bytes:
@ -31,7 +29,9 @@ use error::ErrorStack;
/// rand_bytes(&mut buf).unwrap();
/// ```
///
/// [`RAND_bytes`]: https://www.openssl.org/docs/man1.1.0/crypto/RAND_bytes.html
/// # External OpenSSL Documentation
///
/// [RAND_bytes](https://www.openssl.org/docs/man1.1.0/crypto/RAND_bytes.html)
pub fn rand_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> {
unsafe {
ffi::init();
@ -40,20 +40,6 @@ pub fn rand_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> {
}
}
/// Controls random device file descriptor behavior.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// This corresponds to [`RAND_keep_random_devices_open`].
///
/// [`RAND_keep_random_devices_open`]: https://www.openssl.org/docs/manmaster/man3/RAND_keep_random_devices_open.html
#[cfg(ossl111)]
pub fn keep_random_devices_open(keep: bool) {
unsafe {
ffi::RAND_keep_random_devices_open(keep as c_int);
}
}
#[cfg(test)]
mod tests {
use super::rand_bytes;

File diff suppressed because it is too large Load Diff

View File

@ -16,17 +16,18 @@
//! ```rust
//! extern crate openssl;
//! extern crate hex;
//!
//!
//! use openssl::sha;
//!
//! use hex::ToHex;
//!
//! fn main() {
//! let mut hasher = sha::Sha256::new();
//!
//!
//! hasher.update(b"Hello, ");
//! hasher.update(b"world");
//!
//!
//! let hash = hasher.finish();
//! println!("Hashed \"Hello, world\" to {}", hex::encode(hash));
//! println!("Hashed \"Hello, world\" to {}", hash.to_hex());
//! }
//! ```
//!
@ -39,14 +40,15 @@
//! extern crate hex;
//!
//! use openssl::sha::sha256;
//! use hex::ToHex;
//!
//! fn main() {
//! let hash = sha256(b"your data or message");
//! println!("Hash = {}", hex::encode(hash));
//! println!("Hash = {}", hash.to_hex());
//! }
//! ```
use ffi;
use libc::c_void;
use ffi;
use std::mem;
/// Computes the SHA1 hash of some data.
@ -286,7 +288,7 @@ impl Sha512 {
#[cfg(test)]
mod test {
use hex;
use hex::ToHex;
use super::*;
@ -295,7 +297,7 @@ mod test {
let data = b"abc";
let expected = "a9993e364706816aba3e25717850c26c9cd0d89d";
assert_eq!(hex::encode(sha1(data)), expected);
assert_eq!(sha1(data).to_hex(), expected);
}
#[test]
@ -305,7 +307,7 @@ mod test {
let mut hasher = Sha1::new();
hasher.update(b"a");
hasher.update(b"bc");
assert_eq!(hex::encode(hasher.finish()), expected);
assert_eq!(hasher.finish().to_hex(), expected);
}
#[test]
@ -313,7 +315,7 @@ mod test {
let data = b"abc";
let expected = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7";
assert_eq!(hex::encode(sha224(data)), expected);
assert_eq!(sha224(data).to_hex(), expected);
}
#[test]
@ -323,7 +325,7 @@ mod test {
let mut hasher = Sha224::new();
hasher.update(b"a");
hasher.update(b"bc");
assert_eq!(hex::encode(hasher.finish()), expected);
assert_eq!(hasher.finish().to_hex(), expected);
}
#[test]
@ -331,7 +333,7 @@ mod test {
let data = b"abc";
let expected = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
assert_eq!(hex::encode(sha256(data)), expected);
assert_eq!(sha256(data).to_hex(), expected);
}
#[test]
@ -341,50 +343,46 @@ mod test {
let mut hasher = Sha256::new();
hasher.update(b"a");
hasher.update(b"bc");
assert_eq!(hex::encode(hasher.finish()), expected);
assert_eq!(hasher.finish().to_hex(), expected);
}
#[test]
fn standalone_384() {
let data = b"abc";
let expected =
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\
7cc2358baeca134c825a7";
let expected = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\
7cc2358baeca134c825a7";
assert_eq!(hex::encode(&sha384(data)[..]), expected);
assert_eq!((&sha384(data)[..]).to_hex(), expected);
}
#[test]
fn struct_384() {
let expected =
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\
7cc2358baeca134c825a7";
let expected = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\
7cc2358baeca134c825a7";
let mut hasher = Sha384::new();
hasher.update(b"a");
hasher.update(b"bc");
assert_eq!(hex::encode(&hasher.finish()[..]), expected);
assert_eq!((&hasher.finish()[..]).to_hex(), expected);
}
#[test]
fn standalone_512() {
let data = b"abc";
let expected =
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\
fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
let expected = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\
fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
assert_eq!(hex::encode(&sha512(data)[..]), expected);
assert_eq!((&sha512(data)[..]).to_hex(), expected);
}
#[test]
fn struct_512() {
let expected =
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\
fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
let expected = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\
fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
let mut hasher = Sha512::new();
hasher.update(b"a");
hasher.update(b"bc");
assert_eq!(hex::encode(&hasher.finish()[..]), expected);
assert_eq!((&hasher.finish()[..]).to_hex(), expected);
}
}

View File

@ -26,7 +26,7 @@
//! let mut signer = Signer::new(MessageDigest::sha256(), &keypair).unwrap();
//! signer.update(data).unwrap();
//! signer.update(data2).unwrap();
//! let signature = signer.sign_to_vec().unwrap();
//! let signature = signer.finish().unwrap();
//!
//! // Verify the data
//! let mut verifier = Verifier::new(MessageDigest::sha256(), &keypair).unwrap();
@ -63,57 +63,27 @@
//! ```
use ffi;
use foreign_types::ForeignTypeRef;
use libc::c_int;
use std::io::{self, Write};
use std::marker::PhantomData;
use std::ptr;
use error::ErrorStack;
use hash::MessageDigest;
use pkey::{HasPrivate, HasPublic, PKeyRef};
use rsa::Padding;
use {cvt, cvt_p};
use hash::MessageDigest;
use pkey::{PKeyCtxRef, PKeyRef};
use error::ErrorStack;
cfg_if! {
if #[cfg(ossl110)] {
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};
}
}
/// Salt lengths that must be used with `set_rsa_pss_saltlen`.
pub struct RsaPssSaltlen(c_int);
impl RsaPssSaltlen {
/// Returns the integer representation of `RsaPssSaltlen`.
fn as_raw(&self) -> c_int {
self.0
}
/// Sets the salt length to the given value.
pub fn custom(val: c_int) -> RsaPssSaltlen {
RsaPssSaltlen(val)
}
/// The salt length is set to the digest length.
/// Corresponds to the special value `-1`.
pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1);
/// The salt length is set to the maximum permissible value.
/// Corresponds to the special value `-2`.
pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2);
}
#[cfg(ossl110)]
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
#[cfg(any(ossl101, ossl102))]
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
/// A type which computes cryptographic signatures of data.
pub struct Signer<'a> {
md_ctx: *mut ffi::EVP_MD_CTX,
pctx: *mut ffi::EVP_PKEY_CTX,
_p: PhantomData<&'a ()>,
pkey_ctx: *mut ffi::EVP_PKEY_CTX,
pkey_pd: PhantomData<&'a PKeyRef>,
}
unsafe impl<'a> Sync for Signer<'a> {}
unsafe impl<'a> Send for Signer<'a> {}
impl<'a> Drop for Signer<'a> {
fn drop(&mut self) {
// pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
@ -126,41 +96,10 @@ impl<'a> Drop for Signer<'a> {
impl<'a> Signer<'a> {
/// Creates a new `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
pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
where
T: HasPrivate,
{
Self::new_intern(Some(type_), pkey)
}
/// Creates a new `Signer` without a digest.
///
/// 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
pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
where
T: HasPrivate,
{
Self::new_intern(None, pkey)
}
pub fn new_intern<T>(
type_: Option<MessageDigest>,
pkey: &'a PKeyRef<T>,
) -> Result<Signer<'a>, ErrorStack>
where
T: HasPrivate,
{
pub fn new(type_: MessageDigest, pkey: &'a PKeyRef) -> Result<Signer<'a>, ErrorStack> {
unsafe {
ffi::init();
@ -169,7 +108,7 @@ impl<'a> Signer<'a> {
let r = ffi::EVP_DigestSignInit(
ctx,
&mut pctx,
type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
type_.as_ptr(),
ptr::null_mut(),
pkey.as_ptr(),
);
@ -182,81 +121,24 @@ impl<'a> Signer<'a> {
Ok(Signer {
md_ctx: ctx,
pctx,
_p: PhantomData,
pkey_ctx: pctx,
pkey_pd: PhantomData,
})
}
}
/// Returns the RSA padding mode in use.
///
/// This is only useful for RSA keys.
///
/// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
unsafe {
let mut pad = 0;
cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
.map(|_| Padding::from_raw(pad))
}
/// Returns a shared reference to the `PKeyCtx` associated with the `Signer`.
pub fn pkey_ctx(&self) -> &PKeyCtxRef {
unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
}
/// 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/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_padding.html
pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
self.pctx,
padding.as_raw(),
))
.map(|_| ())
}
}
/// 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/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html
pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
self.pctx,
len.as_raw(),
))
.map(|_| ())
}
}
/// 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
pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
self.pctx,
md.as_ptr() as *mut _,
))
.map(|_| ())
}
/// Returns a mutable reference to the `PKeyCtx` associated with the `Signer`.
pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef {
unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
}
/// Feeds more data into the `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
@ -266,8 +148,7 @@ impl<'a> Signer<'a> {
self.md_ctx,
buf.as_ptr() as *const _,
buf.len(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -280,11 +161,6 @@ impl<'a> Signer<'a> {
///
/// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestSignFinal.html
pub fn len(&self) -> Result<usize, ErrorStack> {
self.len_intern()
}
#[cfg(not(ossl111))]
fn len_intern(&self) -> Result<usize, ErrorStack> {
unsafe {
let mut len = 0;
cvt(ffi::EVP_DigestSignFinal(
@ -296,21 +172,6 @@ impl<'a> Signer<'a> {
}
}
#[cfg(ossl111)]
fn len_intern(&self) -> Result<usize, ErrorStack> {
unsafe {
let mut len = 0;
cvt(ffi::EVP_DigestSign(
self.md_ctx,
ptr::null_mut(),
&mut len,
ptr::null(),
0
))?;
Ok(len)
}
}
/// Writes the signature into the provided buffer, returning the number of bytes written.
///
/// This method will fail if the buffer is not large enough for the signature. Use the `len`
@ -342,42 +203,9 @@ impl<'a> Signer<'a> {
Ok(buf)
}
/// Signs the data in data_buf and writes the siganture into the buffer sig_buf, returning the
/// number of bytes written.
///
/// For PureEdDSA (Ed25519 and Ed448 keys) this is the only way to sign data.
///
/// 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(ossl111)]
pub fn sign_oneshot(&self, sig_buf: &mut [u8], data_buf: &[u8]) -> Result<usize, ErrorStack> {
unsafe {
let mut sig_len = sig_buf.len();
cvt(ffi::EVP_DigestSign(
self.md_ctx,
sig_buf.as_mut_ptr() as *mut _,
&mut sig_len,
data_buf.as_ptr() as *const _,
data_buf.len()
))?;
Ok(sig_len)
}
}
/// Returns the signature.
///
/// This is a simple convenience wrapper over `len` and `sign_oneshot`.
#[cfg(ossl111)]
pub fn sign_oneshot_to_vec(&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)?;
// The advertised length is not always equal to the real length for things like DSA
sig_buf.truncate(len);
Ok(sig_buf)
#[deprecated(since = "0.9.23", note = "renamed to sign_to_vec")]
pub fn finish(&self) -> Result<Vec<u8>, ErrorStack> {
self.sign_to_vec()
}
}
@ -394,13 +222,10 @@ impl<'a> Write for Signer<'a> {
pub struct Verifier<'a> {
md_ctx: *mut ffi::EVP_MD_CTX,
pctx: *mut ffi::EVP_PKEY_CTX,
pkey_pd: PhantomData<&'a ()>,
pkey_ctx: *mut ffi::EVP_PKEY_CTX,
pkey_pd: PhantomData<&'a PKeyRef>,
}
unsafe impl<'a> Sync for Verifier<'a> {}
unsafe impl<'a> Send for Verifier<'a> {}
impl<'a> Drop for Verifier<'a> {
fn drop(&mut self) {
// pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
@ -414,38 +239,10 @@ impl<'a> Drop for Verifier<'a> {
impl<'a> Verifier<'a> {
/// Creates a new `Verifier`.
///
/// This cannot be used with Ed25519 or Ed448 keys. Please refer to
/// `new_without_digest`.
///
/// OpenSSL documentation at [`EVP_DigestVerifyInit`].
///
/// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html
pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
where
T: HasPublic,
{
Verifier::new_intern(Some(type_), pkey)
}
/// 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
pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
where
T: HasPublic
{
Verifier::new_intern(None, pkey)
}
fn new_intern<T>(type_: Option<MessageDigest>, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack>
where
T: HasPublic,
{
pub fn new(type_: MessageDigest, pkey: &'a PKeyRef) -> Result<Verifier<'a>, ErrorStack> {
unsafe {
ffi::init();
@ -454,7 +251,7 @@ impl<'a> Verifier<'a> {
let r = ffi::EVP_DigestVerifyInit(
ctx,
&mut pctx,
type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()),
type_.as_ptr(),
ptr::null_mut(),
pkey.as_ptr(),
);
@ -467,81 +264,24 @@ impl<'a> Verifier<'a> {
Ok(Verifier {
md_ctx: ctx,
pctx,
pkey_ctx: pctx,
pkey_pd: PhantomData,
})
}
}
/// Returns the RSA padding mode in use.
///
/// This is only useful for RSA keys.
///
/// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
unsafe {
let mut pad = 0;
cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
.map(|_| Padding::from_raw(pad))
}
/// Returns a shared reference to the `PKeyCtx` associated with the `Verifier`.
pub fn pkey_ctx(&self) -> &PKeyCtxRef {
unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
}
/// 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/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_padding.html
pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
self.pctx,
padding.as_raw(),
))
.map(|_| ())
}
}
/// 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/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html
pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen(
self.pctx,
len.as_raw(),
))
.map(|_| ())
}
}
/// 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
pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
self.pctx,
md.as_ptr() as *mut _,
))
.map(|_| ())
}
/// Returns a mutable reference to the `PKeyCtx` associated with the `Verifier`.
pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef {
unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
}
/// Feeds more data into the `Verifier`.
///
/// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming.
/// Use `verify_oneshot` instead.
///
/// OpenSSL documentation at [`EVP_DigestUpdate`].
///
/// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html
@ -551,8 +291,7 @@ impl<'a> Verifier<'a> {
self.md_ctx,
buf.as_ptr() as *const _,
buf.len(),
))
.map(|_| ())
)).map(|_| ())
}
}
@ -564,7 +303,7 @@ impl<'a> Verifier<'a> {
pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
unsafe {
let r =
EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len());
EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len());
match r {
1 => Ok(true),
0 => {
@ -576,30 +315,9 @@ 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(ossl111)]
pub fn verify_oneshot(&self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> {
unsafe {
let r = ffi::EVP_DigestVerify(
self.md_ctx,
signature.as_ptr() as *const _,
signature.len(),
buf.as_ptr() as *const _,
buf.len(),
);
match r {
1 => Ok(true),
0 => {
ErrorStack::get();
Ok(false)
},
_ => Err(ErrorStack::get()),
}
}
#[deprecated(since = "0.9.23", note = "renamed to `verify`")]
pub fn finish(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
self.verify(signature)
}
}
@ -629,15 +347,16 @@ unsafe fn EVP_DigestVerifyFinal(
#[cfg(test)]
mod test {
use hex::{self, FromHex};
use hex::{FromHex, ToHex};
use std::iter;
use ec::{EcGroup, EcKey};
use hash::MessageDigest;
use nid::Nid;
use sign::{Signer, Verifier};
use ec::{EcGroup, EcKey};
use nid;
use rsa::{PKCS1_PADDING, Rsa};
use dsa::Dsa;
use pkey::PKey;
use rsa::{Padding, Rsa};
use sign::{RsaPssSaltlen, Signer, Verifier};
const INPUT: &'static str =
"65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
@ -659,12 +378,15 @@ mod test {
let pkey = PKey::from_rsa(private_key).unwrap();
let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1);
signer.set_rsa_padding(Padding::PKCS1).unwrap();
assert_eq!(signer.pkey_ctx_mut().rsa_padding().unwrap(), PKCS1_PADDING);
signer
.pkey_ctx_mut()
.set_rsa_padding(PKCS1_PADDING)
.unwrap();
signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
let result = signer.sign_to_vec().unwrap();
assert_eq!(hex::encode(result), SIGNATURE);
assert_eq!(result.to_hex(), SIGNATURE);
}
#[test]
@ -674,7 +396,10 @@ mod test {
let pkey = PKey::from_rsa(private_key).unwrap();
let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
assert_eq!(verifier.rsa_padding().unwrap(), Padding::PKCS1);
assert_eq!(
verifier.pkey_ctx_mut().rsa_padding().unwrap(),
PKCS1_PADDING
);
verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
assert!(verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
}
@ -691,6 +416,56 @@ mod test {
assert!(!verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
}
#[test]
pub fn dsa_sign_verify() {
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
let private_key = {
let key = include_bytes!("../test/dsa.pem");
PKey::from_dsa(Dsa::private_key_from_pem(key).unwrap()).unwrap()
};
let public_key = {
let key = include_bytes!("../test/dsa.pem.pub");
PKey::from_dsa(Dsa::public_key_from_pem(key).unwrap()).unwrap()
};
let mut signer = Signer::new(MessageDigest::sha1(), &private_key).unwrap();
signer.update(&input).unwrap();
let sig = signer.sign_to_vec().unwrap();
let mut verifier = Verifier::new(MessageDigest::sha1(), &public_key).unwrap();
verifier.update(&input).unwrap();
assert!(verifier.verify(&sig).unwrap());
}
#[test]
pub fn dsa_sign_verify_fail() {
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
let private_key = {
let key = include_bytes!("../test/dsa.pem");
PKey::from_dsa(Dsa::private_key_from_pem(key).unwrap()).unwrap()
};
let public_key = {
let key = include_bytes!("../test/dsa.pem.pub");
PKey::from_dsa(Dsa::public_key_from_pem(key).unwrap()).unwrap()
};
let mut signer = Signer::new(MessageDigest::sha1(), &private_key).unwrap();
signer.update(&input).unwrap();
let mut sig = signer.sign_to_vec().unwrap();
sig[0] -= 1;
let mut verifier = Verifier::new(MessageDigest::sha1(), &public_key).unwrap();
verifier.update(&input).unwrap();
match verifier.verify(&sig) {
Ok(true) => panic!("unexpected success"),
Ok(false) | Err(_) => {}
}
}
fn test_hmac(ty: MessageDigest, tests: &[(Vec<u8>, Vec<u8>, Vec<u8>)]) {
for &(ref key, ref data, ref res) in tests.iter() {
let pkey = PKey::hmac(key).unwrap();
@ -792,26 +567,9 @@ mod test {
test_hmac(MessageDigest::sha1(), &tests);
}
#[test]
#[cfg(ossl110)]
fn test_cmac() {
let cipher = ::symm::Cipher::aes_128_cbc();
let key = Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap();
let pkey = PKey::cmac(&cipher, &key).unwrap();
let mut signer = Signer::new_without_digest(&pkey).unwrap();
let data = b"Hi There";
signer.update(data as &[u8]).unwrap();
let expected = vec![
136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19,
];
assert_eq!(signer.sign_to_vec().unwrap(), expected);
}
#[test]
fn ec() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap();
let key = EcKey::generate(&group).unwrap();
let key = PKey::from_ec_key(key).unwrap();
@ -823,43 +581,4 @@ mod test {
verifier.update(b"hello world").unwrap();
assert!(verifier.verify(&signature).unwrap());
}
#[test]
#[cfg(ossl111)]
fn eddsa() {
let key = PKey::generate_ed25519().unwrap();
let signer = Signer::new_without_digest(&key).unwrap();
let signature = signer.sign_oneshot_to_vec(b"hello world").unwrap();
let verifier = Verifier::new_without_digest(&key).unwrap();
assert!(verifier.verify_oneshot(&signature, b"hello world").unwrap());
}
#[test]
#[cfg(ossl111)]
fn rsa_sign_verify() {
let key = include_bytes!("../test/rsa.pem");
let private_key = Rsa::private_key_from_pem(key).unwrap();
let pkey = PKey::from_rsa(private_key).unwrap();
let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS);
signer
.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
.unwrap();
signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
let signature = signer.sign_to_vec().unwrap();
let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap();
verifier
.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)
.unwrap();
verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
assert!(verifier.verify(&signature).unwrap());
}
}

View File

@ -1,57 +0,0 @@
use ffi;
use foreign_types::ForeignTypeRef;
use libc::c_ulong;
use stack::Stackable;
use std::ffi::CStr;
use std::str;
/// fake free method, since SRTP_PROTECTION_PROFILE is static
unsafe fn free(_profile: *mut ffi::SRTP_PROTECTION_PROFILE) {}
#[allow(unused_unsafe)]
foreign_type_and_impl_send_sync! {
type CType = ffi::SRTP_PROTECTION_PROFILE;
fn drop = free;
pub struct SrtpProtectionProfile;
/// Reference to `SrtpProtectionProfile`.
pub struct SrtpProtectionProfileRef;
}
impl Stackable for SrtpProtectionProfile {
type StackType = ffi::stack_st_SRTP_PROTECTION_PROFILE;
}
impl SrtpProtectionProfileRef {
pub fn id(&self) -> SrtpProfileId {
SrtpProfileId::from_raw(unsafe { (*self.as_ptr()).id })
}
pub fn name(&self) -> &'static str {
unsafe { CStr::from_ptr((*self.as_ptr()).name as *const _) }
.to_str()
.expect("should be UTF-8")
}
}
/// An identifier of an SRTP protection profile.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct SrtpProfileId(c_ulong);
impl SrtpProfileId {
/// Creates a `SrtpProfileId` from an integer representation.
pub fn from_raw(value: c_ulong) -> SrtpProfileId {
SrtpProfileId(value)
}
/// Returns the integer representation of `SrtpProfileId`.
pub fn as_raw(&self) -> c_ulong {
self.0
}
pub const SRTP_AES128_CM_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_CM_SHA1_80);
pub const SRTP_AES128_CM_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_CM_SHA1_32);
pub const SRTP_AES128_F8_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_F8_SHA1_80);
pub const SRTP_AES128_F8_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_F8_SHA1_32);
pub const SRTP_NULL_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_80);
pub const SRTP_NULL_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_32);
}

View File

@ -1,13 +1,11 @@
use ffi::{
self, BIO_clear_retry_flags, BIO_new, BIO_set_retry_read, BIO_set_retry_write, BIO,
BIO_CTRL_FLUSH,
};
use libc::{c_char, c_int, c_long, c_void, strlen};
use ffi::{BIO, BIO_CTRL_FLUSH, BIO_new, BIO_clear_retry_flags, BIO_set_retry_read,
BIO_set_retry_write};
use std::any::Any;
use std::io;
use std::io::prelude::*;
use std::mem;
use std::panic::{catch_unwind, AssertUnwindSafe};
use std::panic::{AssertUnwindSafe, catch_unwind};
use std::ptr;
use std::slice;
@ -17,15 +15,15 @@ use error::ErrorStack;
pub struct StreamState<S> {
pub stream: S,
pub error: Option<io::Error>,
pub panic: Option<Box<dyn Any + Send>>,
pub panic: Option<Box<Any + Send>>,
}
/// Safe wrapper for BIO_METHOD
pub struct BioMethod(BIO_METHOD);
pub struct BioMethod(compat::BIO_METHOD);
impl BioMethod {
fn new<S: Read + Write>() -> BioMethod {
BioMethod(BIO_METHOD::new::<S>())
BioMethod(compat::BIO_METHOD::new::<S>())
}
}
@ -43,8 +41,8 @@ pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, BioMethod), ErrorSta
unsafe {
let bio = cvt_p(BIO_new(method.0.get()))?;
BIO_set_data(bio, Box::into_raw(state) as *mut _);
BIO_set_init(bio, 1);
compat::BIO_set_data(bio, Box::into_raw(state) as *mut _);
compat::BIO_set_init(bio, 1);
return Ok((bio, method));
}
@ -55,13 +53,13 @@ pub unsafe fn take_error<S>(bio: *mut BIO) -> Option<io::Error> {
state.error.take()
}
pub unsafe fn take_panic<S>(bio: *mut BIO) -> Option<Box<dyn Any + Send>> {
pub unsafe fn take_panic<S>(bio: *mut BIO) -> Option<Box<Any + Send>> {
let state = state::<S>(bio);
state.panic.take()
}
pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S {
let state: &'a StreamState<S> = mem::transmute(BIO_get_data(bio));
let state: &'a StreamState<S> = mem::transmute(compat::BIO_get_data(bio));
&state.stream
}
@ -70,7 +68,7 @@ pub unsafe fn get_mut<'a, S: 'a>(bio: *mut BIO) -> &'a mut S {
}
unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState<S> {
&mut *(BIO_get_data(bio) as *mut _)
&mut *(compat::BIO_get_data(bio) as *mut _)
}
unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int {
@ -119,7 +117,8 @@ unsafe extern "C" fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int)
fn retriable_error(err: &io::Error) -> bool {
match err.kind() {
io::ErrorKind::WouldBlock | io::ErrorKind::NotConnected => true,
io::ErrorKind::WouldBlock |
io::ErrorKind::NotConnected => true,
_ => false,
}
}
@ -154,10 +153,10 @@ unsafe extern "C" fn ctrl<S: Write>(
}
unsafe extern "C" fn create(bio: *mut BIO) -> c_int {
BIO_set_init(bio, 0);
BIO_set_num(bio, 0);
BIO_set_data(bio, ptr::null_mut());
BIO_set_flags(bio, 0);
compat::BIO_set_init(bio, 0);
compat::BIO_set_num(bio, 0);
compat::BIO_set_data(bio, ptr::null_mut());
compat::BIO_set_flags(bio, 0);
1
}
@ -166,110 +165,115 @@ unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int {
return 0;
}
let data = BIO_get_data(bio);
let data = compat::BIO_get_data(bio);
assert!(!data.is_null());
Box::<StreamState<S>>::from_raw(data as *mut _);
BIO_set_data(bio, ptr::null_mut());
BIO_set_init(bio, 0);
compat::BIO_set_data(bio, ptr::null_mut());
compat::BIO_set_init(bio, 0);
1
}
cfg_if! {
if #[cfg(any(ossl110, libressl273))] {
use ffi::{BIO_get_data, BIO_set_data, BIO_set_flags, BIO_set_init};
#[cfg(ossl110)]
#[allow(bad_style)]
mod compat {
use std::io::{Read, Write};
#[allow(bad_style)]
unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
use libc::c_int;
use ffi;
pub use ffi::{BIO_set_init, BIO_set_flags, BIO_set_data, BIO_get_data};
#[allow(bad_style)]
struct BIO_METHOD(*mut ffi::BIO_METHOD);
pub unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
impl BIO_METHOD {
fn new<S: Read + Write>() -> BIO_METHOD {
unsafe {
let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _);
assert!(!ptr.is_null());
let ret = BIO_METHOD(ptr);
assert!(ffi::BIO_meth_set_write(ptr, bwrite::<S>) != 0);
assert!(ffi::BIO_meth_set_read(ptr, bread::<S>) != 0);
assert!(ffi::BIO_meth_set_puts(ptr, bputs::<S>) != 0);
assert!(ffi::BIO_meth_set_ctrl(ptr, ctrl::<S>) != 0);
assert!(ffi::BIO_meth_set_create(ptr, create) != 0);
assert!(ffi::BIO_meth_set_destroy(ptr, destroy::<S>) != 0);
return ret;
}
}
pub struct BIO_METHOD(*mut ffi::BIO_METHOD);
fn get(&self) -> *mut ffi::BIO_METHOD {
self.0
impl BIO_METHOD {
pub fn new<S: Read + Write>() -> BIO_METHOD {
unsafe {
let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _);
assert!(!ptr.is_null());
let ret = BIO_METHOD(ptr);
assert!(ffi::BIO_meth_set_write(ptr, super::bwrite::<S>) != 0);
assert!(ffi::BIO_meth_set_read(ptr, super::bread::<S>) != 0);
assert!(ffi::BIO_meth_set_puts(ptr, super::bputs::<S>) != 0);
assert!(ffi::BIO_meth_set_ctrl(ptr, super::ctrl::<S>) != 0);
assert!(ffi::BIO_meth_set_create(ptr, super::create) != 0);
assert!(ffi::BIO_meth_set_destroy(ptr, super::destroy::<S>) != 0);
return ret;
}
}
impl Drop for BIO_METHOD {
fn drop(&mut self) {
unsafe {
ffi::BIO_meth_free(self.0);
}
pub fn get(&self) -> *mut ffi::BIO_METHOD {
self.0
}
}
impl Drop for BIO_METHOD {
fn drop(&mut self) {
unsafe {
ffi::BIO_meth_free(self.0);
}
}
} else {
#[allow(bad_style)]
struct BIO_METHOD(*mut ffi::BIO_METHOD);
impl BIO_METHOD {
fn new<S: Read + Write>() -> BIO_METHOD {
let ptr = Box::new(ffi::BIO_METHOD {
type_: ffi::BIO_TYPE_NONE,
name: b"rust\0".as_ptr() as *const _,
bwrite: Some(bwrite::<S>),
bread: Some(bread::<S>),
bputs: Some(bputs::<S>),
bgets: None,
ctrl: Some(ctrl::<S>),
create: Some(create),
destroy: Some(destroy::<S>),
callback_ctrl: None,
});
BIO_METHOD(Box::into_raw(ptr))
}
fn get(&self) -> *mut ffi::BIO_METHOD {
self.0
}
}
impl Drop for BIO_METHOD {
fn drop(&mut self) {
unsafe {
Box::<ffi::BIO_METHOD>::from_raw(self.0);
}
}
}
#[allow(bad_style)]
unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) {
(*bio).init = init;
}
#[allow(bad_style)]
unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) {
(*bio).flags = flags;
}
#[allow(bad_style)]
unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void {
(*bio).ptr
}
#[allow(bad_style)]
unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) {
(*bio).ptr = data;
}
#[allow(bad_style)]
unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) {
(*bio).num = num;
}
}
}
#[cfg(ossl10x)]
#[allow(bad_style)]
mod compat {
use std::io::{Read, Write};
use ffi;
use libc::{c_int, c_void};
pub struct BIO_METHOD(*mut ffi::BIO_METHOD);
impl BIO_METHOD {
pub fn new<S: Read + Write>() -> BIO_METHOD {
let ptr = Box::new(ffi::BIO_METHOD {
type_: ffi::BIO_TYPE_NONE,
name: b"rust\0".as_ptr() as *const _,
bwrite: Some(super::bwrite::<S>),
bread: Some(super::bread::<S>),
bputs: Some(super::bputs::<S>),
bgets: None,
ctrl: Some(super::ctrl::<S>),
create: Some(super::create),
destroy: Some(super::destroy::<S>),
callback_ctrl: None,
});
BIO_METHOD(Box::into_raw(ptr))
}
pub fn get(&self) -> *mut ffi::BIO_METHOD {
self.0
}
}
impl Drop for BIO_METHOD {
fn drop(&mut self) {
unsafe {
Box::<ffi::BIO_METHOD>::from_raw(self.0);
}
}
}
pub unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) {
(*bio).init = init;
}
pub unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) {
(*bio).flags = flags;
}
pub unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void {
(*bio).ptr
}
pub unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) {
(*bio).ptr = data;
}
pub unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) {
(*bio).num = num;
}
}

View File

@ -1,58 +1,40 @@
use ffi;
use foreign_types::ForeignType;
use foreign_types::ForeignTypeRef;
#[cfg(any(ossl111, not(osslconf = "OPENSSL_NO_PSK")))]
use libc::c_char;
#[cfg(ossl111)]
use libc::size_t;
use libc::{c_int, c_uchar, c_uint, c_void};
#[cfg(any(ossl111, not(osslconf = "OPENSSL_NO_PSK")))]
use libc::{c_int, c_uint, c_char, c_uchar, c_void};
use std::any::Any;
use std::ffi::CStr;
use std::mem;
use std::ptr;
use std::slice;
#[cfg(ossl111)]
use std::str;
use std::sync::Arc;
use std::mem;
use foreign_types::ForeignTypeRef;
use dh::Dh;
#[cfg(all(ossl101, not(ossl110)))]
use ec::EcKey;
use error::ErrorStack;
use pkey::Params;
#[cfg(any(ossl102, libressl261))]
use ssl::AlpnError;
#[cfg(ossl111)]
use ssl::{ClientHelloResponse, ExtensionContext};
use ssl::{SniError, Ssl, SslAlert, SslContext, SslContextRef, SslRef, SslSession, SslSessionRef, SESSION_CTX_INDEX};
#[cfg(ossl111)]
use x509::X509Ref;
use x509::{X509StoreContext, X509StoreContextRef};
use dh::Dh;
#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))]
use ec_key::EcKey;
use ssl::{get_callback_idx, get_ssl_callback_idx, SslRef, SniError, NPN_PROTOS_IDX};
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
use ssl::ALPN_PROTOS_IDX;
use x509::X509StoreContextRef;
pub extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
where
F: Fn(bool, &mut X509StoreContextRef) -> bool + 'static + Sync + Send,
F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send,
{
unsafe {
let ctx = X509StoreContextRef::from_ptr_mut(x509_ctx);
let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing");
let verify_idx = SslContext::cached_ex_index::<F>();
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx);
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _);
let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_callback_idx::<F>());
let verify: &F = &*(verify as *mut F);
// raw pointer shenanigans to break the borrow of ctx
// the callback can't mess with its own ex_data slot so this is safe
let verify = ctx
.ex_data(ssl_idx)
.expect("BUG: store context missing ssl")
.ssl_context()
.ex_data(verify_idx)
.expect("BUG: verify callback missing") as *const F;
let ctx = X509StoreContextRef::from_ptr(x509_ctx);
(*verify)(preverify_ok != 0, ctx) as c_int
verify(preverify_ok != 0, ctx) as c_int
}
}
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
pub extern "C" fn raw_client_psk<F>(
pub extern "C" fn raw_psk<F>(
ssl: *mut ffi::SSL,
hint: *const c_char,
identity: *mut c_char,
@ -62,19 +44,17 @@ pub extern "C" fn raw_client_psk<F>(
) -> c_uint
where
F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8], &mut [u8]) -> Result<usize, ErrorStack>
+ Any
+ 'static
+ Sync
+ Send,
{
unsafe {
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _);
let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_callback_idx::<F>());
let ssl = SslRef::from_ptr_mut(ssl);
let callback_idx = SslContext::cached_ex_index::<F>();
let callback = ssl
.ssl_context()
.ex_data(callback_idx)
.expect("BUG: psk callback missing") as *const F;
let hint = if !hint.is_null() {
let callback = &*(callback as *mut F);
let hint = if hint != ptr::null() {
Some(CStr::from_ptr(hint).to_bytes())
} else {
None
@ -82,50 +62,9 @@ where
// Give the callback mutable slices into which it can write the identity and psk.
let identity_sl = slice::from_raw_parts_mut(identity as *mut u8, max_identity_len as usize);
let psk_sl = slice::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize);
match (*callback)(ssl, hint, identity_sl, psk_sl) {
match callback(ssl, hint, identity_sl, psk_sl) {
Ok(psk_len) => psk_len as u32,
Err(e) => {
e.put();
0
}
}
}
}
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
pub extern "C" fn raw_server_psk<F>(
ssl: *mut ffi::SSL,
identity: *const c_char,
psk: *mut c_uchar,
max_psk_len: c_uint,
) -> c_uint
where
F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8]) -> Result<usize, ErrorStack>
+ 'static
+ Sync
+ Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback_idx = SslContext::cached_ex_index::<F>();
let callback = ssl
.ssl_context()
.ex_data(callback_idx)
.expect("BUG: psk callback missing") as *const F;
let identity = if identity != ptr::null() {
Some(CStr::from_ptr(identity).to_bytes())
} else {
None
};
// Give the callback mutable slices into which it can write the psk.
let psk_sl = slice::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,
Err(e) => {
e.put();
0
}
_ => 0,
}
}
}
@ -135,71 +74,100 @@ pub extern "C" fn ssl_raw_verify<F>(
x509_ctx: *mut ffi::X509_STORE_CTX,
) -> c_int
where
F: Fn(bool, &mut X509StoreContextRef) -> bool + 'static + Sync + Send,
F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send,
{
unsafe {
let ctx = X509StoreContextRef::from_ptr_mut(x509_ctx);
let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing");
let callback_idx = Ssl::cached_ex_index::<Arc<F>>();
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx);
let verify = ffi::SSL_get_ex_data(ssl as *const _, get_ssl_callback_idx::<F>());
let verify: &F = &*(verify as *mut F);
let callback = ctx
.ex_data(ssl_idx)
.expect("BUG: store context missing ssl")
.ex_data(callback_idx)
.expect("BUG: ssl verify callback missing")
.clone();
let ctx = X509StoreContextRef::from_ptr(x509_ctx);
callback(preverify_ok != 0, ctx) as c_int
verify(preverify_ok != 0, ctx) as c_int
}
}
pub extern "C" fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, arg: *mut c_void) -> c_int
pub extern "C" fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, _arg: *mut c_void) -> c_int
where
F: Fn(&mut SslRef, &mut SslAlert) -> Result<(), SniError> + 'static + Sync + Send,
F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send,
{
unsafe {
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl);
let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_callback_idx::<F>());
let callback: &F = &*(callback as *mut F);
let ssl = SslRef::from_ptr_mut(ssl);
let callback = arg as *const F;
let mut alert = SslAlert(*al);
let r = (*callback)(ssl, &mut alert);
*al = alert.0;
match r {
match callback(ssl) {
Ok(()) => ffi::SSL_TLSEXT_ERR_OK,
Err(e) => e.0,
Err(SniError::Fatal(e)) => {
*al = e;
ffi::SSL_TLSEXT_ERR_ALERT_FATAL
}
Err(SniError::Warning(e)) => {
*al = e;
ffi::SSL_TLSEXT_ERR_ALERT_WARNING
}
Err(SniError::NoAck) => ffi::SSL_TLSEXT_ERR_NOACK,
}
}
}
#[cfg(any(ossl102, libressl261))]
pub extern "C" fn raw_alpn_select<F>(
pub unsafe fn select_proto_using(
ssl: *mut ffi::SSL,
out: *mut *mut c_uchar,
outlen: *mut c_uchar,
inbuf: *const c_uchar,
inlen: c_uint,
ex_data: c_int,
) -> c_int {
// First, get the list of protocols (that the client should support) saved in the context
// extra data.
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl);
let protocols = ffi::SSL_CTX_get_ex_data(ssl_ctx, ex_data);
let protocols: &Vec<u8> = &*(protocols as *mut Vec<u8>);
// Prepare the client list parameters to be passed to the OpenSSL function...
let client = protocols.as_ptr();
let client_len = protocols.len() as c_uint;
// Finally, let OpenSSL find a protocol to be used, by matching the given server and
// client lists.
if ffi::SSL_select_next_proto(out, outlen, inbuf, inlen, client, client_len) !=
ffi::OPENSSL_NPN_NEGOTIATED
{
ffi::SSL_TLSEXT_ERR_NOACK
} else {
ffi::SSL_TLSEXT_ERR_OK
}
}
/// The function is given as the callback to `SSL_CTX_set_next_proto_select_cb`.
///
/// It chooses the protocol that the client wishes to use, out of the given list of protocols
/// supported by the server. It achieves this by delegating to the `SSL_select_next_proto`
/// function. The list of protocols supported by the client is found in the extra data of the
/// OpenSSL context.
pub extern "C" fn raw_next_proto_select_cb(
ssl: *mut ffi::SSL,
out: *mut *mut c_uchar,
outlen: *mut c_uchar,
inbuf: *const c_uchar,
inlen: c_uint,
_arg: *mut c_void,
) -> c_int {
unsafe { select_proto_using(ssl, out, outlen, inbuf, inlen, *NPN_PROTOS_IDX) }
}
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
pub extern "C" fn raw_alpn_select_cb(
ssl: *mut ffi::SSL,
out: *mut *const c_uchar,
outlen: *mut c_uchar,
inbuf: *const c_uchar,
inlen: c_uint,
_arg: *mut c_void,
) -> c_int
where
F: for<'a> Fn(&mut SslRef, &'a [u8]) -> Result<&'a [u8], AlpnError> + 'static + Sync + Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: alpn callback missing") as *const F;
let protos = slice::from_raw_parts(inbuf as *const u8, inlen as usize);
match (*callback)(ssl, protos) {
Ok(proto) => {
*out = proto.as_ptr() as *const c_uchar;
*outlen = proto.len() as c_uchar;
ffi::SSL_TLSEXT_ERR_OK
}
Err(e) => e.0,
}
}
) -> c_int {
unsafe { select_proto_using(ssl, out as *mut _, outlen, inbuf, inlen, *ALPN_PROTOS_IDX) }
}
pub unsafe extern "C" fn raw_tmp_dh<F>(
@ -208,50 +176,48 @@ pub unsafe extern "C" fn raw_tmp_dh<F>(
keylength: c_int,
) -> *mut ffi::DH
where
F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send,
F: Fn(&mut SslRef, bool, u32) -> Result<Dh, ErrorStack> + Any + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: tmp dh callback missing") as *const F;
let ctx = ffi::SSL_get_SSL_CTX(ssl);
let callback = ffi::SSL_CTX_get_ex_data(ctx, get_callback_idx::<F>());
let callback = &*(callback as *mut F);
match (*callback)(ssl, is_export != 0, keylength as u32) {
let ssl = SslRef::from_ptr_mut(ssl);
match callback(ssl, is_export != 0, keylength as u32) {
Ok(dh) => {
let ptr = dh.as_ptr();
mem::forget(dh);
ptr
}
Err(e) => {
e.put();
Err(_) => {
// FIXME reset error stack
ptr::null_mut()
}
}
}
#[cfg(all(ossl101, not(ossl110)))]
#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))]
pub unsafe extern "C" fn raw_tmp_ecdh<F>(
ssl: *mut ffi::SSL,
is_export: c_int,
keylength: c_int,
) -> *mut ffi::EC_KEY
where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey, ErrorStack> + Any + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: tmp ecdh callback missing") as *const F;
let ctx = ffi::SSL_get_SSL_CTX(ssl);
let callback = ffi::SSL_CTX_get_ex_data(ctx, get_callback_idx::<F>());
let callback = &*(callback as *mut F);
match (*callback)(ssl, is_export != 0, keylength as u32) {
let ssl = SslRef::from_ptr_mut(ssl);
match callback(ssl, is_export != 0, keylength as u32) {
Ok(ec_key) => {
let ptr = ec_key.as_ptr();
mem::forget(ec_key);
ptr
}
Err(e) => {
e.put();
Err(_) => {
// FIXME reset error stack
ptr::null_mut()
}
}
@ -263,50 +229,46 @@ pub unsafe extern "C" fn raw_tmp_dh_ssl<F>(
keylength: c_int,
) -> *mut ffi::DH
where
F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send,
F: Fn(&mut SslRef, bool, u32) -> Result<Dh, ErrorStack> + Any + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ex_data(Ssl::cached_ex_index::<Arc<F>>())
.expect("BUG: ssl tmp dh callback missing")
.clone();
let callback = ffi::SSL_get_ex_data(ssl, get_ssl_callback_idx::<F>());
let callback = &*(callback as *mut F);
let ssl = SslRef::from_ptr_mut(ssl);
match callback(ssl, is_export != 0, keylength as u32) {
Ok(dh) => {
let ptr = dh.as_ptr();
mem::forget(dh);
ptr
}
Err(e) => {
e.put();
Err(_) => {
// FIXME reset error stack
ptr::null_mut()
}
}
}
#[cfg(all(ossl101, not(ossl110)))]
#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))]
pub unsafe extern "C" fn raw_tmp_ecdh_ssl<F>(
ssl: *mut ffi::SSL,
is_export: c_int,
keylength: c_int,
) -> *mut ffi::EC_KEY
where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey, ErrorStack> + Any + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ex_data(Ssl::cached_ex_index::<Arc<F>>())
.expect("BUG: ssl tmp ecdh callback missing")
.clone();
let callback = ffi::SSL_get_ex_data(ssl, get_ssl_callback_idx::<F>());
let callback = &*(callback as *mut F);
let ssl = SslRef::from_ptr_mut(ssl);
match callback(ssl, is_export != 0, keylength as u32) {
Ok(ec_key) => {
let ptr = ec_key.as_ptr();
mem::forget(ec_key);
ptr
}
Err(e) => {
e.put();
Err(_) => {
// FIXME reset error stack
ptr::null_mut()
}
}
@ -314,21 +276,21 @@ where
pub unsafe extern "C" fn raw_tlsext_status<F>(ssl: *mut ffi::SSL, _: *mut c_void) -> c_int
where
F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + 'static + Sync + Send,
F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + Any + 'static + Sync + Send,
{
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _);
let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_callback_idx::<F>());
let callback = &*(callback as *mut F);
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: ocsp callback missing") as *const F;
let ret = (*callback)(ssl);
let ret = callback(ssl);
if ssl.is_server() {
match ret {
Ok(true) => ffi::SSL_TLSEXT_ERR_OK,
Ok(false) => ffi::SSL_TLSEXT_ERR_NOACK,
Err(e) => {
e.put();
Err(_) => {
// FIXME reset error stack
ffi::SSL_TLSEXT_ERR_ALERT_FATAL
}
}
@ -336,351 +298,42 @@ where
match ret {
Ok(true) => 1,
Ok(false) => 0,
Err(e) => {
e.put();
Err(_) => {
// FIXME reset error stack
-1
}
}
}
}
pub unsafe extern "C" fn raw_new_session<F>(
/// The function is given as the callback to `SSL_CTX_set_next_protos_advertised_cb`.
///
/// It causes the parameter `out` to point at a `*const c_uchar` instance that
/// represents the list of protocols that the server should advertise as those
/// that it supports.
/// The list of supported protocols is found in the extra data of the OpenSSL
/// context.
pub extern "C" fn raw_next_protos_advertise_cb(
ssl: *mut ffi::SSL,
session: *mut ffi::SSL_SESSION,
) -> c_int
where
F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ex_data(*SESSION_CTX_INDEX)
.expect("BUG: session context missing")
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: new session callback missing") as *const F;
let session = SslSession::from_ptr(session);
(*callback)(ssl, session);
// the return code doesn't indicate error vs success, but whether or not we consumed the session
1
}
pub unsafe extern "C" fn raw_remove_session<F>(
ctx: *mut ffi::SSL_CTX,
session: *mut ffi::SSL_SESSION,
) where
F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send,
{
let ctx = SslContextRef::from_ptr(ctx);
let callback = ctx
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: remove session callback missing");
let session = SslSessionRef::from_ptr(session);
callback(ctx, session)
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
type DataPtr = *const c_uchar;
} else {
type DataPtr = *mut c_uchar;
}
}
pub unsafe extern "C" fn raw_get_session<F>(
ssl: *mut ffi::SSL,
data: DataPtr,
len: c_int,
copy: *mut c_int,
) -> *mut ffi::SSL_SESSION
where
F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ex_data(*SESSION_CTX_INDEX)
.expect("BUG: session context missing")
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: get session callback missing") as *const F;
let data = slice::from_raw_parts(data as *const u8, len as usize);
match (*callback)(ssl, data) {
Some(session) => {
let p = session.as_ptr();
mem::forget(session);
*copy = 0;
p
}
None => ptr::null_mut(),
}
}
#[cfg(ossl111)]
pub unsafe extern "C" fn raw_keylog<F>(ssl: *const ffi::SSL, line: *const c_char)
where
F: Fn(&SslRef, &str) + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr(ssl as *mut _);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: get session callback missing");
let line = CStr::from_ptr(line).to_bytes();
let line = str::from_utf8_unchecked(line);
callback(ssl, line);
}
#[cfg(ossl111)]
pub unsafe extern "C" fn raw_stateless_cookie_generate<F>(
ssl: *mut ffi::SSL,
cookie: *mut c_uchar,
cookie_len: *mut size_t,
) -> c_int
where
F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: stateless cookie generate callback missing") as *const F;
let slice = slice::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize);
match (*callback)(ssl, slice) {
Ok(len) => {
*cookie_len = len as size_t;
1
}
Err(e) => {
e.put();
0
}
}
}
#[cfg(ossl111)]
pub unsafe extern "C" fn raw_stateless_cookie_verify<F>(
ssl: *mut ffi::SSL,
cookie: *const c_uchar,
cookie_len: size_t,
) -> c_int
where
F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: stateless cookie verify callback missing") as *const F;
let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize);
(*callback)(ssl, slice) as c_int
}
pub extern "C" fn raw_cookie_generate<F>(
ssl: *mut ffi::SSL,
cookie: *mut c_uchar,
cookie_len: *mut c_uint,
) -> c_int
where
F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.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.
let slice =
slice::from_raw_parts_mut(cookie as *mut u8, ffi::DTLS1_COOKIE_LENGTH as usize - 1);
match (*callback)(ssl, slice) {
Ok(len) => {
*cookie_len = len as c_uint;
1
}
Err(e) => {
e.put();
0
}
}
}
}
cfg_if! {
if #[cfg(any(ossl110, libressl280))] {
type CookiePtr = *const c_uchar;
} else {
type CookiePtr = *mut c_uchar;
}
}
pub extern "C" fn raw_cookie_verify<F>(
ssl: *mut ffi::SSL,
cookie: CookiePtr,
cookie_len: c_uint,
) -> c_int
where
F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: cookie verify callback missing") as *const F;
let slice =
slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize);
(*callback)(ssl, slice) as c_int
}
}
#[cfg(ossl111)]
pub struct CustomExtAddState<T>(Option<T>);
#[cfg(ossl111)]
pub extern "C" fn raw_custom_ext_add<F, T>(
ssl: *mut ffi::SSL,
_: c_uint,
context: c_uint,
out: *mut *const c_uchar,
outlen: *mut size_t,
x: *mut ffi::X509,
chainidx: size_t,
al: *mut c_int,
_: *mut c_void,
) -> c_int
where
F: Fn(&mut SslRef, ExtensionContext, Option<(usize, &X509Ref)>) -> Result<Option<T>, SslAlert>
+ 'static
+ Sync
+ Send,
T: AsRef<[u8]> + 'static + Sync + Send,
{
outlen: *mut c_uint,
_arg: *mut c_void,
) -> c_int {
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: custom ext add callback missing") as *const F;
let ectx = ExtensionContext::from_bits_truncate(context);
let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) {
Some((chainidx, X509Ref::from_ptr(x)))
// First, get the list of (supported) protocols saved in the context extra data.
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl);
let protocols = ffi::SSL_CTX_get_ex_data(ssl_ctx, *NPN_PROTOS_IDX);
if protocols.is_null() {
*out = b"".as_ptr();
*outlen = 0;
} else {
None
};
match (*callback)(ssl, ectx, cert) {
Ok(None) => 0,
Ok(Some(buf)) => {
*outlen = buf.as_ref().len();
*out = buf.as_ref().as_ptr();
let idx = Ssl::cached_ex_index::<CustomExtAddState<T>>();
let mut buf = Some(buf);
let new = match ssl.ex_data_mut(idx) {
Some(state) => {
state.0 = buf.take();
false
}
None => true,
};
if new {
ssl.set_ex_data(idx, CustomExtAddState(buf));
}
1
}
Err(alert) => {
*al = alert.0;
-1
}
// If the pointer is valid, put the pointer to the actual byte array into the
// output parameter `out`, as well as its length into `outlen`.
let protocols: &Vec<u8> = &*(protocols as *mut Vec<u8>);
*out = protocols.as_ptr();
*outlen = protocols.len() as c_uint;
}
}
}
#[cfg(ossl111)]
pub extern "C" fn raw_custom_ext_free<T>(
ssl: *mut ffi::SSL,
_: c_uint,
_: c_uint,
_: *mut *const c_uchar,
_: *mut c_void,
) where
T: 'static + Sync + Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let idx = Ssl::cached_ex_index::<CustomExtAddState<T>>();
if let Some(state) = ssl.ex_data_mut(idx) {
state.0 = None;
}
}
}
#[cfg(ossl111)]
pub extern "C" fn raw_custom_ext_parse<F>(
ssl: *mut ffi::SSL,
_: c_uint,
context: c_uint,
input: *const c_uchar,
inlen: size_t,
x: *mut ffi::X509,
chainidx: size_t,
al: *mut c_int,
_: *mut c_void,
) -> c_int
where
F: Fn(&mut SslRef, ExtensionContext, &[u8], Option<(usize, &X509Ref)>) -> Result<(), SslAlert>
+ 'static
+ Sync
+ Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: custom ext parse callback missing") as *const F;
let ectx = ExtensionContext::from_bits_truncate(context);
let slice = slice::from_raw_parts(input as *const u8, inlen as usize);
let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) {
Some((chainidx, X509Ref::from_ptr(x)))
} else {
None
};
match (*callback)(ssl, ectx, slice, cert) {
Ok(()) => 1,
Err(alert) => {
*al = alert.0;
0
}
}
}
}
#[cfg(ossl111)]
pub unsafe extern "C" fn raw_client_hello<F>(
ssl: *mut ffi::SSL,
al: *mut c_int,
arg: *mut c_void,
) -> c_int
where
F: Fn(&mut SslRef, &mut SslAlert) -> Result<ClientHelloResponse, ErrorStack>
+ 'static
+ Sync
+ Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
let callback = arg as *const F;
let mut alert = SslAlert(*al);
let r = (*callback)(ssl, &mut alert);
*al = alert.0;
match r {
Ok(c) => c.0,
Err(e) => {
e.put();
ffi::SSL_CLIENT_HELLO_ERROR
}
}
ffi::SSL_TLSEXT_ERR_OK
}

View File

@ -3,13 +3,19 @@ use std::ops::{Deref, DerefMut};
use dh::Dh;
use error::ErrorStack;
use ssl::{
HandshakeError, Ssl, SslContext, SslContextBuilder, SslMethod, SslMode, SslOptions, SslRef,
SslStream, SslVerifyMode,
};
use ssl::{self, HandshakeError, Ssl, SslRef, SslContext, SslContextBuilder, SslMethod, SslStream,
SSL_VERIFY_PEER};
use pkey::PKeyRef;
use version;
use x509::X509Ref;
const FFDHE_2048: &str = "
#[cfg(ossl101)]
lazy_static! {
static ref HOSTNAME_IDX: ::ex_data::Index<Ssl, String> = Ssl::new_ex_index().unwrap();
}
// ffdhe2048 from https://wiki.mozilla.org/Security/Server_Side_TLS#ffdhe2048
const DHPARAM_PEM: &'static str = "
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
@ -23,24 +29,26 @@ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
let mut ctx = SslContextBuilder::new(method)?;
let mut opts = SslOptions::ALL
| SslOptions::NO_COMPRESSION
| SslOptions::NO_SSLV2
| SslOptions::NO_SSLV3
| SslOptions::SINGLE_DH_USE
| SslOptions::SINGLE_ECDH_USE;
opts &= !SslOptions::DONT_INSERT_EMPTY_FRAGMENTS;
let mut opts = ssl::SSL_OP_ALL;
opts &= !ssl::SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
opts &= !ssl::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
opts |= ssl::SSL_OP_NO_TICKET;
opts |= ssl::SSL_OP_NO_COMPRESSION;
opts |= ssl::SSL_OP_NO_SSLV2;
opts |= ssl::SSL_OP_NO_SSLV3;
opts |= ssl::SSL_OP_SINGLE_DH_USE;
opts |= ssl::SSL_OP_SINGLE_ECDH_USE;
opts |= ssl::SSL_OP_CIPHER_SERVER_PREFERENCE;
ctx.set_options(opts);
let mut mode =
SslMode::AUTO_RETRY | SslMode::ACCEPT_MOVING_WRITE_BUFFER | SslMode::ENABLE_PARTIAL_WRITE;
let mut mode = ssl::SSL_MODE_AUTO_RETRY | ssl::SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
| ssl::SSL_MODE_ENABLE_PARTIAL_WRITE;
// This is quite a useful optimization for saving memory, but historically
// caused CVEs in OpenSSL pre-1.0.1h, according to
// https://bugs.python.org/issue25672
if version::number() >= 0x1_00_01_08_0 {
mode |= SslMode::RELEASE_BUFFERS;
if version::number() >= 0x1000108f {
mode |= ssl::SSL_MODE_RELEASE_BUFFERS;
}
ctx.set_mode(mode);
@ -48,55 +56,41 @@ fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
Ok(ctx)
}
/// A type which wraps client-side streams in a TLS session.
///
/// OpenSSL's default configuration is highly insecure. This connector manages the OpenSSL
/// structures, configuring cipher suites, session options, hostname verification, and more.
///
/// OpenSSL's built in hostname verification is used when linking against OpenSSL 1.0.2 or 1.1.0,
/// and a custom implementation is used when linking against OpenSSL 1.0.1.
#[derive(Clone)]
pub struct SslConnector(SslContext);
/// A builder for `SslConnector`s.
pub struct SslConnectorBuilder(SslContextBuilder);
impl SslConnector {
impl SslConnectorBuilder {
/// Creates a new builder for TLS connections.
///
/// The default configuration is subject to change, and is currently derived from Python.
pub fn builder(method: SslMethod) -> Result<SslConnectorBuilder, ErrorStack> {
pub fn new(method: SslMethod) -> Result<SslConnectorBuilder, ErrorStack> {
let mut ctx = ctx(method)?;
ctx.set_default_verify_paths()?;
// From https://github.com/python/cpython/blob/a170fa162dc03f0a014373349e548954fff2e567/Lib/ssl.py#L193
ctx.set_cipher_list(
"DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK",
"TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:\
TLS13-AES-128-GCM-SHA256:\
ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:DH+AES256:\
ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:RSA+AESGCM:RSA+AES:RSA+HIGH:\
!aNULL:!eNULL:!MD5:!3DES",
)?;
setup_verify(&mut ctx);
Ok(SslConnectorBuilder(ctx))
}
/// Initiates a client-side TLS session on a stream.
///
/// The domain is used for SNI and hostname verification.
pub fn connect<S>(&self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
where
S: Read + Write,
{
self.configure()?.connect(domain, stream)
#[deprecated(since = "0.9.23",
note = "SslConnectorBuilder now implements Deref<Target=SslContextBuilder>")]
pub fn builder(&self) -> &SslContextBuilder {
self
}
/// Returns a structure allowing for configuration of a single TLS session before connection.
pub fn configure(&self) -> Result<ConnectConfiguration, ErrorStack> {
Ssl::new(&self.0).map(|ssl| ConnectConfiguration {
ssl,
sni: true,
verify_hostname: true,
})
#[deprecated(since = "0.9.23",
note = "SslConnectorBuilder now implements DerefMut<Target=SslContextBuilder>")]
pub fn builder_mut(&mut self) -> &mut SslContextBuilder {
self
}
}
/// A builder for `SslConnector`s.
pub struct SslConnectorBuilder(SslContextBuilder);
impl SslConnectorBuilder {
/// Consumes the builder, returning an `SslConnector`.
pub fn build(self) -> SslConnector {
SslConnector(self.0.build())
@ -117,62 +111,101 @@ impl DerefMut for SslConnectorBuilder {
}
}
/// A type which allows for configuration of a client-side TLS session before connection.
pub struct ConnectConfiguration {
ssl: Ssl,
sni: bool,
verify_hostname: bool,
}
/// A type which wraps client-side streams in a TLS session.
///
/// OpenSSL's default configuration is highly insecure. This connector manages the OpenSSL
/// structures, configuring cipher suites, session options, hostname verification, and more.
///
/// OpenSSL's built in hostname verification is used when linking against OpenSSL 1.0.2 or 1.1.0,
/// and a custom implementation is used when linking against OpenSSL 1.0.1.
#[derive(Clone)]
pub struct SslConnector(SslContext);
impl ConnectConfiguration {
/// A builder-style version of `set_use_server_name_indication`.
pub fn use_server_name_indication(mut self, use_sni: bool) -> ConnectConfiguration {
self.set_use_server_name_indication(use_sni);
self
}
/// Configures the use of Server Name Indication (SNI) when connecting.
impl SslConnector {
/// Initiates a client-side TLS session on a stream.
///
/// Defaults to `true`.
pub fn set_use_server_name_indication(&mut self, use_sni: bool) {
self.sni = use_sni;
/// The domain is used for SNI and hostname verification.
pub fn connect<S>(&self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
where
S: Read + Write,
{
self.configure()?.connect(domain, stream)
}
/// A builder-style version of `set_verify_hostname`.
pub fn verify_hostname(mut self, verify_hostname: bool) -> ConnectConfiguration {
self.set_verify_hostname(verify_hostname);
self
}
/// Configures the use of hostname verification when connecting.
///
/// Defaults to `true`.
/// Initiates a client-side TLS session on a stream without performing hostname verification.
///
/// # Warning
///
/// You should think very carefully before you use this method. If hostname verification is not
/// used, *any* valid certificate for *any* site will be trusted for use from any other. This
/// introduces a significant vulnerability to man-in-the-middle attacks.
pub fn set_verify_hostname(&mut self, verify_hostname: bool) {
self.verify_hostname = verify_hostname;
pub fn danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication<
S,
>(
&self,
stream: S,
) -> Result<SslStream<S>, HandshakeError<S>>
where
S: Read + Write,
{
self.configure()?
.danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication(stream)
}
/// Returns a structure allowing for configuration of a single TLS session before connection.
pub fn configure(&self) -> Result<ConnectConfiguration, ErrorStack> {
Ssl::new(&self.0).map(ConnectConfiguration)
}
}
/// A type which allows for configuration of a client-side TLS session before connection.
pub struct ConnectConfiguration(Ssl);
impl ConnectConfiguration {
#[deprecated(since = "0.9.23",
note = "ConnectConfiguration now implements Deref<Target=SslRef>")]
pub fn ssl(&self) -> &Ssl {
&self.0
}
#[deprecated(since = "0.9.23",
note = "ConnectConfiguration now implements DerefMut<Target=SslRef>")]
pub fn ssl_mut(&mut self) -> &mut Ssl {
&mut self.0
}
/// Initiates a client-side TLS session on a stream.
///
/// The domain is used for SNI and hostname verification if enabled.
/// The domain is used for SNI and hostname verification.
pub fn connect<S>(mut self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
where
S: Read + Write,
{
if self.sni {
self.ssl.set_hostname(domain)?;
}
self.0.set_hostname(domain)?;
setup_verify_hostname(&mut self.0, domain)?;
if self.verify_hostname {
setup_verify_hostname(&mut self.ssl, domain)?;
}
self.0.connect(stream)
}
self.ssl.connect(stream)
/// Initiates a client-side TLS session on a stream without performing hostname verification.
///
/// The verification configuration of the connector's `SslContext` is not overridden.
///
/// # Warning
///
/// You should think very carefully before you use this method. If hostname verification is not
/// used, *any* valid certificate for *any* site will be trusted for use from any other. This
/// introduces a significant vulnerability to man-in-the-middle attacks.
pub fn danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication<
S,
>(
self,
stream: S,
) -> Result<SslStream<S>, HandshakeError<S>>
where
S: Read + Write,
{
self.0.connect(stream)
}
}
@ -180,126 +213,13 @@ impl Deref for ConnectConfiguration {
type Target = SslRef;
fn deref(&self) -> &SslRef {
&self.ssl
&self.0
}
}
impl DerefMut for ConnectConfiguration {
fn deref_mut(&mut self) -> &mut SslRef {
&mut self.ssl
}
}
/// A type which wraps server-side streams in a TLS session.
///
/// OpenSSL's default configuration is highly insecure. This connector manages the OpenSSL
/// structures, configuring cipher suites, session options, and more.
#[derive(Clone)]
pub struct SslAcceptor(SslContext);
impl SslAcceptor {
/// Creates a new builder configured to connect to non-legacy clients. This should generally be
/// considered a reasonable default choice.
///
/// This corresponds to the intermediate configuration of version 5 of Mozilla's server side TLS
/// recommendations. See its [documentation][docs] for more details on specifics.
///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
pub fn mozilla_intermediate_v5(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
let mut ctx = ctx(method)?;
ctx.set_options(SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1);
let dh = Dh::params_from_pem(FFDHE_2048.as_bytes())?;
ctx.set_tmp_dh(&dh)?;
setup_curves(&mut ctx)?;
ctx.set_cipher_list(
"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:\
ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
)?;
#[cfg(ossl111)]
ctx.set_ciphersuites(
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256",
)?;
Ok(SslAcceptorBuilder(ctx))
}
/// Creates a new builder configured to connect to modern clients.
///
/// This corresponds to the modern configuration of version 5 of Mozilla's server side TLS recommendations.
/// See its [documentation][docs] for more details on specifics.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
#[cfg(ossl111)]
pub fn mozilla_modern_v5(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
let mut ctx = ctx(method)?;
ctx.set_options(SslOptions::NO_SSL_MASK & !SslOptions::NO_TLSV1_3);
ctx.set_ciphersuites(
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256",
)?;
Ok(SslAcceptorBuilder(ctx))
}
/// Creates a new builder configured to connect to non-legacy clients. This should generally be
/// considered a reasonable default choice.
///
/// This corresponds to the intermediate configuration of version 4 of Mozilla's server side TLS
/// recommendations. See its [documentation][docs] for more details on specifics.
///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
// FIXME remove in next major version
pub fn mozilla_intermediate(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
let mut ctx = ctx(method)?;
ctx.set_options(SslOptions::CIPHER_SERVER_PREFERENCE);
#[cfg(ossl111)]
ctx.set_options(SslOptions::NO_TLSV1_3);
let dh = Dh::params_from_pem(FFDHE_2048.as_bytes())?;
ctx.set_tmp_dh(&dh)?;
setup_curves(&mut ctx)?;
ctx.set_cipher_list(
"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:\
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:\
ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:\
ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:\
DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:\
EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:\
AES256-SHA:DES-CBC3-SHA:!DSS",
)?;
Ok(SslAcceptorBuilder(ctx))
}
/// Creates a new builder configured to connect to modern clients.
///
/// This corresponds to the modern configuration of version 4 of Mozilla's server side TLS recommendations.
/// See its [documentation][docs] for more details on specifics.
///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
// FIXME remove in next major version
pub fn mozilla_modern(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
let mut ctx = ctx(method)?;
ctx.set_options(
SslOptions::CIPHER_SERVER_PREFERENCE | SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1,
);
#[cfg(ossl111)]
ctx.set_options(SslOptions::NO_TLSV1_3);
setup_curves(&mut ctx)?;
ctx.set_cipher_list(
"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:\
ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\
ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256",
)?;
Ok(SslAcceptorBuilder(ctx))
}
/// Initiates a server-side TLS session on a stream.
pub fn accept<S>(&self, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
where
S: Read + Write,
{
let ssl = Ssl::new(&self.0)?;
ssl.accept(stream)
&mut self.0
}
}
@ -307,6 +227,112 @@ impl SslAcceptor {
pub struct SslAcceptorBuilder(SslContextBuilder);
impl SslAcceptorBuilder {
/// Creates a new builder configured to connect to non-legacy clients. This should generally be
/// considered a reasonable default choice.
///
/// This corresponds to the intermediate configuration of Mozilla's server side TLS
/// recommendations. See its [documentation][docs] for more details on specifics.
///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
pub fn mozilla_intermediate<I>(
method: SslMethod,
private_key: &PKeyRef,
certificate: &X509Ref,
chain: I,
) -> Result<SslAcceptorBuilder, ErrorStack>
where
I: IntoIterator,
I::Item: AsRef<X509Ref>,
{
let builder = SslAcceptorBuilder::mozilla_intermediate_raw(method)?;
builder.finish_setup(private_key, certificate, chain)
}
/// Creates a new builder configured to connect to modern clients.
///
/// This corresponds to the modern configuration of Mozilla's server side TLS recommendations.
/// See its [documentation][docs] for more details on specifics.
///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
pub fn mozilla_modern<I>(
method: SslMethod,
private_key: &PKeyRef,
certificate: &X509Ref,
chain: I,
) -> Result<SslAcceptorBuilder, ErrorStack>
where
I: IntoIterator,
I::Item: AsRef<X509Ref>,
{
let builder = SslAcceptorBuilder::mozilla_modern_raw(method)?;
builder.finish_setup(private_key, certificate, chain)
}
/// Like `mozilla_intermediate`, but does not load the certificate chain and private key.
pub fn mozilla_intermediate_raw(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
let mut ctx = ctx(method)?;
let dh = Dh::from_pem(DHPARAM_PEM.as_bytes())?;
ctx.set_tmp_dh(&dh)?;
setup_curves(&mut ctx)?;
ctx.set_cipher_list(
"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:\
ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:\
ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:\
ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:\
DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:\
EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:\
AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS",
)?;
Ok(SslAcceptorBuilder(ctx))
}
/// Like `mozilla_modern`, but does not load the certificate chain and private key.
pub fn mozilla_modern_raw(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
let mut ctx = ctx(method)?;
setup_curves(&mut ctx)?;
ctx.set_cipher_list(
"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:\
ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256",
)?;
Ok(SslAcceptorBuilder(ctx))
}
fn finish_setup<I>(
mut self,
private_key: &PKeyRef,
certificate: &X509Ref,
chain: I,
) -> Result<SslAcceptorBuilder, ErrorStack>
where
I: IntoIterator,
I::Item: AsRef<X509Ref>,
{
self.0.set_private_key(private_key)?;
self.0.set_certificate(certificate)?;
self.0.check_private_key()?;
for cert in chain {
self.0.add_extra_chain_cert(cert.as_ref().to_owned())?;
}
Ok(self)
}
#[deprecated(since = "0.9.23",
note = "SslAcceptorBuilder now implements Deref<Target=SslContextBuilder>")]
pub fn builder(&self) -> &SslContextBuilder {
self
}
#[deprecated(since = "0.9.23",
note = "SslAcceptorBuilder now implements DerefMut<Target=SslContextBuilder>")]
pub fn builder_mut(&mut self) -> &mut SslContextBuilder {
self
}
/// Consumes the builder, returning a `SslAcceptor`.
pub fn build(self) -> SslAcceptor {
SslAcceptor(self.0.build())
@ -327,228 +353,247 @@ impl DerefMut for SslAcceptorBuilder {
}
}
cfg_if! {
if #[cfg(ossl110)] {
fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> {
Ok(())
}
} else if #[cfg(any(ossl102, libressl))] {
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
ctx.set_ecdh_auto(true)
}
} else {
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
use ec::EcKey;
use nid::Nid;
#[cfg(ossl101)]
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
use ec::EcKey;
use nid;
let curve = EcKey::from_curve_name(Nid::X9_62_PRIME256V1)?;
ctx.set_tmp_ecdh(&curve)
}
let curve = EcKey::from_curve_name(nid::X9_62_PRIME256V1)?;
ctx.set_tmp_ecdh(&curve)
}
#[cfg(ossl102)]
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
ctx._set_ecdh_auto(true)
}
#[cfg(ossl110)]
fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> {
Ok(())
}
/// A type which wraps server-side streams in a TLS session.
///
/// OpenSSL's default configuration is highly insecure. This connector manages the OpenSSL
/// structures, configuring cipher suites, session options, and more.
#[derive(Clone)]
pub struct SslAcceptor(SslContext);
impl SslAcceptor {
/// Initiates a server-side TLS session on a stream.
pub fn accept<S>(&self, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
where
S: Read + Write,
{
let ssl = Ssl::new(&self.0)?;
ssl.accept(stream)
}
}
cfg_if! {
if #[cfg(any(ossl102, libressl261))] {
fn setup_verify(ctx: &mut SslContextBuilder) {
ctx.set_verify(SslVerifyMode::PEER);
#[cfg(any(ossl102, ossl110))]
fn setup_verify(ctx: &mut SslContextBuilder) {
ctx.set_verify(SSL_VERIFY_PEER);
}
#[cfg(ossl101)]
fn setup_verify(ctx: &mut SslContextBuilder) {
ctx.set_verify_callback(SSL_VERIFY_PEER, |p, x509| {
let hostname = match x509.ssl() {
Ok(Some(ssl)) => ssl.ex_data(*HOSTNAME_IDX),
_ => None,
};
match hostname {
Some(hostname) => verify::verify_callback(hostname, p, x509),
None => p,
}
});
}
#[cfg(any(ossl102, ossl110))]
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
let param = ssl._param_mut();
param.set_hostflags(::verify::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
match domain.parse() {
Ok(ip) => param.set_ip(ip),
Err(_) => param.set_host(domain),
}
}
#[cfg(ossl101)]
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
let domain = domain.to_string();
ssl.set_ex_data(*HOSTNAME_IDX, domain);
Ok(())
}
#[cfg(ossl101)]
mod verify {
use std::net::IpAddr;
use std::str;
use nid;
use x509::{GeneralName, X509NameRef, X509Ref, X509StoreContextRef};
use stack::Stack;
pub fn verify_callback(
domain: &str,
preverify_ok: bool,
x509_ctx: &X509StoreContextRef,
) -> bool {
if !preverify_ok || x509_ctx.error_depth() != 0 {
return preverify_ok;
}
fn setup_verify_hostname(ssl: &mut SslRef, domain: &str) -> Result<(), ErrorStack> {
use x509::verify::X509CheckFlags;
match x509_ctx.current_cert() {
Some(x509) => verify_hostname(domain, &x509),
None => true,
}
}
let param = ssl.param_mut();
param.set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS);
match domain.parse() {
Ok(ip) => param.set_ip(ip),
Err(_) => param.set_host(domain),
fn verify_hostname(domain: &str, cert: &X509Ref) -> bool {
match cert.subject_alt_names() {
Some(names) => verify_subject_alt_names(domain, names),
None => verify_subject_name(domain, &cert.subject_name()),
}
}
fn verify_subject_alt_names(domain: &str, names: Stack<GeneralName>) -> bool {
let ip = domain.parse();
for name in &names {
match ip {
Ok(ip) => {
if let Some(actual) = name.ipaddress() {
if matches_ip(&ip, actual) {
return true;
}
}
}
Err(_) => {
if let Some(pattern) = name.dnsname() {
if matches_dns(pattern, domain, false) {
return true;
}
}
}
}
}
} else {
fn setup_verify(ctx: &mut SslContextBuilder) {
ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback);
}
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
let domain = domain.to_string();
ssl.set_ex_data(*verify::HOSTNAME_IDX, domain);
Ok(())
}
false
}
mod verify {
use std::net::IpAddr;
use std::str;
use ex_data::Index;
use nid::Nid;
use ssl::Ssl;
use stack::Stack;
use x509::{
GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef,
X509VerifyResult,
fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool {
if let Some(pattern) = subject_name.entries_by_nid(nid::COMMONNAME).next() {
let pattern = match str::from_utf8(pattern.data().as_slice()) {
Ok(pattern) => pattern,
Err(_) => return false,
};
lazy_static! {
pub static ref HOSTNAME_IDX: Index<Ssl, String> = Ssl::new_ex_index().unwrap();
// Unlike with SANs, IP addresses in the subject name don't have a
// different encoding. We need to pass this down to matches_dns to
// disallow wildcard matches with bogus patterns like *.0.0.1
let is_ip = domain.parse::<IpAddr>().is_ok();
if matches_dns(&pattern, domain, is_ip) {
return true;
}
}
pub fn verify_callback(preverify_ok: bool, x509_ctx: &mut X509StoreContextRef) -> bool {
if !preverify_ok || x509_ctx.error_depth() != 0 {
return preverify_ok;
}
false
}
let ok = match (
x509_ctx.current_cert(),
X509StoreContext::ssl_idx()
.ok()
.and_then(|idx| x509_ctx.ex_data(idx))
.and_then(|ssl| ssl.ex_data(*HOSTNAME_IDX)),
) {
(Some(x509), Some(domain)) => verify_hostname(domain, &x509),
_ => true,
};
fn matches_dns(mut pattern: &str, mut hostname: &str, is_ip: bool) -> bool {
// first strip trailing . off of pattern and hostname to normalize
if pattern.ends_with('.') {
pattern = &pattern[..pattern.len() - 1];
}
if hostname.ends_with('.') {
hostname = &hostname[..hostname.len() - 1];
}
if !ok {
x509_ctx.set_error(X509VerifyResult::APPLICATION_VERIFICATION);
}
matches_wildcard(pattern, hostname, is_ip).unwrap_or_else(|| pattern == hostname)
}
ok
}
fn verify_hostname(domain: &str, cert: &X509Ref) -> bool {
match cert.subject_alt_names() {
Some(names) => verify_subject_alt_names(domain, names),
None => verify_subject_name(domain, &cert.subject_name()),
}
}
fn verify_subject_alt_names(domain: &str, names: Stack<GeneralName>) -> bool {
let ip = domain.parse();
for name in &names {
match ip {
Ok(ip) => {
if let Some(actual) = name.ipaddress() {
if matches_ip(&ip, actual) {
return true;
}
}
}
Err(_) => {
if let Some(pattern) = name.dnsname() {
if matches_dns(pattern, domain) {
return true;
}
}
}
}
}
false
}
fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool {
match subject_name.entries_by_nid(Nid::COMMONNAME).next() {
Some(pattern) => {
let pattern = match str::from_utf8(pattern.data().as_slice()) {
Ok(pattern) => pattern,
Err(_) => return false,
};
// Unlike SANs, IP addresses in the subject name don't have a
// different encoding.
match domain.parse::<IpAddr>() {
Ok(ip) => pattern
.parse::<IpAddr>()
.ok()
.map_or(false, |pattern| pattern == ip),
Err(_) => matches_dns(pattern, domain),
}
}
None => false,
}
}
fn matches_dns(mut pattern: &str, mut hostname: &str) -> bool {
// first strip trailing . off of pattern and hostname to normalize
if pattern.ends_with('.') {
pattern = &pattern[..pattern.len() - 1];
}
if hostname.ends_with('.') {
hostname = &hostname[..hostname.len() - 1];
}
matches_wildcard(pattern, hostname).unwrap_or_else(|| pattern == hostname)
}
fn matches_wildcard(pattern: &str, hostname: &str) -> Option<bool> {
// internationalized domains can't involved in wildcards
if pattern.starts_with("xn--") {
return None;
}
let wildcard_location = match pattern.find('*') {
Some(l) => l,
None => return None,
};
let mut dot_idxs = pattern.match_indices('.').map(|(l, _)| l);
let wildcard_end = match dot_idxs.next() {
Some(l) => l,
None => return None,
};
// Never match wildcards if the pattern has less than 2 '.'s (no *.com)
//
// This is a bit dubious, as it doesn't disallow other TLDs like *.co.uk.
// Chrome has a black- and white-list for this, but Firefox (via NSS) does
// the same thing we do here.
//
// The Public Suffix (https://www.publicsuffix.org/) list could
// potentially be used here, but it's both huge and updated frequently
// enough that management would be a PITA.
if dot_idxs.next().is_none() {
return None;
}
// Wildcards can only be in the first component
if wildcard_location > wildcard_end {
return None;
}
let hostname_label_end = match hostname.find('.') {
Some(l) => l,
None => return None,
};
// check that the non-wildcard parts are identical
if pattern[wildcard_end..] != hostname[hostname_label_end..] {
return Some(false);
}
let wildcard_prefix = &pattern[..wildcard_location];
let wildcard_suffix = &pattern[wildcard_location + 1..wildcard_end];
let hostname_label = &hostname[..hostname_label_end];
// check the prefix of the first label
if !hostname_label.starts_with(wildcard_prefix) {
return Some(false);
}
// and the suffix
if !hostname_label[wildcard_prefix.len()..].ends_with(wildcard_suffix) {
return Some(false);
}
Some(true)
}
fn matches_ip(expected: &IpAddr, actual: &[u8]) -> bool {
match *expected {
IpAddr::V4(ref addr) => actual == addr.octets(),
IpAddr::V6(ref addr) => actual == addr.octets(),
}
fn matches_wildcard(pattern: &str, hostname: &str, is_ip: bool) -> Option<bool> {
// IP addresses and internationalized domains can't involved in wildcards
if is_ip || pattern.starts_with("xn--") {
return None;
}
let wildcard_location = match pattern.find('*') {
Some(l) => l,
None => return None,
};
let mut dot_idxs = pattern.match_indices('.').map(|(l, _)| l);
let wildcard_end = match dot_idxs.next() {
Some(l) => l,
None => return None,
};
// Never match wildcards if the pattern has less than 2 '.'s (no *.com)
//
// This is a bit dubious, as it doesn't disallow other TLDs like *.co.uk.
// Chrome has a black- and white-list for this, but Firefox (via NSS) does
// the same thing we do here.
//
// The Public Suffix (https://www.publicsuffix.org/) list could
// potentially be used here, but it's both huge and updated frequently
// enough that management would be a PITA.
if dot_idxs.next().is_none() {
return None;
}
// Wildcards can only be in the first component
if wildcard_location > wildcard_end {
return None;
}
let hostname_label_end = match hostname.find('.') {
Some(l) => l,
None => return None,
};
// check that the non-wildcard parts are identical
if pattern[wildcard_end..] != hostname[hostname_label_end..] {
return Some(false);
}
let wildcard_prefix = &pattern[..wildcard_location];
let wildcard_suffix = &pattern[wildcard_location + 1..wildcard_end];
let hostname_label = &hostname[..hostname_label_end];
// check the prefix of the first label
if !hostname_label.starts_with(wildcard_prefix) {
return Some(false);
}
// and the suffix
if !hostname_label[wildcard_prefix.len()..].ends_with(wildcard_suffix) {
return Some(false);
}
Some(true)
}
fn matches_ip(expected: &IpAddr, actual: &[u8]) -> bool {
match (expected, actual.len()) {
(&IpAddr::V4(ref addr), 4) => actual == addr.octets(),
(&IpAddr::V6(ref addr), 16) => {
let segments = [
((actual[0] as u16) << 8) | actual[1] as u16,
((actual[2] as u16) << 8) | actual[3] as u16,
((actual[4] as u16) << 8) | actual[5] as u16,
((actual[6] as u16) << 8) | actual[7] as u16,
((actual[8] as u16) << 8) | actual[9] as u16,
((actual[10] as u16) << 8) | actual[11] as u16,
((actual[12] as u16) << 8) | actual[13] as u16,
((actual[14] as u16) << 8) | actual[15] as u16,
];
segments == addr.segments()
}
_ => false,
}
}
}

View File

@ -1,5 +1,4 @@
use ffi;
use libc::c_int;
use std::any::Any;
use std::error;
use std::error::Error as StdError;
use std::fmt;
@ -7,82 +6,56 @@ use std::io;
use error::ErrorStack;
use ssl::MidHandshakeSslStream;
use x509::X509VerifyResult;
/// An error code returned from SSL functions.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct ErrorCode(c_int);
impl ErrorCode {
pub fn from_raw(raw: c_int) -> ErrorCode {
ErrorCode(raw)
}
pub fn as_raw(&self) -> c_int {
self.0
}
/// The SSL session has been closed.
pub const ZERO_RETURN: ErrorCode = ErrorCode(ffi::SSL_ERROR_ZERO_RETURN);
/// An attempt to read data from the underlying socket returned `WouldBlock`.
///
/// Wait for read readiness and retry the operation.
pub const WANT_READ: ErrorCode = ErrorCode(ffi::SSL_ERROR_WANT_READ);
/// An attempt to write data to the underlying socket returned `WouldBlock`.
///
/// Wait for write readiness and retry the operation.
pub const WANT_WRITE: ErrorCode = ErrorCode(ffi::SSL_ERROR_WANT_WRITE);
/// A non-recoverable IO error occurred.
pub const SYSCALL: ErrorCode = ErrorCode(ffi::SSL_ERROR_SYSCALL);
/// An error occurred in the SSL library.
pub const SSL: ErrorCode = ErrorCode(ffi::SSL_ERROR_SSL);
/// The client hello callback indicated that it needed to be retried.
///
/// Requires OpenSSL 1.1.1 or newer.
#[cfg(ossl111)]
pub const WANT_CLIENT_HELLO_CB: ErrorCode = ErrorCode(ffi::SSL_ERROR_WANT_CLIENT_HELLO_CB);
}
/// An SSL error.
// FIXME this is missing variants
#[derive(Debug)]
pub(crate) enum InnerError {
Io(io::Error),
pub enum Error {
/// The SSL session has been closed by the other end
ZeroReturn,
/// An attempt to read data from the underlying socket returned
/// `WouldBlock`. Wait for read readiness and reattempt the operation.
WantRead(io::Error),
/// An attempt to write data from the underlying socket returned
/// `WouldBlock`. Wait for write readiness and reattempt the operation.
WantWrite(io::Error),
/// The client certificate callback requested to be called again.
WantX509Lookup,
/// An error reported by the underlying stream.
Stream(io::Error),
/// An error in the OpenSSL library.
Ssl(ErrorStack),
}
/// An SSL error.
#[derive(Debug)]
pub struct Error {
pub(crate) code: ErrorCode,
pub(crate) cause: Option<InnerError>,
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str(self.description())?;
if let Some(err) = self.cause() {
write!(fmt, ": {}", err)
} else {
Ok(())
}
}
}
impl Error {
pub fn code(&self) -> ErrorCode {
self.code
}
pub fn io_error(&self) -> Option<&io::Error> {
match self.cause {
Some(InnerError::Io(ref e)) => Some(e),
_ => None,
impl error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::ZeroReturn => "The SSL session was closed by the other end",
Error::WantRead(_) => "A read attempt returned a `WouldBlock` error",
Error::WantWrite(_) => "A write attempt returned a `WouldBlock` error",
Error::WantX509Lookup => "The client certificate callback requested to be called again",
Error::Stream(_) => "The underlying stream reported an error",
Error::Ssl(_) => "The OpenSSL library reported an error",
}
}
pub fn into_io_error(self) -> Result<io::Error, Error> {
match self.cause {
Some(InnerError::Io(e)) => Ok(e),
_ => Err(self),
}
}
pub fn ssl_error(&self) -> Option<&ErrorStack> {
match self.cause {
Some(InnerError::Ssl(ref e)) => Some(e),
fn cause(&self) -> Option<&error::Error> {
match *self {
Error::WantRead(ref err) => Some(err),
Error::WantWrite(ref err) => Some(err),
Error::Stream(ref err) => Some(err),
Error::Ssl(ref err) => Some(err),
_ => None,
}
}
@ -90,93 +63,79 @@ impl Error {
impl From<ErrorStack> for Error {
fn from(e: ErrorStack) -> Error {
Error {
code: ErrorCode::SSL,
cause: Some(InnerError::Ssl(e)),
}
Error::Ssl(e)
}
}
impl fmt::Display for Error {
/// An error indicating that the operation can be immediately retried.
///
/// OpenSSL's [`SSL_read`] and [`SSL_write`] functions can return `SSL_ERROR_WANT_READ` even when
/// the underlying socket is performing blocking IO in certain cases. When this happens, the
/// the operation can be immediately retried.
///
/// To signal this event, the `io::Error` inside of [`Error::WantRead`] will be constructed around
/// a `RetryError`.
///
/// [`SSL_read`]: https://www.openssl.org/docs/manmaster/man3/SSL_read.html
/// [`SSL_write`]: https://www.openssl.org/docs/manmaster/man3/SSL_write.html
/// [`Error::WantRead`]: enum.Error.html#variant.WantRead
#[derive(Debug)]
pub struct RetryError;
impl fmt::Display for RetryError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.code {
ErrorCode::ZERO_RETURN => fmt.write_str("the SSL session has been shut down"),
ErrorCode::WANT_READ => match self.io_error() {
Some(_) => fmt.write_str("a nonblocking read call would have blocked"),
None => fmt.write_str("the operation should be retried"),
},
ErrorCode::WANT_WRITE => match self.io_error() {
Some(_) => fmt.write_str("a nonblocking write call would have blocked"),
None => fmt.write_str("the operation should be retried"),
},
ErrorCode::SYSCALL => match self.io_error() {
Some(err) => write!(fmt, "{}", err),
None => fmt.write_str("unexpected EOF"),
},
ErrorCode::SSL => match self.ssl_error() {
Some(e) => write!(fmt, "{}", e),
None => fmt.write_str("OpenSSL error"),
},
ErrorCode(code) => write!(fmt, "unknown error code {}", code),
}
fmt.write_str(error::Error::description(self))
}
}
impl error::Error for Error {
impl error::Error for RetryError {
fn description(&self) -> &str {
"an OpenSSL error"
}
fn cause(&self) -> Option<&dyn error::Error> {
match self.cause {
Some(InnerError::Io(ref e)) => Some(e),
Some(InnerError::Ssl(ref e)) => Some(e),
None => None,
}
"operation must be retried"
}
}
/// An error or intermediate state after a TLS handshake attempt.
// FIXME overhaul
#[derive(Debug)]
pub enum HandshakeError<S> {
/// Setup failed.
SetupFailure(ErrorStack),
/// The handshake failed.
Failure(MidHandshakeSslStream<S>),
/// The handshake encountered a `WouldBlock` error midway through.
/// The handshake was interrupted midway through.
///
/// This error will never be returned for blocking streams.
WouldBlock(MidHandshakeSslStream<S>),
// FIXME change to WouldBlock
Interrupted(MidHandshakeSslStream<S>),
}
impl<S: fmt::Debug> StdError for HandshakeError<S> {
impl<S: Any + fmt::Debug> StdError for HandshakeError<S> {
fn description(&self) -> &str {
match *self {
HandshakeError::SetupFailure(_) => "stream setup failed",
HandshakeError::Failure(_) => "the handshake failed",
HandshakeError::WouldBlock(_) => "the handshake was interrupted",
HandshakeError::Interrupted(_) => "the handshake was interrupted",
}
}
fn cause(&self) -> Option<&dyn StdError> {
fn cause(&self) -> Option<&StdError> {
match *self {
HandshakeError::SetupFailure(ref e) => Some(e),
HandshakeError::Failure(ref s) | HandshakeError::WouldBlock(ref s) => Some(s.error()),
HandshakeError::Failure(ref s) |
HandshakeError::Interrupted(ref s) => Some(s.error()),
}
}
}
impl<S: fmt::Debug> fmt::Display for HandshakeError<S> {
impl<S: Any + fmt::Debug> fmt::Display for HandshakeError<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(StdError::description(self))?;
match *self {
HandshakeError::SetupFailure(ref e) => write!(f, ": {}", e)?,
HandshakeError::Failure(ref s) | HandshakeError::WouldBlock(ref s) => {
HandshakeError::Failure(ref s) |
HandshakeError::Interrupted(ref s) => {
write!(f, ": {}", s.error())?;
let verify = s.ssl().verify_result();
if verify != X509VerifyResult::OK {
write!(f, ": {}", verify)?;
if let Some(err) = s.ssl().verify_result() {
write!(f, ": {}", err)?;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,167 +0,0 @@
use std::io::{Read, Write};
use std::net::{SocketAddr, TcpListener, TcpStream};
use std::thread::{self, JoinHandle};
use ssl::{Ssl, SslContext, SslContextBuilder, SslFiletype, SslMethod, SslRef, SslStream};
pub struct Server {
handle: Option<JoinHandle<()>>,
addr: SocketAddr,
}
impl Drop for Server {
fn drop(&mut self) {
if !thread::panicking() {
self.handle.take().unwrap().join().unwrap();
}
}
}
impl Server {
pub fn builder() -> Builder {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_certificate_chain_file("test/cert.pem").unwrap();
ctx.set_private_key_file("test/key.pem", SslFiletype::PEM)
.unwrap();
Builder {
ctx,
ssl_cb: Box::new(|_| {}),
io_cb: Box::new(|_| {}),
should_error: false,
}
}
pub fn client(&self) -> ClientBuilder {
ClientBuilder {
ctx: SslContext::builder(SslMethod::tls()).unwrap(),
addr: self.addr,
}
}
pub fn connect_tcp(&self) -> TcpStream {
TcpStream::connect(self.addr).unwrap()
}
}
pub struct Builder {
ctx: SslContextBuilder,
ssl_cb: Box<dyn FnMut(&mut SslRef) + Send>,
io_cb: Box<dyn FnMut(SslStream<TcpStream>) + Send>,
should_error: bool,
}
impl Builder {
pub fn ctx(&mut self) -> &mut SslContextBuilder {
&mut self.ctx
}
pub fn ssl_cb<F>(&mut self, cb: F)
where
F: 'static + FnMut(&mut SslRef) + Send,
{
self.ssl_cb = Box::new(cb);
}
pub fn io_cb<F>(&mut self, cb: F)
where
F: 'static + FnMut(SslStream<TcpStream>) + Send,
{
self.io_cb = Box::new(cb);
}
pub fn should_error(&mut self) {
self.should_error = true;
}
pub fn build(self) -> Server {
let ctx = self.ctx.build();
let socket = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = socket.local_addr().unwrap();
let mut ssl_cb = self.ssl_cb;
let mut io_cb = self.io_cb;
let should_error = self.should_error;
let handle = thread::spawn(move || {
let socket = socket.accept().unwrap().0;
let mut ssl = Ssl::new(&ctx).unwrap();
ssl_cb(&mut ssl);
let r = ssl.accept(socket);
if should_error {
r.unwrap_err();
} else {
let mut socket = r.unwrap();
socket.write_all(&[0]).unwrap();
io_cb(socket);
}
});
Server {
handle: Some(handle),
addr,
}
}
}
pub struct ClientBuilder {
ctx: SslContextBuilder,
addr: SocketAddr,
}
impl ClientBuilder {
pub fn ctx(&mut self) -> &mut SslContextBuilder {
&mut self.ctx
}
pub fn build(self) -> Client {
Client {
ctx: self.ctx.build(),
addr: self.addr,
}
}
pub fn connect(self) -> SslStream<TcpStream> {
self.build().builder().connect()
}
pub fn connect_err(self) {
self.build().builder().connect_err();
}
}
pub struct Client {
ctx: SslContext,
addr: SocketAddr,
}
impl Client {
pub fn builder(&self) -> ClientSslBuilder {
ClientSslBuilder {
ssl: Ssl::new(&self.ctx).unwrap(),
addr: self.addr,
}
}
}
pub struct ClientSslBuilder {
ssl: Ssl,
addr: SocketAddr,
}
impl ClientSslBuilder {
pub fn ssl(&mut self) -> &mut SslRef {
&mut self.ssl
}
pub fn connect(self) -> SslStream<TcpStream> {
let socket = TcpStream::connect(self.addr).unwrap();
let mut s = self.ssl.connect(socket).unwrap();
s.read_exact(&mut [0]).unwrap();
s
}
pub fn connect_err(self) {
let socket = TcpStream::connect(self.addr).unwrap();
self.ssl.connect(socket).unwrap_err();
}
}

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