snappymail icon indicating copy to clipboard operation
snappymail copied to clipboard

Improve OpenPGP

Open the-djmaze opened this issue 3 years ago • 29 comments

Describe the bug The RainLoop OpenPGP implementation is incorrect.

  1. Encrypt message should be with 'Recipient' public key (not your own key)
  2. Sign a message should be with 'From' private key
  3. Received signed "Content-Type: multipart/alternative" message can't be verified yet (only plain)
  4. etc. etc.

Some limitations are caused by the current implementation in JavaScript. Either the whole message body should be rendered as-is in JavaScript or handled in PHP with https://php.net/gnupg or others.

Reported issues at RainLoop: https://github.com/RainLoop/rainloop-webmail/issues?q=is%3Aissue+is%3Aopen+pgp

I made a Wiki page that explains the rules. https://github.com/the-djmaze/snappymail/wiki/OpenPGP

TODO:

Keys

Import public/private keys

  • [x] GnuPG
  • [x] Mailvelope
  • [x] OpenPGP.js

Note: as of v2.34 you can search public key servers to find them, and import all keys from server into OpenPGP.js

View public/private keys

  • [x] GnuPG
  • [x] Mailvelope
  • [x] OpenPGP.js

Delete public/private keys

  • [x] GnuPG
  • [x] Mailvelope
  • [x] OpenPGP.js

Allow private keys without password

  • [x] Mailvelope
  • [x] ❌ GnuPG not secure/too risky when allowed
  • [x] OpenPGP.js

Decrypt / Sign when multiple keys exist

  • [ ] Detect which key to use
  • [ ] or let user select

Received messages

PGP/Inline (cleartext)

Decrypt

  • [x] Mailvelope
  • [x] GnuPG
  • [x] OpenPGP.js

Verify signature

  • [x] ❌ Mailvelope https://github.com/mailvelope/mailvelope/issues/434
  • [x] GnuPG
  • [x] OpenPGP.js

Decrypt then verify signature

  • [x] Mailvelope
  • [ ] GnuPG
  • [x] OpenPGP.js

PGP/MIME (multipart)

Decrypt

  • [x] Mailvelope
  • [x] GnuPG
  • [x] OpenPGP.js

Verify signature

  • [x] ❌ Mailvelope https://github.com/mailvelope/mailvelope/issues/434
  • [x] GnuPG
  • [x] OpenPGP.js

Decrypt then verify signature

  • [x] Mailvelope
  • [x] GnuPG
  • [x] OpenPGP.js

Sending messages

PGP/Inline (cleartext)

❌ no, everything is PGP/MIME

PGP/MIME (multipart)

Encrypt message text

  • [x] Mailvelope (no html, only plain)
  • [x] GnuPG
  • [x] OpenPGP.js

Encrypt attachments

  • [x] Mailvelope
  • [x] GnuPG
  • [ ] OpenPGP.js

Sign

  • [x] ❌ Mailvelope https://github.com/mailvelope/mailvelope/issues/750
  • [x] GnuPG
  • [x] OpenPGP.js (no attachments yet)

Sign then Encrypt

  • [x] ❌ Mailvelope (no html, only plain, can't select sign key)
  • [x] GnuPG (also encrypts attachments)
  • [x] OpenPGP.js (no attachments yet)

Autocrypt

As requested in issue #342 for https://autocrypt.org/

  • [x] Import public keys from MIME header
  • [x] Send public keys in MIME header

NOTE

Although we properly support PGP/MIME I've discovered some systems don't, including Mailvelope: https://github.com/roundcube/roundcubemail/issues/8417#issuecomment-1040307808

Also there's the crypto refresh https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh/ And see https://fosdem.org/2024/schedule/event/fosdem-2024-2669--security-modernizing-email-encryption-the-crypto-refresh-of-openpgp/

the-djmaze avatar May 19 '21 13:05 the-djmaze

I remember a discussion back on RainLoop Git. If I recall correctly the keys (so also your private key!) are stored server side. In my case, I'm the server admin so I kind of trust this. But I would not trust anyone else with my private key. Even if I used my own server, I would not trust it if it was a VPS or some other shared service.

So if this is currently broken, I would consider this a good candidate to shrink the SnappyMail code :)

ervee avatar Aug 10 '21 14:08 ervee

If I recall correctly the keys (so also your private key!) are stored server side.

No, private keys are in your browser localStorage (which also sucks). An "encrypted" copy could be stored on the server (with symmetric encryption and passphrase) but that defeats the use of serverside gnupg.

