@@ -139,14 +139,12 @@ where
139139 // Get slot with token
140140 let slot = ctx. get_slots_with_token ( ) ?[ 0 ] ;
141141
142- // Open new session (R/W for key generation)
143- let new_session = ctx. open_rw_session ( slot) ?;
142+ // Open new session (R/O is sufficient for session key generation)
143+ let new_session = ctx. open_ro_session ( slot) ?;
144144
145- // Login as normal user
146- let user_pin = AuthPin :: new ( USER_PIN . into ( ) ) ;
147- new_session. login ( UserType :: User , Some ( & user_pin) ) ?;
145+ // No need to login.
148146
149- println ! ( "Thread {:?}: Opened new RW session" , thread:: current( ) . id( ) ) ;
147+ println ! ( "Thread {:?}: Opened new RO session" , thread:: current( ) . id( ) ) ;
150148
151149 // Store in thread-local storage
152150 * session_opt = Some ( new_session) ;
@@ -251,6 +249,21 @@ fn generate_and_sign(thread_id: usize) -> TestResult {
251249 Ok ( ( ) )
252250}
253251
252+ /// Open and authenticate a persistent session for the application.
253+ ///
254+ /// This opens a read-only session on the first available slot with a token,
255+ /// logs in the normal user (`USER_PIN`) and returns the session. The intent
256+ /// is to keep this session active for the duration of the application's
257+ /// lifetime so other components can rely on a long-lived, logged-in session.
258+ fn open_authenticated_session ( ) -> TestResult < Session > {
259+ let pkcs11 = PKCS11_CTX . get ( ) . ok_or ( "PKCS11 context not initialized" ) ?;
260+ let slot = pkcs11. get_slots_with_token ( ) ?[ 0 ] ;
261+ let session = pkcs11. open_ro_session ( slot) ?;
262+ let user_pin = AuthPin :: new ( USER_PIN . into ( ) ) ;
263+ session. login ( UserType :: User , Some ( & user_pin) ) ?;
264+ Ok ( session)
265+ }
266+
254267fn main ( ) -> TestResult {
255268 println ! ( "Thread-Local Session Pattern Example" ) ;
256269 println ! ( "====================================\n " ) ;
@@ -265,6 +278,10 @@ fn main() -> TestResult {
265278 init_pkcs11_context ( ) ?;
266279 println ! ( ) ;
267280
281+ // Open a persistent session to maintain login state for the app's lifetime
282+ let _persistent_session = open_authenticated_session ( ) ?;
283+ println ! ( "Persistent session opened to maintain login state.\n " ) ;
284+
268285 let max_threads = 3 ;
269286
270287 // Spawn multiple threads
@@ -287,5 +304,9 @@ fn main() -> TestResult {
287304 println ! ( "\n All threads completed successfully!" ) ;
288305 println ! ( "Note: Each thread had its own Session instance, reused across multiple operations." ) ;
289306
307+ // _persistent_session drops here, as Session implements Drop and objects on stack
308+ // are dropped in reverse order of creation. Login state is cleaned up automatically.
309+ // Since Session implements Drop, the compiler will not optimize _persistent_session away,
310+ // and drop will happen as expected.
290311 Ok ( ( ) )
291312}
0 commit comments