feat: update pkcs11 piv

This commit is contained in:
2024-07-06 19:44:10 +08:00
parent a77e6ff44e
commit 1b174db255
6 changed files with 219 additions and 480 deletions

View File

@@ -12,14 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::{collections::HashMap, sync::Arc};
use std::sync::Arc;
use core_foundation::{
base::{TCFType, ToVoid},
string::CFString,
};
use security_framework::{item::KeyClass, key::SecKey};
use security_framework_sys::item::kSecAttrLabel;
use tracing::instrument;
use native_pkcs11_traits::Backend;
@@ -30,17 +24,6 @@ use native_pkcs11_traits::PrivateKey as P11PrivateKey;
use native_pkcs11_traits::PublicKey as P11PublicKey;
use native_pkcs11_traits::Result as P11Result;
use crate::{
certificate::{find_all_certificates, YubikeyPivCertificate},
key::{
find_all_keys,
find_key,
find_key2,
YubikeyPivPrivateKey,
YubikeyPivPublicKey,
},
};
#[derive(Debug, Default)]
pub struct YubikeyPivBackend;
@@ -52,20 +35,21 @@ impl YubikeyPivBackend {
impl Backend for YubikeyPivBackend {
fn name(&self) -> String {
"Keychain".into()
"Yubikey PIV".into()
}
#[instrument]
fn find_all_certificates(
&self,
) -> P11Result<Vec<Box<dyn P11Certificate>>> {
let certs = find_all_certificates()?
.into_iter()
.map(YubikeyPivCertificate::new)
.filter_map(Result::ok)
.map(|cert| Box::new(cert) as _)
.collect();
Ok(certs)
Ok(vec![])
// let certs = find_all_certificates()?
// .into_iter()
// .map(YubikeyPivCertificate::new)
// .filter_map(Result::ok)
// .map(|cert| Box::new(cert) as _)
// .collect();
// Ok(certs)
}
#[instrument]
@@ -73,41 +57,42 @@ impl Backend for YubikeyPivBackend {
&self,
query: P11KeySearchOptions,
) -> P11Result<Option<Arc<dyn P11PrivateKey>>> {
let mut pubkeys_by_pubkey_hash: HashMap<Vec<u8>, SecKey> =
HashMap::from_iter(find_all_certificates()?.into_iter().filter_map(|c| {
c.certificate()
.ok()
.and_then(|cert| cert.public_key().ok())
.and_then(|pk| pk.application_label().map(|pubkey_hash| (pubkey_hash, pk)))
}));
let mut find_pubkey_for_seckey = |sec_key: &SecKey| -> Option<YubikeyPivPublicKey> {
sec_key
.application_label()
.and_then(|pubkey_hash| pubkeys_by_pubkey_hash.remove(&pubkey_hash))
// TODO(kcking): populate label if searching by label
.and_then(|sec_key| YubikeyPivPublicKey::new(sec_key, "").ok())
};
let opt_key = match query {
P11KeySearchOptions::Label(label) => {
find_key(KeyClass::private(), &label)
.ok()
.map(|sec_key| {
let cert = find_pubkey_for_seckey(&sec_key);
YubikeyPivPrivateKey::new(sec_key, label, cert)
})
.transpose()?
}
P11KeySearchOptions::PublicKeyHash(public_key_hash) => {
find_key2(KeyClass::private(), &public_key_hash)?
.map(|sec_key| {
let cert = find_pubkey_for_seckey(&sec_key);
YubikeyPivPrivateKey::new(sec_key, "", cert)
})
.transpose()?
}
};
Ok(opt_key.map(|sec_key| Arc::new(sec_key) as _))
Ok(None)
// let mut pubkeys_by_pubkey_hash: HashMap<Vec<u8>, SecKey> =
// HashMap::from_iter(find_all_certificates()?.into_iter().filter_map(|c| {
// c.certificate()
// .ok()
// .and_then(|cert| cert.public_key().ok())
// .and_then(|pk| pk.application_label().map(|pubkey_hash| (pubkey_hash, pk)))
// }));
//
// let mut find_pubkey_for_seckey = |sec_key: &SecKey| -> Option<YubikeyPivPublicKey> {
// sec_key
// .application_label()
// .and_then(|pubkey_hash| pubkeys_by_pubkey_hash.remove(&pubkey_hash))
// // TODO(kcking): populate label if searching by label
// .and_then(|sec_key| YubikeyPivPublicKey::new(sec_key, "").ok())
// };
// let opt_key = match query {
// P11KeySearchOptions::Label(label) => {
// find_key(KeyClass::private(), &label)
// .ok()
// .map(|sec_key| {
// let cert = find_pubkey_for_seckey(&sec_key);
// YubikeyPivPrivateKey::new(sec_key, label, cert)
// })
// .transpose()?
// }
// P11KeySearchOptions::PublicKeyHash(public_key_hash) => {
// find_key2(KeyClass::private(), &public_key_hash)?
// .map(|sec_key| {
// let cert = find_pubkey_for_seckey(&sec_key);
// YubikeyPivPrivateKey::new(sec_key, "", cert)
// })
// .transpose()?
// }
// };
// Ok(opt_key.map(|sec_key| Arc::new(sec_key) as _))
}
#[instrument]
@@ -115,20 +100,68 @@ impl Backend for YubikeyPivBackend {
&self,
query: P11KeySearchOptions,
) -> P11Result<Option<Box<dyn P11PublicKey>>> {
let opt_key = match query {
P11KeySearchOptions::Label(label) => {
find_key(KeyClass::public(), &label)
.ok()
.map(|sec_key| YubikeyPivPublicKey::new(sec_key, label))
.transpose()?
Ok(None)
// let opt_key = match query {
// P11KeySearchOptions::Label(label) => {
// find_key(KeyClass::public(), &label)
// .ok()
// .map(|sec_key| YubikeyPivPublicKey::new(sec_key, label))
// .transpose()?
// }
// P11KeySearchOptions::PublicKeyHash(public_key_hash) => {
// find_key2(KeyClass::public(), &public_key_hash)?
// .map(|sec_key| YubikeyPivPublicKey::new(sec_key, ""))
// .transpose()?
// }
// };
// Ok(opt_key.map(|sec_key| Box::new(sec_key) as _))
}
P11KeySearchOptions::PublicKeyHash(public_key_hash) => {
find_key2(KeyClass::public(), &public_key_hash)?
.map(|sec_key| YubikeyPivPublicKey::new(sec_key, ""))
.transpose()?
fn find_all_private_keys(
&self,
) -> P11Result<Vec<Arc<dyn P11PrivateKey>>> {
Ok(vec![])
// let sec_keys = find_all_keys(KeyClass::private())?;
// let keys = sec_keys
// .into_iter()
// .filter_map(|sec_key| {
// let label: Option<String> = sec_key
// .attributes()
// .find(unsafe { kSecAttrLabel }.to_void())
// .map(|label| {
// unsafe { CFString::wrap_under_get_rule(label.cast()) }.to_string()
// });
// let label: String = label.unwrap_or_default();
//
// YubikeyPivPrivateKey::new(sec_key, label, None).ok()
// })
// .map(|k| Arc::new(k) as _);
//
// Ok(keys.collect())
}
};
Ok(opt_key.map(|sec_key| Box::new(sec_key) as _))
fn find_all_public_keys(
&self,
) -> P11Result<Vec<Arc<dyn P11PublicKey>>> {
Ok(vec![])
// let sec_keys = find_all_keys(KeyClass::public())?;
//
// let keys = sec_keys
// .into_iter()
// .filter_map(|sec_key| {
// let label: Option<String> = sec_key
// .attributes()
// .find(unsafe { kSecAttrLabel }.to_void())
// .map(|label| {
// unsafe { CFString::wrap_under_get_rule(label.cast()) }.to_string()
// });
// let label: String = label.unwrap_or_default();
//
// YubikeyPivPublicKey::new(sec_key, label).ok()
// })
// .map(|k| Arc::new(k) as _);
//
// Ok(keys.collect())
}
#[instrument]
@@ -139,49 +172,4 @@ impl Backend for YubikeyPivBackend {
) -> P11Result<Arc<dyn P11PrivateKey>> {
Err("Generate key not supported, please use ykman, URL: https://hatter.in/ykman")?
}
fn find_all_private_keys(
&self,
) -> P11Result<Vec<Arc<dyn P11PrivateKey>>> {
let sec_keys = find_all_keys(KeyClass::private())?;
let keys = sec_keys
.into_iter()
.filter_map(|sec_key| {
let label: Option<String> = sec_key
.attributes()
.find(unsafe { kSecAttrLabel }.to_void())
.map(|label| {
unsafe { CFString::wrap_under_get_rule(label.cast()) }.to_string()
});
let label: String = label.unwrap_or_default();
YubikeyPivPrivateKey::new(sec_key, label, None).ok()
})
.map(|k| Arc::new(k) as _);
Ok(keys.collect())
}
fn find_all_public_keys(
&self,
) -> P11Result<Vec<Arc<dyn P11PublicKey>>> {
let sec_keys = find_all_keys(KeyClass::public())?;
let keys = sec_keys
.into_iter()
.filter_map(|sec_key| {
let label: Option<String> = sec_key
.attributes()
.find(unsafe { kSecAttrLabel }.to_void())
.map(|label| {
unsafe { CFString::wrap_under_get_rule(label.cast()) }.to_string()
});
let label: String = label.unwrap_or_default();
YubikeyPivPublicKey::new(sec_key, label).ok()
})
.map(|k| Arc::new(k) as _);
Ok(keys.collect())
}
}

View File

@@ -59,7 +59,6 @@ use native_pkcs11_traits::random_label;
use crate::{
key::{Algorithm, YubikeyPivPublicKey},
keychain,
Result,
};
@@ -112,247 +111,43 @@ impl P11Certificate for YubikeyPivCertificate {
}
pub fn import_certificate(der: &[u8]) -> Result<SecCertificate> {
let cert = SecCertificate::from_der(der)?;
let add_params = ItemAddOptions::new(security_framework::item::ItemAddValue::Ref(
AddRef::Certificate(cert.clone()),
))
.set_location(keychain::location()?)
.set_label(cert.subject_summary())
.to_dictionary();
add_item(add_params)?;
Ok(cert)
Err("")?
// let cert = SecCertificate::from_der(der)?;
//
// let add_params = ItemAddOptions::new(security_framework::item::ItemAddValue::Ref(
// AddRef::Certificate(cert.clone()),
// ))
// .set_location(keychain::location()?)
// .set_label(cert.subject_summary())
// .to_dictionary();
// add_item(add_params)?;
//
// Ok(cert)
}
pub fn find_certificate(pub_key_hash: &[u8]) -> Result<Option<SecIdentity>> {
let results = crate::piv::keychain::item_search_options()?
.load_refs(true)
.class(ItemClass::certificate())
.pub_key_hash(pub_key_hash)
.search()?;
if results.is_empty() {
return Ok(None);
}
let cert = match results.into_iter().next().ok_or("certificate not found")? {
security_framework::item::SearchResult::Ref(Reference::Certificate(certificate)) => {
certificate
}
_ => return Err("no key ref")?,
};
Ok(Some(SecIdentity::with_certificate(&[], &cert)?))
}
pub fn find_all_certificates() -> Result<Vec<SecIdentity>> {
let results = crate::piv::keychain::item_search_options()?
.load_refs(true)
.class(ItemClass::identity())
.limit(99)
.search();
if let Err(e) = results {
if e.code() == errSecItemNotFound {
return Ok(vec![]);
}
}
let loaded_identites = results?
.into_iter()
.filter_map(|result| match result {
security_framework::item::SearchResult::Ref(Reference::Identity(identity)) => {
Some(identity)
}
_ => None,
})
.collect();
Ok(loaded_identites)
}
// NOTE(kcking): After some empirical tests, it appears SecIdentity is really
// just a SecCertificate that happens to have an associated SecKey private key
// in the keychain. Both `SecItemAdd` and `SecItemDelete` treat a SecIdentity
// like it is the underlying SecCertificate. Further reading:
// https://stackoverflow.com/a/13041370.
Ok(None)
// let results = crate::piv::keychain::item_search_options()?
// .load_refs(true)
// .class(ItemClass::certificate())
// .pub_key_hash(pub_key_hash)
// .search()?;
//
// For example, if we import a SecCertificate, then convert it to a SecIdentity
// with SecIdentity::with_certificate, trying to import the resulting
// SecIdentity will error with "already exists". Keychain is treating this
// scenario as trying to import the same certificate twice.
// if results.is_empty() {
// return Ok(None);
// }
//
// An official Apple source also _hints_ at this behavior by saying "working
// with identities as keychain items is very much like working with
// certificates"
// https://developer.apple.com/documentation/security/certificate_key_and_trust_services/identities/storing_an_identity_in_the_keychain?language=objc.
// let cert = match results.into_iter().next().ok_or("certificate not found")? {
// security_framework::item::SearchResult::Ref(Reference::Certificate(certificate)) => {
// certificate
// }
// _ => return Err("no key ref")?,
// };
//
// Overall, this means storing SecIdentities isn't any more useful to us than
// storing SecCertificates. The main use case is using
// `SecIdentity::with_certificate` to search for the private key corresponding
// to a certificate.
pub fn import_identity(certificate: &SecCertificate) -> Result<SecIdentity> {
let keychain = keychain::keychain_or_default()?;
let identity = SecIdentity::with_certificate(&[keychain], certificate)?;
let add_params = ItemAddOptions::new(security_framework::item::ItemAddValue::Ref(
AddRef::Identity(identity.clone()),
))
.set_location(keychain::location()?)
.set_label(certificate.subject_summary())
.to_dictionary();
match add_item(add_params) {
Ok(_) => Ok(identity),
Err(e)
if e.message() == Some("The specified item already exists in the keychain.".into()) =>
{
Ok(identity)
}
Err(e) => Err(e.into()),
}
// Ok(Some(SecIdentity::with_certificate(&[], &cert)?))
}
pub fn random_serial_number() -> [u8; 16] {
use rand::Rng;
rand::thread_rng().gen::<u128>().to_be_bytes()
}
const EXTENDED_KEY_USAGE_SERVER_AUTHENTICATION: ObjectIdentifier =
ObjectIdentifier::new_unwrap("1.3.6.1.5.5.7.3.1");
const EXTENDED_KEY_USAGE_CLIENT_AUTHENTICATION: ObjectIdentifier =
ObjectIdentifier::new_unwrap("1.3.6.1.5.5.7.3.2");
/// Demonstrate signing a certificate
pub fn self_signed_certificate(key_algorithm: Algorithm, private_key: &SecKey) -> Result<Vec<u8>> {
let public_key = private_key
.public_key()
.ok_or("no public key")?
.external_representation()
.ok_or("no external representation")?
.to_vec();
let public_key = match key_algorithm {
Algorithm::RSA => rsa::RsaPublicKey::from_pkcs1_der(&public_key)?
.to_public_key_der()?
.as_bytes()
.to_owned(),
Algorithm::ECC => p256::PublicKey::from_sec1_bytes(public_key.as_slice())?
.to_public_key_der()?
.as_bytes()
.to_owned(),
};
let spki = SubjectPublicKeyInfo::try_from(public_key.as_slice())?;
let subject_name =
RdnSequence::from_str(&format!("cn=Test Cert {}", random_label()))?.to_der()?;
let issuer_name = RdnSequence::from_str("cn=GShoe LLC")?.to_der()?;
let serial_number = random_serial_number();
let san = GeneralName::DnsName(Ia5String::new("localhost")?);
let san = SubjectAltName(vec![san]).to_der()?;
let key_usage = KeyUsage(
KeyUsages::DigitalSignature | KeyUsages::KeyEncipherment | KeyUsages::KeyAgreement,
)
.to_der()?;
let extended_key_usage = ExtendedKeyUsage(vec![
EXTENDED_KEY_USAGE_CLIENT_AUTHENTICATION,
EXTENDED_KEY_USAGE_SERVER_AUTHENTICATION,
])
.to_der()?;
let basic_constraints = BasicConstraints {
ca: false,
path_len_constraint: None,
}
.to_der()?;
let sk_and_ak_id = random_serial_number();
let sk_id = SubjectKeyIdentifier(OctetString::new(sk_and_ak_id)?).to_der()?;
let ak_id = AuthorityKeyIdentifier {
key_identifier: Some(OctetString::new(sk_and_ak_id)?),
authority_cert_issuer: None,
authority_cert_serial_number: None,
}
.to_der()?;
let tbs_certificate = TbsCertificate {
version: x509_cert::Version::V3,
// NOTE: can't be empty
serial_number: SerialNumber::new(&serial_number)?,
signature: spki.algorithm.clone(),
issuer: Name::from_der(&issuer_name)?,
validity: Validity {
not_before: x509_cert::time::Time::GeneralTime(GeneralizedTime::from_system_time(
SystemTime::now() - Duration::from_secs(60 * 60 * 24),
)?),
not_after: x509_cert::time::Time::GeneralTime(GeneralizedTime::from_system_time(
SystemTime::now() + Duration::from_secs(60 * 60 * 24),
)?),
},
subject: Name::from_der(&subject_name)?,
subject_public_key_info: spki.clone(),
// webpki appears to not support these fields:
// https://github.com/briansmith/webpki/blob/17d9189981a618120fd8217a913828e7418e2484/src/cert.rs#L78
issuer_unique_id: None,
subject_unique_id: None,
extensions: Some(vec![
Extension {
extn_id: BasicConstraints::OID,
critical: true,
extn_value: OctetString::new(basic_constraints)?,
},
Extension {
extn_id: SubjectAltName::OID,
critical: false,
extn_value: OctetString::new(san)?,
},
Extension {
extn_id: KeyUsage::OID,
critical: true,
extn_value: OctetString::new(key_usage)?,
},
Extension {
extn_id: ExtendedKeyUsage::OID,
critical: false,
extn_value: OctetString::new(extended_key_usage)?,
},
Extension {
extn_id: SubjectKeyIdentifier::OID,
critical: false,
extn_value: OctetString::new(sk_id)?,
},
Extension {
extn_id: AuthorityKeyIdentifier::OID,
critical: false,
extn_value: OctetString::new(ak_id)?,
},
]),
};
let payload = tbs_certificate.to_der()?;
let signature = private_key.create_signature(
match key_algorithm {
Algorithm::RSA => security_framework_sys::key::Algorithm::RSASignatureMessagePSSSHA256,
Algorithm::ECC => {
security_framework_sys::key::Algorithm::ECDSASignatureMessageX962SHA256
}
},
&payload,
)?;
let cert = Certificate {
tbs_certificate,
signature_algorithm: spki.algorithm,
signature: BitString::from_bytes(signature.as_slice())?,
};
Ok(cert.to_der()?)
}

View File

@@ -252,72 +252,75 @@ impl PublicKey for YubikeyPivPublicKey {
}
pub fn find_key(class: KeyClass, label: &str) -> Result<SecKey> {
let results = crate::keychain::item_search_options()?
.load_refs(true)
.label(label)
.class(ItemClass::key())
.key_class(class)
.limit(1)
.search();
let loaded_key = match results?.into_iter().next().ok_or("key not found")? {
security_framework::item::SearchResult::Ref(Reference::Key(key)) => key,
_ => return Err("no key ref")?,
};
Ok(loaded_key)
Err("")?
// let results = crate::keychain::item_search_options()?
// .load_refs(true)
// .label(label)
// .class(ItemClass::key())
// .key_class(class)
// .limit(1)
// .search();
//
// let loaded_key = match results?.into_iter().next().ok_or("key not found")? {
// security_framework::item::SearchResult::Ref(Reference::Key(key)) => key,
// _ => return Err("no key ref")?,
// };
//
// Ok(loaded_key)
}
#[instrument]
pub fn find_key2(class: KeyClass, label: &[u8]) -> Result<Option<SecKey>> {
let results = crate::keychain::item_search_options()?
.load_refs(true)
.class(ItemClass::key())
.key_class(class)
.application_label(label)
.limit(1)
.search();
let results = match results {
Err(e) if e.code() == -25300 => return Ok(None),
Err(e) => return Err(e)?,
Ok(results) => results,
};
let loaded_key = results
.into_iter()
.next()
.map(|key| match key {
security_framework::item::SearchResult::Ref(Reference::Key(key)) => Ok::<_, &str>(key),
_ => Err("no key ref")?,
})
.transpose()?;
Ok(loaded_key)
Ok(None)
// let results = crate::keychain::item_search_options()?
// .load_refs(true)
// .class(ItemClass::key())
// .key_class(class)
// .application_label(label)
// .limit(1)
// .search();
//
// let results = match results {
// Err(e) if e.code() == -25300 => return Ok(None),
// Err(e) => return Err(e)?,
// Ok(results) => results,
// };
//
// let loaded_key = results
// .into_iter()
// .next()
// .map(|key| match key {
// security_framework::item::SearchResult::Ref(Reference::Key(key)) => Ok::<_, &str>(key),
// _ => Err("no key ref")?,
// })
// .transpose()?;
//
// Ok(loaded_key)
}
#[instrument]
pub fn find_all_keys(key_class: KeyClass) -> Result<Vec<SecKey>> {
let results = crate::keychain::item_search_options()?
.load_refs(true)
.class(ItemClass::key())
.key_class(key_class)
.limit(Limit::All)
.search();
let results = match results {
Err(e) if e.code() == -25300 => return Ok(vec![]),
Err(e) => return Err(e)?,
Ok(results) => results,
};
let keys = results
.into_iter()
.filter_map(|res| match res {
security_framework::item::SearchResult::Ref(Reference::Key(key)) => Some(key),
_ => None,
})
.collect();
Ok(keys)
Ok(vec![])
// let results = crate::keychain::item_search_options()?
// .load_refs(true)
// .class(ItemClass::key())
// .key_class(key_class)
// .limit(Limit::All)
// .search();
//
// let results = match results {
// Err(e) if e.code() == -25300 => return Ok(vec![]),
// Err(e) => return Err(e)?,
// Ok(results) => results,
// };
//
// let keys = results
// .into_iter()
// .filter_map(|res| match res {
// security_framework::item::SearchResult::Ref(Reference::Key(key)) => Some(key),
// _ => None,
// })
// .collect();
//
// Ok(keys)
}

View File

@@ -1,49 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use security_framework::{
item::{ItemSearchOptions, Location},
os::macos::{item::ItemSearchOptionsExt, keychain::SecKeychain},
};
use crate::Result;
fn keychain() -> Result<Option<SecKeychain>> {
match std::env::var("NATIVE_PKCS11_KEYCHAIN_PATH") {
Ok(path) => Ok(Some(SecKeychain::open(path)?)),
Err(_) => Ok(None),
}
}
pub(crate) fn keychain_or_default() -> Result<SecKeychain> {
match keychain()? {
Some(keychain) => Ok(keychain),
None => Ok(SecKeychain::default()?),
}
}
pub(crate) fn location() -> Result<Location> {
match keychain()? {
Some(keychain) => Ok(Location::FileKeychain(keychain)),
None => Ok(Location::DefaultFileKeychain),
}
}
pub fn item_search_options() -> Result<ItemSearchOptions> {
let mut opts = ItemSearchOptions::new();
if let Some(keychain) = keychain()? {
opts.keychains(&[keychain]);
}
Ok(opts)
}

View File

@@ -23,7 +23,6 @@ use tracing_error::SpanTrace;
mod backend;
pub mod certificate;
pub mod key;
pub mod keychain;
pub type Result<T> = std::result::Result<T, Error>;

View File

@@ -16,6 +16,19 @@
#![allow(clippy::missing_safety_doc)]
#![deny(unsafe_op_in_unsafe_fn)]
use std::{
cmp,
slice,
sync::{
atomic::{AtomicBool, Ordering},
Once,
},
};
use tracing::metadata::LevelFilter;
use tracing_error::ErrorLayer;
use tracing_subscriber::{EnvFilter, fmt::format::FmtSpan, prelude::*, Registry};
use native_pkcs11_core::{
attribute::{Attribute, Attributes},
mechanism::{parse_mechanism, SUPPORTED_SIGNATURE_MECHANISMS},
@@ -26,17 +39,6 @@ use native_pkcs11_traits::backend;
use pkcs11_sys::*;
// Export necessary items for registering a custom Backend.
pub use pkcs11_sys::{CK_FUNCTION_LIST, CK_FUNCTION_LIST_PTR_PTR, CK_RV, CKR_OK};
use std::{
cmp,
slice,
sync::{
atomic::{AtomicBool, Ordering},
Once,
},
};
use tracing::metadata::LevelFilter;
use tracing_error::ErrorLayer;
use tracing_subscriber::{EnvFilter, fmt::format::FmtSpan, prelude::*, Registry};
use crate::{
sessions::{FindContext, SignContext},
@@ -48,11 +50,11 @@ mod sessions;
mod utils;
const LIBRARY_DESCRIPTION: &[u8; 32] = b" ";
const MANUFACTURER_ID: &[u8; 32] = b"google ";
const MANUFACTURER_ID: &[u8; 32] = b"hatter ";
const SLOT_DESCRIPTION: &[u8; 64] =
b"Platform Cryptography Support ";
const SLOT_ID: CK_SLOT_ID = 1;
const TOKEN_MODEL: &[u8; 16] = b"software ";
const TOKEN_MODEL: &[u8; 16] = b"hardware ";
const TOKEN_SERIAL_NUMBER: &[u8; 16] = b"0000000000000000";
static INITIALIZED: AtomicBool = AtomicBool::new(false);
@@ -1076,9 +1078,10 @@ cryptoki_fn_not_supported!(
#[cfg(test)]
pub mod tests {
use serial_test::serial;
use std::ptr;
use serial_test::serial;
use super::*;
pub fn test_init() {