ENGINE-472: pgp_gpg.c: don't give up on 1st void subkey (downrate to unreliable instead) ENGINE-472
authorClaudio Luck <claudio.luck@pep.foundation>
Mon, 22 Oct 2018 21:02:53 +0200
branchENGINE-472
changeset 30987d3a9eb26b28
parent 3095 4df9a15497c2
ENGINE-472: pgp_gpg.c: don't give up on 1st void subkey (downrate to unreliable instead)
src/pgp_gpg.c
     1.1 --- a/src/pgp_gpg.c	Mon Oct 22 08:18:06 2018 +0200
     1.2 +++ b/src/pgp_gpg.c	Mon Oct 22 21:02:53 2018 +0200
     1.3 @@ -1990,9 +1990,20 @@
     1.4      case GPG_ERR_NO_ERROR:
     1.5          assert(key);
     1.6          assert(key->subkeys);
     1.7 +        bool crt_available = false;
     1.8 +        bool sgn_available = false;
     1.9 +        bool enc_available = false;
    1.10 +        bool sk_too_short = false;
    1.11 +        bool sk_weak = false;
    1.12 +        bool sk_disabled = false;
    1.13 +        bool sk_invalid = false;
    1.14 +        bool sk_expired = ( key->expired || key->subkeys->expired );
    1.15 +        bool sk_revoked = false;
    1.16          for (gpgme_subkey_t sk = key->subkeys; sk != NULL; sk = sk->next) {
    1.17 -            if (sk->length < 1024)
    1.18 -                *comm_type = PEP_ct_key_too_short;
    1.19 +            if (sk->length < 1024) {
    1.20 +                sk_too_short = 1;
    1.21 +                continue;
    1.22 +            }
    1.23              else if (
    1.24                  (
    1.25                  (sk->pubkey_algo == GPGME_PK_RSA)
    1.26 @@ -2000,21 +2011,53 @@
    1.27                  || (sk->pubkey_algo == GPGME_PK_RSA_S)
    1.28                  )
    1.29                  && sk->length == 1024
    1.30 -                )
    1.31 -                *comm_type = PEP_ct_OpenPGP_weak_unconfirmed;
    1.32 +                ) {
    1.33 +                sk_weak = 1;
    1.34 +            }
    1.35  
    1.36 +            if (sk->disabled) {
    1.37 +                sk_disabled = 1;
    1.38 +                continue;
    1.39 +            }
    1.40              if (sk->invalid) {
    1.41 -                *comm_type = PEP_ct_key_b0rken;
    1.42 -                break;
    1.43 +                sk_invalid = 1;
    1.44 +                continue;
    1.45              }
    1.46              if (sk->expired) {
    1.47 -                *comm_type = PEP_ct_key_expired;
    1.48 -                break;
    1.49 +                sk_expired = 1;
    1.50 +                continue;
    1.51              }
    1.52              if (sk->revoked) {
    1.53 +                sk_revoked = 1;
    1.54 +                continue;
    1.55 +            }
    1.56 +
    1.57 +            if (sk->can_certify) crt_available = true;
    1.58 +            if (sk->can_sign) sgn_available = true;
    1.59 +            if (sk->can_encrypt) enc_available = true;
    1.60 +        }
    1.61 +        if(!(crt_available && sgn_available && enc_available)) {
    1.62 +            if (sk_disabled)
    1.63 +                *comm_type = PEP_ct_key_not_found;
    1.64 +            else if (sk_invalid)
    1.65 +                *comm_type = PEP_ct_key_b0rken;
    1.66 +            else if (sk_expired)
    1.67 +                *comm_type = PEP_ct_key_expired;
    1.68 +            else if (sk_revoked)
    1.69                  *comm_type = PEP_ct_key_revoked;
    1.70 -                break;
    1.71 +            else if (sk_too_short)
    1.72 +                *comm_type = PEP_ct_key_too_short;
    1.73 +            else if (sk_weak)
    1.74 +                *comm_type = PEP_ct_OpenPGP_weak_unconfirmed;
    1.75 +            else {
    1.76 +                assert(NULL);
    1.77 +                *comm_type = PEP_ct_key_not_found;
    1.78              }
    1.79 +            status = PEP_KEY_UNSUITABLE;
    1.80 +        } else {
    1.81 +            /* a tinkered key is not reliable */
    1.82 +            if (sk_disabled || sk_invalid || sk_expired || sk_revoked || sk_too_short || sk_weak)
    1.83 +                *comm_type = PEP_ct_OpenPGP_weak_unconfirmed;  // keep comm on no-color
    1.84          }
    1.85          break;
    1.86      case GPG_ERR_ENOMEM: