Add Curve25519 support (#577)
Supported in PIV applet since firmware 5.7.X
This commit is contained in:
Generated
+84
-2
@@ -187,9 +187,9 @@ checksum = "0dabb6555f92fb9ee4140454eb5dcd14c7960e1225c6d1a6cc361f032947713e"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.11"
|
version = "0.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0"
|
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@@ -229,6 +229,33 @@ dependencies = [
|
|||||||
"rand_core",
|
"rand_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "curve25519-dalek"
|
||||||
|
version = "5.0.0-pre.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f9200d1d13637f15a6acb71e758f64624048d85b31a5fdbfd8eca1e2687d0b7"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"curve25519-dalek-derive",
|
||||||
|
"digest",
|
||||||
|
"fiat-crypto",
|
||||||
|
"rustc_version",
|
||||||
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "curve25519-dalek-derive"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "der"
|
name = "der"
|
||||||
version = "0.8.0-rc.9"
|
version = "0.8.0-rc.9"
|
||||||
@@ -289,6 +316,31 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ed25519"
|
||||||
|
version = "3.0.0-rc.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ef49c0b20c0ad088893ad2a790a29c06a012b3f05bcfc66661fd22a94b32129"
|
||||||
|
dependencies = [
|
||||||
|
"pkcs8",
|
||||||
|
"signature",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ed25519-dalek"
|
||||||
|
version = "3.0.0-pre.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad207ed88a133091f83224265eac21109930db09bedcad05d5252f2af2de20a1"
|
||||||
|
dependencies = [
|
||||||
|
"curve25519-dalek",
|
||||||
|
"ed25519",
|
||||||
|
"serde",
|
||||||
|
"sha2",
|
||||||
|
"signature",
|
||||||
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "elliptic-curve"
|
name = "elliptic-curve"
|
||||||
version = "0.14.0-rc.14"
|
version = "0.14.0-rc.14"
|
||||||
@@ -716,6 +768,15 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sec1"
|
name = "sec1"
|
||||||
version = "0.8.0-rc.10"
|
version = "0.8.0-rc.10"
|
||||||
@@ -738,6 +799,12 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.193"
|
version = "1.0.193"
|
||||||
@@ -1084,6 +1151,18 @@ dependencies = [
|
|||||||
"bitflags 2.5.0",
|
"bitflags 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "x25519-dalek"
|
||||||
|
version = "3.0.0-pre.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a45998121837fd8c92655d2334aa8f3e5ef0645cdfda5b321b13760c548fd55"
|
||||||
|
dependencies = [
|
||||||
|
"curve25519-dalek",
|
||||||
|
"rand_core",
|
||||||
|
"serde",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x509-cert"
|
name = "x509-cert"
|
||||||
version = "0.3.0-rc.2"
|
version = "0.3.0-rc.2"
|
||||||
@@ -1106,9 +1185,11 @@ dependencies = [
|
|||||||
"base16ct 0.2.0",
|
"base16ct 0.2.0",
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.5.0",
|
||||||
"cipher",
|
"cipher",
|
||||||
|
"curve25519-dalek",
|
||||||
"der",
|
"der",
|
||||||
"des",
|
"des",
|
||||||
"ecdsa",
|
"ecdsa",
|
||||||
|
"ed25519-dalek",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
@@ -1127,6 +1208,7 @@ dependencies = [
|
|||||||
"signature",
|
"signature",
|
||||||
"subtle",
|
"subtle",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
"x25519-dalek",
|
||||||
"x509-cert",
|
"x509-cert",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ ecdsa = { version = "0.17.0-rc.6", features = ["digest", "pem"] }
|
|||||||
p256 = "=0.14.0-pre.11"
|
p256 = "=0.14.0-pre.11"
|
||||||
p384 = "=0.14.0-pre.11"
|
p384 = "=0.14.0-pre.11"
|
||||||
pbkdf2 = { version = "0.13.0-rc.1", default-features = false, features = ["hmac"] }
|
pbkdf2 = { version = "0.13.0-rc.1", default-features = false, features = ["hmac"] }
|
||||||
|
curve25519-dalek = "5.0.0-pre.0"
|
||||||
|
x25519-dalek = "3.0.0-pre.0"
|
||||||
|
ed25519-dalek = { version = "3.0.0-pre.0", features = ["alloc", "pkcs8"] }
|
||||||
pcsc = "2.3.1"
|
pcsc = "2.3.1"
|
||||||
rand = "0.9"
|
rand = "0.9"
|
||||||
rand_core = { version = "0.9", features = ["os_rng"] }
|
rand_core = { version = "0.9", features = ["os_rng"] }
|
||||||
|
|||||||
+17
-1
@@ -278,7 +278,7 @@ pub mod yubikey_signer {
|
|||||||
oid::db::rfc5912,
|
oid::db::rfc5912,
|
||||||
Encode, Sequence,
|
Encode, Sequence,
|
||||||
};
|
};
|
||||||
use sha2::{Digest, Sha256, Sha384};
|
use sha2::{Digest, Sha256, Sha384, Sha512};
|
||||||
use signature::Keypair;
|
use signature::Keypair;
|
||||||
use std::{cell::RefCell, fmt, io::Write, marker::PhantomData};
|
use std::{cell::RefCell, fmt, io::Write, marker::PhantomData};
|
||||||
use x509_cert::spki::{
|
use x509_cert::spki::{
|
||||||
@@ -313,6 +313,22 @@ pub mod yubikey_signer {
|
|||||||
fn read_signature(input: &[u8]) -> SigResult<Self::Signature>;
|
fn read_signature(input: &[u8]) -> SigResult<Self::Signature>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl KeyType for ed25519_dalek::SigningKey {
|
||||||
|
const ALGORITHM: AlgorithmId = AlgorithmId::Ed25519;
|
||||||
|
type Error = ed25519_dalek::SignatureError;
|
||||||
|
type Signature = ed25519_dalek::Signature;
|
||||||
|
type VerifyingKey = ed25519_dalek::VerifyingKey;
|
||||||
|
type PublicKey = ed25519_dalek::VerifyingKey;
|
||||||
|
|
||||||
|
fn prepare(input: &[u8]) -> SigResult<Vec<u8>> {
|
||||||
|
Ok(Sha512::digest(input).to_vec())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_signature(input: &[u8]) -> SigResult<Self::Signature> {
|
||||||
|
Self::Signature::try_from(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl KeyType for p256::NistP256 {
|
impl KeyType for p256::NistP256 {
|
||||||
const ALGORITHM: AlgorithmId = AlgorithmId::EccP256;
|
const ALGORITHM: AlgorithmId = AlgorithmId::EccP256;
|
||||||
type Error = ecdsa::Error;
|
type Error = ecdsa::Error;
|
||||||
|
|||||||
+79
-1
@@ -62,7 +62,10 @@ use std::{
|
|||||||
fmt::{Display, Formatter},
|
fmt::{Display, Formatter},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
use x509_cert::{der::Decode, spki::SubjectPublicKeyInfoOwned};
|
use x509_cert::{
|
||||||
|
der::{asn1::BitString, Decode},
|
||||||
|
spki::{AlgorithmIdentifier, ObjectIdentifier, SubjectPublicKeyInfoOwned},
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
@@ -86,6 +89,9 @@ const TAG_RSA_MODULUS: u8 = 0x81;
|
|||||||
const TAG_RSA_EXP: u8 = 0x82;
|
const TAG_RSA_EXP: u8 = 0x82;
|
||||||
const TAG_ECC_POINT: u8 = 0x86;
|
const TAG_ECC_POINT: u8 = 0x86;
|
||||||
|
|
||||||
|
/// OID for ed25519 and x25519 algorithms
|
||||||
|
pub const OID_X25519: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.101.110");
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
const KEYDATA_LEN: usize = 1024;
|
const KEYDATA_LEN: usize = 1024;
|
||||||
|
|
||||||
@@ -492,6 +498,12 @@ pub enum AlgorithmId {
|
|||||||
|
|
||||||
/// ECDSA with the NIST P384 curve.
|
/// ECDSA with the NIST P384 curve.
|
||||||
EccP384,
|
EccP384,
|
||||||
|
|
||||||
|
/// ED25519
|
||||||
|
Ed25519,
|
||||||
|
|
||||||
|
/// X25519
|
||||||
|
X25519,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<u8> for AlgorithmId {
|
impl TryFrom<u8> for AlgorithmId {
|
||||||
@@ -505,6 +517,8 @@ impl TryFrom<u8> for AlgorithmId {
|
|||||||
0x16 => Ok(AlgorithmId::Rsa4096),
|
0x16 => Ok(AlgorithmId::Rsa4096),
|
||||||
0x11 => Ok(AlgorithmId::EccP256),
|
0x11 => Ok(AlgorithmId::EccP256),
|
||||||
0x14 => Ok(AlgorithmId::EccP384),
|
0x14 => Ok(AlgorithmId::EccP384),
|
||||||
|
0xE0 => Ok(AlgorithmId::Ed25519),
|
||||||
|
0xE1 => Ok(AlgorithmId::X25519),
|
||||||
_ => Err(Error::AlgorithmError),
|
_ => Err(Error::AlgorithmError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -519,6 +533,8 @@ impl From<AlgorithmId> for u8 {
|
|||||||
AlgorithmId::Rsa4096 => 0x16,
|
AlgorithmId::Rsa4096 => 0x16,
|
||||||
AlgorithmId::EccP256 => 0x11,
|
AlgorithmId::EccP256 => 0x11,
|
||||||
AlgorithmId::EccP384 => 0x14,
|
AlgorithmId::EccP384 => 0x14,
|
||||||
|
AlgorithmId::Ed25519 => 0xE0,
|
||||||
|
AlgorithmId::X25519 => 0xE1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -538,6 +554,8 @@ impl AlgorithmId {
|
|||||||
AlgorithmId::Rsa4096 => 256,
|
AlgorithmId::Rsa4096 => 256,
|
||||||
AlgorithmId::EccP256 => 32,
|
AlgorithmId::EccP256 => 32,
|
||||||
AlgorithmId::EccP384 => 48,
|
AlgorithmId::EccP384 => 48,
|
||||||
|
AlgorithmId::Ed25519 => 32,
|
||||||
|
AlgorithmId::X25519 => 32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -549,6 +567,8 @@ impl AlgorithmId {
|
|||||||
| AlgorithmId::Rsa3072
|
| AlgorithmId::Rsa3072
|
||||||
| AlgorithmId::Rsa4096 => 0x01,
|
| AlgorithmId::Rsa4096 => 0x01,
|
||||||
AlgorithmId::EccP256 | AlgorithmId::EccP384 => 0x6,
|
AlgorithmId::EccP256 | AlgorithmId::EccP384 => 0x6,
|
||||||
|
AlgorithmId::Ed25519 => 0x07,
|
||||||
|
AlgorithmId::X25519 => 0x08,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -898,6 +918,34 @@ pub fn import_ecc_key(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Imports a private ECDH/EdDSA encryption or signing key into the YubiKey.
|
||||||
|
///
|
||||||
|
/// Errors if `algorithm` isn't `AlgorithmId::Ed25519` or ` AlgorithmId::X25519`.
|
||||||
|
#[cfg(feature = "untested")]
|
||||||
|
pub fn import_cv_key(
|
||||||
|
yubikey: &mut YubiKey,
|
||||||
|
slot: SlotId,
|
||||||
|
algorithm: AlgorithmId,
|
||||||
|
key_data: &[u8],
|
||||||
|
touch_policy: TouchPolicy,
|
||||||
|
pin_policy: PinPolicy,
|
||||||
|
) -> Result<()> {
|
||||||
|
match algorithm {
|
||||||
|
AlgorithmId::Ed25519 | AlgorithmId::X25519 => (),
|
||||||
|
_ => return Err(Error::AlgorithmError),
|
||||||
|
}
|
||||||
|
|
||||||
|
if key_data.len() > KEYDATA_LEN {
|
||||||
|
return Err(Error::SizeError);
|
||||||
|
}
|
||||||
|
|
||||||
|
let params = vec![key_data];
|
||||||
|
|
||||||
|
write_key(yubikey, slot, params, pin_policy, touch_policy, algorithm)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Generate an attestation certificate for a stored key.
|
/// Generate an attestation certificate for a stored key.
|
||||||
///
|
///
|
||||||
/// <https://developers.yubico.com/PIV/Introduction/PIV_attestation.html>
|
/// <https://developers.yubico.com/PIV/Introduction/PIV_attestation.html>
|
||||||
@@ -1128,6 +1176,36 @@ fn read_public_key(
|
|||||||
//
|
//
|
||||||
// 0x7f 0x49 -> Application | Constructed | 0x49
|
// 0x7f 0x49 -> Application | Constructed | 0x49
|
||||||
match algorithm {
|
match algorithm {
|
||||||
|
AlgorithmId::X25519 | AlgorithmId::Ed25519 => {
|
||||||
|
// 2-byte ASN.1 tag, 1-byte length (because all supported EC pubkey lengths
|
||||||
|
// are shorter than 128 bytes, fitting into a definite short ASN.1 length).
|
||||||
|
let data = if skip_asn1_tag { &input[3..] } else { input };
|
||||||
|
|
||||||
|
let (_, tlv) = Tlv::parse(data)?;
|
||||||
|
let pk_data: [u8; 32] = tlv.value.try_into().map_err(|_| Error::InvalidObject)?;
|
||||||
|
|
||||||
|
match algorithm {
|
||||||
|
AlgorithmId::Ed25519 => SubjectPublicKeyInfoOwned::from_der(
|
||||||
|
ed25519_dalek::VerifyingKey::from_bytes(&pk_data)
|
||||||
|
.map_err(|_| Error::InvalidObject)?
|
||||||
|
.to_public_key_der()
|
||||||
|
.map_err(|_| Error::InvalidObject)?
|
||||||
|
.as_bytes(),
|
||||||
|
)
|
||||||
|
.map_err(|_| Error::InvalidObject),
|
||||||
|
AlgorithmId::X25519 => Ok(SubjectPublicKeyInfoOwned {
|
||||||
|
algorithm: AlgorithmIdentifier {
|
||||||
|
oid: OID_X25519,
|
||||||
|
parameters: None,
|
||||||
|
},
|
||||||
|
subject_public_key: BitString::from_bytes(
|
||||||
|
x25519_dalek::PublicKey::from(pk_data).as_bytes(),
|
||||||
|
)
|
||||||
|
.map_err(|_| Error::InvalidObject)?,
|
||||||
|
}),
|
||||||
|
_ => Err(Error::AlgorithmError),
|
||||||
|
}
|
||||||
|
}
|
||||||
AlgorithmId::Rsa1024
|
AlgorithmId::Rsa1024
|
||||||
| AlgorithmId::Rsa2048
|
| AlgorithmId::Rsa2048
|
||||||
| AlgorithmId::Rsa3072
|
| AlgorithmId::Rsa3072
|
||||||
|
|||||||
+16
-1
@@ -320,6 +320,19 @@ impl<'tx> Transaction<'tx> {
|
|||||||
return Err(Error::SizeError);
|
return Err(Error::SizeError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AlgorithmId::X25519 => {
|
||||||
|
if !decipher {
|
||||||
|
return Err(Error::NotSupported);
|
||||||
|
}
|
||||||
|
if in_len != 32 {
|
||||||
|
return Err(Error::SizeError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AlgorithmId::Ed25519 => {
|
||||||
|
if decipher {
|
||||||
|
return Err(Error::NotSupported);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let bytes = if in_len < 0x80 {
|
let bytes = if in_len < 0x80 {
|
||||||
@@ -336,7 +349,9 @@ impl<'tx> Transaction<'tx> {
|
|||||||
Tlv::write(
|
Tlv::write(
|
||||||
&mut buf[2..],
|
&mut buf[2..],
|
||||||
match (algorithm, decipher) {
|
match (algorithm, decipher) {
|
||||||
(AlgorithmId::EccP256, true) | (AlgorithmId::EccP384, true) => 0x85,
|
(AlgorithmId::EccP256, true)
|
||||||
|
| (AlgorithmId::EccP384, true)
|
||||||
|
| (AlgorithmId::X25519, true) => 0x85,
|
||||||
_ => 0x81,
|
_ => 0x81,
|
||||||
},
|
},
|
||||||
sign_in
|
sign_in
|
||||||
|
|||||||
+53
-7
@@ -43,7 +43,10 @@ static YUBIKEY: Lazy<Mutex<YubiKey>> = Lazy::new(|| {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_get_cccid() {
|
fn test_get_cccid() {
|
||||||
let mut yubikey = YUBIKEY.lock().unwrap();
|
let mut yubikey = match YUBIKEY.lock() {
|
||||||
|
Ok(yubikey) => yubikey,
|
||||||
|
Err(poison) => poison.into_inner(),
|
||||||
|
};
|
||||||
|
|
||||||
match yubikey.cccid() {
|
match yubikey.cccid() {
|
||||||
Ok(cccid) => trace!("CCCID: {:?}", cccid),
|
Ok(cccid) => trace!("CCCID: {:?}", cccid),
|
||||||
@@ -59,7 +62,10 @@ fn test_get_cccid() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_get_chuid() {
|
fn test_get_chuid() {
|
||||||
let mut yubikey = YUBIKEY.lock().unwrap();
|
let mut yubikey = match YUBIKEY.lock() {
|
||||||
|
Ok(yubikey) => yubikey,
|
||||||
|
Err(poison) => poison.into_inner(),
|
||||||
|
};
|
||||||
|
|
||||||
match yubikey.chuid() {
|
match yubikey.chuid() {
|
||||||
Ok(chuid) => trace!("CHUID: {:?}", chuid),
|
Ok(chuid) => trace!("CHUID: {:?}", chuid),
|
||||||
@@ -75,7 +81,10 @@ fn test_get_chuid() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_get_config() {
|
fn test_get_config() {
|
||||||
let mut yubikey = YUBIKEY.lock().unwrap();
|
let mut yubikey = match YUBIKEY.lock() {
|
||||||
|
Ok(yubikey) => yubikey,
|
||||||
|
Err(poison) => poison.into_inner(),
|
||||||
|
};
|
||||||
let config_result = yubikey.config();
|
let config_result = yubikey.config();
|
||||||
assert!(config_result.is_ok());
|
assert!(config_result.is_ok());
|
||||||
trace!("config: {:?}", config_result.unwrap());
|
trace!("config: {:?}", config_result.unwrap());
|
||||||
@@ -88,7 +97,10 @@ fn test_get_config() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_list_keys() {
|
fn test_list_keys() {
|
||||||
let mut yubikey = YUBIKEY.lock().unwrap();
|
let mut yubikey = match YUBIKEY.lock() {
|
||||||
|
Ok(yubikey) => yubikey,
|
||||||
|
Err(poison) => poison.into_inner(),
|
||||||
|
};
|
||||||
let keys_result = Key::list(&mut yubikey);
|
let keys_result = Key::list(&mut yubikey);
|
||||||
assert!(keys_result.is_ok());
|
assert!(keys_result.is_ok());
|
||||||
trace!("keys: {:?}", keys_result.unwrap());
|
trace!("keys: {:?}", keys_result.unwrap());
|
||||||
@@ -101,7 +113,10 @@ fn test_list_keys() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_verify_pin() {
|
fn test_verify_pin() {
|
||||||
let mut yubikey = YUBIKEY.lock().unwrap();
|
let mut yubikey = match YUBIKEY.lock() {
|
||||||
|
Ok(yubikey) => yubikey,
|
||||||
|
Err(poison) => poison.into_inner(),
|
||||||
|
};
|
||||||
assert!(yubikey.verify_pin(b"000000").is_err());
|
assert!(yubikey.verify_pin(b"000000").is_err());
|
||||||
assert!(yubikey.verify_pin(b"123456").is_ok());
|
assert!(yubikey.verify_pin(b"123456").is_ok());
|
||||||
}
|
}
|
||||||
@@ -115,7 +130,10 @@ fn test_verify_pin() {
|
|||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_set_mgmkey() {
|
fn test_set_mgmkey() {
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let mut yubikey = YUBIKEY.lock().unwrap();
|
let mut yubikey = match YUBIKEY.lock() {
|
||||||
|
Ok(yubikey) => yubikey,
|
||||||
|
Err(poison) => poison.into_inner(),
|
||||||
|
};
|
||||||
let default_key = MgmKey::get_default(&yubikey).unwrap();
|
let default_key = MgmKey::get_default(&yubikey).unwrap();
|
||||||
|
|
||||||
assert!(yubikey.verify_pin(b"123456").is_ok());
|
assert!(yubikey.verify_pin(b"123456").is_ok());
|
||||||
@@ -267,6 +285,31 @@ fn generate_self_signed_ec_cert() {
|
|||||||
assert!(vk.verify(msg, &sig).is_ok());
|
assert!(vk.verify(msg, &sig).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn generate_self_signed_cv_cert() {
|
||||||
|
let cert = generate_self_signed_cert::<ed25519_dalek::SigningKey>();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Verify that the certificate is signed correctly
|
||||||
|
//
|
||||||
|
|
||||||
|
let pubkey =
|
||||||
|
ed25519_dalek::VerifyingKey::try_from(cert.subject_pki()).expect("ed25519 key expected");
|
||||||
|
|
||||||
|
let data = cert.cert.to_der().expect("serialize certificate");
|
||||||
|
let cert_len = data[2] as usize;
|
||||||
|
let tbs_cert_len = data[5] as usize;
|
||||||
|
let sig_algo_len: usize = 64;
|
||||||
|
let sig_start = cert_len - sig_algo_len + 3;
|
||||||
|
let msg = &data[3..6 + tbs_cert_len];
|
||||||
|
let sig =
|
||||||
|
ed25519_dalek::Signature::from_slice(&data[sig_start..sig_start + sig_algo_len]).unwrap();
|
||||||
|
|
||||||
|
use ed25519_dalek::Verifier;
|
||||||
|
assert!(pubkey.verify(msg, &sig).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_slot_id_display() {
|
fn test_slot_id_display() {
|
||||||
@@ -320,7 +363,10 @@ fn test_slot_id_display() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_read_metadata() {
|
fn test_read_metadata() {
|
||||||
let mut yubikey = YUBIKEY.lock().unwrap();
|
let mut yubikey = match YUBIKEY.lock() {
|
||||||
|
Ok(yubikey) => yubikey,
|
||||||
|
Err(poison) => poison.into_inner(),
|
||||||
|
};
|
||||||
let default_key = MgmKey::get_default(&yubikey).unwrap();
|
let default_key = MgmKey::get_default(&yubikey).unwrap();
|
||||||
|
|
||||||
assert!(yubikey.verify_pin(b"123456").is_ok());
|
assert!(yubikey.verify_pin(b"123456").is_ok());
|
||||||
|
|||||||
Reference in New Issue
Block a user