summaryrefslogtreecommitdiffstats
path: root/vendor/openssl/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/openssl/src
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/openssl/src')
-rw-r--r--vendor/openssl/src/asn1.rs77
-rw-r--r--vendor/openssl/src/bn.rs2
-rw-r--r--vendor/openssl/src/cipher.rs1
-rw-r--r--vendor/openssl/src/derive.rs43
-rw-r--r--vendor/openssl/src/dh.rs66
-rw-r--r--vendor/openssl/src/dsa.rs80
-rw-r--r--vendor/openssl/src/ec.rs20
-rw-r--r--vendor/openssl/src/ecdsa.rs2
-rw-r--r--vendor/openssl/src/hash.rs2
-rw-r--r--vendor/openssl/src/lib.rs3
-rw-r--r--vendor/openssl/src/md_ctx.rs2
-rw-r--r--vendor/openssl/src/nid.rs6
-rw-r--r--vendor/openssl/src/pkcs5.rs26
-rw-r--r--vendor/openssl/src/pkey.rs62
-rw-r--r--vendor/openssl/src/pkey_ctx.rs21
-rw-r--r--vendor/openssl/src/rsa.rs2
-rw-r--r--vendor/openssl/src/sign.rs16
-rw-r--r--vendor/openssl/src/ssl/mod.rs69
-rw-r--r--vendor/openssl/src/ssl/test/mod.rs5
-rw-r--r--vendor/openssl/src/symm.rs19
-rw-r--r--vendor/openssl/src/x509/extension.rs35
-rw-r--r--vendor/openssl/src/x509/mod.rs275
-rw-r--r--vendor/openssl/src/x509/tests.rs152
-rw-r--r--vendor/openssl/src/x509/verify.rs4
24 files changed, 865 insertions, 125 deletions
diff --git a/vendor/openssl/src/asn1.rs b/vendor/openssl/src/asn1.rs
index 8823f95b5..801310d41 100644
--- a/vendor/openssl/src/asn1.rs
+++ b/vendor/openssl/src/asn1.rs
@@ -28,6 +28,7 @@ use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_char, c_int, c_long, time_t};
use std::cmp::Ordering;
+use std::convert::TryInto;
use std::ffi::CString;
use std::fmt;
use std::ptr;
@@ -612,8 +613,49 @@ impl Asn1BitStringRef {
}
foreign_type_and_impl_send_sync! {
+ type CType = ffi::ASN1_OCTET_STRING;
+ fn drop = ffi::ASN1_OCTET_STRING_free;
+ /// ASN.1 OCTET STRING type
+ pub struct Asn1OctetString;
+ /// A reference to an [`Asn1OctetString`].
+ pub struct Asn1OctetStringRef;
+}
+
+impl Asn1OctetString {
+ /// Creates an Asn1OctetString from bytes
+ pub fn new_from_bytes(value: &[u8]) -> Result<Self, ErrorStack> {
+ ffi::init();
+ unsafe {
+ let s = cvt_p(ffi::ASN1_OCTET_STRING_new())?;
+ ffi::ASN1_OCTET_STRING_set(s, value.as_ptr(), value.len().try_into().unwrap());
+ Ok(Self::from_ptr(s))
+ }
+ }
+}
+
+impl Asn1OctetStringRef {
+ /// Returns the octet string as an array of bytes.
+ #[corresponds(ASN1_STRING_get0_data)]
+ pub fn as_slice(&self) -> &[u8] {
+ unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr().cast()), self.len()) }
+ }
+
+ /// Returns the number of bytes in the octet string.
+ #[corresponds(ASN1_STRING_length)]
+ pub fn len(&self) -> usize {
+ unsafe { ffi::ASN1_STRING_length(self.as_ptr().cast()) as usize }
+ }
+
+ /// Determines if the string is empty.
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+}
+
+foreign_type_and_impl_send_sync! {
type CType = ffi::ASN1_OBJECT;
fn drop = ffi::ASN1_OBJECT_free;
+ fn clone = ffi::OBJ_dup;
/// Object Identifier
///
@@ -696,7 +738,7 @@ impl fmt::Debug for Asn1ObjectRef {
}
cfg_if! {
- if #[cfg(any(ossl110, libressl273))] {
+ if #[cfg(any(ossl110, libressl273, boringssl))] {
use ffi::ASN1_STRING_get0_data;
} else {
#[allow(bad_style)]
@@ -706,6 +748,32 @@ cfg_if! {
}
}
+foreign_type_and_impl_send_sync! {
+ type CType = ffi::ASN1_ENUMERATED;
+ fn drop = ffi::ASN1_ENUMERATED_free;
+
+ /// An ASN.1 enumerated.
+ pub struct Asn1Enumerated;
+ /// A reference to an [`Asn1Enumerated`].
+ pub struct Asn1EnumeratedRef;
+}
+
+impl Asn1EnumeratedRef {
+ /// Get the value, if it fits in the required bounds.
+ #[corresponds(ASN1_ENUMERATED_get_int64)]
+ #[cfg(ossl110)]
+ pub fn get_i64(&self) -> Result<i64, ErrorStack> {
+ let mut crl_reason = 0;
+ unsafe {
+ cvt(ffi::ASN1_ENUMERATED_get_int64(
+ &mut crl_reason,
+ self.as_ptr(),
+ ))?;
+ }
+ Ok(crl_reason)
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -833,4 +901,11 @@ mod tests {
&[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01],
);
}
+
+ #[test]
+ fn asn1_octet_string() {
+ let octet_string = Asn1OctetString::new_from_bytes(b"hello world").unwrap();
+ assert_eq!(octet_string.as_slice(), b"hello world");
+ assert_eq!(octet_string.len(), 11);
+ }
}
diff --git a/vendor/openssl/src/bn.rs b/vendor/openssl/src/bn.rs
index 0328730a2..5cfe4b375 100644
--- a/vendor/openssl/src/bn.rs
+++ b/vendor/openssl/src/bn.rs
@@ -814,7 +814,7 @@ impl BigNumRef {
/// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
/// ```
#[corresponds(BN_bn2binpad)]
- #[cfg(ossl110)]
+ #[cfg(any(ossl110, libressl340, boringssl))]
pub fn to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack> {
let mut v = Vec::with_capacity(pad_to as usize);
unsafe {
diff --git a/vendor/openssl/src/cipher.rs b/vendor/openssl/src/cipher.rs
index aeedf459a..87f7660cd 100644
--- a/vendor/openssl/src/cipher.rs
+++ b/vendor/openssl/src/cipher.rs
@@ -324,6 +324,7 @@ impl Cipher {
unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) }
}
+ #[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
pub fn rc4() -> &'static CipherRef {
unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) }
}
diff --git a/vendor/openssl/src/derive.rs b/vendor/openssl/src/derive.rs
index 5d422f697..424c5f92d 100644
--- a/vendor/openssl/src/derive.rs
+++ b/vendor/openssl/src/derive.rs
@@ -56,6 +56,7 @@ use std::ptr;
use crate::error::ErrorStack;
use crate::pkey::{HasPrivate, HasPublic, PKeyRef};
use crate::{cvt, cvt_p};
+use openssl_macros::corresponds;
/// A type used to derive a shared secret between two keys.
pub struct Deriver<'a>(*mut ffi::EVP_PKEY_CTX, PhantomData<&'a ()>);
@@ -82,10 +83,7 @@ impl<'a> Deriver<'a> {
}
/// Sets the peer key used for secret derivation.
- ///
- /// This corresponds to [`EVP_PKEY_derive_set_peer`]:
- ///
- /// [`EVP_PKEY_derive_set_peer`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_derive_init.html
+ #[corresponds(EVP_PKEY_derive_set_peer)]
pub fn set_peer<T>(&mut self, key: &'a PKeyRef<T>) -> Result<(), ErrorStack>
where
T: HasPublic,
@@ -93,6 +91,29 @@ impl<'a> Deriver<'a> {
unsafe { cvt(ffi::EVP_PKEY_derive_set_peer(self.0, key.as_ptr())).map(|_| ()) }
}
+ /// Sets the peer key used for secret derivation along with optionally validating the peer public key.
+ ///
+ /// Requires OpenSSL 3.0.0 or newer.
+ #[corresponds(EVP_PKEY_derive_set_peer_ex)]
+ #[cfg(ossl300)]
+ pub fn set_peer_ex<T>(
+ &mut self,
+ key: &'a PKeyRef<T>,
+ validate_peer: bool,
+ ) -> Result<(), ErrorStack>
+ where
+ T: HasPublic,
+ {
+ unsafe {
+ cvt(ffi::EVP_PKEY_derive_set_peer_ex(
+ self.0,
+ key.as_ptr(),
+ validate_peer as i32,
+ ))
+ .map(|_| ())
+ }
+ }
+
/// Returns the size of the shared secret.
///
/// It can be used to size the buffer passed to [`Deriver::derive`].
@@ -179,4 +200,18 @@ mod test {
let shared = deriver.derive_to_vec().unwrap();
assert!(!shared.is_empty());
}
+
+ #[test]
+ #[cfg(ossl300)]
+ fn test_ec_key_derive_ex() {
+ let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
+ let ec_key = EcKey::generate(&group).unwrap();
+ let ec_key2 = EcKey::generate(&group).unwrap();
+ let pkey = PKey::from_ec_key(ec_key).unwrap();
+ let pkey2 = PKey::from_ec_key(ec_key2).unwrap();
+ let mut deriver = Deriver::new(&pkey).unwrap();
+ deriver.set_peer_ex(&pkey2, true).unwrap();
+ let shared = deriver.derive_to_vec().unwrap();
+ assert!(!shared.is_empty());
+ }
}
diff --git a/vendor/openssl/src/dh.rs b/vendor/openssl/src/dh.rs
index e781543e2..7445e3408 100644
--- a/vendor/openssl/src/dh.rs
+++ b/vendor/openssl/src/dh.rs
@@ -7,7 +7,7 @@ use std::ptr;
use crate::bn::{BigNum, BigNumRef};
use crate::error::ErrorStack;
-use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private};
+use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
@@ -39,6 +39,16 @@ where
params_to_der,
ffi::i2d_DHparams
}
+
+ /// Validates DH parameters for correctness
+ #[corresponds(DH_check_key)]
+ pub fn check_key(&self) -> Result<bool, ErrorStack> {
+ unsafe {
+ let mut codes = 0;
+ cvt(ffi::DH_check(self.as_ptr(), &mut codes))?;
+ Ok(codes == 0)
+ }
+ }
}
impl Dh<Params> {
@@ -66,6 +76,16 @@ impl Dh<Params> {
}
}
+ /// Sets the public key on the DH object.
+ pub fn set_public_key(self, pub_key: BigNum) -> Result<Dh<Public>, ErrorStack> {
+ unsafe {
+ let dh_ptr = self.0;
+ cvt(DH_set0_key(dh_ptr, pub_key.as_ptr(), ptr::null_mut()))?;
+ mem::forget((self, pub_key));
+ Ok(Dh::from_ptr(dh_ptr))
+ }
+ }
+
/// Sets the private key on the DH object and recomputes the public key.
pub fn set_private_key(self, priv_key: BigNum) -> Result<Dh<Private>, ErrorStack> {
unsafe {
@@ -79,6 +99,16 @@ impl Dh<Params> {
}
}
+ /// Sets the public and private keys on the DH object.
+ pub fn set_key(self, pub_key: BigNum, priv_key: BigNum) -> Result<Dh<Private>, ErrorStack> {
+ unsafe {
+ let dh_ptr = self.0;
+ cvt(DH_set0_key(dh_ptr, pub_key.as_ptr(), priv_key.as_ptr()))?;
+ mem::forget((self, pub_key, priv_key));
+ Ok(Dh::from_ptr(dh_ptr))
+ }
+ }
+
/// Generates DH params based on the given `prime_len` and a fixed `generator` value.
#[corresponds(DH_generate_parameters_ex)]
pub fn generate_params(prime_len: u32, generator: u32) -> Result<Dh<Params>, ErrorStack> {
@@ -368,6 +398,30 @@ mod tests {
}
#[test]
+ #[cfg(ossl102)]
+ fn test_set_keys() {
+ let dh1 = Dh::get_2048_256().unwrap();
+ let key1 = dh1.generate_key().unwrap();
+
+ let dh2 = Dh::get_2048_256().unwrap();
+ let key2 = dh2
+ .set_public_key(key1.public_key().to_owned().unwrap())
+ .unwrap();
+
+ assert_eq!(key1.public_key(), key2.public_key());
+
+ let dh3 = Dh::get_2048_256().unwrap();
+ let key3 = dh3
+ .set_key(
+ key1.public_key().to_owned().unwrap(),
+ key1.private_key().to_owned().unwrap(),
+ )
+ .unwrap();
+ assert_eq!(key1.public_key(), key3.public_key());
+ assert_eq!(key1.private_key(), key3.private_key());
+ }
+
+ #[test]
fn test_dh_from_pem() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
let params = include_bytes!("../test/dhparams.pem");
@@ -413,4 +467,14 @@ mod tests {
assert_eq!(shared_a, shared_b);
}
+
+ #[test]
+ fn test_dh_check_key() {
+ let dh1 = Dh::generate_params(512, 2).unwrap();
+ let p = BigNum::from_hex_str("04").unwrap();
+ let g = BigNum::from_hex_str("02").unwrap();
+ let dh2 = Dh::from_pqg(p, None, g).unwrap();
+ assert!(dh1.check_key().unwrap());
+ assert!(!dh2.check_key().unwrap());
+ }
}
diff --git a/vendor/openssl/src/dsa.rs b/vendor/openssl/src/dsa.rs
index c550f6548..1a63e8ad8 100644
--- a/vendor/openssl/src/dsa.rs
+++ b/vendor/openssl/src/dsa.rs
@@ -7,6 +7,7 @@
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
+#[cfg(not(boringssl))]
use libc::c_int;
use std::fmt;
use std::mem;
@@ -14,7 +15,7 @@ use std::ptr;
use crate::bn::{BigNum, BigNumRef};
use crate::error::ErrorStack;
-use crate::pkey::{HasParams, HasPrivate, HasPublic, Private, Public};
+use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
use crate::util::ForeignTypeRefExt;
use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
@@ -127,6 +128,13 @@ where
ffi::PEM_write_bio_DSAPrivateKey
}
+ to_der! {
+ /// Serializes the private_key to a DER-encoded `DSAPrivateKey` structure.
+ #[corresponds(i2d_DSAPrivateKey)]
+ private_key_to_der,
+ ffi::i2d_DSAPrivateKey
+ }
+
/// Returns a reference to the private key component of `self`.
#[corresponds(DSA_get0_key)]
pub fn priv_key(&self) -> &BigNumRef {
@@ -183,17 +191,21 @@ type BitType = libc::c_uint;
#[cfg(not(boringssl))]
type BitType = c_int;
-impl Dsa<Private> {
- /// Generate a DSA key pair.
- ///
- /// Calls [`DSA_generate_parameters_ex`] to populate the `p`, `g`, and `q` values.
- /// These values are used to generate the key pair with [`DSA_generate_key`].
- ///
- /// The `bits` parameter corresponds to the length of the prime `p`.
- ///
- /// [`DSA_generate_parameters_ex`]: https://www.openssl.org/docs/manmaster/crypto/DSA_generate_parameters_ex.html
- /// [`DSA_generate_key`]: https://www.openssl.org/docs/manmaster/crypto/DSA_generate_key.html
- pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
+impl Dsa<Params> {
+ /// Creates a DSA params based upon the given parameters.
+ #[corresponds(DSA_set0_pqg)]
+ pub fn from_pqg(p: BigNum, q: BigNum, g: BigNum) -> Result<Dsa<Params>, ErrorStack> {
+ unsafe {
+ let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
+ cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
+ mem::forget((p, q, g));
+ Ok(dsa)
+ }
+ }
+
+ /// Generates DSA params based on the given number of bits.
+ #[corresponds(DSA_generate_parameters_ex)]
+ pub fn generate_params(bits: u32) -> Result<Dsa<Params>, ErrorStack> {
ffi::init();
unsafe {
let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?);
@@ -206,11 +218,31 @@ impl Dsa<Private> {
ptr::null_mut(),
ptr::null_mut(),
))?;
- cvt(ffi::DSA_generate_key(dsa.0))?;
Ok(dsa)
}
}
+ /// Generates a private key based on the DSA params.
+ #[corresponds(DSA_generate_key)]
+ pub fn generate_key(self) -> Result<Dsa<Private>, ErrorStack> {
+ unsafe {
+ let dsa_ptr = self.0;
+ cvt(ffi::DSA_generate_key(dsa_ptr))?;
+ mem::forget(self);
+ Ok(Dsa::from_ptr(dsa_ptr))
+ }
+ }
+}
+
+impl Dsa<Private> {
+ /// Generate a DSA key pair.
+ ///
+ /// The `bits` parameter corresponds to the length of the prime `p`.
+ pub fn generate(bits: u32) -> Result<Dsa<Private>, ErrorStack> {
+ let params = Dsa::generate_params(bits)?;
+ params.generate_key()
+ }
+
/// Create a DSA key pair with the given parameters
///
/// `p`, `q` and `g` are the common parameters.
@@ -283,7 +315,7 @@ impl<T> fmt::Debug for Dsa<T> {
}
cfg_if! {
- if #[cfg(any(ossl110, libressl273))] {
+ if #[cfg(any(ossl110, libressl273, boringssl))] {
use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg};
} else {
#[allow(bad_style)]
@@ -462,7 +494,7 @@ impl DsaSigRef {
}
cfg_if! {
- if #[cfg(any(ossl110, libressl273))] {
+ if #[cfg(any(ossl110, libressl273, boringssl))] {
use ffi::{DSA_SIG_set0, DSA_SIG_get0};
} else {
#[allow(bad_style)]
@@ -557,6 +589,24 @@ mod test {
}
#[test]
+ fn test_params() {
+ let params = Dsa::generate_params(1024).unwrap();
+ let p = params.p().to_owned().unwrap();
+ let q = params.q().to_owned().unwrap();
+ let g = params.g().to_owned().unwrap();
+ let key = params.generate_key().unwrap();
+ let params2 = Dsa::from_pqg(
+ key.p().to_owned().unwrap(),
+ key.q().to_owned().unwrap(),
+ key.g().to_owned().unwrap(),
+ )
+ .unwrap();
+ assert_eq!(p, *params2.p());
+ assert_eq!(q, *params2.q());
+ assert_eq!(g, *params2.g());
+ }
+
+ #[test]
#[cfg(not(boringssl))]
fn test_signature() {
const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
diff --git a/vendor/openssl/src/ec.rs b/vendor/openssl/src/ec.rs
index 248ced3e4..b648aec33 100644
--- a/vendor/openssl/src/ec.rs
+++ b/vendor/openssl/src/ec.rs
@@ -57,7 +57,7 @@ impl PointConversionForm {
/// Named Curve or Explicit
///
/// This type acts as a boolean as to whether the `EcGroup` is named or explicit.
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Asn1Flag(c_int);
impl Asn1Flag {
@@ -294,6 +294,12 @@ impl EcGroupRef {
}
}
+ /// Gets the flag determining if the group corresponds to a named curve.
+ #[corresponds(EC_GROUP_get_asn1_flag)]
+ pub fn asn1_flag(&self) -> Asn1Flag {
+ unsafe { Asn1Flag(ffi::EC_GROUP_get_asn1_flag(self.as_ptr())) }
+ }
+
/// Returns the name of the curve, if a name is associated.
#[corresponds(EC_GROUP_get_curve_name)]
pub fn curve_name(&self) -> Option<Nid> {
@@ -485,7 +491,7 @@ impl EcPointRef {
/// Places affine coordinates of a curve over a prime field in the provided
/// `x` and `y` `BigNum`s.
#[corresponds(EC_POINT_get_affine_coordinates)]
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, boringssl, libressl350))]
pub fn affine_coordinates(
&self,
group: &EcGroupRef,
@@ -1191,7 +1197,7 @@ mod test {
assert!(ec_key.check_key().is_ok());
}
- #[cfg(ossl111)]
+ #[cfg(any(ossl111, boringssl, libressl350))]
#[test]
fn get_affine_coordinates() {
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
@@ -1265,4 +1271,12 @@ mod test {
let group2 = EcGroup::from_curve_name(Nid::X9_62_PRIME239V3).unwrap();
assert!(!g.is_on_curve(&group2, &mut ctx).unwrap());
}
+
+ #[test]
+ #[cfg(any(boringssl, ossl111, libressl350))]
+ fn asn1_flag() {
+ let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
+ let flag = group.asn1_flag();
+ assert_eq!(flag, Asn1Flag::NAMED_CURVE);
+ }
}
diff --git a/vendor/openssl/src/ecdsa.rs b/vendor/openssl/src/ecdsa.rs
index 0a960e7b9..f3b27b395 100644
--- a/vendor/openssl/src/ecdsa.rs
+++ b/vendor/openssl/src/ecdsa.rs
@@ -110,7 +110,7 @@ impl EcdsaSigRef {
}
cfg_if! {
- if #[cfg(any(ossl110, libressl273))] {
+ if #[cfg(any(ossl110, libressl273, boringssl))] {
use ffi::{ECDSA_SIG_set0, ECDSA_SIG_get0};
} else {
#[allow(bad_style)]
diff --git a/vendor/openssl/src/hash.rs b/vendor/openssl/src/hash.rs
index 37442fb27..52d73deed 100644
--- a/vendor/openssl/src/hash.rs
+++ b/vendor/openssl/src/hash.rs
@@ -43,7 +43,7 @@ use crate::nid::Nid;
use crate::{cvt, cvt_p};
cfg_if! {
- if #[cfg(ossl110)] {
+ if #[cfg(any(ossl110, boringssl))] {
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
} else {
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
diff --git a/vendor/openssl/src/lib.rs b/vendor/openssl/src/lib.rs
index 5678298a0..c2c390cc1 100644
--- a/vendor/openssl/src/lib.rs
+++ b/vendor/openssl/src/lib.rs
@@ -1,7 +1,7 @@
//! Bindings to OpenSSL
//!
//! This crate provides a safe interface to the popular OpenSSL cryptography library. OpenSSL versions 1.0.1 through
-//! 3.x.x and LibreSSL versions 2.5 through 3.4.1 are supported.
+//! 3.x.x and LibreSSL versions 2.5 through 3.7.x are supported.
//!
//! # Building
//!
@@ -165,7 +165,6 @@ pub mod nid;
#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_OCSP")))]
pub mod ocsp;
pub mod pkcs12;
-#[cfg(not(boringssl))]
pub mod pkcs5;
#[cfg(not(boringssl))]
pub mod pkcs7;
diff --git a/vendor/openssl/src/md_ctx.rs b/vendor/openssl/src/md_ctx.rs
index c4d3f06b9..156f3c2fc 100644
--- a/vendor/openssl/src/md_ctx.rs
+++ b/vendor/openssl/src/md_ctx.rs
@@ -93,7 +93,7 @@ use std::convert::TryFrom;
use std::ptr;
cfg_if! {
- if #[cfg(ossl110)] {
+ if #[cfg(any(ossl110, boringssl))] {
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
} else {
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
diff --git a/vendor/openssl/src/nid.rs b/vendor/openssl/src/nid.rs
index 1ab96f370..91fcdeca9 100644
--- a/vendor/openssl/src/nid.rs
+++ b/vendor/openssl/src/nid.rs
@@ -51,13 +51,13 @@ pub struct Nid(c_int);
#[allow(non_snake_case)]
impl Nid {
/// Create a `Nid` from an integer representation.
- pub fn from_raw(raw: c_int) -> Nid {
+ pub const fn from_raw(raw: c_int) -> Nid {
Nid(raw)
}
/// Return the integer representation of a `Nid`.
#[allow(clippy::trivially_copy_pass_by_ref)]
- pub fn as_raw(&self) -> c_int {
+ pub const fn as_raw(&self) -> c_int {
self.0
}
@@ -1074,6 +1074,8 @@ impl Nid {
pub const AES_128_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_128_cbc_hmac_sha1);
pub const AES_192_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_192_cbc_hmac_sha1);
pub const AES_256_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_256_cbc_hmac_sha1);
+ #[cfg(ossl111)]
+ pub const SM2: Nid = Nid(ffi::NID_sm2);
#[cfg(any(ossl111, libressl291))]
pub const SM3: Nid = Nid(ffi::NID_sm3);
#[cfg(ossl111)]
diff --git a/vendor/openssl/src/pkcs5.rs b/vendor/openssl/src/pkcs5.rs
index c15ce4776..cd704e825 100644
--- a/vendor/openssl/src/pkcs5.rs
+++ b/vendor/openssl/src/pkcs5.rs
@@ -1,9 +1,13 @@
+#[cfg(not(boringssl))]
use libc::c_int;
+use std::convert::TryInto;
+#[cfg(not(boringssl))]
use std::ptr;
use crate::cvt;
use crate::error::ErrorStack;
use crate::hash::MessageDigest;
+#[cfg(not(boringssl))]
use crate::symm::Cipher;
use openssl_macros::corresponds;
@@ -25,6 +29,7 @@ pub struct KeyIvPair {
/// `pbkdf2_hmac` or another more modern key derivation algorithm.
#[corresponds(EVP_BytesToKey)]
#[allow(clippy::useless_conversion)]
+#[cfg(not(boringssl))]
pub fn bytes_to_key(
cipher: Cipher,
digest: MessageDigest,
@@ -91,19 +96,15 @@ pub fn pbkdf2_hmac(
key: &mut [u8],
) -> Result<(), ErrorStack> {
unsafe {
- assert!(pass.len() <= c_int::max_value() as usize);
- assert!(salt.len() <= c_int::max_value() as usize);
- assert!(key.len() <= c_int::max_value() as usize);
-
ffi::init();
cvt(ffi::PKCS5_PBKDF2_HMAC(
pass.as_ptr() as *const _,
- pass.len() as c_int,
+ pass.len().try_into().unwrap(),
salt.as_ptr(),
- salt.len() as c_int,
- iter as c_int,
+ salt.len().try_into().unwrap(),
+ iter.try_into().unwrap(),
hash.as_ptr(),
- key.len() as c_int,
+ key.len().try_into().unwrap(),
key.as_mut_ptr(),
))
.map(|_| ())
@@ -114,7 +115,8 @@ pub fn pbkdf2_hmac(
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PBE_scrypt)]
-#[cfg(any(ossl110))]
+#[cfg(any(ossl110, boringssl))]
+#[allow(clippy::useless_conversion)]
pub fn scrypt(
pass: &[u8],
salt: &[u8],
@@ -134,7 +136,7 @@ pub fn scrypt(
n,
r,
p,
- maxmem,
+ maxmem.try_into().unwrap(),
key.as_mut_ptr() as *mut _,
key.len(),
))
@@ -145,6 +147,7 @@ pub fn scrypt(
#[cfg(test)]
mod tests {
use crate::hash::MessageDigest;
+ #[cfg(not(boringssl))]
use crate::symm::Cipher;
// Test vectors from
@@ -246,6 +249,7 @@ mod tests {
}
#[test]
+ #[cfg(not(boringssl))]
fn bytes_to_key() {
let salt = [16_u8, 34_u8, 19_u8, 23_u8, 141_u8, 4_u8, 207_u8, 221_u8];
@@ -282,7 +286,7 @@ mod tests {
}
#[test]
- #[cfg(any(ossl110))]
+ #[cfg(any(ossl110, boringssl))]
fn scrypt() {
let pass = "pleaseletmein";
let salt = "SodiumChloride";
diff --git a/vendor/openssl/src/pkey.rs b/vendor/openssl/src/pkey.rs
index bec4bfdaf..453aeed72 100644
--- a/vendor/openssl/src/pkey.rs
+++ b/vendor/openssl/src/pkey.rs
@@ -57,7 +57,7 @@ use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_int, c_long};
use openssl_macros::corresponds;
-use std::convert::TryFrom;
+use std::convert::{TryFrom, TryInto};
use std::ffi::CString;
use std::fmt;
use std::mem;
@@ -85,8 +85,10 @@ impl Id {
pub const DSA: Id = Id(ffi::EVP_PKEY_DSA);
pub const DH: Id = Id(ffi::EVP_PKEY_DH);
pub const EC: Id = Id(ffi::EVP_PKEY_EC);
+ #[cfg(ossl111)]
+ pub const SM2: Id = Id(ffi::EVP_PKEY_SM2);
- #[cfg(ossl110)]
+ #[cfg(any(ossl110, boringssl))]
pub const HKDF: Id = Id(ffi::EVP_PKEY_HKDF);
#[cfg(any(ossl111, boringssl, libressl370))]
@@ -97,6 +99,8 @@ impl Id {
pub const X25519: Id = Id(ffi::EVP_PKEY_X25519);
#[cfg(ossl111)]
pub const X448: Id = Id(ffi::EVP_PKEY_X448);
+ #[cfg(ossl111)]
+ pub const POLY1305: Id = Id(ffi::EVP_PKEY_POLY1305);
/// Creates a `Id` from an integer representation.
pub fn from_raw(value: c_int) -> Id {
@@ -244,7 +248,11 @@ where
where
U: HasPublic,
{
- unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 }
+ let res = unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 };
+ // Clear the stack. OpenSSL will put an error on the stack when the
+ // keys are different types in some situations.
+ let _ = ErrorStack::get();
+ res
}
/// Raw byte representation of a public key.
@@ -344,10 +352,6 @@ where
/// Serializes a private key into a DER-formatted PKCS#8, using the supplied password to
/// encrypt the key.
- ///
- /// # Panics
- ///
- /// Panics if `passphrase` contains an embedded null.
#[corresponds(i2d_PKCS8PrivateKey_bio)]
pub fn private_key_to_pkcs8_passphrase(
&self,
@@ -356,14 +360,12 @@ where
) -> Result<Vec<u8>, ErrorStack> {
unsafe {
let bio = MemBio::new()?;
- let len = passphrase.len();
- let passphrase = CString::new(passphrase).unwrap();
cvt(ffi::i2d_PKCS8PrivateKey_bio(
bio.as_ptr(),
self.as_ptr(),
cipher.as_ptr(),
passphrase.as_ptr() as *const _ as *mut _,
- len as ::libc::c_int,
+ passphrase.len().try_into().unwrap(),
None,
ptr::null_mut(),
))?;
@@ -406,11 +408,7 @@ impl<T> PKey<T> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
- cvt(ffi::EVP_PKEY_assign(
- pkey.0,
- ffi::EVP_PKEY_RSA,
- rsa.as_ptr() as *mut _,
- ))?;
+ cvt(ffi::EVP_PKEY_assign_RSA(pkey.0, rsa.as_ptr()))?;
mem::forget(rsa);
Ok(pkey)
}
@@ -422,11 +420,7 @@ impl<T> PKey<T> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
- cvt(ffi::EVP_PKEY_assign(
- pkey.0,
- ffi::EVP_PKEY_DSA,
- dsa.as_ptr() as *mut _,
- ))?;
+ cvt(ffi::EVP_PKEY_assign_DSA(pkey.0, dsa.as_ptr()))?;
mem::forget(dsa);
Ok(pkey)
}
@@ -434,15 +428,12 @@ impl<T> PKey<T> {
/// Creates a new `PKey` containing a Diffie-Hellman key.
#[corresponds(EVP_PKEY_assign_DH)]
+ #[cfg(not(boringssl))]
pub fn from_dh(dh: Dh<T>) -> Result<PKey<T>, ErrorStack> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
- cvt(ffi::EVP_PKEY_assign(
- pkey.0,
- ffi::EVP_PKEY_DH,
- dh.as_ptr() as *mut _,
- ))?;
+ cvt(ffi::EVP_PKEY_assign_DH(pkey.0, dh.as_ptr()))?;
mem::forget(dh);
Ok(pkey)
}
@@ -454,11 +445,7 @@ impl<T> PKey<T> {
unsafe {
let evp = cvt_p(ffi::EVP_PKEY_new())?;
let pkey = PKey::from_ptr(evp);
- cvt(ffi::EVP_PKEY_assign(
- pkey.0,
- ffi::EVP_PKEY_EC,
- ec_key.as_ptr() as *mut _,
- ))?;
+ cvt(ffi::EVP_PKEY_assign_EC_KEY(pkey.0, ec_key.as_ptr()))?;
mem::forget(ec_key);
Ok(pkey)
}
@@ -861,6 +848,7 @@ impl<T> TryFrom<PKey<T>> for Dsa<T> {
}
}
+#[cfg(not(boringssl))]
impl<T> TryFrom<Dh<T>> for PKey<T> {
type Error = ErrorStack;
@@ -885,6 +873,7 @@ mod tests {
use crate::dh::Dh;
use crate::dsa::Dsa;
use crate::ec::EcKey;
+ use crate::error::Error;
use crate::nid::Nid;
use crate::rsa::Rsa;
use crate::symm::Cipher;
@@ -1168,4 +1157,17 @@ mod tests {
let key = PKey::ec_gen("prime256v1").unwrap();
assert!(key.ec_key().is_ok());
}
+
+ #[test]
+ fn test_public_eq() {
+ let rsa = Rsa::generate(2048).unwrap();
+ let pkey1 = PKey::from_rsa(rsa).unwrap();
+
+ let group = crate::ec::EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
+ let ec_key = EcKey::generate(&group).unwrap();
+ let pkey2 = PKey::from_ec_key(ec_key).unwrap();
+
+ assert!(!pkey1.public_eq(&pkey2));
+ assert!(Error::get().is_none());
+ }
}
diff --git a/vendor/openssl/src/pkey_ctx.rs b/vendor/openssl/src/pkey_ctx.rs
index 42289b9f4..aba8a66a3 100644
--- a/vendor/openssl/src/pkey_ctx.rs
+++ b/vendor/openssl/src/pkey_ctx.rs
@@ -485,7 +485,7 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_set_hkdf_md)]
- #[cfg(ossl110)]
+ #[cfg(any(ossl110, boringssl))]
#[inline]
pub fn set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack> {
unsafe {
@@ -527,10 +527,13 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_set1_hkdf_key)]
- #[cfg(ossl110)]
+ #[cfg(any(ossl110, boringssl))]
#[inline]
pub fn set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> {
+ #[cfg(not(boringssl))]
let len = c_int::try_from(key.len()).unwrap();
+ #[cfg(boringssl)]
+ let len = key.len();
unsafe {
cvt(ffi::EVP_PKEY_CTX_set1_hkdf_key(
@@ -549,10 +552,13 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_set1_hkdf_salt)]
- #[cfg(ossl110)]
+ #[cfg(any(ossl110, boringssl))]
#[inline]
pub fn set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack> {
+ #[cfg(not(boringssl))]
let len = c_int::try_from(salt.len()).unwrap();
+ #[cfg(boringssl)]
+ let len = salt.len();
unsafe {
cvt(ffi::EVP_PKEY_CTX_set1_hkdf_salt(
@@ -571,10 +577,13 @@ impl<T> PkeyCtxRef<T> {
///
/// Requires OpenSSL 1.1.0 or newer.
#[corresponds(EVP_PKEY_CTX_add1_hkdf_info)]
- #[cfg(ossl110)]
+ #[cfg(any(ossl110, boringssl))]
#[inline]
pub fn add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack> {
+ #[cfg(not(boringssl))]
let len = c_int::try_from(info.len()).unwrap();
+ #[cfg(boringssl)]
+ let len = info.len();
unsafe {
cvt(ffi::EVP_PKEY_CTX_add1_hkdf_info(
@@ -632,7 +641,7 @@ mod test {
#[cfg(not(boringssl))]
use crate::cipher::Cipher;
use crate::ec::{EcGroup, EcKey};
- #[cfg(any(ossl102, libressl310))]
+ #[cfg(any(ossl102, libressl310, boringssl))]
use crate::md::Md;
use crate::nid::Nid;
use crate::pkey::PKey;
@@ -717,7 +726,7 @@ mod test {
}
#[test]
- #[cfg(ossl110)]
+ #[cfg(any(ossl110, boringssl))]
fn hkdf() {
let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap();
ctx.derive_init().unwrap();
diff --git a/vendor/openssl/src/rsa.rs b/vendor/openssl/src/rsa.rs
index 68cf64b03..f155b12df 100644
--- a/vendor/openssl/src/rsa.rs
+++ b/vendor/openssl/src/rsa.rs
@@ -581,7 +581,7 @@ impl<T> fmt::Debug for Rsa<T> {
}
cfg_if! {
- if #[cfg(any(ossl110, libressl273))] {
+ if #[cfg(any(ossl110, libressl273, boringssl))] {
use ffi::{
RSA_get0_key, RSA_get0_factors, RSA_get0_crt_params, RSA_set0_key, RSA_set0_factors,
RSA_set0_crt_params,
diff --git a/vendor/openssl/src/sign.rs b/vendor/openssl/src/sign.rs
index 406bb42e8..a32f5c914 100644
--- a/vendor/openssl/src/sign.rs
+++ b/vendor/openssl/src/sign.rs
@@ -117,10 +117,10 @@ pub struct Signer<'a> {
_p: PhantomData<&'a ()>,
}
-unsafe impl<'a> Sync for Signer<'a> {}
-unsafe impl<'a> Send for Signer<'a> {}
+unsafe impl Sync for Signer<'_> {}
+unsafe impl Send for Signer<'_> {}
-impl<'a> Drop for Signer<'a> {
+impl Drop for Signer<'_> {
fn drop(&mut self) {
// pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
unsafe {
@@ -130,7 +130,7 @@ impl<'a> Drop for Signer<'a> {
}
#[allow(clippy::len_without_is_empty)]
-impl<'a> Signer<'a> {
+impl Signer<'_> {
/// Creates a new `Signer`.
///
/// This cannot be used with Ed25519 or Ed448 keys. Please refer to
@@ -139,7 +139,7 @@ impl<'a> Signer<'a> {
/// OpenSSL documentation at [`EVP_DigestSignInit`].
///
/// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html
- pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
+ pub fn new<'a, T>(type_: MessageDigest, pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
where
T: HasPrivate,
{
@@ -154,16 +154,16 @@ impl<'a> Signer<'a> {
/// OpenSSL documentation at [`EVP_DigestSignInit`].
///
/// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html
- pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
+ pub fn new_without_digest<'a, T>(pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack>
where
T: HasPrivate,
{
Self::new_intern(None, pkey)
}
- fn new_intern<T>(
+ fn new_intern<'a, T>(
type_: Option<MessageDigest>,
- pkey: &'a PKeyRef<T>,
+ pkey: &PKeyRef<T>,
) -> Result<Signer<'a>, ErrorStack>
where
T: HasPrivate,
diff --git a/vendor/openssl/src/ssl/mod.rs b/vendor/openssl/src/ssl/mod.rs
index 6ef356d36..27e817f30 100644
--- a/vendor/openssl/src/ssl/mod.rs
+++ b/vendor/openssl/src/ssl/mod.rs
@@ -72,7 +72,7 @@ use crate::srtp::{SrtpProtectionProfile, SrtpProtectionProfileRef};
use crate::ssl::bio::BioMethod;
use crate::ssl::callbacks::*;
use crate::ssl::error::InnerError;
-use crate::stack::{Stack, StackRef};
+use crate::stack::{Stack, StackRef, Stackable};
use crate::util::{ForeignTypeExt, ForeignTypeRefExt};
use crate::x509::store::{X509Store, X509StoreBuilderRef, X509StoreRef};
#[cfg(any(ossl102, libressl261))]
@@ -599,7 +599,7 @@ impl AlpnError {
/// Terminate the handshake with a fatal alert.
///
/// Requires OpenSSL 1.1.0 or newer.
- #[cfg(any(ossl110))]
+ #[cfg(ossl110)]
pub const ALERT_FATAL: AlpnError = AlpnError(ffi::SSL_TLSEXT_ERR_ALERT_FATAL);
/// Do not select a protocol, but continue the handshake.
@@ -644,6 +644,17 @@ impl SslVersion {
/// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer.
#[cfg(any(ossl111, libressl340))]
pub const TLS1_3: SslVersion = SslVersion(ffi::TLS1_3_VERSION);
+
+ /// DTLSv1.0
+ ///
+ /// DTLS 1.0 corresponds to TLS 1.1.
+ pub const DTLS1: SslVersion = SslVersion(ffi::DTLS1_VERSION);
+
+ /// DTLSv1.2
+ ///
+ /// DTLS 1.2 corresponds to TLS 1.2 to harmonize versions. There was never a DTLS 1.1.
+ #[cfg(any(ossl102, libressl332))]
+ pub const DTLS1_2: SslVersion = SslVersion(ffi::DTLS1_2_VERSION);
}
cfg_if! {
@@ -1929,6 +1940,10 @@ impl ForeignType for SslCipher {
}
}
+impl Stackable for SslCipher {
+ type StackType = ffi::stack_st_SSL_CIPHER;
+}
+
impl Deref for SslCipher {
type Target = SslCipherRef;
@@ -2045,6 +2060,19 @@ impl SslCipherRef {
}
}
+impl fmt::Debug for SslCipherRef {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(fmt, "{}", self.name())
+ }
+}
+
+/// A stack of selected ciphers, and a stack of selected signalling cipher suites
+#[derive(Debug)]
+pub struct CipherLists {
+ pub suites: Stack<SslCipher>,
+ pub signalling_suites: Stack<SslCipher>,
+}
+
foreign_type_and_impl_send_sync! {
type CType = ffi::SSL_SESSION;
fn drop = ffi::SSL_SESSION_free;
@@ -2385,7 +2413,7 @@ impl SslRef {
///
/// Requires OpenSSL 1.0.1 or 1.0.2.
#[corresponds(SSL_set_tmp_ecdh_callback)]
- #[cfg(any(all(ossl101, not(ossl110))))]
+ #[cfg(all(ossl101, not(ossl110)))]
#[deprecated(note = "this function leaks memory and does not exist on newer OpenSSL versions")]
pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F)
where
@@ -3072,6 +3100,41 @@ impl SslRef {
}
}
+ /// Decodes a slice of wire-format cipher suite specification bytes. Unsupported cipher suites
+ /// are ignored.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ #[corresponds(SSL_bytes_to_cipher_list)]
+ #[cfg(ossl111)]
+ pub fn bytes_to_cipher_list(
+ &self,
+ bytes: &[u8],
+ isv2format: bool,
+ ) -> Result<CipherLists, ErrorStack> {
+ unsafe {
+ let ptr = bytes.as_ptr();
+ let len = bytes.len();
+ let mut sk = ptr::null_mut();
+ let mut scsvs = ptr::null_mut();
+ let res = ffi::SSL_bytes_to_cipher_list(
+ self.as_ptr(),
+ ptr,
+ len,
+ isv2format as c_int,
+ &mut sk,
+ &mut scsvs,
+ );
+ if res == 1 {
+ Ok(CipherLists {
+ suites: Stack::from_ptr(sk),
+ signalling_suites: Stack::from_ptr(scsvs),
+ })
+ } else {
+ Err(ErrorStack::get())
+ }
+ }
+ }
+
/// Returns the compression methods field of the client's hello message.
///
/// This can only be used inside of the client hello callback. Otherwise, `None` is returned.
diff --git a/vendor/openssl/src/ssl/test/mod.rs b/vendor/openssl/src/ssl/test/mod.rs
index a34309a7d..7707af238 100644
--- a/vendor/openssl/src/ssl/test/mod.rs
+++ b/vendor/openssl/src/ssl/test/mod.rs
@@ -467,7 +467,7 @@ fn test_alpn_server_advertise_multiple() {
}
#[test]
-#[cfg(any(ossl110))]
+#[cfg(ossl110)]
fn test_alpn_server_select_none_fatal() {
let mut server = Server::builder();
server.ctx().set_alpn_select_callback(|_, client| {
@@ -1458,6 +1458,9 @@ fn client_hello() {
assert!(ssl.client_hello_session_id().is_some());
assert!(ssl.client_hello_ciphers().is_some());
assert!(ssl.client_hello_compression_methods().is_some());
+ assert!(ssl
+ .bytes_to_cipher_list(ssl.client_hello_ciphers().unwrap(), ssl.client_hello_isv2())
+ .is_ok());
CALLED_BACK.store(true, Ordering::SeqCst);
Ok(ClientHelloResponse::SUCCESS)
diff --git a/vendor/openssl/src/symm.rs b/vendor/openssl/src/symm.rs
index 911a7ab2e..c1dbdfee7 100644
--- a/vendor/openssl/src/symm.rs
+++ b/vendor/openssl/src/symm.rs
@@ -142,7 +142,7 @@ impl Cipher {
}
/// Requires OpenSSL 1.1.0 or newer.
- #[cfg(ossl110)]
+ #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
pub fn aes_128_ocb() -> Cipher {
unsafe { Cipher(ffi::EVP_aes_128_ocb()) }
}
@@ -187,7 +187,7 @@ impl Cipher {
}
/// Requires OpenSSL 1.1.0 or newer.
- #[cfg(ossl110)]
+ #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
pub fn aes_192_ocb() -> Cipher {
unsafe { Cipher(ffi::EVP_aes_192_ocb()) }
}
@@ -237,7 +237,7 @@ impl Cipher {
}
/// Requires OpenSSL 1.1.0 or newer.
- #[cfg(ossl110)]
+ #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
pub fn aes_256_ocb() -> Cipher {
unsafe { Cipher(ffi::EVP_aes_256_ocb()) }
}
@@ -283,6 +283,7 @@ impl Cipher {
unsafe { Cipher(ffi::EVP_des_ede3_cfb64()) }
}
+ #[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
pub fn rc4() -> Cipher {
unsafe { Cipher(ffi::EVP_rc4()) }
}
@@ -401,14 +402,14 @@ impl Cipher {
}
/// Determines whether the cipher is using OCB mode
- #[cfg(ossl110)]
+ #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
fn is_ocb(self) -> bool {
self == Cipher::aes_128_ocb()
|| self == Cipher::aes_192_ocb()
|| self == Cipher::aes_256_ocb()
}
- #[cfg(not(ossl110))]
+ #[cfg(any(not(ossl110), osslconf = "OPENSSL_NO_OCB"))]
const fn is_ocb(self) -> bool {
false
}
@@ -1421,7 +1422,7 @@ mod tests {
}
#[test]
- #[cfg(ossl110)]
+ #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
fn test_aes_128_ocb() {
let key = "000102030405060708090a0b0c0d0e0f";
let aad = "0001020304050607";
@@ -1457,7 +1458,7 @@ mod tests {
}
#[test]
- #[cfg(ossl110)]
+ #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
fn test_aes_128_ocb_fail() {
let key = "000102030405060708090a0b0c0d0e0f";
let aad = "0001020304050607";
@@ -1477,7 +1478,7 @@ mod tests {
}
#[test]
- #[cfg(any(ossl110))]
+ #[cfg(ossl110)]
fn test_chacha20() {
let key = "0000000000000000000000000000000000000000000000000000000000000000";
let iv = "00000000000000000000000000000000";
@@ -1492,7 +1493,7 @@ mod tests {
}
#[test]
- #[cfg(any(ossl110))]
+ #[cfg(ossl110)]
fn test_chacha20_poly1305() {
let key = "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f";
let iv = "070000004041424344454647";
diff --git a/vendor/openssl/src/x509/extension.rs b/vendor/openssl/src/x509/extension.rs
index f04d22796..11e015153 100644
--- a/vendor/openssl/src/x509/extension.rs
+++ b/vendor/openssl/src/x509/extension.rs
@@ -67,6 +67,9 @@ impl BasicConstraints {
}
/// Return the `BasicConstraints` extension as an `X509Extension`.
+ // Temporarily silence the deprecation warning - this should be ported to
+ // `X509Extension::new_internal`.
+ #[allow(deprecated)]
pub fn build(&self) -> Result<X509Extension, ErrorStack> {
let mut value = String::new();
if self.critical {
@@ -183,6 +186,9 @@ impl KeyUsage {
}
/// Return the `KeyUsage` extension as an `X509Extension`.
+ // Temporarily silence the deprecation warning - this should be ported to
+ // `X509Extension::new_internal`.
+ #[allow(deprecated)]
pub fn build(&self) -> Result<X509Extension, ErrorStack> {
let mut value = String::new();
let mut first = true;
@@ -346,6 +352,9 @@ impl SubjectKeyIdentifier {
}
/// Return a `SubjectKeyIdentifier` extension as an `X509Extension`.
+ // Temporarily silence the deprecation warning - this should be ported to
+ // `X509Extension::new_internal`.
+ #[allow(deprecated)]
pub fn build(&self, ctx: &X509v3Context<'_>) -> Result<X509Extension, ErrorStack> {
let mut value = String::new();
let mut first = true;
@@ -398,6 +407,9 @@ impl AuthorityKeyIdentifier {
}
/// Return a `AuthorityKeyIdentifier` extension as an `X509Extension`.
+ // Temporarily silence the deprecation warning - this should be ported to
+ // `X509Extension::new_internal`.
+ #[allow(deprecated)]
pub fn build(&self, ctx: &X509v3Context<'_>) -> Result<X509Extension, ErrorStack> {
let mut value = String::new();
let mut first = true;
@@ -422,6 +434,7 @@ enum RustGeneralName {
Uri(String),
Ip(String),
Rid(String),
+ OtherName(Asn1Object, Vec<u8>),
}
/// An extension that allows additional identities to be bound to the subject
@@ -494,12 +507,21 @@ impl SubjectAlternativeName {
/// Sets the `otherName` flag.
///
- /// Not currently actually supported, always panics.
- #[deprecated = "other_name is deprecated and always panics. Please file a bug if you have a use case for this."]
+ /// Not currently actually supported, always panics. Please use other_name2
+ #[deprecated = "other_name is deprecated and always panics. Please use other_name2."]
pub fn other_name(&mut self, _other_name: &str) -> &mut SubjectAlternativeName {
- unimplemented!(
- "This has not yet been adapted for the new internals. File a bug if you need this."
- );
+ unimplemented!("This has not yet been adapted for the new internals. Use other_name2.");
+ }
+
+ /// Sets the `otherName` flag.
+ ///
+ /// `content` must be a valid der encoded ASN1_TYPE
+ ///
+ /// If you want to add just a ia5string use `other_name_ia5string`
+ pub fn other_name2(&mut self, oid: Asn1Object, content: &[u8]) -> &mut SubjectAlternativeName {
+ self.items
+ .push(RustGeneralName::OtherName(oid, content.into()));
+ self
}
/// Return a `SubjectAlternativeName` extension as an `X509Extension`.
@@ -514,6 +536,9 @@ impl SubjectAlternativeName {
GeneralName::new_ip(s.parse().map_err(|_| ErrorStack::get())?)?
}
RustGeneralName::Rid(s) => GeneralName::new_rid(Asn1Object::from_str(s)?)?,
+ RustGeneralName::OtherName(oid, content) => {
+ GeneralName::new_other_name(oid.clone(), content)?
+ }
};
stack.push(gn)?;
}
diff --git a/vendor/openssl/src/x509/mod.rs b/vendor/openssl/src/x509/mod.rs
index eab1ea675..4325b132e 100644
--- a/vendor/openssl/src/x509/mod.rs
+++ b/vendor/openssl/src/x509/mod.rs
@@ -24,8 +24,8 @@ use std::slice;
use std::str;
use crate::asn1::{
- Asn1BitStringRef, Asn1IntegerRef, Asn1Object, Asn1ObjectRef, Asn1StringRef, Asn1TimeRef,
- Asn1Type,
+ Asn1BitStringRef, Asn1Enumerated, Asn1IntegerRef, Asn1Object, Asn1ObjectRef,
+ Asn1OctetStringRef, Asn1StringRef, Asn1TimeRef, Asn1Type,
};
use crate::bio::MemBioSlice;
use crate::conf::ConfRef;
@@ -50,6 +50,16 @@ pub mod store;
#[cfg(test)]
mod tests;
+/// A type of X509 extension.
+///
+/// # Safety
+/// The value of NID and Output must match those in OpenSSL so that
+/// `Output::from_ptr_opt(*_get_ext_d2i(*, NID, ...))` is valid.
+pub unsafe trait ExtensionType {
+ const NID: Nid;
+ type Output: ForeignType;
+}
+
foreign_type_and_impl_send_sync! {
type CType = ffi::X509_STORE_CTX;
fn drop = ffi::X509_STORE_CTX_free;
@@ -391,7 +401,10 @@ impl X509Ref {
/// Returns the hash of the certificates subject
#[corresponds(X509_subject_name_hash)]
pub fn subject_name_hash(&self) -> u32 {
- unsafe { ffi::X509_subject_name_hash(self.as_ptr()) as u32 }
+ #[allow(clippy::unnecessary_cast)]
+ unsafe {
+ ffi::X509_subject_name_hash(self.as_ptr()) as u32
+ }
}
/// Returns this certificate's issuer name.
@@ -406,7 +419,10 @@ impl X509Ref {
/// Returns the hash of the certificates issuer
#[corresponds(X509_issuer_name_hash)]
pub fn issuer_name_hash(&self) -> u32 {
- unsafe { ffi::X509_issuer_name_hash(self.as_ptr()) as u32 }
+ #[allow(clippy::unnecessary_cast)]
+ unsafe {
+ ffi::X509_issuer_name_hash(self.as_ptr()) as u32
+ }
}
/// Returns this certificate's subject alternative name entries, if they exist.
@@ -467,6 +483,54 @@ impl X509Ref {
}
}
+ /// Retrieves the path length extension from a certificate, if it exists.
+ #[corresponds(X509_get_pathlen)]
+ #[cfg(ossl110)]
+ pub fn pathlen(&self) -> Option<u32> {
+ let v = unsafe { ffi::X509_get_pathlen(self.as_ptr()) };
+ u32::try_from(v).ok()
+ }
+
+ /// Returns this certificate's subject key id, if it exists.
+ #[corresponds(X509_get0_subject_key_id)]
+ #[cfg(ossl110)]
+ pub fn subject_key_id(&self) -> Option<&Asn1OctetStringRef> {
+ unsafe {
+ let data = ffi::X509_get0_subject_key_id(self.as_ptr());
+ Asn1OctetStringRef::from_const_ptr_opt(data)
+ }
+ }
+
+ /// Returns this certificate's authority key id, if it exists.
+ #[corresponds(X509_get0_authority_key_id)]
+ #[cfg(ossl110)]
+ pub fn authority_key_id(&self) -> Option<&Asn1OctetStringRef> {
+ unsafe {
+ let data = ffi::X509_get0_authority_key_id(self.as_ptr());
+ Asn1OctetStringRef::from_const_ptr_opt(data)
+ }
+ }
+
+ /// Returns this certificate's authority issuer name entries, if they exist.
+ #[corresponds(X509_get0_authority_issuer)]
+ #[cfg(ossl111d)]
+ pub fn authority_issuer(&self) -> Option<&StackRef<GeneralName>> {
+ unsafe {
+ let stack = ffi::X509_get0_authority_issuer(self.as_ptr());
+ StackRef::from_const_ptr_opt(stack)
+ }
+ }
+
+ /// Returns this certificate's authority serial number, if it exists.
+ #[corresponds(X509_get0_authority_serial)]
+ #[cfg(ossl111d)]
+ pub fn authority_serial(&self) -> Option<&Asn1IntegerRef> {
+ unsafe {
+ let r = ffi::X509_get0_authority_serial(self.as_ptr());
+ Asn1IntegerRef::from_const_ptr_opt(r)
+ }
+ }
+
#[corresponds(X509_get_pubkey)]
pub fn public_key(&self) -> Result<PKey<Public>, ErrorStack> {
unsafe {
@@ -562,6 +626,7 @@ impl X509Ref {
/// Note that `0` return value stands for version 1, `1` for version 2 and so on.
#[corresponds(X509_get_version)]
#[cfg(ossl110)]
+ #[allow(clippy::unnecessary_cast)]
pub fn version(&self) -> i32 {
unsafe { ffi::X509_get_version(self.as_ptr()) as i32 }
}
@@ -825,6 +890,13 @@ impl X509Extension {
/// mini-language that can read arbitrary files.
///
/// See the extension module for builder types which will construct certain common extensions.
+ ///
+ /// This function is deprecated, `X509Extension::new_from_der` or the
+ /// types in `x509::extension` should be used in its place.
+ #[deprecated(
+ note = "Use x509::extension types or new_from_der instead",
+ since = "0.10.51"
+ )]
pub fn new(
conf: Option<&ConfRef>,
context: Option<&X509v3Context<'_>>,
@@ -870,6 +942,13 @@ impl X509Extension {
/// mini-language that can read arbitrary files.
///
/// See the extension module for builder types which will construct certain common extensions.
+ ///
+ /// This function is deprecated, `X509Extension::new_from_der` or the
+ /// types in `x509::extension` should be used in its place.
+ #[deprecated(
+ note = "Use x509::extension types or new_from_der instead",
+ since = "0.10.51"
+ )]
pub fn new_nid(
conf: Option<&ConfRef>,
context: Option<&X509v3Context<'_>>,
@@ -904,6 +983,31 @@ impl X509Extension {
}
}
+ /// Constructs a new X509 extension value from its OID, whether it's
+ /// critical, and its DER contents.
+ ///
+ /// The extent structure of the DER value will vary based on the
+ /// extension type, and can generally be found in the RFC defining the
+ /// extension.
+ ///
+ /// For common extension types, there are Rust APIs provided in
+ /// `openssl::x509::extensions` which are more ergonomic.
+ pub fn new_from_der(
+ oid: &Asn1ObjectRef,
+ critical: bool,
+ der_contents: &Asn1OctetStringRef,
+ ) -> Result<X509Extension, ErrorStack> {
+ unsafe {
+ cvt_p(ffi::X509_EXTENSION_create_by_OBJ(
+ ptr::null_mut(),
+ oid.as_ptr(),
+ critical as _,
+ der_contents.as_ptr(),
+ ))
+ .map(X509Extension)
+ }
+ }
+
pub(crate) unsafe fn new_internal(
nid: Nid,
critical: bool,
@@ -919,6 +1023,10 @@ impl X509Extension {
///
/// This method modifies global state without locking and therefore is not thread safe
#[corresponds(X509V3_EXT_add_alias)]
+ #[deprecated(
+ note = "Use x509::extension types or new_from_der and then this is not necessary",
+ since = "0.10.51"
+ )]
pub unsafe fn add_alias(to: Nid, from: Nid) -> Result<(), ErrorStack> {
ffi::init();
cvt(ffi::X509V3_EXT_add_alias(to.as_raw(), from.as_raw())).map(|_| ())
@@ -969,13 +1077,13 @@ impl X509NameBuilder {
pub fn append_entry_by_text(&mut self, field: &str, value: &str) -> Result<(), ErrorStack> {
unsafe {
let field = CString::new(field).unwrap();
- assert!(value.len() <= c_int::max_value() as usize);
+ assert!(value.len() <= crate::SLenType::max_value() as usize);
cvt(ffi::X509_NAME_add_entry_by_txt(
self.0.as_ptr(),
field.as_ptr() as *mut _,
ffi::MBSTRING_UTF8,
value.as_ptr(),
- value.len() as c_int,
+ value.len() as crate::SLenType,
-1,
0,
))
@@ -996,13 +1104,13 @@ impl X509NameBuilder {
) -> Result<(), ErrorStack> {
unsafe {
let field = CString::new(field).unwrap();
- assert!(value.len() <= c_int::max_value() as usize);
+ assert!(value.len() <= crate::SLenType::max_value() as usize);
cvt(ffi::X509_NAME_add_entry_by_txt(
self.0.as_ptr(),
field.as_ptr() as *mut _,
ty.as_raw(),
value.as_ptr(),
- value.len() as c_int,
+ value.len() as crate::SLenType,
-1,
0,
))
@@ -1017,13 +1125,13 @@ impl X509NameBuilder {
/// [`X509_NAME_add_entry_by_NID`]: https://www.openssl.org/docs/manmaster/crypto/X509_NAME_add_entry_by_NID.html
pub fn append_entry_by_nid(&mut self, field: Nid, value: &str) -> Result<(), ErrorStack> {
unsafe {
- assert!(value.len() <= c_int::max_value() as usize);
+ assert!(value.len() <= crate::SLenType::max_value() as usize);
cvt(ffi::X509_NAME_add_entry_by_NID(
self.0.as_ptr(),
field.as_raw(),
ffi::MBSTRING_UTF8,
value.as_ptr() as *mut _,
- value.len() as c_int,
+ value.len() as crate::SLenType,
-1,
0,
))
@@ -1043,13 +1151,13 @@ impl X509NameBuilder {
ty: Asn1Type,
) -> Result<(), ErrorStack> {
unsafe {
- assert!(value.len() <= c_int::max_value() as usize);
+ assert!(value.len() <= crate::SLenType::max_value() as usize);
cvt(ffi::X509_NAME_add_entry_by_NID(
self.0.as_ptr(),
field.as_raw(),
ty.as_raw(),
value.as_ptr() as *mut _,
- value.len() as c_int,
+ value.len() as crate::SLenType,
-1,
0,
))
@@ -1442,6 +1550,7 @@ impl X509ReqRef {
/// This corresponds to [`X509_REQ_get_version`]
///
/// [`X509_REQ_get_version`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_get_version.html
+ #[allow(clippy::unnecessary_cast)]
pub fn version(&self) -> i32 {
unsafe { X509_REQ_get_version(self.as_ptr()) as i32 }
}
@@ -1495,13 +1604,41 @@ impl X509ReqRef {
}
}
+/// The reason that a certificate was revoked.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct CrlReason(c_int);
+
+#[allow(missing_docs)] // no need to document the constants
+impl CrlReason {
+ pub const UNSPECIFIED: CrlReason = CrlReason(ffi::CRL_REASON_UNSPECIFIED);
+ pub const KEY_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_KEY_COMPROMISE);
+ pub const CA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_CA_COMPROMISE);
+ pub const AFFILIATION_CHANGED: CrlReason = CrlReason(ffi::CRL_REASON_AFFILIATION_CHANGED);
+ pub const SUPERSEDED: CrlReason = CrlReason(ffi::CRL_REASON_SUPERSEDED);
+ pub const CESSATION_OF_OPERATION: CrlReason = CrlReason(ffi::CRL_REASON_CESSATION_OF_OPERATION);
+ pub const CERTIFICATE_HOLD: CrlReason = CrlReason(ffi::CRL_REASON_CERTIFICATE_HOLD);
+ pub const REMOVE_FROM_CRL: CrlReason = CrlReason(ffi::CRL_REASON_REMOVE_FROM_CRL);
+ pub const PRIVILEGE_WITHDRAWN: CrlReason = CrlReason(ffi::CRL_REASON_PRIVILEGE_WITHDRAWN);
+ pub const AA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_AA_COMPROMISE);
+
+ /// Constructs an `CrlReason` from a raw OpenSSL value.
+ pub const fn from_raw(value: c_int) -> Self {
+ CrlReason(value)
+ }
+
+ /// Returns the raw OpenSSL value represented by this type.
+ pub const fn as_raw(&self) -> c_int {
+ self.0
+ }
+}
+
foreign_type_and_impl_send_sync! {
type CType = ffi::X509_REVOKED;
fn drop = ffi::X509_REVOKED_free;
- /// An `X509` certificate request.
+ /// An `X509` certificate revocation status.
pub struct X509Revoked;
- /// Reference to `X509Crl`.
+ /// Reference to `X509Revoked`.
pub struct X509RevokedRef;
}
@@ -1527,6 +1664,13 @@ impl X509RevokedRef {
ffi::i2d_X509_REVOKED
}
+ /// Copies the entry to a new `X509Revoked`.
+ #[corresponds(X509_NAME_dup)]
+ #[cfg(any(boringssl, ossl110, libressl270))]
+ pub fn to_owned(&self) -> Result<X509Revoked, ErrorStack> {
+ unsafe { cvt_p(ffi::X509_REVOKED_dup(self.as_ptr())).map(|n| X509Revoked::from_ptr(n)) }
+ }
+
/// Get the date that the certificate was revoked
#[corresponds(X509_REVOKED_get0_revocationDate)]
pub fn revocation_date(&self) -> &Asn1TimeRef {
@@ -1546,13 +1690,67 @@ impl X509RevokedRef {
Asn1IntegerRef::from_ptr(r as *mut _)
}
}
+
+ /// Get the criticality and value of an extension.
+ ///
+ /// This returns None if the extension is not present or occurs multiple times.
+ #[corresponds(X509_REVOKED_get_ext_d2i)]
+ pub fn extension<T: ExtensionType>(&self) -> Result<Option<(bool, T::Output)>, ErrorStack> {
+ let mut critical = -1;
+ let out = unsafe {
+ // SAFETY: self.as_ptr() is a valid pointer to an X509_REVOKED.
+ let ext = ffi::X509_REVOKED_get_ext_d2i(
+ self.as_ptr(),
+ T::NID.as_raw(),
+ &mut critical as *mut _,
+ ptr::null_mut(),
+ );
+ // SAFETY: Extensions's contract promises that the type returned by
+ // OpenSSL here is T::Output.
+ T::Output::from_ptr_opt(ext as *mut _)
+ };
+ match (critical, out) {
+ (0, Some(out)) => Ok(Some((false, out))),
+ (1, Some(out)) => Ok(Some((true, out))),
+ // -1 means the extension wasn't found, -2 means multiple were found.
+ (-1 | -2, _) => Ok(None),
+ // A critical value of 0 or 1 suggests success, but a null pointer
+ // was returned so something went wrong.
+ (0 | 1, None) => Err(ErrorStack::get()),
+ (c_int::MIN..=-2 | 2.., _) => panic!("OpenSSL should only return -2, -1, 0, or 1 for an extension's criticality but it returned {}", critical),
+ }
+ }
+}
+
+/// The CRL entry extension identifying the reason for revocation see [`CrlReason`],
+/// this is as defined in RFC 5280 Section 5.3.1.
+pub enum ReasonCode {}
+
+// SAFETY: CertificateIssuer is defined to be a stack of GeneralName in the RFC
+// and in OpenSSL.
+unsafe impl ExtensionType for ReasonCode {
+ const NID: Nid = Nid::from_raw(ffi::NID_crl_reason);
+
+ type Output = Asn1Enumerated;
+}
+
+/// The CRL entry extension identifying the issuer of a certificate used in
+/// indirect CRLs, as defined in RFC 5280 Section 5.3.3.
+pub enum CertificateIssuer {}
+
+// SAFETY: CertificateIssuer is defined to be a stack of GeneralName in the RFC
+// and in OpenSSL.
+unsafe impl ExtensionType for CertificateIssuer {
+ const NID: Nid = Nid::from_raw(ffi::NID_certificate_issuer);
+
+ type Output = Stack<GeneralName>;
}
foreign_type_and_impl_send_sync! {
type CType = ffi::X509_CRL;
fn drop = ffi::X509_CRL_free;
- /// An `X509` certificate request.
+ /// An `X509` certificate revocation list.
pub struct X509Crl;
/// Reference to `X509Crl`.
pub struct X509CrlRef;
@@ -1856,6 +2054,37 @@ impl GeneralName {
Ok(GeneralName::from_ptr(gn))
}
}
+
+ pub(crate) fn new_other_name(
+ oid: Asn1Object,
+ value: &Vec<u8>,
+ ) -> Result<GeneralName, ErrorStack> {
+ unsafe {
+ ffi::init();
+
+ let typ = cvt_p(ffi::d2i_ASN1_TYPE(
+ ptr::null_mut(),
+ &mut value.as_ptr().cast(),
+ value.len().try_into().unwrap(),
+ ))?;
+
+ let gn = cvt_p(ffi::GENERAL_NAME_new())?;
+ (*gn).type_ = ffi::GEN_OTHERNAME;
+
+ if let Err(e) = cvt(ffi::GENERAL_NAME_set0_othername(
+ gn,
+ oid.as_ptr().cast(),
+ typ,
+ )) {
+ ffi::GENERAL_NAME_free(gn);
+ return Err(e);
+ }
+
+ mem::forget(oid);
+
+ Ok(GeneralName::from_ptr(gn))
+ }
+ }
}
impl GeneralNameRef {
@@ -1886,6 +2115,22 @@ impl GeneralNameRef {
self.ia5_string(ffi::GEN_EMAIL)
}
+ /// Returns the contents of this `GeneralName` if it is a `directoryName`.
+ pub fn directory_name(&self) -> Option<&X509NameRef> {
+ unsafe {
+ if (*self.as_ptr()).type_ != ffi::GEN_DIRNAME {
+ return None;
+ }
+
+ #[cfg(boringssl)]
+ let d = (*self.as_ptr()).d.ptr;
+ #[cfg(not(boringssl))]
+ let d = (*self.as_ptr()).d;
+
+ Some(X509NameRef::from_const_ptr(d as *const _))
+ }
+ }
+
/// Returns the contents of this `GeneralName` if it is a `dNSName`.
pub fn dnsname(&self) -> Option<&str> {
self.ia5_string(ffi::GEN_DNS)
diff --git a/vendor/openssl/src/x509/tests.rs b/vendor/openssl/src/x509/tests.rs
index 365960441..da3ce2fed 100644
--- a/vendor/openssl/src/x509/tests.rs
+++ b/vendor/openssl/src/x509/tests.rs
@@ -1,6 +1,6 @@
use std::cmp::Ordering;
-use crate::asn1::Asn1Time;
+use crate::asn1::{Asn1Object, Asn1OctetString, Asn1Time};
use crate::bn::{BigNum, MsbOption};
use crate::hash::MessageDigest;
use crate::nid::Nid;
@@ -18,19 +18,24 @@ use crate::x509::store::X509Lookup;
use crate::x509::store::X509StoreBuilder;
#[cfg(any(ossl102, libressl261))]
use crate::x509::verify::{X509VerifyFlags, X509VerifyParam};
-#[cfg(ossl110)]
-use crate::x509::X509Builder;
#[cfg(ossl102)]
use crate::x509::X509PurposeId;
#[cfg(any(ossl102, libressl261))]
use crate::x509::X509PurposeRef;
+#[cfg(ossl110)]
+use crate::x509::{CrlReason, X509Builder};
use crate::x509::{
CrlStatus, X509Crl, X509Extension, X509Name, X509Req, X509StoreContext, X509VerifyResult, X509,
};
+
+#[cfg(ossl110)]
+use foreign_types::ForeignType;
use hex::{self, FromHex};
#[cfg(any(ossl102, libressl261))]
use libc::time_t;
+use super::{CertificateIssuer, ReasonCode};
+
fn pkey() -> PKey<Private> {
let rsa = Rsa::generate(2048).unwrap();
PKey::from_rsa(rsa).unwrap()
@@ -167,6 +172,70 @@ fn test_subject_alt_name() {
}
#[test]
+#[cfg(ossl110)]
+fn test_retrieve_pathlen() {
+ let cert = include_bytes!("../../test/root-ca.pem");
+ let cert = X509::from_pem(cert).unwrap();
+ assert_eq!(cert.pathlen(), None);
+
+ let cert = include_bytes!("../../test/intermediate-ca.pem");
+ let cert = X509::from_pem(cert).unwrap();
+ assert_eq!(cert.pathlen(), Some(0));
+
+ let cert = include_bytes!("../../test/alt_name_cert.pem");
+ let cert = X509::from_pem(cert).unwrap();
+ assert_eq!(cert.pathlen(), None);
+}
+
+#[test]
+#[cfg(ossl110)]
+fn test_subject_key_id() {
+ let cert = include_bytes!("../../test/certv3.pem");
+ let cert = X509::from_pem(cert).unwrap();
+
+ let subject_key_id = cert.subject_key_id().unwrap();
+ assert_eq!(
+ subject_key_id.as_slice(),
+ &b"\xB6\x73\x2F\x61\xA5\x4B\xA1\xEF\x48\x2C\x15\xB1\x9F\xF3\xDC\x34\x2F\xBC\xAC\x30"[..]
+ );
+}
+
+#[test]
+#[cfg(ossl110)]
+fn test_authority_key_id() {
+ let cert = include_bytes!("../../test/certv3.pem");
+ let cert = X509::from_pem(cert).unwrap();
+
+ let authority_key_id = cert.authority_key_id().unwrap();
+ assert_eq!(
+ authority_key_id.as_slice(),
+ &b"\x6C\xD3\xA5\x03\xAB\x0D\x5F\x2C\xC9\x8D\x8A\x9C\x88\xA7\x88\x77\xB8\x37\xFD\x9A"[..]
+ );
+}
+
+#[test]
+#[cfg(ossl111d)]
+fn test_authority_issuer_and_serial() {
+ let cert = include_bytes!("../../test/authority_key_identifier.pem");
+ let cert = X509::from_pem(cert).unwrap();
+
+ let authority_issuer = cert.authority_issuer().unwrap();
+ assert_eq!(1, authority_issuer.len());
+ let dn = authority_issuer[0].directory_name().unwrap();
+ let mut o = dn.entries_by_nid(Nid::ORGANIZATIONNAME);
+ let o = o.next().unwrap().data().as_utf8().unwrap();
+ assert_eq!(o.as_bytes(), b"PyCA");
+ let mut cn = dn.entries_by_nid(Nid::COMMONNAME);
+ let cn = cn.next().unwrap().data().as_utf8().unwrap();
+ assert_eq!(cn.as_bytes(), b"cryptography.io");
+
+ let authority_serial = cert.authority_serial().unwrap();
+ let serial = authority_serial.to_bn().unwrap();
+ let expected = BigNum::from_u32(3).unwrap();
+ assert_eq!(serial, expected);
+}
+
+#[test]
fn test_subject_alt_name_iter() {
let cert = include_bytes!("../../test/alt_name_cert.pem");
let cert = X509::from_pem(cert).unwrap();
@@ -288,6 +357,8 @@ fn x509_builder() {
}
#[test]
+// This tests `X509Extension::new`, even though its deprecated.
+#[allow(deprecated)]
fn x509_extension_new() {
assert!(X509Extension::new(None, None, "crlDistributionPoints", "section").is_err());
assert!(X509Extension::new(None, None, "proxyCertInfo", "").is_err());
@@ -296,6 +367,20 @@ fn x509_extension_new() {
}
#[test]
+fn x509_extension_new_from_der() {
+ let ext = X509Extension::new_from_der(
+ &Asn1Object::from_str("2.5.29.19").unwrap(),
+ true,
+ &Asn1OctetString::new_from_bytes(b"\x30\x03\x01\x01\xff").unwrap(),
+ )
+ .unwrap();
+ assert_eq!(
+ ext.to_der().unwrap(),
+ b"0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff"
+ );
+}
+
+#[test]
fn x509_extension_to_der() {
let builder = X509::builder().unwrap();
@@ -612,6 +697,42 @@ fn test_load_crl() {
}
#[test]
+fn test_crl_entry_extensions() {
+ let crl = include_bytes!("../../test/entry_extensions.crl");
+ let crl = X509Crl::from_pem(crl).unwrap();
+
+ let revoked_certs = crl.get_revoked().unwrap();
+ let entry = &revoked_certs[0];
+
+ let (critical, issuer) = entry
+ .extension::<CertificateIssuer>()
+ .unwrap()
+ .expect("Certificate issuer extension should be present");
+ assert!(critical, "Certificate issuer extension is critical");
+ assert_eq!(issuer.len(), 1, "Certificate issuer should have one entry");
+ let issuer = issuer[0]
+ .directory_name()
+ .expect("Issuer should be a directory name");
+ assert_eq!(
+ format!("{:?}", issuer),
+ r#"[countryName = "GB", commonName = "Test CA"]"#
+ );
+
+ // reason_code can't be inspected without ossl110
+ #[allow(unused_variables)]
+ let (critical, reason_code) = entry
+ .extension::<ReasonCode>()
+ .unwrap()
+ .expect("Reason code extension should be present");
+ assert!(!critical, "Reason code extension is not critical");
+ #[cfg(ossl110)]
+ assert_eq!(
+ CrlReason::KEY_COMPROMISE,
+ CrlReason::from_raw(reason_code.get_i64().unwrap() as ffi::c_int)
+ );
+}
+
+#[test]
fn test_save_subject_der() {
let cert = include_bytes!("../../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
@@ -987,6 +1108,31 @@ fn ipv6_as_subject_alternative_name_is_formatted_in_debug() {
]);
}
+#[cfg(ossl110)]
+#[test]
+fn other_name_as_subject_alternative_name() {
+ let oid = Asn1Object::from_str("1.3.6.1.5.5.7.8.11").unwrap();
+ // this is the hex representation of "test" encoded as a ia5string
+ let content = [0x16, 0x04, 0x74, 0x65, 0x73, 0x74];
+
+ let mut builder = X509Builder::new().unwrap();
+ let san = SubjectAlternativeName::new()
+ .other_name2(oid, &content)
+ .build(&builder.x509v3_context(None, None))
+ .unwrap();
+ builder.append_extension(san).unwrap();
+ let cert = builder.build();
+ let general_name = cert
+ .subject_alt_names()
+ .into_iter()
+ .flatten()
+ .next()
+ .unwrap();
+ unsafe {
+ assert_eq!((*general_name.as_ptr()).type_, 0);
+ }
+}
+
#[test]
fn test_dist_point() {
let cert = include_bytes!("../../test/certv3.pem");
diff --git a/vendor/openssl/src/x509/verify.rs b/vendor/openssl/src/x509/verify.rs
index b0e22ef46..e8481c551 100644
--- a/vendor/openssl/src/x509/verify.rs
+++ b/vendor/openssl/src/x509/verify.rs
@@ -120,9 +120,11 @@ impl X509VerifyParamRef {
#[corresponds(X509_VERIFY_PARAM_set1_host)]
pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> {
unsafe {
+ // len == 0 means "run strlen" :(
+ let raw_host = if host.is_empty() { "\0" } else { host };
cvt(ffi::X509_VERIFY_PARAM_set1_host(
self.as_ptr(),
- host.as_ptr() as *const _,
+ raw_host.as_ptr() as *const _,
host.len(),
))
.map(|_| ())