Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move from GnuPG to Sequoia #812

Open
eaon opened this issue Jul 24, 2022 · 13 comments
Open

Move from GnuPG to Sequoia #812

eaon opened this issue Jul 24, 2022 · 13 comments

Comments

@eaon
Copy link
Contributor

eaon commented Jul 24, 2022

Piggy backing off of freedomofpress/securedrop#6499 on the server.

Once we determined how Rust fits into our overall strategy (including but not limited to dependency review), and especially if Sequoia support gets merged into the server, I think it would be a good idea to discuss replacing sd-gpg with a Sequoia based solution as well.

Such a move would also imply that the qubes.Gpg RPC call couldn't be used anymore, and we would need to replace it with our own.

@legoktm
Copy link
Member

legoktm commented Nov 17, 2023

A few notes from this week:

  • Encryption of new replies can be done fully in the client because it doesn't require any private info - it just needs the source public key and Submission public key.
  • Decrypting of submissions needs to be done in a VM, we have some options:
    • we can continue to rely on qubes-split-gpg for this (status quo)
    • there's a task about switching split-gpg to use Sequoia: port Qubes Split GPG to Sequoia-PGP QubesOS/qubes-issues#8241 (could be using the chameleon or writing a new RPC protocol
    • we can write our own RPC thing, it needs to read a secret key from somewhere, then accept an PGP encrypted message (maybe over stdin?) and then stream the decrypted contents back. This is probably possible with sq (could it be done without any bash in the middle)?
  • Switching to Sequoia makes it really simple to implement stuff like Validate encrypted submissions are PGP compliant in sd-app securedrop-client#433
  • redwood is in the SecureDrop server monorepo, but it would be nice to copy a lot of it - what's the best way to share code across server and workstation?
  • If the secret key is stored in qubesdb, and source keys are never imported into a gpg keyring (because it's handled in the client), then sd-gpg could be disposable.
    • It would also greatly simplify provisioning, because then we don't need to check the key was imported into the keyring, etc.

@legoktm
Copy link
Member

legoktm commented Nov 17, 2023

@rocodes
Copy link
Contributor

rocodes commented Nov 22, 2023

I was curious, so I did as DemiMarie suggested and replaced gpg2 in qubes.Gpg with chameleon, and.... it worked.

Re upstream, there are still significant unimplemented methods that would still be needed to satisfy qubes-gpg-client, so this isn't a drop-in replacecment for gpg2 in Qubes. (I'm curious what's on the roadmap for chameleon, and if more commands will be implemented or not.) But for our purposes it's neat to check it out, since our gpg usage is quite basic and I think the commands we need are covered off (import --with colons doesn't print with colons using chameleon, but that's not a huge deal).

[user@disp9996 ~]$ echo $QUBES_GPG_DOMAIN
sq-gpg
[user@disp9996 ~]$ qubes-gpg-client --version
gpg (GnuPG-compatible Sequoia Chameleon) 2.2.40
Sequoia gpg Chameleon 0.3.2
sequoia-openpgp 1.17.0
Copyright (C) 2022 p≡p foundation
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /home/user/.gnupg
Supported algorithms:
Pubkey: RSA, DSA, ECDH, ECDSA, EDDSA
Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
[user@disp9996 ~]$ qubes-gpg-client -k
/home/user/.local/share/pgp.cert.d
----------------------------------
pub   rsa4096 2021-05-10 [SC] [expires: 2024-07-08]
      2359E6538C0613E652955E6C188EDD3B7B22E6A3
uid           [ unknown] SecureDrop Release Signing Key <[email protected]>
sub   rsa4096 2021-05-10 [E] [expires: 2024-07-08]

pub   rsa4096 2023-11-21 [SC]
      A4AD67A1CEA7F66D631CC3817DBCCDC9DA24ECF4
uid           [ultimate] testy (test key) <[email protected]>
sub   rsa4096 2023-11-21 [E]

[user@disp9996 ~]$ echo "sequoia rocks" > hi.txt && qubes-gpg-client --trust-model always --encrypt -r 2359E6538C0613E652955E6C188EDD3B7B22E6A3 -r [email protected] --armor hi.txt > hi.txt.asc
[user@disp9996 ~]$ head -n1 hi.txt.asc 
-----BEGIN PGP MESSAGE-----
[user@disp9996 ~]$ qubes-gpg-client --decrypt hi.txt.asc 
gpg: encrypted with 4096-bit RSA key, ID 6275A4BA4C71447A, created 2021-05-10
      "SecureDrop Release Signing Key <[email protected]>"
gpg: encrypted with 4096-bit RSA key, ID 18C3F3B6BA15BE14, created 2023-11-21
      "testy (test key) <[email protected]>"
sequoia rocks

Few examples of things that aren't implemented:

user@sq-gpg:~/sequoia-chameleon-gnupg$ gpg --full-generate-key  # it's not a qubes-gpg-client command either, I was just curious 
Greetings from the people of earth!
gpg: Command aFullKeygen is not implemented.

also

user@disp9996 ~]$ qubes-gpg-client --list-sig 
gpg: Command aListSigs is not implemented.

