using Net.Pkcs11Interop.Common; using Net.Pkcs11Interop.HighLevelAPI; using System; using System.Threading; using System.Threading.Tasks; namespace StellaOps.Cryptography.Kms; internal sealed partial class Pkcs11InteropFacade { #pragma warning disable CS1998 private async Task OpenSessionAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var session = _slot.OpenSession(SessionType.ReadOnly); var loggedIn = false; try { if (!string.IsNullOrWhiteSpace(_options.UserPin)) { session.Login(CKU.CKU_USER, _options.UserPin); loggedIn = true; } return new SessionContext(session, loggedIn); } catch { if (loggedIn) { try { session.Logout(); } catch { } } session.Dispose(); throw; } } private sealed class SessionContext : IDisposable { private readonly ISession _session; private readonly bool _logoutOnDispose; private bool _disposed; public SessionContext(ISession session, bool logoutOnDispose) { _session = session ?? throw new ArgumentNullException(nameof(session)); _logoutOnDispose = logoutOnDispose; } public ISession Session => _session; public void Dispose() { if (_disposed) { return; } if (_logoutOnDispose) { try { _session.Logout(); } catch { // ignore logout failures } } _session.Dispose(); _disposed = true; } } }