From 74b270a437646c723f2660484c47641fe5462514 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sun, 17 May 2020 21:55:55 -0400 Subject: [PATCH 1/3] api: mark PublicKeyOptions as Default and prime for #[non_exhaustive] --- src/api.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/api.rs b/src/api.rs index 39ca0d0..606ca48 100644 --- a/src/api.rs +++ b/src/api.rs @@ -640,7 +640,8 @@ impl KeyctlHash { } /// Options for output from public key functions (encryption, decryption, signing, and verifying). -#[derive(Debug, Clone)] +#[derive(Debug, Default, Clone)] +// #[non_exhaustive] pub struct PublicKeyOptions { /// The encoding of the encrypted blob or the signature. pub encoding: Option, From 3ed84f1c7b7442703e90b679f752b2cb50180f11 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sun, 17 May 2020 21:56:17 -0400 Subject: [PATCH 2/3] tests: add pkey tests for basic key types --- src/tests/mod.rs | 1 + src/tests/pkey.rs | 205 ++++++++++++++++++++++++++++++++++++++ src/tests/utils/kernel.rs | 18 ++++ 3 files changed, 224 insertions(+) create mode 100644 src/tests/pkey.rs diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 740048b..013a6f0 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -37,6 +37,7 @@ mod keytype; mod link; mod newring; mod permitting; +mod pkey; mod reading; mod revoke; mod search; diff --git a/src/tests/pkey.rs b/src/tests/pkey.rs new file mode 100644 index 0000000..7113859 --- /dev/null +++ b/src/tests/pkey.rs @@ -0,0 +1,205 @@ +// Copyright (c) 2020, Ben Boeckel +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of this project nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::keytypes::User; + +use super::utils; +use super::utils::kernel::*; + +#[test] +fn invalid_keyring_query() { + let keyring = utils::invalid_keyring(); + let key = utils::keyring_as_key(&keyring); + let err = key.pkey_query_support(&Default::default()).unwrap_err(); + assert_eq!(err, errno::Errno(libc::EINVAL)); +} + +#[test] +fn invalid_key_query() { + let key = utils::invalid_key(); + let err = key.pkey_query_support(&Default::default()).unwrap_err(); + assert_eq!(err, errno::Errno(libc::EINVAL)); +} + +#[test] +fn pkey_query_keyring() { + let keyring = utils::new_test_keyring(); + let key = utils::keyring_as_key(&keyring); + let err = key.pkey_query_support(&Default::default()).unwrap_err(); + + if *HAVE_PKEY { + assert_eq!(err, errno::Errno(libc::EOPNOTSUPP)); + } else { + assert_eq!(err, errno::Errno(libc::ENOSYS)); + } +} + +#[test] +fn pkey_query_user() { + let mut keyring = utils::new_test_keyring(); + let payload = &b"payload"[..]; + let key = keyring + .add_key::("pkey_query_user", payload) + .unwrap(); + + let err = key.pkey_query_support(&Default::default()).unwrap_err(); + + if *HAVE_PKEY { + assert_eq!(err, errno::Errno(libc::EOPNOTSUPP)); + } else { + assert_eq!(err, errno::Errno(libc::ENOSYS)); + } +} + +#[test] +fn pkey_encrypt_keyring() { + let keyring = utils::new_test_keyring(); + let key = utils::keyring_as_key(&keyring); + let data = &b"data"[..]; + let err = key.encrypt(&Default::default(), data).unwrap_err(); + + if *HAVE_PKEY { + assert_eq!(err, errno::Errno(libc::EOPNOTSUPP)); + } else { + assert_eq!(err, errno::Errno(libc::ENOSYS)); + } +} + +#[test] +fn pkey_encrypt_user() { + let mut keyring = utils::new_test_keyring(); + let payload = &b"payload"[..]; + let key = keyring + .add_key::("pkey_encrypt_user", payload) + .unwrap(); + + let data = &b"data"[..]; + let err = key.encrypt(&Default::default(), data).unwrap_err(); + + if *HAVE_PKEY { + assert_eq!(err, errno::Errno(libc::EOPNOTSUPP)); + } else { + assert_eq!(err, errno::Errno(libc::ENOSYS)); + } +} + +#[test] +fn pkey_decrypt_keyring() { + let keyring = utils::new_test_keyring(); + let key = utils::keyring_as_key(&keyring); + let data = &b"data"[..]; + let err = key.decrypt(&Default::default(), data).unwrap_err(); + + if *HAVE_PKEY { + assert_eq!(err, errno::Errno(libc::EOPNOTSUPP)); + } else { + assert_eq!(err, errno::Errno(libc::ENOSYS)); + } +} + +#[test] +fn pkey_decrypt_user() { + let mut keyring = utils::new_test_keyring(); + let payload = &b"payload"[..]; + let key = keyring + .add_key::("pkey_decrypt_user", payload) + .unwrap(); + + let data = &b"data"[..]; + let err = key.decrypt(&Default::default(), data).unwrap_err(); + + if *HAVE_PKEY { + assert_eq!(err, errno::Errno(libc::EOPNOTSUPP)); + } else { + assert_eq!(err, errno::Errno(libc::ENOSYS)); + } +} + +#[test] +fn pkey_sign_keyring() { + let keyring = utils::new_test_keyring(); + let key = utils::keyring_as_key(&keyring); + let data = &b"data"[..]; + let err = key.sign(&Default::default(), data).unwrap_err(); + + if *HAVE_PKEY { + assert_eq!(err, errno::Errno(libc::EOPNOTSUPP)); + } else { + assert_eq!(err, errno::Errno(libc::ENOSYS)); + } +} + +#[test] +fn pkey_sign_user() { + let mut keyring = utils::new_test_keyring(); + let payload = &b"payload"[..]; + let key = keyring + .add_key::("pkey_sign_user", payload) + .unwrap(); + + let data = &b"data"[..]; + let err = key.sign(&Default::default(), data).unwrap_err(); + + if *HAVE_PKEY { + assert_eq!(err, errno::Errno(libc::EOPNOTSUPP)); + } else { + assert_eq!(err, errno::Errno(libc::ENOSYS)); + } +} + +#[test] +fn pkey_verify_keyring() { + let keyring = utils::new_test_keyring(); + let key = utils::keyring_as_key(&keyring); + let data = &b"data"[..]; + let sig = &b"sig"[..]; + let err = key.verify(&Default::default(), data, sig).unwrap_err(); + + if *HAVE_PKEY { + assert_eq!(err, errno::Errno(libc::EOPNOTSUPP)); + } else { + assert_eq!(err, errno::Errno(libc::ENOSYS)); + } +} + +#[test] +fn pkey_verify_user() { + let mut keyring = utils::new_test_keyring(); + let payload = &b"payload"[..]; + let key = keyring + .add_key::("pkey_verify_user", payload) + .unwrap(); + + let data = &b"data"[..]; + let sig = &b"sig"[..]; + let err = key.verify(&Default::default(), data, sig).unwrap_err(); + + if *HAVE_PKEY { + assert_eq!(err, errno::Errno(libc::EOPNOTSUPP)); + } else { + assert_eq!(err, errno::Errno(libc::ENOSYS)); + } +} diff --git a/src/tests/utils/kernel.rs b/src/tests/utils/kernel.rs index ec55816..52d5650 100644 --- a/src/tests/utils/kernel.rs +++ b/src/tests/utils/kernel.rs @@ -38,6 +38,7 @@ lazy_static! { pub static ref KERNEL_VERSION: String = kernel_version(); pub static ref SEMVER_KERNEL_VERSION: &'static str = semver_kernel_version(); pub static ref HAVE_INVALIDATE: bool = have_invalidate(); + pub static ref HAVE_PKEY: bool = have_pkey(); pub static ref PAGE_SIZE: usize = page_size(); pub static ref UID: libc::uid_t = getuid(); pub static ref GID: libc::gid_t = getgid(); @@ -82,6 +83,23 @@ fn have_invalidate() -> bool { } } +// Whether the kernel supports the `pkey` APIs on a key. +fn have_pkey() -> bool { + match Version::parse(*SEMVER_KERNEL_VERSION) { + Ok(ver) => { + let minver = VersionReq::parse(">=4.20").unwrap(); + minver.matches(&ver) + }, + Err(err) => { + eprintln!( + "failed to parse kernel version `{}` ({}): assuming incompatibility", + *SEMVER_KERNEL_VERSION, err + ); + false + }, + } +} + fn page_size() -> usize { errno::set_errno(errno::Errno(0)); let ret = unsafe { libc::sysconf(libc::_SC_PAGESIZE) }; From 635e878c4e5360ca8baf45eeca397d5e33d10c99 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Sun, 17 May 2020 22:04:37 -0400 Subject: [PATCH 3/3] WIP: debug cirrus kernel version info --- src/tests/utils/kernel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/utils/kernel.rs b/src/tests/utils/kernel.rs index 52d5650..6e900aa 100644 --- a/src/tests/utils/kernel.rs +++ b/src/tests/utils/kernel.rs @@ -85,7 +85,7 @@ fn have_invalidate() -> bool { // Whether the kernel supports the `pkey` APIs on a key. fn have_pkey() -> bool { - match Version::parse(*SEMVER_KERNEL_VERSION) { + match Version::parse(dbg!(*SEMVER_KERNEL_VERSION)) { Ok(ver) => { let minver = VersionReq::parse(">=4.20").unwrap(); minver.matches(&ver)