// 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 std::sync::Arc; use tracing::instrument; use native_pkcs11_traits::Backend; use native_pkcs11_traits::Certificate as P11Certificate; use native_pkcs11_traits::KeyAlgorithm as P11KeyAlgorithm; use native_pkcs11_traits::KeySearchOptions as P11KeySearchOptions; use native_pkcs11_traits::PrivateKey as P11PrivateKey; use native_pkcs11_traits::PublicKey as P11PublicKey; use native_pkcs11_traits::Result as P11Result; #[derive(Debug, Default)] pub struct YubikeyPivBackend; impl YubikeyPivBackend { pub fn new() -> Self { Self } } impl Backend for YubikeyPivBackend { fn name(&self) -> String { "Yubikey PIV".into() } #[instrument] fn find_all_certificates( &self, ) -> P11Result>> { 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] fn find_private_key( &self, query: P11KeySearchOptions, ) -> P11Result>> { Ok(None) // let mut pubkeys_by_pubkey_hash: HashMap, 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 { // 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] fn find_public_key( &self, query: P11KeySearchOptions, ) -> P11Result>> { 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 _)) } fn find_all_private_keys( &self, ) -> P11Result>> { Ok(vec![]) // let sec_keys = find_all_keys(KeyClass::private())?; // let keys = sec_keys // .into_iter() // .filter_map(|sec_key| { // let label: Option = 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>> { Ok(vec![]) // let sec_keys = find_all_keys(KeyClass::public())?; // // let keys = sec_keys // .into_iter() // .filter_map(|sec_key| { // let label: Option = 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] fn generate_key( &self, _algorithm: P11KeyAlgorithm, _label: Option<&str>, ) -> P11Result> { Err("Generate key not supported, please use ykman, URL: https://hatter.in/ykman")? } }