merge "default" branch into "keysync" branch and resolve 2 minor merge conflicts. keysync
authorRoker <roker@pep-project.org>
Wed, 10 Aug 2016 16:17:11 +0200
branchkeysync
changeset 100142e0841b71f0
parent 991 b230b6418b52
parent 999 2c9ed75a67af
child 1002 602771124712
merge "default" branch into "keysync" branch and resolve 2 minor merge conflicts.
src/keymanagement.c
src/message_api.c
src/message_api.h
src/mime.c
src/pEpEngine.c
src/pEpEngine.h
src/platform_windows.h
     1.1 --- a/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj	Wed Aug 10 14:12:19 2016 +0200
     1.2 +++ b/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj	Wed Aug 10 16:17:11 2016 +0200
     1.3 @@ -1,5 +1,5 @@
     1.4  <?xml version="1.0" encoding="utf-8"?>
     1.5 -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
     1.6 +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
     1.7    <ItemGroup Label="ProjectConfigurations">
     1.8      <ProjectConfiguration Include="Debug|Win32">
     1.9        <Configuration>Debug</Configuration>
    1.10 @@ -19,13 +19,13 @@
    1.11    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    1.12      <ConfigurationType>StaticLibrary</ConfigurationType>
    1.13      <UseDebugLibraries>true</UseDebugLibraries>
    1.14 -    <PlatformToolset>v120</PlatformToolset>
    1.15 +    <PlatformToolset>v140</PlatformToolset>
    1.16      <CharacterSet>Unicode</CharacterSet>
    1.17    </PropertyGroup>
    1.18    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    1.19      <ConfigurationType>StaticLibrary</ConfigurationType>
    1.20      <UseDebugLibraries>false</UseDebugLibraries>
    1.21 -    <PlatformToolset>v120</PlatformToolset>
    1.22 +    <PlatformToolset>v140</PlatformToolset>
    1.23      <WholeProgramOptimization>true</WholeProgramOptimization>
    1.24      <CharacterSet>Unicode</CharacterSet>
    1.25    </PropertyGroup>
    1.26 @@ -54,6 +54,7 @@
    1.27        <WarningLevel>Level3</WarningLevel>
    1.28        <Optimization>Disabled</Optimization>
    1.29        <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    1.30 +	  <CompileAs>Default</CompileAs>
    1.31      </ClCompile>
    1.32      <Link>
    1.33        <SubSystem>Windows</SubSystem>
     2.1 --- a/db/create_system_db.sql	Wed Aug 10 14:12:19 2016 +0200
     2.2 +++ b/db/create_system_db.sql	Wed Aug 10 16:17:11 2016 +0200
     2.3 @@ -42,6 +42,6 @@
     2.4  INSERT INTO i18n_token VALUES ('ca', 1000, 'Vull mostrar les trustwords en català');
     2.5  
     2.6  INSERT INTO i18n_language VALUES ('tr', 'Türkçe');
     2.7 -INSERT INTO i18n_token VALUES ('tr', 1000, 'Güvenlik kelimelerini Türk dilinde görüntülemek istiyorum.');
     2.8 +INSERT INTO i18n_token VALUES ('tr', 1000, 'Güvenlik kelimelerini Türk dilinde görüntülemek istiyorum');
     2.9  -- add more languages here
    2.10  
     3.1 --- a/pEpEngine.vcxproj	Wed Aug 10 14:12:19 2016 +0200
     3.2 +++ b/pEpEngine.vcxproj	Wed Aug 10 16:17:11 2016 +0200
     3.3 @@ -1,5 +1,5 @@
     3.4  <?xml version="1.0" encoding="utf-8"?>
     3.5 -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
     3.6 +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
     3.7    <ItemGroup Label="ProjectConfigurations">
     3.8      <ProjectConfiguration Include="Debug|Win32">
     3.9        <Configuration>Debug</Configuration>
    3.10 @@ -14,18 +14,19 @@
    3.11      <ProjectGuid>{146E69F8-E1DA-456A-B048-6DD29D9ACF6B}</ProjectGuid>
    3.12      <Keyword>Win32Proj</Keyword>
    3.13      <RootNamespace>pEpEngine</RootNamespace>
    3.14 +	<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
    3.15    </PropertyGroup>
    3.16    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
    3.17    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    3.18      <ConfigurationType>DynamicLibrary</ConfigurationType>
    3.19      <UseDebugLibraries>true</UseDebugLibraries>
    3.20 -    <PlatformToolset>v120</PlatformToolset>
    3.21 +    <PlatformToolset>v140</PlatformToolset>
    3.22      <CharacterSet>Unicode</CharacterSet>
    3.23    </PropertyGroup>
    3.24    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    3.25      <ConfigurationType>DynamicLibrary</ConfigurationType>
    3.26      <UseDebugLibraries>false</UseDebugLibraries>
    3.27 -    <PlatformToolset>v120</PlatformToolset>
    3.28 +    <PlatformToolset>v140</PlatformToolset>
    3.29      <WholeProgramOptimization>true</WholeProgramOptimization>
    3.30      <CharacterSet>Unicode</CharacterSet>
    3.31    </PropertyGroup>
    3.32 @@ -47,7 +48,8 @@
    3.33    </PropertyGroup>
    3.34    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    3.35      <LinkIncremental>false</LinkIncremental>
    3.36 -    <IncludePath>C:\Users\vb\Documents\Visual Studio 2013\Projects\libetpan\build-windows\include;C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath)</IncludePath>
    3.37 +    <IncludePath>$(ProjectDir)\..\libetpan\build-windows\include;C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath)</IncludePath>
    3.38 +    <LibraryPath>$(ProjectDir)\..\libetpan\build-windows\Release;$(LibraryPath)</LibraryPath>
    3.39    </PropertyGroup>
    3.40    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    3.41      <ClCompile>
    3.42 @@ -58,6 +60,7 @@
    3.43        <SDLCheck>true</SDLCheck>
    3.44        <EnablePREfast>false</EnablePREfast>
    3.45        <AdditionalIncludeDirectories>C:\Users\vb\share\asn1c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    3.46 +	  <CompileAs>Default</CompileAs>
    3.47      </ClCompile>
    3.48      <Link>
    3.49        <SubSystem>Windows</SubSystem>
    3.50 @@ -80,6 +83,7 @@
    3.51        <SDLCheck>false</SDLCheck>
    3.52        <TreatWarningAsError>false</TreatWarningAsError>
    3.53        <AdditionalIncludeDirectories>C:\Users\vb\share\asn1c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    3.54 +	  <CompileAs>Default</CompileAs>
    3.55      </ClCompile>
    3.56      <Link>
    3.57        <SubSystem>Windows</SubSystem>
     4.1 --- a/src/message_api.c	Wed Aug 10 14:12:19 2016 +0200
     4.2 +++ b/src/message_api.c	Wed Aug 10 16:17:11 2016 +0200
     4.3 @@ -103,15 +103,20 @@
     4.4      if (longmsg == NULL)
     4.5          longmsg = "";
     4.6  
     4.7 -    size_t bufsize = strlen(shortmsg) + strlen(longmsg) + 12;
     4.8 +    const char * const subject = "Subject: ";
     4.9 +    const size_t SUBJ_LEN = 9;
    4.10 +    const char * const newlines = "\n\n";
    4.11 +    const size_t NL_LEN = 2;
    4.12 +
    4.13 +    size_t bufsize = SUBJ_LEN + strlen(shortmsg) + NL_LEN + strlen(longmsg) + 1;
    4.14      ptext = calloc(1, bufsize);
    4.15      assert(ptext);
    4.16      if (ptext == NULL)
    4.17          return NULL;
    4.18  
    4.19 -    strlcpy(ptext, "Subject: ", bufsize);
    4.20 +    strlcpy(ptext, subject, bufsize);
    4.21      strlcat(ptext, shortmsg, bufsize);
    4.22 -    strlcat(ptext, "\n\n", bufsize);
    4.23 +    strlcat(ptext, newlines, bufsize);
    4.24      strlcat(ptext, longmsg, bufsize);
    4.25  
    4.26      return ptext;
    4.27 @@ -528,12 +533,13 @@
    4.28  
    4.29                      if (_s->filename) {
    4.30                          size_t len = strlen(_s->filename);
    4.31 -                        filename = calloc(1, len + 5);
    4.32 +                        size_t bufsize = len + 5; // length of .pgp extension + NUL
    4.33 +                        filename = calloc(1, bufsize);
    4.34                          if (filename == NULL)
    4.35                              goto enomem;
    4.36  
    4.37 -                        strlcpy(filename, _s->filename, len + 1);
    4.38 -                        strlcpy(filename + len, ".pgp", 5);
    4.39 +                        strlcpy(filename, _s->filename, bufsize);
    4.40 +                        strlcat(filename, ".pgp", bufsize);
    4.41                      }
    4.42                      else {
    4.43                          filename = calloc(1, 20);
    4.44 @@ -623,7 +629,7 @@
    4.45      case PEP_rating_b0rken:
    4.46          return "b0rken";
    4.47      case PEP_rating_under_attack:
    4.48 -        return "unter_attack";
    4.49 +        return "under_attack";
    4.50      default:
    4.51          return "undefined";
    4.52      }
    4.53 @@ -637,7 +643,7 @@
    4.54  {
    4.55      assert(msg);
    4.56  
    4.57 -    add_opt_field(msg, "X-pEp-Version", "1.0");
    4.58 +    add_opt_field(msg, "X-pEp-Version", PEP_VERSION);
    4.59      
    4.60      if (color != PEP_rating_undefined)
    4.61          add_opt_field(msg, "X-EncStatus", color_to_string(color));
    4.62 @@ -1206,6 +1212,103 @@
    4.63      return status;
    4.64  }
    4.65  
    4.66 +DYNAMIC_API PEP_STATUS encrypt_message_for_self(
    4.67 +        PEP_SESSION session,
    4.68 +        pEp_identity* target_id,
    4.69 +        message *src,
    4.70 +        message **dst,
    4.71 +        PEP_enc_format enc_format
    4.72 +    )
    4.73 +{
    4.74 +    PEP_STATUS status = PEP_STATUS_OK;
    4.75 +    message * msg = NULL;
    4.76 +    stringlist_t * keys = NULL;
    4.77 +
    4.78 +    assert(session);
    4.79 +    assert(src);
    4.80 +    assert(dst);
    4.81 +    assert(enc_format != PEP_enc_none);
    4.82 +
    4.83 +    if (!(session && src && dst && enc_format != PEP_enc_none))
    4.84 +        return PEP_ILLEGAL_VALUE;
    4.85 +
    4.86 +    if (src->dir == PEP_dir_incoming)
    4.87 +        return PEP_ILLEGAL_VALUE;
    4.88 +    
    4.89 +    determine_encryption_format(src);
    4.90 +    if (src->enc_format != PEP_enc_none)
    4.91 +        return PEP_ILLEGAL_VALUE;
    4.92 +
    4.93 +    status = myself(session, target_id);
    4.94 +    if (status != PEP_STATUS_OK)
    4.95 +        goto pep_error;
    4.96 +
    4.97 +    *dst = NULL;
    4.98 +
    4.99 +    
   4.100 +    PEP_STATUS _status = update_identity(session, target_id);
   4.101 +    if (_status != PEP_STATUS_OK) {
   4.102 +        status = _status;
   4.103 +        goto pep_error;
   4.104 +    }
   4.105 +
   4.106 +    char* target_fpr = target_id->fpr;
   4.107 +    if (!target_fpr)
   4.108 +        return PEP_KEY_NOT_FOUND; // FIXME: Error condition
   4.109 +        
   4.110 +    keys = new_stringlist(target_fpr);
   4.111 +
   4.112 +    
   4.113 +    msg = clone_to_empty_message(src);
   4.114 +    if (msg == NULL)
   4.115 +        goto enomem;
   4.116 +
   4.117 +    switch (enc_format) {
   4.118 +        case PEP_enc_PGP_MIME:
   4.119 +        case PEP_enc_PEP: // BUG: should be implemented extra
   4.120 +            status = encrypt_PGP_MIME(session, src, keys, msg);
   4.121 +            break;
   4.122 +
   4.123 +        case PEP_enc_pieces:
   4.124 +            status = encrypt_PGP_in_pieces(session, src, keys, msg);
   4.125 +            break;
   4.126 +
   4.127 +        /* case PEP_enc_PEP:
   4.128 +            // TODO: implement
   4.129 +            NOT_IMPLEMENTED */
   4.130 +
   4.131 +        default:
   4.132 +            assert(0);
   4.133 +            status = PEP_ILLEGAL_VALUE;
   4.134 +            goto pep_error;
   4.135 +    }
   4.136 +        
   4.137 +    if (status == PEP_OUT_OF_MEMORY)
   4.138 +        goto enomem;
   4.139 +    
   4.140 +    if (status != PEP_STATUS_OK)
   4.141 +        goto pep_error;
   4.142 +
   4.143 +     if (msg && msg->shortmsg == NULL) {
   4.144 +         msg->shortmsg = strdup("pEp");
   4.145 +         assert(msg->shortmsg);
   4.146 +         if (msg->shortmsg == NULL)
   4.147 +             goto enomem;
   4.148 +     }
   4.149 +
   4.150 +    *dst = msg;
   4.151 +    return status;
   4.152 +
   4.153 +enomem:
   4.154 +    status = PEP_OUT_OF_MEMORY;
   4.155 +
   4.156 +pep_error:
   4.157 +    free_stringlist(keys);
   4.158 +    free_message(msg);
   4.159 +
   4.160 +    return status;
   4.161 +}
   4.162 +
   4.163  static bool is_a_pEpmessage(const message *msg)
   4.164  {
   4.165      for (stringpair_list_t *i = msg->opt_fields; i && i->value ; i=i->next) {
   4.166 @@ -1604,8 +1707,8 @@
   4.167      if (!(session && msg && ident))
   4.168          return PEP_ILLEGAL_VALUE;
   4.169  
   4.170 -    message *dst; 
   4.171 -    stringlist_t *keylist;
   4.172 +    message *dst = NULL; 
   4.173 +    stringlist_t *keylist = NULL;
   4.174      PEP_color color;
   4.175      PEP_decrypt_flags_t flags; 
   4.176  
   4.177 @@ -1624,6 +1727,8 @@
   4.178      }
   4.179  
   4.180      free_identity_list(private_il);
   4.181 +    free_stringlist(keylist);
   4.182 +    free_message(dst);
   4.183  
   4.184      return status;
   4.185  
     5.1 --- a/src/message_api.h	Wed Aug 10 14:12:19 2016 +0200
     5.2 +++ b/src/message_api.h	Wed Aug 10 16:17:11 2016 +0200
     5.3 @@ -56,6 +56,39 @@
     5.4          PEP_encrypt_flags_t flags
     5.5      );
     5.6  
     5.7 +// encrypt_message_for_identity() - encrypt message for one particular identity in memory
     5.8 +//                     (to be used, for example, to save message drafts
     5.9 +//                      encrypted with owner ID)
    5.10 +//
    5.11 +//  parameters:
    5.12 +//      session (in)        session handle
    5.13 +//      target_id (in)      self identity this message should be encrypted for
    5.14 +//      src (in)            message to encrypt
    5.15 +//      dst (out)           pointer to new encrypted message or NULL on failure
    5.16 +//      enc_format (in)     encrypted format
    5.17 +//
    5.18 +//  return value:       (FIXME: This may not be correct or complete)
    5.19 +//      PEP_STATUS_OK                   on success
    5.20 +//		PEP_KEY_NOT_FOUND	            at least one of the receipient keys
    5.21 +//		                                could not be found
    5.22 +//		PEP_KEY_HAS_AMBIG_NAME          at least one of the receipient keys has
    5.23 +//		                                an ambiguous name
    5.24 +//		PEP_GET_KEY_FAILED		        cannot retrieve key
    5.25 +//
    5.26 +//	caveat:
    5.27 +//	    the ownership of src remains with the caller
    5.28 +//      the ownership of target_id remains w/ caller            
    5.29 +//	    the ownership of dst goes to the caller
    5.30 +//      message is NOT encrypted for identities other than the target_id (and then,
    5.31 +//          only if the target_id refers to self!)
    5.32 +
    5.33 +DYNAMIC_API PEP_STATUS encrypt_message_for_self(
    5.34 +        PEP_SESSION session,
    5.35 +        pEp_identity* target_id,
    5.36 +        message *src,
    5.37 +        message **dst,
    5.38 +        PEP_enc_format enc_format
    5.39 +    );
    5.40  
    5.41  typedef enum _PEP_color {
    5.42      PEP_rating_undefined = 0,
     6.1 --- a/src/mime.c	Wed Aug 10 14:12:19 2016 +0200
     6.2 +++ b/src/mime.c	Wed Aug 10 16:17:11 2016 +0200
     6.3 @@ -1281,6 +1281,8 @@
     6.4                  }
     6.5                  free(_longmsg);
     6.6                  _longmsg = _text;
     6.7 +                // FIXME: KG - This is where we have the text we want to deal with.
     6.8 +                // Now we need to strip sigs and process them.
     6.9              }
    6.10          }
    6.11      }
     7.1 --- a/src/pEpEngine.c	Wed Aug 10 14:12:19 2016 +0200
     7.2 +++ b/src/pEpEngine.c	Wed Aug 10 16:17:11 2016 +0200
     7.3 @@ -592,6 +592,18 @@
     7.4                  sqlite3_finalize(session->blacklist_is_listed);
     7.5              if (session->blacklist_retrieve)
     7.6                  sqlite3_finalize(session->blacklist_retrieve);
     7.7 +            if (session->own_key_is_listed)
     7.8 +                sqlite3_finalize(session->own_key_is_listed);
     7.9 +            if (session->own_key_retrieve)
    7.10 +                sqlite3_finalize(session->own_key_retrieve);
    7.11 +            if (session->sequence_value1)
    7.12 +                sqlite3_finalize(session->sequence_value1);
    7.13 +            if (session->sequence_value2)
    7.14 +                sqlite3_finalize(session->sequence_value2);
    7.15 +            if (session->set_revoked)
    7.16 +                sqlite3_finalize(session->set_revoked);
    7.17 +            if (session->get_revoked)
    7.18 +                sqlite3_finalize(session->get_revoked);
    7.19  
    7.20              if (session->db)
    7.21                  sqlite3_close_v2(session->db);
     8.1 --- a/src/pEpEngine.h	Wed Aug 10 14:12:19 2016 +0200
     8.2 +++ b/src/pEpEngine.h	Wed Aug 10 16:17:11 2016 +0200
     8.3 @@ -12,7 +12,7 @@
     8.4  #include "stringlist.h"
     8.5  #include "timestamp.h"
     8.6  
     8.7 -#define PEP_VERSION "1.0"
     8.8 +#define PEP_VERSION "1.0" // protocol version
     8.9  
    8.10  #define PEP_OWN_USERID "pEp_own_userId"
    8.11      
     9.1 --- a/src/platform_windows.h	Wed Aug 10 14:12:19 2016 +0200
     9.2 +++ b/src/platform_windows.h	Wed Aug 10 16:17:11 2016 +0200
     9.3 @@ -26,8 +26,10 @@
     9.4  #define strdup(A) _strdup((A))
     9.5  #endif
     9.6  #ifndef snprintf
     9.7 +#if _MSC_VER<1900 // Includes undefined case. This is a check for VS 2015, which throws an error.
     9.8  #define snprintf(...) _snprintf(__VA_ARGS__)
     9.9  #endif
    9.10 +#endif
    9.11  #ifndef strtok_r
    9.12  #define strtok_r(A, B, C) strtok_s((A), (B), (C))
    9.13  #endif
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/test/encrypt_for_identity_test.cc	Wed Aug 10 16:17:11 2016 +0200
    10.3 @@ -0,0 +1,107 @@
    10.4 +#include <stdlib.h>
    10.5 +#include <string.h>
    10.6 +#include "platform.h"
    10.7 +#include <iostream>
    10.8 +#include <fstream>
    10.9 +#include <assert.h>
   10.10 +#include "mime.h"
   10.11 +#include "message_api.h"
   10.12 +
   10.13 +using namespace std;
   10.14 +
   10.15 +int main() {
   10.16 +    cout << "\n*** encrypt_for_identity_test ***\n\n";
   10.17 +
   10.18 +    PEP_SESSION session;
   10.19 +    
   10.20 +    cout << "calling init()\n";
   10.21 +    PEP_STATUS status1 = init(&session);
   10.22 +    assert(status1 == PEP_STATUS_OK);
   10.23 +    assert(session);
   10.24 +    cout << "init() completed.\n";
   10.25 +
   10.26 +    // message_api test code
   10.27 +
   10.28 +    cout << "creating message…\n";
   10.29 +    pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, "Alice Test");
   10.30 +    pEp_identity* bob = new_identity("pep.test.bob@pep-project.org", NULL, "42", "Bob Test");
   10.31 +    alice->me = true;
   10.32 +    identity_list* to_list = new_identity_list(bob); // to bob
   10.33 +    message* outgoing_message = new_message(PEP_dir_outgoing);
   10.34 +    assert(outgoing_message);
   10.35 +    outgoing_message->from = alice;
   10.36 +    outgoing_message->to = to_list;
   10.37 +    outgoing_message->shortmsg = strdup("Greetings, humans!");
   10.38 +    outgoing_message->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
   10.39 +    cout << "message created.\n";
   10.40 +
   10.41 +    char* encoded_text = nullptr;
   10.42 +    PEP_STATUS status = mime_encode_message(outgoing_message, false, &encoded_text);
   10.43 +    assert(status == PEP_STATUS_OK);
   10.44 +    assert(encoded_text);
   10.45 +
   10.46 +    cout << "decrypted:\n\n";
   10.47 +    cout << encoded_text << "\n";
   10.48 +
   10.49 +    free(encoded_text);
   10.50 +
   10.51 +    cout << "encrypting message as MIME multipart…\n";
   10.52 +    message* encrypted_msg = nullptr;
   10.53 +    cout << "calling encrypt_message_for_identity()\n";
   10.54 +    status = encrypt_message_for_self(session, alice, outgoing_message, &encrypted_msg, PEP_enc_PGP_MIME);
   10.55 +    cout << "encrypt_message() returns " << std::hex << status << '.' << endl;
   10.56 +    assert(status == PEP_STATUS_OK);
   10.57 +    assert(encrypted_msg);
   10.58 +    cout << "message encrypted.\n";
   10.59 +    
   10.60 +    status = mime_encode_message(encrypted_msg, false, &encoded_text);
   10.61 +    assert(status == PEP_STATUS_OK);
   10.62 +    assert(encoded_text);
   10.63 +
   10.64 +    cout << "encrypted:\n\n";
   10.65 +    cout << encoded_text << "\n";
   10.66 +
   10.67 +    message* decoded_msg = nullptr;
   10.68 +    status = mime_decode_message(encoded_text, strlen(encoded_text), &decoded_msg);
   10.69 +    assert(status == PEP_STATUS_OK);
   10.70 +    const string string3 = encoded_text;
   10.71 +
   10.72 +    unlink("msg_encrypt_for_self.asc");
   10.73 +    ofstream outFile3("msg_encrypt_for_self.asc");
   10.74 +    outFile3.write(string3.c_str(), string3.size());
   10.75 +    outFile3.close();
   10.76 +
   10.77 +    message* decrypted_msg = nullptr;
   10.78 +    stringlist_t* keylist_used = nullptr;
   10.79 +
   10.80 +    PEP_color color;
   10.81 +    PEP_decrypt_flags_t flags;
   10.82 +
   10.83 +    status = decrypt_message(session, encrypted_msg, &decrypted_msg, &keylist_used, &color, &flags);
   10.84 +    assert(status == PEP_STATUS_OK);
   10.85 +    assert(decrypted_msg);
   10.86 +    assert(keylist_used);
   10.87 +    assert(color);
   10.88 +    PEP_comm_type ct = encrypted_msg->from->comm_type;
   10.89 +    assert(ct == PEP_ct_pEp || ct == PEP_ct_pEp_unconfirmed || ct == PEP_ct_OpenPGP || ct == PEP_ct_OpenPGP_unconfirmed );
   10.90 +
   10.91 +    cout << "keys used:\n";
   10.92 +
   10.93 +    for (stringlist_t* kl4 = keylist_used; kl4 && kl4->value; kl4 = kl4->next)
   10.94 +    {
   10.95 +        cout << "\t " << kl4->value << endl;
   10.96 +        assert(strcmp("4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", kl4->value) == 0);
   10.97 +        cout << "Encrypted for Alice! Yay! It worked!" << endl;
   10.98 +    }
   10.99 +    cout << "Encrypted ONLY for Alice! Test passed. Move along. These are not the bugs you are looking for." << endl;
  10.100 + 
  10.101 +    cout << "freeing messages…\n";
  10.102 +    free_message(encrypted_msg);
  10.103 +    free_message(decrypted_msg);
  10.104 +    free_message(outgoing_message);
  10.105 +    cout << "done.\n";
  10.106 +
  10.107 +    cout << "calling release()\n";
  10.108 +    release(session);
  10.109 +    return 0;
  10.110 +}