Skip to content

Commit aab0ca3

Browse files
committed
Adds validation of session attributes.
- Adds validation method to SessionAttributes and SessionAttributesMask. - Changes conversion functions from 'From' to 'TryFrom' and makes them call the validation function. Signed-off-by: Jesper Brynolf <[email protected]>
1 parent 4620f3f commit aab0ca3

File tree

3 files changed

+140
-46
lines changed

3 files changed

+140
-46
lines changed

tss-esapi/src/attributes/session.rs

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
use crate::tss2_esys::TPMA_SESSION;
1+
use crate::{tss2_esys::TPMA_SESSION, Error, Result, WrapperErrorKind};
22
use bitfield::bitfield;
3+
use std::convert::TryFrom;
34

45
// SESSION ATTRIBUTES
56

67
bitfield! {
7-
/// Bitfield representing the session attributes.
8+
/// Struct representing the session attributes.
89
#[derive(Copy, Clone, Eq, PartialEq)]
910
pub struct SessionAttributes(TPMA_SESSION);
1011
impl Debug;
@@ -15,7 +16,7 @@ bitfield! {
1516
pub audit_exclusive, _: 1;
1617
_, set_audit_reset: 2;
1718
pub audit_reset, _: 2;
18-
// Reserved 3,4 (Shall be clear)
19+
reserved, _: 4, 3; // Reserved 3,4 (Shall be clear)
1920
_, set_decrypt: 5;
2021
pub decrypt, _: 5;
2122
_, set_encrypt: 6;
@@ -29,32 +30,47 @@ impl SessionAttributes {
2930
pub const fn builder() -> SessionAttributesBuilder {
3031
SessionAttributesBuilder::new()
3132
}
33+
34+
/// Validates the session attributes
35+
pub fn validate(&self) -> Result<()> {
36+
if self.reserved() != 0 {
37+
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
38+
}
39+
Ok(())
40+
}
3241
}
3342

34-
impl From<TPMA_SESSION> for SessionAttributes {
35-
fn from(tss_session_attributes: TPMA_SESSION) -> SessionAttributes {
36-
SessionAttributes(tss_session_attributes)
43+
impl TryFrom<TPMA_SESSION> for SessionAttributes {
44+
type Error = Error;
45+
46+
fn try_from(tss_session_attributes: TPMA_SESSION) -> Result<SessionAttributes> {
47+
let result = SessionAttributes(tss_session_attributes);
48+
result.validate()?;
49+
Ok(result)
3750
}
3851
}
3952

40-
impl From<SessionAttributes> for TPMA_SESSION {
41-
fn from(session_attributes: SessionAttributes) -> TPMA_SESSION {
42-
session_attributes.0
53+
impl TryFrom<SessionAttributes> for TPMA_SESSION {
54+
type Error = Error;
55+
56+
fn try_from(session_attributes: SessionAttributes) -> Result<TPMA_SESSION> {
57+
session_attributes.validate()?;
58+
Ok(session_attributes.0)
4359
}
4460
}
4561

4662
// SESSION ATTRIBUTES MASK
4763

4864
bitfield! {
49-
/// Bitfield representing the session attributes mask.
65+
/// Struct representing the session attributes mask.
5066
#[derive(Copy, Clone, Eq, PartialEq)]
5167
pub struct SessionAttributesMask(TPMA_SESSION);
5268
impl Debug;
5369

5470
_, use_continue_session: 0;
5571
_, use_audit_exclusive: 1;
5672
_, use_audit_reset: 2;
57-
// Reserved 3,4 (Shall be clear)
73+
reserved, _: 4, 3; // Reserved 3,4 (Shall be clear)
5874
_, use_decrypt: 5;
5975
_, use_encrypt: 6;
6076
_, use_audit: 7;
@@ -65,17 +81,32 @@ impl SessionAttributesMask {
6581
pub const fn builder() -> SessionAttributesBuilder {
6682
SessionAttributesBuilder::new()
6783
}
84+
85+
/// Validates the session attributes
86+
pub fn validate(&self) -> Result<()> {
87+
if self.reserved() != 0 {
88+
return Err(Error::local_error(WrapperErrorKind::InvalidParam));
89+
}
90+
Ok(())
91+
}
6892
}
6993

70-
impl From<TPMA_SESSION> for SessionAttributesMask {
71-
fn from(tss_session_attributes: TPMA_SESSION) -> SessionAttributesMask {
72-
SessionAttributesMask(tss_session_attributes)
94+
impl TryFrom<TPMA_SESSION> for SessionAttributesMask {
95+
type Error = Error;
96+
97+
fn try_from(tpma_session: TPMA_SESSION) -> Result<SessionAttributesMask> {
98+
let result = SessionAttributesMask(tpma_session);
99+
result.validate()?;
100+
Ok(result)
73101
}
74102
}
75103

76-
impl From<SessionAttributesMask> for TPMA_SESSION {
77-
fn from(session_attributes_mask: SessionAttributesMask) -> TPMA_SESSION {
78-
session_attributes_mask.0
104+
impl TryFrom<SessionAttributesMask> for TPMA_SESSION {
105+
type Error = Error;
106+
107+
fn try_from(session_attributes_mask: SessionAttributesMask) -> Result<TPMA_SESSION> {
108+
session_attributes_mask.validate()?;
109+
Ok(session_attributes_mask.0)
79110
}
80111
}
81112

tss-esapi/src/context/session_administration.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::{
88
Context, Result, ReturnCode,
99
};
1010
use log::error;
11+
use std::convert::TryInto;
1112

1213
impl Context {
1314
/// Set the given attributes on a given session.
@@ -22,8 +23,8 @@ impl Context {
2223
Esys_TRSess_SetAttributes(
2324
self.mut_context(),
2425
SessionHandle::from(session).into(),
25-
attributes.into(),
26-
mask.into(),
26+
attributes.try_into()?,
27+
mask.try_into()?,
2728
)
2829
},
2930
|ret| {

tss-esapi/tests/integration_tests/attributes_tests/session_attributes_tests.rs

Lines changed: 89 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,79 @@
11
// Copyright 2022 Contributors to the Parsec project.
22
// SPDX-License-Identifier: Apache-2.0
3+
use std::convert::{TryFrom, TryInto};
34
use tss_esapi::{
45
attributes::{SessionAttributes, SessionAttributesBuilder, SessionAttributesMask},
56
tss2_esys::TPMA_SESSION,
7+
Error, WrapperErrorKind,
68
};
79

810
macro_rules! test_valid_conversion {
911
($tpm_value:expr, $method:ident) => {
10-
let tpma_session_attribute: TPMA_SESSION = $tpm_value;
11-
let session_attributes = SessionAttributes::from(tpma_session_attribute);
12+
let tpma_session: TPMA_SESSION = $tpm_value;
13+
let session_attributes = SessionAttributes::try_from(tpma_session).expect("Failed to convert TPMA_SESSION into SessionAttributes");
1214
assert_eq!(
1315
true,
1416
session_attributes.$method(),
15-
"SessionAttributes converted from TPMA_SESSION = {} did not produce the expected result with regard to {}.", tpma_session_attribute, stringify!($method),
17+
"SessionAttributes converted from TPMA_SESSION = {} did not produce the expected result with regard to {}.", tpma_session, stringify!($method),
1618
);
1719
assert_eq!(
18-
tpma_session_attribute,
19-
session_attributes.into(),
20+
tpma_session,
21+
session_attributes.try_into().expect("Failed to convert SessionAttributes into TPMA_SESSION_ATTRIBUTE."),
2022
"Converting session attributes with {} set did not convert into the expected TPMA_SESSION value", std::stringify!($method),
2123
);
2224
};
2325
}
2426

2527
macro_rules! test_valid_mask_conversion {
2628
($tpm_value:expr, $attribute:tt) => {
27-
let tpma_session_attribute: TPMA_SESSION = $tpm_value;
28-
let session_attributes_mask = SessionAttributesMask::from(tpma_session_attribute);
29+
let tpma_session: TPMA_SESSION = $tpm_value;
30+
let session_attributes_mask = SessionAttributesMask::try_from(tpma_session).expect("Failed to convert TPMA_SESSION into SessionAttributesMask");
2931
assert_eq!(
30-
tpma_session_attribute,
31-
session_attributes_mask.into(),
32+
tpma_session,
33+
session_attributes_mask.try_into().expect("Failed to convert SessionAttributesMask into TPMA_SESSION"),
3234
"Converting session attributes mask with {} set did not convert into the expected TPMA_SESSION value", $attribute,
3335
);
3436
};
3537
}
3638

39+
macro_rules! test_conversion_with_reserved_bits_set {
40+
($tpm_value:expr) => {
41+
let tpma_session: TPMA_SESSION = $tpm_value;
42+
assert_eq!(
43+
Err(Error::WrapperError(WrapperErrorKind::InvalidParam)),
44+
SessionAttributes::try_from(tpma_session),
45+
"Converting TPMA_SESSION into SessionAttributes with reserved bits sets did not produce the correct error"
46+
);
47+
};
48+
}
49+
50+
macro_rules! test_mask_conversion_with_reserved_bits_set {
51+
($tpm_value:expr) => {
52+
let tpma_session: TPMA_SESSION = $tpm_value;
53+
assert_eq!(
54+
Err(Error::WrapperError(WrapperErrorKind::InvalidParam)),
55+
SessionAttributesMask::try_from(tpma_session),
56+
"Converting TPMA_SESSION into SessionAttributesMask with reserved bits sets did not produce the correct error"
57+
);
58+
};
59+
}
60+
61+
#[test]
62+
fn test_validate_() {
63+
let valid = SessionAttributes(0b11100111u8);
64+
let invalid = SessionAttributes(0b00011000u8);
65+
assert_eq!(
66+
Ok(()),
67+
valid.validate(),
68+
"Valid SessionAttributes value generated an unexpected error when calling 'validate'"
69+
);
70+
assert_eq!(
71+
Err(Error::WrapperError(WrapperErrorKind::InvalidParam)),
72+
invalid.validate(),
73+
"Invalid SessionAttributes value did not generate the expected error."
74+
);
75+
}
76+
3777
#[test]
3878
fn test_valid_session_attributes_conversions() {
3979
test_valid_conversion!(
@@ -67,12 +107,14 @@ fn test_valid_session_attributes_conversions() {
67107
);
68108
}
69109

70-
#[ignore]
71110
#[test]
72111
fn test_invalid_session_attributes_conversions() {
73-
// bit 3 and 4 are reserved and shall be cleared.
74-
// No error for this is implemented.
75-
// See https://github.com/parallaxsecond/rust-tss-esapi/issues/330
112+
test_conversion_with_reserved_bits_set!(1u8
113+
.checked_shl(3)
114+
.expect("Failed to create value with resrved bit 3 set"));
115+
test_conversion_with_reserved_bits_set!(1u8
116+
.checked_shl(4)
117+
.expect("Failed to create value with resrved bit 4 set"));
76118
}
77119

78120
#[test]
@@ -109,12 +151,14 @@ fn test_valid_session_attributes_mask_conversions() {
109151
);
110152
}
111153

112-
#[ignore]
113154
#[test]
114155
fn test_invalid_session_attributes_mask_conversions() {
115-
// bit 3 and 4 are reserved and shall be cleared.
116-
// No error for this is implemented.
117-
// See https://github.com/parallaxsecond/rust-tss-esapi/issues/330
156+
test_mask_conversion_with_reserved_bits_set!(1u8
157+
.checked_shl(3)
158+
.expect("Failed to create value with resrved bit 3 set"));
159+
test_mask_conversion_with_reserved_bits_set!(1u8
160+
.checked_shl(4)
161+
.expect("Failed to create value with resrved bit 4 set"));
118162
}
119163

120164
#[test]
@@ -128,35 +172,53 @@ fn test_session_attributes_builder_constructing() {
128172
#[test]
129173
fn test_builder_from_session_attributes() {
130174
let (attributes, mask) = SessionAttributes::builder().build();
131-
assert_eq!(SessionAttributes::from(0), attributes, "Building session attributes without anything set using SessionAttributes::builder() did not produce expected result");
132-
assert_eq!(SessionAttributesMask::from(0), mask, "Building sesssion attributes mask without anything set using SessionAttributes::builder() did not produce expected result")
175+
assert_eq!(SessionAttributes::try_from(0).expect("Failed to convert 0 into SessionAttributes"), attributes, "Building session attributes without anything set using SessionAttributes::builder() did not produce expected result");
176+
assert_eq!(SessionAttributesMask::try_from(0).expect("Failed to convert 0 into SessionAttributesMask"), mask, "Building session attributes mask without anything set using SessionAttributes::builder() did not produce expected result")
133177
}
134178

135179
#[test]
136180
fn test_builder_from_session_attributes_mask() {
137181
let (attributes, mask) = SessionAttributesMask::builder().build();
138-
assert_eq!(SessionAttributes::from(0), attributes, "Building session attributes without anything set using SessionAttributesMask::builder() did not produce expected result");
139-
assert_eq!(SessionAttributesMask::from(0), mask, "Building sesssion attributes mask without anything set using SessionAttributesMask::builder() did not produce expected result")
182+
assert_eq!(SessionAttributes::try_from(0).expect("Failed to convert 0 into SessionAttributes"), attributes, "Building session attributes without anything set using SessionAttributesMask::builder() did not produce expected result");
183+
assert_eq!(SessionAttributesMask::try_from(0).expect("Failed to convert 0 into SessionAttributesMask"), mask, "Building session attributes mask without anything set using SessionAttributesMask::builder() did not produce expected result")
140184
}
141185

142186
#[test]
143187
fn test_builder_from_session_attributes_builder_default() {
144188
let (attributes, mask) = SessionAttributesBuilder::default().build();
145-
assert_eq!(SessionAttributes::from(0), attributes, "Building session attributes without anything set using SessionAttributesBuilder::default() did not produce expected result");
146-
assert_eq!(SessionAttributesMask::from(0), mask, "Building sesssion attributes mask without anything set using SessionAttributesBuilder::default() did not produce expected result")
189+
assert_eq!(SessionAttributes::try_from(0).expect("Failed to convert 0 into SessionAttributes"), attributes, "Building session attributes without anything set using SessionAttributesBuilder::default() did not produce expected result");
190+
assert_eq!(SessionAttributesMask::try_from(0).expect("Failed to convert 0 into SessionAttributesMask"), mask, "Building session attributes mask without anything set using SessionAttributesBuilder::default() did not produce expected result")
147191
}
148192

149193
#[test]
150194
fn test_builder_from_session_attributes_builder_new() {
151195
let (attributes, mask) = SessionAttributesBuilder::new().build();
152-
assert_eq!(SessionAttributes::from(0), attributes, "Building session attributes without anything set using SessionAttributesBuilder::new() did not produce expected result");
153-
assert_eq!(SessionAttributesMask::from(0), mask, "Building sesssion attributes mask without anything set using SessionAttributesBuilder::new() did not produce expected result")
196+
assert_eq!(SessionAttributes::try_from(0).expect("Failed to convert 0 into SessionAttributes"), attributes, "Building session attributes without anything set using SessionAttributesBuilder::new() did not produce expected result");
197+
assert_eq!(SessionAttributesMask::try_from(0).expect("Failed to convert 0 into SessionAttributesMask"), mask, "Building session attributes mask without anything set using SessionAttributesBuilder::new() did not produce expected result")
198+
}
199+
200+
#[test]
201+
fn test_mask_validate_() {
202+
let valid = SessionAttributesMask(0b11100111u8);
203+
let invalid = SessionAttributesMask(0b00011000u8);
204+
assert_eq!(
205+
Ok(()),
206+
valid.validate(),
207+
"Valid SessionAttributesMask value generated an unexpected error when calling 'validate'"
208+
);
209+
assert_eq!(
210+
Err(Error::WrapperError(WrapperErrorKind::InvalidParam)),
211+
invalid.validate(),
212+
"Invalid SessionAttributesMask value did not generate the expected error."
213+
);
154214
}
155215

156216
#[test]
157217
fn test_session_attributes_builder() {
158-
let expected_session_attributes = SessionAttributes::from(0b11100111u8);
159-
let expected_session_attributes_mask = SessionAttributesMask::from(0b11100111u8);
218+
let expected_session_attributes = SessionAttributes::try_from(0b11100111u8)
219+
.expect("Failed to convert 0b11100111u8 into SessionAttributes");
220+
let expected_session_attributes_mask = SessionAttributesMask::try_from(0b11100111u8)
221+
.expect("Failed to convert 0b11100111u8 into SessionAttributesMask");
160222

161223
let (actual_session_attributes, actual_session_attributes_mask) =
162224
SessionAttributesBuilder::new()

0 commit comments

Comments
 (0)