RoundCube: uses gnupg ProtonMail: does not use PGP (they say they do, but they send an e-mail with a link and you must open the link) etc.

There are only 2 cases where we need private keys:

  1. Sign a message
  2. Decrypt received message

Public keys is no issue and we can still use for:

  1. Verify received signature
  2. Encrypt message to send

Solving the public keys issue would be the first step to solve. This should be easy for webmail without security issues.

the-djmaze avatar Aug 10 '21 15:08 the-djmaze

ProtonMail: does not use PGP (they say they do, but they send an e-mail with a link and you must open the link) etc.

Plaît-il ? Some people send messages to me from protonmail, and I received them PGP-encrypted (as I have WKD configured in my domain, and then my public keys are easily discoverable).

Maybe you receive the message in this form when the user force encryption to a recipient who don't have a public key known or discoverable via WKD? Cause, with protonmail we are able to encrypt to recipient whithout PGP-enabled encryption, with something like a password.

GregThib avatar Dec 16 '21 20:12 GregThib

Just my two cents: in the RainLoop issue feed, there is a lot of questions about PGP implementation, e.g. the use of WKD to discover keys, the opportunistic encryption, and a few things more.

Today, I think it's important to reach a core-base PGP encryption (encrypt, sign, verify) without getting too much pressure about the remaining (trust model, key discover, etc.).

As we can see with Thunderbird, since they have dropped the Enigmail support, their implementation is suffering too.

GregThib avatar Dec 16 '21 21:12 GregThib

@GregThib oh yes, i've added OpenPGP.js 5.0.1 for comparison and development. Problem is that the library is not 100% compiled for web, it also (still) has Node.js code. So i'm cleaning up the 1.5 MiB code to get more in line with the old 636 KiB openpgp-sm.js

But still, i should look at GnuPG as well

the-djmaze avatar Dec 22 '21 19:12 the-djmaze

Working on this issue revealed that RainLoop never correctly verified signed messages. A signature must be done on the whole multipart/signed but it never does. It only checks if the pgp sgnature is valid.

the-djmaze avatar Jan 16 '22 12:01 the-djmaze

Oo This is a pretty serious issue.

GregThib avatar Jan 16 '22 13:01 GregThib

Oo This is a pretty serious issue.

Yep, but as you can see all the commits, there is work in progress :)

For now it uses GnuPG to verify PGP messages. This method is tested and now works properly here.

  1. uses php pecl gnupg
  2. store public keys in: …/_data_/_default_/storage/[example.com]/[account]/.gnupg (no UI yet)
  3. JavaScript click on "🔒OpenPGP signed message (click to verify)" will call the new MessagePgpVerify (result not in UI yet)

Still todo regarding "verify":

  1. Improve UI /#/settings/openpgp with public keys section for verifying received messages
  2. Show verify results in UI
  3. Alternatives to GnuPG extension: Crypt_GPG, OpenPGP.js, Mailvelope, openpgp-php + phpseclib

Todo after that:

  1. Encrypt using public keys
  2. Manage private keys
  3. Decrypt messages with private keys
  4. Sign messages with private keys

the-djmaze avatar Jan 18 '22 14:01 the-djmaze

Update: latest changes now properly load keyrings of:

  • Mailvelope
  • OpenPGP.js
  • GnuPG

Composer window is revamped and has no PopupsComposeOpenPgp. Instead the dropdown menu now has two options:

  • Sign
  • Encrypt

Sign

Only enabled when chosen identity (from) has a private key.

Encrypt

Only enabled when all recipients (to, cc, bcc) have a public key. Also all recipients must be either in Mailvelope or OpenPGP.js or GnuPG and can't be mixed. TODO: should be extended to lookup HKP servers and others to find the keys.

The system is still defunct and does not Sign nor Encrypt yet. First i need to get all keyring systems to work properly.

the-djmaze avatar Jan 19 '22 19:01 the-djmaze

Impressive!

I wanted to congratulate you very much for your work on this tool. I am impressed by the speed and efficiency with which you deal with this problem, and thank you for the attention given to your users.

Gratefully!

GregThib avatar Jan 19 '22 20:01 GregThib

@GregThib thank you!

Working on this, i noticed many problems that have to be dealt with:

  1. PHP PECL GnuPG doesn't import private keys. I need to call gpg --import --homedir=/home/snappymail/__data__/,,,,/.gnupg secret_key.asc
  2. gnupg_keyinfo() v1.5+ should have hidden param to list private keys, else only public keys are returned
  3. OpenPGP.js and Mailvelope can't sign/encrypt attachments or the whole message (only cleartext)
  4. etc.

