merge
authorEdouard Tisserant
Thu, 07 May 2015 18:54:58 +0200
changeset 255813b795312b1
parent 254 710ff44d3cf0
parent 251 dba7f09db1ed
child 257 5655f3dea506
child 263 6ec7559afec4
merge
src/pEp_internal.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/db/CREATE_DB.txt	Thu May 07 18:54:58 2015 +0200
     1.3 @@ -0,0 +1,8 @@
     1.4 +To create system.db:
     1.5 +
     1.6 +1) run the create script
     1.7 +
     1.8 +2) import wordlists, 65535 words each language
     1.9 +
    1.10 +3) insert an i18n text per language
    1.11 +
     2.1 --- a/db/create_system_db.sql	Thu May 07 18:54:13 2015 +0200
     2.2 +++ b/db/create_system_db.sql	Thu May 07 18:54:58 2015 +0200
     2.3 @@ -6,3 +6,15 @@
     2.4  );
     2.5  
     2.6  CREATE UNIQUE INDEX wordlist_pk on wordlist (lang, id);
     2.7 +
     2.8 +CREATE TABLE i18n (
     2.9 +    lang text,
    2.10 +    id integer,
    2.11 +    phrase text
    2.12 +);
    2.13 +
    2.14 +CREATE UNIQUE INDEX i18n_pk on i18n (lang, id);
    2.15 +
    2.16 +INSERT INTO i18n VALUES ('en', 1, 'I want to have this conversation in English language');
    2.17 +INSERT INTO i18n VALUES ('de', 1, 'Ich möchte diese Unterhaltung auf Deutsch führen');
    2.18 +' add more languages here
     4.1 --- a/src/message_api.c	Thu May 07 18:54:13 2015 +0200
     4.2 +++ b/src/message_api.c	Thu May 07 18:54:58 2015 +0200
     4.3 @@ -105,6 +105,22 @@
     4.4          msg->attachments = bl;
     4.5  }
     4.6  
     4.7 +void determine_encryption_format(message *msg)
     4.8 +{
     4.9 +    assert(msg);
    4.10 +
    4.11 +    if (msg->enc_format != PEP_enc_none)
    4.12 +        return;
    4.13 +
    4.14 +    if (is_PGP_message_text(msg->longmsg))
    4.15 +        msg->enc_format = PEP_enc_pieces;
    4.16 +    else if (msg->attachments && msg->attachments->next &&
    4.17 +            is_mime_type(msg->attachments, "multipart/encrypted") &&
    4.18 +            is_PGP_message_text(msg->attachments->next->data)
    4.19 +        )
    4.20 +        msg->enc_format = PEP_enc_PGP_MIME;
    4.21 +}
    4.22 +
    4.23  static char * combine_short_and_long(const char *shortmsg, const char *longmsg)
    4.24  {
    4.25      char * ptext;
    4.26 @@ -344,6 +360,7 @@
    4.27  
    4.28      *dst = NULL;
    4.29  
    4.30 +    determine_encryption_format(src);
    4.31      import_attached_keys(session, src);
    4.32  
    4.33      if (src->enc_format >= PEP_enc_pieces) {
    4.34 @@ -362,7 +379,8 @@
    4.35              PEP_MIME_format mime = (enc_format == PEP_enc_PEP) ? PEP_MIME :
    4.36                      PEP_MIME_fields_omitted;
    4.37  
    4.38 -            status = decrypt_message(session, src, mime, &_dst, &_keylist);
    4.39 +            PEP_color color;
    4.40 +            status = decrypt_message(session, src, mime, &_dst, &_keylist, &color);
    4.41              if (status != PEP_STATUS_OK)
    4.42                  goto pep_error;
    4.43              free_stringlist(_keylist);
    4.44 @@ -646,12 +664,109 @@
    4.45      return strndup(filename, ext - filename);
    4.46  }
    4.47  
    4.48 +static PEP_color decrypt_color(PEP_STATUS status)
    4.49 +{
    4.50 +    switch (status) {
    4.51 +        case PEP_UNENCRYPTED:
    4.52 +        case PEP_VERIFIED:
    4.53 +        case PEP_VERIFY_NO_KEY:
    4.54 +        case PEP_VERIFIED_AND_TRUSTED:
    4.55 +            return PEP_rating_unencrypted;
    4.56 +
    4.57 +        case PEP_DECRYPTED:
    4.58 +            return PEP_rating_unreliable;
    4.59 +
    4.60 +        case PEP_DECRYPTED_AND_VERIFIED:
    4.61 +            return PEP_rating_reliable;
    4.62 +
    4.63 +        case PEP_DECRYPT_WRONG_FORMAT:
    4.64 +        case PEP_DECRYPT_NO_KEY:
    4.65 +        case PEP_CANNOT_DECRYPT_UNKNOWN:
    4.66 +            return PEP_rating_cannot_decrypt;
    4.67 +
    4.68 +        default:
    4.69 +            return PEP_rating_undefined;
    4.70 +    }
    4.71 +}
    4.72 +
    4.73 +static PEP_color _rating(PEP_comm_type ct)
    4.74 +{
    4.75 +    if (ct == PEP_ct_unknown)
    4.76 +        return PEP_rating_undefined;
    4.77 +
    4.78 +    else if (ct == PEP_ct_compromized)
    4.79 +        return PEP_rating_under_attack;
    4.80 +
    4.81 +    else if (ct >= PEP_ct_confirmed_enc_anon)
    4.82 +        return PEP_rating_trusted_and_anonymized;
    4.83 +
    4.84 +    else if (ct >= PEP_ct_strong_encryption)
    4.85 +        return PEP_rating_trusted;
    4.86 +
    4.87 +    else if (ct >= PEP_ct_strong_but_unconfirmed && ct < PEP_ct_confirmed)
    4.88 +        return PEP_rating_reliable;
    4.89 +    
    4.90 +    else if (ct == PEP_ct_no_encryption || ct == PEP_ct_no_encrypted_channel)
    4.91 +        return PEP_rating_unencrypted;
    4.92 +
    4.93 +    else
    4.94 +        return PEP_rating_unreliable;
    4.95 +}
    4.96 +
    4.97 +static PEP_color key_color(PEP_SESSION session, const char *fpr) {
    4.98 +    PEP_comm_type comm_type = PEP_ct_unknown;
    4.99 +
   4.100 +    assert(session);
   4.101 +    assert(fpr);
   4.102 +
   4.103 +    PEP_STATUS status = get_key_rating(session, fpr, &comm_type);
   4.104 +    if (status != PEP_STATUS_OK)
   4.105 +        return PEP_rating_undefined;
   4.106 +
   4.107 +    return _rating(comm_type);
   4.108 +}
   4.109 +
   4.110 +static PEP_color keylist_color(PEP_SESSION session, stringlist_t *keylist)
   4.111 +{
   4.112 +    PEP_color color = PEP_rating_reliable;
   4.113 +
   4.114 +    assert(keylist && keylist->value);
   4.115 +    if (keylist == NULL || keylist->value == NULL)
   4.116 +        return PEP_rating_unencrypted;
   4.117 +
   4.118 +    stringlist_t *_kl;
   4.119 +    for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
   4.120 +        PEP_comm_type ct;
   4.121 +        PEP_STATUS status;
   4.122 +        PEP_color _color;
   4.123 +
   4.124 +        _color = key_color(session, _kl->value);
   4.125 +        if (_color == PEP_rating_under_attack)
   4.126 +            return PEP_rating_under_attack;
   4.127 +
   4.128 +        color = MIN(color, _color);
   4.129 +
   4.130 +        status = least_trust(session, _kl->value, &ct);
   4.131 +        if (status != PEP_STATUS_OK)
   4.132 +            return PEP_rating_undefined;
   4.133 +
   4.134 +        _color = _rating(ct);
   4.135 +        if (_color == PEP_rating_under_attack)
   4.136 +            return PEP_rating_under_attack;
   4.137 +
   4.138 +        color = MIN(color, _color);
   4.139 +    }
   4.140 +
   4.141 +    return color;
   4.142 +}
   4.143 +
   4.144  DYNAMIC_API PEP_STATUS decrypt_message(
   4.145          PEP_SESSION session,
   4.146          message *src,
   4.147          PEP_MIME_format mime,
   4.148          message **dst,
   4.149 -        stringlist_t **keylist
   4.150 +        stringlist_t **keylist,
   4.151 +        PEP_color *color
   4.152      )
   4.153  {
   4.154      PEP_STATUS status = PEP_STATUS_OK;
   4.155 @@ -667,12 +782,16 @@
   4.156      assert(src);
   4.157      assert(dst);
   4.158      assert(keylist);
   4.159 +    assert(color);
   4.160  
   4.161 -    if (!(session && src && dst && keylist))
   4.162 +    if (!(session && src && dst && keylist && color))
   4.163          return PEP_ILLEGAL_VALUE;
   4.164  
   4.165      *dst = NULL;
   4.166 +    *keylist = NULL;
   4.167 +    *color = PEP_rating_undefined;
   4.168   
   4.169 +    determine_encryption_format(src);
   4.170      import_attached_keys(session, src);
   4.171  
   4.172      if (src->mime == PEP_MIME_fields_omitted || src->mime == PEP_MIME) {
   4.173 @@ -706,9 +825,18 @@
   4.174  
   4.175      status = decrypt_and_verify(session, ctext, csize, &ptext, &psize,
   4.176              &_keylist);
   4.177 +    *color = decrypt_color(status);
   4.178      if (ptext == NULL)
   4.179          goto pep_error;
   4.180  
   4.181 +    if (*color != PEP_rating_under_attack) {
   4.182 +        PEP_color _color = keylist_color(session, _keylist);
   4.183 +        if (_color == PEP_rating_under_attack)
   4.184 +            *color = PEP_rating_under_attack;
   4.185 +        else
   4.186 +            *color = MIN(*color, _color);
   4.187 +    }
   4.188 +
   4.189      switch (src->enc_format) {
   4.190          case PEP_enc_PGP_MIME:
   4.191              status = mime_decode_message(ptext, &msg);
   4.192 @@ -884,31 +1012,7 @@
   4.193      }
   4.194  }
   4.195  
   4.196 -static PEP_color _rating(PEP_comm_type ct)
   4.197 -{
   4.198 -    if (ct == PEP_ct_unknown)
   4.199 -        return PEP_rating_undefined;
   4.200 -
   4.201 -    else if (ct == PEP_ct_compromized)
   4.202 -        return PEP_rating_under_attack;
   4.203 -
   4.204 -    else if (ct >= PEP_ct_confirmed_enc_anon)
   4.205 -        return PEP_rating_trusted_and_anonymized;
   4.206 -
   4.207 -    else if (ct >= PEP_ct_strong_encryption)
   4.208 -        return PEP_rating_trusted;
   4.209 -
   4.210 -    else if (ct >= PEP_ct_strong_but_unconfirmed && ct < PEP_ct_confirmed)
   4.211 -        return PEP_rating_reliable;
   4.212 -    
   4.213 -    else if (ct == PEP_ct_no_encryption || ct == PEP_ct_no_encrypted_channel)
   4.214 -        return PEP_rating_unencrypted;
   4.215 -
   4.216 -    else
   4.217 -        return PEP_rating_unreliable;
   4.218 -}
   4.219 -
   4.220 -DYNAMIC_API PEP_STATUS message_color(
   4.221 +DYNAMIC_API PEP_STATUS outgoing_message_color(
   4.222          PEP_SESSION session,
   4.223          message *msg,
   4.224          PEP_color *color
   4.225 @@ -921,50 +1025,40 @@
   4.226  
   4.227      assert(session);
   4.228      assert(msg);
   4.229 +    assert(msg->from);
   4.230 +    assert(msg->dir == PEP_dir_outgoing);
   4.231      assert(color);
   4.232  
   4.233      if (!(session && msg && color))
   4.234          return PEP_ILLEGAL_VALUE;
   4.235  
   4.236 +    if (msg->from == NULL || msg->dir != PEP_dir_outgoing)
   4.237 +        return PEP_ILLEGAL_VALUE;
   4.238 +
   4.239      *color = PEP_rating_undefined;
   4.240  
   4.241      assert(msg->from);
   4.242      if (msg->from == NULL)
   4.243          return PEP_ILLEGAL_VALUE;
   4.244  
   4.245 -    switch (msg->dir) {
   4.246 -        case PEP_dir_incoming:
   4.247 -            status = update_identity(session, msg->from);
   4.248 -            if (status != PEP_STATUS_OK)
   4.249 -                return status;
   4.250 -            max_comm_type = msg->from->comm_type;
   4.251 -            comm_type_determined = true;
   4.252 -            break;
   4.253 -        
   4.254 -        case PEP_dir_outgoing:
   4.255 -            status = myself(session, msg->from);
   4.256 -            if (status != PEP_STATUS_OK)
   4.257 -                return status;
   4.258 +    status = myself(session, msg->from);
   4.259 +    if (status != PEP_STATUS_OK)
   4.260 +        return status;
   4.261  
   4.262 -            for (il = msg->to; il != NULL; il = il->next) {
   4.263 -                if (il->ident) {
   4.264 -                    max_comm_type = _get_comm_type(session, max_comm_type,
   4.265 -                            il->ident);
   4.266 -                    comm_type_determined = true;
   4.267 -                }
   4.268 -            }
   4.269 +    for (il = msg->to; il != NULL; il = il->next) {
   4.270 +        if (il->ident) {
   4.271 +            max_comm_type = _get_comm_type(session, max_comm_type,
   4.272 +                    il->ident);
   4.273 +            comm_type_determined = true;
   4.274 +        }
   4.275 +    }
   4.276  
   4.277 -            for (il = msg->cc; il != NULL; il = il->next) {
   4.278 -                if (il->ident) {
   4.279 -                    max_comm_type = _get_comm_type(session, max_comm_type,
   4.280 -                            il->ident);
   4.281 -                    comm_type_determined = true;
   4.282 -                }
   4.283 -            }
   4.284 -            break;
   4.285 -
   4.286 -        default:
   4.287 -            return PEP_ILLEGAL_VALUE;
   4.288 +    for (il = msg->cc; il != NULL; il = il->next) {
   4.289 +        if (il->ident) {
   4.290 +            max_comm_type = _get_comm_type(session, max_comm_type,
   4.291 +                    il->ident);
   4.292 +            comm_type_determined = true;
   4.293 +        }
   4.294      }
   4.295  
   4.296      if (comm_type_determined == false)
     5.1 --- a/src/message_api.h	Thu May 07 18:54:13 2015 +0200
     5.2 +++ b/src/message_api.h	Thu May 07 18:54:58 2015 +0200
     5.3 @@ -31,7 +31,8 @@
     5.4  //		PEP_GET_KEY_FAILED		        cannot retrieve key
     5.5  //
     5.6  //	caveat:
     5.7 -//	    the ownership of the new message goes to the caller
     5.8 +//	    the ownershop of src remains with the caller
     5.9 +//	    the ownership of dst goes to the caller
    5.10  //	    if src is unencrypted this function returns PEP_UNENCRYPTED and sets
    5.11  //	    dst to NULL
    5.12  
    5.13 @@ -44,30 +45,6 @@
    5.14      );
    5.15  
    5.16  
    5.17 -// decrypt_message() - decrypt message in memory
    5.18 -//
    5.19 -//  parameters:
    5.20 -//      session (in)        session handle
    5.21 -//      src (in)            message to decrypt
    5.22 -//      mime (in)           MIME encoding wanted
    5.23 -//      dst (out)           pointer to new decrypted message or NULL on failure
    5.24 -//      keylist (out)       stringlist with keyids
    5.25 -//
    5.26 -//  return value:
    5.27 -//      error status or PEP_STATUS_OK on success
    5.28 -//
    5.29 -//	caveat:
    5.30 -//	    the ownership of the new message goes to the caller
    5.31 -
    5.32 -DYNAMIC_API PEP_STATUS decrypt_message(
    5.33 -        PEP_SESSION session,
    5.34 -        message *src,
    5.35 -        PEP_MIME_format mime,
    5.36 -        message **dst,
    5.37 -        stringlist_t **keylist
    5.38 -    );
    5.39 -
    5.40 -
    5.41  typedef enum _PEP_color {
    5.42      PEP_rating_undefined = 0,
    5.43      PEP_rating_unencrypted,
    5.44 @@ -85,7 +62,35 @@
    5.45      PEP_rating_b0rken = -2
    5.46  } PEP_color;
    5.47  
    5.48 -// message_color() - get color for a message
    5.49 +// decrypt_message() - decrypt message in memory
    5.50 +//
    5.51 +//  parameters:
    5.52 +//      session (in)        session handle
    5.53 +//      src (in)            message to decrypt
    5.54 +//      mime (in)           MIME encoding wanted
    5.55 +//      dst (out)           pointer to new decrypted message or NULL on failure
    5.56 +//      keylist (out)       stringlist with keyids
    5.57 +//      color (out)         color for the message
    5.58 +//
    5.59 +//  return value:
    5.60 +//      error status or PEP_STATUS_OK on success
    5.61 +//
    5.62 +//	caveat:
    5.63 +//	    the ownership of src remains with the caller
    5.64 +//	    the ownership of dst goes to the caller
    5.65 +//	    the ownership of keylist goes to the caller
    5.66 +
    5.67 +DYNAMIC_API PEP_STATUS decrypt_message(
    5.68 +        PEP_SESSION session,
    5.69 +        message *src,
    5.70 +        PEP_MIME_format mime,
    5.71 +        message **dst,
    5.72 +        stringlist_t **keylist,
    5.73 +        PEP_color *color
    5.74 +    );
    5.75 +
    5.76 +
    5.77 +// outgoing_message_color() - get color for an outgoing message
    5.78  //
    5.79  //  parameters:
    5.80  //      session (in)        session handle
    5.81 @@ -97,8 +102,10 @@
    5.82  //
    5.83  //  caveat:
    5.84  //      msg->from must point to a valid pEp_identity
    5.85 +//      msg->dir must be PEP_dir_outgoing
    5.86 +//      the ownership of msg remains with the caller
    5.87  
    5.88 -DYNAMIC_API PEP_STATUS message_color(
    5.89 +DYNAMIC_API PEP_STATUS outgoing_message_color(
    5.90          PEP_SESSION session,
    5.91          message *msg,
    5.92          PEP_color *color
    5.93 @@ -114,6 +121,9 @@
    5.94  //
    5.95  //  return value:
    5.96  //      error status or PEP_STATUS_OK on success
    5.97 +//
    5.98 +//  caveat:
    5.99 +//      the ownership of ident remains with the caller
   5.100  
   5.101  DYNAMIC_API PEP_STATUS identity_color(
   5.102          PEP_SESSION session,
     6.1 --- a/src/mime.c	Thu May 07 18:54:13 2015 +0200
     6.2 +++ b/src/mime.c	Thu May 07 18:54:58 2015 +0200
     6.3 @@ -11,7 +11,6 @@
     6.4  
     6.5  DYNAMIC_API bool is_PGP_message_text(const char *text)
     6.6  {
     6.7 -    assert(text);
     6.8      if (text == NULL)
     6.9          return false;
    6.10  
    6.11 @@ -1280,8 +1279,6 @@
    6.12  
    6.13              clistiter *cur;
    6.14              for (cur = clist_begin(partlist); cur; cur = clist_next(cur)) {
    6.15 -                size_t index;
    6.16 -                int r;
    6.17                  struct mailmime *part = clist_content(cur);
    6.18                  if (part == NULL)
    6.19                      return PEP_ILLEGAL_VALUE;
     7.1 --- a/src/pEpEngine.c	Thu May 07 18:54:13 2015 +0200
     7.2 +++ b/src/pEpEngine.c	Thu May 07 18:54:58 2015 +0200
     7.3 @@ -17,6 +17,7 @@
     7.4  	static const char *sql_set_identity;
     7.5  	static const char *sql_set_trust;
     7.6      static const char *sql_get_trust;
     7.7 +    static const char *sql_least_trust;
     7.8      bool in_first = false;
     7.9  
    7.10      assert(sqlite3_threadsafe());
    7.11 @@ -193,6 +194,8 @@
    7.12  
    7.13          sql_get_trust = "select user_id, comm_type from trust where user_id = ?1 "
    7.14                          "and pgp_keypair_fpr = ?2 ;";
    7.15 +
    7.16 +        sql_least_trust = "select min(comm_type) from trust where pgp_keypair_fpr = ?1 ;";
    7.17      }
    7.18  
    7.19      int_result = sqlite3_prepare_v2(_session->db, sql_log, strlen(sql_log),
    7.20 @@ -227,6 +230,10 @@
    7.21              strlen(sql_get_trust), &_session->get_trust, NULL);
    7.22      assert(int_result == SQLITE_OK);
    7.23  
    7.24 +    int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
    7.25 +            strlen(sql_least_trust), &_session->least_trust, NULL);
    7.26 +    assert(int_result == SQLITE_OK);
    7.27 +
    7.28      status = init_cryptotech(_session, in_first);
    7.29      if (status != PEP_STATUS_OK)
    7.30          goto pep_error;
    7.31 @@ -285,6 +292,8 @@
    7.32                  sqlite3_finalize(session->set_trust);
    7.33              if (session->get_trust)
    7.34                  sqlite3_finalize(session->get_trust);
    7.35 +            if (session->least_trust)
    7.36 +                sqlite3_finalize(session->least_trust);
    7.37  
    7.38              if (session->db)
    7.39                  sqlite3_close_v2(session->db);
    7.40 @@ -374,9 +383,9 @@
    7.41  		if (*word)
    7.42              *wsize = sqlite3_column_bytes(session->trustword, 1);
    7.43  		else
    7.44 -			status = PEP_SAFEWORD_NOT_FOUND;
    7.45 +			status = PEP_TRUSTWORD_NOT_FOUND;
    7.46  	} else
    7.47 -		status = PEP_SAFEWORD_NOT_FOUND;
    7.48 +		status = PEP_TRUSTWORD_NOT_FOUND;
    7.49  
    7.50  	sqlite3_reset(session->trustword);
    7.51  	return status;
    7.52 @@ -405,7 +414,7 @@
    7.53  	*words = NULL;
    7.54  	*wsize = 0;
    7.55  
    7.56 -    buffer = calloc(1, MAX_SAFEWORDS_SPACE);
    7.57 +    buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
    7.58      assert(buffer);
    7.59      if (buffer == NULL)
    7.60          return PEP_OUT_OF_MEMORY;
    7.61 @@ -447,10 +456,10 @@
    7.62          }
    7.63  		if (word == NULL) {
    7.64              free(buffer);
    7.65 -			return PEP_SAFEWORD_NOT_FOUND;
    7.66 +			return PEP_TRUSTWORD_NOT_FOUND;
    7.67          }
    7.68  
    7.69 -		if (dest + _wsize < buffer + MAX_SAFEWORDS_SPACE - 1) {
    7.70 +		if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
    7.71  			strncpy(dest, word, _wsize);
    7.72              free(word);
    7.73  			dest += _wsize;
    7.74 @@ -461,7 +470,7 @@
    7.75          }
    7.76  
    7.77  		if (source < fingerprint + fsize
    7.78 -                && dest + _wsize < buffer + MAX_SAFEWORDS_SPACE - 1)
    7.79 +                && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
    7.80  			*dest++ = ' ';
    7.81  
    7.82  		++n_words;
    7.83 @@ -738,6 +747,41 @@
    7.84      return status;
    7.85  }
    7.86  
    7.87 +DYNAMIC_API PEP_STATUS least_trust(
    7.88 +        PEP_SESSION session,
    7.89 +        const char *fpr,
    7.90 +        PEP_comm_type *comm_type
    7.91 +    )
    7.92 +{
    7.93 +    PEP_STATUS status = PEP_STATUS_OK;
    7.94 +    int result;
    7.95 +    PEP_comm_type _comm_type = PEP_ct_unknown;
    7.96 +
    7.97 +    assert(session);
    7.98 +    assert(fpr);
    7.99 +    assert(comm_type);
   7.100 +
   7.101 +    if (!(session && fpr && comm_type))
   7.102 +        return PEP_ILLEGAL_VALUE;
   7.103 +
   7.104 +    sqlite3_reset(session->least_trust);
   7.105 +    sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
   7.106 +
   7.107 +    result = sqlite3_step(session->least_trust);
   7.108 +    switch (result) {
   7.109 +        case SQLITE_ROW: {
   7.110 +            *comm_type = (PEP_comm_type)
   7.111 +                    sqlite3_column_int(session->get_identity, 1);
   7.112 +            break;
   7.113 +        }
   7.114 +        default:
   7.115 +            status = PEP_CANNOT_FIND_IDENTITY;
   7.116 +    }
   7.117 +
   7.118 +    sqlite3_reset(session->least_trust);
   7.119 +    return status;
   7.120 +}
   7.121 +
   7.122  DYNAMIC_API PEP_STATUS decrypt_and_verify(
   7.123      PEP_SESSION session, const char *ctext, size_t csize,
   7.124      char **ptext, size_t *psize, stringlist_t **keylist
     8.1 --- a/src/pEpEngine.h	Thu May 07 18:54:13 2015 +0200
     8.2 +++ b/src/pEpEngine.h	Thu May 07 18:54:58 2015 +0200
     8.3 @@ -56,7 +56,7 @@
     8.4      PEP_VERIFIED_AND_TRUSTED                        = 0x0408,
     8.5  	PEP_CANNOT_DECRYPT_UNKNOWN						= 0x04ff,
     8.6  
     8.7 -	PEP_SAFEWORD_NOT_FOUND							= 0x0501,
     8.8 +	PEP_TRUSTWORD_NOT_FOUND							= 0x0501,
     8.9  
    8.10      PEP_CANNOT_CREATE_KEY                           = 0x0601,
    8.11      PEP_CANNOT_SEND_KEY                             = 0x0602,
    8.12 @@ -230,7 +230,7 @@
    8.13  //
    8.14  //	return value:
    8.15  //	    PEP_STATUS_OK           trustword retrieved
    8.16 -//	    PEP_SAFEWORD_NOT_FOUND  trustword not found
    8.17 +//	    PEP_TRUSTWORD_NOT_FOUND  trustword not found
    8.18  //
    8.19  //	caveat:
    8.20  //		the word pointer goes to the ownership of the caller
    8.21 @@ -259,7 +259,7 @@
    8.22  //	return value:
    8.23  //	    PEP_STATUS_OK           trustwords retrieved
    8.24  //      PEP_OUT_OF_MEMORY       out of memory
    8.25 -//	    PEP_SAFEWORD_NOT_FOUND  at least one trustword not found
    8.26 +//	    PEP_TRUSTWORD_NOT_FOUND at least one trustword not found
    8.27  //
    8.28  //	caveat:
    8.29  //		the word pointer goes to the ownership of the caller
    8.30 @@ -583,13 +583,29 @@
    8.31  //                              user_id and comm_type as result (out)
    8.32  //
    8.33  //  this function modifies the given identity struct; the struct remains in
    8.34 -// the ownership of the caller
    8.35 +//  the ownership of the caller
    8.36  //  if the trust level cannot be determined identity->comm_type is set
    8.37  //  to PEP_ct_unknown
    8.38  
    8.39  DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity);
    8.40  
    8.41  
    8.42 +// least_trust() - get the least known trust level for a key in the database
    8.43 +//
    8.44 +//  parameters:
    8.45 +//      session (in)            session handle
    8.46 +//      fpr (in)                fingerprint of key to check
    8.47 +//      comm_type (out)         least comm_type as result (out)
    8.48 +//
    8.49 +//  if the trust level cannot be determined comm_type is set to PEP_ct_unknown
    8.50 +
    8.51 +DYNAMIC_API PEP_STATUS least_trust(
    8.52 +        PEP_SESSION session,
    8.53 +        const char *fpr,
    8.54 +        PEP_comm_type *comm_type
    8.55 +    );
    8.56 +
    8.57 +
    8.58  // get_key_rating() - get the rating a bare key has
    8.59  //
    8.60  //  parameters:
     9.1 --- a/src/pEp_internal.h	Thu May 07 18:54:13 2015 +0200
     9.2 +++ b/src/pEp_internal.h	Thu May 07 18:54:58 2015 +0200
     9.3 @@ -1,7 +1,7 @@
     9.4  #define PEP_ENGINE_VERSION "0.5.0"
     9.5  
     9.6  // this is 20 trustwords with 79 chars max
     9.7 -#define MAX_SAFEWORDS_SPACE (20 * 80)
     9.8 +#define MAX_TRUSTWORDS_SPACE (20 * 80)
     9.9  
    9.10  // XML parameters string
    9.11  #define PARMS_MAX 32768
    9.12 @@ -84,6 +84,7 @@
    9.13      sqlite3_stmt *set_identity;
    9.14      sqlite3_stmt *set_trust;
    9.15      sqlite3_stmt *get_trust;
    9.16 +    sqlite3_stmt *least_trust;
    9.17  } pEpSession;
    9.18  
    9.19  PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first);
    10.1 --- a/test/message_api_test.cc	Thu May 07 18:54:13 2015 +0200
    10.2 +++ b/test/message_api_test.cc	Thu May 07 18:54:58 2015 +0200
    10.3 @@ -66,7 +66,8 @@
    10.4  
    10.5      message *msg4;
    10.6      stringlist_t *keylist4;
    10.7 -    PEP_STATUS status4 = decrypt_message(session, enc_msg2, PEP_MIME_none, &msg4, &keylist4);
    10.8 +    PEP_color color;
    10.9 +    PEP_STATUS status4 = decrypt_message(session, enc_msg2, PEP_MIME_none, &msg4, &keylist4, &color);
   10.10      assert(status4 == PEP_STATUS_OK);
   10.11      assert(msg4);
   10.12      assert(keylist4);