Browse Source

ENGINE-423: partial implementation of reencrypt functionality. Stashing changes to check another bug.

doc_update_sequoia
Krista Bennett 4 years ago
parent
commit
097b196755
4 changed files with 140 additions and 11 deletions
  1. +0
    -2
      src/keymanagement.c
  2. +134
    -7
      src/message_api.c
  3. +4
    -2
      src/message_api.h
  4. +2
    -0
      src/pEp_internal.h

+ 0
- 2
src/keymanagement.c View File

@ -15,8 +15,6 @@
#include "sync_fsm.h"
#include "blacklist.h"
#define KEY_EXPIRE_DELTA (60 * 60 * 24 * 365)
static bool key_matches_address(PEP_SESSION session, const char* address,
const char* fpr) {
if (!session || !address || !fpr)


+ 134
- 7
src/message_api.c View File

@ -2030,11 +2030,15 @@ DYNAMIC_API PEP_STATUS encrypt_message_for_self(
target_id->user_id = own_id; // ownership transfer
}
}
status = myself(session, target_id);
if (status != PEP_STATUS_OK)
goto pep_error;
if (target_id->address) {
status = myself(session, target_id);
if (status != PEP_STATUS_OK)
goto pep_error;
}
else if (!target_fpr)
return PEP_ILLEGAL_VALUE;
*dst = NULL;
// PEP_STATUS _status = update_identity(session, target_id);
@ -2853,6 +2857,84 @@ static PEP_STATUS reconcile_src_and_inner_messages(message* src,
// FIXME - are there any flags or anything else we need to be sure are carried?
}
static bool is_trusted_own_priv_fpr(PEP_SESSION session,
const char* own_id,
const char* fpr
)
{
bool retval = false;
if (!EMPTYSTR(fpr)) {
pEp_identity* test_identity = new_identity(NULL, fpr, own_id, NULL);
if (test_identity) {
PEP_STATUS status = get_trust(session, test_identity);
if (status == PEP_STATUS_OK) {
if (test_identity->comm_type & PEP_ct_confirmed) {
bool has_priv = false;
status = contains_priv_key(session, fpr, &has_priv);
if (status == PEP_STATUS_OK && has_priv)
retval = true;
}
}
free(test_identity);
}
}
return retval;
}
static bool reject_fpr(PEP_SESSION session, const char* fpr) {
bool reject = true;
PEP_STATUS status = key_revoked(session, fpr, &reject);
if (!reject) {
status = key_expired(session, fpr, &reject);
if (reject) {
timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
status = renew_key(session, fpr, ts);
free_timestamp(ts);
if (status == PEP_STATUS_OK)
reject = false;
}
}
return reject;
}
static char* seek_good_trusted_private_fpr(PEP_SESSION session, char* own_id,
stringlist_t* keylist) {
if (!own_id || !keylist)
return NULL;
stringlist_t* kl_curr = keylist;
char* retval = NULL;
while (kl_curr) {
char* fpr = kl_curr->value;
if (is_own_trusted_private_fpr(fpr)) {
if (!reject_fpr(fpr))
return strdup(fpr);
}
kl_curr = kl_curr->next;
}
char* target_own_fpr = NULL;
// Last shot...
status = get_user_default_key(session, own_id,
&target_own_fpr);
if (status == PEP_STATUS_OK && !EMPTYSTR(target_own_fpr)) {
if (is_own_trusted_private_fpr(target_own_fpr)) {
if (!reject_fpr(target_own_fpr))
return target_own_fpr;
}
}
// TODO: We can also go through all of the other available fprs for the
// own identity, but then I submit this function requires a little refactoring
return NULL;
}
DYNAMIC_API PEP_STATUS _decrypt_message(
PEP_SESSION session,
@ -2888,11 +2970,21 @@ DYNAMIC_API PEP_STATUS _decrypt_message(
char* signer_fpr = NULL;
bool is_pep_msg = is_a_pEpmessage(src);
// Grab input flags
bool reencrypt = (*flags & PEP_decrypt_flag_untrusted_server > 0);
// We own this pointer, and we take control of *keylist if reencrypting.
stringlist_t* extra = NULL;
if (reencrypt) {
if (*keylist) {
extra = *keylist;
}
}
*dst = NULL;
*keylist = NULL;
*rating = PEP_rating_undefined;
*flags = 0;
// *flags = 0;
/*** End init ***/
@ -3230,6 +3322,41 @@ DYNAMIC_API PEP_STATUS _decrypt_message(
*dst = msg;
*keylist = _keylist;
if (reencrypt) {
if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
PEP_STATUS reencrypt_status = PEP_CANNOT_REENCRYPT;
char* own_id = NULL;
status = get_default_own_userid(session, &own_id);
if (own_id) {
char* target_own_fpr = seek_good_trusted_private_fpr(session,
own_id,
_keylist);
if (target_own_fpr) {
pEp_identity* target_id = new_identity(NULL, own_id,
target_own_fpr, NULL);
if (target_id) {
*dst = NULL;
reencrypt_status = encrypt_message_for_self(session, target_id, msg,
extra, dst, PEP_enc_PGP_MIME,
0);
if (reencrypt_status != PEP_STATUS_OK)
reencrypt_status = PEP_CANNOT_REENCRYPT;
free_identity(target_id);
}
free(target_own_fpr);
}
free(own_id);
}
}
free_stringlist(extra); // This was an input variable for us. Keylist is overwritten above.
if (reencrypt_status == PEP_CANNOT_REENCRYPT)
decrypt_status = reencrypt_status;
else {
// Copy msg into src
}
}
if(decrypt_status == PEP_DECRYPTED_AND_VERIFIED)
return PEP_STATUS_OK;
else


+ 4
- 2
src/message_api.h View File

@ -38,6 +38,7 @@ typedef enum _PEP_encrypt_flags {
// This is used for outer messages (used to wrap the real message)
// This is only used internally and (eventually) by transport functions
PEP_encrypt_flag_inner_message = 0x8
} PEP_encrypt_flags;
typedef unsigned int PEP_encrypt_flags_t;
@ -229,7 +230,8 @@ DYNAMIC_API PEP_color color_from_rating(PEP_rating rating);
typedef enum _PEP_decrypt_flags {
PEP_decrypt_flag_own_private_key = 0x1,
PEP_decrypt_flag_consume = 0x2,
PEP_decrypt_flag_ignore = 0x4
PEP_decrypt_flag_ignore = 0x4,
PEP_decrypt_flag_untrusted_server = 0x8
} PEP_decrypt_flags;
typedef unsigned int PEP_decrypt_flags_t;
@ -243,7 +245,7 @@ typedef unsigned int PEP_decrypt_flags_t;
// dst (out) pointer to new decrypted message or NULL on failure
// keylist (out) stringlist with keyids
// rating (out) rating for the message
// flags (out) flags to signal special decryption features
// flags (in/out) flags to signal special decryption features
//
// return value:
// error status


+ 2
- 0
src/pEp_internal.h View File

@ -8,6 +8,8 @@
#define MAX_KEY_SIZE (1024 * 1024)
#define MAX_KEYS_TO_IMPORT 20
#define KEY_EXPIRE_DELTA (60 * 60 * 24 * 365)
// this is 20 trustwords with 79 chars max
#define MAX_TRUSTWORDS_SPACE (20 * 80)


Loading…
Cancel
Save