mirror of
https://github.com/deltachat/deltachat-core.git
synced 2025-10-05 19:42:04 +02:00
prepare mrapeerstate_t to handle gossip keys, allow public_key and gossip_key being NULL
This commit is contained in:
parent
4a1f2b2d81
commit
bc6e8e0a9e
6 changed files with 61 additions and 19 deletions
|
@ -261,7 +261,7 @@ static void log_contactlist(mrmailbox_t* mailbox, mrarray_t* contacts)
|
|||
case MRA_PE_RESET: pe = safe_strdup("reset"); break;
|
||||
default: pe = mr_mprintf("unknown-value (%i)", peerstate->m_prefer_encrypt); break;
|
||||
}
|
||||
line2 = mr_mprintf(", prefer-encrypt=%s, key-bytes=%i", pe, peerstate->m_public_key->m_bytes);
|
||||
line2 = mr_mprintf(", prefer-encrypt=%s", pe);
|
||||
free(pe);
|
||||
}
|
||||
mrcontact_unref(contact);
|
||||
|
|
|
@ -44,9 +44,16 @@ static void mrapeerstate_empty(mrapeerstate_t* ths)
|
|||
free(ths->m_addr);
|
||||
ths->m_addr = NULL;
|
||||
|
||||
if( ths->m_public_key->m_binary ) {
|
||||
if( ths->m_public_key ) {
|
||||
mrkey_unref(ths->m_public_key);
|
||||
ths->m_public_key = mrkey_new();
|
||||
ths->m_public_key = NULL;
|
||||
}
|
||||
|
||||
ths->m_gossip_timestamp = 0;
|
||||
|
||||
if( ths->m_gossip_key ) {
|
||||
mrkey_unref(ths->m_gossip_key);
|
||||
ths->m_gossip_key = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +70,7 @@ int mrapeerstate_load_from_db__(mrapeerstate_t* ths, mrsqlite3_t* sql, const cha
|
|||
mrapeerstate_empty(ths);
|
||||
|
||||
stmt = mrsqlite3_predefine__(sql, SELECT_aclpp_FROM_acpeerstates_WHERE_a,
|
||||
"SELECT addr, last_seen, last_seen_autocrypt, prefer_encrypted, public_key FROM acpeerstates WHERE addr=? COLLATE NOCASE;");
|
||||
"SELECT addr, last_seen, last_seen_autocrypt, prefer_encrypted, public_key, gossip_timestamp, gossip_key FROM acpeerstates WHERE addr=? COLLATE NOCASE;");
|
||||
sqlite3_bind_text(stmt, 1, addr, -1, SQLITE_STATIC);
|
||||
if( sqlite3_step(stmt) != SQLITE_ROW ) {
|
||||
goto cleanup;
|
||||
|
@ -72,7 +79,19 @@ int mrapeerstate_load_from_db__(mrapeerstate_t* ths, mrsqlite3_t* sql, const cha
|
|||
ths->m_last_seen = sqlite3_column_int64 (stmt, 1);
|
||||
ths->m_last_seen_autocrypt = sqlite3_column_int64 (stmt, 2);
|
||||
ths->m_prefer_encrypt = sqlite3_column_int (stmt, 3);
|
||||
mrkey_set_from_stmt (ths->m_public_key, stmt, 4, MR_PUBLIC);
|
||||
#define PUBLIC_KEY_COL 4
|
||||
ths->m_gossip_timestamp = sqlite3_column_int (stmt, 5);
|
||||
#define GOSSIP_KEY_COL 6
|
||||
|
||||
if( sqlite3_column_type(stmt, PUBLIC_KEY_COL)!=SQLITE_NULL ) {
|
||||
ths->m_public_key = mrkey_new();
|
||||
mrkey_set_from_stmt(ths->m_public_key, stmt, PUBLIC_KEY_COL, MR_PUBLIC);
|
||||
}
|
||||
|
||||
if( sqlite3_column_type(stmt, GOSSIP_KEY_COL)!=SQLITE_NULL ) {
|
||||
ths->m_gossip_key = mrkey_new();
|
||||
mrkey_set_from_stmt(ths->m_gossip_key, stmt, GOSSIP_KEY_COL, MR_PUBLIC);
|
||||
}
|
||||
|
||||
success = 1;
|
||||
|
||||
|
@ -86,8 +105,7 @@ int mrapeerstate_save_to_db__(const mrapeerstate_t* ths, mrsqlite3_t* sql, int c
|
|||
int success = 0;
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
if( ths==NULL || sql==NULL
|
||||
|| ths->m_addr==NULL || ths->m_public_key->m_binary==NULL || ths->m_public_key->m_bytes<=0 ) {
|
||||
if( ths==NULL || sql==NULL || ths->m_addr==NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -100,12 +118,14 @@ int mrapeerstate_save_to_db__(const mrapeerstate_t* ths, mrsqlite3_t* sql, int c
|
|||
if( (ths->m_to_save&MRA_SAVE_ALL) || create )
|
||||
{
|
||||
stmt = mrsqlite3_predefine__(sql, UPDATE_acpeerstates_SET_lcpp_WHERE_a,
|
||||
"UPDATE acpeerstates SET last_seen=?, last_seen_autocrypt=?, prefer_encrypted=?, public_key=? WHERE addr=?;");
|
||||
"UPDATE acpeerstates SET last_seen=?, last_seen_autocrypt=?, prefer_encrypted=?, public_key=?, gossip_timestamp=?, gossip_key=? WHERE addr=?;");
|
||||
sqlite3_bind_int64(stmt, 1, ths->m_last_seen);
|
||||
sqlite3_bind_int64(stmt, 2, ths->m_last_seen_autocrypt);
|
||||
sqlite3_bind_int64(stmt, 3, ths->m_prefer_encrypt);
|
||||
sqlite3_bind_blob (stmt, 4, ths->m_public_key->m_binary, ths->m_public_key->m_bytes, SQLITE_STATIC);
|
||||
sqlite3_bind_text (stmt, 5, ths->m_addr, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_blob (stmt, 4, ths->m_public_key? ths->m_public_key->m_binary : NULL/*results in sqlite3_bind_null()*/, ths->m_public_key? ths->m_public_key->m_bytes : 0, SQLITE_STATIC);
|
||||
sqlite3_bind_int64(stmt, 5, ths->m_gossip_timestamp);
|
||||
sqlite3_bind_blob (stmt, 6, ths->m_gossip_key? ths->m_gossip_key->m_binary : NULL/*results in sqlite3_bind_null()*/, ths->m_gossip_key? ths->m_gossip_key->m_bytes : 0, SQLITE_STATIC);
|
||||
sqlite3_bind_text (stmt, 7, ths->m_addr, -1, SQLITE_STATIC);
|
||||
if( sqlite3_step(stmt) != SQLITE_DONE ) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -142,8 +162,6 @@ mrapeerstate_t* mrapeerstate_new()
|
|||
exit(43); /* cannot allocate little memory, unrecoverable error */
|
||||
}
|
||||
|
||||
ths->m_public_key = mrkey_new();
|
||||
|
||||
return ths;
|
||||
}
|
||||
|
||||
|
@ -156,6 +174,7 @@ void mrapeerstate_unref(mrapeerstate_t* ths)
|
|||
|
||||
free(ths->m_addr);
|
||||
mrkey_unref(ths->m_public_key);
|
||||
mrkey_unref(ths->m_gossip_key);
|
||||
free(ths);
|
||||
}
|
||||
|
||||
|
@ -167,7 +186,7 @@ char* mrapeerstate_render_gossip_header(mrapeerstate_t* peerstate)
|
|||
|
||||
autocryptheader->m_prefer_encrypt = MRA_PE_NOPREFERENCE; /* the spec says, we SHOULD NOT gossip this flag */
|
||||
autocryptheader->m_addr = safe_strdup(peerstate->m_addr);
|
||||
autocryptheader->m_public_key = mrkey_ref(peerstate->m_public_key);
|
||||
autocryptheader->m_public_key = mrkey_ref(peerstate->m_public_key? peerstate->m_public_key : peerstate->m_gossip_key); /* may be NULL */
|
||||
|
||||
ret = mraheader_render(autocryptheader);
|
||||
|
||||
|
@ -193,7 +212,10 @@ int mrapeerstate_init_from_header(mrapeerstate_t* ths, const mraheader_t* header
|
|||
ths->m_last_seen_autocrypt = message_time;
|
||||
ths->m_to_save = MRA_SAVE_ALL;
|
||||
ths->m_prefer_encrypt = header->m_prefer_encrypt;
|
||||
|
||||
ths->m_public_key = mrkey_new();
|
||||
mrkey_set_from_key(ths->m_public_key, header->m_public_key);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -233,6 +255,10 @@ int mrapeerstate_apply_header(mrapeerstate_t* ths, const mraheader_t* header, ti
|
|||
ths->m_to_save |= MRA_SAVE_ALL;
|
||||
}
|
||||
|
||||
if( ths->m_public_key == NULL ) {
|
||||
ths->m_public_key = mrkey_new();
|
||||
}
|
||||
|
||||
if( !mrkey_equals(ths->m_public_key, header->m_public_key) )
|
||||
{
|
||||
mrkey_set_from_key(ths->m_public_key, header->m_public_key);
|
||||
|
|
|
@ -47,10 +47,14 @@ typedef struct mrapeerstate_t
|
|||
/** @privatesection */
|
||||
char* m_addr;
|
||||
time_t m_last_seen;
|
||||
|
||||
time_t m_last_seen_autocrypt;
|
||||
mrkey_t* m_public_key; /*!=NULL*/
|
||||
mrkey_t* m_public_key; /* may be NULL */
|
||||
int m_prefer_encrypt;
|
||||
|
||||
time_t m_gossip_timestamp;
|
||||
mrkey_t* m_gossip_key; /* may be NULL */
|
||||
|
||||
#define MRA_SAVE_LAST_SEEN 0x01
|
||||
#define MRA_SAVE_ALL 0x02
|
||||
int m_to_save;
|
||||
|
|
|
@ -4855,7 +4855,7 @@ char* mrmailbox_get_contact_encrinfo(mrmailbox_t* mailbox, uint32_t contact_id)
|
|||
if( e2ee_enabled
|
||||
&& peerstate_ok
|
||||
&& peerstate->m_prefer_encrypt==MRA_PE_MUTUAL
|
||||
&& peerstate->m_public_key->m_binary!=NULL )
|
||||
&& peerstate->m_public_key!=NULL )
|
||||
{
|
||||
/* e2e fine and used */
|
||||
p = mrstock_str(MR_STR_ENCR_E2E); mrstrbuilder_cat(&ret, p); free(p);
|
||||
|
@ -4875,7 +4875,7 @@ char* mrmailbox_get_contact_encrinfo(mrmailbox_t* mailbox, uint32_t contact_id)
|
|||
}
|
||||
|
||||
/* ... and then explain why we cannot use e2e */
|
||||
if( peerstate_ok && peerstate->m_public_key->m_binary!=NULL && peerstate->m_prefer_encrypt!=MRA_PE_MUTUAL ) {
|
||||
if( peerstate_ok && peerstate->m_public_key && peerstate->m_prefer_encrypt!=MRA_PE_MUTUAL ) {
|
||||
explain_id = MR_STR_E2E_DIS_BY_RCPT;
|
||||
}
|
||||
else if( !e2ee_enabled ) {
|
||||
|
@ -4888,7 +4888,7 @@ char* mrmailbox_get_contact_encrinfo(mrmailbox_t* mailbox, uint32_t contact_id)
|
|||
|
||||
/* show fingerprints for comparison (sorted by email-address to make a device-side-by-side comparison easier) */
|
||||
if( peerstate_ok
|
||||
&& peerstate->m_public_key->m_binary!=NULL )
|
||||
&& peerstate->m_public_key )
|
||||
{
|
||||
if( self_key->m_binary == NULL ) {
|
||||
mrpgp_rand_seed(mailbox, peerstate->m_addr, strlen(peerstate->m_addr) /*just some random data*/);
|
||||
|
|
|
@ -366,6 +366,7 @@ void mrmailbox_e2ee_encrypt(mrmailbox_t* mailbox, const clist* recipients_addr,
|
|||
const char* recipient_addr = clist_content(iter1);
|
||||
mrapeerstate_t* peerstate = mrapeerstate_new();
|
||||
if( mrapeerstate_load_from_db__(peerstate, mailbox->m_sql, recipient_addr)
|
||||
&& peerstate->m_public_key
|
||||
&& peerstate->m_public_key->m_binary!=NULL
|
||||
&& peerstate->m_public_key->m_bytes>0
|
||||
&& (peerstate->m_prefer_encrypt==MRA_PE_MUTUAL || e2ee_guaranteed) )
|
||||
|
@ -747,7 +748,7 @@ int mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_message
|
|||
}
|
||||
|
||||
/* if not yet done, load peer with public key for verification (should be last as the peer may be modified above) */
|
||||
if( peerstate->m_public_key->m_bytes <= 0 ) {
|
||||
if( peerstate->m_last_seen == 0 ) {
|
||||
mrapeerstate_load_from_db__(peerstate, mailbox->m_sql, from);
|
||||
}
|
||||
|
||||
|
@ -758,7 +759,7 @@ int mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_message
|
|||
*ret_validation_errors = 0;
|
||||
int avoid_deadlock = 10;
|
||||
while( avoid_deadlock > 0 ) {
|
||||
if( !decrypt_recursive(mailbox, in_out_message, private_keyring, peerstate->m_public_key->m_bytes>0? peerstate->m_public_key : NULL, ret_validation_errors) ) {
|
||||
if( !decrypt_recursive(mailbox, in_out_message, private_keyring, peerstate->m_public_key, ret_validation_errors) ) {
|
||||
break;
|
||||
}
|
||||
sth_decrypted = 1;
|
||||
|
|
|
@ -331,6 +331,17 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags)
|
|||
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
|
||||
}
|
||||
#undef NEW_DB_VERSION
|
||||
|
||||
#define NEW_DB_VERSION 18
|
||||
if( dbversion < NEW_DB_VERSION )
|
||||
{
|
||||
mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN gossip_timestamp INTEGER DEFAULT 0;");
|
||||
mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN gossip_key;");
|
||||
|
||||
dbversion = NEW_DB_VERSION;
|
||||
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
|
||||
}
|
||||
#undef NEW_DB_VERSION
|
||||
}
|
||||
|
||||
mrmailbox_log_info(ths->m_mailbox, 0, "Opened \"%s\" successfully.", dbfile);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue