Giter Club home page Giter Club logo

Comments (8)

flatcap avatar flatcap commented on May 25, 2024 1

Good idea!
If Thunderbird can get the info, then I'm sure we can.


I don't know how NeoMutt encrypts, but gpg has two options:

--recipient name
-r Encrypt for user id name.

--hidden-recipient name
-R Encrypt for user ID name, but hide the key ID of this user's key.

The hidden option means that key is only known at decryption time,
and then only by trying our private keys until we get a match.

from neomutt.

alejandro-colomar avatar alejandro-colomar commented on May 25, 2024 1

I'll need to test gpg(1) to see what info is available, and what info can be faked. Thanks for the pointers!

from neomutt.

alejandro-colomar avatar alejandro-colomar commented on May 25, 2024 1

I've found this:

https://www.gnupg.org/documentation/manuals/gpgme.pdf#Decrypt

$ grepc gpgme_decrypt_result_t /usr/include/
/usr/include/gpgme.h:typedef struct _gpgme_op_decrypt_result *gpgme_decrypt_result_t;
$ grepc _gpgme_op_decrypt_result /usr/include/
/usr/include/gpgme.h:struct _gpgme_op_decrypt_result
{
  char *unsupported_algorithm;

  /* Key should not have been used for encryption.  */
  unsigned int wrong_key_usage : 1;

  /* True if the message was encrypted in compliance to the de-vs
   * mode.  */
  unsigned int is_de_vs : 1;

  /* The message claims that the content is a MIME object.  */
  unsigned int is_mime : 1;

  /* The message was made by a legacy algorithm without any integrity
   * protection.  This might be an old but legitimate message. */
  unsigned int legacy_cipher_nomdc : 1;

  /* Internal to GPGME, do not use.  */
  int _unused : 28;

  gpgme_recipient_t recipients;

  /* The original file name of the plaintext message, if
   * available.  */
  char *file_name;

  /* A textual representation of the session key used to decrypt the
   * message, if available */
  char *session_key;

  /* A string with the symmetric encryption algorithm and mode using
   * the format "<algo>.<mode>".  */
  char *symkey_algo;
};

The important part is:

  gpgme_recipient_t recipients;

from neomutt.

flatcap avatar flatcap commented on May 25, 2024 1

Well done!

from neomutt.

flatcap avatar flatcap commented on May 25, 2024 1

I guess we could ... check the keyring to see if we can find a name for the recipient

That would look pretty cool, but... I suspect it could be a bit slow if the keyring is large.

Perhaps in v2, with a config variable to en-/disable it.

from neomutt.

flatcap avatar flatcap commented on May 25, 2024 1

More v2 ideas...

We're displaying the sub-key that was used to encrypt.
Can we get to the main key? (which would be more recognisable to people)

e.g. For my key, that'd be 69AD1D636AC292E820658C16EBC150E4B5DA63DF rather than 544F271C223CE792

If we can get to the main key?
Can we get the real name / email address?

from neomutt.

alejandro-colomar avatar alejandro-colomar commented on May 25, 2024

I've written some draft to see if it would work, and yeah, looks simple. I'll need to polish it, but it looks simple enough.

commit 79a0f81a378bcf6134ad3019cc68cf01d4d00dfe (HEAD -> gpg)
Author: Alejandro Colomar (@alejandro-colomar) <[email protected]>
Date:   Thu Mar 28 16:44:19 2024 +0100

    Begin encryption information
    
    Signed-off-by: Alejandro Colomar <[email protected]>

diff --git a/ncrypt/crypt_gpgme.c b/ncrypt/crypt_gpgme.c
index b98f78d95..a55b97b85 100644
--- a/ncrypt/crypt_gpgme.c
+++ b/ncrypt/crypt_gpgme.c
@@ -1699,6 +1699,7 @@ static struct Body *decrypt_part(struct Body *b, struct State *state,
   struct Body *tattach = NULL;
   int err = 0;
   gpgme_data_t ciphertext = NULL, plaintext = NULL;
+  gpgme_decrypt_result_t result = NULL;
   bool maybe_signed = false;
   bool anywarn = false;
   int sig_stat = 0;
@@ -1740,6 +1741,27 @@ restart:
   }
   gpgme_data_release(ciphertext);
   ciphertext = NULL;
