ENGINE-84: merged into default
authorKrista Grothoff <krista@pep-project.org>
Fri, 11 Nov 2016 14:15:15 +0100
changeset 13797c35b268a922
parent 1376 0404bdfa9beb
parent 1378 b2b2c6d361c9
child 1381 f84211f27e5b
ENGINE-84: merged into default
     1.1 --- a/src/cryptotech.c	Fri Nov 11 12:03:31 2016 +0100
     1.2 +++ b/src/cryptotech.c	Fri Nov 11 14:15:15 2016 +0100
     1.3 @@ -47,6 +47,8 @@
     1.4          cryptotech[PEP_crypt_OpenPGP].key_expired = pgp_key_expired;
     1.5          cryptotech[PEP_crypt_OpenPGP].key_revoked = pgp_key_revoked;
     1.6          cryptotech[PEP_crypt_OpenPGP].key_created = pgp_key_created;
     1.7 +        cryptotech[PEP_crypt_OpenPGP].contains_priv_key = pgp_contains_priv_key;
     1.8 +        cryptotech[PEP_crypt_OpenPGP].find_private_keys = pgp_find_private_keys;
     1.9  #ifdef PGP_BINARY_PATH
    1.10          cryptotech[PEP_crypt_OpenPGP].binary_path = PGP_BINARY_PATH;
    1.11  #endif
     2.1 --- a/src/cryptotech.h	Fri Nov 11 12:03:31 2016 +0100
     2.2 +++ b/src/cryptotech.h	Fri Nov 11 14:15:15 2016 +0100
     2.3 @@ -72,6 +72,13 @@
     2.4  
     2.5  typedef PEP_STATUS (*binary_path_t)(const char **path);
     2.6  
     2.7 +typedef PEP_STATUS (*contains_priv_key_t)(PEP_SESSION session, const char *fpr,
     2.8 +        bool *has_private);
     2.9 +
    2.10 +typedef PEP_STATUS (*find_private_keys_t)(
    2.11 +    PEP_SESSION session, const char *pattern, stringlist_t **keylist
    2.12 +);
    2.13 +
    2.14  typedef struct _PEP_cryptotech_t {
    2.15      uint8_t id;
    2.16      // the following are default values; comm_type may vary with key length or b0rken crypto
    2.17 @@ -94,6 +101,8 @@
    2.18      key_revoked_t key_revoked;
    2.19      key_created_t key_created;
    2.20      binary_path_t binary_path;
    2.21 +    contains_priv_key_t contains_priv_key;
    2.22 +    find_private_keys_t find_private_keys;
    2.23  } PEP_cryptotech_t;
    2.24  
    2.25  extern PEP_cryptotech_t cryptotech[PEP_crypt__count];
     3.1 --- a/src/keymanagement.c	Fri Nov 11 12:03:31 2016 +0100
     3.2 +++ b/src/keymanagement.c	Fri Nov 11 14:15:15 2016 +0100
     3.3 @@ -325,7 +325,7 @@
     3.4      free(identity->fpr);
     3.5      identity->fpr = NULL;
     3.6  
     3.7 -    status = find_keys(session, identity->address, &keylist);
     3.8 +    status = find_private_keys(session, identity->address, &keylist);
     3.9      assert(status != PEP_OUT_OF_MEMORY);
    3.10      if (status == PEP_OUT_OF_MEMORY)
    3.11          return PEP_OUT_OF_MEMORY;
    3.12 @@ -390,6 +390,26 @@
    3.13      return PEP_STATUS_OK;
    3.14  }
    3.15  
    3.16 +PEP_STATUS _has_usable_priv_key(PEP_SESSION session, char* fpr,
    3.17 +                                bool* is_usable) {
    3.18 +    
    3.19 +    bool dont_use_fpr = true;
    3.20 +    
    3.21 +    PEP_STATUS status = blacklist_is_listed(session, fpr, &dont_use_fpr);
    3.22 +    if (status == PEP_STATUS_OK && !dont_use_fpr) {
    3.23 +        // Make sure there is a *private* key associated with this fpr
    3.24 +        bool has_private = false;
    3.25 +        status = contains_priv_key(session, fpr, &has_private);
    3.26 +
    3.27 +        if (status == PEP_STATUS_OK)
    3.28 +            dont_use_fpr = !has_private;
    3.29 +    }
    3.30 +    
    3.31 +    *is_usable = !dont_use_fpr;
    3.32 +    
    3.33 +    return status;
    3.34 +}
    3.35 +
    3.36  DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
    3.37  {
    3.38      pEp_identity *stored_identity;
    3.39 @@ -429,30 +449,55 @@
    3.40      assert(status != PEP_OUT_OF_MEMORY);
    3.41      if (status == PEP_OUT_OF_MEMORY)
    3.42          return PEP_OUT_OF_MEMORY;
    3.43 -    
    3.44 +
    3.45 +    bool dont_use_stored_fpr = true;
    3.46 +    bool dont_use_input_fpr = true;
    3.47 +        
    3.48      if (stored_identity)
    3.49      {
    3.50          if (EMPTYSTR(identity->fpr)) {
    3.51 -            identity->fpr = strdup(stored_identity->fpr);
    3.52 -            assert(identity->fpr);
    3.53 -            if (identity->fpr == NULL)
    3.54 -            {
    3.55 -                return PEP_OUT_OF_MEMORY;
    3.56 +            
    3.57 +            bool has_private = false;
    3.58 +            
    3.59 +            status = _has_usable_priv_key(session, stored_identity->fpr, &has_private); 
    3.60 +            
    3.61 +            // N.B. has_private is never true if the returned status is not PEP_STATUS_OK
    3.62 +            if (has_private) {
    3.63 +                identity->fpr = strdup(stored_identity->fpr);
    3.64 +                assert(identity->fpr);
    3.65 +                if (identity->fpr == NULL)
    3.66 +                {
    3.67 +                    return PEP_OUT_OF_MEMORY;
    3.68 +                }
    3.69 +                dont_use_stored_fpr = false;
    3.70              }
    3.71          }
    3.72 -
    3.73 +        
    3.74          identity->flags = stored_identity->flags;
    3.75      }
    3.76 -    else if (!EMPTYSTR(identity->fpr))
    3.77 +    
    3.78 +    if (dont_use_stored_fpr && !EMPTYSTR(identity->fpr))
    3.79      {
    3.80          // App must have a good reason to give fpr, such as explicit
    3.81          // import of private key, or similar.
    3.82  
    3.83          // Take given fpr as-is.
    3.84  
    3.85 -        identity->flags = 0;
    3.86 +        // BUT:
    3.87 +        // First check to see if it's blacklisted or private part is missing?
    3.88 +        bool has_private = false;
    3.89 +        
    3.90 +        status = _has_usable_priv_key(session, identity->fpr, &has_private); 
    3.91 +        
    3.92 +        // N.B. has_private is never true if the returned status is not PEP_STATUS_OK
    3.93 +        if (has_private) {
    3.94 +            identity->flags = 0;
    3.95 +            dont_use_input_fpr = false;
    3.96 +        }
    3.97      }
    3.98 -    else
    3.99 +    
   3.100 +    // Ok, we failed to get keys either way, so let's elect one.
   3.101 +    if (dont_use_input_fpr && dont_use_stored_fpr)
   3.102      {
   3.103          status = elect_ownkey(session, identity);
   3.104          assert(status == PEP_STATUS_OK);
   3.105 @@ -460,7 +505,26 @@
   3.106              return status;
   3.107          }
   3.108  
   3.109 -        identity->flags = 0;
   3.110 +        bool has_private = false;
   3.111 +        if (identity->fpr) {
   3.112 +            // ok, we elected something.
   3.113 +            // elect_ownkey only returns private keys, so we don't check again.
   3.114 +            // Check to see if it's blacklisted
   3.115 +            bool listed;
   3.116 +            status = blacklist_is_listed(session, identity->fpr, &listed); 
   3.117 +
   3.118 +            if (status == PEP_STATUS_OK)
   3.119 +                has_private = !listed;
   3.120 +        }
   3.121 +        
   3.122 +        if (has_private) {
   3.123 +            identity->flags = 0;
   3.124 +            dont_use_input_fpr = false;
   3.125 +        }
   3.126 +        else { // OK, we've tried everything. Time to generate new keys.
   3.127 +            free(identity->fpr); // It can stay in this state (unallocated) because we'll generate a new key 
   3.128 +            identity->fpr = NULL;
   3.129 +        }
   3.130      }
   3.131  
   3.132      bool revoked = false;
   3.133 @@ -848,3 +912,16 @@
   3.134      return status;
   3.135  }
   3.136  
   3.137 +
   3.138 +PEP_STATUS contains_priv_key(PEP_SESSION session, const char *fpr,
   3.139 +                             bool *has_private) {
   3.140 +
   3.141 +    assert(session);
   3.142 +    assert(fpr);
   3.143 +    assert(has_private);
   3.144 +    
   3.145 +    if (!(session && fpr && has_private))
   3.146 +        return PEP_ILLEGAL_VALUE;
   3.147 +
   3.148 +    return session->cryptotech[PEP_crypt_OpenPGP].contains_priv_key(session, fpr, has_private);
   3.149 +}
   3.150 \ No newline at end of file
     4.1 --- a/src/keymanagement.h	Fri Nov 11 12:03:31 2016 +0100
     4.2 +++ b/src/keymanagement.h	Fri Nov 11 14:15:15 2016 +0100
     4.3 @@ -189,6 +189,9 @@
     4.4          identity_list **own_identities
     4.5      );
     4.6  
     4.7 +PEP_STATUS contains_priv_key(PEP_SESSION session, const char *fpr,
     4.8 +                             bool *has_private);
     4.9 +
    4.10  #ifdef __cplusplus
    4.11  }
    4.12  #endif
     5.1 --- a/src/pEpEngine.c	Fri Nov 11 12:03:31 2016 +0100
     5.2 +++ b/src/pEpEngine.c	Fri Nov 11 14:15:15 2016 +0100
     5.3 @@ -2107,6 +2107,16 @@
     5.4              created);
     5.5  }
     5.6  
     5.7 +PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
     5.8 +                             stringlist_t **keylist) {
     5.9 +    assert(session && pattern && keylist);
    5.10 +    if (!(session && pattern && keylist))
    5.11 +        return PEP_ILLEGAL_VALUE;
    5.12 +    
    5.13 +    return session->cryptotech[PEP_crypt_OpenPGP].find_private_keys(session, pattern,
    5.14 +                                                                    keylist);
    5.15 +}
    5.16 +
    5.17  DYNAMIC_API const char* get_engine_version() {
    5.18      return PEP_ENGINE_VERSION;
    5.19  }
     6.1 --- a/src/pEpEngine.h	Fri Nov 11 12:03:31 2016 +0100
     6.2 +++ b/src/pEpEngine.h	Fri Nov 11 14:15:15 2016 +0100
     6.3 @@ -999,6 +999,20 @@
     6.4      );
     6.5  
     6.6  
     6.7 +// find_private_keys() - find keys in keyring
     6.8 +//
     6.9 +//  parameters:
    6.10 +//      session (in)            session handle
    6.11 +//      pattern (in)            key id, user id or address to search for as
    6.12 +//                              UTF-8 string
    6.13 +//      keylist (out)           list of fingerprints found or NULL on error
    6.14 +//
    6.15 +//  caveat:
    6.16 +//        the ownerships of keylist isgoing to the caller
    6.17 +//        the caller must use free_stringlist() to free it
    6.18 +PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
    6.19 +                             stringlist_t **keylist);
    6.20 +
    6.21  // get_engine_version() - returns the current version of pEpEngine (this is different
    6.22  //                        from the pEp protocol version!)
    6.23  //
     7.1 --- a/src/pgp_gpg.c	Fri Nov 11 12:03:31 2016 +0100
     7.2 +++ b/src/pgp_gpg.c	Fri Nov 11 14:15:15 2016 +0100
     7.3 @@ -1411,61 +1411,61 @@
     7.4      return PEP_STATUS_OK;
     7.5  }
     7.6  
     7.7 -PEP_STATUS pgp_find_keys(
     7.8 -    PEP_SESSION session, const char *pattern, stringlist_t **keylist
     7.9 -    )
    7.10 -{
    7.11 +
    7.12 +static PEP_STATUS _pgp_search_keys(PEP_SESSION session, const char* pattern,
    7.13 +                            stringlist_t** keylist,
    7.14 +                            int private_only) {
    7.15      gpgme_error_t gpgme_error;
    7.16      gpgme_key_t key;
    7.17 -
    7.18 +    
    7.19      assert(session);
    7.20      assert(pattern);
    7.21      assert(keylist);
    7.22 -
    7.23 +    
    7.24      *keylist = NULL;
    7.25 -
    7.26 -    gpgme_error = gpg.gpgme_op_keylist_start(session->ctx, pattern, 0);
    7.27 +    
    7.28 +    gpgme_error = gpg.gpgme_op_keylist_start(session->ctx, pattern, private_only);
    7.29      gpgme_error = _GPGERR(gpgme_error);
    7.30      switch (gpgme_error) {
    7.31 -    case GPG_ERR_NO_ERROR:
    7.32 -        break;
    7.33 -    case GPG_ERR_INV_VALUE:
    7.34 -        assert(0);
    7.35 -        return PEP_UNKNOWN_ERROR;
    7.36 -    default:
    7.37 -        gpg.gpgme_op_keylist_end(session->ctx);
    7.38 -        return PEP_GET_KEY_FAILED;
    7.39 +        case GPG_ERR_NO_ERROR:
    7.40 +            break;
    7.41 +        case GPG_ERR_INV_VALUE:
    7.42 +            assert(0);
    7.43 +            return PEP_UNKNOWN_ERROR;
    7.44 +        default:
    7.45 +            gpg.gpgme_op_keylist_end(session->ctx);
    7.46 +            return PEP_GET_KEY_FAILED;
    7.47      };
    7.48 -
    7.49 +    
    7.50      stringlist_t *_keylist = new_stringlist(NULL);
    7.51      stringlist_t *_k = _keylist;
    7.52 -
    7.53 +    
    7.54      do {
    7.55          gpgme_error = gpg.gpgme_op_keylist_next(session->ctx, &key);
    7.56          gpgme_error = _GPGERR(gpgme_error);
    7.57          assert(gpgme_error != GPG_ERR_INV_VALUE);
    7.58          switch (gpgme_error) {
    7.59 -        case GPG_ERR_EOF:
    7.60 -            break;
    7.61 -        case GPG_ERR_NO_ERROR:
    7.62 -            assert(key);
    7.63 -            assert(key->subkeys);
    7.64 -            char *fpr = key->subkeys->fpr;
    7.65 -            assert(fpr);
    7.66 -            _k = stringlist_add(_k, fpr);
    7.67 -            assert(_k);
    7.68 -            if (_k != NULL)
    7.69 +            case GPG_ERR_EOF:
    7.70                  break;
    7.71 -        case GPG_ERR_ENOMEM:
    7.72 -            free_stringlist(_keylist);
    7.73 -            gpg.gpgme_op_keylist_end(session->ctx);
    7.74 -            return PEP_OUT_OF_MEMORY;
    7.75 -        default:
    7.76 -            gpg.gpgme_op_keylist_end(session->ctx);
    7.77 -            return PEP_UNKNOWN_ERROR;
    7.78 +            case GPG_ERR_NO_ERROR:
    7.79 +                assert(key);
    7.80 +                assert(key->subkeys);
    7.81 +                char *fpr = key->subkeys->fpr;
    7.82 +                assert(fpr);
    7.83 +                _k = stringlist_add(_k, fpr);
    7.84 +                assert(_k);
    7.85 +                if (_k != NULL)
    7.86 +                    break;
    7.87 +            case GPG_ERR_ENOMEM:
    7.88 +                free_stringlist(_keylist);
    7.89 +                gpg.gpgme_op_keylist_end(session->ctx);
    7.90 +                return PEP_OUT_OF_MEMORY;
    7.91 +            default:
    7.92 +                gpg.gpgme_op_keylist_end(session->ctx);
    7.93 +                return PEP_UNKNOWN_ERROR;
    7.94          };
    7.95      } while (gpgme_error != GPG_ERR_EOF);
    7.96 -
    7.97 +    
    7.98      gpg.gpgme_op_keylist_end(session->ctx);
    7.99      if (_keylist->value == NULL) {
   7.100          free_stringlist(_keylist);
   7.101 @@ -1475,6 +1475,20 @@
   7.102      return PEP_STATUS_OK;
   7.103  }
   7.104  
   7.105 +PEP_STATUS pgp_find_keys(
   7.106 +    PEP_SESSION session, const char *pattern, stringlist_t **keylist
   7.107 +    )
   7.108 +{
   7.109 +    return _pgp_search_keys(session, pattern, keylist, 0);
   7.110 +}    
   7.111 +
   7.112 +PEP_STATUS pgp_find_private_keys(
   7.113 +    PEP_SESSION session, const char *pattern, stringlist_t **keylist
   7.114 +)
   7.115 +{
   7.116 +    return _pgp_search_keys(session, pattern, keylist, 1);
   7.117 +}
   7.118 +
   7.119  PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
   7.120  {
   7.121      gpgme_error_t gpgme_error;
   7.122 @@ -2118,3 +2132,30 @@
   7.123      return PEP_STATUS_OK;
   7.124  }
   7.125  
   7.126 +PEP_STATUS pgp_contains_priv_key(PEP_SESSION session, const char *fpr,
   7.127 +        bool *has_private) {
   7.128 +    PEP_STATUS status = PEP_STATUS_OK;
   7.129 +    gpgme_key_t output_key;
   7.130 +    gpgme_error_t gpgerr = gpg.gpgme_get_key(session->ctx, fpr, &output_key, true);
   7.131 +    *has_private = false;
   7.132 +    switch (gpgerr) {
   7.133 +        case GPG_ERR_EOF:
   7.134 +        case GPG_ERR_INV_VALUE:
   7.135 +            status = PEP_KEY_NOT_FOUND;
   7.136 +            break;
   7.137 +        case GPG_ERR_AMBIGUOUS_NAME:
   7.138 +            status = PEP_KEY_HAS_AMBIG_NAME;
   7.139 +            break;
   7.140 +        case GPG_ERR_NO_ERROR:
   7.141 +            *has_private = true;
   7.142 +            gpgme_key_release(output_key);
   7.143 +            break;
   7.144 +        case GPG_ERR_ENOMEM:
   7.145 +            status = PEP_OUT_OF_MEMORY;
   7.146 +            break;
   7.147 +        default:
   7.148 +            status = PEP_UNKNOWN_ERROR;
   7.149 +            break;
   7.150 +    }
   7.151 +    return status;
   7.152 +}
   7.153 \ No newline at end of file
     8.1 --- a/src/pgp_gpg.h	Fri Nov 11 12:03:31 2016 +0100
     8.2 +++ b/src/pgp_gpg.h	Fri Nov 11 14:15:15 2016 +0100
     8.3 @@ -85,6 +85,15 @@
     8.4          time_t *created
     8.5      );
     8.6  
     8.7 +PEP_STATUS pgp_contains_priv_key(
     8.8 +        PEP_SESSION session, 
     8.9 +        const char *fpr,
    8.10 +        bool *has_private);
    8.11 +
    8.12 +PEP_STATUS pgp_find_private_keys(
    8.13 +    PEP_SESSION session, const char *pattern, stringlist_t **keylist
    8.14 +);
    8.15 +
    8.16  PEP_STATUS pgp_binary(const char **path);
    8.17  #define PGP_BINARY_PATH pgp_binary
    8.18  
     9.1 --- a/src/pgp_netpgp.c	Fri Nov 11 12:03:31 2016 +0100
     9.2 +++ b/src/pgp_netpgp.c	Fri Nov 11 14:15:15 2016 +0100
     9.3 @@ -1178,6 +1178,29 @@
     9.4      return PEP_STATUS_OK;
     9.5  }
     9.6  
     9.7 +static PEP_STATUS add_secret_key_fpr_to_stringlist(void *arg, pgp_key_t *key)
     9.8 +{
     9.9 +    if (pgp_is_key_secret(key)) {
    9.10 +        stringlist_t **keylist = arg;
    9.11 +        char *newfprstr = NULL;
    9.12 +        
    9.13 +        fpr_to_str(&newfprstr,
    9.14 +                key->pubkeyfpr.fingerprint,
    9.15 +                key->pubkeyfpr.length);
    9.16 +        
    9.17 +        if (newfprstr == NULL) {
    9.18 +            return PEP_OUT_OF_MEMORY;
    9.19 +        } else { 
    9.20 +            stringlist_add(*keylist, newfprstr);
    9.21 +            free(newfprstr);
    9.22 +            if (*keylist == NULL) {
    9.23 +                return PEP_OUT_OF_MEMORY;
    9.24 +            }
    9.25 +        }
    9.26 +    }
    9.27 +    return PEP_STATUS_OK;
    9.28 +}
    9.29 +
    9.30  static PEP_STATUS add_keyinfo_to_stringpair_list(void* arg, pgp_key_t *key) {
    9.31      stringpair_list_t** keyinfo_list = (stringpair_list_t**)arg;
    9.32      stringpair_t* pair = NULL;
    9.33 @@ -1754,3 +1777,66 @@
    9.34      
    9.35      return result;
    9.36  }
    9.37 +
    9.38 +/* copied from find_keys, but we need to use a callback that filters. */
    9.39 +PEP_STATUS pgp_find_private_keys(
    9.40 +    PEP_SESSION session, const char *pattern, stringlist_t **keylist)
    9.41 +{
    9.42 +    stringlist_t *_keylist, *_k;
    9.43 +    
    9.44 +    PEP_STATUS result;
    9.45 +    
    9.46 +    assert(session);
    9.47 +    assert(pattern);
    9.48 +    assert(keylist);
    9.49 +    
    9.50 +    if (!session || !pattern || !keylist )
    9.51 +    {
    9.52 +        return PEP_ILLEGAL_VALUE;
    9.53 +    }
    9.54 +    
    9.55 +    if (pthread_mutex_lock(&netpgp_mutex))
    9.56 +    {
    9.57 +        return PEP_UNKNOWN_ERROR;
    9.58 +    }
    9.59 +    
    9.60 +    *keylist = NULL;
    9.61 +    _keylist = new_stringlist(NULL);
    9.62 +    if (_keylist == NULL) {
    9.63 +        result = PEP_OUT_OF_MEMORY;
    9.64 +        goto unlock_netpgp;
    9.65 +    }
    9.66 +    _k = _keylist;
    9.67 +    
    9.68 +    result = find_keys_do(pattern, &add_secret_key_fpr_to_stringlist, &_k);
    9.69 +    
    9.70 +    if (result == PEP_STATUS_OK) {
    9.71 +        *keylist = _keylist;
    9.72 +        // Transfer ownership, no free
    9.73 +        goto unlock_netpgp;
    9.74 +    }
    9.75 +    
    9.76 +free_keylist:
    9.77 +    free_stringlist(_keylist);
    9.78 +    
    9.79 +unlock_netpgp:
    9.80 +    pthread_mutex_unlock(&netpgp_mutex);
    9.81 +    
    9.82 +    return result;    
    9.83 +}
    9.84 +
    9.85 +PEP_STATUS pgp_contains_priv_key(
    9.86 +    PEP_SESSION session, 
    9.87 +    const char *fpr,
    9.88 +    bool *has_private) {
    9.89 +    stringlist_t* keylist = NULL;
    9.90 +    PEP_STATUS status = pgp_find_private_keys(session, fpr, &keylist);
    9.91 +    if (status == PEP_STATUS_OK && keylist) {
    9.92 +        free_stringlist(keylist);
    9.93 +        *has_private = true;
    9.94 +    }
    9.95 +    else {
    9.96 +        has_private = false;
    9.97 +    }
    9.98 +    return status;
    9.99 +}
    10.1 --- a/src/pgp_netpgp.h	Fri Nov 11 12:03:31 2016 +0100
    10.2 +++ b/src/pgp_netpgp.h	Fri Nov 11 14:15:15 2016 +0100
    10.3 @@ -81,3 +81,12 @@
    10.4          time_t *created
    10.5      );
    10.6  
    10.7 +PEP_STATUS pgp_contains_priv_key(
    10.8 +    PEP_SESSION session, 
    10.9 +    const char *fpr,
   10.10 +    bool *has_private);
   10.11 +
   10.12 +PEP_STATUS pgp_find_private_keys(
   10.13 +    PEP_SESSION session, const char *pattern, stringlist_t **keylist
   10.14 +);
   10.15 +
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/encrypt_missing_private_key_test.cc	Fri Nov 11 14:15:15 2016 +0100
    11.3 @@ -0,0 +1,121 @@
    11.4 +#include <iostream>
    11.5 +#include <iostream>
    11.6 +#include <fstream>
    11.7 +#include <string>
    11.8 +#include <cstring> // for strcmp()
    11.9 +#include <assert.h>
   11.10 +#include "blacklist.h"
   11.11 +#include "keymanagement.h"
   11.12 +#include "message_api.h"
   11.13 +#include "mime.h"
   11.14 +
   11.15 +using namespace std;
   11.16 +
   11.17 +int main() {
   11.18 +    cout << "\n*** encrypt_missing_private_key_test ***\n\n";
   11.19 +
   11.20 +    PEP_SESSION session;
   11.21 +    
   11.22 +    cout << "calling init()\n";
   11.23 +    PEP_STATUS status1 = init(&session);   
   11.24 +    assert(status1 == PEP_STATUS_OK);
   11.25 +    assert(session);
   11.26 +    cout << "init() completed.\n";
   11.27 +
   11.28 +    // blacklist test code
   11.29 +
   11.30 +    cout << "blacklist only key for identity / add key / check which key is used" << endl;
   11.31 +    
   11.32 +    // B252066DE0513BECA2954F30E8E18177B28D9B9D - this is the blacklisted key in blacklisted_self.asc
   11.33 +
   11.34 +    /* read the key into memory */
   11.35 +    ifstream infile("test_keys/priv/blacklist_self.asc");
   11.36 +    string keytext;
   11.37 +    while (!infile.eof()) {
   11.38 +        static string line;
   11.39 +        getline(infile, line);
   11.40 +        keytext += line + "\n";
   11.41 +    }
   11.42 +    infile.close(); 
   11.43 +    
   11.44 +    /* import it into pep */
   11.45 +    PEP_STATUS status7 = import_key(session, keytext.c_str(), keytext.length(), NULL);
   11.46 +    
   11.47 +    const char* bl_fpr_1 = "B252066DE0513BECA2954F30E8E18177B28D9B9D";
   11.48 +    bool is_blacklisted = false;
   11.49 +    
   11.50 +    pEp_identity* blacklisted_identity = new_identity("blacklistself@kgrothoff.org",
   11.51 +                                                      bl_fpr_1,
   11.52 +                                                      PEP_OWN_USERID,
   11.53 +                                                      "Blacklist Self");
   11.54 +    blacklisted_identity->me = true;
   11.55 +    PEP_STATUS status8 = update_identity(session, blacklisted_identity);
   11.56 +    PEP_STATUS status9 = blacklist_add(session, bl_fpr_1);
   11.57 +    PEP_STATUS status10 = blacklist_is_listed(session, bl_fpr_1, &is_blacklisted);
   11.58 +    PEP_STATUS status11 = update_identity(session, blacklisted_identity);
   11.59 +
   11.60 +    /* identity is blacklisted. Now let's try to encrypt a message. */
   11.61 +    
   11.62 +    const char* new_key = NULL;    
   11.63 +    
   11.64 +    ifstream infile2("test_mails/blacklist_no_key.eml");
   11.65 +    string mailtext;
   11.66 +    while (!infile2.eof()) {
   11.67 +        static string line;
   11.68 +        getline(infile2, line);
   11.69 +        mailtext += line + "\n";
   11.70 +    }     infile2.close(); 
   11.71 +
   11.72 +    
   11.73 +    message* tmp_msg = NULL;
   11.74 +    message* enc_msg = NULL;
   11.75 +    
   11.76 +    PEP_STATUS status = mime_decode_message(mailtext.c_str(), mailtext.length(), &tmp_msg);
   11.77 +    assert(status == PEP_STATUS_OK);
   11.78 +    
   11.79 +    
   11.80 +    
   11.81 +    // This isn't incoming, though... so we need to reverse the direction
   11.82 +    tmp_msg->dir = PEP_dir_outgoing;
   11.83 +    status = encrypt_message(session,
   11.84 +                             tmp_msg,
   11.85 +                             NULL,
   11.86 +                             &enc_msg,
   11.87 +                             PEP_enc_PGP_MIME,
   11.88 +                             0);
   11.89 +    assert(status == PEP_STATUS_OK);
   11.90 +    
   11.91 +    
   11.92 +//    PEP_STATUS status69 = MIME_encrypt_message(session, mailtext.c_str(), mailtext.length(), NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   11.93 +//    pEp_identity * me1 = new_identity("blacklist_test@kgrothoff.org", NULL, PEP_OWN_USERID, "Blacklisted Key Message Recipient");    
   11.94 +
   11.95 +    new_key = enc_msg->from->fpr;
   11.96 +    cout << "Encrypted with key " << new_key << endl;
   11.97 +    assert (strcasecmp(new_key, bl_fpr_1) != 0);
   11.98 +//     PEP_STATUS status = update_identity(session, me1);
   11.99 +//     message* msg_ptr = nullptr;
  11.100 +//     message* dest_msg = nullptr;
  11.101 +//     stringlist_t* keylist = nullptr;
  11.102 +//     PEP_rating rating;
  11.103 +//     PEP_decrypt_flags_t flags;
  11.104 +//     
  11.105 +//     status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
  11.106 +//     assert(status == PEP_STATUS_OK);
  11.107 +//     status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
  11.108 +// 
  11.109 +//     PEP_STATUS status12 = update_identity(session, blacklisted_identity);
  11.110 +// 
  11.111 +//     assert(strcasecmp(blacklisted_identity->fpr, new_key) == 0);
  11.112 +    
  11.113 +    status = delete_keypair(session, new_key);
  11.114 +    PEP_STATUS status13 = blacklist_delete(session, bl_fpr_1);
  11.115 +    PEP_STATUS status14 = update_identity(session, blacklisted_identity);
  11.116 +
  11.117 +    free_message(tmp_msg);    
  11.118 +    free_message(enc_msg);
  11.119 +    
  11.120 +    cout << "calling release()\n";
  11.121 +    release(session);
  11.122 +    return 0;
  11.123 +}
  11.124 +
    12.1 --- a/test/message_api_test.cc	Fri Nov 11 12:03:31 2016 +0100
    12.2 +++ b/test/message_api_test.cc	Fri Nov 11 14:15:15 2016 +0100
    12.3 @@ -146,10 +146,13 @@
    12.4      inFile4.close();
    12.5      
    12.6      const char* out_msg_plain = text4.c_str();
    12.7 +    
    12.8 +//    const char* out_msg_plain = "From: krista@kgrothoff.org\nTo: Volker <vb@pep-project.org>\nSubject: Test\nContent-Type: text/plain; charset=utf-8\nContent-Language: en-US\nContent-Transfer-Encoding:quoted-printable\n\ngaga\n\n";
    12.9      char* enc_msg = NULL;
   12.10      char* dec_msg = NULL;
   12.11  
   12.12      PEP_STATUS status7 = MIME_encrypt_message(session, text4.c_str(), text4.length(), NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   12.13 +//    PEP_STATUS status7 = MIME_encrypt_message(session, out_msg_plain, strlen(out_msg_plain), NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   12.14      assert(status7 == PEP_STATUS_OK);
   12.15      
   12.16      cout << enc_msg << endl;
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/test/test_keys/priv/blacklist_self.asc	Fri Nov 11 14:15:15 2016 +0100
    13.3 @@ -0,0 +1,57 @@
    13.4 +-----BEGIN PGP PRIVATE KEY BLOCK-----
    13.5 +
    13.6 +lQOYBFgltZIBCADIlORdZvfrWGP/QL1rVYGfy1TeqrlvBPgb5h9ZMB0RCHAq6hMV
    13.7 +nyq2zBTNgrOVC41VKq6qd+3GffPqgc+Ja/2q2YQJ480j2E5vRue8rUSFWg6msMvQ
    13.8 +1Df23LNfRR7g1D7d0wGMsXaMm6PduXuAmj4z5/8BTHriDPAh8DqrdtKj1v5WBSaZ
    13.9 +5O1fJK2f6/1Opa2Kg1hmAupP6IK8AZtuPJ8JPqmYt0LNOfmQNFZpRIc1VpbcC62H
   13.10 +IYcCYW3SwJQr2O/v06fJGao4A914JbcwLeJpSXwbtMJClN3go9MUSf8JYuhIiUJ0
   13.11 +jgdP6WvopRnn1STWDv0Hq1jd8Lb+M5GBX24/ABEBAAEAB/oCciewveMzDae2gp8X
   13.12 +XSUQrPA9gN50V0lWlGv4cJ5CHr9jaT75/1q20kPvV53XU5s8bndPy9jsl+JED04t
   13.13 +ElHhu0z2uT4/UXwaCPF60FrADN+V3R0MewdYWCD100geR2hMLdkHKAOBO8VNRwhA
   13.14 +WAvUd9/uWko7UcYR2+CTRlvTifOSCHFqMLz22WIw0DyIU0dU+yjtCYI3Q0HKyZtB
   13.15 +VmNTFZxTkMtYKI1yvma0VsYNsOc6Dvs4gbU0kD0FiDPcCJz1NyA4Xj4VjsW//k0/
   13.16 +exVXkYvXWuzVzyOBAS5rURhNL7Tm8W/tZVRuEaZ8mzykvPszMckg706FUgqfcnSV
   13.17 +2nfVBADQlJujiB1rz9/g39YKB4kzOm9aELgpyGo+oEQgttVkHJLMdsnAliM7lDsy
   13.18 +ck60QsSnELku931qOPYW6NICs5GD23kexsv5HqK9FlTeXJjnvx+HRubaHyKIndJG
   13.19 +iWieQCXuH94t5TNy0FafVhsdKWuDPNAGfewNKILYc3aPQI399QQA9i6/l3mEuGpf
   13.20 +UkQxfrW9gHniXx4b2VJTlzh+8nxc0iF+Z6x8nq/H5+gN0Y/firk+hB74LXeV5X7o
   13.21 +B2JpjscyVhW3BodBACAZU5qNO48Vpl5H1GcBNLrdtGhYU7y9utEHxgDWlJY2RyuR
   13.22 +IE+SLrlM+y6vq528REzfqMhuTZfFhuMEAJRRY/RBLbmND094tT3IKKU/I1Uu5Tuv
   13.23 +6IC3pqoxeuJLxsRxqREPqoTtkwFpnAAbdOYFhNpC3m1bhTzbyavK68006+9DLRXT
   13.24 +kV/7DRm2PLcR9fJZqgWhQImktsQvWkcqYqLzwGT1bkG+QqpBq1ou1Hb2ufg44pCK
   13.25 +CxT3Yij2XsdFN0+0VUJsYWNrbGlzdCBTZWxmIChUZXN0IERvIE5vdCBVc2UgRm9y
   13.26 +IE90aGVyIFRlc3RzIFBsZWFzZSkgPGJsYWNrbGlzdHNlbGZAa2dyb3Rob2ZmLm9y
   13.27 +Zz6JATgEEwEIACIFAlgltZICGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJ
   13.28 +EOjhgXeyjZud5JEH/3p7258h32EmOvMdJZfl7S3W5g1OTGij6rs656eJu5lv/E6w
   13.29 +yre+MbqcBGHHJfjobrIx8qzyaq1lYBksnZcT+sAf++i5xG/LXF+MhmpaM8ZIiopv
   13.30 +KzRXSzEyCp/58oggIbz/DkT1DfI1CjTwQzOCyPdOXM1e0DcKTT8HAiRgm1tQaxw7
   13.31 +sOjdfatt37aOclJQatIE0eCBqk7Zn5Qt9KURmUCq6IkGf4XJ4bTEvbbtdizsy4ie
   13.32 +6uUt3m/csZqLmV9vXPJAPvgYAB7hd4jBOOdQGtWRzZ05Q59QWHjvlAoZaXmfH3ER
   13.33 +BEAixn6cP4Kl7wKtHMA8npCGMcdDd4o4q1KlhnidA5gEWCW1kgEIAMRJTlhJsyv3
   13.34 +8T3P/lgzLKplWF6/XkrLZ8B6aR6WphafUoSeknD2fvLa+0MyfGpThMdPDICTsjN5
   13.35 +yCnO5HqX/dtM2tGmnKNtJFpMup8a5aSe8/bcfWg7qZLzebexsw0DaNZjlrbjtI/6
   13.36 +nF/JfpPKTgXb1bHhu3Fn6/USeG2Y0F54V4Y9K5Sljz5pVFQGNGU+Wb5jBE7FSa9+
   13.37 +beo2ik3iL4W2AYadONSZTD2FnjNTrZ0oHGaD65kHnJ+yDLCMMkeZ16gCN89weQas
   13.38 +I+9on2E1afXCpi1fPUvnktijkxZ9xgGNRYDljxPqgXuXM3H0oWND4+v3ZB55h/jH
   13.39 +0OEdMW6IoJMAEQEAAQAH/AtobUkF44e6BKwb8Of/0NXRkHzC8K3tKS3hs/3m6IuL
   13.40 +VIZahvsILjPtS4C3qBZ5CyuXIMMaSUUHnkZSoXQbbgiuEQcWboLYw0Av/9z1Qk3x
   13.41 +YsYKHLChp6JyApBWVqhVv5u7WUwlaxUH++2mG/Rm0YtXMm1cR94dGZlDhjGRB5hb
   13.42 +mjbYgXhq5jXR1hzDGAR5imtSyCRiTYPIKkRUg8vdG4RfNt4eds15F15m4RjuGZol
   13.43 +c9K0fS0dIemQNfyv40Hu8Ow0EuKXqZwnsfc/opnoUUkvhmuid4zo213NhQGpxtTm
   13.44 +2xz7OuWzJvHbt5UD73YVohbCjDYZSIdJMKpFLM4ynYkEANSiPetbNMwPLNlM0dqe
   13.45 +/0EGgq/UMblvCXNI1Ie1OeLAkAgMEY8ztu8ye0bI7jR8xzBywF7ho3HruWXkm4bG
   13.46 +fqeP4Zx8GiHYEa61wyhVnZjXJbKlY1PcDeyTd4HnjX+CM4DqhP2a+HHYby7Dv1vg
   13.47 +jjwOKL0JNiy6rRvpMVdMVT05BADsUY363Q3TJY4H2zh3IFpGoxDgo9U9YCOwf16r
   13.48 +f+qAKdy0KsS13DWdQifRcIJFS6EzdB6oHLWl70kvgAPbgmr4u1za4Y+jZ/1+euG6
   13.49 +tYB45CSfeoBhhEsQJRKHxNA4m0OWYuZTR1TOvrEwd4f6/LlSSmfJ9w6hffuZ8WEH
   13.50 +TEoYKwQAwWDk0BNzQNk6AUxURw0p7HlWGCcCRgBOfr2xg/+mkZ6DkKcs3ExGOvm8
   13.51 +6cdzcwMJjqBNC45q5ZTAUCC+nxK5/AfvLlAopRYOoj8DfAbMR+S1CmCgC5RC/zn/
   13.52 +yHUnP+HrcvSfLzCi8wF7fqYsB6uU2PN+/TP6Ncui3fEPd+BvEdc+s4kBHwQYAQgA
   13.53 +CQUCWCW1kgIbDAAKCRDo4YF3so2bnbAkB/4z30XQR4LUUU/0NvkV7qpce2PTkjqB
   13.54 +8j3xtSUgxKx+XLXLdweF1ysxP6NJs6zZ4NK8mqCqqZ4ejaRtLUuQZ+t+aZUzjoRS
   13.55 +j5jGMtxY8zItkqm+A7UD8sXN9nyTwGFgGIaNyMK6I5PMQUR7Us3y3STlVeUJW1/m
   13.56 +JpfzWiFuXPX89QowqRUXtOzrh4RP+6uuu4mjj4w0HV50VUa/jaEDmYRxYRWAcqm+
   13.57 +OYoC38TJ9UelavDJq54H9etZ5mr7vhpTdrMFxAc91tqFS32Bg8c1qjO7dlXOI0Bl
   13.58 +31llkCRRc8Ft20Bfa4lMoM2lMU43OlaaOotutSWW+ZiHIHUHO71Chjt9
   13.59 +=/xdd
   13.60 +-----END PGP PRIVATE KEY BLOCK-----
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/test_keys/pub/blacklist_self_pub.asc	Fri Nov 11 14:15:15 2016 +0100
    14.3 @@ -0,0 +1,30 @@
    14.4 +-----BEGIN PGP PUBLIC KEY BLOCK-----
    14.5 +
    14.6 +mQENBFgltZIBCADIlORdZvfrWGP/QL1rVYGfy1TeqrlvBPgb5h9ZMB0RCHAq6hMV
    14.7 +nyq2zBTNgrOVC41VKq6qd+3GffPqgc+Ja/2q2YQJ480j2E5vRue8rUSFWg6msMvQ
    14.8 +1Df23LNfRR7g1D7d0wGMsXaMm6PduXuAmj4z5/8BTHriDPAh8DqrdtKj1v5WBSaZ
    14.9 +5O1fJK2f6/1Opa2Kg1hmAupP6IK8AZtuPJ8JPqmYt0LNOfmQNFZpRIc1VpbcC62H
   14.10 +IYcCYW3SwJQr2O/v06fJGao4A914JbcwLeJpSXwbtMJClN3go9MUSf8JYuhIiUJ0
   14.11 +jgdP6WvopRnn1STWDv0Hq1jd8Lb+M5GBX24/ABEBAAG0VUJsYWNrbGlzdCBTZWxm
   14.12 +IChUZXN0IERvIE5vdCBVc2UgRm9yIE90aGVyIFRlc3RzIFBsZWFzZSkgPGJsYWNr
   14.13 +bGlzdHNlbGZAa2dyb3Rob2ZmLm9yZz6JATgEEwEIACIFAlgltZICGwMGCwkIBwMC
   14.14 +BhUIAgkKCwQWAgMBAh4BAheAAAoJEOjhgXeyjZud5JEH/3p7258h32EmOvMdJZfl
   14.15 +7S3W5g1OTGij6rs656eJu5lv/E6wyre+MbqcBGHHJfjobrIx8qzyaq1lYBksnZcT
   14.16 ++sAf++i5xG/LXF+MhmpaM8ZIiopvKzRXSzEyCp/58oggIbz/DkT1DfI1CjTwQzOC
   14.17 +yPdOXM1e0DcKTT8HAiRgm1tQaxw7sOjdfatt37aOclJQatIE0eCBqk7Zn5Qt9KUR
   14.18 +mUCq6IkGf4XJ4bTEvbbtdizsy4ie6uUt3m/csZqLmV9vXPJAPvgYAB7hd4jBOOdQ
   14.19 +GtWRzZ05Q59QWHjvlAoZaXmfH3ERBEAixn6cP4Kl7wKtHMA8npCGMcdDd4o4q1Kl
   14.20 +hni5AQ0EWCW1kgEIAMRJTlhJsyv38T3P/lgzLKplWF6/XkrLZ8B6aR6WphafUoSe
   14.21 +knD2fvLa+0MyfGpThMdPDICTsjN5yCnO5HqX/dtM2tGmnKNtJFpMup8a5aSe8/bc
   14.22 +fWg7qZLzebexsw0DaNZjlrbjtI/6nF/JfpPKTgXb1bHhu3Fn6/USeG2Y0F54V4Y9
   14.23 +K5Sljz5pVFQGNGU+Wb5jBE7FSa9+beo2ik3iL4W2AYadONSZTD2FnjNTrZ0oHGaD
   14.24 +65kHnJ+yDLCMMkeZ16gCN89weQasI+9on2E1afXCpi1fPUvnktijkxZ9xgGNRYDl
   14.25 +jxPqgXuXM3H0oWND4+v3ZB55h/jH0OEdMW6IoJMAEQEAAYkBHwQYAQgACQUCWCW1
   14.26 +kgIbDAAKCRDo4YF3so2bnbAkB/4z30XQR4LUUU/0NvkV7qpce2PTkjqB8j3xtSUg
   14.27 +xKx+XLXLdweF1ysxP6NJs6zZ4NK8mqCqqZ4ejaRtLUuQZ+t+aZUzjoRSj5jGMtxY
   14.28 +8zItkqm+A7UD8sXN9nyTwGFgGIaNyMK6I5PMQUR7Us3y3STlVeUJW1/mJpfzWiFu
   14.29 +XPX89QowqRUXtOzrh4RP+6uuu4mjj4w0HV50VUa/jaEDmYRxYRWAcqm+OYoC38TJ
   14.30 +9UelavDJq54H9etZ5mr7vhpTdrMFxAc91tqFS32Bg8c1qjO7dlXOI0Bl31llkCRR
   14.31 +c8Ft20Bfa4lMoM2lMU43OlaaOotutSWW+ZiHIHUHO71Chjt9
   14.32 +=TA0e
   14.33 +-----END PGP PUBLIC KEY BLOCK-----
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/test/test_mails/blacklist_no_key.eml	Fri Nov 11 14:15:15 2016 +0100
    15.3 @@ -0,0 +1,12 @@
    15.4 +From: Blacklist Self <blacklistself@kgrothoff.org> 
    15.5 +To: Bob <pep.test.bob@pep-project.org>
    15.6 +Subject: This is a test of the emergency broadcast system.
    15.7 +Message-ID: <c1329dd1-b404-3e95-2612-cfe430352c3d@pep-project.org>
    15.8 +Date: Mon, 24 Oct 2016 12:57:28 +0200
    15.9 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
   15.10 + Thunderbird/45.3.0
   15.11 +MIME-Version: 1.0
   15.12 +Content-Type: text/plain; charset=utf-8
   15.13 +Content-Transfer-Encoding: 7bit
   15.14 +
   15.15 +So this is a very exciting MIME mail. Yay!