Goal
Today's goal is to add support for OpenPGP hardware card credentials.
Roadmap
Changes from last time:
- marked "create credential when init repo" and "initialize chunk repository" as finished
- picked "OpenPGP card credential" as next task
Plan
- Implement a new credential using the
rsoctprogram by Heiko Schaefer. Testing with hardware can be tricky to automate, but test at least manually.- Implement a
CredentialKind::OpenPgpCardvariant. - Implement an
obnam credential openpgp-cardcommand.
- Implement a
Notes
- First change actually needs to be to change
obnam sopto supportrsoct. I've done this before insopassby usingrsopfor most things, butrsoctfor things that require the key on the card. - The jist of it is to have two commands, both defaulting to
rsop, but allowing the other command to be set torsoctto support an OpenPGP card. - I split
Sopso it knows two commands. Also changed all call sites for constructing aSop. - This allows me to run
obnam sop decrypt rsoct CERT MSGto decrypt a message encrypted withrsop encrypt. However, I can't encrypt withobnam sop encryptis it wants to extract the certificate from the file given as a key, and for cards that's not a key, it's a certificate. I'll live with this, for now. - Added a
CredentialKind::OpenPgpCardvariant, and implemented it using software keys, for now. - Hm,
Sop::decryptalso wants anOpenPgpKey, but we don't have that for cards. Changing that will result in messy changes. I need a re-think. - OK, I'll throw away all I did in this branch (read: I'll start a new branch off
main), and splitSopintoSopandSopCard. - There may be a need for
SopLiketrait. But not now. - Changed
obnam sop decryptto supportSopCardif--sop-cardoption is used.obnam sop encryptdoesn't need that, for now, but will need the same treatment later. - Interesting problem: now that I have two credential method variants, the
CredentialSpec::methodmethod can't return animpl CredentialMethod, because it can only return one concrete type that implements a credential mehtod. If I change the return type to beBox<dyn CredentialMethod>, thenConfig::credential_methodalso needs to return a vector of that type, which means whensrc/bin/cmd/credential.rsuses them, there's a problem: "the trait boundstd::boxed::Box<dyn obnam::credential::CredentialMethod>: obnam::credential::CredentialMethodis not satisfied". There's also a warning about multiple versions of theobnamcrate in use. - I can work around this by putting all use of credential methods created
from the configuration into
src/config.rs, at least for now. - Hm, no, that's not good enough. It would require
src/config.rsto know about how to encrypt different kinds of credentials. Tricky. - I'll change
CredentialMethodto be an enum instead of a trait. - I'd prefer a trait based approach, as it keeps types and their impls smaller, but if I can't get that to work, then I'll do this.
- I can refactor this once I learn how to achieve this in Rust with traits.
- Now I realize I haven't actually implemented creating a first credential when initializing a client, oops. That means I can't test this.
- I'll tidy up the branch and continue next time.
Summary
I ran a little over time today, and found out that I hadn't actually implemented some things I thought I had, but I did make progress. I can now create an OpenPGP card credential, and can continue from here next time. I'll need to fix up store and client initialization so that at least one credential chunk is actually created, and then I'll be able to test the card credentials, manually.
Comments?
If you have feedback on this development session, please use the following fediverse thread: https://toot.liw.fi/@liw/115201974511602854.