Skip to content

Commit

Permalink
Introduce X509Flags
Browse files Browse the repository at this point in the history
For now it has a single associated constant, X509Flags::TRUSTED_FIRST.
  • Loading branch information
nox committed Jan 3, 2024
1 parent bc55210 commit 3539b16
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 3 deletions.
7 changes: 6 additions & 1 deletion boring/src/ssl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3176,7 +3176,7 @@ impl SslRef {
/// This corresponds to [`SSL_get0_param`].
///
/// [`SSL_get0_param`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_get0_param.html
pub fn param_mut(&mut self) -> &mut X509VerifyParamRef {
pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef {
#[cfg(feature = "rpk")]
assert!(
!self.ssl_context().is_rpk(),
Expand All @@ -3186,6 +3186,11 @@ impl SslRef {
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) }
}

/// See [`Self::verify_param_mut`].
pub fn param_mut(&mut self) -> &mut X509VerifyParamRef {
self.verify_param_mut()
}

/// Returns the certificate verification result.
///
/// This corresponds to [`SSL_get_verify_result`].
Expand Down
12 changes: 11 additions & 1 deletion boring/src/x509/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//! Internet protocols, including SSL/TLS, which is the basis for HTTPS,
//! the secure protocol for browsing the web.
use crate::ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_int, c_long, c_void};
use std::convert::TryInto;
Expand All @@ -30,12 +29,14 @@ use crate::bio::MemBioSlice;
use crate::conf::ConfRef;
use crate::error::ErrorStack;
use crate::ex_data::Index;
use crate::ffi;
use crate::hash::{DigestBytes, MessageDigest};
use crate::nid::Nid;
use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public};
use crate::ssl::SslRef;
use crate::stack::{Stack, StackRef, Stackable};
use crate::string::OpensslString;
use crate::x509::verify::X509VerifyParamRef;
use crate::{cvt, cvt_n, cvt_p};

pub mod extension;
Expand Down Expand Up @@ -147,6 +148,15 @@ impl X509StoreContextRef {
}
}

/// Returns a mutable reference to the X509 verification configuration.
///
/// This corresponds to [`X509_STORE_CTX_get0_param`].
///
/// [`SSL_get0_param`]: https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get0_param.html
pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef {
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::X509_STORE_CTX_get0_param(self.as_ptr())) }
}

/// Verifies the stored certificate.
///
/// Returns `true` if verification succeeds. The `error` method will return the specific
Expand Down
21 changes: 21 additions & 0 deletions boring/src/x509/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
use crate::error::ErrorStack;
use crate::ffi;
use crate::stack::StackRef;
use crate::x509::verify::{X509Flags, X509VerifyParamRef};
use crate::x509::{X509Object, X509};
use crate::{cvt, cvt_p};
use foreign_types::{ForeignType, ForeignTypeRef};
Expand Down Expand Up @@ -91,6 +92,26 @@ impl X509StoreBuilderRef {
pub fn set_default_paths(&mut self) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())).map(|_| ()) }
}

/// Sets verify flags.
///
/// This corresponds to [`X509_STORE_set_flags`].
///
/// [`X509_STORE_set_flags`]: https://www.openssl.org/docs/manmaster/man3/X509_STORE_set_flags.html
pub fn set_flags(&mut self, flags: X509Flags) {
unsafe {
ffi::X509_STORE_set_flags(self.as_ptr(), flags.bits());
}
}

/// Returns a mutable reference to the X509 verification configuration.
///
/// This corresponds to [`X509_STORE_get0_param`].
///
/// [`SSL_get0_param`]: https://www.openssl.org/docs/manmaster/man3/X509_STORE_get0_param.html
pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef {
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::X509_STORE_get0_param(self.as_ptr())) }
}
}

