cryptoki/context/
session_management.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3//! Session management functions
4
5use cryptoki_sys::{CKF_RW_SESSION, CKF_SERIAL_SESSION};
6
7use crate::context::Pkcs11;
8use crate::error::{Result, Rv};
9use crate::session::Session;
10use crate::slot::Slot;
11
12use super::Function;
13
14impl Pkcs11 {
15    #[inline(always)]
16    fn open_session(&self, slot_id: Slot, read_write: bool) -> Result<Session> {
17        let mut session_handle = 0;
18
19        let flags = if read_write {
20            CKF_SERIAL_SESSION | CKF_RW_SESSION
21        } else {
22            CKF_SERIAL_SESSION
23        };
24        unsafe {
25            Rv::from(get_pkcs11!(self, C_OpenSession)(
26                slot_id.into(),
27                flags,
28                // TODO: abstract those types or create new functions for callbacks
29                std::ptr::null_mut(),
30                None,
31                &mut session_handle,
32            ))
33            .into_result(Function::OpenSession)?;
34        }
35
36        Ok(Session::new(session_handle, self.clone()))
37    }
38
39    /// Open a new Read-Only session
40    ///
41    /// For a Read-Write session, use `open_rw_session`
42    ///
43    /// Note: No callback is set when opening the session.
44    ///
45    /// # Examples
46    ///
47    /// ```rust
48    /// # fn main() -> testresult::TestResult {
49    /// use cryptoki::session::Session;
50    /// use cryptoki::context::Pkcs11;
51    ///
52    /// let mut client = Pkcs11::new(
53    ///     std::env::var("TEST_PKCS11_MODULE")
54    ///        .unwrap_or_else(|_| "/usr/local/lib/softhsm/libsofthsm2.so".to_string()),
55    /// )?;
56    /// client.initialize(cryptoki::context::CInitializeArgs::OsThreads)?;
57    ///
58    /// // Use the first slot
59    /// let slot = client.get_all_slots()?[0];
60    /// let session = client.open_ro_session(slot)?;
61    /// # let _ = session; Ok(()) }
62    /// ```
63    pub fn open_ro_session(&self, slot_id: Slot) -> Result<Session> {
64        self.open_session(slot_id, false)
65    }
66
67    /// Open a new Read/Write session
68    ///
69    /// Note: No callback is set when opening the session.
70    pub fn open_rw_session(&self, slot_id: Slot) -> Result<Session> {
71        self.open_session(slot_id, true)
72    }
73}