So basically it is a PITA to sign/encrypt properly. But hopefully i get there eventually.

Looking at the Enigma source of RoundCube it seems that it also should have issues with it.

the-djmaze avatar Jan 20 '22 15:01 the-djmaze

Dropped support for PEAR Crypt_GPG because it is missing features. For best memory usage i want to stream data in/out the mailso imap stream with GnuPG in between. That way it is easy to encrypt/decrypt/sign/verify large messages (20MiB+). Crypt_GPG does have encryptFile but not an encryptStream.

Also it can't generate ECC keys.

So i'm building a new gpg.php class that shall solve it using gnupg and Crypt_GPG as examples.

the-djmaze avatar Jan 24 '22 20:01 the-djmaze

Improved detection of PGP/MIME encrypted messages. As reported at https://github.com/RainLoop/rainloop-webmail/issues/1848

It also nicely shows unencrypted attachments.

afbeelding

the-djmaze avatar Jan 25 '22 16:01 the-djmaze

Decryption now works using Mailvelope afbeelding

the-djmaze avatar Jan 26 '22 16:01 the-djmaze

I've updated the demo at https://snappymail.eu/demo/ You can follow progress there and test using the new OpenPGP, GnuPG and Mailvelope

You can send test e-mails to [email protected] and see the result.

When using Mailvelope don't forget to edit the settings in Mailvelope -> Options -> Authorized Domains -> Add new entry afbeelding

Private key password: demo

-----BEGIN PGP PRIVATE KEY BLOCK-----

xYYEYfQDqBYJKwYBBAHaRw8BAQdAy+llquGb/U4M0kD2xyJoQ2pwlDN02C7X
D9067I8zdB3+CQMIu0SL71bzJVng2v4G53CCF+SXbvCXxV6vEIS+LapvPWov
XNdC0BYt9IhYdyumVe+eRwGbJO/r6mIY/oIHVuWnBM5FZcVHTEVm23WbjYaj
Ac0ZZGVtbyA8ZGVtb0BzbmFwcHltYWlsLmV1PsKMBBAWCgAdBQJh9AOoBAsJ
BwgDFQgKBBYAAgECGQECGwMCHgEAIQkQXzpc3AmtiuMWIQQsIj8g6irbTLaP
gdlfOlzcCa2K4/nPAP4uUrWr39wv+YKsNcLwHwOpljyu59iHOXA3halUbVCe
JwD/dY6JXCwMDgG+BmurPcJhS/S8Q6fjlN9hUi/za3acYATHiwRh9AOoEgor
BgEEAZdVAQUBAQdAvXl+RCkqtUqNVQ3Fj3bFTZjZOeNlI3ibK2eN6EjlnwcD
AQgH/gkDCND/LFApgNcK4OTn9H4weJlpeZkM4X6vpQKIH4D6LVkppyjNzMhj
/tkS+49qmxVy1KdWRunaqEIaes6huDKsxahIOnQPim7In6UMSzEeACrCeAQY
FggACQUCYfQDqAIbDAAhCRBfOlzcCa2K4xYhBCwiPyDqKttMto+B2V86XNwJ
rYrjolQBAMqdz8VkgMYjM7tinwUUTe4JjZoCsuhHPN6SpQLd/UzKAQDgRlbA
drl042/nJcdrBrQz3+wVzkaF0ehvihBf4/tfDw==
=BqC1
-----END PGP PRIVATE KEY BLOCK-----

-----BEGIN PGP PUBLIC KEY BLOCK-----

xjMEYfQDqBYJKwYBBAHaRw8BAQdAy+llquGb/U4M0kD2xyJoQ2pwlDN02C7X
D9067I8zdB3NGWRlbW8gPGRlbW9Ac25hcHB5bWFpbC5ldT7CjAQQFgoAHQUC
YfQDqAQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJEF86XNwJrYrjFiEELCI/
IOoq20y2j4HZXzpc3AmtiuP5zwD+LlK1q9/cL/mCrDXC8B8DqZY8rufYhzlw
N4WpVG1QnicA/3WOiVwsDA4BvgZrqz3CYUv0vEOn45TfYVIv82t2nGAEzjgE
YfQDqBIKKwYBBAGXVQEFAQEHQL15fkQpKrVKjVUNxY92xU2Y2TnjZSN4mytn
jehI5Z8HAwEIB8J4BBgWCAAJBQJh9AOoAhsMACEJEF86XNwJrYrjFiEELCI/
IOoq20y2j4HZXzpc3AmtiuOiVAEAyp3PxWSAxiMzu2KfBRRN7gmNmgKy6Ec8
3pKlAt39TMoBAOBGVsB2uXTjb+clx2sGtDPf7BXORoXR6G+KEF/j+18P
=n8aj
-----END PGP PUBLIC KEY BLOCK-----

