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

Improve OpenPGP #89

Open
42 of 46 tasks
the-djmaze opened this issue May 19, 2021 · 29 comments
Open
42 of 46 tasks

Improve OpenPGP #89

the-djmaze opened this issue May 19, 2021 · 29 comments
Assignees
Labels
enhancement New feature or request

Comments

@the-djmaze
Copy link
Owner

the-djmaze commented May 19, 2021

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

  • GnuPG
  • Mailvelope
  • 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

  • GnuPG
  • Mailvelope
  • OpenPGP.js

Delete public/private keys

  • GnuPG
  • Mailvelope
  • OpenPGP.js

Allow private keys without password

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

Decrypt / Sign when multiple keys exist

  • Detect which key to use
  • or let user select

Received messages

PGP/Inline (cleartext)

Decrypt

  • Mailvelope
  • GnuPG
  • OpenPGP.js

Verify signature

Decrypt then verify signature

  • Mailvelope
  • GnuPG
  • OpenPGP.js

PGP/MIME (multipart)

Decrypt

  • Mailvelope
  • GnuPG
  • OpenPGP.js

Verify signature

Decrypt then verify signature

  • Mailvelope
  • GnuPG
  • OpenPGP.js

Sending messages

PGP/Inline (cleartext)

❌ no, everything is PGP/MIME

PGP/MIME (multipart)

Encrypt message text

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

Encrypt attachments

  • Mailvelope
  • GnuPG
  • OpenPGP.js

Sign

Sign then Encrypt

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

Autocrypt

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

  • Import public keys from MIME header
  • Send public keys in MIME header

NOTE

Although we properly support PGP/MIME
I've discovered some systems don't, including Mailvelope:
roundcube/roundcubemail#8417 (comment)

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/

@ervee
Copy link

ervee commented Aug 10, 2021

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 :)

@the-djmaze
Copy link
Owner Author

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.

@GregThib
Copy link

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
Copy link

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.

@the-djmaze
Copy link
Owner Author

@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 pushed a commit that referenced this issue Dec 22, 2021
@the-djmaze
Copy link
Owner Author

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.

@GregThib
Copy link

Oo
This is a pretty serious issue.

the-djmaze pushed a commit that referenced this issue Jan 17, 2022
Now it does not fetch the PGP signature, because validation was broken anyway.
Instead it validates multipart/signed according to RFC 3156 section 5 and returns details for the signed part:
* BodyPartId
* SigPartId
* MicAlg

So in the future several implementations (GnuPG, OpenPGP.js, etc.) can use the correct data for verification.
the-djmaze pushed a commit that referenced this issue Jan 17, 2022
This part fetches the required message parts for pgp verification.
the-djmaze pushed a commit that referenced this issue Jan 17, 2022
Bugfix SnappyMail\PGP\Keyservers
Renamed DoPgpVerify to DoMessagePgpVerify
@the-djmaze
Copy link
Owner Author

the-djmaze commented Jan 18, 2022

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
Copy link
Owner Author

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.

@GregThib
Copy link

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!

the-djmaze pushed a commit that referenced this issue Jan 20, 2022
@the-djmaze
Copy link
Owner Author

the-djmaze commented Jan 20, 2022

@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
Copy link
Owner Author

the-djmaze commented Jan 24, 2022

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.

@luluwebmaster
Copy link

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

@the-djmaze
Copy link
Owner Author

the-djmaze commented Feb 11, 2023

@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

@luluwebmaster
Copy link

The message received has been encrypted by Thunderbird.

Could this be a problem with Thunderbird ?

@the-djmaze
Copy link
Owner Author

the-djmaze commented Feb 13, 2023

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

@luluwebmaster
Copy link

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

@the-djmaze
Copy link
Owner Author

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
Copy link
Owner Author

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

afbeelding

@luluwebmaster
Copy link

Ok, not problem, I wait your feedback !

@luluwebmaster
Copy link

luluwebmaster commented Feb 14, 2023

Hello,

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

Thank you.

@LeifAndersen
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants