ENGINE-174: fixed several bugs making it impossible for rating to be calculated correctly if there was more than one identity to consider ENGINE-174
authorKrista Grothoff <krista@pep-project.org>
Mon, 13 Feb 2017 22:10:13 +0100
branchENGINE-174
changeset 1579267b874fc39f
parent 1578 a676a68136e3
child 1580 b2b599902703
child 1583 b557eb33191f
ENGINE-174: fixed several bugs making it impossible for rating to be calculated correctly if there was more than one identity to consider
src/message_api.c
src/pgp_gpg.c
     1.1 --- a/src/message_api.c	Mon Feb 13 10:43:56 2017 +0100
     1.2 +++ b/src/message_api.c	Mon Feb 13 22:10:13 2017 +0100
     1.3 @@ -804,6 +804,10 @@
     1.4      return _rating(comm_type, PEP_rating_undefined);
     1.5  }
     1.6  
     1.7 +static PEP_rating worst_rating(PEP_rating rating1, PEP_rating rating2) {
     1.8 +    return ((rating1 < rating2) ? rating1 : rating2);
     1.9 +}
    1.10 +
    1.11  static PEP_rating keylist_rating(PEP_SESSION session, stringlist_t *keylist)
    1.12  {
    1.13      PEP_rating rating = PEP_rating_reliable;
    1.14 @@ -818,11 +822,12 @@
    1.15          PEP_STATUS status;
    1.16  
    1.17          PEP_rating _rating_ = key_rating(session, _kl->value);
    1.18 +         
    1.19          if (_rating_ <= PEP_rating_mistrust)
    1.20              return _rating_;
    1.21  
    1.22          if (rating == PEP_rating_undefined)
    1.23 -            rating = _rating_;
    1.24 +            rating = worst_rating(rating, _rating_);
    1.25  
    1.26          if (_rating_ >= PEP_rating_reliable) {
    1.27              status = least_trust(session, _kl->value, &ct);
    1.28 @@ -830,16 +835,16 @@
    1.29                  return PEP_rating_undefined;
    1.30              if (ct == PEP_ct_unknown){
    1.31                  if (rating >= PEP_rating_reliable){
    1.32 -                    rating = PEP_rating_reliable;
    1.33 +                    rating = worst_rating(rating, PEP_rating_reliable);
    1.34                  }
    1.35              }
    1.36              else{
    1.37 -                rating = _rating(ct, rating);
    1.38 +                rating = worst_rating(rating, _rating(ct, rating));
    1.39              }
    1.40          }
    1.41          else if (_rating_ == PEP_rating_unencrypted) {
    1.42              if (rating > PEP_rating_unencrypted_for_some)
    1.43 -                rating = PEP_rating_unencrypted_for_some;
    1.44 +                rating = worst_rating(rating, PEP_rating_unencrypted_for_some);
    1.45          }
    1.46      }
    1.47  
     2.1 --- a/src/pgp_gpg.c	Mon Feb 13 10:43:56 2017 +0100
     2.2 +++ b/src/pgp_gpg.c	Mon Feb 13 22:10:13 2017 +0100
     2.3 @@ -396,6 +396,7 @@
     2.4      gpgme_error_t gpgme_error;
     2.5      gpgme_data_t cipher, plain;
     2.6      gpgme_data_type_t dt;
     2.7 +    gpgme_decrypt_result_t gpgme_decrypt_result = NULL;
     2.8  
     2.9      stringlist_t *_keylist = NULL;
    2.10      //int i_key = 0;
    2.11 @@ -432,6 +433,7 @@
    2.12              return PEP_UNKNOWN_ERROR;
    2.13      }
    2.14  
    2.15 +
    2.16      dt = gpg.gpgme_data_identify(cipher);
    2.17      switch (dt) {
    2.18  #if GPGME_VERSION_NUMBER > 0x010600
    2.19 @@ -453,6 +455,8 @@
    2.20          switch (gpgme_error) {
    2.21              case GPG_ERR_NO_ERROR:
    2.22              {
    2.23 +                gpgme_decrypt_result = gpg.gpgme_op_decrypt_result(session->ctx);
    2.24 +                
    2.25                  gpgme_verify_result_t gpgme_verify_result;
    2.26                  char *_buffer = NULL;
    2.27                  size_t reading;
    2.28 @@ -489,16 +493,6 @@
    2.29                      gpg.gpgme_op_verify_result(session->ctx);
    2.30                  assert(gpgme_verify_result);
    2.31                  gpgme_signature = gpgme_verify_result->signatures;
    2.32 -/*
    2.33 -                if (!gpgme_signature) {
    2.34 -                    // try cleartext sig verification
    2.35 -                    gpg.gpgme_op_verify(session->ctx, plain, NULL, plain);
    2.36 -                    gpgme_verify_result =
    2.37 -                        gpg.gpgme_op_verify_result(session->ctx);
    2.38 -                    assert(gpgme_verify_result);
    2.39 -                    gpgme_signature = gpgme_verify_result->signatures;                    
    2.40 -                }
    2.41 -*/
    2.42  
    2.43                  if (gpgme_signature) {
    2.44                      stringlist_t *k;
    2.45 @@ -611,7 +605,7 @@
    2.46              case GPG_ERR_DECRYPT_FAILED:
    2.47              default:
    2.48              {
    2.49 -                gpgme_decrypt_result_t gpgme_decrypt_result = gpg.gpgme_op_decrypt_result(session->ctx);
    2.50 +                gpgme_decrypt_result = gpg.gpgme_op_decrypt_result(session->ctx);
    2.51                  result = PEP_DECRYPT_NO_KEY;
    2.52  
    2.53                  if (gpgme_decrypt_result != NULL) {
    2.54 @@ -624,19 +618,6 @@
    2.55                          result = PEP_OUT_OF_MEMORY;
    2.56                          break;
    2.57                      }
    2.58 -                    stringlist_t *_keylist = *keylist;
    2.59 -                    for (gpgme_recipient_t r = gpgme_decrypt_result->recipients; r != NULL; r = r->next) {
    2.60 -                        _keylist = stringlist_add(_keylist, r->keyid);
    2.61 -                        assert(_keylist);
    2.62 -                        if (_keylist == NULL) {
    2.63 -                            free_stringlist(*keylist);
    2.64 -                            *keylist = NULL;
    2.65 -                            result = PEP_OUT_OF_MEMORY;
    2.66 -                            break;
    2.67 -                        }
    2.68 -                    }
    2.69 -                    if (result == PEP_OUT_OF_MEMORY)
    2.70 -                        break;
    2.71                  }
    2.72              }
    2.73          }
    2.74 @@ -646,6 +627,45 @@
    2.75          result = PEP_DECRYPT_WRONG_FORMAT;
    2.76      }
    2.77  
    2.78 +    if (result != PEP_DECRYPT_WRONG_FORMAT && result != PEP_OUT_OF_MEMORY) {
    2.79 +        gpgme_key_t key;
    2.80 +        memset(&key,0,sizeof(key));
    2.81 +        
    2.82 +        if (gpgme_decrypt_result != NULL) {
    2.83 +            if (!(*keylist))
    2.84 +                *keylist = new_stringlist(""); // no sig
    2.85 +            stringlist_t* _keylist = *keylist;
    2.86 +            for (gpgme_recipient_t r = gpgme_decrypt_result->recipients; r != NULL; r = r->next) {
    2.87 +                // GPGME may give subkey's fpr instead of primary key's fpr.
    2.88 +                // Therefore we ask for the primary fingerprint instead
    2.89 +                // we assume that gpgme_get_key can find key by subkey's fpr
    2.90 +                gpgme_error = gpg.gpgme_get_key(session->ctx,
    2.91 +                    r->keyid, &key, 0);
    2.92 +                gpgme_error = _GPGERR(gpgme_error);
    2.93 +                assert(gpgme_error != GPG_ERR_ENOMEM);
    2.94 +                if (gpgme_error == GPG_ERR_ENOMEM) {
    2.95 +                    free_stringlist(_keylist);
    2.96 +                    result = PEP_OUT_OF_MEMORY;
    2.97 +                }
    2.98 +                // Primary key is given as the first subkey
    2.99 +                if (gpgme_error == GPG_ERR_NO_ERROR &&
   2.100 +                    key && key->subkeys && key->subkeys->fpr
   2.101 +                    && key->subkeys->fpr[0]) {
   2.102 +                    _keylist = stringlist_add(_keylist, key->subkeys->fpr);
   2.103 +
   2.104 +                    gpg.gpgme_key_unref(key);
   2.105 +
   2.106 +                }
   2.107 +            }
   2.108 +            assert(_keylist);
   2.109 +            if (_keylist == NULL) {
   2.110 +                free_stringlist(*keylist);
   2.111 +                *keylist = NULL;
   2.112 +                result = PEP_OUT_OF_MEMORY;
   2.113 +            }
   2.114 +        }
   2.115 +    }
   2.116 +
   2.117      gpg.gpgme_data_release(plain);
   2.118      gpg.gpgme_data_release(cipher);
   2.119      return result;