Skip to content

Commit

Permalink
Add Card.keys for retrieving card-backed secret keys info
Browse files Browse the repository at this point in the history
Signed-off-by: Wiktor Kwapisiewicz <[email protected]>
  • Loading branch information
wiktor-k committed Nov 23, 2023
1 parent bce5003 commit b871d92
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 2 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ crate-type = ["cdylib"]
anyhow = "1"
card-backend-pcsc = "0.5"
chrono = "0.4"
hex = "0.4.3"
once_cell = "1.18"
openpgp-card-sequoia = { version = "0.2.0", default-features = false }
openpgp-cert-d = "0.1"
Expand Down
1 change: 1 addition & 0 deletions NEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ v0.1.21

New:
- `Card.cert_url` - for retrieving certificate URL stored on the card, note that the URL returned can be empty or invalid,
- `Card.keys` - for enumerating secret keys stored on the card,

Changed:

Expand Down
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ gpg --batch --pinentry-mode loopback --passphrase '' --export-secret-key no-pass
# initialize dummy OpenPGP Card
sh /start.sh
echo 12345678 > pin
opgpcard admin --card 0000:00000000 --admin-pin pin import no-passwd.pgp
opgpcard admin --card 0000:00000000 --admin-pin pin import full-key.asc
opgpcard admin --card 0000:00000000 --admin-pin pin name "John Doe"
opgpcard admin --card 0000:00000000 --admin-pin pin url "https://example.com/key.pgp"
```
Expand Down Expand Up @@ -412,6 +412,25 @@ assert card.cardholder == "John Doe"
assert card.cert_url == "https://example.com/key.pgp"
```

Cards provide `keys` property that can be used to see which keys are imported
on the card:

```python
keys = card.keys
print(f"Keys: {keys}")
assert len(keys) == 3

assert keys[0].fingerprint == "ddc3e03c91fb52ca2d95c2444566f2743ed5f382"
assert "sign" in keys[0].usage

assert keys[1].fingerprint == "689e152a7420be13dcaf2c142ac27adc1db9395e"
assert "decrypt" in keys[1].usage

assert keys[2].fingerprint == "731fbca93ce9821347bf8e696444723371d3c650"
assert "authenticate" in keys[2].usage
```


Cards can be used for signing data:

