Skip to content

Commit 005d56d

Browse files
add better From implementations for Fingerprint
1 parent 72280d5 commit 005d56d

File tree

8 files changed

+72
-89
lines changed

8 files changed

+72
-89
lines changed

cursive/src/main.rs

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use cursive::{
3333
RadioGroup, ResizedView, ScrollView, SelectView, TextArea, TextView,
3434
},
3535
};
36-
use hex::FromHex;
3736
use pass::Result;
3837
use ripasso::{
3938
crypto::CryptoImpl,
@@ -53,7 +52,6 @@ use crate::helpers::{
5352
};
5453
use lazy_static::lazy_static;
5554
use ripasso::crypto::Fingerprint;
56-
use ripasso::pass::Error;
5755
use zeroize::Zeroize;
5856

5957
/// The 'pointer' to the current PasswordStore is of this convoluted type.
@@ -1385,17 +1383,7 @@ fn get_stores(config: &config::Config, home: &Option<PathBuf>) -> Result<Vec<Pas
13851383

13861384
let own_fingerprint = store.get("own_fingerprint");
13871385
let own_fingerprint = own_fingerprint
1388-
.map(|k| {
1389-
k.clone().into_string().map(|key| {
1390-
if key.len() == 40 || key.len() == 42 {
1391-
Ok(Fingerprint::from(<[u8; 20]>::from_hex(key)?))
1392-
} else if key.len() == 64 || key.len() == 66 {
1393-
Ok(Fingerprint::from(<[u8; 32]>::from_hex(key)?))
1394-
} else {
1395-
Err(Error::Generic("unable to parse fingerprint"))
1396-
}
1397-
})?
1398-
})
1386+
.map(|k| k.clone().into_string().map(|key| key.as_str().try_into())?)
13991387
.transpose()?;
14001388

14011389
final_stores.push(PasswordStore::new(
@@ -1514,13 +1502,7 @@ fn save_edit_config(
15141502
false => CryptoImpl::GpgMe,
15151503
};
15161504

1517-
let own_fingerprint = if own_fingerprint.len() == 40 || own_fingerprint.len() == 42 {
1518-
Ok(Fingerprint::from(<[u8; 20]>::from_hex(own_fingerprint)?))
1519-
} else if own_fingerprint.len() == 64 || own_fingerprint.len() == 66 {
1520-
Ok(Fingerprint::from(<[u8; 32]>::from_hex(own_fingerprint)?))
1521-
} else {
1522-
Err(Error::Generic("unable to parse fingerprint"))
1523-
};
1505+
let own_fingerprint: Fingerprint = own_fingerprint.as_str().try_into()?;
15241506

15251507
let new_store = PasswordStore::new(
15261508
e_n,
@@ -1529,7 +1511,7 @@ fn save_edit_config(
15291511
home,
15301512
&None,
15311513
&pgp_impl,
1532-
&Some(own_fingerprint?),
1514+
&Some(own_fingerprint),
15331515
);
15341516
if let Err(err) = new_store {
15351517
helpers::errorbox(ui, &err);

cursive/src/tests/helpers.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use cursive::{
88
views::{Checkbox, EditView, LinearLayout, RadioButton, RadioGroup},
99
};
1010
use hex::FromHex;
11-
use ripasso::crypto::CryptoImpl;
11+
use ripasso::crypto::{CryptoImpl, Fingerprint};
1212
use ripasso::pass::{Comment, KeyRingStatus, OwnerTrustLevel, Recipient};
1313

1414
#[test]
@@ -100,9 +100,9 @@ pub fn recipient_alex() -> Recipient {
100100
post_comment: None,
101101
},
102102
key_id: "1D108E6C07CBC406".to_owned(),
103-
fingerprint: Some(
103+
fingerprint: Some(Fingerprint::V4(
104104
<[u8; 20]>::from_hex("7E068070D5EF794B00C8A9D91D108E6C07CBC406").unwrap(),
105-
),
105+
)),
106106
key_ring_status: KeyRingStatus::InKeyRing,
107107
trust_level: OwnerTrustLevel::Ultimate,
108108
not_usable: false,

cursive/src/tests/main.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::{fs::File, io::Write};
22

33
use chrono::Local;
4+
use hex::FromHex;
45
use ripasso::pass::{PasswordEntry, RepositoryStatus};
56
use tempfile::tempdir;
67

@@ -168,9 +169,9 @@ fn render_recipient_label_ultimate() {
168169
post_comment: None,
169170
},
170171
key_id: "1D108E6C07CBC406".to_owned(),
171-
fingerprint: Some(
172+
fingerprint: Some(Fingerprint::V4(
172173
<[u8; 20]>::from_hex("7E068070D5EF794B00C8A9D91D108E6C07CBC406").unwrap(),
173-
),
174+
)),
174175
key_ring_status: pass::KeyRingStatus::InKeyRing,
175176
trust_level: OwnerTrustLevel::Ultimate,
176177
not_usable: false,

gtk/src/window/mod.rs

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ use gtk::{
1313
AboutDialog, CustomFilter, Dialog, DialogFlags, Entry, FilterListModel, Label, ListBox,
1414
ListBoxRow, NoSelection, ResponseType, SelectionMode, gio, glib, glib::BindingFlags, pango,
1515
};
16-
use hex::FromHex;
17-
use ripasso::crypto::Fingerprint;
18-
use ripasso::pass::Error;
1916
use ripasso::{crypto::CryptoImpl, pass::PasswordStore};
2017

2118
glib::wrapper! {
@@ -582,17 +579,7 @@ fn get_stores(
582579

583580
let own_fingerprint = store.get("own_fingerprint");
584581
let own_fingerprint = own_fingerprint
585-
.map(|k| {
586-
k.clone().into_string().map(|fingerprint| {
587-
if fingerprint.len() == 40 || fingerprint.len() == 42 {
588-
Ok(Fingerprint::from(<[u8; 20]>::from_hex(fingerprint)?))
589-
} else if fingerprint.len() == 64 || fingerprint.len() == 66 {
590-
Ok(Fingerprint::from(<[u8; 32]>::from_hex(fingerprint)?))
591-
} else {
592-
Err(Error::Generic("unable to parse fingerprint"))
593-
}
594-
})
595-
})
582+
.map(|k| k.clone().into_string().map(|fp| fp.as_str().try_into()))
596583
.transpose()?
597584
.transpose()?;
598585

src/crypto.rs

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,12 @@ pub enum FindSigningFingerprintStrategy {
114114
GPG,
115115
}
116116

117+
/// Contains a full pgp fingerprint of a certificate.
117118
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
118119
pub enum Fingerprint {
120+
/// A RFC4880 style fingerprint.
119121
V4([u8; 20]),
122+
/// A RFC9580 style fingerprint.
120123
V6([u8; 32]),
121124
}
122125

@@ -132,6 +135,42 @@ impl From<[u8; 20]> for Fingerprint {
132135
}
133136
}
134137

138+
/// Intended for usage with slices containing a v4 or v6 fingerprint.
139+
impl TryFrom<&[u8]> for Fingerprint {
140+
type Error = Error;
141+
142+
fn try_from(b: &[u8]) -> std::result::Result<Self, Self::Error> {
143+
match b.len() {
144+
20 => Ok(Fingerprint::V4(
145+
b.try_into().expect("slice with incorrect length"),
146+
)),
147+
32 => Ok(Fingerprint::V6(
148+
b.try_into().expect("slice with incorrect length"),
149+
)),
150+
_ => Err(Error::Generic("slice isn't 20 or 32 bytes")),
151+
}
152+
}
153+
}
154+
155+
/// Intended for usage with string containing a v4 or v6 fingerprint in hex.
156+
impl TryFrom<&str> for Fingerprint {
157+
type Error = Error;
158+
159+
fn try_from(key: &str) -> std::result::Result<Self, Self::Error> {
160+
if key.len() == 40 {
161+
Ok(Fingerprint::from(<[u8; 20]>::from_hex(key)?))
162+
} else if key.len() == 42 {
163+
Ok(Fingerprint::from(<[u8; 20]>::from_hex(&key[2..])?))
164+
} else if key.len() == 64 {
165+
Ok(Fingerprint::from(<[u8; 32]>::from_hex(key)?))
166+
} else if key.len() == 66 {
167+
Ok(Fingerprint::from(<[u8; 32]>::from_hex(&key[2..])?))
168+
} else {
169+
Err(Error::Generic("unable to parse fingerprint"))
170+
}
171+
}
172+
}
173+
135174
impl AsRef<[u8]> for Fingerprint {
136175
fn as_ref(&self) -> &[u8] {
137176
match self {
@@ -628,19 +667,6 @@ impl DecryptionHelper for Helper<'_> {
628667
}
629668
}
630669

631-
/// Intended for usage with slices containing a v4 fingerprint.
632-
pub fn slice_to_fingerprint(b: &[u8]) -> Result<Fingerprint> {
633-
match b.len() {
634-
20 => Ok(Fingerprint::V4(
635-
b.try_into().expect("slice with incorrect length"),
636-
)),
637-
32 => Ok(Fingerprint::V6(
638-
b.try_into().expect("slice with incorrect length"),
639-
)),
640-
_ => Err(Error::Generic("slice isn't 20 bytes")),
641-
}
642-
}
643-
644670
/// A pgp key produced with sequoia.
645671
pub struct SequoiaKey {
646672
/// The pgp key
@@ -656,7 +682,7 @@ impl Key for SequoiaKey {
656682
}
657683

658684
fn fingerprint(&self) -> Result<Fingerprint> {
659-
slice_to_fingerprint(self.cert.fingerprint().as_bytes())
685+
self.cert.fingerprint().as_bytes().try_into()
660686
}
661687

662688
fn is_not_usable(&self) -> bool {
@@ -698,7 +724,7 @@ impl Sequoia {
698724
let data = fs::read(path)?;
699725
let cert = Cert::from_bytes(&data)?;
700726

701-
let fingerprint = slice_to_fingerprint(cert.fingerprint().as_bytes())?;
727+
let fingerprint = cert.fingerprint().as_bytes().try_into()?;
702728
key_ring.insert(fingerprint, Arc::new(cert));
703729
}
704730
}
@@ -770,7 +796,7 @@ impl Sequoia {
770796
fn write_cert(&mut self, cert_str: &str, keys_dir: &Path) -> Result<String> {
771797
let cert = Cert::from_bytes(cert_str.as_bytes())?;
772798

773-
let fingerprint = slice_to_fingerprint(cert.fingerprint().as_bytes())?;
799+
let fingerprint = cert.fingerprint().as_bytes().try_into()?;
774800

775801
let mut file = File::create(keys_dir.join(hex::encode(fingerprint)))?;
776802

src/signature.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ use std::{
66
path::{Path, PathBuf},
77
};
88

9-
use hex::FromHex;
10-
119
use crate::crypto::{FindSigningFingerprintStrategy, Fingerprint};
1210
pub use crate::error::{Error, Result};
1311

@@ -66,15 +64,7 @@ pub fn parse_signing_keys(
6664
)));
6765
}
6866

69-
if trimmed.len() == 40 {
70-
signing_keys.push(Fingerprint::V4(<[u8; 20]>::from_hex(trimmed)?));
71-
} else if trimmed.len() == 42 {
72-
signing_keys.push(Fingerprint::V4(<[u8; 20]>::from_hex(&trimmed[2..])?));
73-
} else if trimmed.len() == 64 {
74-
signing_keys.push(Fingerprint::V6(<[u8; 32]>::from_hex(trimmed)?));
75-
} else {
76-
signing_keys.push(Fingerprint::V6(<[u8; 32]>::from_hex(&trimmed[2..])?));
77-
}
67+
signing_keys.push(trimmed.as_str().try_into()?);
7868
}
7969
Ok(signing_keys)
8070
}

src/tests/crypto.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use tempfile::tempdir;
66

77
use crate::crypto::Fingerprint;
88
use crate::{
9-
crypto::{Crypto, CryptoImpl, Sequoia, slice_to_fingerprint},
9+
crypto::{Crypto, CryptoImpl, Sequoia},
1010
signature::Recipient,
1111
};
1212

@@ -32,20 +32,20 @@ pub fn crypto_impl_display() {
3232

3333
#[test]
3434
pub fn slice_to_20_bytes_failure() {
35-
let input = [3; 16];
35+
let input: [u8; 16] = [3; 16];
3636

37-
let result = slice_to_fingerprint(&input);
37+
let result = TryInto::<Fingerprint>::try_into(input.as_slice());
3838

3939
assert!(result.is_err());
4040
}
4141

4242
#[test]
4343
pub fn slice_to_20_bytes_success() {
44-
let input = [3; 20];
44+
let input: &[u8] = &[3; 20];
4545

46-
let result = slice_to_fingerprint(&input).unwrap();
46+
let result = input.try_into().unwrap();
4747

48-
assert_eq!(Fingerprint::V4(input), result);
48+
assert_eq!(Fingerprint::V4([3; 20]), result);
4949
}
5050

5151
#[test]
@@ -59,7 +59,7 @@ pub fn new_one_cert() {
5959
.generate()
6060
.unwrap();
6161

62-
let f = slice_to_fingerprint(cert.fingerprint().as_bytes()).unwrap();
62+
let f = cert.fingerprint().as_bytes().try_into().unwrap();
6363

6464
let p = dir.path().join("share").join("ripasso").join("keys");
6565
std::fs::create_dir_all(&p).unwrap();
@@ -227,7 +227,7 @@ pub fn sign_string_sequoia() {
227227
.generate()
228228
.unwrap();
229229

230-
let f = slice_to_fingerprint(cert.fingerprint().as_bytes()).unwrap();
230+
let f = cert.fingerprint().as_bytes().try_into().unwrap();
231231

232232
let mut c = Sequoia {
233233
user_key_id: f,
@@ -258,7 +258,7 @@ pub fn sign_then_verify_sequoia_with_signing_keys() {
258258
.generate()
259259
.unwrap();
260260

261-
let f = slice_to_fingerprint(cert.fingerprint().as_bytes()).unwrap();
261+
let f = cert.fingerprint().as_bytes().try_into().unwrap();
262262

263263
let mut c = Sequoia {
264264
user_key_id: f,
@@ -293,7 +293,7 @@ pub fn sign_then_verify_sequoia_with_v6_signing_keys() {
293293
.generate()
294294
.unwrap();
295295

296-
let f = slice_to_fingerprint(cert.fingerprint().as_bytes()).unwrap();
296+
let f = cert.fingerprint().as_bytes().try_into().unwrap();
297297

298298
let mut c = Sequoia {
299299
user_key_id: f,
@@ -326,7 +326,7 @@ pub fn sign_then_verify_sequoia_without_signing_keys() {
326326
.generate()
327327
.unwrap();
328328

329-
let f = slice_to_fingerprint(cert.fingerprint().as_bytes()).unwrap();
329+
let f = cert.fingerprint().as_bytes().try_into().unwrap();
330330

331331
let mut c = Sequoia {
332332
user_key_id: f,
@@ -359,7 +359,7 @@ pub fn encrypt_then_decrypt_sequoia() {
359359
.generate()
360360
.unwrap();
361361

362-
let f = slice_to_fingerprint(cert.fingerprint().as_bytes()).unwrap();
362+
let f = cert.fingerprint().as_bytes().try_into().unwrap();
363363

364364
let mut c = Sequoia {
365365
user_key_id: f,
@@ -408,7 +408,7 @@ pub fn encrypt_then_decrypt_sequoia_v6() {
408408

409409
let cert = cert_v6();
410410

411-
let f = slice_to_fingerprint(cert.fingerprint().as_bytes()).unwrap();
411+
let f = cert.fingerprint().as_bytes().try_into().unwrap();
412412

413413
let mut c = Sequoia {
414414
user_key_id: f,

src/tests/pass.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@ use std::{env, fs::File, path::PathBuf};
1212
use tempfile::tempdir;
1313

1414
use super::*;
15-
use crate::{
16-
crypto::slice_to_fingerprint,
17-
test_helpers::{
18-
MockCrypto, UnpackedDir, count_recipients, generate_sequoia_cert,
19-
generate_sequoia_cert_without_private_key,
20-
},
15+
use crate::test_helpers::{
16+
MockCrypto, UnpackedDir, count_recipients, generate_sequoia_cert,
17+
generate_sequoia_cert_without_private_key,
2118
};
2219

2320
impl PartialEq for Error {
@@ -40,7 +37,7 @@ pub fn setup_store(
4037
];
4138
let mut key_ring = HashMap::new();
4239
for u in &users {
43-
key_ring.insert(slice_to_fingerprint(u.fingerprint().as_bytes())?, u.clone());
40+
key_ring.insert(u.fingerprint().as_bytes().try_into()?, u.clone());
4441
}
4542

4643
let store = PasswordStore {
@@ -50,7 +47,7 @@ pub fn setup_store(
5047
passwords: [].to_vec(),
5148
style_file: None,
5249
crypto: Box::new(Sequoia::from_values(
53-
slice_to_fingerprint(users[0].fingerprint().as_bytes())?,
50+
users[0].fingerprint().as_bytes().try_into()?,
5451
key_ring,
5552
user_home,
5653
)),
@@ -1875,7 +1872,7 @@ fn test_verify_gpg_id_files_untrusted_key_in_keyring() {
18751872
.add_signing_subkey()
18761873
.generate()
18771874
.unwrap();
1878-
let sofp = slice_to_fingerprint(store_owner.fingerprint().as_bytes()).unwrap();
1875+
let sofp = store_owner.fingerprint().as_bytes().try_into().unwrap();
18791876
let (unrelated_user, _) = CertBuilder::new()
18801877
.add_userid("unrelated_user@example.org")
18811878
.add_signing_subkey()

0 commit comments

Comments
 (0)