1
0
Fork 0
mirror of https://github.com/deltachat/deltachat-core.git synced 2025-10-04 10:19:16 +02:00

Prepare cryptographic verification.

This commit is contained in:
B. Petersen 2017-06-24 19:06:05 +02:00
parent be5abc03f7
commit e9357dbef2
5 changed files with 55 additions and 32 deletions

View file

@ -10,6 +10,7 @@
#include "netpgp/signature.h" #include "netpgp/signature.h"
#include "netpgp/readerwriter.h" #include "netpgp/readerwriter.h"
#include "netpgp/validate.h" #include "netpgp/validate.h"
#include "netpgp/netpgpsdk.h"
unsigned rsa_generate_keypair(pgp_key_t *keydata, const int numbits, const unsigned long e, const char *hashalg, const char *cipher); unsigned rsa_generate_keypair(pgp_key_t *keydata, const int numbits, const unsigned long e, const char *hashalg, const char *cipher);
#endif // __NETPGP_EXTRA_H__ #endif // __NETPGP_EXTRA_H__

View file

@ -515,7 +515,7 @@ static int decrypt_part(mrmailbox_t* mailbox, struct mailmime* mime, const mrkey
goto cleanup; goto cleanup;
} }
if( !mrpgp_pk_decrypt(mailbox, decoded_data, decoded_data_bytes, private_keyring, 1, &plain_buf, &plain_bytes) if( !mrpgp_pk_decrypt(mailbox, decoded_data, decoded_data_bytes, private_keyring, NULL, 1, &plain_buf, &plain_bytes)
|| plain_buf==NULL || plain_bytes<=0 ) { || plain_buf==NULL || plain_bytes<=0 ) {
goto cleanup; goto cleanup;
} }

View file

