diff --git a/cryptoki/src/object.rs b/cryptoki/src/object.rs index 463a1007..89278855 100644 --- a/cryptoki/src/object.rs +++ b/cryptoki/src/object.rs @@ -1114,18 +1114,25 @@ impl TryFrom for Attribute { Ok(Attribute::ValidationVersion(Version::new(val[0], val[1]))) } AttributeType::AllowedMechanisms => { - let val = unsafe { - std::slice::from_raw_parts( - attribute.pValue as *const CK_MECHANISM_TYPE, - attribute.ulValueLen.try_into()?, - ) - }; - let types: Vec = val - .iter() - .copied() - .map(|t| t.try_into()) - .collect::>>()?; - Ok(Attribute::AllowedMechanisms(types)) + if attribute.ulValueLen == 0 { + /* For zero-length attributes we are getting pointer to static + * buffer of length zero, which can not be used to create slices. + * Short-circuit here to avoid crash (#324) */ + Ok(Attribute::AllowedMechanisms(Vec::::new())) + } else { + let val = unsafe { + std::slice::from_raw_parts( + attribute.pValue as *const CK_MECHANISM_TYPE, + attribute.ulValueLen.try_into()?, + ) + }; + let types: Vec = val + .iter() + .copied() + .map(|t| t.try_into()) + .collect::>>()?; + Ok(Attribute::AllowedMechanisms(types)) + } } AttributeType::EndDate => { if val.is_empty() { diff --git a/cryptoki/tests/basic.rs b/cryptoki/tests/basic.rs index f6bbde4f..cb390478 100644 --- a/cryptoki/tests/basic.rs +++ b/cryptoki/tests/basic.rs @@ -1113,6 +1113,20 @@ fn import_export() -> TestResult { panic!("Expected the Modulus attribute."); } + let mut attrs = + session.get_attributes(is_it_the_public_key, &[AttributeType::AllowedMechanisms])?; + + if is_softhsm() { + let attr = attrs.remove(0); + if let Attribute::AllowedMechanisms(v) = attr { + assert_eq!(v, Vec::::new()); + } else { + panic!("Expected the AllowedMechanisms attribute."); + } + } else { + assert_eq!(attrs, Vec::::new()); + } + // delete key session.destroy_object(is_it_the_public_key)?;