Skip to content

Commit

Permalink
Fix Date attribute parsing (#74)
Browse files Browse the repository at this point in the history
The Date attribute can be returned as empty (i.e., parameter length is 0),
however our parsing did not consider this option.
A test is also added to ensure that any regressions are caught.

Signed-off-by: Ionut Mihalcea <[email protected]>
  • Loading branch information
ionut-arm committed Mar 2, 2022
1 parent 23328a8 commit 3a21c37
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 32 deletions.
72 changes: 40 additions & 32 deletions cryptoki/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -884,41 +884,49 @@ impl TryFrom<CK_ATTRIBUTE> for Attribute {
Ok(Attribute::AllowedMechanisms(types))
}
AttributeType::EndDate => {
let date = val.as_ptr() as *const CK_DATE;
unsafe {
let year = String::from_utf8_lossy(Vec::from((*date).year).as_slice())
.trim_end()
.to_string();
let month = String::from_utf8_lossy(Vec::from((*date).month).as_slice())
.trim_end()
.to_string();
let day = String::from_utf8_lossy(Vec::from((*date).day).as_slice())
.trim_end()
.to_string();
Ok(Attribute::EndDate(Date::new_from_str_slice(
year.as_str(),
month.as_str(),
day.as_str(),
)?))
if val.is_empty() {
Ok(Attribute::EndDate(Date::new_empty()))
} else {
let date = val.as_ptr() as *const CK_DATE;
unsafe {
let year = String::from_utf8_lossy(Vec::from((*date).year).as_slice())
.trim_end()
.to_string();
let month = String::from_utf8_lossy(Vec::from((*date).month).as_slice())
.trim_end()
.to_string();
let day = String::from_utf8_lossy(Vec::from((*date).day).as_slice())
.trim_end()
.to_string();
Ok(Attribute::EndDate(Date::new_from_str_slice(
year.as_str(),
month.as_str(),
day.as_str(),
)?))
}
}
}
AttributeType::StartDate => {
let date = val.as_ptr() as *const CK_DATE;
unsafe {
let year = String::from_utf8_lossy(Vec::from((*date).year).as_slice())
.trim_end()
.to_string();
let month = String::from_utf8_lossy(Vec::from((*date).month).as_slice())
.trim_end()
.to_string();
let day = String::from_utf8_lossy(Vec::from((*date).day).as_slice())
.trim_end()
.to_string();
Ok(Attribute::StartDate(Date::new_from_str_slice(
year.as_str(),
month.as_str(),
day.as_str(),
)?))
if val.is_empty() {
Ok(Attribute::EndDate(Date::new_empty()))
} else {
let date = val.as_ptr() as *const CK_DATE;
unsafe {
let year = String::from_utf8_lossy(Vec::from((*date).year).as_slice())
.trim_end()
.to_string();
let month = String::from_utf8_lossy(Vec::from((*date).month).as_slice())
.trim_end()
.to_string();
let day = String::from_utf8_lossy(Vec::from((*date).day).as_slice())
.trim_end()
.to_string();
Ok(Attribute::StartDate(Date::new_from_str_slice(
year.as_str(),
month.as_str(),
day.as_str(),
)?))
}
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions cryptoki/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,29 @@ impl Date {
let date = CK_DATE { year, month, day };
Self { date }
}

/// Creates a new, empty `Date` structure
///
/// This represents the default value of the attribute (on
/// newer implementations of `Cryptoki`).
pub fn new_empty() -> Self {
let date = CK_DATE {
year: Default::default(),
month: Default::default(),
day: Default::default(),
};
Self { date }
}

/// Check if `Date` is empty
///
/// *NOTE*: This function is only representative of newer implementations
/// of `Cryptoki`, for which dates are represented as empty object attributes.
pub fn is_empty(&self) -> bool {
self.date.year == <[u8; 4]>::default()
&& self.date.month == <[u8; 2]>::default()
&& self.date.day == <[u8; 2]>::default()
}
}

impl Deref for Date {
Expand Down
34 changes: 34 additions & 0 deletions cryptoki/tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,3 +677,37 @@ fn is_initialized_test() {
Ok(()) => panic!("Initializing twice should not have been allowed"),
}
}

#[test]
#[serial]
fn aes_key_attributes_test() -> Result<()> {
let (pkcs11, slot) = init_pins();

// open a session
let session = pkcs11.open_session_no_callback(slot, true)?;

// log in the session
session.login(UserType::User, Some(USER_PIN))?;

// get mechanism
let mechanism = Mechanism::AesKeyGen;

// pub key template
let key_template = vec![
Attribute::Class(ObjectClass::SECRET_KEY),
Attribute::Token(true),
Attribute::Sensitive(true),
Attribute::ValueLen(16.into()),
Attribute::KeyType(KeyType::AES),
Attribute::Label(b"testAES".to_vec()),
Attribute::Private(true),
];

// generate a key pair
let key = session.generate_key(&mechanism, &key_template)?;

let _attributes_result =
session.get_attributes(key, &[AttributeType::EndDate, AttributeType::StartDate])?;

Ok(())
}

0 comments on commit 3a21c37

Please sign in to comment.