the-djmaze avatar Jan 28 '22 14:01 the-djmaze

Pfffft this was work: https://github.com/the-djmaze/snappymail/commit/e265a0f1c175a989e82ff2a6ce2411f9e9582a48

RainLoop modified the message HTML part in PHP on the server, and so did SnappyMail. But while supporting PGP/MIME multipart encrypted messages, the issue with parsing HTML and attachments became a problem because that is server-side.

So i've moved all code to be client-side so that decrypted messages act the same.

the-djmaze avatar Feb 02 '22 12:02 the-djmaze

Demo at https://snappymail.eu/demo/ is updated with latest changes.

You can encrypt using Mailvelope. afbeelding A Mailvelope button will appear when all recipients can receive encrypted data.

the-djmaze avatar Feb 03 '22 16:02 the-djmaze

Here's a preview release https://github.com/the-djmaze/snappymail/releases

the-djmaze avatar Feb 07 '22 11:02 the-djmaze

@GregThib you can start with https://github.com/the-djmaze/snappymail/releases/tag/2.12.0

the-djmaze avatar Feb 11 '22 15:02 the-djmaze

Hello !

Note : My English is not very good, sorry for that.

I'm having a problem on my docker installation, based on @kouinkouin image ( #44 ).

Very simply, I can't decipher the encrypted emails.

Whether with OpenPGP or GnuPG, the decryption is done well (I have the message "Message encrypted by OpenPGP" after decryption), but the encrypted message is not replaced in the interface.

I note an interesting point, with GnuPG, when I look at the Ajax requests and I launch the decryption, the response contains the decrypted message, but the JSON does not seem correct ( See the screenshots ).

Note that I don't know if this is a problem specific to the Docker image, or if the problem also exists in the context of a classic installation.

Is this issue known / related to this issue?

Thanks in advance !

After click on "Decrypt" button :

image

Reponse of request when use GnuPG ( Response is decrypted, I can read message ) :

image

image

luluwebmaster avatar Feb 11 '23 10:02 luluwebmaster

@luluwebmaster Who encrypted the message? (Hopefully Thunderbird, because that has bugs and should only be used in PGP/MIME mode).

Looking at it, it is quoted-printable encoded HTML and that is wrong.

There are 2 types of PGP encryption:

  1. PGP/Inline which is plain text (not HTML)
  2. PGP/MIME which can be plain and/or HTML with optional attachments and/or inline images

the-djmaze avatar Feb 11 '23 15:02 the-djmaze

The message received has been encrypted by Thunderbird.

Could this be a problem with Thunderbird ?

luluwebmaster avatar Feb 13 '23 10:02 luluwebmaster

Correct! https://superuser.com/questions/794959/what-is-introducing-quoted-printables-into-my-pgp-encrypted-emails

Force Thunderbird to use PGP/MIME and try again

the-djmaze avatar Feb 13 '23 15:02 the-djmaze

Does that mean that all my correspondents must activate this option .. ? It's not possible to "fix" this on Snappy interface ?

luluwebmaster avatar Feb 14 '23 08:02 luluwebmaster

If we make a workaround, how would other people with different applications see the broken Thunderbird?

  • gmail
  • kmail
  • fairemail
  • apple mail
  • outlook
  • microsoft mail
  • etc. etc.

the-djmaze avatar Feb 14 '23 09:02 the-djmaze

Looking at it, the issue is different these days and i will look into it.

afbeelding

the-djmaze avatar Feb 14 '23 10:02 the-djmaze

Ok, not problem, I wait your feedback !

luluwebmaster avatar Feb 14 '23 10:02 luluwebmaster

Hello,

After update of docker image ( 2.26.1 ), now that works correctly !

Thank you.

luluwebmaster avatar Feb 14 '23 16:02 luluwebmaster

@the-djmaze FWIW, I seem to have the same problem that @luluwebmaster was describing. But the message was encrypted using mailvalope instead of thunderbird.

LeifAndersen avatar Feb 28 '23 21:02 LeifAndersen