Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ac72797d1f | |||
| fdd3b8730a | |||
| d51ec0a225 | |||
| d601c33ba3 | |||
| 8e52d75992 | |||
| 42ae5fb974 | |||
| 224d346f09 | |||
| 01e5bba33f | |||
| 48f42780df |
+19
-1
@@ -4,7 +4,25 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## 0.4.0 (2021-07-12)
|
## 0.4.2 (2021-07-13)
|
||||||
|
### Added
|
||||||
|
- Make `yubikey::Buffer` a pub type ([#290])
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Have `YubiKey::block_puk` take `&mut self` as argument ([#289])
|
||||||
|
|
||||||
|
[#289]: https://github.com/iqlusioninc/yubikey.rs/pull/289
|
||||||
|
[#290]: https://github.com/iqlusioninc/yubikey.rs/pull/290
|
||||||
|
|
||||||
|
## 0.4.1 (2021-07-12)
|
||||||
|
### Changed
|
||||||
|
- Rename `SettingValue` to `Setting` ([#286])
|
||||||
|
- Rename `Ccc` to `CccId` ([#287])
|
||||||
|
|
||||||
|
[#286]: https://github.com/iqlusioninc/yubikey.rs/pull/286
|
||||||
|
[#287]: https://github.com/iqlusioninc/yubikey.rs/pull/287
|
||||||
|
|
||||||
|
## 0.4.0 (2021-07-12) [YANKED]
|
||||||
### Added
|
### Added
|
||||||
- `Result` alias ([#271])
|
- `Result` alias ([#271])
|
||||||
|
|
||||||
|
|||||||
Generated
+2
-2
@@ -964,7 +964,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yubikey"
|
name = "yubikey"
|
||||||
version = "0.4.0"
|
version = "0.4.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"cookie-factory",
|
"cookie-factory",
|
||||||
@@ -998,7 +998,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yubikey-cli"
|
name = "yubikey-cli"
|
||||||
version = "0.4.0-pre"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"gumdrop",
|
"gumdrop",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "yubikey"
|
name = "yubikey"
|
||||||
version = "0.4.0" # Also update html_root_url in lib.rs when bumping this
|
version = "0.4.2" # Also update html_root_url in lib.rs when bumping this
|
||||||
description = """
|
description = """
|
||||||
Pure Rust cross-platform host-side driver for YubiKey devices from Yubico with
|
Pure Rust cross-platform host-side driver for YubiKey devices from Yubico with
|
||||||
support for hardware-backed public-key decryption and digital signatures using
|
support for hardware-backed public-key decryption and digital signatures using
|
||||||
|
|||||||
@@ -6,10 +6,8 @@
|
|||||||
[![Docs][docs-image]][docs-link]
|
[![Docs][docs-image]][docs-link]
|
||||||
[![2-Clause BSD Licensed][license-image]][license-link]
|
[![2-Clause BSD Licensed][license-image]][license-link]
|
||||||
![Rust Version][rustc-image]
|
![Rust Version][rustc-image]
|
||||||
![Maintenance Status: Experimental][maintenance-image]
|
|
||||||
[![Safety Dance][safety-image]][safety-link]
|
[![Safety Dance][safety-image]][safety-link]
|
||||||
[![Build Status][build-image]][build-link]
|
[![Build Status][build-image]][build-link]
|
||||||
[![Gitter Chat][gitter-image]][gitter-link]
|
|
||||||
|
|
||||||
Pure Rust cross-platform host-side driver for [YubiKey] devices from [Yubico]
|
Pure Rust cross-platform host-side driver for [YubiKey] devices from [Yubico]
|
||||||
with support for public-key encryption and digital signatures using the
|
with support for public-key encryption and digital signatures using the
|
||||||
@@ -167,13 +165,10 @@ or conditions.
|
|||||||
[license-image]: https://img.shields.io/badge/license-BSD-blue.svg
|
[license-image]: https://img.shields.io/badge/license-BSD-blue.svg
|
||||||
[license-link]: https://github.com/iqlusioninc/yubikey.rs/blob/main/COPYING
|
[license-link]: https://github.com/iqlusioninc/yubikey.rs/blob/main/COPYING
|
||||||
[rustc-image]: https://img.shields.io/badge/rustc-1.51+-blue.svg
|
[rustc-image]: https://img.shields.io/badge/rustc-1.51+-blue.svg
|
||||||
[maintenance-image]: https://img.shields.io/badge/maintenance-experimental-blue.svg
|
|
||||||
[safety-image]: https://img.shields.io/badge/unsafe-forbidden-success.svg
|
[safety-image]: https://img.shields.io/badge/unsafe-forbidden-success.svg
|
||||||
[safety-link]: https://github.com/rust-secure-code/safety-dance/
|
[safety-link]: https://github.com/rust-secure-code/safety-dance/
|
||||||
[build-image]: https://github.com/iqlusioninc/yubikey.rs/workflows/CI/badge.svg?branch=main&event=push
|
[build-image]: https://github.com/iqlusioninc/yubikey.rs/workflows/CI/badge.svg?branch=main&event=push
|
||||||
[build-link]: https://github.com/iqlusioninc/yubikey.rs/actions
|
[build-link]: https://github.com/iqlusioninc/yubikey.rs/actions
|
||||||
[gitter-image]: https://badges.gitter.im/badge.svg
|
|
||||||
[gitter-link]: https://gitter.im/iqlusioninc/community
|
|
||||||
|
|
||||||
[//]: # (general links)
|
[//]: # (general links)
|
||||||
|
|
||||||
|
|||||||
+10
-3
@@ -4,16 +4,23 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## 0.4.0 (2021-07-12)
|
||||||
|
### Changed
|
||||||
|
- Switch to renamed `yubikey` crate ([#283])
|
||||||
|
- Bump MSRV to 1.51+ ([#283])
|
||||||
|
|
||||||
|
[#283]: https://github.com/iqlusioninc/yubikey.rs/pull/283
|
||||||
|
|
||||||
## 0.3.0 (2021-03-22)
|
## 0.3.0 (2021-03-22)
|
||||||
### Changed
|
### Changed
|
||||||
- Bump `yubikey` dependency to v0.3 ([#240])
|
- Bump `yubikey-piv` dependency to v0.3 ([#240])
|
||||||
|
|
||||||
[#240]: https://github.com/iqlusioninc/yubikey.rs/pull/240
|
[#240]: https://github.com/iqlusioninc/yubikey.rs/pull/240
|
||||||
|
|
||||||
## 0.2.0 (2021-01-30)
|
## 0.2.0 (2021-01-30)
|
||||||
### Changed
|
### Changed
|
||||||
- Bump MSRV to 1.46+ ([#208])
|
- Bump MSRV to 1.46+ ([#208])
|
||||||
- Bump `yubikey` dependency to v0.2 ([#220])
|
- Bump `yubikey-piv` dependency to v0.2 ([#220])
|
||||||
|
|
||||||
[#208]: https://github.com/iqlusioninc/yubikey.rs/pull/208
|
[#208]: https://github.com/iqlusioninc/yubikey.rs/pull/208
|
||||||
[#220]: https://github.com/iqlusioninc/yubikey.rs/pull/220
|
[#220]: https://github.com/iqlusioninc/yubikey.rs/pull/220
|
||||||
@@ -23,7 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- `status` command ([#72], [#74])
|
- `status` command ([#72], [#74])
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Bump `yubikey` to v0.1.0 ([#180])
|
- Bump `yubikey-piv` to v0.1.0 ([#180])
|
||||||
- Bump `x509-parser` to v0.8 ([#181])
|
- Bump `x509-parser` to v0.8 ([#181])
|
||||||
- Bump `sha2` to v0.9 ([#182])
|
- Bump `sha2` to v0.9 ([#182])
|
||||||
- Rename `list` command to `readers`; improve usage ([#71])
|
- Rename `list` command to `readers`; improve usage ([#71])
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "yubikey-cli"
|
name = "yubikey-cli"
|
||||||
version = "0.4.0-pre"
|
version = "0.4.0"
|
||||||
description = """
|
description = """
|
||||||
Command-line interface for performing encryption and signing using RSA/ECC keys
|
Command-line interface for performing encryption and signing using RSA/ECC keys
|
||||||
stored on YubiKey devices.
|
stored on YubiKey devices.
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
//! Print device status
|
//! Print device status
|
||||||
|
|
||||||
use crate::terminal::STDOUT;
|
use crate::terminal::{print_cert_info, STDOUT};
|
||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use termcolor::{ColorSpec, StandardStreamLock, WriteColor};
|
use termcolor::{ColorSpec, StandardStreamLock, WriteColor};
|
||||||
use yubikey::{piv::*, YubiKey};
|
use yubikey::{piv::*, YubiKey};
|
||||||
|
|
||||||
use crate::print_cert_info;
|
|
||||||
|
|
||||||
// String to use for `None`
|
// String to use for `None`
|
||||||
const NONE_STR: &str = "<none>";
|
const NONE_STR: &str = "<none>";
|
||||||
|
|
||||||
|
|||||||
+6
-85
@@ -1,92 +1,13 @@
|
|||||||
//! `yubikey` command-line utility.
|
//! `yubikey` command-line utility.
|
||||||
|
//!
|
||||||
|
//! The goal of this tool is to provide functionality similar to `yubico-piv-tool`
|
||||||
|
//! but implemented in pure Rust.
|
||||||
|
//!
|
||||||
|
//! It also serves as a demonstration/example of how to use the `yubikey` crate.
|
||||||
|
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
#![warn(
|
#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
|
||||||
missing_docs,
|
|
||||||
rust_2018_idioms,
|
|
||||||
unused_lifetimes,
|
|
||||||
unused_qualifications
|
|
||||||
)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod terminal;
|
pub mod terminal;
|
||||||
|
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
|
|
||||||
use log::debug;
|
|
||||||
use sha2::{Digest, Sha256};
|
|
||||||
use std::io::{self, Write};
|
|
||||||
use std::str;
|
|
||||||
use subtle_encoding::hex;
|
|
||||||
use termcolor::{ColorSpec, StandardStreamLock, WriteColor};
|
|
||||||
use x509_parser::parse_x509_certificate;
|
|
||||||
use yubikey::{certificate::Certificate, piv::*, YubiKey};
|
|
||||||
|
|
||||||
/// Write information about certificate found in slot a la yubico-piv-tool output.
|
|
||||||
pub fn print_cert_info(
|
|
||||||
yubikey: &mut YubiKey,
|
|
||||||
slot: SlotId,
|
|
||||||
stream: &mut StandardStreamLock<'_>,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
let cert = match Certificate::read(yubikey, slot) {
|
|
||||||
Ok(c) => c,
|
|
||||||
Err(e) => {
|
|
||||||
debug!("error reading certificate in slot {:?}: {}", slot, e);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let buf = cert.into_buffer();
|
|
||||||
|
|
||||||
if !buf.is_empty() {
|
|
||||||
let fingerprint = Sha256::digest(&buf);
|
|
||||||
let slot_id: u8 = slot.into();
|
|
||||||
print_cert_attr(stream, "Slot", format!("{:x}", slot_id))?;
|
|
||||||
match parse_x509_certificate(&buf) {
|
|
||||||
Ok((_rem, cert)) => {
|
|
||||||
print_cert_attr(
|
|
||||||
stream,
|
|
||||||
"Algorithm",
|
|
||||||
cert.tbs_certificate.subject_pki.algorithm.algorithm,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
print_cert_attr(stream, "Subject", cert.tbs_certificate.subject)?;
|
|
||||||
print_cert_attr(stream, "Issuer", cert.tbs_certificate.issuer)?;
|
|
||||||
print_cert_attr(
|
|
||||||
stream,
|
|
||||||
"Fingerprint",
|
|
||||||
str::from_utf8(hex::encode(fingerprint).as_slice()).unwrap(),
|
|
||||||
)?;
|
|
||||||
print_cert_attr(
|
|
||||||
stream,
|
|
||||||
"Not Before",
|
|
||||||
cert.tbs_certificate.validity.not_before.to_rfc2822(),
|
|
||||||
)?;
|
|
||||||
print_cert_attr(
|
|
||||||
stream,
|
|
||||||
"Not After",
|
|
||||||
cert.tbs_certificate.validity.not_after.to_rfc2822(),
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
println!("Failed to parse certificate");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Print a status attribute
|
|
||||||
fn print_cert_attr(
|
|
||||||
stream: &mut StandardStreamLock<'_>,
|
|
||||||
name: &str,
|
|
||||||
value: impl ToString,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
stream.set_color(ColorSpec::new().set_bold(true))?;
|
|
||||||
write!(stream, "{:>12}:", name)?;
|
|
||||||
stream.reset()?;
|
|
||||||
writeln!(stream, " {}", value.to_string())?;
|
|
||||||
stream.flush()?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|||||||
+80
-3
@@ -1,9 +1,17 @@
|
|||||||
//! Status messages
|
//! Status messages
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::io::{self, Write};
|
use log::debug;
|
||||||
use std::sync::Mutex;
|
use sha2::{Digest, Sha256};
|
||||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
use std::{
|
||||||
|
io::{self, Write},
|
||||||
|
str,
|
||||||
|
sync::Mutex,
|
||||||
|
};
|
||||||
|
use subtle_encoding::hex;
|
||||||
|
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, StandardStreamLock, WriteColor};
|
||||||
|
use x509_parser::parse_x509_certificate;
|
||||||
|
use yubikey::{certificate::Certificate, piv::*, YubiKey};
|
||||||
|
|
||||||
/// Print a success status message (in green if colors are enabled)
|
/// Print a success status message (in green if colors are enabled)
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
@@ -163,3 +171,72 @@ impl Status {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Write information about certificate found in slot a la yubico-piv-tool output.
|
||||||
|
pub fn print_cert_info(
|
||||||
|
yubikey: &mut YubiKey,
|
||||||
|
slot: SlotId,
|
||||||
|
stream: &mut StandardStreamLock<'_>,
|
||||||
|
) -> io::Result<()> {
|
||||||
|
let cert = match Certificate::read(yubikey, slot) {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => {
|
||||||
|
debug!("error reading certificate in slot {:?}: {}", slot, e);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let buf = cert.into_buffer();
|
||||||
|
|
||||||
|
if !buf.is_empty() {
|
||||||
|
let fingerprint = Sha256::digest(&buf);
|
||||||
|
let slot_id: u8 = slot.into();
|
||||||
|
print_cert_attr(stream, "Slot", format!("{:x}", slot_id))?;
|
||||||
|
match parse_x509_certificate(&buf) {
|
||||||
|
Ok((_rem, cert)) => {
|
||||||
|
print_cert_attr(
|
||||||
|
stream,
|
||||||
|
"Algorithm",
|
||||||
|
cert.tbs_certificate.subject_pki.algorithm.algorithm,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
print_cert_attr(stream, "Subject", cert.tbs_certificate.subject)?;
|
||||||
|
print_cert_attr(stream, "Issuer", cert.tbs_certificate.issuer)?;
|
||||||
|
print_cert_attr(
|
||||||
|
stream,
|
||||||
|
"Fingerprint",
|
||||||
|
str::from_utf8(hex::encode(fingerprint).as_slice()).unwrap(),
|
||||||
|
)?;
|
||||||
|
print_cert_attr(
|
||||||
|
stream,
|
||||||
|
"Not Before",
|
||||||
|
cert.tbs_certificate.validity.not_before.to_rfc2822(),
|
||||||
|
)?;
|
||||||
|
print_cert_attr(
|
||||||
|
stream,
|
||||||
|
"Not After",
|
||||||
|
cert.tbs_certificate.validity.not_after.to_rfc2822(),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("Failed to parse certificate");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Print a status attribute
|
||||||
|
fn print_cert_attr(
|
||||||
|
stream: &mut StandardStreamLock<'_>,
|
||||||
|
name: &str,
|
||||||
|
value: impl ToString,
|
||||||
|
) -> io::Result<()> {
|
||||||
|
stream.set_color(ColorSpec::new().set_bold(true))?;
|
||||||
|
write!(stream, "{:>12}:", name)?;
|
||||||
|
stream.reset()?;
|
||||||
|
writeln!(stream, " {}", value.to_string())?;
|
||||||
|
stream.flush()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
+3
-3
@@ -78,9 +78,9 @@ impl CardId {
|
|||||||
|
|
||||||
/// Cardholder Capability Container (CCC) Identifier.
|
/// Cardholder Capability Container (CCC) Identifier.
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct Ccc(pub [u8; Self::BYTE_SIZE]);
|
pub struct CccId(pub [u8; Self::BYTE_SIZE]);
|
||||||
|
|
||||||
impl Ccc {
|
impl CccId {
|
||||||
/// CCC size in bytes
|
/// CCC size in bytes
|
||||||
pub const BYTE_SIZE: usize = 51;
|
pub const BYTE_SIZE: usize = 51;
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ impl Ccc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Ccc {
|
impl Display for CccId {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.write_str(str::from_utf8(&hex::encode(&self.0[..])).unwrap())
|
f.write_str(str::from_utf8(&hex::encode(&self.0[..])).unwrap())
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -131,7 +131,7 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc(
|
#![doc(
|
||||||
html_logo_url = "https://raw.githubusercontent.com/iqlusioninc/yubikey.rs/main/img/logo.png",
|
html_logo_url = "https://raw.githubusercontent.com/iqlusioninc/yubikey.rs/main/img/logo.png",
|
||||||
html_root_url = "https://docs.rs/yubikey/0.4.0"
|
html_root_url = "https://docs.rs/yubikey/0.4.2"
|
||||||
)]
|
)]
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
#![warn(missing_docs, rust_2018_idioms, trivial_casts, unused_qualifications)]
|
#![warn(missing_docs, rust_2018_idioms, trivial_casts, unused_qualifications)]
|
||||||
@@ -153,12 +153,12 @@ pub mod piv;
|
|||||||
mod policy;
|
mod policy;
|
||||||
pub mod reader;
|
pub mod reader;
|
||||||
mod serialization;
|
mod serialization;
|
||||||
mod settings;
|
mod setting;
|
||||||
mod transaction;
|
mod transaction;
|
||||||
mod yubikey;
|
mod yubikey;
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
cccid::{CardId, Ccc},
|
cccid::{CardId, CccId},
|
||||||
certificate::Certificate,
|
certificate::Certificate,
|
||||||
chuid::ChuId,
|
chuid::ChuId,
|
||||||
config::Config,
|
config::Config,
|
||||||
@@ -167,7 +167,7 @@ pub use crate::{
|
|||||||
piv::Key,
|
piv::Key,
|
||||||
policy::{PinPolicy, TouchPolicy},
|
policy::{PinPolicy, TouchPolicy},
|
||||||
reader::Context,
|
reader::Context,
|
||||||
settings::{SettingSource, SettingValue},
|
setting::{Setting, SettingSource},
|
||||||
yubikey::{CachedPin, Serial, Version, YubiKey},
|
yubikey::{CachedPin, Serial, Version, YubiKey},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -180,4 +180,4 @@ pub use uuid::Uuid;
|
|||||||
pub type ObjectId = u32;
|
pub type ObjectId = u32;
|
||||||
|
|
||||||
/// Buffer type (self-zeroizing byte vector)
|
/// Buffer type (self-zeroizing byte vector)
|
||||||
pub(crate) type Buffer = zeroize::Zeroizing<Vec<u8>>;
|
pub type Buffer = zeroize::Zeroizing<Vec<u8>>;
|
||||||
|
|||||||
+5
-5
@@ -48,7 +48,7 @@ use crate::{
|
|||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
policy::{PinPolicy, TouchPolicy},
|
policy::{PinPolicy, TouchPolicy},
|
||||||
serialization::*,
|
serialization::*,
|
||||||
settings,
|
setting,
|
||||||
yubikey::YubiKey,
|
yubikey::YubiKey,
|
||||||
Buffer, ObjectId,
|
Buffer, ObjectId,
|
||||||
};
|
};
|
||||||
@@ -481,7 +481,7 @@ pub fn generate(
|
|||||||
const SZ_ROCA_BLOCK_ADMIN: &str = "was blocked due to an administrator configuration setting.";
|
const SZ_ROCA_BLOCK_ADMIN: &str = "was blocked due to an administrator configuration setting.";
|
||||||
const SZ_ROCA_DEFAULT: &str = "was permitted by default, but is not recommended. The default behavior will change in a future Yubico release.";
|
const SZ_ROCA_DEFAULT: &str = "was permitted by default, but is not recommended. The default behavior will change in a future Yubico release.";
|
||||||
|
|
||||||
let setting_roca: settings::SettingValue;
|
let setting_roca: setting::Setting;
|
||||||
|
|
||||||
match algorithm {
|
match algorithm {
|
||||||
AlgorithmId::Rsa1024 | AlgorithmId::Rsa2048 => {
|
AlgorithmId::Rsa1024 | AlgorithmId::Rsa2048 => {
|
||||||
@@ -489,17 +489,17 @@ pub fn generate(
|
|||||||
&& (yubikey.version.minor < 3
|
&& (yubikey.version.minor < 3
|
||||||
|| yubikey.version.minor == 3 && (yubikey.version.patch < 5))
|
|| yubikey.version.minor == 3 && (yubikey.version.patch < 5))
|
||||||
{
|
{
|
||||||
setting_roca = settings::SettingValue::get(SZ_SETTING_ROCA, true);
|
setting_roca = setting::Setting::get(SZ_SETTING_ROCA, true);
|
||||||
|
|
||||||
let psz_msg = match setting_roca.source {
|
let psz_msg = match setting_roca.source {
|
||||||
settings::SettingSource::User => {
|
setting::SettingSource::User => {
|
||||||
if setting_roca.value {
|
if setting_roca.value {
|
||||||
SZ_ROCA_ALLOW_USER
|
SZ_ROCA_ALLOW_USER
|
||||||
} else {
|
} else {
|
||||||
SZ_ROCA_BLOCK_USER
|
SZ_ROCA_BLOCK_USER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
settings::SettingSource::Admin => {
|
setting::SettingSource::Admin => {
|
||||||
if setting_roca.value {
|
if setting_roca.value {
|
||||||
SZ_ROCA_ALLOW_ADMIN
|
SZ_ROCA_ALLOW_ADMIN
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ impl Default for SettingSource {
|
|||||||
/// system administrator, or by the local user via `YUBIKEY_PIV_*` environment
|
/// system administrator, or by the local user via `YUBIKEY_PIV_*` environment
|
||||||
/// variables.
|
/// variables.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct SettingValue {
|
pub struct Setting {
|
||||||
/// Boolean value
|
/// Boolean value
|
||||||
pub value: bool,
|
pub value: bool,
|
||||||
|
|
||||||
@@ -74,8 +74,8 @@ pub struct SettingValue {
|
|||||||
pub source: SettingSource,
|
pub source: SettingSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SettingValue {
|
impl Setting {
|
||||||
/// Get a [`SettingValue`] value by name.
|
/// Get a setting by name.
|
||||||
pub fn get(key: &str, default: bool) -> Self {
|
pub fn get(key: &str, default: bool) -> Self {
|
||||||
Self::from_file(key)
|
Self::from_file(key)
|
||||||
.or_else(|| Self::from_env(key))
|
.or_else(|| Self::from_env(key))
|
||||||
@@ -109,7 +109,7 @@ impl SettingValue {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if name == key {
|
if name == key {
|
||||||
return Some(SettingValue {
|
return Some(Setting {
|
||||||
source: SettingSource::Admin,
|
source: SettingSource::Admin,
|
||||||
value: value == "1" || value == "true",
|
value: value == "1" || value == "true",
|
||||||
});
|
});
|
||||||
@@ -124,14 +124,14 @@ impl SettingValue {
|
|||||||
fn from_env(key: &str) -> Option<Self> {
|
fn from_env(key: &str) -> Option<Self> {
|
||||||
env::var(format!("YUBIKEY_PIV_{}", key))
|
env::var(format!("YUBIKEY_PIV_{}", key))
|
||||||
.ok()
|
.ok()
|
||||||
.map(|value| SettingValue {
|
.map(|value| Setting {
|
||||||
source: SettingSource::User,
|
source: SettingSource::User,
|
||||||
value: value == "1" || value == "true",
|
value: value == "1" || value == "true",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SettingValue {
|
impl Default for Setting {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
value: false,
|
value: false,
|
||||||
+5
-5
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
apdu::{Apdu, Ins},
|
apdu::{Apdu, Ins},
|
||||||
cccid::Ccc,
|
cccid::CccId,
|
||||||
chuid::ChuId,
|
chuid::ChuId,
|
||||||
config::Config,
|
config::Config,
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
@@ -275,8 +275,8 @@ impl YubiKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get Cardholder Capability Container (CCC) Identifier.
|
/// Get Cardholder Capability Container (CCC) Identifier.
|
||||||
pub fn cccid(&mut self) -> Result<Ccc> {
|
pub fn cccid(&mut self) -> Result<CccId> {
|
||||||
Ccc::get(self)
|
CccId::get(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Authenticate to the card using the provided management key (MGM).
|
/// Authenticate to the card using the provided management key (MGM).
|
||||||
@@ -476,12 +476,12 @@ impl YubiKey {
|
|||||||
/// Block PUK: permanently prevent the PIN from becoming unblocked.
|
/// Block PUK: permanently prevent the PIN from becoming unblocked.
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "untested")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "untested")))]
|
||||||
pub fn block_puk(yubikey: &mut YubiKey) -> Result<()> {
|
pub fn block_puk(&mut self) -> Result<()> {
|
||||||
let mut puk = [0x30, 0x42, 0x41, 0x44, 0x46, 0x30, 0x30, 0x44];
|
let mut puk = [0x30, 0x42, 0x41, 0x44, 0x46, 0x30, 0x30, 0x44];
|
||||||
let mut tries_remaining: i32 = -1;
|
let mut tries_remaining: i32 = -1;
|
||||||
let mut flags = [0];
|
let mut flags = [0];
|
||||||
|
|
||||||
let txn = yubikey.begin_transaction()?;
|
let txn = self.begin_transaction()?;
|
||||||
|
|
||||||
while tries_remaining != 0 {
|
while tries_remaining != 0 {
|
||||||
// 2 -> change puk
|
// 2 -> change puk
|
||||||
|
|||||||
Reference in New Issue
Block a user