Skip to content

Commit 1b35300

Browse files
simo5Gemini
andcommitted
Add Profile and Mechanism objects support
Implement `ProfileFactory` and `MechanismFactory` to support `CKO_PROFILE` and `CKO_MECHANISM` classes. Move `CKA_UNIQUE_ID` to common attributes as it applies to these new classes as well. Update object creation to only apply the `CKA_LOCAL` default to key objects, allow matching `CKA_CLASS` attributes in templates, and return `CKR_TEMPLATE_INCONSISTENT` for unsupported objects. Co-authored-by: Gemini <gemini@google.com> Signed-off-by: Simo Sorce <simo@redhat.com>
1 parent aee7741 commit 1b35300

File tree

1 file changed

+130
-10
lines changed

1 file changed

+130
-10
lines changed

src/object.rs

Lines changed: 130 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,9 @@ pub trait ObjectFactory: Debug + Send + Sync {
604604
attrs.push(attr_element!(
605605
CKA_CLASS; OAFlags::RequiredOnCreate;
606606
Attribute::from_ulong; val 0));
607+
attrs.push(attr_element!(
608+
CKA_UNIQUE_ID; OAFlags::NeverSettable | OAFlags::Unchangeable;
609+
Attribute::from_string; val String::new()));
607610
}
608611

609612
/// Adds the storage object attributes defined in the spec
@@ -628,9 +631,6 @@ pub trait ObjectFactory: Debug + Send + Sync {
628631
attrs.push(attr_element!(
629632
CKA_DESTROYABLE; OAFlags::Defval; Attribute::from_bool;
630633
val true));
631-
attrs.push(attr_element!(
632-
CKA_UNIQUE_ID; OAFlags::NeverSettable | OAFlags::Unchangeable;
633-
Attribute::from_string; val String::new()));
634634
}
635635

636636
/// Default object creation function
@@ -646,8 +646,13 @@ pub trait ObjectFactory: Debug + Send + Sync {
646646
OAFlags::RequiredOnCreate,
647647
)?;
648648

649-
// default key attributes on CreateObject
650-
obj.set_attr(Attribute::from_bool(CKA_LOCAL, false))?;
649+
match obj.get_class() {
650+
CKO_PUBLIC_KEY | CKO_PRIVATE_KEY | CKO_SECRET_KEY => {
651+
// default key attributes on CreateObject
652+
obj.set_attr(Attribute::from_bool(CKA_LOCAL, false))?;
653+
}
654+
_ => (),
655+
}
651656

