diff --git a/cryptoki/src/error/rv.rs b/cryptoki/src/error/rv.rs index 32b74a5c..14a0e8df 100644 --- a/cryptoki/src/error/rv.rs +++ b/cryptoki/src/error/rv.rs @@ -8,7 +8,7 @@ use super::{Error, Result, RvError}; use cryptoki_sys::*; use log::error; -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] /// Return value of a PKCS11 function pub enum Rv { /// The function exited successfully @@ -116,13 +116,14 @@ impl From for Rv { CKR_PIN_TOO_WEAK => Rv::Error(RvError::PinTooWeak), CKR_PUBLIC_KEY_INVALID => Rv::Error(RvError::PublicKeyInvalid), CKR_FUNCTION_REJECTED => Rv::Error(RvError::FunctionRejected), - CKR_VENDOR_DEFINED => Rv::Error(RvError::VendorDefined), + // Section 3.6 of v3.1: "Return values CKR_VENDOR_DEFINED and above are permanently reserved for token vendors." + CKR_VENDOR_DEFINED..=CK_ULONG::MAX => Rv::Error(RvError::VendorDefined(ck_rv)), other => { error!( - "Can not find a corresponding error for {}, converting to GeneralError.", + "Can not find a corresponding error for {}, converting to UnknownErrorCode.", other ); - Rv::Error(RvError::GeneralError) + Rv::Error(RvError::UnknownErrorCode(other)) } } } @@ -137,3 +138,33 @@ impl Rv { } } } + +#[cfg(test)] +mod test { + use super::{Rv, RvError}; + use cryptoki_sys::*; + + #[test] + fn vendor_defined_exact() { + let code = CKR_VENDOR_DEFINED; + let actual = Rv::from(code); + let expected = Rv::Error(RvError::VendorDefined(code)); + assert_eq!(actual, expected); + } + + #[test] + fn vendor_defined_higher() { + let code = CKR_VENDOR_DEFINED + 42; + let actual = Rv::from(code); + let expected = Rv::Error(RvError::VendorDefined(code)); + assert_eq!(actual, expected); + } + + #[test] + fn unknown_code() { + let code = CKR_VENDOR_DEFINED - 42; + let actual = Rv::from(code); + let expected = Rv::Error(RvError::UnknownErrorCode(code)); + assert_eq!(actual, expected); + } +} diff --git a/cryptoki/src/error/rv_error.rs b/cryptoki/src/error/rv_error.rs index 61af8d03..36ba1b9c 100644 --- a/cryptoki/src/error/rv_error.rs +++ b/cryptoki/src/error/rv_error.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 //! Function types +use cryptoki_sys::CK_RV; use std::fmt; #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -193,8 +194,10 @@ pub enum RvError { PublicKeyInvalid, /// The signature request is rejected by the user. FunctionRejected, - /// CKR_VENDOR_DEFINED - VendorDefined, + /// A vendor defined error code, CKR_VENDOR_DEFINED and above. + VendorDefined(CK_RV), + /// An unknown error code + UnknownErrorCode(CK_RV), } impl fmt::Display for RvError { @@ -293,7 +296,8 @@ impl fmt::Display for RvError { RvError::PinTooWeak => write!(f, "The specified PIN is too weak so that it could be easy to guess. If the PIN is too short, CKR_PIN_LEN_RANGE should be returned instead. This return code only applies to functions which attempt to set a PIN."), RvError::PublicKeyInvalid => write!(f, "The public key fails a public key validation. For example, an EC public key fails the public key validation specified in Section 5.2.2 of ANSI X9.62. This error code may be returned by C_CreateObject, when the public key is created, or by C_VerifyInit or C_VerifyRecoverInit, when the public key is used. It may also be returned by C_DeriveKey, in preference to CKR_MECHANISM_PARAM_INVALID, if the other party's public key specified in the mechanism's parameters is invalid."), RvError::FunctionRejected => write!(f, "The signature request is rejected by the user."), - RvError::VendorDefined => write!(f, "CKR_VENDOR_DEFINED"), + RvError::VendorDefined(code) => write!(f, "CKR_VENDOR_DEFINED({code:#x})"), + RvError::UnknownErrorCode(code) => write!(f, "Unknown error code: {code:#x}"), } } } diff --git a/cryptoki/src/object.rs b/cryptoki/src/object.rs index a8c30e1a..b1c00d3d 100644 --- a/cryptoki/src/object.rs +++ b/cryptoki/src/object.rs @@ -14,8 +14,6 @@ use std::fmt::Formatter; use std::mem::size_of; use std::ops::Deref; -const MAX_CU_ULONG: CK_ULONG = !0; - #[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] #[non_exhaustive] /// Type of an attribute @@ -261,7 +259,7 @@ impl AttributeType { CKA_DERIVE_TEMPLATE => String::from(stringify!(CKA_DERIVE_TEMPLATE)), CKA_ALLOWED_MECHANISMS => String::from(stringify!(CKA_ALLOWED_MECHANISMS)), CKA_UNIQUE_ID => String::from(stringify!(CKA_UNIQUE_ID)), - CKA_VENDOR_DEFINED..=MAX_CU_ULONG => { + CKA_VENDOR_DEFINED..=CK_ULONG::MAX => { format!("{}_{}", stringify!(CKA_VENDOR_DEFINED), val) } _ => format!("unknown ({val:08x})"), @@ -409,7 +407,7 @@ impl TryFrom for AttributeType { CKA_VERIFY_RECOVER => Ok(AttributeType::VerifyRecover), CKA_WRAP => Ok(AttributeType::Wrap), CKA_WRAP_WITH_TRUSTED => Ok(AttributeType::WrapWithTrusted), - CKA_VENDOR_DEFINED..=MAX_CU_ULONG => Ok(AttributeType::VendorDefined(attribute_type)), + CKA_VENDOR_DEFINED..=CK_ULONG::MAX => Ok(AttributeType::VendorDefined(attribute_type)), attr_type => { error!("Attribute type {} not supported.", attr_type); Err(Error::NotSupported) @@ -1296,7 +1294,7 @@ impl KeyType { CKK_EC_EDWARDS => String::from(stringify!(CKK_EC_EDWARDS)), CKK_EC_MONTGOMERY => String::from(stringify!(CKK_EC_MONTGOMERY)), CKK_HKDF => String::from(stringify!(CKK_HKDF)), - CKK_VENDOR_DEFINED..=MAX_CU_ULONG => String::from(stringify!(key_type)), + CKK_VENDOR_DEFINED..=CK_ULONG::MAX => String::from(stringify!(key_type)), _ => format!("unknown ({key_type:08x})"), } } @@ -1371,7 +1369,7 @@ impl TryFrom for KeyType { CKK_EC_EDWARDS => Ok(KeyType::EC_EDWARDS), CKK_EC_MONTGOMERY => Ok(KeyType::EC_MONTGOMERY), CKK_HKDF => Ok(KeyType::HKDF), - CKK_VENDOR_DEFINED..=MAX_CU_ULONG => KeyType::new_vendor_defined(key_type), + CKK_VENDOR_DEFINED..=CK_ULONG::MAX => KeyType::new_vendor_defined(key_type), _ => { error!("Key type {} is not supported.", key_type); Err(Error::NotSupported)