Skip to content

Commit 082fa3b

Browse files
authored
Merge pull request #63 from wiktor-k/wiktor/use-secrecy
Use `secrecy` crate to protect PINs from accidental leaks
2 parents 2fcef7a + 4756c67 commit 082fa3b

File tree

3 files changed

+20
-7
lines changed

3 files changed

+20
-7
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ thiserror = "1.0.58"
3232
#uuid = { version = "1.8.0", features = ["v4"] }
3333
subtle = { version = "2", default-features = false }
3434
signature = { version = "2.2.0", features = ["alloc"] }
35+
secrecy = "0.8.0"
3536

3637
[features]
3738
default = ["agent"]

examples/openpgp-card-agent.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,15 @@ impl CardSession {
102102
let mut tx = card.transaction()?;
103103
let ident = tx.application_identifier()?.ident();
104104
if ident == key.id {
105-
tx.verify_pw1_user(key.pin.as_bytes())?;
105+
tx.verify_pw1_user(key.pin.expose_secret().as_bytes())?;
106106
Ok::<_, Box<dyn std::error::Error>>(true)
107107
} else {
108108
Ok(false)
109109
}
110110
})
111111
.any(|x| x);
112112
if card_pin_matches {
113-
self.pwds.insert(key.id, key.pin.into(), expiration).await;
113+
self.pwds.insert(key.id, key.pin, expiration).await;
114114
Ok(())
115115
} else {
116116
Err(AgentError::IO(std::io::Error::other(

src/proto/message/add_remove.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ mod credential;
55

66
pub use constrained::*;
77
pub use credential::*;
8+
use secrecy::ExposeSecret as _;
9+
use secrecy::SecretString;
810
use ssh_encoding::{self, CheckedSum, Decode, Encode, Reader, Writer};
911
use ssh_key::public::KeyData;
1012

@@ -46,7 +48,7 @@ impl Encode for AddIdentity {
4648
/// This structure is sent in a [`Request::AddSmartcardKey`](super::Request::AddSmartcardKey) (`SSH_AGENTC_ADD_SMARTCARD_KEY`) message.
4749
///
4850
/// Described in [draft-miller-ssh-agent-14 § 3.2](https://www.ietf.org/archive/id/draft-miller-ssh-agent-14.html#section-3.2)
49-
#[derive(Clone, PartialEq, Debug)]
51+
#[derive(Clone, Debug)]
5052
pub struct SmartcardKey {
5153
/// An opaque identifier for the hardware token
5254
///
@@ -55,33 +57,43 @@ pub struct SmartcardKey {
5557
pub id: String,
5658

5759
/// An optional password to unlock the key
58-
pub pin: String,
60+
pub pin: SecretString,
5961
}
6062

6163
impl Decode for SmartcardKey {
6264
type Error = Error;
6365

6466
fn decode(reader: &mut impl Reader) -> Result<Self> {
6567
let id = String::decode(reader)?;
66-
let pin = String::decode(reader)?;
68+
let pin = String::decode(reader)?.into();
6769

6870
Ok(Self { id, pin })
6971
}
7072
}
7173

7274
impl Encode for SmartcardKey {
7375
fn encoded_len(&self) -> ssh_encoding::Result<usize> {
74-
[self.id.encoded_len()?, self.pin.encoded_len()?].checked_sum()
76+
[
77+
self.id.encoded_len()?,
78+
self.pin.expose_secret().encoded_len()?,
79+
]
80+
.checked_sum()
7581
}
7682

7783
fn encode(&self, writer: &mut impl Writer) -> ssh_encoding::Result<()> {
7884
self.id.encode(writer)?;
79-
self.pin.encode(writer)?;
85+
self.pin.expose_secret().encode(writer)?;
8086

8187
Ok(())
8288
}
8389
}
8490

91+
impl PartialEq for SmartcardKey {
92+
fn eq(&self, other: &Self) -> bool {
93+
self.id == other.id && self.pin.expose_secret() == other.pin.expose_secret()
94+
}
95+
}
96+
8597
/// Remove a key from an agent.
8698
///
8799
/// This structure is sent in a [`Request::RemoveIdentity`](super::Request::RemoveIdentity) (`SSH_AGENTC_REMOVE_IDENTITY`) message.

0 commit comments

Comments
 (0)