652657
match obj.get_class() {
653658
CKO_PRIVATE_KEY | CKO_SECRET_KEY => {
@@ -796,8 +801,11 @@ pub trait ObjectFactory: Debug + Send + Sync {
796801
}
797802
/* duplicate? */
798803
match obj.get_attr(ck_attr.type_) {
799-
Some(a) => {
800-
if a.get_type() != CKA_CLASS {
804+
Some(oa) => {
805+
if oa.get_type() != CKA_CLASS
806+
|| (oa.get_type() == CKA_CLASS
807+
&& ck_attr.to_ulong()? != oa.to_ulong()?)
808+
{
801809
return Err(CKR_TEMPLATE_INCONSISTENT)?;
802810
}
803811
}
@@ -2057,6 +2065,106 @@ impl Mechanism for GenericSecretKeyMechanism {
20572065
}
20582066
}
20592067

2068+
/// This is a specialized factory for objects of class CKO_PROFILE
2069+
2070+
#[derive(Debug)]
2071+
struct ProfileFactory {
2072+
data: ObjectFactoryData,
2073+
}
2074+
2075+
impl ProfileFactory {
2076+
/// Initializes a new ProfileFactory object
2077+
fn new() -> ProfileFactory {
2078+
let mut factory: ProfileFactory = ProfileFactory {
2079+
data: ObjectFactoryData::new(CKO_PROFILE),
2080+
};
2081+
2082+
factory.add_common_object_attrs();
2083+
2084+
let attributes = factory.data.get_attributes_mut();
2085+
2086+
attributes.push(attr_element!(
2087+
CKA_PROFILE_ID; OAFlags::RequiredOnCreate; Attribute::from_ulong;
2088+
val CK_UNAVAILABLE_INFORMATION));
2089+
2090+
factory.data.finalize();
2091+
2092+
factory
2093+
}
2094+
}
2095+
2096+
impl ObjectFactory for ProfileFactory {
2097+
fn create(&self, _template: &[CK_ATTRIBUTE]) -> Result<Object> {
2098+
Err(CKR_TEMPLATE_INCOMPLETE)?
2099+
}
2100+
2101+
fn copy(
2102+
&self,
2103+
_origin: &Object,
2104+
_template: &[CK_ATTRIBUTE],
2105+
) -> Result<Object> {
2106+
Err(CKR_TEMPLATE_INCOMPLETE)?
2107+
}
2108+
2109+
fn get_data(&self) -> &ObjectFactoryData {
2110+
&self.data
2111+
}
2112+
2113+
fn get_data_mut(&mut self) -> &mut ObjectFactoryData {
2114+
&mut self.data
2115+
}
2116+
}
2117+
2118+
/// This is a specialized factory for objects of class CKO_MECHANISM
2119+
2120+
#[derive(Debug)]
2121+
struct MechanismFactory {
2122+
data: ObjectFactoryData,
2123+
}
2124+
2125+
impl MechanismFactory {
2126+
/// Initializes a new MechanismFactory object
2127+
fn new() -> MechanismFactory {
2128+
let mut factory: MechanismFactory = MechanismFactory {
2129+
data: ObjectFactoryData::new(CKO_MECHANISM),
2130+
};
2131+
2132+
factory.add_common_object_attrs();
2133+
2134+
let attributes = factory.data.get_attributes_mut();
2135+
2136+
attributes.push(attr_element!(
2137+
CKA_MECHANISM_TYPE; OAFlags::RequiredOnCreate; Attribute::from_ulong;
2138+
val CK_UNAVAILABLE_INFORMATION));
2139+
2140+
factory.data.finalize();
2141+
2142+
factory
2143+
}
2144+
}
2145+
2146+
impl ObjectFactory for MechanismFactory {
2147+
fn create(&self, _template: &[CK_ATTRIBUTE]) -> Result<Object> {
2148+
Err(CKR_TEMPLATE_INCOMPLETE)?
2149+
}
2150+
2151+
fn copy(
2152+
&self,
2153+
_origin: &Object,
2154+
_template: &[CK_ATTRIBUTE],
2155+
) -> Result<Object> {
2156+
Err(CKR_TEMPLATE_INCOMPLETE)?
2157+
}
2158+
2159+
fn get_data(&self) -> &ObjectFactoryData {
2160+
&self.data
2161+
}
2162+
2163+
fn get_data_mut(&mut self) -> &mut ObjectFactoryData {
2164+
&mut self.data
2165+
}
2166+
}
2167+
20602168
/// Structure that defines an Object Type
20612169
///
20622170
/// Holds a Class type and the underlying type.
@@ -2125,7 +2233,7 @@ impl ObjectFactories {
21252233
None => return Err(CKR_TEMPLATE_INCOMPLETE)?,
21262234
};
21272235
let type_ = match class {
2128-
CKO_DATA | CKO_TRUST => 0,
2236+
CKO_DATA | CKO_TRUST | CKO_PROFILE | CKO_MECHANISM => 0,
21292237
#[cfg(feature = "nssdb")]
21302238
CKO_NSS_TRUST => 0,
21312239
CKO_CERTIFICATE => {
@@ -2153,12 +2261,14 @@ impl ObjectFactories {
21532261
None => return Err(CKR_TEMPLATE_INCOMPLETE)?,
21542262
}
21552263
}
2156-
/* TODO:
2264+
/*
21572265
* CKO_HW_FEATURE, CKO_DOMAIN_PARAMETERS,
21582266
* CKO_MECHANISM, CKO_OTP_KEY, CKO_PROFILE,
21592267
* CKO_VENDOR_DEFINED
2268+
* Builtin objects cannot be created so they always return
2269+
* this error. Unsupported objects alaso return the same.
21602270
*/
2161-
_ => return Err(CKR_DEVICE_ERROR)?,
2271+
_ => return Err(CKR_TEMPLATE_INCONSISTENT)?,
21622272
};
21632273
self.get_factory(ObjectType::new(class, type_))?
21642274
.create(template)
@@ -2366,6 +2476,14 @@ static TRUST_OBJECT_FACTORY: LazyLock<Box<dyn ObjectFactory>> =
23662476
static NSS_TRUST_OBJECT_FACTORY: LazyLock<Box<dyn ObjectFactory>> =
23672477
LazyLock::new(|| Box::new(NSSTrustObject::new()));
23682478

2479+
/// The static Profile Object factory
2480+
static PROFILE_FACTORY: LazyLock<Box<dyn ObjectFactory>> =
2481+
LazyLock::new(|| Box::new(ProfileFactory::new()));
2482+
2483+
/// The static Mechanism Object factory
2484+
static MECHANISM_FACTORY: LazyLock<Box<dyn ObjectFactory>> =
2485+
LazyLock::new(|| Box::new(MechanismFactory::new()));
2486+
23692487
/// Registers mechanisms and key factories for Data Objects, X509
23702488
/// Certificates and Generic Secret Keys
23712489
pub fn register(mechs: &mut Mechanisms, ot: &mut ObjectFactories) {
@@ -2386,4 +2504,6 @@ pub fn register(mechs: &mut Mechanisms, ot: &mut ObjectFactories) {
23862504
ObjectType::new(CKO_NSS_TRUST, 0),
23872505
&(*NSS_TRUST_OBJECT_FACTORY),
23882506
);
2507+
ot.add_factory(ObjectType::new(CKO_PROFILE, 0), &(*PROFILE_FACTORY));
2508+
ot.add_factory(ObjectType::new(CKO_MECHANISM, 0), &(*MECHANISM_FACTORY));
23892509
}

0 commit comments

Comments
 (0)