```python
Expand All @@ -427,7 +446,7 @@ As well as for decryption:
decryptor = card.decryptor("123456")

sender = Cert.from_file("passwd.pgp")
receiver = Cert.from_file("no-passwd.pgp")
receiver = Cert.from_file("full-key.asc")

content = "Red Green Blue"

Expand Down
34 changes: 34 additions & 0 deletions full-key.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
Comment: F6C0 B7D0 BE82 025B EFFA 5EE0 4D26 BE97 42B6 BBC7

xVgEZV8mnBYJKwYBBAHaRw8BAQdAJDEsAEHqAegSu4T1NhLE7g2S2HHy4grzbpwq
9AiLw+UAAQC3vMRsRHXFH1UasVFlaJKuMi5vnh/6zZIC+HKTzveufhCUwsARBB8W
CgCDBYJlXyacBYkFpI+9AwsJBwkQTSa+l0K2u8dHFAAAAAAAHgAgc2FsdEBub3Rh
dGlvbnMuc2VxdW9pYS1wZ3Aub3JnmXA62AXv9IgC1jf0lrW3qDxOnM3L4FyOCZP0
T/QcX2oDFQoIApsBAh4BFiEE9sC30L6CAlvv+l7gTSa+l0K2u8cAAC9sAQDF3O3V
F7Io3q4ooV5T9c4wU3k1qgX6L/La9J7YZbAFNgD/XD0DZH591o7npestwbEzy6tP
41lXOfmmem4g1u1imQvHWARlXyacFgkrBgEEAdpHDwEBB0A0t/rqqLhO3H6pGnev
2RVJaHWX+YaO1BDhYpwfzM6fuAAA/joDnLjfZvKrsOnM5UPgBJ6ezamFvGlObtRD
0mRlVOxoE1TCwMUEGBYKATcFgmVfJpwFiQWkj70JEE0mvpdCtrvHRxQAAAAAAB4A
IHNhbHRAbm90YXRpb25zLnNlcXVvaWEtcGdwLm9yZ8z+3bumoO/kE4EwsErcwzw3
826BSouBjm7uu/5ehvotApsCvqAEGRYKAG8FgmVfJpwJEEVm8nQ+1fOCRxQAAAAA
AB4AIHNhbHRAbm90YXRpb25zLnNlcXVvaWEtcGdwLm9yZw7po5+COFy4etWJg2nm
+i/9PScl422lMcBzCR44aPOVFiEE3cPgPJH7UsotlcJERWbydD7V84IAAJfLAQDs
THGJXK7Endv4V6115rrkywEv39V6OwfmpmlJKrG5zAEAi929loAzFS6z6OSDx295
SG0hupFJ6UVOwOVXFd+26QcWIQT2wLfQvoICW+/6XuBNJr6XQra7xwAAoCIBAOtF
eJaKP7JzSKiZRBSu+xPSvTjiTzMdkZaLRRPF/6saAP9PxVbzs08y8qMLaSUrpfkg
O3jPDVES5MdglikhK7PUD8dYBGVfJpwWCSsGAQQB2kcPAQEHQJDciggHlBrtgrZd
lXDBDHsgSQTwpKPNuEXDZqIrDQvXAAEA0wdknEP9as31ddUvzcjmnt91W5SM5OC7
52v3fbiCAqoT08LABgQYFgoAeAWCZV8mnAWJBaSPvQkQTSa+l0K2u8dHFAAAAAAA
HgAgc2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3JnrKpsjxP3qa5eaieh9pHi
A3A++ziK7MsUvqHPYy4oSKUCmyAWIQT2wLfQvoICW+/6XuBNJr6XQra7xwAAZiEB
AJJQ0sQryZmb0fld/hC8QG22QFn4Ikn9Vvo7B2TocQ6UAQDEt+cz0NQtNU6Wl6qY
7AwF3T/0UJHhWZyZd7DSfxkTA8ddBGVfJpwSCisGAQQBl1UBBQEBB0CPSesAmVD/
J2GV/YbGB/B3tsLAZH9knrUYs8Zykq81AQMBCAcAAP9qKRK1yDqk28GM/G7gvm5B
qGRBydJqwUjrF3Gjn6m2ABJNwsAGBBgWCgB4BYJlXyacBYkFpI+9CRBNJr6XQra7
x0cUAAAAAAAeACBzYWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmfuHcLDGf/3
uJvZemz5fmZNhTCZ8VndC8uhuBv4J/jBDgKbDBYhBPbAt9C+ggJb7/pe4E0mvpdC
trvHAABEcAD/Rp6y0YAk69SatdaTG/DgjCEzOJRyYL/S52XAWK0wNr8A/AhtbkuL
BPxLEbJ4QkSsjJROF+HC08GXlI+XcLE3t2wI
=ZfI0
-----END PGP PRIVATE KEY BLOCK-----
52 changes: 52 additions & 0 deletions src/card.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,56 @@ impl Card {
pub fn __repr__(&mut self) -> anyhow::Result<String> {
Ok(format!("<Card ident={}>", self.ident()?))
}

#[getter]
pub fn keys(&mut self) -> anyhow::Result<Vec<CardKey>> {
let transaction = self.open.transaction()?;
let card_keys = transaction.fingerprints()?;
let mut keys = Vec::with_capacity(3);
if let Some(key) = card_keys.signature() {
keys.push(CardKey {
fingerprint: hex::encode(key.as_bytes()),
usage: vec!["sign".into()],
})
}
if let Some(key) = card_keys.decryption() {
keys.push(CardKey {
fingerprint: hex::encode(key.as_bytes()),
usage: vec!["decrypt".into()],
})
}
if let Some(key) = card_keys.authentication() {
keys.push(CardKey {
fingerprint: hex::encode(key.as_bytes()),
usage: vec!["authenticate".into()],
})
}
Ok(keys)
}
}

#[pyclass]
pub struct CardKey {
fingerprint: String,
usage: Vec<String>,
}

#[pymethods]
impl CardKey {
#[getter]
fn fingerprint(&self) -> &String {
&self.fingerprint
}

#[getter]
fn usage(&self) -> Vec<String> {
self.usage.clone()
}

pub fn __repr__(&self) -> String {
format!(
"<Key fingerprint={} usage={:?}>",
self.fingerprint, self.usage
)
}
}

0 comments on commit b871d92

Please sign in to comment.