diff --git a/Cargo.lock b/Cargo.lock
index 60efea9..4eca4d3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -11,6 +11,45 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "asn1-rs"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22ad1373757efa0f70ec53939aabc7152e1591cb485208052993070ac8d2429d"
+dependencies = [
+ "asn1-rs-derive",
+ "asn1-rs-impl",
+ "displaydoc",
+ "nom",
+ "num-traits",
+ "rusticata-macros",
+ "thiserror",
+ "time",
+]
+
+[[package]]
+name = "asn1-rs-derive"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7378575ff571966e99a744addeff0bff98b8ada0dedf1956d59e634db95eaac1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "asn1-rs-impl"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "autocfg"
version = "1.3.0"
@@ -164,6 +203,12 @@ dependencies = [
"typenum",
]
+[[package]]
+name = "data-encoding"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
+
[[package]]
name = "der"
version = "0.7.9"
@@ -177,6 +222,20 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "der-parser"
+version = "9.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553"
+dependencies = [
+ "asn1-rs",
+ "displaydoc",
+ "nom",
+ "num-bigint",
+ "num-traits",
+ "rusticata-macros",
+]
+
[[package]]
name = "der_derive"
version = "0.7.2"
@@ -188,6 +247,15 @@ dependencies = [
"syn",
]
+[[package]]
+name = "deranged"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
+dependencies = [
+ "powerfmt",
+]
+
[[package]]
name = "des"
version = "0.8.1"
@@ -209,6 +277,17 @@ dependencies = [
"subtle",
]
+[[package]]
+name = "displaydoc"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "ecdsa"
version = "0.16.9"
@@ -381,6 +460,12 @@ dependencies = [
"either",
]
+[[package]]
+name = "itoa"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -508,11 +593,13 @@ dependencies = [
"rsa",
"secrecy",
"serial_test",
+ "sha1",
"spki",
"thiserror",
"tracing",
"tracing-error",
"x509-cert",
+ "x509-parser",
"yubikey",
]
@@ -545,6 +632,16 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "num-bigint"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
+dependencies = [
+ "num-integer",
+ "num-traits",
+]
+
[[package]]
name = "num-bigint-dig"
version = "0.8.4"
@@ -563,6 +660,12 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
[[package]]
name = "num-integer"
version = "0.1.46"
@@ -593,6 +696,15 @@ dependencies = [
"libm",
]
+[[package]]
+name = "oid-registry"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d"
+dependencies = [
+ "asn1-rs",
+]
+
[[package]]
name = "once_cell"
version = "1.19.0"
@@ -750,6 +862,12 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
[[package]]
name = "ppv-lite86"
version = "0.2.17"
@@ -934,6 +1052,15 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+[[package]]
+name = "rusticata-macros"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632"
+dependencies = [
+ "nom",
+]
+
[[package]]
name = "rustix"
version = "0.38.34"
@@ -1145,6 +1272,17 @@ dependencies = [
"unicode-ident",
]
+[[package]]
+name = "synstructure"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "thiserror"
version = "1.0.61"
@@ -1175,6 +1313,37 @@ dependencies = [
"once_cell",
]
+[[package]]
+name = "time"
+version = "0.3.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
+dependencies = [
+ "deranged",
+ "itoa",
+ "num-conv",
+ "powerfmt",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+
+[[package]]
+name = "time-macros"
+version = "0.2.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
+dependencies = [
+ "num-conv",
+ "time-core",
+]
+
[[package]]
name = "tls_codec"
version = "0.4.1"
@@ -1504,6 +1673,23 @@ dependencies = [
"tls_codec",
]
+[[package]]
+name = "x509-parser"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69"
+dependencies = [
+ "asn1-rs",
+ "data-encoding",
+ "der-parser",
+ "lazy_static",
+ "nom",
+ "oid-registry",
+ "rusticata-macros",
+ "thiserror",
+ "time",
+]
+
[[package]]
name = "yubikey"
version = "0.8.0"
diff --git a/README.md b/README.md
index a58ce8c..bb2914c 100644
--- a/README.md
+++ b/README.md
@@ -3,3 +3,16 @@ Yubikey PIV PKCS#11
> Fork form: https://github.com/google/native-pkcs11
+
+
+Alias:
+```shell
+alias p11='pkcs11-tool --module /FULLPATH/libyubikey_piv_pkcs11.dylib'
+```
+
+List certificates
+```shell
+p11 --list-object --type cert
+```
+
+
diff --git a/native-pkcs11-piv/Cargo.toml b/native-pkcs11-piv/Cargo.toml
index fcb9bbf..74b75a9 100644
--- a/native-pkcs11-piv/Cargo.toml
+++ b/native-pkcs11-piv/Cargo.toml
@@ -28,6 +28,8 @@ tracing = "0.1.40"
tracing-error = { version = "0.2.0", default-features = false }
x509-cert = { version = "0.2.5", default-features = false }
yubikey = { version = "0.8.0", features = ["untested"] }
+sha1 = "0.10"
+x509-parser = "0.16.0"
[dev-dependencies]
serial_test = { version = "3.1.1", default-features = false }
diff --git a/native-pkcs11-piv/src/piv/backend.rs b/native-pkcs11-piv/src/piv/backend.rs
index c07b7af..bd77097 100644
--- a/native-pkcs11-piv/src/piv/backend.rs
+++ b/native-pkcs11-piv/src/piv/backend.rs
@@ -15,6 +15,9 @@
use std::sync::{Arc, Mutex};
use tracing::instrument;
+use x509_cert::der::Encode;
+use x509_parser::nom::Parser;
+use yubikey::piv::AlgorithmId;
use yubikey::YubiKey;
use native_pkcs11_traits::{Backend, KeySearchOptions};
@@ -25,6 +28,9 @@ use native_pkcs11_traits::PrivateKey as P11PrivateKey;
use native_pkcs11_traits::PublicKey as P11PublicKey;
use native_pkcs11_traits::Result as P11Result;
+use crate::certificate::YubikeyPivCertificate;
+use crate::piv::util::get_algorithm_id_by_certificate;
+
#[derive(Debug, Default)]
pub struct YubikeyPivBackend {
cached_pin: Mutex