176 lines
6.2 KiB
Rust
176 lines
6.2 KiB
Rust
// 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<Vec<Box<dyn P11Certificate>>> {
|
|
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<Option<Arc<dyn P11PrivateKey>>> {
|
|
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]
|
|
fn find_public_key(
|
|
&self,
|
|
query: P11KeySearchOptions,
|
|
) -> P11Result<Option<Box<dyn P11PublicKey>>> {
|
|
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<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())
|
|
}
|
|
|
|
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]
|
|
fn generate_key(
|
|
&self,
|
|
_algorithm: P11KeyAlgorithm,
|
|
_label: Option<&str>,
|
|
) -> P11Result<Arc<dyn P11PrivateKey>> {
|
|
Err("Generate key not supported, please use ykman, URL: https://hatter.in/ykman")?
|
|
}
|
|
}
|