@nwalfield
Copy link

Thanks for this interesting feedback about the chameleon!

(cc: @teythoon)

there are still significant unimplemented methods that would still be needed to satisfy qubes-gpg-client

If you are thinking of using the chameleon, then it would be helpful for us if you could open an issue with the list of methods that you need so that we can prioritize them. If not, we'll get to them eventually.

I'm curious what's on the roadmap for chameleon, and if more commands will be implemented or not.

The chameleon is intended to be a drop-in replacement for gpg. So anything not yet implemented is on the to do list.

Import --with colons doesn't print with colons using chameleon, but that's not a huge deal

As an aside: please don't work around any limitations of the chameleon. These are bugs in the chameleon.

Thanks!

@teythoon
Copy link

I'm curious what's on the roadmap for chameleon, and if more commands will be implemented or not.

The chameleon is intended to be a drop-in replacement for gpg. So anything not yet implemented is on the to do list.

The best way to drive the chameleon development into the direction you want is to propose a test suite that it should pass.

Import --with colons doesn't print with colons using chameleon, but that's not a huge deal

As an aside: please don't work around any limitations of the chameleon. These are bugs in the chameleon.

If you find divergences, please do file bugs. In this particular case, I'm not sure there is a divergence, because GnuPG also doesn't emit colon delimited output, at least not the version I'm testing:

% /bin/gpg --with-colons --import damian.pgp
gpg: keybox '/tmp/tmp.L00Zzx1LlL/pubring.kbx' created
gpg: /tmp/tmp.L00Zzx1LlL/trustdb.gpg: trustdb created
gpg: key 10246E144519DA63: public key "[email protected]" imported
gpg: key 10246E144519DA63: secret key imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
% /bin/gpg --version
gpg (GnuPG) 2.2.40
libgcrypt 1.10.1
Copyright (C) 2022 g10 Code GmbH
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /tmp/tmp.L00Zzx1LlL
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

@rocodes
Copy link
Contributor

rocodes commented Nov 22, 2023

Hi @nwalfield @teythoon thanks so much for your fast responses :) Look forward to spending more time looking at chameleon and at Sequoia generally, and great to hear about your plans.

Qubes makes use of a wrapper around gpg2 that is called qubes-gpg-client that implements a subset of gpg2 features, so those would be the commands that would be required for Qubes users to replace gpg2 with gpg-sq.

Re: test suite-- that makes sense. I/we will file bug reports as you suggest as relevant info surfaces (although I'm not sure on what timeframe, we're definitely interested in looking at this more as capacity permits). You'd also probably have a lot of interest in your comments+work in the upstream Qubes ticket that @legoktm mentioned.

Re gpg import with-colons (debian 12, but same behaviour on debian 11):

user@deb-12-test:~$ gpg --import-options import-show --with-colons --import test.asc 
pub:-:4096:1:43B760F197CA1BF5:1488853415:::-:::scSC::::::23::0:
fpr:::::::::A55DC100FFD712ADB92B5B1043B760F197CA1BF5:
uid:-::::1488853415::D82AF4D6CF20CCE151A3AF00046E5D1C0FE15EFF::Qubes OS 4 Debian Packages Signing Key::::::::::0:
gpg: Total number processed: 1
gpg:              unchanged: 1
user@deb-12-test:~$ gpg --version
gpg (GnuPG) 2.2.40
libgcrypt 1.10.1
Copyright (C) 2022 g10 Code GmbH
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /home/user/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

@teythoon
Copy link

Ah, I didn't know about --import-options import-show, that is indeed not implemented yet. I'll put that into the queue.

@teythoon
Copy link

@rocodes by the way, the latest release of the Chameleon now supports --import-options import-show.

@legoktm
Copy link
Member

legoktm commented Jul 25, 2024

Just some more verbose notes on how to move forward here.

encryption

Journalists write replies to sources, which are encrypted to the source's public key and sent to the server. Currently this goes over qubes-split-gpg in the offline sd-gpg VM, and then back to the client. (And the source's public key has to be imported into the sd-gpg keyring.)

