зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset a93095760b1f (bug 1658042) for causing Bug 1658576 a=backout
This commit is contained in:
Родитель
8df04ff073
Коммит
54c193f6bc
|
@ -26,7 +26,6 @@ use core_foundation::string::*;
|
|||
// etc.. This is easier.
|
||||
include!("bindings_macos.rs");
|
||||
|
||||
use crate::manager::SlotType;
|
||||
use crate::util::*;
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -815,17 +814,7 @@ pub enum Object {
|
|||
}
|
||||
|
||||
impl Object {
|
||||
pub fn matches(&self, slot_type: SlotType, attrs: &[(CK_ATTRIBUTE_TYPE, Vec<u8>)]) -> bool {
|
||||
// The modern/legacy slot distinction in theory enables differentiation
|
||||
// between keys that are from modules that can use modern cryptography
|
||||
// (namely EC keys and RSA-PSS signatures) and those that cannot.
|
||||
// However, the function that would enable this
|
||||
// (SecKeyIsAlgorithmSupported) causes a password dialog to appear on
|
||||
// our test machines, so this backend pretends that everything supports
|
||||
// modern crypto for now.
|
||||
if slot_type != SlotType::Modern {
|
||||
return false;
|
||||
}
|
||||
pub fn matches(&self, attrs: &[(CK_ATTRIBUTE_TYPE, Vec<u8>)]) -> bool {
|
||||
match self {
|
||||
Object::Cert(cert) => cert.matches(attrs),
|
||||
Object::Key(key) => key.matches(attrs),
|
||||
|
|
|
@ -17,7 +17,6 @@ use winapi::um::errhandlingapi::GetLastError;
|
|||
use winapi::um::ncrypt::*;
|
||||
use winapi::um::wincrypt::{HCRYPTHASH, HCRYPTPROV, *};
|
||||
|
||||
use crate::manager::SlotType;
|
||||
use crate::util::*;
|
||||
|
||||
// winapi has some support for ncrypt.h, but not for this function.
|
||||
|
@ -65,25 +64,6 @@ fn get_cert_subject_dn(cert_info: &CERT_INFO) -> Result<Vec<u8>, ()> {
|
|||
Ok(subject_dn_string_bytes)
|
||||
}
|
||||
|
||||
/// Helper function to determine which slot to expose a certificate/key on.
|
||||
/// Certificates with keys that are available via the CNG APIs are exposed on the modern slot.
|
||||
/// Certificates with keys that are only available via the CryptoAPI APIs are exposed on the legacy
|
||||
/// slot.
|
||||
fn get_slot_type_for_cert(cert: PCCERT_CONTEXT) -> SlotType {
|
||||
if unsafe {
|
||||
CryptFindCertificateKeyProvInfo(
|
||||
cert,
|
||||
CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG,
|
||||
std::ptr::null_mut(),
|
||||
)
|
||||
} != 0
|
||||
{
|
||||
SlotType::Modern
|
||||
} else {
|
||||
SlotType::Legacy
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a certificate for which there exists a corresponding private key.
|
||||
pub struct Cert {
|
||||
/// PKCS #11 object class. Will be `CKO_CERTIFICATE`.
|
||||
|
@ -102,13 +82,11 @@ pub struct Cert {
|
|||
serial_number: Vec<u8>,
|
||||
/// The DER bytes of the subject distinguished name of the certificate.
|
||||
subject: Vec<u8>,
|
||||
/// Which slot this certificate should be exposed on.
|
||||
slot_type: SlotType,
|
||||
}
|
||||
|
||||
impl Cert {
|
||||
fn new(cert_context: PCCERT_CONTEXT) -> Result<Cert, ()> {
|
||||
let cert = unsafe { &*cert_context };
|
||||
fn new(cert: PCCERT_CONTEXT) -> Result<Cert, ()> {
|
||||
let cert = unsafe { &*cert };
|
||||
let cert_info = unsafe { &*cert.pCertInfo };
|
||||
let value =
|
||||
unsafe { slice::from_raw_parts(cert.pbCertEncoded, cert.cbCertEncoded as usize) };
|
||||
|
@ -133,7 +111,6 @@ impl Cert {
|
|||
issuer,
|
||||
serial_number,
|
||||
subject,
|
||||
slot_type: get_slot_type_for_cert(cert_context),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -169,10 +146,7 @@ impl Cert {
|
|||
&self.subject
|
||||
}
|
||||
|
||||
fn matches(&self, slot_type: SlotType, attrs: &[(CK_ATTRIBUTE_TYPE, Vec<u8>)]) -> bool {
|
||||
if slot_type != self.slot_type {
|
||||
return false;
|
||||
}
|
||||
fn matches(&self, attrs: &[(CK_ATTRIBUTE_TYPE, Vec<u8>)]) -> bool {
|
||||
for (attr_type, attr_value) in attrs {
|
||||
let comparison = match *attr_type {
|
||||
CKA_CLASS => self.class(),
|
||||
|
@ -589,8 +563,6 @@ pub struct Key {
|
|||
ec_params: Option<Vec<u8>>,
|
||||
/// An enum identifying this key's type.
|
||||
key_type_enum: KeyType,
|
||||
/// Which slot this key should be exposed on.
|
||||
slot_type: SlotType,
|
||||
}
|
||||
|
||||
impl Key {
|
||||
|
@ -637,7 +609,6 @@ impl Key {
|
|||
modulus,
|
||||
ec_params,
|
||||
key_type_enum,
|
||||
slot_type: get_slot_type_for_cert(cert_context),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -675,10 +646,7 @@ impl Key {
|
|||
}
|
||||
}
|
||||
|
||||
fn matches(&self, slot_type: SlotType, attrs: &[(CK_ATTRIBUTE_TYPE, Vec<u8>)]) -> bool {
|
||||
if slot_type != self.slot_type {
|
||||
return false;
|
||||
}
|
||||
fn matches(&self, attrs: &[(CK_ATTRIBUTE_TYPE, Vec<u8>)]) -> bool {
|
||||
for (attr_type, attr_value) in attrs {
|
||||
let comparison = match *attr_type {
|
||||
CKA_CLASS => self.class(),
|
||||
|
@ -765,10 +733,10 @@ pub enum Object {
|
|||
}
|
||||
|
||||
impl Object {
|
||||
pub fn matches(&self, slot_type: SlotType, attrs: &[(CK_ATTRIBUTE_TYPE, Vec<u8>)]) -> bool {
|
||||
pub fn matches(&self, attrs: &[(CK_ATTRIBUTE_TYPE, Vec<u8>)]) -> bool {
|
||||
match self {
|
||||
Object::Cert(cert) => cert.matches(slot_type, attrs),
|
||||
Object::Key(key) => key.matches(slot_type, attrs),
|
||||
Object::Cert(cert) => cert.matches(attrs),
|
||||
Object::Key(key) => key.matches(attrs),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ mod backend_macos;
|
|||
#[cfg(target_os = "windows")]
|
||||
mod backend_windows;
|
||||
|
||||
use manager::{ManagerProxy, SlotType};
|
||||
use manager::ManagerProxy;
|
||||
|
||||
lazy_static! {
|
||||
/// The singleton `ManagerProxy` that handles state with respect to PKCS #11. Only one thread
|
||||
|
@ -144,12 +144,8 @@ extern "C" fn C_GetInfo(pInfo: CK_INFO_PTR) -> CK_RV {
|
|||
CKR_OK
|
||||
}
|
||||
|
||||
/// This module has two slots.
|
||||
const SLOT_COUNT: CK_ULONG = 2;
|
||||
/// The slot with ID 1 supports modern mechanisms like RSA-PSS.
|
||||
const SLOT_ID_MODERN: CK_SLOT_ID = 1;
|
||||
/// The slot with ID 2 only supports legacy mechanisms.
|
||||
const SLOT_ID_LEGACY: CK_SLOT_ID = 2;
|
||||
/// This module only has one slot. Its ID is 1.
|
||||
const SLOT_ID: CK_SLOT_ID = 1;
|
||||
|
||||
/// This gets called twice: once with a null `pSlotList` to get the number of slots (returned via
|
||||
/// `pulCount`) and a second time to get the ID for each slot.
|
||||
|
@ -162,42 +158,35 @@ extern "C" fn C_GetSlotList(
|
|||
error!("C_GetSlotList: CKR_ARGUMENTS_BAD");
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
unsafe {
|
||||
*pulCount = 1;
|
||||
}
|
||||
if !pSlotList.is_null() {
|
||||
if unsafe { *pulCount } < SLOT_COUNT {
|
||||
let slotCount = unsafe { *pulCount };
|
||||
if slotCount < 1 {
|
||||
error!("C_GetSlotList: CKR_BUFFER_TOO_SMALL");
|
||||
return CKR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
unsafe {
|
||||
*pSlotList = SLOT_ID_MODERN;
|
||||
*pSlotList.offset(1) = SLOT_ID_LEGACY;
|
||||
*pSlotList = SLOT_ID;
|
||||
}
|
||||
};
|
||||
unsafe {
|
||||
*pulCount = SLOT_COUNT;
|
||||
}
|
||||
debug!("C_GetSlotList: CKR_OK");
|
||||
CKR_OK
|
||||
}
|
||||
|
||||
const SLOT_DESCRIPTION_MODERN_BYTES: &[u8; 64] =
|
||||
b"OS Client Cert Slot (Modern) ";
|
||||
const SLOT_DESCRIPTION_LEGACY_BYTES: &[u8; 64] =
|
||||
b"OS Client Cert Slot (Legacy) ";
|
||||
const SLOT_DESCRIPTION_BYTES: &[u8; 64] =
|
||||
b"OS Client Cert Slot ";
|
||||
|
||||
/// This gets called to obtain information about slots. In this implementation, the tokens are
|
||||
/// always present in the slots.
|
||||
/// This gets called to obtain information about slots. In this implementation, the token is always
|
||||
/// present in the slot.
|
||||
extern "C" fn C_GetSlotInfo(slotID: CK_SLOT_ID, pInfo: CK_SLOT_INFO_PTR) -> CK_RV {
|
||||
if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || pInfo.is_null() {
|
||||
if slotID != SLOT_ID || pInfo.is_null() {
|
||||
error!("C_GetSlotInfo: CKR_ARGUMENTS_BAD");
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
let description = if slotID == SLOT_ID_MODERN {
|
||||
SLOT_DESCRIPTION_MODERN_BYTES
|
||||
} else {
|
||||
SLOT_DESCRIPTION_LEGACY_BYTES
|
||||
};
|
||||
let slot_info = CK_SLOT_INFO {
|
||||
slotDescription: *description,
|
||||
slotDescription: *SLOT_DESCRIPTION_BYTES,
|
||||
manufacturerID: *MANUFACTURER_ID_BYTES,
|
||||
flags: CKF_TOKEN_PRESENT,
|
||||
hardwareVersion: CK_VERSION::default(),
|
||||
|
@ -210,25 +199,19 @@ extern "C" fn C_GetSlotInfo(slotID: CK_SLOT_ID, pInfo: CK_SLOT_INFO_PTR) -> CK_R
|
|||
CKR_OK
|
||||
}
|
||||
|
||||
const TOKEN_LABEL_MODERN_BYTES: &[u8; 32] = b"OS Client Cert Token (Modern) ";
|
||||
const TOKEN_LABEL_LEGACY_BYTES: &[u8; 32] = b"OS Client Cert Token (Legacy) ";
|
||||
const TOKEN_LABEL_BYTES: &[u8; 32] = b"OS Client Cert Token ";
|
||||
const TOKEN_MODEL_BYTES: &[u8; 16] = b"osclientcerts ";
|
||||
const TOKEN_SERIAL_NUMBER_BYTES: &[u8; 16] = b"0000000000000000";
|
||||
|
||||
/// This gets called to obtain some information about tokens. This implementation has two slots,
|
||||
/// so it has two tokens. This information is primarily for display purposes.
|
||||
/// This gets called to obtain some information about tokens. This implementation only has one slot,
|
||||
/// so it only has one token. This information is primarily for display purposes.
|
||||
extern "C" fn C_GetTokenInfo(slotID: CK_SLOT_ID, pInfo: CK_TOKEN_INFO_PTR) -> CK_RV {
|
||||
if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || pInfo.is_null() {
|
||||
if slotID != SLOT_ID || pInfo.is_null() {
|
||||
error!("C_GetTokenInfo: CKR_ARGUMENTS_BAD");
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
let mut token_info = CK_TOKEN_INFO::default();
|
||||
let label = if slotID == SLOT_ID_MODERN {
|
||||
TOKEN_LABEL_MODERN_BYTES
|
||||
} else {
|
||||
TOKEN_LABEL_LEGACY_BYTES
|
||||
};
|
||||
token_info.label = *label;
|
||||
token_info.label = *TOKEN_LABEL_BYTES;
|
||||
token_info.manufacturerID = *MANUFACTURER_ID_BYTES;
|
||||
token_info.model = *TOKEN_MODEL_BYTES;
|
||||
token_info.serialNumber = *TOKEN_SERIAL_NUMBER_BYTES;
|
||||
|
@ -239,22 +222,18 @@ extern "C" fn C_GetTokenInfo(slotID: CK_SLOT_ID, pInfo: CK_TOKEN_INFO_PTR) -> CK
|
|||
CKR_OK
|
||||
}
|
||||
|
||||
/// This gets called to determine what mechanisms a slot supports. The modern slot supports ECDSA,
|
||||
/// RSA PKCS, and RSA PSS. The legacy slot only supports RSA PKCS.
|
||||
/// This gets called to determine what mechanisms a slot supports. This implementation supports
|
||||
/// ECDSA, RSA PKCS, and RSA PSS.
|
||||
extern "C" fn C_GetMechanismList(
|
||||
slotID: CK_SLOT_ID,
|
||||
pMechanismList: CK_MECHANISM_TYPE_PTR,
|
||||
pulCount: CK_ULONG_PTR,
|
||||
) -> CK_RV {
|
||||
if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || pulCount.is_null() {
|
||||
if slotID != SLOT_ID || pulCount.is_null() {
|
||||
error!("C_GetMechanismList: CKR_ARGUMENTS_BAD");
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
let mechanisms = if slotID == SLOT_ID_MODERN {
|
||||
vec![CKM_ECDSA, CKM_RSA_PKCS, CKM_RSA_PKCS_PSS]
|
||||
} else {
|
||||
vec![CKM_RSA_PKCS]
|
||||
};
|
||||
let mechanisms = [CKM_ECDSA, CKM_RSA_PKCS, CKM_RSA_PKCS_PSS];
|
||||
if !pMechanismList.is_null() {
|
||||
if unsafe { *pulCount as usize } < mechanisms.len() {
|
||||
error!("C_GetMechanismList: CKR_ARGUMENTS_BAD");
|
||||
|
@ -321,18 +300,13 @@ extern "C" fn C_OpenSession(
|
|||
_Notify: CK_NOTIFY,
|
||||
phSession: CK_SESSION_HANDLE_PTR,
|
||||
) -> CK_RV {
|
||||
if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || phSession.is_null() {
|
||||
if slotID != SLOT_ID || phSession.is_null() {
|
||||
error!("C_OpenSession: CKR_ARGUMENTS_BAD");
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
let mut manager_guard = try_to_get_manager_guard!();
|
||||
let manager = manager_guard_to_manager!(manager_guard);
|
||||
let slot_type = if slotID == SLOT_ID_MODERN {
|
||||
SlotType::Modern
|
||||
} else {
|
||||
SlotType::Legacy
|
||||
};
|
||||
let session_handle = match manager.open_session(slot_type) {
|
||||
let session_handle = match manager.open_session() {
|
||||
Ok(session_handle) => session_handle,
|
||||
Err(()) => {
|
||||
error!("C_OpenSession: open_session failed");
|
||||
|
@ -360,18 +334,13 @@ extern "C" fn C_CloseSession(hSession: CK_SESSION_HANDLE) -> CK_RV {
|
|||
|
||||
/// This gets called to close all open sessions at once. This is handled by the `ManagerProxy`.
|
||||
extern "C" fn C_CloseAllSessions(slotID: CK_SLOT_ID) -> CK_RV {
|
||||
if slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY {
|
||||
if slotID != SLOT_ID {
|
||||
error!("C_CloseAllSessions: CKR_ARGUMENTS_BAD");
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
let mut manager_guard = try_to_get_manager_guard!();
|
||||
let manager = manager_guard_to_manager!(manager_guard);
|
||||
let slot_type = if slotID == SLOT_ID_MODERN {
|
||||
SlotType::Modern
|
||||
} else {
|
||||
SlotType::Legacy
|
||||
};
|
||||
match manager.close_all_sessions(slot_type) {
|
||||
match manager.close_all_sessions() {
|
||||
Ok(()) => {
|
||||
debug!("C_CloseAllSessions: CKR_OK");
|
||||
CKR_OK
|
||||
|
|
|
@ -18,15 +18,6 @@ use std::thread;
|
|||
use std::thread::JoinHandle;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
/// Helper enum to differentiate between sessions on the modern slot and sessions on the legacy
|
||||
/// slot. The former is for EC keys and RSA keys that can be used with RSA-PSS whereas the latter is
|
||||
/// for RSA keys that cannot be used with RSA-PSS.
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum SlotType {
|
||||
Modern,
|
||||
Legacy,
|
||||
}
|
||||
|
||||
/// Helper type for sending `ManagerArguments` to the real `Manager`.
|
||||
type ManagerArgumentsSender = Sender<ManagerArguments>;
|
||||
/// Helper type for receiving `ManagerReturnValue`s from the real `Manager`.
|
||||
|
@ -36,9 +27,9 @@ type ManagerReturnValueReceiver = Receiver<ManagerReturnValue>;
|
|||
/// `ManagerArguments::Stop` is a special variant that stops the background thread and drops the
|
||||
/// `Manager`.
|
||||
enum ManagerArguments {
|
||||
OpenSession(SlotType),
|
||||
OpenSession,
|
||||
CloseSession(CK_SESSION_HANDLE),
|
||||
CloseAllSessions(SlotType),
|
||||
CloseAllSessions,
|
||||
StartSearch(CK_SESSION_HANDLE, Vec<(CK_ATTRIBUTE_TYPE, Vec<u8>)>),
|
||||
Search(CK_SESSION_HANDLE, usize),
|
||||
ClearSearch(CK_SESSION_HANDLE),
|
||||
|
@ -112,16 +103,14 @@ impl ManagerProxy {
|
|||
}
|
||||
};
|
||||
let results = match arguments {
|
||||
ManagerArguments::OpenSession(slot_type) => {
|
||||
ManagerReturnValue::OpenSession(real_manager.open_session(slot_type))
|
||||
ManagerArguments::OpenSession => {
|
||||
ManagerReturnValue::OpenSession(real_manager.open_session())
|
||||
}
|
||||
ManagerArguments::CloseSession(session_handle) => {
|
||||
ManagerReturnValue::CloseSession(real_manager.close_session(session_handle))
|
||||
}
|
||||
ManagerArguments::CloseAllSessions(slot_type) => {
|
||||
ManagerReturnValue::CloseAllSessions(
|
||||
real_manager.close_all_sessions(slot_type),
|
||||
)
|
||||
ManagerArguments::CloseAllSessions => {
|
||||
ManagerReturnValue::CloseAllSessions(real_manager.close_all_sessions())
|
||||
}
|
||||
ManagerArguments::StartSearch(session, attrs) => {
|
||||
ManagerReturnValue::StartSearch(real_manager.start_search(session, &attrs))
|
||||
|
@ -196,10 +185,10 @@ impl ManagerProxy {
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn open_session(&mut self, slot_type: SlotType) -> Result<CK_SESSION_HANDLE, ()> {
|
||||
pub fn open_session(&mut self) -> Result<CK_SESSION_HANDLE, ()> {
|
||||
manager_proxy_fn_impl!(
|
||||
self,
|
||||
ManagerArguments::OpenSession(slot_type),
|
||||
ManagerArguments::OpenSession,
|
||||
ManagerReturnValue::OpenSession
|
||||
)
|
||||
}
|
||||
|
@ -212,10 +201,10 @@ impl ManagerProxy {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn close_all_sessions(&mut self, slot_type: SlotType) -> Result<(), ()> {
|
||||
pub fn close_all_sessions(&mut self) -> Result<(), ()> {
|
||||
manager_proxy_fn_impl!(
|
||||
self,
|
||||
ManagerArguments::CloseAllSessions(slot_type),
|
||||
ManagerArguments::CloseAllSessions,
|
||||
ManagerReturnValue::CloseAllSessions
|
||||
)
|
||||
}
|
||||
|
@ -352,9 +341,8 @@ fn search_is_for_all_certificates_or_keys(
|
|||
/// specification. This includes what sessions are open, which search and sign operations are
|
||||
/// ongoing, and what objects are known and by what handle.
|
||||
struct Manager {
|
||||
/// A map of session to session type (modern or legacy). Sessions can be created (opened) and
|
||||
/// later closed.
|
||||
sessions: BTreeMap<CK_SESSION_HANDLE, SlotType>,
|
||||
/// A set of sessions. Sessions can be created (opened) and later closed.
|
||||
sessions: BTreeSet<CK_SESSION_HANDLE>,
|
||||
/// A map of searches to PKCS #11 object handles that match those searches.
|
||||
searches: BTreeMap<CK_SESSION_HANDLE, Vec<CK_OBJECT_HANDLE>>,
|
||||
/// A map of sign operations to a pair of the object handle and optionally some params being
|
||||
|
@ -379,7 +367,7 @@ struct Manager {
|
|||
impl Manager {
|
||||
pub fn new() -> Manager {
|
||||
let mut manager = Manager {
|
||||
sessions: BTreeMap::new(),
|
||||
sessions: BTreeSet::new(),
|
||||
searches: BTreeMap::new(),
|
||||
signs: BTreeMap::new(),
|
||||
objects: BTreeMap::new(),
|
||||
|
@ -432,29 +420,23 @@ impl Manager {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn open_session(&mut self, slot_type: SlotType) -> Result<CK_SESSION_HANDLE, ()> {
|
||||
pub fn open_session(&mut self) -> Result<CK_SESSION_HANDLE, ()> {
|
||||
let next_session = self.next_session;
|
||||
self.next_session += 1;
|
||||
self.sessions.insert(next_session, slot_type);
|
||||
self.sessions.insert(next_session);
|
||||
Ok(next_session)
|
||||
}
|
||||
|
||||
pub fn close_session(&mut self, session: CK_SESSION_HANDLE) -> Result<(), ()> {
|
||||
self.sessions.remove(&session).ok_or(()).map(|_| ())
|
||||
if self.sessions.remove(&session) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn close_all_sessions(&mut self, slot_type: SlotType) -> Result<(), ()> {
|
||||
let mut to_remove = Vec::new();
|
||||
for (session, open_slot_type) in self.sessions.iter() {
|
||||
if slot_type == *open_slot_type {
|
||||
to_remove.push(*session);
|
||||
}
|
||||
}
|
||||
for session in to_remove {
|
||||
if self.sessions.remove(&session).is_none() {
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
pub fn close_all_sessions(&mut self) -> Result<(), ()> {
|
||||
self.sessions.clear();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -473,10 +455,9 @@ impl Manager {
|
|||
session: CK_SESSION_HANDLE,
|
||||
attrs: &[(CK_ATTRIBUTE_TYPE, Vec<u8>)],
|
||||
) -> Result<(), ()> {
|
||||
let slot_type = match self.sessions.get(&session) {
|
||||
Some(slot_type) => *slot_type,
|
||||
None => return Err(()),
|
||||
};
|
||||
if self.searches.contains_key(&session) {
|
||||
return Err(());
|
||||
}
|
||||
// If the search is for an attribute we don't support, no objects will match. This check
|
||||
// saves us having to look through all of our objects.
|
||||
for (attr, _) in attrs {
|
||||
|
@ -495,7 +476,7 @@ impl Manager {
|
|||
}
|
||||
let mut handles = Vec::new();
|
||||
for (handle, object) in &self.objects {
|
||||
if object.matches(slot_type, attrs) {
|
||||
if object.matches(attrs) {
|
||||
handles.push(*handle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,7 @@ async function check_osclientcerts_module_loaded() {
|
|||
slot => slot.name
|
||||
);
|
||||
testModuleSlotNames.sort();
|
||||
const expectedSlotNames = [
|
||||
"OS Client Cert Slot (Legacy)",
|
||||
"OS Client Cert Slot (Modern)",
|
||||
];
|
||||
const expectedSlotNames = ["OS Client Cert Slot"];
|
||||
deepEqual(
|
||||
testModuleSlotNames,
|
||||
expectedSlotNames,
|
||||
|
|
Загрузка…
Ссылка в новой задаче