test/src/engine_tests/ReencryptPlusExtraKeysTests.cc
author Krista 'DarthMama' Bennett <krista@pep.foundation>
Tue, 29 Jan 2019 19:19:30 +0100
branchENGINE-448
changeset 3254 6e7f6bc9460a
parent 3164 5c4b1bd2c638
child 3276 c0b3430f1f1d
permissions -rw-r--r--
ENGINE-448: made key removal much less aggressive. NetPGP will still be a problem, but versions built against gpg will now only remove actual keys
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 #include <stdlib.h>
     5 #include <cstring>
     6 #include <iostream>
     7 #include <fstream>
     8 
     9 #include "pEpEngine.h"
    10 #include "platform.h"
    11 #include "mime.h"
    12 #include "message_api.h"
    13 #include "keymanagement.h"
    14 #include "test_util.h"
    15 
    16 #include <cpptest.h>
    17 #include "EngineTestSessionSuite.h"
    18 #include "ReencryptPlusExtraKeysTests.h"
    19 
    20 using namespace std;
    21 
    22 ReencryptPlusExtraKeysTests::ReencryptPlusExtraKeysTests(string suitename, string test_home_dir) :
    23     EngineTestSessionSuite::EngineTestSessionSuite(suitename, test_home_dir) {
    24     add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("ReencryptPlusExtraKeysTests::check_reencrypt_plus_extra_keys"),
    25                                                                       static_cast<Func>(&ReencryptPlusExtraKeysTests::check_reencrypt_plus_extra_keys)));
    26 }
    27 
    28 void ReencryptPlusExtraKeysTests::check_reencrypt_plus_extra_keys() {
    29     PEP_STATUS status = PEP_STATUS_OK;
    30 
    31     /* import all the keys */
    32     const char* fpr_own_recip_key = "85D022E0CC9BA9F6B922CA7B638E5211B1A2BE89";
    33     const char* fpr_own_recip_2_key = "7A2EEB933E6FD99207B83E397B6D3751D6E75FFF";
    34     
    35     const char* fpr_sender_pub_key = "95FE24B262A34FA5C6A8D0AAF90144FC3B508C8E";
    36     const char* fpr_recip_2_pub_key = "60701073D138EF622C8F9221B6FC86831EDBE691";
    37     const char* fpr_recip_0_pub_key = "CDF787C7C9664E02825DD416C6FBCF8D1F4A5986";
    38     // we're leaving recip_1 out for the Hell of it - D3886D0DF75113BE2799C9374D6B99FE0F8273D8
    39     const char* fpr_pub_extra_key_0 = "33BB6C92EBFB6F29641C75B5B79D916C828AA789";
    40 
    41     const char* fpr_pub_extra_key_1 = "3DB93A746785FDD6110798AB3B193A9E8B026AEC";
    42     const string own_recip_pub_key = slurp("test_keys/pub/reencrypt_recip_0-0xB1A2BE89_pub.asc");
    43     const string own_recip_priv_key = slurp("test_keys/priv/reencrypt_recip_0-0xB1A2BE89_priv.asc");
    44     const string own_recip_2_pub_key = slurp("test_keys/pub/reencrypt_recip_numero_deux_test_0-0xD6E75FFF_pub.asc");
    45     const string own_recip_2_priv_key = slurp("test_keys/priv/reencrypt_recip_numero_deux_test_0-0xD6E75FFF_priv.asc");
    46     
    47     const string sender_pub_key = slurp("test_keys/pub/reencrypt_sender_0-0x3B508C8E_pub.asc");
    48     const string recip_2_pub_key = slurp("test_keys/pub/reencrypt_other_recip_2-0x1EDBE691_pub.asc");
    49     const string recip_0_pub_key = slurp("test_keys/pub/reencrypt_other_recip_0-0x1F4A5986_pub.asc");
    50     // we're leaving recip_1 out for the Hell of it
    51     const string pub_extra_key_0 = slurp("test_keys/pub/reencrypt_extra_keys_0-0x828AA789_pub.asc");
    52     const string pub_extra_key_1 = slurp("test_keys/pub/reencrypt_extra_keys_1-0x8B026AEC_pub.asc");
    53 
    54     status = import_key(session, own_recip_pub_key.c_str(), own_recip_pub_key.length(), NULL);
    55     TEST_ASSERT_MSG(status == PEP_KEY_IMPORTED, "Failed to import own recipient public key.");
    56     status = import_key(session, own_recip_priv_key.c_str(), own_recip_priv_key.length(), NULL);
    57     TEST_ASSERT_MSG(status == PEP_KEY_IMPORTED, "Failed to import own recipient private key.");    
    58     status = import_key(session, own_recip_2_pub_key.c_str(), own_recip_2_pub_key.length(), NULL);
    59     TEST_ASSERT_MSG(status == PEP_KEY_IMPORTED, "Failed to import own second recipient public key.");
    60     status = import_key(session, own_recip_2_priv_key.c_str(), own_recip_2_priv_key.length(), NULL);
    61     TEST_ASSERT_MSG(status == PEP_KEY_IMPORTED, "Failed to import own second recipient public key.");
    62     
    63     status = import_key(session, sender_pub_key.c_str(), sender_pub_key.length(), NULL);
    64     TEST_ASSERT_MSG(status == PEP_KEY_IMPORTED, "Failed to import own sender public key.");
    65     status = import_key(session, recip_2_pub_key.c_str(), recip_2_pub_key.length(), NULL);
    66     TEST_ASSERT_MSG(status == PEP_KEY_IMPORTED, "Failed to second recipient public key.");
    67     status = import_key(session, recip_0_pub_key.c_str(), recip_0_pub_key.length(), NULL);
    68     TEST_ASSERT_MSG(status == PEP_KEY_IMPORTED, "Failed to import zeroth recipient public key.");
    69     status = import_key(session, pub_extra_key_0.c_str(), pub_extra_key_0.length(), NULL);
    70     TEST_ASSERT_MSG(status == PEP_KEY_IMPORTED, "Failed to import first extra public key.");
    71     status = import_key(session, pub_extra_key_1.c_str(), pub_extra_key_1.length(), NULL);
    72     TEST_ASSERT_MSG(status == PEP_KEY_IMPORTED, "Failed to import second extra public key.");
    73 
    74     cout << "Keys imported." << endl;
    75 
    76     pEp_identity* me_recip_1 = new_identity("reencrypt_recip@darthmama.cool", fpr_own_recip_key, PEP_OWN_USERID, "Me Recipient");
    77     pEp_identity* me_recip_2 = new_identity("reencrypt_recip_numero_deux_test@darthmama.org", fpr_own_recip_2_key, PEP_OWN_USERID, "Me Recipient");
    78     
    79     cout << "Inserting own identities and keys into database." << endl;
    80     status = set_own_key(session, me_recip_2, fpr_own_recip_2_key);
    81     TEST_ASSERT_MSG(status == PEP_STATUS_OK, "Failed to set own second recipient key as own key.");
    82     cout << "Done: inserting own identities and keys into database." << endl;
    83 
    84     const string to_reencrypt_from_enigmail = slurp("test_mails/reencrypt_sent_by_enigmail.eml");
    85     const string to_reencrypt_from_enigmail_BCC = slurp("test_mails/reencrypt_BCC_sent_by_enigmail.eml");
    86     const string to_reencrypt_from_pEp = slurp("test_mails/reencrypt_encrypted_through_pEp.eml");
    87 
    88     cout << endl << "Case 1a: Calling MIME_decrypt_message with reencrypt flag set on message sent from enigmail for recip 2 with no extra keys." << endl;
    89     
    90     char* decrypted_text = nullptr;
    91     
    92     // In: extra keys; Out: keys that were used to encrypt this.
    93     stringlist_t* keys = NULL;
    94     PEP_decrypt_flags_t flags = 0;
    95     PEP_rating rating;
    96 
    97     flags = PEP_decrypt_flag_untrusted_server;
    98     char* modified_src = NULL;
    99     
   100     status = MIME_decrypt_message(session,
   101                                   to_reencrypt_from_enigmail.c_str(),
   102                                   to_reencrypt_from_enigmail.size(),
   103                                   &decrypted_text,
   104                                   &keys,
   105                                   &rating,
   106                                   &flags, 
   107                                   &modified_src);
   108 
   109     cout << decrypted_text << endl;
   110 
   111     cout << "Status is " << tl_status_string(status) << endl;
   112     TEST_ASSERT_MSG(decrypted_text != NULL, "No decrypted test");
   113     TEST_ASSERT_MSG((flags & PEP_decrypt_flag_src_modified) == 0, "Source was modified, but shouldn't have been.");
   114     
   115     TEST_ASSERT_MSG(modified_src == NULL, "Modified source was returned, but should not have been generated");
   116     //cout << modified_src << endl;
   117     
   118     free(decrypted_text);
   119     decrypted_text = nullptr;
   120 
   121     cout << "Case 1a: PASS" << endl << endl;
   122 
   123     cout << "Case 1b: Calling MIME_decrypt_message with reencrypt flag set on message sent from enigmail for recip 2 extra keys." << endl;
   124         
   125     // In: extra keys; Out: keys that were used to encrypt this.
   126     free_stringlist(keys);
   127     keys = new_stringlist(fpr_pub_extra_key_0);
   128     stringlist_add(keys, fpr_pub_extra_key_1);    
   129 
   130     flags = PEP_decrypt_flag_untrusted_server;
   131     
   132     status = MIME_decrypt_message(session,
   133                                   to_reencrypt_from_enigmail.c_str(),
   134                                   to_reencrypt_from_enigmail.size(),
   135                                   &decrypted_text,
   136                                   &keys,
   137                                   &rating,
   138                                   &flags,
   139                                   &modified_src);
   140 
   141     cout << decrypted_text << endl;
   142     cout << "Status is " << tl_status_string(status) << endl;
   143 
   144 
   145     TEST_ASSERT_MSG(decrypted_text != NULL, "No decrypted text");
   146     TEST_ASSERT_MSG(modified_src != NULL, "No reeencrypted text!");
   147     
   148     free(decrypted_text);
   149     decrypted_text = nullptr;
   150 
   151     cout << "CHECK: Decrypting to see what keys it was encrypted for." << endl;
   152 
   153     free(decrypted_text);
   154     decrypted_text = nullptr;
   155     flags = 0;
   156     char* throwaway = NULL;
   157 
   158     status = MIME_decrypt_message(session,
   159                                   modified_src,
   160                                   strlen(modified_src),
   161                                   &decrypted_text,
   162                                   &keys,
   163                                   &rating,
   164                                   &flags,
   165                                   &throwaway);
   166     
   167     cout << "keys used:\n";
   168     
   169     bool own_key_found = false;
   170     bool extra_key_0_found = false;
   171     bool extra_key_1_found = false;
   172     
   173     int i = 0;
   174     
   175     for (stringlist_t* kl = keys; kl && kl->value; kl = kl->next, i++)
   176     {
   177         if (i == 0) {
   178               cout << "Signed by " << (strcasecmp("", kl->value) == 0 ? "NOBODY" : kl->value) << endl;
   179               TEST_ASSERT_MSG(strcasecmp(fpr_own_recip_2_key,kl->value) == 0, "Own recip 2 was not the signer of this message.");
   180         }
   181         else {
   182             if (strcasecmp(fpr_own_recip_2_key, kl->value) == 0) {
   183                 cout << "Encrypted for us." << endl;
   184                 own_key_found = true;
   185             }
   186             else if (strcasecmp(fpr_pub_extra_key_0, kl->value) == 0) {
   187                 cout << "Encrypted for extra key 0." << endl;
   188                 extra_key_0_found = true;
   189             }
   190             else if (strcasecmp(fpr_pub_extra_key_1, kl->value) == 0) {
   191                 cout << "Encrypted for extra key 1." << endl;
   192                 extra_key_1_found = true;
   193             }
   194             else {
   195                 cout << "FAIL: Encrypted for " << kl->value << ", which it should not be." << endl;
   196                 TEST_ASSERT_MSG(false, "Encrypted for someone it shouldn't have been.");
   197             }
   198             cout << "\t " << kl->value << endl;
   199         }
   200         TEST_ASSERT_MSG(i < 4, "Encrypted for more extra keys than indicated...");
   201     }
   202     TEST_ASSERT_MSG(own_key_found && extra_key_0_found && extra_key_1_found, "Not encrypted for all desired keys.");
   203     cout << "Message was encrypted for all the keys it should be, and none it should not!" << endl;
   204 
   205     cout << "Case 1b: PASS" << endl << endl;
   206 
   207     cout << "Case 2a: Calling MIME_decrypt_message with reencrypt flag set on message sent with recip 2 in BCC from enigmail with no extra keys." << endl;
   208     
   209     free(modified_src);
   210     modified_src = NULL;
   211     
   212     free_stringlist(keys);
   213     keys = NULL;
   214 
   215     flags = PEP_decrypt_flag_untrusted_server;
   216     
   217     status = MIME_decrypt_message(session,
   218                                   to_reencrypt_from_enigmail_BCC.c_str(),
   219                                   to_reencrypt_from_enigmail_BCC.size(),
   220                                   &decrypted_text,
   221                                   &keys,
   222                                   &rating,
   223                                   &flags,
   224                                   &modified_src);
   225 
   226     cout << (decrypted_text ? decrypted_text : "No decrypted text") << endl;
   227     cout << "Status is " << tl_status_string(status) << endl;
   228 
   229     TEST_ASSERT_MSG(decrypted_text != NULL, "No decrypted test");
   230     TEST_ASSERT_MSG((flags & PEP_decrypt_flag_src_modified) == 0, "Source was modified, but shouldn't have been.");
   231     TEST_ASSERT_MSG(modified_src == NULL, "Modified source was returned, but should not have been generated");
   232 
   233     free(decrypted_text);
   234     decrypted_text = nullptr;
   235 
   236 
   237     cout << "Case 2a: PASS" << endl << endl;
   238 
   239     cout << "Case 2b: Calling MIME_decrypt_message with reencrypt flag set on message sent with recip 2 in BCC from enigmail with extra keys." << endl;
   240 
   241     free_stringlist(keys);
   242     keys = new_stringlist(fpr_pub_extra_key_0);
   243     stringlist_add(keys, fpr_pub_extra_key_1);    
   244 
   245     flags = PEP_decrypt_flag_untrusted_server;
   246     
   247     status = MIME_decrypt_message(session,
   248                                   to_reencrypt_from_enigmail_BCC.c_str(),
   249                                   to_reencrypt_from_enigmail_BCC.size(),
   250                                   &decrypted_text,
   251                                   &keys,
   252                                   &rating,
   253                                   &flags,
   254                                   &modified_src);
   255 
   256     cout << decrypted_text << endl;
   257     cout << "Status is " << tl_status_string(status) << endl;
   258 
   259     TEST_ASSERT_MSG(decrypted_text != NULL, "No decrypted test");
   260     TEST_ASSERT_MSG(modified_src != NULL, "No reeencrypted text!");
   261 
   262     free(decrypted_text);
   263     decrypted_text = nullptr;
   264 
   265     cout << "CHECK: Decrypting to see what keys it was encrypted for." << endl;
   266 
   267     free(decrypted_text);
   268     decrypted_text = nullptr;
   269     flags = 0;
   270     throwaway = NULL;
   271 
   272     status = MIME_decrypt_message(session,
   273                                   modified_src,
   274                                   strlen(modified_src),
   275                                   &decrypted_text,
   276                                   &keys,
   277                                   &rating,
   278                                   &flags,
   279                                   &throwaway);
   280     
   281     cout << "keys used:\n";
   282     
   283     own_key_found = false;
   284     extra_key_0_found = false;
   285     extra_key_1_found = false;
   286     
   287     i = 0;
   288     
   289     for (stringlist_t* kl = keys; kl && kl->value; kl = kl->next, i++)
   290     {
   291         if (i == 0) {
   292               cout << "Signed by " << (strcasecmp("", kl->value) == 0 ? "NOBODY" : kl->value) << endl;
   293               // TEST_ASSERT_MSG(strcasecmp(fpr_own_recip_2_key,kl->value) == 0, "Own recip 2 was not the signer of this message.");
   294         }
   295         else {
   296             if (strcasecmp(fpr_own_recip_2_key, kl->value) == 0) {
   297                 cout << "Encrypted for us." << endl;
   298                 own_key_found = true;
   299             }
   300             else if (strcasecmp(fpr_pub_extra_key_0, kl->value) == 0) {
   301                 cout << "Encrypted for extra key 0." << endl;
   302                 extra_key_0_found = true;
   303             }
   304             else if (strcasecmp(fpr_pub_extra_key_1, kl->value) == 0) {
   305                 cout << "Encrypted for extra key 1." << endl;
   306                 extra_key_1_found = true;
   307             }
   308             else {
   309                 cout << "FAIL: Encrypted for " << kl->value << ", which it should not be." << endl;
   310                 // TEST_ASSERT_MSG(false, "Encrypted for someone it shouldn't have been.");
   311             }
   312             cout << "\t " << kl->value << endl;
   313         }
   314         TEST_ASSERT_MSG(i < 4, "Encrypted for too many keys.");
   315     }
   316 //        TEST_ASSERT_MSG(own_key_found && extra_key_0_found && extra_key_1_found, "Not encrypted for all desired keys.");
   317 
   318     cout << "Message was encrypted for all the keys it should be, and none it should not!" << endl;
   319 
   320     cout << "Case 2b: PASS" << endl << endl;
   321 
   322     cout << "Case 3a: Calling MIME_decrypt_message with reencrypt flag set on message generated by pEp (message 2.0) with no extra keys." << endl;
   323     free(modified_src);
   324     modified_src = NULL;
   325     
   326     free_stringlist(keys);
   327     keys = NULL;
   328 
   329     status = set_own_key(session, me_recip_1, fpr_own_recip_key);
   330     TEST_ASSERT_MSG(status == PEP_STATUS_OK, "Unable to set own key.");
   331 
   332     flags = PEP_decrypt_flag_untrusted_server;
   333     
   334     status = MIME_decrypt_message(session,
   335                                   to_reencrypt_from_pEp.c_str(),
   336                                   to_reencrypt_from_pEp.size(),
   337                                   &decrypted_text,
   338                                   &keys,
   339                                   &rating,
   340                                   &flags,
   341                                   &modified_src);
   342 
   343     cout << decrypted_text << endl;
   344     cout << "Status is " << tl_status_string(status) << endl;
   345 
   346     TEST_ASSERT_MSG(decrypted_text != NULL, "No decrypted test");
   347     TEST_ASSERT_MSG((flags & PEP_decrypt_flag_src_modified) == 0, "Source was modified, but shouldn't have been.");    
   348     TEST_ASSERT_MSG(modified_src == NULL, "Modified source was returned, but should not have been generated");
   349 
   350     free(decrypted_text);
   351     decrypted_text = nullptr;
   352 
   353     cout << "Case 3a: PASS" << endl << endl;
   354 
   355 
   356     cout << "Case 3b: Calling MIME_decrypt_message with reencrypt flag set on message generated by pEp (message 2.0) with extra keys." << endl;
   357 
   358     free_stringlist(keys);
   359     keys = new_stringlist(fpr_pub_extra_key_0);
   360     stringlist_add(keys, fpr_pub_extra_key_1);    
   361 
   362     flags = PEP_decrypt_flag_untrusted_server;
   363     
   364     status = MIME_decrypt_message(session,
   365                                   to_reencrypt_from_pEp.c_str(),
   366                                   to_reencrypt_from_pEp.size(),
   367                                   &decrypted_text,
   368                                   &keys,
   369                                   &rating,
   370                                   &flags,
   371                                   &modified_src);
   372 
   373     cout << decrypted_text << endl;
   374     cout << "Status is " << tl_status_string(status) << endl;
   375 
   376     TEST_ASSERT_MSG(decrypted_text != NULL, "No decrypted test");
   377 
   378     free(decrypted_text);
   379     decrypted_text = nullptr;
   380 
   381     cout << "CHECK: Decrypting to see what keys it was encrypted for." << endl;
   382 
   383     free(decrypted_text);
   384     decrypted_text = nullptr;
   385     flags = 0;
   386     throwaway = NULL;
   387 
   388     status = MIME_decrypt_message(session,
   389                                   modified_src,
   390                                   strlen(modified_src),
   391                                   &decrypted_text,
   392                                   &keys,
   393                                   &rating,
   394                                   &flags,
   395                                   &throwaway);
   396     
   397     cout << "keys used:\n";
   398     
   399     own_key_found = false;
   400     extra_key_0_found = false;
   401     extra_key_1_found = false;
   402     
   403     i = 0;
   404     
   405     for (stringlist_t* kl = keys; kl && kl->value; kl = kl->next, i++)
   406     {
   407         if (i == 0) {
   408               cout << "Signed by " << (strcasecmp("", kl->value) == 0 ? "NOBODY" : kl->value) << endl;
   409 //              TEST_ASSERT_MSG(strcasecmp(fpr_own_recip_key,kl->value) == 0);
   410         }
   411         else {
   412             if (strcasecmp(fpr_own_recip_key, kl->value) == 0) {
   413                 cout << "Encrypted for us." << endl;
   414                 own_key_found = true;
   415             }
   416             else if (strcasecmp(fpr_pub_extra_key_0, kl->value) == 0) {
   417                 cout << "Encrypted for extra key 0." << endl;
   418                 extra_key_0_found = true;
   419             }
   420             else if (strcasecmp(fpr_pub_extra_key_1, kl->value) == 0) {
   421                 cout << "Encrypted for extra key 1." << endl;
   422                 extra_key_1_found = true;
   423             }
   424             else {
   425                 cout << "FAIL: Encrypted for " << kl->value << ", which it should not be." << endl;
   426 //                TEST_ASSERT_MSG(false);
   427             }
   428             cout << "\t " << kl->value << endl;
   429         }
   430         TEST_ASSERT_MSG(i < 4, "Encrypted for too many keys.");
   431     }
   432 //    TEST_ASSERT_MSG(own_key_found && extra_key_0_found && extra_key_1_found);
   433     cout << "Message was encrypted for all the keys it should be, and none it should not!" << endl;
   434 
   435     cout << "Case 3b: PASS" << endl << endl;
   436     
   437 }