Skip to content

Commit d37bf7a

Browse files
authored
Merge pull request #8 from pkgxdev/add-fingerprint-and-key-id
Add `fingerprint` and `key-id` commands
2 parents 7f67658 + e3f6149 commit d37bf7a

File tree

4 files changed

+57
-26
lines changed

4 files changed

+57
-26
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ jobs:
8787
toolchain: 1.81.0
8888
override: true
8989
- name: Cache dependencies
90-
uses: actions/cache@v2
90+
uses: actions/cache@v4
9191
env:
9292
cache-name: cache-dependencies
9393
with:

bpb/src/config.rs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,25 +62,22 @@ struct PublicKey {
6262
}
6363

6464
fn keys_file() -> std::path::PathBuf {
65-
// for archaic reasons we first check the config path
66-
// however this is an error, we shouldn’t store this as config seeing as it is
67-
// tied to the private key which is likely a host setting and should not thus be
68-
// synced between machines
65+
// for archaic reasons we first check the config path
66+
// however this is an error, we shouldn’t store this as config seeing as it is
67+
// tied to the private key which is likely a host setting and should not thus be
68+
// synced between machines
6969

70-
let config_path = if let Ok(config_home) = std::env::var("XDG_CONFIG_HOME") {
71-
std::path::PathBuf::from(config_home).join("pkgx/bpb.toml")
72-
} else {
73-
std::path::PathBuf::from(std::env::var("HOME").unwrap()).join(".config/pkgx/bpb.toml")
74-
};
70+
let config_path = if let Ok(config_home) = std::env::var("XDG_CONFIG_HOME") {
71+
std::path::PathBuf::from(config_home).join("pkgx/bpb.toml")
72+
} else {
73+
std::path::PathBuf::from(std::env::var("HOME").unwrap()).join(".config/pkgx/bpb.toml")
74+
};
7575

76-
if config_path.exists() {
77-
config_path
78-
} else {
79-
let data_path = if let Ok(data_home) = std::env::var("XDG_DATA_HOME") {
80-
std::path::PathBuf::from(data_home).join("pkgx/bpb.toml")
81-
} else {
82-
std::path::PathBuf::from(std::env::var("HOME").unwrap()).join(".local/share/pkgx/bpb.toml")
83-
};
84-
data_path
85-
}
76+
if config_path.exists() {
77+
config_path
78+
} else if let Ok(data_home) = std::env::var("XDG_DATA_HOME") {
79+
std::path::PathBuf::from(data_home).join("pkgx/bpb.toml")
80+
} else {
81+
std::path::PathBuf::from(std::env::var("HOME").unwrap()).join(".local/share/pkgx/bpb.toml")
82+
}
8683
}

bpb/src/keychain.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ pub fn add_keychain_item(service: &str, account: &str, secret: &str) -> Result<(
8181
Ok(())
8282
} else {
8383
Err(failure::err_msg(format!(
84-
"SecItemAdd failed with status: {}",
85-
status
84+
"SecItemAdd failed with status: {status}"
8685
)))
8786
}
8887
}
@@ -155,8 +154,7 @@ pub fn get_keychain_item(service: &str, account: &str) -> Result<String, Error>
155154
Ok(secret)
156155
} else {
157156
Err(failure::err_msg(format!(
158-
"SecItemCopyMatching failed with status: {}",
159-
status
157+
"SecItemCopyMatching failed with status: {status}"
160158
)))
161159
}
162160
}

bpb/src/main.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ fn main() -> Result<(), Error> {
3333
Some("import") => import(),
3434
Some("upgrade") => upgrade(),
3535
Some("print") => print_public_key(),
36+
Some("fingerprint") => print_fingerprint(),
37+
Some("key-id") => print_key_id(),
3638
Some("--help") => print_help_message(),
3739
Some(arg) if gpg_sign_arg(arg) => verify_commit(),
3840
_ => {
@@ -54,7 +56,10 @@ fn print_help_message() -> Result<(), Error> {
5456
println!("A program for signing git commits.\n");
5557
println!("Arguments:");
5658
println!(" init <userid>: Generate a keypair and store in the keychain.");
57-
println!(" print: Print public key in OpenPGP format.\n");
59+
println!(" import <key>: Import a key from the command line.");
60+
println!(" print: Print public key in OpenPGP format.");
61+
println!(" fingerprint: Print the fingerprint of the public key.");
62+
println!(" key-id: Print the key ID of the public key.\n");
5863
println!("See https://github.com/pkgxdev/bpb for more information.");
5964
Ok(())
6065
}
@@ -104,6 +109,29 @@ fn print_public_key() -> Result<(), Error> {
104109
Ok(())
105110
}
106111

112+
fn get_fingerprint() -> Result<pbp::Fingerprint, Error> {
113+
let config = Config::load()?;
114+
let service = config.service();
115+
let account = config.user_id();
116+
let secret_str = get_keychain_item(service, account)?;
117+
let secret = to_32_bytes(&secret_str)?;
118+
119+
let keypair = KeyData::load(&config, secret)?;
120+
Ok(keypair.fingerprint())
121+
}
122+
123+
// Prints the fingerprint (sha256 hash of the public key -- 20 bytes)
124+
fn print_fingerprint() -> Result<(), Error> {
125+
println!("{}", pretty_print_hex_string(&get_fingerprint()?));
126+
Ok(())
127+
}
128+
129+
// Prints the long key ID (the last 8 bytes of the fingerprint)
130+
fn print_key_id() -> Result<(), Error> {
131+
println!("{}", pretty_print_hex_string(&get_fingerprint()?[12..]));
132+
Ok(())
133+
}
134+
107135
fn verify_commit() -> Result<(), Error> {
108136
use std::io::Read;
109137

@@ -123,7 +151,7 @@ fn verify_commit() -> Result<(), Error> {
123151
let sig = keypair.sign(commit.as_bytes())?;
124152

125153
eprintln!("\n[GNUPG:] SIG_CREATED ");
126-
println!("{}", sig);
154+
println!("{sig}");
127155
Ok(())
128156
}
129157

@@ -167,3 +195,11 @@ fn to_32_bytes(slice: &String) -> Result<[u8; 32], Error> {
167195
array[..len].copy_from_slice(&vector[..len]);
168196
Ok(array)
169197
}
198+
199+
// iterates over a hex array and prints space-separated groups of four characters
200+
fn pretty_print_hex_string(hex: &[u8]) -> String {
201+
hex.chunks(2)
202+
.map(hex::encode_upper)
203+
.collect::<Vec<String>>()
204+
.join(" ")
205+
}

0 commit comments

Comments
 (0)