What do returned values of PHP gnupg signature verification mean?

我与影子孤独终老i 提交于 2019-12-23 20:59:01

问题


I want to verify pgp signed text in PHP. Following PHP documentation and answer to this question i made simple script to test gnupg library. I sent signed email between two email accounts using Thunderbird with Enigmail - receiving Thunderbird shows that signature is correct.

In PHP, when i use plain email text and senders public key, verify() function returns array like this:

array(1) {
  [0]=>
  array(5) {
    ["fingerprint"]=>
    string(40) "468F82339FC55DE5CAFD71BB63DD32AE1308A57F"
    ["validity"]=>
    int(0)
    ["timestamp"]=>
    int(1443033896)
    ["status"]=>
    int(0)
    ["summary"]=>
    int(0)
  }
}

When i change in signed message single word, result changes to:

array(1) {
  [0]=>
  array(5) {
    ["fingerprint"]=>
    string(16) "63DD32AE1308A57F"
    ["validity"]=>
    int(0)
    ["timestamp"]=>
    int(0)
    ["status"]=>
    int(117440520)
    ["summary"]=>
    int(4)
  }
}

And finally, when i change a lot of text or broke signature, function returns false.

So, what do these array values mean?

  • Why validity is always 0?
  • timestamp value is a timestamp of what? Time when message was signed?
  • Why status value is so big in second case? Its just random value or specific error code?
  • Same with summary what stands value of 4 for?

If i want to just simply recognize if text is signed correctly or not, can i just compare returned fingerprint with fingerprint of public key and check if status and summary are equal to 0?


回答1:


PHP's GnuPG documentation is indeed lacking information here. Looking at the source code and GPGME manual and sources, you can derive the relevant information.

Disclaimer: The answer contains some guesswork, by sure to get a reasonable feeling about what's going on if building on it, and feel free to give feedback!

Validity

Why validity is always 0?

For verifying the validity of a signature, you need to assign trust (so GnuPG is able to compute a trust chain). The validity is defined in following GPGME enums:

/* The available validities for a trust item or key.  */
typedef enum
  {
    GPGME_VALIDITY_UNKNOWN   = 0,
    GPGME_VALIDITY_UNDEFINED = 1,
    GPGME_VALIDITY_NEVER     = 2,
    GPGME_VALIDITY_MARGINAL  = 3,
    GPGME_VALIDITY_FULL      = 4,
    GPGME_VALIDITY_ULTIMATE  = 5
  }
gpgme_validity_t;

Timestamp

timestamp value is a timestamp of what? Time when message was signed?

Yes, this one's easy, this is the signature creation timestamp. Be aware the timestamp is usually defined by the signer and can be faked to arbitrary dates.

Status

Same with summary what stands value of 4 for?

Reading the documentation (gpgme_error_t status), it seems the status is defined in gpg-error.h. This is a very long list hosted in GnuPG's git repository.

Yet, the defined status in your question does not make sense to me.

Summary

Why status value is so big in second case? Its just random value or specific error code?

This is a summary on the signature. Again, the summary is defined in a GPGME enum:

/* Flags used for the SUMMARY field in a gpgme_signature_t.  */
typedef enum
  {
    GPGME_SIGSUM_VALID       = 0x0001,  /* The signature is fully valid.  */
    GPGME_SIGSUM_GREEN       = 0x0002,  /* The signature is good.  */
    GPGME_SIGSUM_RED         = 0x0004,  /* The signature is bad.  */
    GPGME_SIGSUM_KEY_REVOKED = 0x0010,  /* One key has been revoked.  */
    GPGME_SIGSUM_KEY_EXPIRED = 0x0020,  /* One key has expired.  */
    GPGME_SIGSUM_SIG_EXPIRED = 0x0040,  /* The signature has expired.  */
    GPGME_SIGSUM_KEY_MISSING = 0x0080,  /* Can't verify: key missing.  */
    GPGME_SIGSUM_CRL_MISSING = 0x0100,  /* CRL not available.  */
    GPGME_SIGSUM_CRL_TOO_OLD = 0x0200,  /* Available CRL is too old.  */
    GPGME_SIGSUM_BAD_POLICY  = 0x0400,  /* A policy was not met.  */
    GPGME_SIGSUM_SYS_ERROR   = 0x0800   /* A system error occured.  */
  }
gpgme_sigsum_t;

Thus, you've got to read the result as binary flags. A status of 4 indicates a bad signature.

Wrap-Up

The first signature was generated some days ago on 2015-09-23T18:44:56+00:00 by key 468F82339FC55DE5CAFD71BB63DD32AE1308A57F and is a correct signature, but the key could be validated (missing trust path).

The second signature seems to be issued by the same key, but is broken.

If i want to just simply recognize if text is signed correctly or not, can i just compare returned fingerprint with fingerprint of public key and check if status and summary are equal to 0?

As far as I understand what's going on, you should test whether summary's bit 4 is set or not. If it is set, you've got a bad signature. Don't compare it with 4, but use bit manipulation to test against the single bit:

($summary & 0x04) == 0x04

If you don't use the web of trust and validity flag to verify signatures, make sure to compare the whole fingerprint against a list of trusted keys.



来源:https://stackoverflow.com/questions/32787007/what-do-returned-values-of-php-gnupg-signature-verification-mean

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!