// 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::fmt::Debug; use security_framework::key::SecKey; use tracing::instrument; use native_pkcs11_traits::{Backend, KeyAlgorithm, PrivateKey, PublicKey, SignatureAlgorithm}; use native_pkcs11_traits::Result as P11Result; #[derive(Debug)] pub enum Algorithm { RSA, ECC, } #[derive(Debug)] pub struct YubikeyPivPrivateKey { sec_key: SecKey, label: String, public_key_hash: Vec, algorithm: KeyAlgorithm, pub_key: Option, } impl YubikeyPivPrivateKey { // #[instrument] // pub fn new( // sec_key: SecKey, // label: impl Into + Debug, // pub_key: Option, // ) -> Result { // let label = label.into(); // let public_key_hash = sec_key.application_label().ok_or("no application_label")?; // Ok(Self { // algorithm: sec_key_algorithm(&sec_key)?, // sec_key, // label, // public_key_hash, // pub_key, // }) // } } impl PrivateKey for YubikeyPivPrivateKey { #[instrument] fn public_key_hash(&self) -> Vec { self.public_key_hash.clone() } #[instrument] fn label(&self) -> String { self.label.clone() } #[instrument] fn sign( &self, algorithm: &SignatureAlgorithm, data: &[u8], ) -> P11Result> { match algorithm { SignatureAlgorithm::Ecdsa => {} SignatureAlgorithm::RsaRaw => {} SignatureAlgorithm::RsaPkcs1v15Raw => {} SignatureAlgorithm::RsaPkcs1v15Sha1 => {} SignatureAlgorithm::RsaPkcs1v15Sha384 => {} SignatureAlgorithm::RsaPkcs1v15Sha256 => {} SignatureAlgorithm::RsaPkcs1v15Sha512 => {} SignatureAlgorithm::RsaPss { .. } => {} } // TODO sign data or hash?? Ok(vec![]) } #[instrument] fn delete(&self) { // yubikey-piv-pkcs11 just cannot delete private key } #[instrument] fn algorithm(&self) -> KeyAlgorithm { self.algorithm } fn find_public_key( &self, _backend: &dyn Backend, ) -> P11Result>> { Ok(None) } } #[derive(Debug, Clone)] pub struct YubikeyPivPublicKey { pub sec_key: SecKey, pub label: String, der: Vec, public_key_hash: Vec, algorithm: KeyAlgorithm, } impl YubikeyPivPublicKey { // #[instrument] // pub fn new(sec_key: SecKey, label: impl Into + Debug) -> Result { // let der = sec_key // .external_representation() // .ok_or("no external representation")?; // let key_ty = sec_key_algorithm(&sec_key)?; // Ok(Self { // public_key_hash: sec_key.application_label().ok_or("no application_label")?, // sec_key, // label: label.into(), // der: der.to_vec(), // algorithm: key_ty, // }) // } } impl PublicKey for YubikeyPivPublicKey { #[instrument] fn public_key_hash(&self) -> Vec { self.public_key_hash.clone() } #[instrument] fn label(&self) -> String { self.label.clone() } #[instrument] fn to_der(&self) -> Vec { self.der.clone() } #[instrument] fn verify( &self, algorithm: &SignatureAlgorithm, data: &[u8], signature: &[u8], ) -> P11Result<()> { // let algorithm = sigalg_to_seckeyalg(algorithm)?; // let result = self.sec_key.verify_signature(algorithm, data, signature)?; // if !result { // return Err("verify failed")?; // } Ok(()) } fn delete(self: Box) { let _ = self.sec_key.delete(); } fn algorithm(&self) -> KeyAlgorithm { self.algorithm } }