foreign_type_and_impl_send_sync! {
Expand Down
2 changes: 2 additions & 0 deletions boring/src/x509/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use crate::x509::extension::{
use crate::x509::store::X509StoreBuilder;
use crate::x509::{X509Extension, X509Name, X509Req, X509StoreContext, X509};

mod trusted_first;

fn pkey() -> PKey<Private> {
let rsa = Rsa::generate(2048).unwrap();
PKey::from_rsa(rsa).unwrap()
Expand Down
104 changes: 104 additions & 0 deletions boring/src/x509/tests/trusted_first.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//! See https://github.com/google/boringssl/blob/cc696073cffe7978d489297fbdeac4c0030384aa/crypto/x509/x509_test.cc#L3977-L3980
use crate::stack::Stack;
use crate::x509::store::X509StoreBuilder;
use crate::x509::verify::{X509Flags, X509VerifyParamRef};
use crate::x509::{X509Ref, X509StoreContext, X509VerifyError, X509VerifyResult, X509};

#[test]
fn test_verify_cert() {
let root2 = X509::from_pem(include_bytes!("../../../test/root-ca-2.pem")).unwrap();
let root1 = X509::from_pem(include_bytes!("../../../test/root-ca.pem")).unwrap();
let root1_cross = X509::from_pem(include_bytes!("../../../test/root-ca-cross.pem")).unwrap();
let intermediate = X509::from_pem(include_bytes!("../../../test/intermediate-ca.pem")).unwrap();
let leaf = X509::from_pem(include_bytes!("../../../test/cert.pem")).unwrap();

assert_eq!(Ok(()), verify(&leaf, &[&root1], &[&intermediate], |_| {}));

#[cfg(not(feature = "fips"))]
assert_eq!(
Ok(()),
verify(
&leaf,
&[&root1, &root2],
&[&intermediate, &root1_cross],
|_| {}
)
);

#[cfg(feature = "fips")]
assert_eq!(
Err(X509VerifyError::CERT_HAS_EXPIRED),
verify(
&leaf,
&[&root1, &root2],
&[&intermediate, &root1_cross],
|_| {}
)
);

assert_eq!(
Ok(()),
verify(
&leaf,
&[&root1, &root2],
&[&intermediate, &root1_cross],
|param| param.set_flags(X509Flags::TRUSTED_FIRST),
)
);

assert_eq!(
Err(X509VerifyError::CERT_HAS_EXPIRED),
verify(
&leaf,
&[&root1, &root2],
&[&intermediate, &root1_cross],
|param| param.clear_flags(X509Flags::TRUSTED_FIRST),
)
);

assert_eq!(
Ok(()),
verify(&leaf, &[&root1], &[&intermediate, &root1_cross], |param| {
param.clear_flags(X509Flags::TRUSTED_FIRST)
},)
);
}

fn verify(
cert: &X509Ref,
trusted: &[&X509Ref],
untrusted: &[&X509Ref],
configure: impl FnOnce(&mut X509VerifyParamRef),
) -> X509VerifyResult {
let trusted = {
let mut builder = X509StoreBuilder::new().unwrap();

for cert in trusted {
builder.add_cert((**cert).to_owned()).unwrap();
}

builder.build()
};

let untrusted = {
let mut stack = Stack::new().unwrap();

for cert in untrusted {
stack.push((**cert).to_owned()).unwrap();
}

stack
};

let mut store_ctx = X509StoreContext::new().unwrap();

let _ = store_ctx.init(&trusted, cert, &untrusted, |ctx| {
configure(ctx.verify_param_mut());
ctx.verify_cert().unwrap();

Ok(())
});

store_ctx.verify_result()
}
35 changes: 34 additions & 1 deletion boring/src/x509/verify.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::ffi;
use foreign_types::ForeignTypeRef;
use libc::c_uint;
use libc::{c_uint, c_ulong};
use std::net::IpAddr;

use crate::cvt;
Expand All @@ -22,6 +22,14 @@ bitflags! {
}
}

bitflags! {
/// Flags used to check an `X509` certificate.
#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
pub struct X509Flags: c_ulong {
const TRUSTED_FIRST = ffi::X509_V_FLAG_TRUSTED_FIRST as _;
}
}

foreign_type_and_impl_send_sync! {
type CType = ffi::X509_VERIFY_PARAM;
fn drop = ffi::X509_VERIFY_PARAM_free;
Expand All @@ -31,6 +39,31 @@ foreign_type_and_impl_send_sync! {
}

impl X509VerifyParamRef {
/// Set flags.
///
/// This corresponds to [`X509_VERIFY_PARAM_set_flags`].
///
/// [`X509_VERIFY_PARAM_set_flags`]: https://www.openssl.org/docs/man3.2/man3/X509_VERIFY_PARAM_set_flags.html
pub fn set_flags(&mut self, flags: X509Flags) {
unsafe {
ffi::X509_VERIFY_PARAM_set_flags(self.as_ptr(), flags.bits());
}
}

/// Clear flags.
///
/// Useful to clear out default flags, such as `X509Flags::TRUSTED_FIRST` when the fips feature is off.
///
/// This corresponds to [`X509_VERIFY_PARAM_clear_flags`].
///
/// [`X509_VERIFY_PARAM_set_flags`]: https://www.openssl.org/docs/man3.2/man3/X509_VERIFY_PARAM_set_flags.html
pub fn clear_flags(&mut self, flags: X509Flags) {
unsafe {
ffi::X509_VERIFY_PARAM_clear_flags(self.as_ptr(), flags.bits());
}
}

///
/// Set the host flags.
///
/// This corresponds to [`X509_VERIFY_PARAM_set_hostflags`].
Expand Down
27 changes: 27 additions & 0 deletions boring/test/root-ca-2.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAwSgPW00nGOTje0FHm1HXT3ANHjW3HGPbxiMSRvSoBEdv8R9e
0PoKjse0xQsa5nKolbUhJBS6dkH+13VPOs6e+vZyXD6OYQfi2e42Mw0SPFl5g2qU
fy/17q3ipqPJnT6YHhGpx/P91F7yjDAF2MvNRGQ/6AYWD4MUr6+5vPHEYhQ/JlAK
cN/uWUM+bg2mwMNpmuGRV1tg0hKl9nT1fX1i6OSszPLIY1dC0eHv2gRh1unrXNoY
A76xohiwcJYAAPjrx167S8td8gmWnOwYnCnGIw2ceNpEQv4/bEvtKiLGOu4HUO/x
a7emy1QZgJth5TqQf0pwPEJC0mV5LFoXtlOpjwIDAQABAoIBAB3xBshhYlEikfy2
NtJl0ll3BiGLtBHLjPLe1uN242CebkTTVxBP4jkVzfjJaucUGPvz8uoz6F+ShV2C
ysBT7SL79uhDrjBuV4TuvyoUuaHvQL3VVKWOmrHf9IVeWE9ut4fZtxbOxKcZ/MEs
ZIuhs/UJETr3To4jBJ7jP4iBda66LXeGDwnhia04zpFWwRRyRFvdVwTvMm9TN2GY
21J6rnc44bGQ/l0qsxSrv/OuW3ZmFNz85mRbuLswgawJgjMSlt1orLz5mdofDxlz
898nSrpJq/mAj8kgV+sH2jGv5FVZrv30W/0GlXObiJLhJiywYkpXbSn/H//w9+ij
ItQXjDECgYEA9RNootH8F0vuWVezKrt9ApE+8AzwltDgMlFc/HEjINnKFg7SWsSN
oinPVcQ07PS+2E7Fgv/6IFv/RTATGIPYrNWGE17dR8xmwh+Xrexz45c49cHTwVCF
VM2J0PvlcEEAscMe1bd5HqIOJm+hvvqfwWdacUPZgtsaS9F/e33vj0cCgYEAycQx
c5EQ9T82z+qMhQ/mf63kYMYDsHbv6F92Pt38V24yh8NTW5lEcV+NonDFrPVH5Vd3
gU1lvXnG8e3Aj6EXOeEzfu9dpfdyqyZXIU2hbRPYuha+goBd03pM8+YEIgJX3ktu
1Q+G6uMrSLVbe+l06OEcYmvj8xGNWrk/3+ZiB3kCgYEA15+c92xjLSgcbDTyKU3O
Pj0Gr/Pilf7u0ratZlowew3DdMbToxK+PogkqKQ5oKXxZ6Vet9R6AJCQtxIGKxKN
x/sRvOdBL5OScYeUT2zzxbFeZzODGNm8hZFViS6nfq1ibARtk8Gaai5Q3tZm6/3c
IzDI7VCyBiS6LS0EyeVSqa8CgYBRmM6G9jvtcssv+qMpjOyi5iheGraTPwZ262Re
uFe85Av7a7riaHGNiB83enP3JpsU3PKvkCV9IyqZ3JTrgTJrbe/tfdBZtmDhZngG
N+b4vfYADAKvtEo9pFBKstMpDdmLROZltAnUJFr05KNC0X8+Twuzof5l5stLzW9P
lVQ/wQKBgQDT4ixRRx4DlMMzBXNRTkUuZloEhZtLC5xj71KhE7OeOdJ0e6DHJMg3
VDVQk+y3Qc+8Hh9yxMK/zrYLdHSVyvHTk+7AbppLGX7ZtyLm/gVq3l3VjWKmXKbm
ZT+3+2gqVyjr/p69T7/aLexvfzU5LdjwO7SQFNB4qZaG74WpGAlkMg==
-----END RSA PRIVATE KEY-----
20 changes: 20 additions & 0 deletions boring/test/root-ca-2.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDSzCCAjOgAwIBAgIUOQyKTQXHMKXZgwc5iktVZkL7hfwwDQYJKoZIhvcNAQEL
BQAwRzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxIzAhBgNVBAoM
GkludGVybmV0IFdpZGdpdHMgUHR5IEx0ZCAyMB4XDTIzMTIwNDEwMzA0N1oXDTIz
MTIxNDEwMzA0N1owRzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
IzAhBgNVBAoMGkludGVybmV0IFdpZGdpdHMgUHR5IEx0ZCAyMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSgPW00nGOTje0FHm1HXT3ANHjW3HGPbxiMS
RvSoBEdv8R9e0PoKjse0xQsa5nKolbUhJBS6dkH+13VPOs6e+vZyXD6OYQfi2e42
Mw0SPFl5g2qUfy/17q3ipqPJnT6YHhGpx/P91F7yjDAF2MvNRGQ/6AYWD4MUr6+5
vPHEYhQ/JlAKcN/uWUM+bg2mwMNpmuGRV1tg0hKl9nT1fX1i6OSszPLIY1dC0eHv
2gRh1unrXNoYA76xohiwcJYAAPjrx167S8td8gmWnOwYnCnGIw2ceNpEQv4/bEvt
KiLGOu4HUO/xa7emy1QZgJth5TqQf0pwPEJC0mV5LFoXtlOpjwIDAQABoy8wLTAd
BgNVHQ4EFgQU1rQttC2Y2T0HZAjzRkacyFLVBr8wDAYDVR0TBAUwAwEB/zANBgkq
hkiG9w0BAQsFAAOCAQEAsVucQLIzAKHwN/4ZuVOPpfy/B3+i/Stu2tvNhBxWpbh9
RQTa0ylpDfaAOLr+TfxCyT0/NmblK4QWxN6AJ5AZS9fVnstLhInafv7So0n3LCg5
eQkVcQtMdwHucfMw/iz7r229mOHBbK6cnZhu72rcnn7N/RlU+iEucfi6jO+r9iD1
y20glRta+wEqIBg7nGhulOwwdHVkX7ulpnXIqNCgNvU7/Mp7J+CxuWmeZKLvUQAh
D/gHs9kOPK4izN9QBrRwbiyTaD8G7kFlVWD1tPXrOhBdE1L4OJWvUDSfO0DKueIW
aQa2fFsR1iPuFX/jeTuPk5X2+u5eH4pXj13NEqKvOA==
-----END CERTIFICATE-----
21 changes: 21 additions & 0 deletions boring/test/root-ca-cross.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDajCCAlKgAwIBAgIUSYINSQdbr8yzV186s/zQj+2zol8wDQYJKoZIhvcNAQEL
BQAwRzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxIzAhBgNVBAoM
GkludGVybmV0IFdpZGdpdHMgUHR5IEx0ZCAyMB4XDTI0MDEwMzEwMzUyM1oXDTI2
MDgxMjEwMzUyM1owRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAK1R1hZ+di25dZefXsXbmZ7VUmcg2KcwzQ/kti1H
Dun0QVoVf9Ss6MfthmabW7jBpnyN4gJ29AhU+Lgt5AZEEJV6JxgE0lcmhUxUfo6v
5XNEj/vQXe0gV4niFXiF5WNU75cCL49zbcPc1/rHEwOEl8R+jNKyr/YEzrm9rwjE
h3hdel/A0K+F7GbkK+wqe49SOGqjicmqeSU5eYo5hvHJ7tJ/vFHEZQc8vfXS1iRt
AHyN1USXVqRkzVWfdmhX390aStxf1iNoKd6ldcp0QCrr5p3Bgtyw72H3HNnYLHNT
ehX6vBiK5IEaG+ngXJJQx6dXdNty8K3vlWlQ0qNf/2O9lBcCAwEAAaNQME4wHQYD
VR0OBBYEFGzTpQOrDV8syY2KnIiniHe4N/2aMB8GA1UdIwQYMBaAFNa0LbQtmNk9
B2QI80ZGnMhS1Qa/MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBALw+
mUsLEoqk6eI4jGv5TPP56RPMRdI+wwmQ8+sQ4DIOzDErkIIQMtoP3aqU6kstHrfY
RZ2tJSWfKb9GcE2SL5VtHQCjSJLsE7f+fTpCFn41q0QMsXF22IOxT2eDvK4Kb496
NVulV6DhsHmbSjo6kla9U3Zqv4WiqLTNj757j+YgmplZQNx8vT5HkPIUi20IxEKV
m6CtPa0M2c2Hl/Y9v006AHmaXnabGvwnLsK92NV0oQb6KnB0mxOrL8od765SF9T0
OXiNK/2ilN2UB1ft16GI/tU+2N+sTmW9/+S5lExfG/S3qXJwc1l4OC9tH9CxOtYt
6Q+cAmgl6qxF3ltltCM=
-----END CERTIFICATE-----

0 comments on commit 3539b16

Please sign in to comment.