cryptoki/session/
session_info.rs1use crate::error::{Error, Result};
6use crate::slot::Slot;
7use bitflags::bitflags;
8use cryptoki_sys::*;
9use std::convert::{TryFrom, TryInto};
10use std::fmt::Debug;
11
12bitflags! {
13 struct SessionInfoFlags: CK_FLAGS {
15 const RW_SESSION = CKF_RW_SESSION;
16 const SERIAL_SESSION = CKF_SERIAL_SESSION;
17 }
18}
19
20#[derive(Copy, Clone, Debug)]
22pub struct SessionInfo {
23 slot_id: Slot,
24 state: SessionState,
25 flags: SessionInfoFlags,
26 device_error: u64,
27}
28
29impl SessionInfo {
30 pub fn slot_id(&self) -> Slot {
32 self.slot_id
33 }
34
35 pub fn session_state(&self) -> SessionState {
37 self.state
38 }
39
40 pub fn read_write(&self) -> bool {
43 self.flags.contains(SessionInfoFlags::RW_SESSION)
44 }
45
46 pub fn device_error(&self) -> u64 {
49 self.device_error
50 }
51}
52
53#[doc(hidden)]
54impl TryFrom<CK_SESSION_INFO> for SessionInfo {
55 type Error = Error;
56 fn try_from(val: CK_SESSION_INFO) -> Result<Self> {
57 #[allow(clippy::useless_conversion)]
58 let device_error = val.ulDeviceError.into();
59 Ok(Self {
60 slot_id: Slot::new(val.slotID),
61 state: val.state.try_into()?,
62 flags: SessionInfoFlags::from_bits_truncate(val.flags),
63 device_error,
64 })
65 }
66}
67
68#[derive(Debug, Copy, Clone, PartialEq, Eq)]
71pub enum SessionState {
72 RoPublic,
75 RoUser,
79 RwPublic,
81 RwUser,
84 RwSecurityOfficer,
88}
89
90#[doc(hidden)]
91impl TryFrom<CK_STATE> for SessionState {
92 type Error = Error;
93 fn try_from(value: CK_STATE) -> Result<Self> {
94 match value {
95 CKS_RO_PUBLIC_SESSION => Ok(Self::RoPublic),
96 CKS_RO_USER_FUNCTIONS => Ok(Self::RoUser),
97 CKS_RW_PUBLIC_SESSION => Ok(Self::RwPublic),
98 CKS_RW_USER_FUNCTIONS => Ok(Self::RwUser),
99 CKS_RW_SO_FUNCTIONS => Ok(Self::RwSecurityOfficer),
100 _ => Err(Error::InvalidValue),
101 }
102 }
103}
104
105#[cfg(test)]
106mod test {
107 use super::{SessionInfo, SessionInfoFlags, SessionState};
108 use crate::slot::Slot;
109
110 #[test]
111 fn debug_flags_all() {
112 let expected = "RW_SESSION | SERIAL_SESSION";
113 let all = SessionInfoFlags::all();
114 let observed = format!("{all:#?}");
115 assert_eq!(observed, expected);
116 }
117
118 #[test]
119 fn debug_info() {
120 let info = SessionInfo {
121 slot_id: Slot::new(100),
122 state: SessionState::RoPublic,
123 flags: SessionInfoFlags::empty(),
124 device_error: 0,
125 };
126 let expected = r#"SessionInfo {
127 slot_id: Slot {
128 slot_id: 100,
129 },
130 state: RoPublic,
131 flags: (empty),
132 device_error: 0,
133}"#;
134 let observed = format!("{info:#?}");
135 assert_eq!(observed, expected);
136 }
137}