@ -427,10 +427,14 @@ cleanup:
******************************************************************************/ ******************************************************************************/
int mrpgp_pk_encrypt( mrmailbox_t* mailbox, int mrpgp_pk_encrypt( mrmailbox_t* mailbox,
const void* plain_text, size_t plain_bytes, const void* plain_text,
const mrkeyring_t* raw_keys, const mrkey_t* sign_key, int use_armor, size_t plain_bytes,
void** ret_ctext, size_t* ret_ctext_bytes) const mrkeyring_t* raw_public_keys_for_encryption,
const mrkey_t* raw_private_key_for_signing,
int use_armor,
void** ret_ctext,
size_t* ret_ctext_bytes)
{ {
pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t)); pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t));
pgp_keyring_t* private_keys = calloc(1, sizeof(pgp_keyring_t)); pgp_keyring_t* private_keys = calloc(1, sizeof(pgp_keyring_t));
@ -440,7 +444,7 @@ int mrpgp_pk_encrypt( mrmailbox_t* mailbox,
int i, success = 0; int i, success = 0;
if( mailbox==NULL || plain_text==NULL || plain_bytes==0 || ret_ctext==NULL || ret_ctext_bytes==NULL if( mailbox==NULL || plain_text==NULL || plain_bytes==0 || ret_ctext==NULL || ret_ctext_bytes==NULL
|| raw_keys==NULL || raw_keys->m_count<=0 || raw_public_keys_for_encryption==NULL || raw_public_keys_for_encryption->m_count<=0
|| keysmem==NULL || public_keys==NULL || private_keys==NULL || dummy_keys==NULL ) { || keysmem==NULL || public_keys==NULL || private_keys==NULL || dummy_keys==NULL ) {
goto cleanup; goto cleanup;
} }
@ -449,8 +453,8 @@ int mrpgp_pk_encrypt( mrmailbox_t* mailbox,
*ret_ctext_bytes = 0; *ret_ctext_bytes = 0;
/* setup keys (the keys may come from pgp_filter_keys_fileread(), see also pgp_keyring_add(rcpts, key)) */ /* setup keys (the keys may come from pgp_filter_keys_fileread(), see also pgp_keyring_add(rcpts, key)) */
for( i = 0; i < raw_keys->m_count; i++ ) { for( i = 0; i < raw_public_keys_for_encryption->m_count; i++ ) {
pgp_memory_add(keysmem, raw_keys->m_keys[i]->m_binary, raw_keys->m_keys[i]->m_bytes); pgp_memory_add(keysmem, raw_public_keys_for_encryption->m_keys[i]->m_binary, raw_public_keys_for_encryption->m_keys[i]->m_bytes);
} }
pgp_filter_keys_from_mem(&s_io, public_keys, private_keys/*should stay empty*/, NULL, 0, keysmem); pgp_filter_keys_from_mem(&s_io, public_keys, private_keys/*should stay empty*/, NULL, 0, keysmem);
@ -465,9 +469,9 @@ int mrpgp_pk_encrypt( mrmailbox_t* mailbox,
size_t signed_bytes = 0; size_t signed_bytes = 0;
int encrypt_raw_packet = 0; int encrypt_raw_packet = 0;
if( sign_key ) { if( raw_private_key_for_signing ) {
pgp_memory_clear(keysmem); pgp_memory_clear(keysmem);
pgp_memory_add(keysmem, sign_key->m_binary, sign_key->m_bytes); pgp_memory_add(keysmem, raw_private_key_for_signing->m_binary, raw_private_key_for_signing->m_bytes);
pgp_filter_keys_from_mem(&s_io, dummy_keys, private_keys, NULL, 0, keysmem); pgp_filter_keys_from_mem(&s_io, dummy_keys, private_keys, NULL, 0, keysmem);
if( private_keys->keyc <= 0 ) { if( private_keys->keyc <= 0 ) {
mrmailbox_log_warning(mailbox, 0, "No key for signing found."); mrmailbox_log_warning(mailbox, 0, "No key for signing found.");
@ -512,20 +516,27 @@ cleanup:
} }
int mrpgp_pk_decrypt( mrmailbox_t* mailbox, int mrpgp_pk_decrypt( mrmailbox_t* mailbox,
const void* ctext, size_t ctext_bytes, const void* ctext,
const mrkeyring_t* raw_keys, size_t ctext_bytes,
int use_armor, const mrkeyring_t* raw_private_keys_for_decryption,
void** ret_plain, size_t* ret_plain_bytes) const mrkey_t* raw_public_key_for_validation,
int use_armor,
void** ret_plain,
size_t* ret_plain_bytes)
{ {
pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t)); /*should be 0 after parsing*/ pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t)); /*should be 0 after parsing*/
pgp_keyring_t* private_keys = calloc(1, sizeof(pgp_keyring_t)); pgp_keyring_t* private_keys = calloc(1, sizeof(pgp_keyring_t));
pgp_memory_t *keysmem = pgp_memory_new(); pgp_keyring_t* dummy_keys = calloc(1, sizeof(pgp_keyring_t));
int i, success = 0; pgp_validation_t* vresult = calloc(1, sizeof(pgp_validation_t));
key_id_t* recipients_key_ids = NULL;
unsigned recipients_count = 0;
pgp_memory_t* keysmem = pgp_memory_new();
int i, success = 0;
if( mailbox==NULL || ctext==NULL || ctext_bytes==0 || ret_plain==NULL || ret_plain_bytes==NULL if( mailbox==NULL || ctext==NULL || ctext_bytes==0 || ret_plain==NULL || ret_plain_bytes==NULL
|| raw_keys==NULL || raw_keys->m_count<=0 || raw_private_keys_for_decryption==NULL || raw_private_keys_for_decryption->m_count<=0
|| keysmem==NULL || public_keys==NULL || private_keys==NULL ) { || vresult==NULL || keysmem==NULL || public_keys==NULL || private_keys==NULL ) {
goto cleanup; goto cleanup;
} }
@ -533,20 +544,26 @@ int mrpgp_pk_decrypt( mrmailbox_t* mailbox,
*ret_plain_bytes = 0; *ret_plain_bytes = 0;
/* setup keys (the keys may come from pgp_filter_keys_fileread(), see also pgp_keyring_add(rcpts, key)) */ /* setup keys (the keys may come from pgp_filter_keys_fileread(), see also pgp_keyring_add(rcpts, key)) */
for( i = 0; i < raw_keys->m_count; i++ ) { for( i = 0; i < raw_private_keys_for_decryption->m_count; i++ ) {
pgp_memory_add(keysmem, raw_keys->m_keys[i]->m_binary, raw_keys->m_keys[i]->m_bytes); pgp_memory_add(keysmem, raw_private_keys_for_decryption->m_keys[i]->m_binary, raw_private_keys_for_decryption->m_keys[i]->m_bytes);
} }
pgp_filter_keys_from_mem(&s_io, public_keys, private_keys/*should stay empty*/, NULL, 0, keysmem); pgp_filter_keys_from_mem(&s_io, dummy_keys/*should stay empty*/, private_keys, NULL, 0, keysmem);
if( private_keys->keyc<=0 ) { if( private_keys->keyc<=0 ) {
mrmailbox_log_warning(mailbox, 0, "Decryption-keyring contains unexpected data (%i/%i)", public_keys->keyc, private_keys->keyc); mrmailbox_log_warning(mailbox, 0, "Decryption-keyring contains unexpected data (%i/%i)", public_keys->keyc, private_keys->keyc);
goto cleanup; goto cleanup;
} }
if( raw_public_key_for_validation ) {
pgp_memory_clear(keysmem);
pgp_memory_add(keysmem, raw_public_key_for_validation->m_binary, raw_public_key_for_validation->m_bytes);
pgp_filter_keys_from_mem(&s_io, public_keys, dummy_keys/*should stay empty*/, NULL, 0, keysmem);
}
/* decrypt */ /* decrypt */
{ {
pgp_memory_t* outmem = pgp_decrypt_buf(&s_io, ctext, ctext_bytes, private_keys, public_keys, pgp_memory_t* outmem = pgp_decrypt_and_validate_buf(&s_io, vresult, ctext, ctext_bytes, private_keys, public_keys,
use_armor, 0/*sshkeys*/, NULL/*passfp*/, 0/*numtries*/, NULL/*getpassfunc*/); use_armor, &recipients_key_ids, &recipients_count);
if( outmem == NULL ) { if( outmem == NULL ) {
mrmailbox_log_warning(mailbox, 0, "Decryption failed."); mrmailbox_log_warning(mailbox, 0, "Decryption failed.");
goto cleanup; goto cleanup;
@ -554,13 +571,18 @@ int mrpgp_pk_decrypt( mrmailbox_t* mailbox,
*ret_plain = outmem->buf; *ret_plain = outmem->buf;
*ret_plain_bytes = outmem->length; *ret_plain_bytes = outmem->length;
free(outmem); /* do not use pgp_memory_free() as we took ownership of the buffer */ free(outmem); /* do not use pgp_memory_free() as we took ownership of the buffer */
// TODO: check vresult
} }
success = 1; success = 1;
cleanup: cleanup:
if( keysmem ) { pgp_memory_free(keysmem); } if( keysmem ) { pgp_memory_free(keysmem); }
if( public_keys ) { pgp_keyring_purge(public_keys); free(public_keys); } /*pgp_keyring_free() frees the content, not the pointer itself*/ if( public_keys ) { pgp_keyring_purge(public_keys); free(public_keys); } /*pgp_keyring_free() frees the content, not the pointer itself*/
if( private_keys ) { pgp_keyring_purge(private_keys); free(private_keys); } if( private_keys ) { pgp_keyring_purge(private_keys); free(private_keys); }
if( dummy_keys ) { pgp_keyring_purge(dummy_keys); free(dummy_keys); }
if( vresult ) { pgp_validate_result_free(vresult); }
if( recipients_key_ids ) { free(recipients_key_ids); }
return success; return success;
} }

View file

@ -52,7 +52,7 @@ int mrpgp_calc_fingerprint (mrmailbox_t*, const mrkey_t*, uint8_t** fingerprint
int mrpgp_split_key (mrmailbox_t*, const mrkey_t* private_in, mrkey_t* public_out); int mrpgp_split_key (mrmailbox_t*, const mrkey_t* private_in, mrkey_t* public_out);
int mrpgp_pk_encrypt (mrmailbox_t*, const void* plain, size_t plain_bytes, const mrkeyring_t*, const mrkey_t* sign_key, int use_armor, void** ret_ctext, size_t* ret_ctext_bytes); int mrpgp_pk_encrypt (mrmailbox_t*, const void* plain, size_t plain_bytes, const mrkeyring_t*, const mrkey_t* sign_key, int use_armor, void** ret_ctext, size_t* ret_ctext_bytes);
int mrpgp_pk_decrypt (mrmailbox_t*, const void* ctext, size_t ctext_bytes, const mrkeyring_t*, int use_armor, void** plain, size_t* plain_bytes); int mrpgp_pk_decrypt (mrmailbox_t*, const void* ctext, size_t ctext_bytes, const mrkeyring_t*, const mrkey_t* validate_key, int use_armor, void** plain, size_t* plain_bytes);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -242,7 +242,7 @@ void stress_functions(mrmailbox_t* mailbox)
mrkeyring_t* keyring = mrkeyring_new(); mrkeyring_t* keyring = mrkeyring_new();
mrkeyring_add(keyring, private_key); mrkeyring_add(keyring, private_key);
void* plain = NULL; void* plain = NULL;
int ok = mrpgp_pk_decrypt(mailbox, ctext, ctext_bytes, keyring, 1, &plain, &plain_bytes); int ok = mrpgp_pk_decrypt(mailbox, ctext, ctext_bytes, keyring, public_key/*for verify*/, 1, &plain, &plain_bytes);
assert( ok && plain && plain_bytes>0 ); assert( ok && plain && plain_bytes>0 );
assert( strncmp((char*)plain, original_text, strlen(original_text))==0 ); assert( strncmp((char*)plain, original_text, strlen(original_text))==0 );
mrkeyring_unref(keyring); mrkeyring_unref(keyring);
@ -253,7 +253,7 @@ void stress_functions(mrmailbox_t* mailbox)
mrkeyring_t* keyring = mrkeyring_new(); mrkeyring_t* keyring = mrkeyring_new();
mrkeyring_add(keyring, private_key2); mrkeyring_add(keyring, private_key2);
void* plain = NULL; void* plain = NULL;
int ok = mrpgp_pk_decrypt(mailbox, ctext, ctext_bytes, keyring, 1, &plain, &plain_bytes); int ok = mrpgp_pk_decrypt(mailbox, ctext, ctext_bytes, keyring, public_key/*for verify*/, 1, &plain, &plain_bytes);
assert( ok && plain && plain_bytes>0 ); assert( ok && plain && plain_bytes>0 );
assert( strcmp(plain, original_text)==0 ); assert( strcmp(plain, original_text)==0 );
mrkeyring_unref(keyring); mrkeyring_unref(keyring);