From c713961336d28244e9eafd9fd4cadb76e80212a7 Mon Sep 17 00:00:00 2001 From: David Runge <dvzrv@archlinux.org> Date: Fri, 21 Feb 2025 08:34:07 +0100 Subject: [PATCH 1/2] feat: Switch to Rust edition 2024 Use resolver 3 (which came with Rust edition 2024). Set the minimum required Rust version to 1.85.0. Signed-off-by: David Runge <dvzrv@archlinux.org> --- Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8c2322c0..616c5a8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -resolver = "2" +resolver = "3" members = [ "nethsm", "nethsm-backup", @@ -44,10 +44,11 @@ authors = [ "David Runge <dvzrv@archlinux.org>", "Wiktor Kwapisiewicz <wiktor@archlinux.org>", ] -edition = "2021" +edition = "2024" homepage = "https://gitlab.archlinux.org/archlinux/signstar" license = "Apache-2.0 OR MIT" repository = "https://gitlab.archlinux.org/archlinux/signstar" +rust-version = "1.85.0" [profile.release] lto = true -- GitLab From 264045aad154aef7f74066a88722ad38336231a7 Mon Sep 17 00:00:00 2001 From: David Runge <dvzrv@archlinux.org> Date: Fri, 21 Feb 2025 08:36:47 +0100 Subject: [PATCH 2/2] chore: Switch to rustfmt style edition 2024 Ensure to always use style edition 2024. Format all code according to style edition 2024. Signed-off-by: David Runge <dvzrv@archlinux.org> --- nethsm-backup/src/lib.rs | 8 +- nethsm-backup/tests/backup-decrypt.rs | 2 +- nethsm-cli/src/cli.rs | 4 +- nethsm-cli/src/main.rs | 6 +- nethsm-cli/src/passphrase_file.rs | 2 +- nethsm-config/src/config.rs | 166 +++++++++++++---------- nethsm-config/src/credentials.rs | 2 +- nethsm-config/src/mapping.rs | 12 +- nethsm-tests/src/container.rs | 2 +- nethsm-tests/src/lib.rs | 2 +- nethsm/src/key.rs | 126 +++++++++-------- nethsm/src/lib.rs | 174 +++++++++++++----------- nethsm/src/openpgp.rs | 45 ++++--- nethsm/src/tls.rs | 10 +- nethsm/src/user.rs | 16 ++- nethsm/tests/certificates.rs | 22 +-- nethsm/tests/config.rs | 84 +++++++----- nethsm/tests/encryption.rs | 6 +- nethsm/tests/health.rs | 2 +- nethsm/tests/keys.rs | 36 +++-- nethsm/tests/locking.rs | 4 +- nethsm/tests/metrics.rs | 2 +- nethsm/tests/namespace.rs | 2 +- nethsm/tests/provisioning.rs | 4 +- nethsm/tests/random.rs | 4 +- nethsm/tests/signing.rs | 11 +- nethsm/tests/system.rs | 6 +- nethsm/tests/users.rs | 180 ++++++++++++++----------- rustfmt.toml | 1 + signstar-configure-build/src/cli.rs | 6 +- signstar-configure-build/src/lib.rs | 10 +- signstar-configure-build/src/main.rs | 6 +- signstar-request-signature/src/lib.rs | 2 +- signstar-request-signature/src/main.rs | 2 +- 34 files changed, 551 insertions(+), 416 deletions(-) diff --git a/nethsm-backup/src/lib.rs b/nethsm-backup/src/lib.rs index c20fbfd8..d04cb24f 100644 --- a/nethsm-backup/src/lib.rs +++ b/nethsm-backup/src/lib.rs @@ -126,8 +126,8 @@ use std::{ slice::Iter, }; -use aes_gcm::{aead::Aead as _, Aes256Gcm, KeyInit as _}; -use scrypt::{scrypt, Params}; +use aes_gcm::{Aes256Gcm, KeyInit as _, aead::Aead as _}; +use scrypt::{Params, scrypt}; /// Backup processing error. #[derive(Debug, thiserror::Error)] @@ -162,7 +162,9 @@ pub enum Error { /// Version number is not recognized. /// /// This library supports only version `0` backups. - #[error("Unsupported backup version number: {backup_version:?}. The highest supported version is {highest_supported_version}")] + #[error( + "Unsupported backup version number: {backup_version:?}. The highest supported version is {highest_supported_version}" + )] BadVersion { highest_supported_version: u8, backup_version: Vec<u8>, diff --git a/nethsm-backup/tests/backup-decrypt.rs b/nethsm-backup/tests/backup-decrypt.rs index 6769afe4..5a909399 100644 --- a/nethsm-backup/tests/backup-decrypt.rs +++ b/nethsm-backup/tests/backup-decrypt.rs @@ -1,6 +1,6 @@ use nethsm::{NetHsm, Passphrase, UserId}; use nethsm_backup::Backup; -use nethsm_tests::{nethsm_with_users, NetHsmImage, ADMIN_USER_ID, BACKUP_USER_ID}; +use nethsm_tests::{ADMIN_USER_ID, BACKUP_USER_ID, NetHsmImage, nethsm_with_users}; use rstest::rstest; use rustainers::Container; use testdir::testdir; diff --git a/nethsm-cli/src/cli.rs b/nethsm-cli/src/cli.rs index caa39886..c207da61 100644 --- a/nethsm-cli/src/cli.rs +++ b/nethsm-cli/src/cli.rs @@ -40,7 +40,9 @@ pub const BIN_NAME: &str = "nethsm"; #[derive(Debug, thiserror::Error)] pub enum Error { /// An option is missing - #[error("The \"{0}\" option must be provided for this command if more than one environment is defined.")] + #[error( + "The \"{0}\" option must be provided for this command if more than one environment is defined." + )] OptionMissing(String), } diff --git a/nethsm-cli/src/main.rs b/nethsm-cli/src/main.rs index 253584bd..83971709 100644 --- a/nethsm-cli/src/main.rs +++ b/nethsm-cli/src/main.rs @@ -1,5 +1,5 @@ -use std::fs::{read, read_to_string, File}; -use std::io::{stdout, Write}; +use std::fs::{File, read, read_to_string}; +use std::io::{Write, stdout}; use std::path::{Path, PathBuf}; use chrono::Utc; @@ -17,7 +17,6 @@ use cli::{ }; use cli::{KeyCertCommand, KeyCommand, NamespaceCommand, SystemCommand}; use nethsm::{ - validate_backup, DistinguishedName, KeyFormat, KeyMechanism, @@ -27,6 +26,7 @@ use nethsm::{ SystemState, UserId, UserRole, + validate_backup, }; use nethsm_config::{ Config, diff --git a/nethsm-cli/src/passphrase_file.rs b/nethsm-cli/src/passphrase_file.rs index a78155ff..75b438a0 100644 --- a/nethsm-cli/src/passphrase_file.rs +++ b/nethsm-cli/src/passphrase_file.rs @@ -44,7 +44,7 @@ mod tests { use std::fs::File; use std::io::Write; - use rand::{thread_rng, Rng}; + use rand::{Rng, thread_rng}; use rstest::rstest; use testdir::testdir; use testresult::TestResult; diff --git a/nethsm-config/src/config.rs b/nethsm-config/src/config.rs index 4f4f6734..3612a9b9 100644 --- a/nethsm-config/src/config.rs +++ b/nethsm-config/src/config.rs @@ -1,6 +1,6 @@ use std::{ cell::RefCell, - collections::{hash_map::Entry, HashMap, HashSet}, + collections::{HashMap, HashSet, hash_map::Entry}, error::Error as StdError, fmt::Display, path::{Path, PathBuf}, @@ -56,7 +56,9 @@ pub enum Error { /// Shamir's Secret Sharing (SSS) is not used for administrative secret handling, but users for /// handling of secret shares are defined - #[error("Shamir's Secret Sharing not used for administrative secret handling, but the following users are setup to handle shares: {share_users:?}")] + #[error( + "Shamir's Secret Sharing not used for administrative secret handling, but the following users are setup to handle shares: {share_users:?}" + )] NoSssButShareUsers { share_users: Vec<SystemUserId> }, /// Device exists already @@ -314,23 +316,25 @@ impl DeviceConfig { /// )?; /// /// // this fails because the provided credentials contain duplicates - /// assert!(DeviceConfig::new( - /// connection.clone(), - /// vec![ - /// ConfigCredentials::new( - /// UserRole::Operator, - /// "user1".parse()?, - /// Some("my-passphrase".to_string()), - /// ), - /// ConfigCredentials::new( - /// UserRole::Operator, - /// "user1".parse()?, - /// Some("my-passphrase".to_string()), - /// ), - /// ], - /// ConfigInteractivity::NonInteractive, - /// ) - /// .is_err()); + /// assert!( + /// DeviceConfig::new( + /// connection.clone(), + /// vec![ + /// ConfigCredentials::new( + /// UserRole::Operator, + /// "user1".parse()?, + /// Some("my-passphrase".to_string()), + /// ), + /// ConfigCredentials::new( + /// UserRole::Operator, + /// "user1".parse()?, + /// Some("my-passphrase".to_string()), + /// ), + /// ], + /// ConfigInteractivity::NonInteractive, + /// ) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -395,13 +399,15 @@ impl DeviceConfig { /// ))?; /// /// // this fails because the credentials exist already - /// assert!(device_config - /// .add_credentials(ConfigCredentials::new( - /// UserRole::Operator, - /// "user1".parse()?, - /// Some("my-passphrase".to_string()), - /// )) - /// .is_err()); + /// assert!( + /// device_config + /// .add_credentials(ConfigCredentials::new( + /// UserRole::Operator, + /// "user1".parse()?, + /// Some("my-passphrase".to_string()), + /// )) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -580,24 +586,32 @@ impl DeviceConfig { /// ); /// /// // this fails because we must provide a role to match against - /// assert!(device_config - /// .get_matching_credentials(&[], &["user1".parse()?]) - /// .is_err()); + /// assert!( + /// device_config + /// .get_matching_credentials(&[], &["user1".parse()?]) + /// .is_err() + /// ); /// /// // this fails because no user in the requested role exists - /// assert!(device_config - /// .get_matching_credentials(&[UserRole::Metrics], &[]) - /// .is_err()); + /// assert!( + /// device_config + /// .get_matching_credentials(&[UserRole::Metrics], &[]) + /// .is_err() + /// ); /// /// // this fails because no user with the name first provided exists - /// assert!(device_config - /// .get_matching_credentials(&[UserRole::Operator], &["user2".parse()?, "user1".parse()?]) - /// .is_err()); + /// assert!( + /// device_config + /// .get_matching_credentials(&[UserRole::Operator], &["user2".parse()?, "user1".parse()?]) + /// .is_err() + /// ); /// /// // this fails because no user in the requested role with any of the provided names exists - /// assert!(device_config - /// .get_matching_credentials(&[UserRole::Metrics], &["admin1".parse()?, "user1".parse()?]) - /// .is_err()); + /// assert!( + /// device_config + /// .get_matching_credentials(&[UserRole::Metrics], &["admin1".parse()?, "user1".parse()?]) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -991,13 +1005,15 @@ impl Config { /// )?; /// /// // adding the same device again leads to error - /// assert!(config - /// .add_device( - /// "device1".to_string(), - /// "https://example.org/api/v1".parse()?, - /// ConnectionSecurity::Unsafe, - /// ) - /// .is_err()); + /// assert!( + /// config + /// .add_device( + /// "device1".to_string(), + /// "https://example.org/api/v1".parse()?, + /// ConnectionSecurity::Unsafe, + /// ) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -1223,16 +1239,18 @@ impl Config { /// # )?; /// /// // this fails because the targeted device does not yet exist - /// assert!(config - /// .add_credentials( - /// "device1".to_string(), - /// ConfigCredentials::new( - /// UserRole::Operator, - /// "user1".parse()?, - /// Some("my-passphrase".to_string()), - /// ), - /// ) - /// .is_err()); + /// assert!( + /// config + /// .add_credentials( + /// "device1".to_string(), + /// ConfigCredentials::new( + /// UserRole::Operator, + /// "user1".parse()?, + /// Some("my-passphrase".to_string()), + /// ), + /// ) + /// .is_err() + /// ); /// /// config.add_device( /// "device1".to_string(), @@ -1250,16 +1268,18 @@ impl Config { /// )?; /// /// // this fails because the credentials exist already - /// assert!(config - /// .add_credentials( - /// "device1".to_string(), - /// ConfigCredentials::new( - /// UserRole::Operator, - /// "user1".parse()?, - /// Some("my-passphrase".to_string()), - /// ), - /// ) - /// .is_err()); + /// assert!( + /// config + /// .add_credentials( + /// "device1".to_string(), + /// ConfigCredentials::new( + /// UserRole::Operator, + /// "user1".parse()?, + /// Some("my-passphrase".to_string()), + /// ), + /// ) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -1302,9 +1322,11 @@ impl Config { /// # )?; /// /// // this fails because the targeted device does not yet exist - /// assert!(config - /// .delete_credentials("device1", &"user1".parse()?) - /// .is_err()); + /// assert!( + /// config + /// .delete_credentials("device1", &"user1".parse()?) + /// .is_err() + /// ); /// /// config.add_device( /// "device1".to_string(), @@ -1313,9 +1335,11 @@ impl Config { /// )?; /// /// // this fails because the targeted credentials does not yet exist - /// assert!(config - /// .delete_credentials("device1", &"user1".parse()?) - /// .is_err()); + /// assert!( + /// config + /// .delete_credentials("device1", &"user1".parse()?) + /// .is_err() + /// ); /// /// config.add_credentials( /// "device1".to_string(), diff --git a/nethsm-config/src/credentials.rs b/nethsm-config/src/credentials.rs index cfd8bb80..35501845 100644 --- a/nethsm-config/src/credentials.rs +++ b/nethsm-config/src/credentials.rs @@ -2,7 +2,7 @@ use std::{collections::HashSet, fmt::Display, str::FromStr}; use nethsm::{Credentials, Passphrase, UserId, UserRole}; use serde::{Deserialize, Serialize}; -use ssh_key::{authorized_keys::Entry, PublicKey}; +use ssh_key::{PublicKey, authorized_keys::Entry}; use zeroize::Zeroize; /// Errors related to credentials diff --git a/nethsm-config/src/mapping.rs b/nethsm-config/src/mapping.rs index fe21ea2b..777ad416 100644 --- a/nethsm-config/src/mapping.rs +++ b/nethsm-config/src/mapping.rs @@ -55,11 +55,13 @@ impl NetHsmMetricsUsers { /// )?; /// /// // this fails because there are duplicate UserIds - /// assert!(NetHsmMetricsUsers::new( - /// "metrics1".parse()?, - /// vec!["metrics1".parse()?, "user2".parse()?,], - /// ) - /// .is_err()); + /// assert!( + /// NetHsmMetricsUsers::new( + /// "metrics1".parse()?, + /// vec!["metrics1".parse()?, "user2".parse()?,], + /// ) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` diff --git a/nethsm-tests/src/container.rs b/nethsm-tests/src/container.rs index 1a3415c6..f34014d4 100644 --- a/nethsm-tests/src/container.rs +++ b/nethsm-tests/src/container.rs @@ -8,7 +8,7 @@ use rustainers::{ WaitStrategy, }; use testresult::TestResult; -use uuid::{timestamp::Timestamp, NoContext, Uuid}; +use uuid::{NoContext, Uuid, timestamp::Timestamp}; /// The NetHSM container image and specific tag /// diff --git a/nethsm-tests/src/lib.rs b/nethsm-tests/src/lib.rs index 6a44d4e7..3a29c269 100644 --- a/nethsm-tests/src/lib.rs +++ b/nethsm-tests/src/lib.rs @@ -16,8 +16,8 @@ use nethsm::{ UserRole, }; use rstest::fixture; -use rustainers::runner::Runner; use rustainers::Container; +use rustainers::runner::Runner; use testresult::TestResult; /// Identifier for an admin user. diff --git a/nethsm/src/key.rs b/nethsm/src/key.rs index 2d39c955..38c3756f 100644 --- a/nethsm/src/key.rs +++ b/nethsm/src/key.rs @@ -3,10 +3,10 @@ use std::{fmt::Display, str::FromStr}; use base64ct::{Base64, Encoding}; use nethsm_sdk_rs::models::KeyPrivateData; use rsa::{ + RsaPrivateKey, pkcs8::DecodePrivateKey, traits::PrivateKeyParts, traits::PublicKeyParts, - RsaPrivateKey, }; use serde::{Deserialize, Serialize}; @@ -151,11 +151,15 @@ pub enum Error { KeyLengthRequired { key_type: KeyType }, /// AES key is generated with unsupported key length (not 128, 192 or 256) - #[error("AES only defines key lengths of 128, 192 and 256. A key length of {key_length} is unsupported!")] + #[error( + "AES only defines key lengths of 128, 192 and 256. A key length of {key_length} is unsupported!" + )] InvalidKeyLengthAes { key_length: u32 }, /// RSA key is generated with unsafe key length (smaller than 2048) - #[error("RSA keys shorter than {MIN_RSA_BIT_LENGTH} are not supported. A key length of {key_length} is unsafe!")] + #[error( + "RSA keys shorter than {MIN_RSA_BIT_LENGTH} are not supported. A key length of {key_length} is unsafe!" + )] InvalidKeyLengthRsa { key_length: u32 }, /// Elliptic curve TLS keys do not support providing a length @@ -167,7 +171,9 @@ pub enum Error { TlsKeyLengthRequired { tls_key_type: TlsKeyType }, /// RSA TLS key is generated with unsafe key length (smaller than 2048) - #[error("RSA keys shorter than {MIN_RSA_BIT_LENGTH} are not supported. A key length of {key_length} is unsafe!")] + #[error( + "RSA keys shorter than {MIN_RSA_BIT_LENGTH} are not supported. A key length of {key_length} is unsafe!" + )] InvalidTlsKeyLengthRsa { key_length: u32 }, /// Invalid Key ID @@ -182,7 +188,9 @@ pub enum Error { }, /// The key mechanisms provided for a signature type are not valid - #[error("The key mechanism {required_key_mechanism} must be used with signature type {signature_type}")] + #[error( + "The key mechanism {required_key_mechanism} must be used with signature type {signature_type}" + )] InvalidKeyMechanismsForSignatureType { required_key_mechanism: KeyMechanism, signature_type: SignatureType, @@ -193,7 +201,9 @@ pub enum Error { InvalidCryptograhicKeyUse(String), /// A signing key setup is not compatible with raw cryptographic signing - #[error("The key type {key_type}, key mechanisms {key_mechanisms:?} and signature type {signature_type} are incompatible with raw cryptographic signing")] + #[error( + "The key type {key_type}, key mechanisms {key_mechanisms:?} and signature type {signature_type} are incompatible with raw cryptographic signing" + )] InvalidRawSigningKeySetup { key_type: KeyType, key_mechanisms: Vec<KeyMechanism>, @@ -201,7 +211,9 @@ pub enum Error { }, /// A signing key setup is not compatible with OpenPGP signing - #[error("The key type {key_type}, key mechanisms {key_mechanisms:?} and signature type {signature_type} are incompatible with OpenPGP signing")] + #[error( + "The key type {key_type}, key mechanisms {key_mechanisms:?} and signature type {signature_type} are incompatible with OpenPGP signing" + )] InvalidOpenPgpSigningKeySetup { key_type: KeyType, key_mechanisms: Vec<KeyMechanism>, @@ -266,16 +278,20 @@ impl CryptographicKeyContext { /// )?; /// /// // OpenPGP does not support ECDSA P224 - /// assert!(CryptographicKeyContext::OpenPgp { - /// user_ids: OpenPgpUserIdList::new(vec!["Foobar McFooface <foobar@mcfooface.org>".parse()?])?, - /// version: OpenPgpVersion::V4, - /// } - /// .validate_signing_key_setup( - /// KeyType::EcP224, - /// &[KeyMechanism::EcdsaSignature], - /// SignatureType::EcdsaP224, - /// ) - /// .is_err()); + /// assert!( + /// CryptographicKeyContext::OpenPgp { + /// user_ids: OpenPgpUserIdList::new(vec![ + /// "Foobar McFooface <foobar@mcfooface.org>".parse()? + /// ])?, + /// version: OpenPgpVersion::V4, + /// } + /// .validate_signing_key_setup( + /// KeyType::EcP224, + /// &[KeyMechanism::EcdsaSignature], + /// SignatureType::EcdsaP224, + /// ) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -316,7 +332,7 @@ impl CryptographicKeyContext { key_type, key_mechanisms: key_mechanisms.to_vec(), signature_type, - }) + }); } }, Self::OpenPgp { @@ -338,7 +354,7 @@ impl CryptographicKeyContext { key_type, key_mechanisms: key_mechanisms.to_vec(), signature_type, - }) + }); } }, } @@ -395,43 +411,47 @@ impl SigningKeySetup { /// SignatureType::EdDsa, /// CryptographicKeyContext::OpenPgp { /// user_ids: OpenPgpUserIdList::new(vec![ - /// "Foobar McFooface <foobar@mcfooface.org>".parse()? + /// "Foobar McFooface <foobar@mcfooface.org>".parse()?, /// ])?, /// version: "v4".parse()?, /// }, /// )?; /// /// // this fails because Curve25519 does not support the ECDSA key mechanism - /// assert!(SigningKeySetup::new( - /// "key1".parse()?, - /// KeyType::Curve25519, - /// vec![KeyMechanism::EcdsaSignature], - /// None, - /// SignatureType::EdDsa, - /// CryptographicKeyContext::OpenPgp { - /// user_ids: OpenPgpUserIdList::new(vec![ - /// "Foobar McFooface <foobar@mcfooface.org>".parse()? - /// ])?, - /// version: "v4".parse()?, - /// }, - /// ) - /// .is_err()); + /// assert!( + /// SigningKeySetup::new( + /// "key1".parse()?, + /// KeyType::Curve25519, + /// vec![KeyMechanism::EcdsaSignature], + /// None, + /// SignatureType::EdDsa, + /// CryptographicKeyContext::OpenPgp { + /// user_ids: OpenPgpUserIdList::new(vec![ + /// "Foobar McFooface <foobar@mcfooface.org>".parse()? + /// ])?, + /// version: "v4".parse()?, + /// }, + /// ) + /// .is_err() + /// ); /// /// // this fails because OpenPGP does not support the ECDSA P224 key type - /// assert!(SigningKeySetup::new( - /// "key1".parse()?, - /// KeyType::EcP224, - /// vec![KeyMechanism::EcdsaSignature], - /// None, - /// SignatureType::EcdsaP224, - /// CryptographicKeyContext::OpenPgp { - /// user_ids: OpenPgpUserIdList::new(vec![ - /// "Foobar McFooface <foobar@mcfooface.org>".parse()? - /// ])?, - /// version: "v4".parse()?, - /// }, - /// ) - /// .is_err()); + /// assert!( + /// SigningKeySetup::new( + /// "key1".parse()?, + /// KeyType::EcP224, + /// vec![KeyMechanism::EcdsaSignature], + /// None, + /// SignatureType::EcdsaP224, + /// CryptographicKeyContext::OpenPgp { + /// user_ids: OpenPgpUserIdList::new(vec![ + /// "Foobar McFooface <foobar@mcfooface.org>".parse()? + /// ])?, + /// version: "v4".parse()?, + /// }, + /// ) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -563,7 +583,7 @@ impl PrivateKeyImport { /// /// ``` /// # use testresult::TestResult; - /// use ed25519_dalek::{pkcs8::EncodePrivateKey, SigningKey}; + /// use ed25519_dalek::{SigningKey, pkcs8::EncodePrivateKey}; /// use nethsm::{KeyType, PrivateKeyImport}; /// use rand::rngs::OsRng; /// # fn main() -> TestResult { @@ -653,7 +673,7 @@ impl PrivateKeyImport { /// # use testresult::TestResult; /// use std::ops::Deref; /// - /// use ed25519_dalek::{pkcs8::spki::der::pem::LineEnding, pkcs8::EncodePrivateKey, SigningKey}; + /// use ed25519_dalek::{SigningKey, pkcs8::EncodePrivateKey, pkcs8::spki::der::pem::LineEnding}; /// use nethsm::{KeyType, PrivateKeyImport}; /// use rand::rngs::OsRng; /// # fn main() -> TestResult { @@ -1126,7 +1146,7 @@ pub fn key_type_and_mechanisms_match_signature_type( /// # Examples /// /// ``` -/// use nethsm::{key_type_matches_length, KeyType}; +/// use nethsm::{KeyType, key_type_matches_length}; /// /// # fn main() -> testresult::TestResult { /// key_type_matches_length(KeyType::Curve25519, None)?; @@ -1194,7 +1214,7 @@ pub fn key_type_matches_length(key_type: KeyType, length: Option<u32>) -> Result /// # Examples /// /// ``` -/// use nethsm::{tls_key_type_matches_length, TlsKeyType}; +/// use nethsm::{TlsKeyType, tls_key_type_matches_length}; /// /// # fn main() -> testresult::TestResult { /// tls_key_type_matches_length(TlsKeyType::Curve25519, None)?; @@ -1239,8 +1259,8 @@ pub fn tls_key_type_matches_length( #[cfg(test)] mod tests { - use rsa::pkcs8::EncodePrivateKey; use rsa::RsaPrivateKey; + use rsa::pkcs8::EncodePrivateKey; use rstest::{fixture, rstest}; use testresult::TestResult; diff --git a/nethsm/src/lib.rs b/nethsm/src/lib.rs index 89d6e98d..e423d292 100644 --- a/nethsm/src/lib.rs +++ b/nethsm/src/lib.rs @@ -101,6 +101,7 @@ use log::{debug, error, info}; use md5::{Digest as _, Md5}; use nethsm_sdk_rs::apis::configuration::Configuration; use nethsm_sdk_rs::apis::default_api::{ + KeysPostBody, config_backup_passphrase_put, config_logging_get, config_logging_put, @@ -162,7 +163,6 @@ use nethsm_sdk_rs::apis::default_api::{ users_user_id_tags_get, users_user_id_tags_tag_delete, users_user_id_tags_tag_put, - KeysPostBody, }; use nethsm_sdk_rs::models::{ BackupPassphraseConfig, @@ -195,7 +195,7 @@ pub use nethsm_sdk_rs::models::{ }; use nethsm_sdk_rs::ureq::{Agent, AgentBuilder}; use rustls::client::ClientConfig; -use rustls::crypto::{ring as tls_provider, CryptoProvider}; +use rustls::crypto::{CryptoProvider, ring as tls_provider}; use serde::{Deserialize, Serialize}; use serde_json::Value; use sha1::Sha1; @@ -203,14 +203,14 @@ use sha2::{Digest, Sha224, Sha256, Sha384, Sha512}; mod key; pub use key::{ + CryptographicKeyContext, + MIN_RSA_BIT_LENGTH, + PrivateKeyImport, + SigningKeySetup, key_type_and_mechanisms_match_signature_type, key_type_matches_length, key_type_matches_mechanisms, tls_key_type_matches_length, - CryptographicKeyContext, - PrivateKeyImport, - SigningKeySetup, - MIN_RSA_BIT_LENGTH, }; mod nethsm_sdk; @@ -229,12 +229,12 @@ pub use nethsm_sdk::{ }; mod openpgp; pub use openpgp::{ - extract_certificate as extract_openpgp_certificate, - tsk_to_private_key_import, KeyUsageFlags as OpenPgpKeyUsageFlags, OpenPgpUserId, OpenPgpUserIdList, OpenPgpVersion, + extract_certificate as extract_openpgp_certificate, + tsk_to_private_key_import, }; mod tls; @@ -388,7 +388,7 @@ impl FromStr for Url { /// # Examples /// /// ```no_run -/// use nethsm::{validate_backup, ConnectionSecurity, Credentials, NetHsm, Passphrase}; +/// use nethsm::{ConnectionSecurity, Credentials, NetHsm, Passphrase, validate_backup}; /// /// # fn main() -> testresult::TestResult { /// // create a connection with a user in the Backup role @@ -1108,12 +1108,14 @@ impl NetHsm { /// /// // N-Administrators can not set the unlock passphrase /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?; - /// assert!(nethsm - /// .set_unlock_passphrase( - /// Passphrase::new("current-unlock-passphrase".to_string()), - /// Passphrase::new("new-unlock-passphrase".to_string()), - /// ) - /// .is_err()); + /// assert!( + /// nethsm + /// .set_unlock_passphrase( + /// Passphrase::new("current-unlock-passphrase".to_string()), + /// Passphrase::new("new-unlock-passphrase".to_string()), + /// ) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -1479,17 +1481,19 @@ impl NetHsm { /// /// // N-Administrators can not get a CSR for the TLS certificate /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?; - /// assert!(nethsm - /// .get_tls_csr(DistinguishedName { - /// country_name: Some("DE".to_string()), - /// state_or_province_name: Some("Berlin".to_string()), - /// locality_name: Some("Berlin".to_string()), - /// organization_name: Some("Foobar Inc".to_string()), - /// organizational_unit_name: Some("Department of Foo".to_string()), - /// common_name: "Foobar Inc".to_string(), - /// email_address: Some("foobar@mcfooface.com".to_string()), - /// }) - /// .is_err()); + /// assert!( + /// nethsm + /// .get_tls_csr(DistinguishedName { + /// country_name: Some("DE".to_string()), + /// state_or_province_name: Some("Berlin".to_string()), + /// locality_name: Some("Berlin".to_string()), + /// organization_name: Some("Foobar Inc".to_string()), + /// organizational_unit_name: Some("Department of Foo".to_string()), + /// common_name: "Foobar Inc".to_string(), + /// email_address: Some("foobar@mcfooface.com".to_string()), + /// }) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -1561,9 +1565,11 @@ impl NetHsm { /// /// // N-Administrators can not generate a new TLS certificate /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?; - /// assert!(nethsm - /// .generate_tls_cert(TlsKeyType::Rsa, Some(4096)) - /// .is_err()); + /// assert!( + /// nethsm + /// .generate_tls_cert(TlsKeyType::Rsa, Some(4096)) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -2061,9 +2067,11 @@ impl NetHsm { /// /// // N-Administrators can not set logging configuration /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?; - /// assert!(nethsm - /// .set_logging(Ipv4Addr::new(192, 168, 1, 2), 513, LogLevel::Debug) - /// .is_err()); + /// assert!( + /// nethsm + /// .set_logging(Ipv4Addr::new(192, 168, 1, 2), 513, LogLevel::Debug) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -2143,12 +2151,14 @@ impl NetHsm { /// /// // N-Administrators can not set logging configuration /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?; - /// assert!(nethsm - /// .set_backup_passphrase( - /// Passphrase::new("new-backup-passphrase".to_string()), - /// Passphrase::new("current-backup-passphrase".to_string()), - /// ) - /// .is_err()); + /// assert!( + /// nethsm + /// .set_backup_passphrase( + /// Passphrase::new("new-backup-passphrase".to_string()), + /// Passphrase::new("current-backup-passphrase".to_string()), + /// ) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -2363,13 +2373,15 @@ impl NetHsm { /// /// // N-Administrators can not restore from backup /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?; - /// assert!(nethsm - /// .restore( - /// Passphrase::new("backup-passphrase".to_string()), - /// Utc::now(), - /// std::fs::read("nethsm.bkp")?, - /// ) - /// .is_err()); + /// assert!( + /// nethsm + /// .restore( + /// Passphrase::new("backup-passphrase".to_string()), + /// Utc::now(), + /// std::fs::read("nethsm.bkp")?, + /// ) + /// .is_err() + /// ); /// /// // R-Administrators can restore from backup /// nethsm.use_credentials(&"admin".parse()?)?; @@ -3626,12 +3638,14 @@ impl NetHsm { /// Passphrase::new("new-admin-passphrase".to_string()), /// )?; /// // the R-Administrator can not set the N-Administrator's passphrase - /// assert!(nethsm - /// .set_user_passphrase( - /// "namespace1~admin".parse()?, - /// Passphrase::new("new-admin-passphrase".to_string()), - /// ) - /// .is_err()); + /// assert!( + /// nethsm + /// .set_user_passphrase( + /// "namespace1~admin".parse()?, + /// Passphrase::new("new-admin-passphrase".to_string()), + /// ) + /// .is_err() + /// ); /// /// // the N-Administrator can set its own passphrase /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?; @@ -3640,12 +3654,14 @@ impl NetHsm { /// Passphrase::new("new-admin-passphrase".to_string()), /// )?; /// // the N-Administrator can not set the R-Administrator's passphrase - /// assert!(nethsm - /// .set_user_passphrase( - /// "admin".parse()?, - /// Passphrase::new("new-admin-passphrase".to_string()) - /// ) - /// .is_err()); + /// assert!( + /// nethsm + /// .set_user_passphrase( + /// "admin".parse()?, + /// Passphrase::new("new-admin-passphrase".to_string()) + /// ) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -3766,9 +3782,11 @@ impl NetHsm { /// // R-Administrators can add tags for system-wide users /// nethsm.add_user_tag(&"user1".parse()?, "tag1")?; /// // R-Administrators can not add tags for namespace users - /// assert!(nethsm - /// .add_user_tag(&"namespace1~user1".parse()?, "tag1") - /// .is_err()); + /// assert!( + /// nethsm + /// .add_user_tag(&"namespace1~user1".parse()?, "tag1") + /// .is_err() + /// ); /// /// // user tags in namespaces /// nethsm.use_credentials(&"namespace1~admin1".parse()?)?; @@ -5874,15 +5892,17 @@ impl NetHsm { /// /// // create an OpenPGP certificate for the key with ID "signing1" /// nethsm.use_credentials(&"operator1".parse()?)?; - /// assert!(!nethsm - /// .create_openpgp_cert( - /// &"signing1".parse()?, - /// OpenPgpKeyUsageFlags::default(), - /// "Test <test@example.org>".parse()?, - /// SystemTime::now().into(), - /// OpenPgpVersion::V4, - /// )? - /// .is_empty()); + /// assert!( + /// !nethsm + /// .create_openpgp_cert( + /// &"signing1".parse()?, + /// OpenPgpKeyUsageFlags::default(), + /// "Test <test@example.org>".parse()?, + /// SystemTime::now().into(), + /// OpenPgpVersion::V4, + /// )? + /// .is_empty() + /// ); /// # Ok(()) /// # } /// ``` @@ -5994,9 +6014,11 @@ impl NetHsm { /// /// // create OpenPGP signature /// nethsm.use_credentials(&"operator1".parse()?)?; - /// assert!(!nethsm - /// .openpgp_sign(&"signing1".parse()?, b"sample message")? - /// .is_empty()); + /// assert!( + /// !nethsm + /// .openpgp_sign(&"signing1".parse()?, b"sample message")? + /// .is_empty() + /// ); /// # Ok(()) } /// ``` /// [OpenPGP signature]: https://openpgp.dev/book/signing_data.html @@ -6101,9 +6123,11 @@ impl NetHsm { /// /// // create OpenPGP signature /// nethsm.use_credentials(&"operator1".parse()?)?; - /// assert!(!nethsm - /// .openpgp_sign_state(&"signing1".parse()?, state)? - /// .is_empty()); + /// assert!( + /// !nethsm + /// .openpgp_sign_state(&"signing1".parse()?, state)? + /// .is_empty() + /// ); /// # Ok(()) } /// ``` /// [OpenPGP signature]: https://openpgp.dev/book/signing_data.html diff --git a/nethsm/src/openpgp.rs b/nethsm/src/openpgp.rs index 73332392..5bfeba97 100644 --- a/nethsm/src/openpgp.rs +++ b/nethsm/src/openpgp.rs @@ -11,6 +11,10 @@ use base64ct::{Base64, Encoding as _}; use chrono::{DateTime, Utc}; use email_address::{EmailAddress, Options}; use pgp::{ + Deserializable, + KeyDetails, + SignedPublicKey, + SignedSecretKey, crypto::{ecc_curve::ECCCurve, hash::HashAlgorithm, public_key::PublicKeyAlgorithm}, packet::{ KeyFlags, @@ -39,20 +43,16 @@ use pgp::{ SignatureBytes, Version, }, - Deserializable, - KeyDetails, - SignedPublicKey, - SignedSecretKey, }; use picky_asn1_x509::{ - signature::EcdsaSignatureValue, AlgorithmIdentifier, DigestInfo, ShaVariant, + signature::EcdsaSignatureValue, }; use rand::prelude::{CryptoRng, Rng}; -use crate::{key_type_matches_length, KeyMechanism, KeyType, NetHsm, PrivateKeyImport}; +use crate::{KeyMechanism, KeyType, NetHsm, PrivateKeyImport, key_type_matches_length}; #[derive(Debug, thiserror::Error)] pub enum Error { @@ -356,11 +356,13 @@ impl OpenPgpUserIdList { /// ])?; /// /// // this fails because the two OpenPgpUserIds are the same - /// assert!(OpenPgpUserIdList::new(vec![ - /// "🤡 <foo@xn--rl8h.org>".parse()?, - /// "🤡 <foo@xn--rl8h.org>".parse()?, - /// ]) - /// .is_err()); + /// assert!( + /// OpenPgpUserIdList::new(vec![ + /// "🤡 <foo@xn--rl8h.org>".parse()?, + /// "🤡 <foo@xn--rl8h.org>".parse()?, + /// ]) + /// .is_err() + /// ); /// # Ok(()) /// # } /// ``` @@ -456,7 +458,7 @@ fn parse_signature(sig_type: crate::SignatureType, sig: &[u8]) -> pgp::errors::R param => { return Err(pgp::errors::Error::Unsupported(format!( "Unsupoprted key type: {param:?}" - ))) + ))); } }) } @@ -481,7 +483,7 @@ impl<'a, 'b> HsmKey<'a, 'b> { param => { return Err(pgp::errors::Error::Unsupported(format!( "Unsupported EC key type: {param:?}" - ))) + ))); } }, PublicParams::EdDSALegacy { .. } => crate::SignatureType::EdDsa, @@ -489,7 +491,7 @@ impl<'a, 'b> HsmKey<'a, 'b> { param => { return Err(pgp::errors::Error::Unsupported(format!( "Unsupported key type: {param:?}" - ))) + ))); } }) } @@ -684,7 +686,7 @@ fn hash_to_oid(hash: HashAlgorithm) -> pgp::errors::Result<AlgorithmIdentifier> hash => { return Err(pgp::errors::Error::Unsupported(format!( "Unsupported hash: {hash:?}" - ))) + ))); } })) } @@ -733,7 +735,7 @@ pub fn tsk_to_private_key_import( _ => { return Err(crate::Error::OpenPgp(Error::UnsupportedKeyFormat { public_params: Box::new(key.public_params().clone()), - })) + })); } } } else { @@ -754,7 +756,7 @@ pub fn tsk_to_private_key_import( (_, public_params) => { return Err(crate::Error::OpenPgp(Error::UnsupportedKeyFormat { public_params: Box::new(public_params.clone()), - })) + })); } }) } @@ -999,7 +1001,7 @@ fn hsm_pk_to_pgp_pk( _ => { return Err(pgp::errors::Error::Unsupported( "unsupported key type".into(), - ))? + ))?; } }) } @@ -1434,8 +1436,11 @@ mod tests { // being used. If the digest is short enough to be smaller than the curve specific field // size the digest is used as a whole. assert_eq!( - data.len(), usize::min(max_len, digest.len()), - "the data to be signed's length ({}) cannot exceed maximum length imposed by the curve ({})", data.len(), max_len + data.len(), + usize::min(max_len, digest.len()), + "the data to be signed's length ({}) cannot exceed maximum length imposed by the curve ({})", + data.len(), + max_len ); Ok(()) diff --git a/nethsm/src/tls.rs b/nethsm/src/tls.rs index 8c3f6e0e..78c042c6 100644 --- a/nethsm/src/tls.rs +++ b/nethsm/src/tls.rs @@ -74,10 +74,12 @@ impl FromStr for ConnectionSecurity { /// /// assert!(ConnectionSecurity::from_str("unsafe").is_ok()); /// assert!(ConnectionSecurity::from_str("native").is_ok()); - /// assert!(ConnectionSecurity::from_str( - /// "sha256:324f7bd1530c55cf6812ca6865445de21dfc74cf7a3bb5fae7585e849e3553b7" - /// ) - /// .is_ok()); + /// assert!( + /// ConnectionSecurity::from_str( + /// "sha256:324f7bd1530c55cf6812ca6865445de21dfc74cf7a3bb5fae7585e849e3553b7" + /// ) + /// .is_ok() + /// ); /// assert!(ConnectionSecurity::from_str("something").is_err()); /// ``` fn from_str(s: &str) -> Result<Self, Self::Err> { diff --git a/nethsm/src/user.rs b/nethsm/src/user.rs index e4a06684..2ff8caf6 100644 --- a/nethsm/src/user.rs +++ b/nethsm/src/user.rs @@ -569,13 +569,17 @@ mod tests { #[case] result: Option<()>, ) -> TestResult { if result.is_some() { - assert!(caller - .validate_namespace_access(namespace_support, target.as_ref(), role.as_ref()) - .is_ok()); + assert!( + caller + .validate_namespace_access(namespace_support, target.as_ref(), role.as_ref()) + .is_ok() + ); } else { - assert!(caller - .validate_namespace_access(namespace_support, target.as_ref(), role.as_ref()) - .is_err()) + assert!( + caller + .validate_namespace_access(namespace_support, target.as_ref(), role.as_ref()) + .is_err() + ) } Ok(()) } diff --git a/nethsm/tests/certificates.rs b/nethsm/tests/certificates.rs index 0a0e02c9..b95ca02e 100644 --- a/nethsm/tests/certificates.rs +++ b/nethsm/tests/certificates.rs @@ -1,17 +1,17 @@ use nethsm::{DistinguishedName, KeyMechanism, KeyType, NetHsm, PrivateKeyImport}; -use nethsm_tests::nethsm_with_users; -use nethsm_tests::NetHsmImage; use nethsm_tests::DEFAULT_AES_BITS; use nethsm_tests::DEFAULT_KEY_ID; use nethsm_tests::DEFAULT_OPERATOR_USER_ID; use nethsm_tests::DEFAULT_RSA_BITS; use nethsm_tests::DEFAULT_TAG; use nethsm_tests::ENC_KEY_ID; +use nethsm_tests::NetHsmImage; use nethsm_tests::OTHER_KEY_ID; use nethsm_tests::OTHER_OPERATOR_USER_ID; use nethsm_tests::OTHER_TAG; -use rsa::pkcs8::EncodePrivateKey; +use nethsm_tests::nethsm_with_users; use rsa::RsaPrivateKey; +use rsa::pkcs8::EncodePrivateKey; use rstest::rstest; use rustainers::Container; use testdir::testdir; @@ -136,9 +136,11 @@ async fn user_tags(nethsm: &NetHsm) -> TestResult { == 1 ); nethsm.delete_user_tag(&DEFAULT_OPERATOR_USER_ID.parse()?, DEFAULT_TAG)?; - assert!(nethsm - .get_user_tags(&DEFAULT_OPERATOR_USER_ID.parse()?)? - .is_empty()); + assert!( + nethsm + .get_user_tags(&DEFAULT_OPERATOR_USER_ID.parse()?)? + .is_empty() + ); nethsm.add_user_tag(&OTHER_OPERATOR_USER_ID.parse()?, OTHER_TAG)?; assert!( @@ -148,9 +150,11 @@ async fn user_tags(nethsm: &NetHsm) -> TestResult { == 1 ); nethsm.delete_user_tag(&OTHER_OPERATOR_USER_ID.parse()?, OTHER_TAG)?; - assert!(nethsm - .get_user_tags(&OTHER_OPERATOR_USER_ID.parse()?)? - .is_empty()); + assert!( + nethsm + .get_user_tags(&OTHER_OPERATOR_USER_ID.parse()?)? + .is_empty() + ); nethsm.delete_key_tag(&DEFAULT_KEY_ID.parse()?, DEFAULT_TAG)?; diff --git a/nethsm/tests/config.rs b/nethsm/tests/config.rs index 1d6a0330..d1003e0d 100644 --- a/nethsm/tests/config.rs +++ b/nethsm/tests/config.rs @@ -12,13 +12,13 @@ use nethsm::{ TlsKeyType, }; use nethsm_tests::{ - nethsm_with_users, - unprovisioned_nethsm, - update_file, - NetHsmImage, ADMIN_USER_ID, NAMESPACE1_ADMIN_USER_ID, + NetHsmImage, UNLOCK_PASSPHRASE, + nethsm_with_users, + unprovisioned_nethsm, + update_file, }; use rstest::rstest; use rustainers::Container; @@ -66,9 +66,11 @@ async fn tls_cert( // N-Administrators can not generate a TLS cert nethsm.use_credentials(&NAMESPACE1_ADMIN_USER_ID.parse()?)?; - assert!(nethsm - .generate_tls_cert(TlsKeyType::Rsa, Some(4096)) - .is_err()); + assert!( + nethsm + .generate_tls_cert(TlsKeyType::Rsa, Some(4096)) + .is_err() + ); nethsm.use_credentials(&ADMIN_USER_ID.parse()?)?; nethsm.generate_tls_cert(TlsKeyType::Rsa, Some(4096))?; @@ -82,17 +84,19 @@ async fn tls_cert( // N-Administrators can not a TLS CSR nethsm.use_credentials(&NAMESPACE1_ADMIN_USER_ID.parse()?)?; - assert!(nethsm - .get_tls_csr(DistinguishedName { - country_name: Some("DE".to_string()), - state_or_province_name: Some("Berlin".to_string()), - locality_name: Some("Berlin".to_string()), - organization_name: Some("Foobar Inc".to_string()), - organizational_unit_name: Some("Department of Foo".to_string()), - common_name: "Foobar Inc".to_string(), - email_address: Some("foobar@mcfooface.com".to_string()), - }) - .is_err()); + assert!( + nethsm + .get_tls_csr(DistinguishedName { + country_name: Some("DE".to_string()), + state_or_province_name: Some("Berlin".to_string()), + locality_name: Some("Berlin".to_string()), + organization_name: Some("Foobar Inc".to_string()), + organizational_unit_name: Some("Department of Foo".to_string()), + common_name: "Foobar Inc".to_string(), + email_address: Some("foobar@mcfooface.com".to_string()), + }) + .is_err() + ); nethsm.use_credentials(&ADMIN_USER_ID.parse()?)?; let csr = nethsm.get_tls_csr(DistinguishedName { @@ -129,13 +133,15 @@ async fn network( // N-Administrators can neither get nor set network settings nethsm.use_credentials(&NAMESPACE1_ADMIN_USER_ID.parse()?)?; assert!(nethsm.get_network().is_err()); - assert!(nethsm - .set_network(NetworkConfig::new( - ip_address.clone(), - "255.255.255.0".to_string(), - "0.0.0.0".to_string(), - )) - .is_err()); + assert!( + nethsm + .set_network(NetworkConfig::new( + ip_address.clone(), + "255.255.255.0".to_string(), + "0.0.0.0".to_string(), + )) + .is_err() + ); // R-Administrators can get and set network settings nethsm.use_credentials(&ADMIN_USER_ID.parse()?)?; @@ -201,12 +207,14 @@ async fn set_unlock_passphrase( )?; // N-Administrators can not set the unlock passphrase nethsm.use_credentials(&NAMESPACE1_ADMIN_USER_ID.parse()?)?; - assert!(nethsm - .set_unlock_passphrase( - Passphrase::new(UNLOCK_PASSPHRASE.to_string()), - Passphrase::new(new_unlock_passphrase.to_string()), - ) - .is_err()); + assert!( + nethsm + .set_unlock_passphrase( + Passphrase::new(UNLOCK_PASSPHRASE.to_string()), + Passphrase::new(new_unlock_passphrase.to_string()), + ) + .is_err() + ); Ok(()) } @@ -241,12 +249,14 @@ async fn set_backup_passphrase( Passphrase::new(new_backup_passphrase.to_string()), )?; // the passphrase is too short! - assert!(nethsm - .set_backup_passphrase( - Passphrase::new(new_backup_passphrase.to_string()), - Passphrase::new(initial_passphrase.to_string()), - ) - .is_err()); + assert!( + nethsm + .set_backup_passphrase( + Passphrase::new(new_backup_passphrase.to_string()), + Passphrase::new(initial_passphrase.to_string()), + ) + .is_err() + ); Ok(()) } diff --git a/nethsm/tests/encryption.rs b/nethsm/tests/encryption.rs index 5b46f49f..26ed63de 100644 --- a/nethsm/tests/encryption.rs +++ b/nethsm/tests/encryption.rs @@ -1,17 +1,17 @@ use nethsm::Credentials; use nethsm::Passphrase; use nethsm::{DecryptMode, EncryptMode, NetHsm}; -use nethsm_tests::nethsm_with_keys; -use nethsm_tests::NetHsmImage; use nethsm_tests::ENC_KEY_ID; use nethsm_tests::ENC_OPERATOR_USER_ID; use nethsm_tests::ENC_OPERATOR_USER_PASSPHRASE; +use nethsm_tests::NetHsmImage; use nethsm_tests::OTHER_KEY_ID; use nethsm_tests::OTHER_OPERATOR_USER_ID; use nethsm_tests::OTHER_OPERATOR_USER_PASSPHRASE; -use rsa::pkcs8::DecodePublicKey; +use nethsm_tests::nethsm_with_keys; use rsa::Pkcs1v15Encrypt; use rsa::RsaPublicKey; +use rsa::pkcs8::DecodePublicKey; use rstest::rstest; use rustainers::Container; use testresult::TestResult; diff --git a/nethsm/tests/health.rs b/nethsm/tests/health.rs index 3f04b71d..62fae744 100644 --- a/nethsm/tests/health.rs +++ b/nethsm/tests/health.rs @@ -1,5 +1,5 @@ use nethsm::{NetHsm, SystemState}; -use nethsm_tests::{nethsm_with_users, unprovisioned_nethsm, NetHsmImage}; +use nethsm_tests::{NetHsmImage, nethsm_with_users, unprovisioned_nethsm}; use rstest::rstest; use rustainers::Container; use testresult::TestResult; diff --git a/nethsm/tests/keys.rs b/nethsm/tests/keys.rs index b0155bf4..1f822f13 100644 --- a/nethsm/tests/keys.rs +++ b/nethsm/tests/keys.rs @@ -3,8 +3,6 @@ use nethsm::NamespaceId; use nethsm::PrivateKeyImport; use nethsm::UserId; use nethsm::{KeyMechanism, KeyType, NetHsm}; -use nethsm_tests::nethsm_with_users; -use nethsm_tests::NetHsmImage; use nethsm_tests::ADMIN_USER_ID; use nethsm_tests::DEFAULT_AES_BITS; use nethsm_tests::DEFAULT_OPERATOR_USER_ID; @@ -14,6 +12,8 @@ use nethsm_tests::NAMESPACE1_ADMIN_USER_ID; use nethsm_tests::NAMESPACE1_OPERATOR_USER_ID; use nethsm_tests::NAMESPACE2_ADMIN_USER_ID; use nethsm_tests::NAMESPACE2_OPERATOR_USER_ID; +use nethsm_tests::NetHsmImage; +use nethsm_tests::nethsm_with_users; use rstest::{fixture, rstest}; use rustainers::Container; use testresult::TestResult; @@ -148,18 +148,26 @@ async fn generate_keys( nethsm.use_credentials(&admin_user_id)?; // R-Administrator is unable to add or delete namespace user tags - assert!(nethsm - .add_user_tag(&namespace1_operator_user_id, "test") - .is_err()); - assert!(nethsm - .delete_user_tag(&namespace1_operator_user_id, &ns1_tag) - .is_err()); - assert!(nethsm - .add_user_tag(&namespace2_operator_user_id, "test") - .is_err()); - assert!(nethsm - .delete_user_tag(&namespace2_operator_user_id, &ns2_tag) - .is_err()); + assert!( + nethsm + .add_user_tag(&namespace1_operator_user_id, "test") + .is_err() + ); + assert!( + nethsm + .delete_user_tag(&namespace1_operator_user_id, &ns1_tag) + .is_err() + ); + assert!( + nethsm + .add_user_tag(&namespace2_operator_user_id, "test") + .is_err() + ); + assert!( + nethsm + .delete_user_tag(&namespace2_operator_user_id, &ns2_tag) + .is_err() + ); // R-Administrator is able to see namespace user tags println!( "namespace1 operator tags: {:?}", diff --git a/nethsm/tests/locking.rs b/nethsm/tests/locking.rs index c64676d4..d082461a 100644 --- a/nethsm/tests/locking.rs +++ b/nethsm/tests/locking.rs @@ -1,10 +1,10 @@ use nethsm::{NetHsm, Passphrase, SystemState, UserId}; use nethsm_tests::{ - nethsm_with_users, - NetHsmImage, ADMIN_USER_ID, NAMESPACE1_ADMIN_USER_ID, + NetHsmImage, UNLOCK_PASSPHRASE, + nethsm_with_users, }; use rstest::rstest; use rustainers::Container; diff --git a/nethsm/tests/metrics.rs b/nethsm/tests/metrics.rs index ed9f523f..797b8778 100644 --- a/nethsm/tests/metrics.rs +++ b/nethsm/tests/metrics.rs @@ -1,5 +1,5 @@ use nethsm::NetHsm; -use nethsm_tests::{nethsm_with_users, NetHsmImage, METRICS_USER_ID}; +use nethsm_tests::{METRICS_USER_ID, NetHsmImage, nethsm_with_users}; use rstest::rstest; use rustainers::Container; use testresult::TestResult; diff --git a/nethsm/tests/namespace.rs b/nethsm/tests/namespace.rs index 09dec8d9..4fc2f9bf 100644 --- a/nethsm/tests/namespace.rs +++ b/nethsm/tests/namespace.rs @@ -1,5 +1,5 @@ use nethsm::NetHsm; -use nethsm_tests::{nethsm_with_users, NetHsmImage}; +use nethsm_tests::{NetHsmImage, nethsm_with_users}; use rstest::rstest; use rustainers::Container; use testresult::TestResult; diff --git a/nethsm/tests/provisioning.rs b/nethsm/tests/provisioning.rs index fadfd91c..b19ec2ac 100644 --- a/nethsm/tests/provisioning.rs +++ b/nethsm/tests/provisioning.rs @@ -4,11 +4,11 @@ use chrono::Utc; use nethsm::Credentials; use nethsm::Passphrase; use nethsm::{NetHsm, SystemState}; -use nethsm_tests::unprovisioned_nethsm; -use nethsm_tests::NetHsmImage; use nethsm_tests::ADMIN_USER_ID; use nethsm_tests::ADMIN_USER_PASSPHRASE; +use nethsm_tests::NetHsmImage; use nethsm_tests::UNLOCK_PASSPHRASE; +use nethsm_tests::unprovisioned_nethsm; use rstest::rstest; use rustainers::Container; use testresult::TestResult; diff --git a/nethsm/tests/random.rs b/nethsm/tests/random.rs index 8c45f74d..81ef0ce8 100644 --- a/nethsm/tests/random.rs +++ b/nethsm/tests/random.rs @@ -1,10 +1,10 @@ use nethsm::Credentials; use nethsm::NetHsm; use nethsm::Passphrase; -use nethsm_tests::nethsm_with_users; -use nethsm_tests::NetHsmImage; use nethsm_tests::DEFAULT_OPERATOR_USER_ID; use nethsm_tests::DEFAULT_OPERATOR_USER_PASSPHRASE; +use nethsm_tests::NetHsmImage; +use nethsm_tests::nethsm_with_users; use rstest::rstest; use rustainers::Container; use testresult::TestResult; diff --git a/nethsm/tests/signing.rs b/nethsm/tests/signing.rs index 46d017a2..13f832bf 100644 --- a/nethsm/tests/signing.rs +++ b/nethsm/tests/signing.rs @@ -1,19 +1,19 @@ use nethsm::Credentials; use nethsm::Passphrase; use nethsm::{NetHsm, SignatureType}; -use nethsm_tests::nethsm_with_keys; -use nethsm_tests::NetHsmImage; use nethsm_tests::DEFAULT_KEY_ID; use nethsm_tests::DEFAULT_OPERATOR_USER_ID; use nethsm_tests::DEFAULT_OPERATOR_USER_PASSPHRASE; +use nethsm_tests::NetHsmImage; use nethsm_tests::OTHER_KEY_ID; use nethsm_tests::OTHER_OPERATOR_USER_ID; use nethsm_tests::OTHER_OPERATOR_USER_PASSPHRASE; +use nethsm_tests::nethsm_with_keys; +use rsa::RsaPublicKey; use rsa::pkcs1v15::VerifyingKey; use rsa::pkcs8::DecodePublicKey; use rsa::sha2::Sha256; use rsa::signature::Verifier; -use rsa::RsaPublicKey; use rstest::rstest; use rustainers::Container; use testresult::TestResult; @@ -73,7 +73,10 @@ async fn signing( let pubkey = RsaPublicKey::from_public_key_pem(&pubkey)?; let verifying_key: VerifyingKey<Sha256> = VerifyingKey::new_unprefixed(pubkey); let signature_parsed = rsa::pkcs1v15::Signature::try_from(signature.as_slice())?; - println!("A signature created using an RSA pubkey for which the NetHSM provides the private key: {:?}", signature_parsed); + println!( + "A signature created using an RSA pubkey for which the NetHSM provides the private key: {:?}", + signature_parsed + ); verifying_key.verify(MESSAGE, &signature_parsed)?; Ok(()) diff --git a/nethsm/tests/system.rs b/nethsm/tests/system.rs index 9ddbfe50..2564cada 100644 --- a/nethsm/tests/system.rs +++ b/nethsm/tests/system.rs @@ -1,11 +1,11 @@ use chrono::Utc; use nethsm::{NetHsm, Passphrase, UserId}; use nethsm_tests::{ - nethsm_with_users, - unprovisioned_nethsm, - NetHsmImage, ADMIN_USER_ID, BACKUP_USER_ID, + NetHsmImage, + nethsm_with_users, + unprovisioned_nethsm, }; use rstest::rstest; use rustainers::Container; diff --git a/nethsm/tests/users.rs b/nethsm/tests/users.rs index 4392663a..bbf5eb12 100644 --- a/nethsm/tests/users.rs +++ b/nethsm/tests/users.rs @@ -2,8 +2,6 @@ use nethsm::NamespaceId; use nethsm::Passphrase; use nethsm::UserId; use nethsm::{NetHsm, UserRole}; -use nethsm_tests::provisioned_nethsm; -use nethsm_tests::NetHsmImage; use nethsm_tests::ADMIN_USER_ID; use nethsm_tests::DEFAULT_OPERATOR_USER_PASSPHRASE; use nethsm_tests::DEFAULT_OPERATOR_USER_REAL_NAME; @@ -21,9 +19,11 @@ use nethsm_tests::NAMESPACE2_ADMIN_USER_PASSPHRASE; use nethsm_tests::NAMESPACE2_OPERATOR_REAL_NAME; use nethsm_tests::NAMESPACE2_OPERATOR_USER_ID; use nethsm_tests::NAMESPACE2_OPERATOR_USER_PASSPHRASE; +use nethsm_tests::NetHsmImage; use nethsm_tests::OTHER_OPERATOR_USER_ID; use nethsm_tests::OTHER_OPERATOR_USER_PASSPHRASE; use nethsm_tests::OTHER_OPERATOR_USER_REAL_NAME; +use nethsm_tests::provisioned_nethsm; use rstest::rstest; use rustainers::Container; use testresult::TestResult; @@ -148,14 +148,16 @@ async fn create_users_in_namespaces( // add namespace1 assert_eq!(nethsm.get_users()?.len(), 1); // R-Administrators can add Administrator users for namespaces that do not yet exist - assert!(nethsm - .add_user( - NAMESPACE1_ADMIN_REAL_NAME.to_string(), - UserRole::Administrator, - Passphrase::new(NAMESPACE1_ADMIN_USER_PASSPHRASE.to_string()), - Some(namespace1_admin_user_id.clone()), - ) - .is_ok()); + assert!( + nethsm + .add_user( + NAMESPACE1_ADMIN_REAL_NAME.to_string(), + UserRole::Administrator, + Passphrase::new(NAMESPACE1_ADMIN_USER_PASSPHRASE.to_string()), + Some(namespace1_admin_user_id.clone()), + ) + .is_ok() + ); println!( "Created {} admin user: {}", &namespace1, &namespace1_admin_user_id @@ -166,14 +168,16 @@ async fn create_users_in_namespaces( nethsm.get_user(&namespace1_admin_user_id)? ); // R-Administrators can add Operator users for namespaces that do not yet exist - assert!(nethsm - .add_user( - NAMESPACE1_OPERATOR_REAL_NAME.to_string(), - UserRole::Operator, - Passphrase::new(NAMESPACE1_OPERATOR_USER_PASSPHRASE.to_string()), - Some(namespace1_operator_user_id.clone()), - ) - .is_ok()); + assert!( + nethsm + .add_user( + NAMESPACE1_OPERATOR_REAL_NAME.to_string(), + UserRole::Operator, + Passphrase::new(NAMESPACE1_OPERATOR_USER_PASSPHRASE.to_string()), + Some(namespace1_operator_user_id.clone()), + ) + .is_ok() + ); println!( "Created {} Operator user: {}", &namespace1, &namespace1_operator_user_id @@ -205,43 +209,51 @@ async fn create_users_in_namespaces( nethsm.get_user(&namespace2_admin_user_id)? ); // R-Administrators can not add users in the Backup role to a not yet existing namespace - assert!(nethsm - .add_user( - NAMESPACE2_BACKUP_REAL_NAME.to_string(), - UserRole::Backup, - Passphrase::new(NAMESPACE2_BACKUP_USER_PASSPHRASE.to_string()), - Some(namespace2_backup_user_id.clone()), - ) - .is_err()); + assert!( + nethsm + .add_user( + NAMESPACE2_BACKUP_REAL_NAME.to_string(), + UserRole::Backup, + Passphrase::new(NAMESPACE2_BACKUP_USER_PASSPHRASE.to_string()), + Some(namespace2_backup_user_id.clone()), + ) + .is_err() + ); // R-Administrators can not add users in the Metrics role to a not yet existing namespace - assert!(nethsm - .add_user( - NAMESPACE2_METRICS_REAL_NAME.to_string(), - UserRole::Metrics, - Passphrase::new(NAMESPACE2_METRICS_USER_PASSPHRASE.to_string()), - Some(namespace2_metrics_user_id.clone()), - ) - .is_err()); + assert!( + nethsm + .add_user( + NAMESPACE2_METRICS_REAL_NAME.to_string(), + UserRole::Metrics, + Passphrase::new(NAMESPACE2_METRICS_USER_PASSPHRASE.to_string()), + Some(namespace2_metrics_user_id.clone()), + ) + .is_err() + ); nethsm.add_namespace(&namespace2)?; println!("Namespaces {:?}", nethsm.get_namespaces()?); assert_eq!(nethsm.get_namespaces()?.len(), 2); // R-Administrators can not change the passphrase for a namespace user - assert!(nethsm - .set_user_passphrase( - namespace1_admin_user_id.clone(), - Passphrase::new("some-other-passphrase".to_string()), - ) - .is_err()); + assert!( + nethsm + .set_user_passphrase( + namespace1_admin_user_id.clone(), + Passphrase::new("some-other-passphrase".to_string()), + ) + .is_err() + ); // R-Administrators can not add a user to a namespace (but their own) - assert!(nethsm - .add_user( - NAMESPACE1_OPERATOR_REAL_NAME.to_string(), - UserRole::Operator, - Passphrase::new(NAMESPACE1_OPERATOR_USER_PASSPHRASE.to_string()), - Some(namespace1_operator_user_id.clone()), - ) - .is_err()); + assert!( + nethsm + .add_user( + NAMESPACE1_OPERATOR_REAL_NAME.to_string(), + UserRole::Operator, + Passphrase::new(NAMESPACE1_OPERATOR_USER_PASSPHRASE.to_string()), + Some(namespace1_operator_user_id.clone()), + ) + .is_err() + ); // namespace1 nethsm.use_credentials(&namespace1_admin_user_id)?; @@ -256,14 +268,16 @@ async fn create_users_in_namespaces( // N-Administrators can not get namespaces assert!(nethsm.get_namespaces().is_err()); // N-Administrators can not add users in other namespaces - assert!(nethsm - .add_user( - NAMESPACE2_OPERATOR_REAL_NAME.to_string(), - UserRole::Operator, - Passphrase::new(NAMESPACE2_OPERATOR_USER_PASSPHRASE.to_string()), - Some(namespace2_operator_user_id.clone()), - ) - .is_err()); + assert!( + nethsm + .add_user( + NAMESPACE2_OPERATOR_REAL_NAME.to_string(), + UserRole::Operator, + Passphrase::new(NAMESPACE2_OPERATOR_USER_PASSPHRASE.to_string()), + Some(namespace2_operator_user_id.clone()), + ) + .is_err() + ); // N-Administrators can delete users in their own namespace assert!(nethsm.delete_user(&namespace1_operator_user_id).is_ok()); assert_eq!(nethsm.get_users()?.len(), 1); @@ -271,32 +285,38 @@ async fn create_users_in_namespaces( // namespace2 nethsm.use_credentials(&namespace2_admin_user_id)?; // N-Administrators can add users in the Operator role in their own namespace - assert!(nethsm - .add_user( - NAMESPACE2_OPERATOR_REAL_NAME.to_string(), - UserRole::Operator, - Passphrase::new(NAMESPACE2_OPERATOR_USER_PASSPHRASE.to_string()), - Some(namespace2_operator_user_id.clone()), - ) - .is_ok()); + assert!( + nethsm + .add_user( + NAMESPACE2_OPERATOR_REAL_NAME.to_string(), + UserRole::Operator, + Passphrase::new(NAMESPACE2_OPERATOR_USER_PASSPHRASE.to_string()), + Some(namespace2_operator_user_id.clone()), + ) + .is_ok() + ); // N-Administrators can not add users in the Backup role to their own namespace - assert!(nethsm - .add_user( - NAMESPACE2_BACKUP_REAL_NAME.to_string(), - UserRole::Backup, - Passphrase::new(NAMESPACE2_BACKUP_USER_PASSPHRASE.to_string()), - Some(namespace2_backup_user_id.clone()), - ) - .is_err()); + assert!( + nethsm + .add_user( + NAMESPACE2_BACKUP_REAL_NAME.to_string(), + UserRole::Backup, + Passphrase::new(NAMESPACE2_BACKUP_USER_PASSPHRASE.to_string()), + Some(namespace2_backup_user_id.clone()), + ) + .is_err() + ); // N-Administrators can not add users in the Metrics role to their own namespace - assert!(nethsm - .add_user( - NAMESPACE2_METRICS_REAL_NAME.to_string(), - UserRole::Metrics, - Passphrase::new(NAMESPACE2_METRICS_USER_PASSPHRASE.to_string()), - Some(namespace2_metrics_user_id.clone()), - ) - .is_err()); + assert!( + nethsm + .add_user( + NAMESPACE2_METRICS_REAL_NAME.to_string(), + UserRole::Metrics, + Passphrase::new(NAMESPACE2_METRICS_USER_PASSPHRASE.to_string()), + Some(namespace2_metrics_user_id.clone()), + ) + .is_err() + ); println!("{:?}", nethsm.get_users()?); // N-Administrators can add users without specifying a User ID and the newly created user will // inherit their namespace diff --git a/rustfmt.toml b/rustfmt.toml index 82b6a51e..bafc0872 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -3,4 +3,5 @@ format_code_in_doc_comments = true group_imports = "StdExternalCrate" imports_layout = "HorizontalVertical" reorder_imports = true +style_edition = "2024" wrap_comments = true diff --git a/signstar-configure-build/src/cli.rs b/signstar-configure-build/src/cli.rs index 42d42398..4f1808bd 100644 --- a/signstar-configure-build/src/cli.rs +++ b/signstar-configure-build/src/cli.rs @@ -1,15 +1,15 @@ -use clap::{crate_name, Parser}; +use clap::{Parser, crate_name}; use strum::VariantNames; use crate::{ ConfigPath, - SshForceCommand, DEFAULT_CONFIG_FILE, ETC_OVERRIDE_CONFIG_FILE, HOME_BASE_DIR, RUN_OVERRIDE_CONFIG_FILE, - SSHD_DROPIN_CONFIG_DIR, SSH_AUTHORIZED_KEY_BASE_DIR, + SSHD_DROPIN_CONFIG_DIR, + SshForceCommand, USR_LOCAL_OVERRIDE_CONFIG_FILE, }; diff --git a/signstar-configure-build/src/lib.rs b/signstar-configure-build/src/lib.rs index c099a664..219fec9c 100644 --- a/signstar-configure-build/src/lib.rs +++ b/signstar-configure-build/src/lib.rs @@ -2,7 +2,7 @@ use std::{ fs::File, io::Write, path::{Path, PathBuf}, - process::{id, Command, ExitStatus}, + process::{Command, ExitStatus, id}, str::FromStr, }; @@ -27,7 +27,9 @@ pub enum Error { Config(#[from] nethsm_config::Error), /// A [`Command`] exited unsuccessfully - #[error("The command exited with non-zero status code (\"{exit_status}\") and produced the following output on stderr:\n{stderr}")] + #[error( + "The command exited with non-zero status code (\"{exit_status}\") and produced the following output on stderr:\n{stderr}" + )] CommandNonZero { exit_status: ExitStatus, stderr: String, @@ -38,7 +40,9 @@ pub enum Error { FailedU32ToUsizeConversion, /// There is no SSH ForceCommand defined for a [`UserMapping`] - #[error("No SSH ForceCommand defined for user mapping (NetHSM users: {nethsm_users:?}, system user: {system_user})")] + #[error( + "No SSH ForceCommand defined for user mapping (NetHSM users: {nethsm_users:?}, system user: {system_user})" + )] NoForceCommandForMapping { nethsm_users: Vec<String>, system_user: String, diff --git a/signstar-configure-build/src/main.rs b/signstar-configure-build/src/main.rs index 96a6a16a..ce5e3ecc 100644 --- a/signstar-configure-build/src/main.rs +++ b/signstar-configure-build/src/main.rs @@ -1,10 +1,10 @@ -use clap::{crate_version, Parser}; +use clap::{Parser, crate_version}; use nethsm_config::{ConfigInteractivity, ConfigSettings, HermeticParallelConfig}; use signstar_configure_build::{ - cli::{Cli, BIN_NAME}, + Error, + cli::{BIN_NAME, Cli}, create_system_users, ensure_root, - Error, }; fn main() -> Result<(), Error> { diff --git a/signstar-request-signature/src/lib.rs b/signstar-request-signature/src/lib.rs index 0513fb93..5cbb4c80 100644 --- a/signstar-request-signature/src/lib.rs +++ b/signstar-request-signature/src/lib.rs @@ -7,8 +7,8 @@ use std::collections::HashMap; use semver::Version; use serde::{Deserialize, Serialize}; use serde_json::Value; -use sha2::digest::crypto_common::hazmat::SerializableState; pub use sha2::Sha512; +use sha2::digest::crypto_common::hazmat::SerializableState; pub mod cli; diff --git a/signstar-request-signature/src/main.rs b/signstar-request-signature/src/main.rs index ed028f20..baa7c0ce 100644 --- a/signstar-request-signature/src/main.rs +++ b/signstar-request-signature/src/main.rs @@ -4,7 +4,7 @@ use clap::Parser; use rand::Rng; use serde_json::Value; use sha2::Digest; -use signstar_request_signature::{cli::Cli, Request, Required, SignatureRequestOutput}; +use signstar_request_signature::{Request, Required, SignatureRequestOutput, cli::Cli}; fn main() -> Result<(), Box<dyn std::error::Error>> { let args = Cli::parse(); -- GitLab