+
+  result = gpgme_op_decrypt_result(ctx);
+  if (result)
+  {
+    if ((state->flags & STATE_DISPLAY))
+    {
+      state_attach_puts(state, _("[-- Begin encryption information --]\n"));
+    }
+
+    for (gpgme_recipient_t r = result->recipients; r; r = r->next)
+    {
+      state_puts(state, r->keyid);
+      state_puts(state, "\n");
+    }
+
+    if ((state->flags & STATE_DISPLAY))
+    {
+      state_attach_puts(state, _("[-- End encryption information --]\n\n"));
+    }
+  }
+
   if (err != 0)
   {
 #ifdef USE_AUTOCRYPT
@@ -1754,9 +1776,6 @@ restart:
        * header told us.  Retry then.  gpgsm returns the error information
        * "unsupported Algorithm '?'" but GPGME will not store this unknown
        * algorithm, thus we test that it has not been set. */
-      gpgme_decrypt_result_t result = NULL;
-
-      result = gpgme_op_decrypt_result(ctx);
       if (!result->unsupported_algorithm)
       {
         maybe_signed = true;

And then I read an email I have encrypted to me and the other recipient, and it shows this:

[-- Begin encryption information --]
C527609C7E1875BD
00C14A7DBBDD521C
[-- End encryption information --]

[-- Begin signature information --]
Good signature from: Alejandro Colomar <[email protected]>
                aka: Alejandro Colomar <[email protected]>
                aka: Alejandro Colomar Andres <[email protected]>
            created: Sun Mar 24 15:26:50 2024
[-- End signature information --]

from neomutt.

alejandro-colomar avatar alejandro-colomar commented on May 25, 2024

@flatcap , do you have any preference for the formatting?

Thunderbird shows messages as

In addition, this message was encrypted to the owners of the
following keys:
The message was encrypted to the owners of the following keys:
0x00C14A7DBBDD521C
The message was encrypted to the owners of the following keys:
0x0000000000000000
The message was encrypted to the owners of the following keys:
0x0011111111111111

For neomutt(1), I would keep it simpler:

[-- Begin encryption information --]
Recipient: 0xC527609C7E1875BD
Recipient: 0x00C14A7DBBDD521C
[-- End encryption information --]

The structure also seems to have the information about the algorithm, which could be interesting to show.

$ grepc gpgme_recipient_t /usr/include/
/usr/include/gpgme.h:typedef struct _gpgme_recipient *gpgme_recipient_t;
$ grepc _gpgme_recipient /usr/include/
/usr/include/gpgme.h:struct _gpgme_recipient
{
  struct _gpgme_recipient *next;

  /* The key ID of key for which the text was encrypted.  */
  char *keyid;

  /* Internal to GPGME, do not use.  */
  char _keyid[16 + 1];

  /* The public key algorithm of the recipient key.  */
  gpgme_pubkey_algo_t pubkey_algo;

  /* The status of the recipient.  */
  gpgme_error_t status;
};
  /* The public key algorithm of the recipient key.  */
  gpgme_pubkey_algo_t pubkey_algo;

Which contains this kind of info:

$ grepc gpgme_pubkey_algo_t /usr/include/
/usr/include/gpgme.h:typedef enum
  {
    GPGME_PK_RSA   = 1,
    GPGME_PK_RSA_E = 2,
    GPGME_PK_RSA_S = 3,
    GPGME_PK_ELG_E = 16,
    GPGME_PK_DSA   = 17,
    GPGME_PK_ECC   = 18,
    GPGME_PK_ELG   = 20,
    GPGME_PK_ECDSA = 301,
    GPGME_PK_ECDH  = 302,
    GPGME_PK_EDDSA = 303
  }
gpgme_pubkey_algo_t;

Documented in https://www.gnupg.org/documentation/manuals/gpgme.pdf#Public%20Key%20Algorithms.

Maybe we could show that info in parentheses, like:

[-- Begin encryption information --]
Recipient: (RSA) 0xC527609C7E1875BD
Recipient: (RSA) 0x00C14A7DBBDD521C
[-- End encryption information --]

With those key IDs, I guess we could go further, and check the keyring to see if we can find a name for the recipient, and then print it alongside it. Or maybe we can keep it simple for now, since it's trivial to check it manually once you have the key ID. I prefer to keep it simple.

@dd9jn , maybe you want to share your opinion, since I think you wrote or significantly edited that gpgme function. I'll CC you here just in case. :-)

from neomutt.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.