mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
rust/pv: Reorganize some tests
Use a static Mockito server instead of creating multiple on-the-fly during testing. Add the `mockito_server_available` test to quickly verify that the mockito server could be constructed. Relocate the verifier API test to the test folder as it tests the public API. Also, make the Debug impl for CertVerifier public. The test relocation requires this. Before, there could be a test local implementation of the Debug impl as it was in the same crate. While at it, get rid of the lazy_static crate in favor of the once_cell crate. As the new std lib implementation is very near to the one from once cell. The project will switch to the std impl when v1.70 is available in all supported distros. See: https://doc.rust-lang.org/std/sync/struct.OnceLock.html Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
02dded11a5
commit
c0a12b29d0
Generated
+3
-3
@@ -651,9 +651,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
@@ -779,9 +779,9 @@ dependencies = [
|
||||
"byteorder",
|
||||
"clap",
|
||||
"curl",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"mockito",
|
||||
"once_cell",
|
||||
"openssl",
|
||||
"openssl_extensions",
|
||||
"pv_core",
|
||||
|
||||
+1
-1
@@ -20,5 +20,5 @@ pv_core = { path = "../pv_core" }
|
||||
|
||||
[dev-dependencies]
|
||||
mockito = {version = "1", default-features = false }
|
||||
once_cell = "1.19"
|
||||
serde_test = "1"
|
||||
lazy_static = "1.1"
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ pub mod request {
|
||||
pub use crate::crypto::{Aes256Key, SymKey, SymKeyType};
|
||||
pub use crate::req::{Aad, Encrypt, Keyslot, ReqEncrCtx, Request};
|
||||
pub use crate::secret::{Secret, Zeroize};
|
||||
pub use crate::verify::HkdVerifier;
|
||||
pub use crate::verify::{CertVerifier, HkdVerifier, NoVerifyHkd};
|
||||
|
||||
/// Reexports some useful OpenSSL symbols
|
||||
pub mod openssl {
|
||||
|
||||
@@ -45,6 +45,12 @@ pub struct CertVerifier {
|
||||
offline: bool,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for CertVerifier {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str("CertVerifier")
|
||||
}
|
||||
}
|
||||
|
||||
impl HkdVerifier for CertVerifier {
|
||||
/// This function verifies a host-key
|
||||
/// document. To do so multiple steps are required:
|
||||
|
||||
+11
-118
@@ -7,46 +7,30 @@
|
||||
use super::{helper, helper::*, *};
|
||||
use crate::{Error, HkdVerifyErrorType::*};
|
||||
use core::slice;
|
||||
use once_cell::sync::OnceCell;
|
||||
use openssl::stack::Stack;
|
||||
use std::ffi::c_int;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use crate::test_utils::*;
|
||||
|
||||
pub fn mock_endpt(res: &str) -> mockito::Mock {
|
||||
static MOCK_SERVER: OnceCell<Mutex<mockito::Server>> = OnceCell::new();
|
||||
|
||||
let res_path = get_cert_asset_path(res);
|
||||
|
||||
let mut server = mockito::Server::new();
|
||||
server
|
||||
MOCK_SERVER
|
||||
.get_or_init(|| mockito::Server::new_with_port(1234).into())
|
||||
.lock()
|
||||
.expect("COULD NOT GET THE MOCK_SERVER LOCK")
|
||||
.mock("GET", format!("/crl/{res}").as_str())
|
||||
.with_header("content-type", "application/pkix-crl")
|
||||
.with_body_from_file(res_path)
|
||||
.create()
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn verify_sign_error(exp_raw: c_int, obs: Error) {
|
||||
verify_sign_error_slice(&[exp_raw], obs)
|
||||
}
|
||||
fn verify_sign_error_slice(exp_raw: &[c_int], obs: Error) {
|
||||
if exp_raw
|
||||
.iter()
|
||||
.filter(|e| match &obs {
|
||||
Error::HkdVerify(ty) => match ty {
|
||||
IbmSignInvalid(err, _d) => &&err.as_raw() == e,
|
||||
_ => false,
|
||||
},
|
||||
e => panic!("Unexpected error type: {e:?}"),
|
||||
})
|
||||
.count()
|
||||
== 0
|
||||
{
|
||||
panic!("Error {obs:?} did not match one of the expected {exp_raw:?}");
|
||||
}
|
||||
}
|
||||
impl std::fmt::Debug for CertVerifier {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str("CertVerifier")
|
||||
}
|
||||
#[test]
|
||||
fn mockito_server_available() {
|
||||
let _mock = mock_endpt("ibm.crt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -175,97 +159,6 @@ fn verify_offline() {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verifier_new() {
|
||||
let root_chn_crt = get_cert_asset_path_string("root_ca.chained.crt");
|
||||
let root_crt = get_cert_asset_path_string("root_ca.crt");
|
||||
let inter_crt = get_cert_asset_path_string("inter_ca.crt");
|
||||
let inter_fake_crt = get_cert_asset_path_string("fake_inter_ca.crt");
|
||||
let inter_fake_crl = get_cert_asset_path_string("fake_inter_ca.crl");
|
||||
let inter_crl = get_cert_asset_path_string("inter_ca.crl");
|
||||
let ibm_crt = get_cert_asset_path_string("ibm.crt");
|
||||
let ibm_early_crt = get_cert_asset_path_string("ibm_outdated_early.crl");
|
||||
let ibm_late_crt = get_cert_asset_path_string("ibm_outdated_late.crl");
|
||||
let ibm_rev_crt = get_cert_asset_path_string("ibm_rev.crt");
|
||||
|
||||
// To many signing keys
|
||||
let verifier = CertVerifier::new(&[ibm_crt.clone(), ibm_rev_crt.clone()], &[], &None, true);
|
||||
assert!(matches!(verifier, Err(Error::HkdVerify(ManyIbmSignKeys))));
|
||||
|
||||
// no CRL for each X509
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_crt),
|
||||
false,
|
||||
);
|
||||
verify_sign_error(3, verifier.unwrap_err());
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
);
|
||||
verify_sign_error(3, verifier.unwrap_err());
|
||||
|
||||
// wrong intermediate (or ibm key)
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_fake_crt, ibm_crt.clone()],
|
||||
&[inter_fake_crl],
|
||||
&Some(root_chn_crt.clone()),
|
||||
true,
|
||||
);
|
||||
//Depending on the OpenSSL version different error codes can appear
|
||||
verify_sign_error_slice(&[20, 30], verifier.unwrap_err());
|
||||
|
||||
//wrong root ca
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[inter_crl.clone()],
|
||||
&None,
|
||||
true,
|
||||
);
|
||||
verify_sign_error(20, verifier.unwrap_err());
|
||||
|
||||
//correct signing key + intermediate cert
|
||||
let _verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// no intermediate key
|
||||
let verifier = CertVerifier::new(&[ibm_crt], &[], &Some(root_chn_crt.clone()), false);
|
||||
verify_sign_error(20, verifier.unwrap_err());
|
||||
|
||||
//Ibm Sign outdated
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_early_crt],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
);
|
||||
assert!(matches!(verifier, Err(Error::HkdVerify(NoIbmSignKey))));
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_late_crt],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
);
|
||||
assert!(matches!(verifier, Err(Error::HkdVerify(NoIbmSignKey))));
|
||||
|
||||
// revoked
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt, ibm_rev_crt],
|
||||
&[inter_crl],
|
||||
&Some(root_chn_crt),
|
||||
false,
|
||||
);
|
||||
verify_sign_error(23, verifier.unwrap_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dist_points() {
|
||||
let crt = load_gen_cert("ibm.crt");
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright IBM Corp. 2023
|
||||
|
||||
use pv::request::CertVerifier;
|
||||
use pv::test_utils::*;
|
||||
use pv::{Error, HkdVerifyErrorType::*};
|
||||
use std::ffi::c_int;
|
||||
|
||||
#[track_caller]
|
||||
fn verify_sign_error(exp_raw: c_int, obs: Error) {
|
||||
verify_sign_error_slice(&[exp_raw], obs)
|
||||
}
|
||||
fn verify_sign_error_slice(exp_raw: &[c_int], obs: Error) {
|
||||
if exp_raw
|
||||
.iter()
|
||||
.filter(|e| match &obs {
|
||||
Error::HkdVerify(ty) => match ty {
|
||||
IbmSignInvalid(err, _d) => &&err.as_raw() == e,
|
||||
_ => false,
|
||||
},
|
||||
e => panic!("Unexpected error type: {e:?}"),
|
||||
})
|
||||
.count()
|
||||
== 0
|
||||
{
|
||||
panic!("Error {obs:?} did not match one of the expected {exp_raw:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verifier_new() {
|
||||
let root_chn_crt = get_cert_asset_path_string("root_ca.chained.crt");
|
||||
let root_crt = get_cert_asset_path_string("root_ca.crt");
|
||||
let inter_crt = get_cert_asset_path_string("inter_ca.crt");
|
||||
let inter_fake_crt = get_cert_asset_path_string("fake_inter_ca.crt");
|
||||
let inter_fake_crl = get_cert_asset_path_string("fake_inter_ca.crl");
|
||||
let inter_crl = get_cert_asset_path_string("inter_ca.crl");
|
||||
let ibm_crt = get_cert_asset_path_string("ibm.crt");
|
||||
let ibm_early_crt = get_cert_asset_path_string("ibm_outdated_early.crl");
|
||||
let ibm_late_crt = get_cert_asset_path_string("ibm_outdated_late.crl");
|
||||
let ibm_rev_crt = get_cert_asset_path_string("ibm_rev.crt");
|
||||
|
||||
// Too many signing keys
|
||||
let verifier = CertVerifier::new(&[ibm_crt.clone(), ibm_rev_crt.clone()], &[], &None, true);
|
||||
assert!(matches!(verifier, Err(Error::HkdVerify(ManyIbmSignKeys))));
|
||||
|
||||
// No CRL for each X509
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_crt),
|
||||
false,
|
||||
);
|
||||
verify_sign_error(3, verifier.unwrap_err());
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
);
|
||||
verify_sign_error(3, verifier.unwrap_err());
|
||||
|
||||
// Wrong intermediate (or ibm key)
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_fake_crt, ibm_crt.clone()],
|
||||
&[inter_fake_crl],
|
||||
&Some(root_chn_crt.clone()),
|
||||
true,
|
||||
);
|
||||
// Depending on the OpenSSL version different error codes can appear
|
||||
verify_sign_error_slice(&[20, 30], verifier.unwrap_err());
|
||||
|
||||
// Wrong root ca
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[inter_crl.clone()],
|
||||
&None,
|
||||
true,
|
||||
);
|
||||
verify_sign_error(20, verifier.unwrap_err());
|
||||
|
||||
// Correct signing key + intermediate cert
|
||||
let _verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// No intermediate key
|
||||
let verifier = CertVerifier::new(&[ibm_crt], &[], &Some(root_chn_crt.clone()), false);
|
||||
verify_sign_error(20, verifier.unwrap_err());
|
||||
|
||||
// IBM Sign outdated
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_early_crt],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
);
|
||||
assert!(matches!(verifier, Err(Error::HkdVerify(NoIbmSignKey))));
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt.clone(), ibm_late_crt],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
);
|
||||
assert!(matches!(verifier, Err(Error::HkdVerify(NoIbmSignKey))));
|
||||
|
||||
// Revoked
|
||||
let verifier = CertVerifier::new(
|
||||
&[inter_crt, ibm_rev_crt],
|
||||
&[inter_crl],
|
||||
&Some(root_chn_crt),
|
||||
false,
|
||||
);
|
||||
verify_sign_error(23, verifier.unwrap_err());
|
||||
}
|
||||
Reference in New Issue
Block a user