The source's public key is already stored in our sd-app VM's SQLite database, so I think we should adopt Sequoia in a similar way to how we did it on the server, with a module like redwood. (here: https://github.com/freedomofpress/securedrop-client/blob/b8c2970ed9177e34ce45d4e922d58646e4d7544e/client/securedrop_client/crypto.py#L187)

This should provide a noticable performance improvement because 1) we no longer need to import the source's PGP key into the sd-gpg keyring 2) we no longer need to roundtrip through the sd-gpg VM for encrypting messages.

decryption

To decrypt messages from sources, the encrypted file is sent to the sd-gpg VM, decrypted using the instance secret key, and then passed back to the sd-app VM. This must go over the VM boundary because the PGP secret key is kept in a separate, offline VM.

I think we have two options here:

Chameleon

Continue using qubes-split-gpg but have the Chameleon inside the sd-gpg VM.

Pros:

  • we can basically keep the same client code and get most of the Sequoia benefits
  • we can keep using qubes-split-gpg and all of the filtering it has

Cons:

  • stuck to the GPG CLI
  • need to make sure Qubes usptream doesn't make changes to qubes-split-gpg that are incompatible with Chameleon

Custom RPC with Sequoia

We write our own Qubes RPC protocol that invokes Sequoia (maybe via sq)

Pros:

  • We aren't tied to the GPG command-line

Cons:

  • We have to write our own custom RPC protocol

I think we could probably do...both? Start with the Chameleon to get the Sequoia benefits right away and then figure out a custom RPC protocol later on.

packages

Chameleon isn't in bookworm (just trixie) and via IRC it was mentioned that sq in bookworm is outdated too. We can build/ship our own binaries via, e.g. cargo install sequoia-chameleon-gnupg --version $version --locked. (Maybe we'd clone via git first to check cargo vet or something.)

@legoktm legoktm changed the title Consider moving from GnuPG to Sequoia Move from GnuPG to Sequoia Jul 25, 2024
@ben-grande
Copy link

ben-grande commented Jan 7, 2025

I think we could probably do...both? Start with the Chameleon to get the Sequoia benefits right away and then figure out a custom RPC protocol later on.

Starting with the Chameleon seems to be the best idea. Demi did recent improvements to support gpg-sq in split-gpg2:

Which I have tested and used gpg-sq on both ends, client and server. It "works" for basic things.

Demi said on Matrix qubes-public:

I tried it on the client side with Mutt and ran into a problem (key not valid I think).

Marek said on Matrix qubes-public:

I'd love to see more Sequoia usage (instead of GnuPG), but since it has stricter rules for key validity (even if technically correct) it fails in many real world cases... AFAIR the most common issue I hit is extending key validity - sequoia expects to see all binding signatures, not just the most recent one, and very few implementations export all of them (https://gitlab.com/sequoia-pgp/sequoia/-/issues/1105)

Which is an edge case but also a deal breaker when it happens.

Doing custom RPC with sequoia only works in the split-gpg (v1) style, as Sequoia has no agent, only the Chameleon version has. The client would be a wrapper and the server side could also be a workaround. It a subset of Sequoia options were used, this could work, but using split-gpg2 is cleaner from my POV, less maintenance burden letting Qubes OS restrict calls that can be made to the server.

@nwalfield
Copy link

It "works" for basic things.

If something is missing that you need it would be helpful for us to prioritize development if you would open an issue.

a deal breaker when it happens.

What deal do you think is being broken?

as Sequoia has no agent, only the Chameleon version has.

Both the chameleon and sq can use gpg-agent. Can you please elaborate on what you mean?

@ben-grande
Copy link

It "works" for basic things.

If something is missing that you need it would be helpful for us to prioritize development if you would open an issue.

Sure!

a deal breaker when it happens.

What deal do you think is being broken?

For me, signing and encryption operations works, but validating signatures of users that updated their keys from vulnerable algorithms will be reported by sequoia as invalid:

This is not a problem on all use cases of course.

as Sequoia has no agent, only the Chameleon version has.

Both the chameleon and sq can use gpg-agent. Can you please elaborate on what you mean?

Outdated information from my part, just read your comment about having gpg-agent support in sequoia (not only chameleon) now.

Thanks for working on this!

@nwalfield
Copy link

but validating signatures of users that updated their keys from vulnerable algorithms will be reported by sequoia as invalid:

I think you are saying the following: A certificate, which relies on weak algorithms, is created at t0. At t1, it creates a signature. At t2, the certificate is updated to not rely on weak signatures. At t3, the signature still can't be verified. Is that correct?

In that case, yes, the signature will be considered invalid.

To be clear, this is not due to the use of --export-options export-minimal, but because the new self signatures are made after the signature.

Thanks for working on this!

🙇‍♂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants