feat: update native-pkcs11-piv

This commit is contained in:
2024-07-06 19:29:38 +08:00
parent d8a2309b95
commit a77e6ff44e
3 changed files with 67 additions and 54 deletions

View File

@@ -18,11 +18,18 @@ use core_foundation::{
base::{TCFType, ToVoid},
string::CFString,
};
use native_pkcs11_traits::Backend;
use security_framework::{item::KeyClass, key::SecKey};
use security_framework_sys::item::kSecAttrLabel;
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;
use crate::{
certificate::{find_all_certificates, YubikeyPivCertificate},
key::{
@@ -51,7 +58,7 @@ impl Backend for YubikeyPivBackend {
#[instrument]
fn find_all_certificates(
&self,
) -> native_pkcs11_traits::Result<Vec<Box<dyn native_pkcs11_traits::Certificate>>> {
) -> P11Result<Vec<Box<dyn P11Certificate>>> {
let certs = find_all_certificates()?
.into_iter()
.map(YubikeyPivCertificate::new)
@@ -64,8 +71,8 @@ impl Backend for YubikeyPivBackend {
#[instrument]
fn find_private_key(
&self,
query: native_pkcs11_traits::KeySearchOptions,
) -> native_pkcs11_traits::Result<Option<Arc<dyn native_pkcs11_traits::PrivateKey>>> {
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()
@@ -82,7 +89,7 @@ impl Backend for YubikeyPivBackend {
.and_then(|sec_key| YubikeyPivPublicKey::new(sec_key, "").ok())
};
let opt_key = match query {
native_pkcs11_traits::KeySearchOptions::Label(label) => {
P11KeySearchOptions::Label(label) => {
find_key(KeyClass::private(), &label)
.ok()
.map(|sec_key| {
@@ -91,7 +98,7 @@ impl Backend for YubikeyPivBackend {
})
.transpose()?
}
native_pkcs11_traits::KeySearchOptions::PublicKeyHash(public_key_hash) => {
P11KeySearchOptions::PublicKeyHash(public_key_hash) => {
find_key2(KeyClass::private(), &public_key_hash)?
.map(|sec_key| {
let cert = find_pubkey_for_seckey(&sec_key);
@@ -106,16 +113,16 @@ impl Backend for YubikeyPivBackend {
#[instrument]
fn find_public_key(
&self,
query: native_pkcs11_traits::KeySearchOptions,
) -> native_pkcs11_traits::Result<Option<Box<dyn native_pkcs11_traits::PublicKey>>> {
query: P11KeySearchOptions,
) -> P11Result<Option<Box<dyn P11PublicKey>>> {
let opt_key = match query {
native_pkcs11_traits::KeySearchOptions::Label(label) => {
P11KeySearchOptions::Label(label) => {
find_key(KeyClass::public(), &label)
.ok()
.map(|sec_key| YubikeyPivPublicKey::new(sec_key, label))
.transpose()?
}
native_pkcs11_traits::KeySearchOptions::PublicKeyHash(public_key_hash) => {
P11KeySearchOptions::PublicKeyHash(public_key_hash) => {
find_key2(KeyClass::public(), &public_key_hash)?
.map(|sec_key| YubikeyPivPublicKey::new(sec_key, ""))
.transpose()?
@@ -127,15 +134,15 @@ impl Backend for YubikeyPivBackend {
#[instrument]
fn generate_key(
&self,
_algorithm: native_pkcs11_traits::KeyAlgorithm,
_algorithm: P11KeyAlgorithm,
_label: Option<&str>,
) -> native_pkcs11_traits::Result<Arc<dyn native_pkcs11_traits::PrivateKey>> {
) -> P11Result<Arc<dyn P11PrivateKey>> {
Err("Generate key not supported, please use ykman, URL: https://hatter.in/ykman")?
}
fn find_all_private_keys(
&self,
) -> native_pkcs11_traits::Result<Vec<Arc<dyn native_pkcs11_traits::PrivateKey>>> {
) -> P11Result<Vec<Arc<dyn P11PrivateKey>>> {
let sec_keys = find_all_keys(KeyClass::private())?;
let keys = sec_keys
.into_iter()
@@ -157,7 +164,7 @@ impl Backend for YubikeyPivBackend {
fn find_all_public_keys(
&self,
) -> native_pkcs11_traits::Result<Vec<Arc<dyn native_pkcs11_traits::PublicKey>>> {
) -> P11Result<Vec<Arc<dyn P11PublicKey>>> {
let sec_keys = find_all_keys(KeyClass::public())?;
let keys = sec_keys

View File

@@ -17,7 +17,6 @@ use std::{
time::{Duration, SystemTime},
};
use native_pkcs11_traits::random_label;
use rsa::{pkcs1::DecodeRsaPublicKey, pkcs8::AssociatedOid};
use security_framework::{
certificate::SecCertificate,
@@ -28,33 +27,36 @@ use security_framework::{
};
use security_framework_sys::base::errSecItemNotFound;
use x509_cert::{
Certificate,
der::{
asn1::{GeneralizedTime, Ia5String, OctetString},
oid::ObjectIdentifier,
Decode,
Encode,
oid::ObjectIdentifier,
},
ext::{
Extension,
pkix::{
name::GeneralName,
AuthorityKeyIdentifier,
BasicConstraints,
ExtendedKeyUsage,
KeyUsage,
KeyUsages,
name::GeneralName,
SubjectAltName,
SubjectKeyIdentifier,
},
Extension,
},
name::{Name, RdnSequence},
serial_number::SerialNumber,
spki::{der::asn1::BitString, EncodePublicKey, SubjectPublicKeyInfo},
time::Validity,
Certificate,
TbsCertificate,
time::Validity,
};
use native_pkcs11_traits::Certificate as P11Certificate;
use native_pkcs11_traits::random_label;
use crate::{
key::{Algorithm, YubikeyPivPublicKey},
keychain,
@@ -91,7 +93,7 @@ impl std::fmt::Debug for YubikeyPivCertificate {
}
}
impl native_pkcs11_traits::Certificate for YubikeyPivCertificate {
impl P11Certificate for YubikeyPivCertificate {
fn label(&self) -> String {
self.label.to_string()
}
@@ -115,9 +117,9 @@ pub fn import_certificate(der: &[u8]) -> Result<SecCertificate> {
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();
.set_location(keychain::location()?)
.set_label(cert.subject_summary())
.to_dictionary();
add_item(add_params)?;
Ok(cert)
@@ -197,17 +199,17 @@ pub fn import_identity(certificate: &SecCertificate) -> Result<SecIdentity> {
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();
.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)
}
if e.message() == Some("The specified item already exists in the keychain.".into()) =>
{
Ok(identity)
}
Err(e) => Err(e.into()),
}
}
@@ -256,19 +258,19 @@ pub fn self_signed_certificate(key_algorithm: Algorithm, private_key: &SecKey) -
let key_usage = KeyUsage(
KeyUsages::DigitalSignature | KeyUsages::KeyEncipherment | KeyUsages::KeyAgreement,
)
.to_der()?;
.to_der()?;
let extended_key_usage = ExtendedKeyUsage(vec![
EXTENDED_KEY_USAGE_CLIENT_AUTHENTICATION,
EXTENDED_KEY_USAGE_SERVER_AUTHENTICATION,
])
.to_der()?;
.to_der()?;
let basic_constraints = BasicConstraints {
ca: false,
path_len_constraint: None,
}
.to_der()?;
.to_der()?;
let sk_and_ak_id = random_serial_number();
let sk_id = SubjectKeyIdentifier(OctetString::new(sk_and_ak_id)?).to_der()?;
@@ -277,7 +279,7 @@ pub fn self_signed_certificate(key_algorithm: Algorithm, private_key: &SecKey) -
authority_cert_issuer: None,
authority_cert_serial_number: None,
}
.to_der()?;
.to_der()?;
let tbs_certificate = TbsCertificate {
version: x509_cert::Version::V3,

View File

@@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::fmt::Debug;
use core_foundation::base::ToVoid;
use native_pkcs11_traits::{KeyAlgorithm, PrivateKey, PublicKey, SignatureAlgorithm};
use security_framework::{
item::{ItemClass, KeyClass, Limit, Reference},
key::SecKey,
@@ -25,9 +26,12 @@ use security_framework_sys::item::{
kSecAttrKeyTypeRSA,
kSecAttrTokenID,
};
use std::fmt::Debug;
use tracing::instrument;
use native_pkcs11_traits::{KeyAlgorithm, PrivateKey, PublicKey, SignatureAlgorithm};
use native_pkcs11_traits::DigestType as P11DigestType;
use native_pkcs11_traits::Result as P11Result;
use crate::Result;
#[derive(Debug)]
@@ -41,22 +45,22 @@ fn sigalg_to_seckeyalg(
) -> Result<security_framework_sys::key::Algorithm> {
use security_framework_sys::key::Algorithm::*;
let alg = match signature_algorithm {
native_pkcs11_traits::SignatureAlgorithm::Ecdsa => ECDSASignatureRFC4754,
native_pkcs11_traits::SignatureAlgorithm::RsaRaw => RSASignatureRaw,
native_pkcs11_traits::SignatureAlgorithm::RsaPkcs1v15Raw => RSASignatureDigestPKCS1v15Raw,
native_pkcs11_traits::SignatureAlgorithm::RsaPkcs1v15Sha1 => {
SignatureAlgorithm::Ecdsa => ECDSASignatureRFC4754,
SignatureAlgorithm::RsaRaw => RSASignatureRaw,
SignatureAlgorithm::RsaPkcs1v15Raw => RSASignatureDigestPKCS1v15Raw,
SignatureAlgorithm::RsaPkcs1v15Sha1 => {
RSASignatureMessagePKCS1v15SHA1
}
native_pkcs11_traits::SignatureAlgorithm::RsaPkcs1v15Sha384 => {
SignatureAlgorithm::RsaPkcs1v15Sha384 => {
RSASignatureMessagePKCS1v15SHA384
}
native_pkcs11_traits::SignatureAlgorithm::RsaPkcs1v15Sha256 => {
SignatureAlgorithm::RsaPkcs1v15Sha256 => {
RSASignatureMessagePKCS1v15SHA256
}
native_pkcs11_traits::SignatureAlgorithm::RsaPkcs1v15Sha512 => {
SignatureAlgorithm::RsaPkcs1v15Sha512 => {
RSASignatureMessagePKCS1v15SHA512
}
native_pkcs11_traits::SignatureAlgorithm::RsaPss {
SignatureAlgorithm::RsaPss {
digest,
mask_generation_function,
salt_length,
@@ -69,11 +73,11 @@ fn sigalg_to_seckeyalg(
.into());
}
match mask_generation_function {
native_pkcs11_traits::DigestType::Sha1 => RSASignatureDigestPSSSHA1,
native_pkcs11_traits::DigestType::Sha224 => RSASignatureDigestPSSSHA224,
native_pkcs11_traits::DigestType::Sha256 => RSASignatureDigestPSSSHA256,
native_pkcs11_traits::DigestType::Sha384 => RSASignatureDigestPSSSHA384,
native_pkcs11_traits::DigestType::Sha512 => RSASignatureDigestPSSSHA512,
P11DigestType::Sha1 => RSASignatureDigestPSSSHA1,
P11DigestType::Sha224 => RSASignatureDigestPSSSHA224,
P11DigestType::Sha256 => RSASignatureDigestPSSSHA256,
P11DigestType::Sha384 => RSASignatureDigestPSSSHA384,
P11DigestType::Sha512 => RSASignatureDigestPSSSHA512,
}
}
};
@@ -122,9 +126,9 @@ impl PrivateKey for YubikeyPivPrivateKey {
#[instrument]
fn sign(
&self,
algorithm: &native_pkcs11_traits::SignatureAlgorithm,
algorithm: &SignatureAlgorithm,
data: &[u8],
) -> native_pkcs11_traits::Result<Vec<u8>> {
) -> P11Result<Vec<u8>> {
let algorithm = sigalg_to_seckeyalg(algorithm)?;
Ok(self.sec_key.create_signature(algorithm, data.as_ref())?)
}
@@ -141,7 +145,7 @@ impl PrivateKey for YubikeyPivPrivateKey {
fn find_public_key(
&self,
_backend: &dyn native_pkcs11_traits::Backend,
) -> native_pkcs11_traits::Result<Option<Box<dyn PublicKey>>> {
) -> P11Result<Option<Box<dyn PublicKey>>> {
let sec_copy = self
.sec_key
.public_key()
@@ -229,7 +233,7 @@ impl PublicKey for YubikeyPivPublicKey {
algorithm: &native_pkcs11_traits::SignatureAlgorithm,
data: &[u8],
signature: &[u8],
) -> native_pkcs11_traits::Result<()> {
) -> P11Result<()> {
let algorithm = sigalg_to_seckeyalg(algorithm)?;
let result = self.sec_key.verify_signature(algorithm, data, signature)?;
if !result {