@ -0,0 +1,98 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<ItemGroup Label="ProjectConfigurations"> | |||
<ProjectConfiguration Include="Debug|Win32"> | |||
<Configuration>Debug</Configuration> | |||
<Platform>Win32</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Release|Win32"> | |||
<Configuration>Release</Configuration> | |||
<Platform>Win32</Platform> | |||
</ProjectConfiguration> | |||
</ItemGroup> | |||
<PropertyGroup Label="Globals"> | |||
<ProjectGuid>{146E69F8-E1DA-456A-B048-6DD29D9ACF6B}</ProjectGuid> | |||
<Keyword>Win32Proj</Keyword> | |||
<RootNamespace>pEpEngine</RootNamespace> | |||
</PropertyGroup> | |||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | |||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
<PlatformToolset>v120</PlatformToolset> | |||
<CharacterSet>Unicode</CharacterSet> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | |||
<ConfigurationType>DynamicLibrary</ConfigurationType> | |||
<UseDebugLibraries>false</UseDebugLibraries> | |||
<PlatformToolset>v120</PlatformToolset> | |||
<WholeProgramOptimization>true</WholeProgramOptimization> | |||
<CharacterSet>Unicode</CharacterSet> | |||
</PropertyGroup> | |||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | |||
<ImportGroup Label="ExtensionSettings"> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<PropertyGroup Label="UserMacros" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||
<LinkIncremental>true</LinkIncremental> | |||
<IncludePath>C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath)</IncludePath> | |||
<RunCodeAnalysis>true</RunCodeAnalysis> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||
<LinkIncremental>false</LinkIncremental> | |||
<IncludePath>C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath)</IncludePath> | |||
</PropertyGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||
<ClCompile> | |||
<PrecompiledHeader>NotUsing</PrecompiledHeader> | |||
<WarningLevel>Level3</WarningLevel> | |||
<Optimization>Disabled</Optimization> | |||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PEPENGINE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||
<SDLCheck>true</SDLCheck> | |||
<EnablePREfast>true</EnablePREfast> | |||
</ClCompile> | |||
<Link> | |||
<SubSystem>Windows</SubSystem> | |||
<GenerateDebugInformation>true</GenerateDebugInformation> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||
<ClCompile> | |||
<WarningLevel>Level3</WarningLevel> | |||
<PrecompiledHeader>NotUsing</PrecompiledHeader> | |||
<Optimization>MaxSpeed</Optimization> | |||
<FunctionLevelLinking>true</FunctionLevelLinking> | |||
<IntrinsicFunctions>true</IntrinsicFunctions> | |||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PEPENGINE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||
<SDLCheck>false</SDLCheck> | |||
<TreatWarningAsError>false</TreatWarningAsError> | |||
</ClCompile> | |||
<Link> | |||
<SubSystem>Windows</SubSystem> | |||
<GenerateDebugInformation>true</GenerateDebugInformation> | |||
<EnableCOMDATFolding>true</EnableCOMDATFolding> | |||
<OptimizeReferences>true</OptimizeReferences> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemGroup> | |||
<ClCompile Include="src\keymanagement.c" /> | |||
<ClCompile Include="src\pEpEngine.c" /> | |||
<ClCompile Include="src\platform_windows.cpp" /> | |||
<ClCompile Include="src\sqlite3.c" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ClInclude Include="src\keymanagement.h" /> | |||
<ClInclude Include="src\pEpEngine.h" /> | |||
<ClInclude Include="src\platform_windows.h" /> | |||
<ClInclude Include="src\sqlite3.h" /> | |||
</ItemGroup> | |||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | |||
<ImportGroup Label="ExtensionTargets"> | |||
</ImportGroup> | |||
</Project> |
@ -0,0 +1,45 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<ItemGroup> | |||
<Filter Include="Quelldateien"> | |||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> | |||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> | |||
</Filter> | |||
<Filter Include="Headerdateien"> | |||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> | |||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> | |||
</Filter> | |||
<Filter Include="Ressourcendateien"> | |||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> | |||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> | |||
</Filter> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ClCompile Include="src\keymanagement.c"> | |||
<Filter>Quelldateien</Filter> | |||
</ClCompile> | |||
<ClCompile Include="src\pEpEngine.c"> | |||
<Filter>Quelldateien</Filter> | |||
</ClCompile> | |||
<ClCompile Include="src\platform_windows.cpp"> | |||
<Filter>Quelldateien</Filter> | |||
</ClCompile> | |||
<ClCompile Include="src\sqlite3.c"> | |||
<Filter>Quelldateien</Filter> | |||
</ClCompile> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ClInclude Include="src\keymanagement.h"> | |||
<Filter>Headerdateien</Filter> | |||
</ClInclude> | |||
<ClInclude Include="src\pEpEngine.h"> | |||
<Filter>Headerdateien</Filter> | |||
</ClInclude> | |||
<ClInclude Include="src\platform_windows.h"> | |||
<Filter>Headerdateien</Filter> | |||
</ClInclude> | |||
<ClInclude Include="src\sqlite3.h"> | |||
<Filter>Headerdateien</Filter> | |||
</ClInclude> | |||
</ItemGroup> | |||
</Project> |
@ -0,0 +1,210 @@ | |||
#ifndef WIN32 // UNIX | |||
#define _POSIX_C_SOURCE 200809L | |||
#else | |||
#include "platform_windows.h" | |||
#endif | |||
#include <string.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <assert.h> | |||
#define _EXPORT_PEP_ENGINE_DLL | |||
#include "pEpEngine.h" | |||
#include "keymanagement.h" | |||
#ifndef MIN | |||
#define MIN(A, B) ((B) > (A) ? (A) : (B)) | |||
#endif | |||
DYNAMIC_API PEP_STATUS update_identity( | |||
PEP_SESSION session, pEp_identity * identity | |||
) | |||
{ | |||
pEp_identity *stored_identity; | |||
PEP_STATUS status; | |||
bool bDirty; | |||
assert(session); | |||
assert(identity); | |||
assert(identity->address); | |||
status = get_identity(session, identity->address, &stored_identity); | |||
assert(status != PEP_OUT_OF_MEMORY); | |||
if (status == PEP_OUT_OF_MEMORY) | |||
return PEP_OUT_OF_MEMORY; | |||
if (stored_identity) { | |||
if (identity->username == NULL || identity->username[0] == 0) { | |||
free(identity->username); | |||
identity->username = strdup(stored_identity->username); | |||
} | |||
if (identity->user_id == NULL || identity->user_id[0] == 0) { | |||
free(identity->user_id); | |||
identity->user_id = strdup(stored_identity->user_id); | |||
} | |||
if (identity->fpr != NULL && identity->fpr[0] != 0) { | |||
if (strcmp(identity->fpr, stored_identity->fpr) != 0) | |||
identity->comm_type = PEP_ct_unknown; | |||
} | |||
} | |||
else | |||
identity->comm_type = PEP_ct_unknown; | |||
status = set_identity(session, identity); | |||
return PEP_STATUS_OK; | |||
} | |||
DYNAMIC_API PEP_STATUS outgoing_comm_type( | |||
PEP_SESSION session, | |||
const stringlist_t *addresses, | |||
PEP_comm_type *comm_type | |||
) | |||
{ | |||
int i; | |||
const stringlist_t *l; | |||
assert(session); | |||
assert(addresses); | |||
assert(addresses->value); | |||
assert(comm_type); | |||
*comm_type = PEP_ct_unknown; | |||
for (l=addresses; l && l->value; l = l->next) { | |||
PEP_STATUS _status; | |||
pEp_identity *identity; | |||
_status = get_identity(session, l->value, &identity); | |||
assert(_status != PEP_OUT_OF_MEMORY); | |||
if (identity == NULL) { | |||
*comm_type = PEP_ct_no_encryption; | |||
return PEP_STATUS_OK; | |||
} | |||
else if (identity->comm_type == PEP_ct_unknown) { | |||
*comm_type = PEP_ct_no_encryption; | |||
free_identity(identity); | |||
return PEP_STATUS_OK; | |||
} | |||
else if (*comm_type == PEP_ct_unknown) { | |||
*comm_type = identity->comm_type; | |||
} | |||
else if (*comm_type != identity->comm_type) { | |||
PEP_comm_type min = MIN(*comm_type, identity->comm_type); | |||
if (min < PEP_ct_unconfirmed_encryption) { | |||
*comm_type = PEP_ct_no_encryption; | |||
free_identity(identity); | |||
return PEP_STATUS_OK; | |||
} | |||
else if (min < PEP_ct_unconfirmed_enc_anon) | |||
*comm_type = PEP_ct_unconfirmed_encryption; | |||
else if (min < PEP_ct_confirmed_encryption) | |||
*comm_type = PEP_ct_unconfirmed_enc_anon; | |||
else if (min < PEP_ct_confirmed_enc_anon) | |||
*comm_type = PEP_ct_confirmed_encryption; | |||
else | |||
*comm_type = PEP_ct_confirmed_enc_anon; | |||
} | |||
free_identity(identity); | |||
} | |||
return PEP_STATUS_OK; | |||
} | |||
DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity) | |||
{ | |||
PEP_STATUS status; | |||
stringlist_t *keylist; | |||
assert(session); | |||
assert(identity); | |||
assert(identity->address); | |||
assert(identity->username); | |||
assert(identity->user_id); | |||
identity->comm_type = PEP_ct_pEp; | |||
identity->me = true; | |||
pEp_identity *_identity; | |||
log_event(session, "myself", "debug", identity->address, NULL); | |||
status = get_identity(session, identity->address, &_identity); | |||
assert(status != PEP_OUT_OF_MEMORY); | |||
if (status == PEP_OUT_OF_MEMORY) | |||
return PEP_OUT_OF_MEMORY; | |||
status = find_keys(session, identity->address, &keylist); | |||
assert(status != PEP_OUT_OF_MEMORY); | |||
if (status == PEP_OUT_OF_MEMORY) | |||
return PEP_OUT_OF_MEMORY; | |||
if (keylist == NULL || keylist->value == NULL) { | |||
log_event(session, "generating key pair", "debug", identity->address, NULL); | |||
status = generate_keypair(session, identity); | |||
assert(status != PEP_OUT_OF_MEMORY); | |||
if (status != PEP_STATUS_OK) { | |||
char buf[11]; | |||
snprintf(buf, 11, "%d", status); | |||
log_event(session, "generating key pair failed", "debug", buf, NULL); | |||
return status; | |||
} | |||
status = find_keys(session, identity->address, &keylist); | |||
assert(status != PEP_OUT_OF_MEMORY); | |||
if (status == PEP_OUT_OF_MEMORY) | |||
return PEP_OUT_OF_MEMORY; | |||
assert(keylist); | |||
} | |||
if (identity->fpr) | |||
free(identity->fpr); | |||
identity->fpr = strdup(keylist->value); | |||
assert(identity->fpr); | |||
free_stringlist(keylist); | |||
if (identity->fpr == NULL) | |||
return PEP_OUT_OF_MEMORY; | |||
status = set_identity(session, identity); | |||
assert(status == PEP_STATUS_OK); | |||
return PEP_STATUS_OK; | |||
} | |||
DYNAMIC_API PEP_STATUS do_keymanagement( | |||
retrieve_next_identity_t retrieve_next_identity, | |||
void *management | |||
) | |||
{ | |||
PEP_SESSION session; | |||
pEp_identity *identity; | |||
PEP_STATUS status = init(&session); | |||
assert(status == PEP_STATUS_OK); | |||
if (status != PEP_STATUS_OK) | |||
return status; | |||
log_event(session, "keymanagement thread started", "pEp engine", NULL, NULL); | |||
while (identity = retrieve_next_identity(management)) { | |||
assert(identity->address); | |||
log_event(session, "do_keymanagement", "debug", identity->address, NULL); | |||
if (identity->me) { | |||
status = myself(session, identity); | |||
assert(status != PEP_OUT_OF_MEMORY); | |||
} else { | |||
status = recv_key(session, identity->address); | |||
assert(status != PEP_OUT_OF_MEMORY); | |||
} | |||
free_identity(identity); | |||
} | |||
log_event(session, "keymanagement thread shutdown", "pEp engine", NULL, NULL); | |||
release(session); | |||
return PEP_STATUS_OK; | |||
} | |||
@ -0,0 +1,103 @@ | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
// update_identity() - update identity information | |||
// | |||
// parameters: | |||
// session (in) session to use | |||
// identity (inout) identity information of communication partner | |||
// | |||
// caveat: | |||
// if this function returns PEP_ct_unknown in identity->comm_type, the | |||
// caller must insert the identity into the asynchronous management | |||
// implementation, so retrieve_next_identity() will return this identity | |||
// later | |||
// at least identity->address must be a valid C string as input | |||
DYNAMIC_API PEP_STATUS update_identity( | |||
PEP_SESSION session, pEp_identity * identity | |||
); | |||
// outgoing_comm_type() - minimum comm_type for a list of addresses | |||
// | |||
// parameters: | |||
// session (in) session to use | |||
// addresses (in) list of addresses | |||
// comm_type (out) comm_type which can be used to communicate with | |||
// addresses | |||
DYNAMIC_API PEP_STATUS outgoing_comm_type( | |||
PEP_SESSION session, | |||
const stringlist_t *addresses, | |||
PEP_comm_type *comm_type | |||
); | |||
// myself() - ensures that the own identity is being complete | |||
// | |||
// parameters: | |||
// session (in) session to use | |||
// identity (inout) identity of local user | |||
// at least .address, .username, .user_id must be set | |||
// | |||
// return value: | |||
// PEP_STATUS_OK if identity could be completed or was already complete, | |||
// any other value on error | |||
// | |||
// caveat: | |||
// this function generates a keypair on demand; because it's synchronous | |||
// it can need a decent amount of time to return | |||
// if you need to do this asynchronous, you need to return an identity | |||
// with retrieve_next_identity() where pEp_identity.me is true | |||
DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity); | |||
// retrieve_next_identity() - callback being called by do_keymanagement() | |||
// | |||
// parameters: | |||
// management (in) data structure to deliver (implementation defined) | |||
// | |||
// return value: | |||
// identity to check or NULL to terminate do_keymanagement() | |||
// if given identity must be created with new_identity() | |||
// the identity struct is going to the ownership of this library | |||
// it must not be freed by the callee | |||
// | |||
// caveat: | |||
// this callback has to block until an identity or NULL can be returned | |||
// an implementation is not provided by this library; instead it has to be | |||
// implemented by the user of this library | |||
typedef pEp_identity *(*retrieve_next_identity_t)(void *management); | |||
// do_keymanagement() - function to be run on an extra thread | |||
// | |||
// parameters: | |||
// retrieve_next_identity pointer to retrieve_next_identity() callback | |||
// which returns at least a valid address field in | |||
// the identity struct | |||
// management management data to give to keymanagement | |||
// (implementation defined) | |||
// | |||
// return value: | |||
// PEP_STATUS_OK if thread has to terminate successfully or any other | |||
// value on failure | |||
// | |||
// caveat: | |||
// to ensure proper working of this library, a thread has to be started | |||
// with this function immediately after initialization | |||
// do_keymanagement() calls retrieve_next_identity(management) | |||
DYNAMIC_API PEP_STATUS do_keymanagement( | |||
retrieve_next_identity_t retrieve_next_identity, | |||
void *management | |||
); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
@ -0,0 +1,583 @@ | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
#include <stdint.h> | |||
#include <stdbool.h> | |||
#ifdef WIN32 | |||
#ifdef _EXPORT_PEP_ENGINE_DLL | |||
#define DYNAMIC_API __declspec(dllexport) | |||
#else | |||
#define DYNAMIC_API __declspec(dllimport) | |||
#endif | |||
#else | |||
#define DYNAMIC_API | |||
#endif | |||
// pEp Engine API | |||
// caveat: | |||
// Unicode data has to be normalized to NFC before calling | |||
// UTF-8 strings are UTF-8 encoded C strings (zero terminated) | |||
typedef void * PEP_SESSION; | |||
typedef enum { | |||
PEP_STATUS_OK = 0, | |||
PEP_INIT_CANNOT_LOAD_GPGME = 0x0110, | |||
PEP_INIT_GPGME_INIT_FAILED = 0x0111, | |||
PEP_INIT_SQLITE3_WITHOUT_MUTEX = 0x0120, | |||
PEP_INIT_CANNOT_OPEN_DB = 0x0121, | |||
PEP_INIT_CANNOT_OPEN_SYSTEM_DB = 0x0122, | |||
PEP_KEY_NOT_FOUND = 0x0201, | |||
PEP_KEY_HAS_AMBIG_NAME = 0x0202, | |||
PEP_GET_KEY_FAILED = 0x0203, | |||
PEP_CANNOT_FIND_IDENTITY = 0x0301, | |||
PEP_CANNOT_SET_PERSON = 0x0381, | |||
PEP_CANNOT_SET_PGP_KEYPAIR = 0x0382, | |||
PEP_CANNOT_SET_IDENTITY = 0x0383, | |||
PEP_UNENCRYPTED = 0x0400, | |||
PEP_VERIFIED = 0x0401, | |||
PEP_DECRYPTED = 0x0402, | |||
PEP_DECRYPTED_AND_VERIFIED = 0x0403, | |||
PEP_DECRYPT_WRONG_FORMAT = 0x0404, | |||
PEP_DECRYPT_NO_KEY = 0x0405, | |||
PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH = 0x0406, | |||
PEP_VERIFY_NO_KEY = 0x0407, | |||
PEP_VERIFIED_AND_TRUSTED = 0x0408, | |||
PEP_CANNOT_DECRYPT_UNKNOWN = 0x04ff, | |||
PEP_SAFEWORD_NOT_FOUND = 0x0501, | |||
PEP_CANNOT_CREATE_KEY = 0x0601, | |||
PEP_CANNOT_SEND_KEY = 0x0602, | |||
PEP_COMMIT_FAILED = 0xff01, | |||
PEP_ILLEGAL_VALUE = -4, | |||
PEP_BUFFER_TOO_SMALL = -3, | |||
PEP_OUT_OF_MEMORY = -2, | |||
PEP_UNKNOWN_ERROR = -1 | |||
} PEP_STATUS; | |||
// INIT_STATUS init() - initialize pEpEngine for a thread | |||
// | |||
// parameters: | |||
// session (out) init() allocates session memory and returns a pointer | |||
// as a handle | |||
// | |||
// return value: | |||
// PEP_STATUS_OK = 0 if init() succeeds | |||
// PEP_INIT_SQLITE3_WITHOUT_MUTEX if SQLite3 was compiled with | |||
// SQLITE_THREADSAFE 0 | |||
// PEP_INIT_CANNOT_LOAD_GPGME if libgpgme.dll cannot be found | |||
// PEP_INIT_GPGME_INIT_FAILED if GPGME init fails | |||
// PEP_INIT_CANNOT_OPEN_DB if user's management db cannot be | |||
// opened | |||
// PEP_INIT_CANNOT_OPEN_SYSTEM_DB if system's management db cannot be | |||
// opened | |||
// | |||
// caveat: | |||
// the pointer is valid only if the return value is PEP_STATUS_OK | |||
// in other case a NULL pointer will be returned; a valid handle must | |||
// be released using release() when it's no longer needed | |||
DYNAMIC_API PEP_STATUS init(PEP_SESSION *session); | |||
// void release() - release thread session handle | |||
// | |||
// parameters: | |||
// session (in) session handle to release | |||
DYNAMIC_API void release(PEP_SESSION session); | |||
typedef struct _stringlist_t { | |||
char *value; | |||
struct _stringlist_t *next; | |||
} stringlist_t; | |||
// new_stringlist() - allocate a new stringlist | |||
// | |||
// parameters: | |||
// value (in) initial value as C string or NULL for empty list | |||
// | |||
// return value: | |||
// pointer to stringlist_t object or NULL if out of memory | |||
// | |||
// caveat: | |||
// the value is being copied before being added to the list | |||
// the original string is still being owned by the caller | |||
DYNAMIC_API stringlist_t *new_stringlist(const char *value); | |||
// stringlist_add() - add key to stringlist | |||
// | |||
// parameters: | |||
// stringlist (in) stringlist struct or NULL to create a new one | |||
// value (in) value as C string | |||
// | |||
// return value: | |||
// pointer to last element in stringlist or NULL if out of memory | |||
// | |||
// caveat: | |||
// the value is being copied before being added to the list | |||
// the original string is still being owned by the caller | |||
DYNAMIC_API stringlist_t *stringlist_add(stringlist_t *stringlist, const char *value); | |||
// stringlist_length() - get length of stringlist | |||
// | |||
// parameters: | |||
// stringlist (in) stringlist struct to determine length of | |||
// | |||
// return value: | |||
// length of stringlist in number of elements | |||
DYNAMIC_API int stringlist_length(const stringlist_t *stringlist); | |||
// free_stringlist() - free memory occupied by stringlist | |||
// | |||
// parameters: | |||
// stringlist (in) stringlist to free | |||
DYNAMIC_API void free_stringlist(stringlist_t *stringlist); | |||
// decrypt_and_verify() - decrypt and/or verify a message | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// ctext (in) cipher text to decrypt and/or verify | |||
// csize (in) size of cipher text | |||
// ptext (out) pointer to internal buffer with plain text | |||
// psize (out) size of plain text | |||
// keylist (out) array of key ids which where used to encrypt or NULL on | |||
// error | |||
// | |||
// return value: | |||
// PEP_UNENCRYPTED message was unencrypted and not signed | |||
// PEP_VERIFIED message was unencrypted, signature matches | |||
// PEP_DECRYPTED message is decrypted now, no signature | |||
// PEP_DECRYPTED_AND_VERIFIED message is decrypted now and verified | |||
// PEP_DECRYPT_WRONG_FORMAT message has wrong format to handle | |||
// PEP_DECRYPT_NO_KEY key not available to decrypt and/or verify | |||
// PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH wrong signature | |||
// | |||
// caveat: | |||
// the ownerships of ptext as well as keylist are going to the caller | |||
// the caller must use free() (or an Windoze pEp_free()) and | |||
// free_stringlist() to free them | |||
DYNAMIC_API PEP_STATUS decrypt_and_verify( | |||
PEP_SESSION session, const char *ctext, size_t csize, | |||
char **ptext, size_t *psize, stringlist_t **keylist | |||
); | |||
// verify_text() - verfy plain text with a digital signature | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// text (in) text to verify | |||
// size (in) size of text | |||
// signature (in) signature text | |||
// sig_size (in) size of signature | |||
// keylist (out) array of key ids which where used to encrypt or NULL on | |||
// error | |||
// | |||
// return value: | |||
// PEP_VERIFIED message was unencrypted, signature matches | |||
// PEP_DECRYPT_NO_KEY key not available to decrypt and/or verify | |||
// PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH wrong signature | |||
DYNAMIC_API PEP_STATUS verify_text( | |||
PEP_SESSION session, const char *text, size_t size, | |||
const char *signature, size_t sig_size, stringlist_t **keylist | |||
); | |||
// encrypt_and_sign() - encrypt and sign a message | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// keylist (in) array of key ids to encrypt with as C strings | |||
// ptext (in) plain text to decrypt and/or verify | |||
// psize (in) size of plain text | |||
// ctext (out) pointer to internal buffer with cipher text | |||
// csize (out) size of cipher text | |||
// | |||
// return value: | |||
// PEP_STATUS_OK = 0 encryption and signing succeeded | |||
// PEP_KEY_NOT_FOUND at least one of the receipient keys | |||
// could not be found | |||
// PEP_KEY_HAS_AMBIG_NAME at least one of the receipient keys has | |||
// an ambiguous name | |||
// PEP_GET_KEY_FAILED cannot retrieve key | |||
// | |||
// caveat: | |||
// the ownership of ctext is going to the caller | |||
// the caller is responsible to free() it (on Windoze use pEp_free()) | |||
DYNAMIC_API PEP_STATUS encrypt_and_sign( | |||
PEP_SESSION session, const stringlist_t *keylist, const char *ptext, | |||
size_t psize, char **ctext, size_t *csize | |||
); | |||
// log_event() - log a user defined event defined by UTF-8 encoded strings into | |||
// management log | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// title (in) C string with event name | |||
// entity (in) C string with name of entity which is logging | |||
// description (in) C string with long description for event or NULL if | |||
// omitted | |||
// comment (in) C string with user defined comment or NULL if | |||
// omitted | |||
// | |||
// return value: | |||
// PEP_STATUS_OK log entry created | |||
DYNAMIC_API PEP_STATUS log_event( | |||
PEP_SESSION session, const char *title, const char *entity, | |||
const char *description, const char *comment | |||
); | |||
// safeword() - get the corresponding safeword for a 16 bit value | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// value (in) value to find a safeword for | |||
// lang (in) C string with ISO 3166-1 ALPHA-2 language code | |||
// word (out) pointer to C string with safeword UTF-8 encoded | |||
// NULL if language is not supported or safeword | |||
// wordlist is damaged or unavailable | |||
// wsize (out) length of safeword | |||
// | |||
// return value: | |||
// PEP_STATUS_OK safeword retrieved | |||
// PEP_SAFEWORD_NOT_FOUND safeword not found | |||
// | |||
// caveat: | |||
// the word pointer goes to the ownership of the caller | |||
// the caller is responsible to free() it (on Windoze use pEp_free()) | |||
DYNAMIC_API PEP_STATUS safeword( | |||
PEP_SESSION session, uint16_t value, const char *lang, | |||
char **word, size_t *wsize | |||
); | |||
// safewords() - get safewords for a string of hex values of a fingerprint | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// fingerprint (in) C string with hex values to find safewords for | |||
// lang (in) C string with ISO 3166-1 ALPHA-2 language code | |||
// words (out) pointer to C string with safewords UTF-8 encoded, | |||
// separated by a blank each | |||
// NULL if language is not supported or safeword | |||
// wordlist is damaged or unavailable | |||
// wsize (out) length of safewords string | |||
// max_words (in) only generate a string with max_words; | |||
// if max_words == 0 there is no such limit | |||
// | |||
// return value: | |||
// PEP_STATUS_OK safewords retrieved | |||
// PEP_OUT_OF_MEMORY out of memory | |||
// PEP_SAFEWORD_NOT_FOUND at least one safeword not found | |||
// | |||
// caveat: | |||
// the word pointer goes to the ownership of the caller | |||
// the caller is responsible to free() it (on Windoze use pEp_free()) | |||
// | |||
// DON'T USE THIS FUNCTION FROM HIGH LEVEL LANGUAGES! | |||
// | |||
// Better implement a simple one in the adapter yourself using safeword(), and | |||
// return a list of safewords. | |||
// This function is provided for being used by C and C++ programs only. | |||
DYNAMIC_API PEP_STATUS safewords( | |||
PEP_SESSION session, const char *fingerprint, const char *lang, | |||
char **words, size_t *wsize, int max_words | |||
); | |||
typedef enum _PEP_comm_type { | |||
PEP_ct_unknown = 0, | |||
// range 0x01 to 0x0f: no encryption or nothing reasonable | |||
PEP_ct_no_encryption = 0x01, // generic | |||
PEP_ct_key_too_short = 0x02, // key too short to talk | |||
// about encryption | |||
PEP_ct_compromized = 0x0f, // known compromized connection | |||
// range 0x10 to 0x3f: unconfirmed encryption | |||
PEP_ct_unconfirmed_encryption = 0x10, // generic | |||
PEP_ct_OpenPGP_1024_RSA_unconfirmed = 0x11, // RSA 1024 is weak | |||
PEP_ct_OpenPGP_unconfirmed = 0x3f, // key at least 2048 bit RSA | |||
// or 1024 bit DSA | |||
// range 0x40 to 0x7f: unconfirmed encryption and anonymization | |||
PEP_ct_unconfirmed_enc_anon = 0x40, // generic | |||
PEP_ct_PEP_unconfirmed = 0x7f, | |||
// range 0x80 to 0x8f: reserved | |||
// range 0x90 to 0xbf: confirmed encryption | |||
PEP_ct_confirmed_encryption = 0x90, // generic | |||
PEP_ct_OpenPGP_1024_RSA = 0x91, // RSA 1024 is weak | |||
PEP_ct_OpenPGP = 0xbf, // key at least 2048 bit RSA or 1024 bit DSA | |||
// range 0xc0 to 0xff: confirmed encryption and anonymization | |||
PEP_ct_confirmed_enc_anon = 0xc0, // generic | |||
PEP_ct_pEp = 0xff | |||
} PEP_comm_type; | |||
typedef struct _pEp_identity { | |||
size_t struct_size; // size of whole struct | |||
char *address; // C string with address UTF-8 encoded | |||
size_t address_size; // size of address | |||
char *fpr; // C string with fingerprint UTF-8 encoded | |||
size_t fpr_size; // size of fingerprint | |||
char *user_id; // C string with user ID UTF-8 encoded | |||
size_t user_id_size; // size of user ID | |||
char *username; // C string with user name UTF-8 encoded | |||
size_t username_size; // size of user name | |||
PEP_comm_type comm_type; // type of communication with this ID | |||
char lang[3]; // language of conversation | |||
// ISO 639-1 ALPHA-2, last byte is 0 | |||
bool me; // if this is the local user herself/himself | |||
} pEp_identity; | |||
// new_identity() - allocate memory and set the string and size fields | |||
// | |||
// parameters: | |||
// address (in) UTF-8 string or NULL | |||
// fpr (in) UTF-8 string or NULL | |||
// user_id (in) UTF-8 string or NULL | |||
// username (in) UTF-8 string or NULL | |||
// | |||
// return value: | |||
// pEp_identity struct with correct size values or NULL if out of memory | |||
// | |||
// caveat: | |||
// the strings are copied; the original strings are still being owned by | |||
// the caller | |||
DYNAMIC_API pEp_identity *new_identity( | |||
const char *address, const char *fpr, const char *user_id, | |||
const char *username | |||
); | |||
// free_identity() - free all memory being occupied by a pEp_identity struct | |||
// | |||
// parameters: | |||
// identity (in) struct to release | |||
// | |||
// caveat: | |||
// not only the struct but also all string memory referenced by the | |||
// struct is being freed; all pointers inside are invalid afterwards | |||
DYNAMIC_API void free_identity(pEp_identity *identity); | |||
// get_identity() - get identity information | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// address (in) C string with communication address, UTF-8 encoded | |||
// identity (out) pointer to pEp_identity structure with results or | |||
// NULL if failure | |||
// | |||
// caveat: | |||
// the address string is being copied; the original string remains in the | |||
// ownership of the caller | |||
// the resulting pEp_identity structure goes to the ownership of the | |||
// caller and has to be freed with free_identity() when not in use any | |||
// more | |||
DYNAMIC_API PEP_STATUS get_identity( | |||
PEP_SESSION session, const char *address, | |||
pEp_identity **identity | |||
); | |||
// set_identity() - set identity information | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// identity (in) pointer to pEp_identity structure | |||
// | |||
// return value: | |||
// PEP_STATUS_OK = 0 encryption and signing succeeded | |||
// PEP_CANNOT_SET_PERSON writing to table person failed | |||
// PEP_CANNOT_SET_PGP_KEYPAIR writing to table pgp_keypair failed | |||
// PEP_CANNOT_SET_IDENTITY writing to table identity failed | |||
// PEP_COMMIT_FAILED SQL commit failed | |||
// | |||
// caveat: | |||
// in the identity structure you need to set the const char * fields to | |||
// UTF-8 C strings | |||
// the size fields are ignored | |||
DYNAMIC_API PEP_STATUS set_identity( | |||
PEP_SESSION session, const pEp_identity *identity | |||
); | |||
// generate_keypair() - generate a new key pair and add it to the key ring | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// identity (inout) pointer to pEp_identity structure | |||
// | |||
// return value: | |||
// PEP_STATUS_OK = 0 encryption and signing succeeded | |||
// PEP_ILLEGAL_VALUE illegal values for identity fields given | |||
// PEP_CANNOT_CREATE_KEY key engine is on strike | |||
// | |||
// caveat: | |||
// address and username fields must be set to UTF-8 strings | |||
// the fpr field must be set to NULL | |||
// | |||
// this function allocates a string and sets set fpr field of identity | |||
// the caller is responsible to call free() for that string or use | |||
// free_identity() on the struct | |||
DYNAMIC_API PEP_STATUS generate_keypair( | |||
PEP_SESSION session, pEp_identity *identity | |||
); | |||
// delete_keypair() - delete a public key or a key pair from the key ring | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// fpr (in) C string with key id or fingerprint of the | |||
// public key | |||
// | |||
// return value: | |||
// PEP_STATUS_OK = 0 key was successfully deleted | |||
// PEP_KEY_NOT_FOUND key not found | |||
// PEP_ILLEGAL_VALUE not a valid key id or fingerprint | |||
// PEP_KEY_HAS_AMBIG_NAME fpr does not uniquely identify a key | |||
// PEP_OUT_OF_MEMORY out of memory | |||
DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr); | |||
// import_key() - import key from data | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// key_data (in) key data, i.e. ASCII armored OpenPGP key | |||
// size (in) amount of data to handle | |||
// | |||
// return value: | |||
// PEP_STATUS_OK = 0 key was successfully imported | |||
// PEP_OUT_OF_MEMORY out of memory | |||
// PEP_ILLEGAL_VALUE there is no key data to import | |||
DYNAMIC_API PEP_STATUS import_key(PEP_SESSION session, const char *key_data, size_t size); | |||
// export_key() - export ascii armored key | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// fpr (in) key id or fingerprint of key | |||
// key_data (out) ASCII armored OpenPGP key | |||
// size (out) amount of data to handle | |||
// | |||
// return value: | |||
// PEP_STATUS_OK = 0 key was successfully exported | |||
// PEP_OUT_OF_MEMORY out of memory | |||
// PEP_KEY_NOT_FOUND key not found | |||
// | |||
// caveat: | |||
// the key_data goes to the ownership of the caller | |||
// the caller is responsible to free() it (on Windoze use pEp_free()) | |||
DYNAMIC_API PEP_STATUS export_key( | |||
PEP_SESSION session, const char *fpr, char **key_data, size_t *size | |||
); | |||
// recv_key() - update key(s) from keyserver | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// pattern (in) key id, user id or address to search for as | |||
// UTF-8 string | |||
DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern); | |||
// find_keys() - find keys in keyring | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// pattern (in) key id, user id or address to search for as | |||
// UTF-8 string | |||
// keylist (out) list of fingerprints found or NULL on error | |||
// | |||
// caveat: | |||
// the ownerships of keylist isgoing to the caller | |||
// the caller must use free_stringlist() to free it | |||
DYNAMIC_API PEP_STATUS find_keys( | |||
PEP_SESSION session, const char *pattern, stringlist_t **keylist | |||
); | |||
// send_key() - send key(s) to keyserver | |||
// | |||
// parameters: | |||
// session (in) session handle | |||
// pattern (in) key id, user id or address to search for as | |||
// UTF-8 string | |||
DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern); | |||
// pEp_free() - free memory allocated by pEp engine | |||
// | |||
// parameters: | |||
// p (in) pointer to free | |||
// | |||
// The reason for this function is that heap management can be a pretty | |||
// complex task with Windoze. This free() version calls the free() | |||
// implementation of the C runtime library which was used to build pEp engine, | |||
// so you're using the correct heap. For more information, see: | |||
// <http://msdn.microsoft.com/en-us/library/windows/desktop/aa366711(v=vs.85).aspx> | |||
DYNAMIC_API void pEp_free(void *p); | |||
#ifdef __cplusplus | |||
} | |||
#endif |
@ -0,0 +1,189 @@ | |||
// Windows platform specifica | |||
#define WIN32_LEAN_AND_MEAN | |||
#ifndef UNICODE | |||
#define UNICODE | |||
#endif | |||
#define _WIN32_WINNT 0x0600 | |||
#include <windows.h> | |||
#include <assert.h> | |||
#include <string> | |||
#include <stdexcept> | |||
#include "platform_windows.h" | |||
#ifndef WC_ERR_INVALID_CHARS | |||
#define WC_ERR_INVALID_CHARS 0x00000080 // error for invalid chars | |||
#endif | |||
using namespace std; | |||
static string utf8_string(wstring wstr) { | |||
string result; | |||
if (wstr.length()) { | |||
int size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, | |||
wstr.c_str(), -1, NULL, 0, NULL, NULL); | |||
assert(size); | |||
if (size) { | |||
char *buf = new char[size]; | |||
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wstr.c_str(), | |||
-1, buf, size, NULL, NULL); | |||
result = buf; | |||
delete[] buf; | |||
} else | |||
throw out_of_range("input wstring is not valid" | |||
" while converting UTF-16 to UTF-8."); | |||
} | |||
return result; | |||
} | |||
static wstring utf16_string(string str) { | |||
wstring result; | |||
if (str.length()) { | |||
int size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, | |||
str.c_str(), -1, NULL, 0); | |||
assert(size); | |||
if (size) { | |||
wchar_t * buf = new wchar_t[size]; | |||
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.c_str(), -1, | |||
buf, size); | |||
result = buf; | |||
delete[] buf; | |||
} else | |||
throw out_of_range("input string is not valid" | |||
" while converting UTF-8 to UTF-16."); | |||
} | |||
return result; | |||
} | |||
static bool readRegistryString( | |||
HKEY hKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, LPTSTR lpResult, | |||
DWORD dwSize, LPCTSTR lpDefault | |||
) | |||
{ | |||
assert(lpResult); | |||
HKEY theKey; | |||
DWORD type; | |||
DWORD bytesCopied = dwSize; | |||
HRESULT result; | |||
result = RegOpenKeyEx(hKey, lpSubKey, 0, KEY_READ, &theKey); | |||
if (result != ERROR_SUCCESS) { | |||
if (lpDefault) { | |||
wcsncpy_s(lpResult, dwSize, lpDefault, _TRUNCATE); | |||
return true; | |||
} | |||
else | |||
return false; | |||
} | |||
result = RegQueryValueEx(theKey, lpValueName, NULL, &type, | |||
(LPBYTE) lpResult, &bytesCopied); | |||
if (result != ERROR_SUCCESS || (type != REG_EXPAND_SZ && type != REG_SZ)) { | |||
if (lpDefault) { | |||
wcsncpy_s(lpResult, dwSize, lpDefault, _TRUNCATE); | |||
RegCloseKey(theKey); | |||
return true; | |||
} | |||
else { | |||
RegCloseKey(theKey); | |||
return false; | |||
} | |||
} | |||
RegCloseKey(theKey); | |||
return true; | |||
} | |||
static const DWORD PATH_BUF_SIZE = 32768; | |||
static inline string managementPath(const char *file_path, const char *file_name) | |||
{ | |||
string path; | |||
static TCHAR tPath[PATH_BUF_SIZE]; | |||
DWORD length = ExpandEnvironmentStringsW(utf16_string(file_path).c_str(), | |||
tPath, PATH_BUF_SIZE); | |||
assert(length); | |||
if (length == 0) | |||
throw bad_alloc(); | |||
CreateDirectory(tPath, NULL); | |||
DWORD error = GetLastError(); | |||
assert(error == 0 || error == ERROR_ALREADY_EXISTS); | |||
path = utf8_string(tPath); | |||
path += "\\"; | |||
path += file_name; | |||
return path; | |||
} | |||
extern "C" { | |||
void *dlopen(const char *filename, int flag) { | |||
static TCHAR path[PATH_BUF_SIZE]; | |||
assert(filename); | |||
assert(flag == RTLD_LAZY); // only lazy binding is implemented | |||
bool result = readRegistryString(HKEY_LOCAL_MACHINE, | |||
TEXT("SOFTWARE\\GNU\\GnuPG"), TEXT("Install Directory"), path, | |||
PATH_BUF_SIZE, NULL); | |||
assert(result); | |||
if (!result) | |||
return NULL; | |||
SetDllDirectory(TEXT("")); | |||
BOOL _result = SetDllDirectory(path); | |||
assert(_result != 0); | |||
if (_result == 0) | |||
return NULL; | |||
HMODULE module = LoadLibrary(utf16_string(filename).c_str()); | |||
SetDllDirectory(NULL); | |||
if (module == NULL) | |||
return NULL; | |||
else | |||
return (void *) module; | |||
} | |||
int dlclose(void *handle) { | |||
if (FreeLibrary((HMODULE) handle)) | |||
return 0; | |||
else | |||
return 1; | |||
} | |||
void *dlsym(void *handle, const char *symbol) { | |||
return (void *) (intptr_t) GetProcAddress((HMODULE) handle, symbol); | |||
} | |||
const char *windoze_local_db() { | |||
static string path; | |||
if (path.length() == 0) | |||
path = managementPath("%LOCALAPPDATA%\\pEp", "management.db"); | |||
return path.c_str(); | |||
} | |||
const char *windoze_system_db() { | |||
static string path; | |||
if (path.length() == 0) | |||
path = managementPath("%ALLUSERSPROFILE%\\pEp", "system.db"); | |||
return path.c_str(); | |||
} | |||
const char *gpg_conf() | |||
{ | |||
static string path; | |||
if (path.length() == 0) | |||
path = managementPath("%APPDATA%\\gnupg", "gpg.conf"); | |||
return path.c_str(); | |||
} | |||
} // "C" |
@ -0,0 +1,29 @@ | |||
#pragma once | |||
// Windows platform specifica | |||
#define RTLD_LAZY 1 | |||
#ifndef strdup | |||
#define strdup _strdup | |||
#endif | |||
#ifndef snprintf | |||
#define snprintf _snprintf | |||
#endif | |||
#define _CRT_NONSTDC_NO_DEPRECATE | |||
#define _CRT_SECURE_NO_WARNINGS | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
void *dlopen(const char *filename, int flag); | |||
int dlclose(void *handle); | |||
void *dlsym(void *handle, const char *symbol); | |||
const char *windoze_local_db(void); | |||
const char *windoze_system_db(void); | |||
const char *gpg_conf(void); | |||
#ifdef __cplusplus | |||
} | |||
#endif |
@ -0,0 +1,261 @@ | |||
#include <iostream> | |||
#include <fstream> | |||
#include <string> | |||
#include <assert.h> | |||
#include <string.h> | |||
#include "../src/pEpEngine.h" | |||
#include "../src/keymanagement.h" | |||
#ifdef _WIN32 | |||
#define strdup _strdup | |||
#endif | |||
using namespace std; | |||
int main(int argc, char* argv[]) | |||
{ | |||
PEP_SESSION session; | |||
cout << "calling init()\n"; | |||
PEP_STATUS init_result = init(&session); | |||
cout << "returning from init() with result == " << init_result << "\n"; | |||
assert(init_result == PEP_STATUS_OK); | |||
PEP_SESSION second_session; | |||
cout << "second session test\n"; | |||
PEP_STATUS second_init_result = init(&second_session); | |||
cout << "returning from second init() with result == " << second_init_result << "\n"; | |||
assert(second_init_result == PEP_STATUS_OK); | |||
assert(second_session); | |||
cout << "dropping second session\n"; | |||
release(second_session); | |||
cout << "logging test\n"; | |||
log_event(session, "log test", "pEp Enginge Test", "This is a logging test sample.", "please ignore this line"); | |||
string cipher; | |||
cout << "opening msc.asc for reading\n"; | |||
ifstream inFile ("msg.asc"); | |||
assert(inFile.is_open()); | |||
cout << "reading cipher text of msc.asc\n"; | |||
while (!inFile.eof()) { | |||
static string line; | |||
getline(inFile, line); | |||
cipher += line + "\n"; | |||
} | |||
inFile.close(); | |||
cout << "\n" << cipher; | |||
char *buf_text; | |||
size_t buf_size; | |||
stringlist_t *keylist; | |||
cout << "calling decrypt_and_verify()\n"; | |||
PEP_STATUS decrypt_result = decrypt_and_verify(session, cipher.c_str(), cipher.length(), &buf_text, &buf_size, &keylist); | |||
cout << "returning from decrypt_and_verify() with result == " << decrypt_result << "\n"; | |||
assert(decrypt_result == PEP_DECRYPTED_AND_VERIFIED); | |||
assert(buf_text); | |||
assert(keylist); | |||
for (stringlist_t *_keylist=keylist; _keylist!=NULL; _keylist=_keylist->next) { | |||
assert(_keylist->value); | |||
cout << "signed with " << _keylist->value << "\n"; | |||
} | |||
free_stringlist(keylist); | |||
buf_text[buf_size] = 0; | |||
string plain(buf_text); | |||
pEp_free(buf_text); | |||
cout << "\n" << plain; | |||
string t1, t2, sig; | |||
cout << "\nopening t1.txt for reading\n"; | |||
ifstream txtFile ("t1.txt"); | |||
assert(txtFile.is_open()); | |||
cout << "reading t1 from t1.txt\n"; | |||
while (!txtFile.eof()) { | |||
static string line; | |||
getline(txtFile, line); | |||
t1 += line + "\r\n"; | |||
} | |||
txtFile.close(); | |||
assert(t1.size()); | |||
t1.erase(t1.size()-2, 2); | |||
cout << "opening signature.asc for reading\n"; | |||
ifstream sigFile ("signature.asc"); | |||
assert(sigFile.is_open()); | |||
cout << "reading sig from signature.asc\n"; | |||
while (!sigFile.eof()) { | |||
static string line; | |||
getline(sigFile, line); | |||
sig += line + "\n"; | |||
} | |||
sigFile.close(); | |||
cout << "\ncalling verify_test()\n"; | |||
PEP_STATUS verify_result = verify_text(session, t1.c_str(), t1.size(), sig.c_str(), sig.size(), &keylist); | |||
cout << "result = " << verify_result << "\n"; | |||
assert(verify_result == PEP_VERIFIED || verify_result == PEP_VERIFIED_AND_TRUSTED); | |||
assert(keylist->value); | |||
cout << "signed with " << keylist->value << "\n"; | |||
free_stringlist(keylist); | |||
cout << "\nopening t2.txt for reading\n"; | |||
ifstream txt2File ("t2.txt"); | |||
assert(txt2File.is_open()); | |||
cout << "reading t2 from t2.txt\n"; | |||
while (!txt2File.eof()) { | |||
static string line; | |||
getline(txt2File, line); | |||
t2 += line + "\r\n"; | |||
} | |||
txt2File.close(); | |||
assert(t2.size()); | |||
t1.erase(t2.size()-2, 2); | |||
cout << "\ncalling verify_test()\n"; | |||
verify_result = verify_text(session, t2.c_str(), t2.size(), sig.c_str(), sig.size(), &keylist); | |||
cout << "result = " << verify_result << "\n"; | |||
assert(verify_result == PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH); | |||
free_stringlist(keylist); | |||
keylist = new_stringlist("FA7261F7"); | |||
cout << "\ncalling encrypt_and_sign()\n"; | |||
PEP_STATUS encrypt_result = encrypt_and_sign(session, keylist, plain.c_str(), plain.length(), &buf_text, &buf_size); | |||
cout << "returning from encrypt_and_sign() with result == " << encrypt_result << "\n"; | |||
assert(encrypt_result == PEP_STATUS_OK); | |||
free_stringlist(keylist); | |||
buf_text[buf_size] = 0; | |||
string cipher2(buf_text); | |||
cout << "\n" << cipher2; | |||
pEp_free(buf_text); | |||
cout << "\nfinding English safeword for 2342...\n"; | |||
char * word; | |||
size_t wsize; | |||
safeword(session, 2342, "en", &word, &wsize); | |||
assert(word); | |||
cout << "the safeword for 2342 is " << word << "\n"; | |||
pEp_free(word); | |||
string fingerprint = "4942 2235 FC99 585B 891C 6653 0C7B 109B FA72 61F7"; | |||
char * words; | |||
cout << "\nfinding German safewords for " << fingerprint << "...\n"; | |||
safewords(session, fingerprint.c_str(), "de", &words, &wsize, 5); | |||
assert(words); | |||
cout << words << "\n"; | |||
pEp_free(words); | |||
pEp_identity *identity; | |||
identity = new_identity( | |||
strdup("leon.schumacher@digitalekho.com"), | |||
strdup("8BD08954C74D830EEFFB5DEB2682A17F7C87F73D"), | |||
strdup("23"), | |||
strdup("Leon Schumacher") | |||
); | |||
identity->comm_type = PEP_ct_pEp; | |||
cout << "\nsetting identity...\n"; | |||
PEP_STATUS pep_set_result = set_identity(session, identity); | |||
assert(pep_set_result == PEP_STATUS_OK); | |||
free_identity(identity); | |||
get_identity(session, "leon.schumacher@digitalekho.com", &identity); | |||
assert(identity); | |||
cout << "set: " << identity->address << ", " << identity->fpr << ", " << identity->user_id << ", " << identity->username << "\n"; | |||
free_identity(identity); | |||
stringlist_t *addresses = new_stringlist("leon.schumacher@digitalekho.com"); | |||
PEP_comm_type comm_type; | |||
cout << "\nretrieving communication type for leon.schumacher@digitalekho.com\n"; | |||
PEP_STATUS oct_result = outgoing_comm_type(session, addresses, &comm_type); | |||
cout << "communication type is " << comm_type << "\n"; | |||
free_stringlist(addresses); | |||
assert(oct_result == PEP_STATUS_OK && comm_type == PEP_ct_pEp); | |||
stringlist_t *addresses2 = new_stringlist("leon.schumacher@digitalekho.com"); | |||
stringlist_add(addresses2, "this.email@is.invalid"); | |||
cout << "\nretrieving communication type for an unknown address\n"; | |||
oct_result = outgoing_comm_type(session, addresses2, &comm_type); | |||
cout << "communication type is " << comm_type << "\n"; | |||
cout << "status is " << oct_result << "\n"; | |||
free_stringlist(addresses2); | |||
assert(oct_result == PEP_STATUS_OK && comm_type == PEP_ct_no_encryption); | |||
cout << "\ngenerating key for testuser\n"; | |||
identity = new_identity( | |||
strdup("testuser@pibit.ch"), | |||
NULL, | |||
strdup("423"), | |||
strdup("Alfred E. Neuman") | |||
); | |||
assert(identity); | |||
PEP_STATUS generate_status = generate_keypair(session, identity); | |||
cout << "generate_keypair() exits with " << generate_status << "\n"; | |||
assert(generate_status == PEP_STATUS_OK); | |||
cout << "generated key is " << identity->fpr << "\n"; | |||
string key(identity->fpr); | |||
free_identity(identity); | |||
char *key_data; | |||
size_t size; | |||
cout << "export_key()\n\n"; | |||
PEP_STATUS export_status = export_key(session, key.c_str(), &key_data, &size); | |||
assert(export_status == PEP_STATUS_OK); | |||
cout << key_data << "\n\n"; | |||
cout << "deleting key pair " << key.c_str() << "\n"; | |||
PEP_STATUS delete_status = delete_keypair(session, key.c_str()); | |||
cout << "delete_keypair() exits with " << delete_status << "\n"; | |||
assert(delete_status == PEP_STATUS_OK); | |||
cout << "import_key()\n"; | |||
PEP_STATUS import_status = import_key(session, key_data, size); | |||
assert(import_status == PEP_STATUS_OK); | |||
cout << "successfully imported key\n"; | |||
pEp_free(key_data); | |||
cout << "deleting key " << key.c_str() << " again\n"; | |||
delete_status = delete_keypair(session, key.c_str()); | |||
cout << "delete_keypair() exits with " << delete_status << "\n"; | |||
assert(delete_status == PEP_STATUS_OK); | |||
cout << "finding key for outlooktest@dingens.org\n"; | |||
PEP_STATUS find_keys_status = find_keys(session, "outlooktest@dingens.org", &keylist); | |||
assert(find_keys_status == PEP_STATUS_OK); | |||
assert(keylist); | |||
cout << "found: " << keylist->value << "\n"; | |||
assert(keylist->next == NULL); | |||
free_stringlist(keylist); | |||
cout << "searching for vb@ulm.ccc.de on keyserver\n"; | |||
PEP_STATUS recv_key_status = recv_key(session, "vb@ulm.ccc.de"); | |||
assert(recv_key_status == PEP_STATUS_OK); | |||
cout << "sending vb@ulm.ccc.de to keyserver\n"; | |||
PEP_STATUS send_key_status = send_key(session, "vb@ulm.ccc.de"); | |||
assert(recv_key_status == PEP_STATUS_OK); | |||
cout << "\ncalling release()\n"; | |||
release(session); | |||
return 0; | |||
} |
@ -0,0 +1,77 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<ItemGroup Label="ProjectConfigurations"> | |||
<ProjectConfiguration Include="Debug|Win32"> | |||
<Configuration>Debug</Configuration> | |||
<Platform>Win32</Platform> | |||
</ProjectConfiguration> | |||
<ProjectConfiguration Include="Release|Win32"> | |||
<Configuration>Release</Configuration> | |||
<Platform>Win32</Platform> | |||
</ProjectConfiguration> | |||
</ItemGroup> | |||
<PropertyGroup Label="Globals"> | |||
<ProjectGuid>{7181F561-8E6C-4C92-B680-D268610A3465}</ProjectGuid> | |||
<RootNamespace>pEpEngineTest</RootNamespace> | |||
</PropertyGroup> | |||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | |||
<ConfigurationType>Application</ConfigurationType> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
<PlatformToolset>v120</PlatformToolset> | |||
<CharacterSet>MultiByte</CharacterSet> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | |||
<ConfigurationType>Application</ConfigurationType> | |||
<UseDebugLibraries>false</UseDebugLibraries> | |||
<PlatformToolset>v120</PlatformToolset> | |||
<WholeProgramOptimization>true</WholeProgramOptimization> | |||
<CharacterSet>MultiByte</CharacterSet> | |||
</PropertyGroup> | |||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | |||
<ImportGroup Label="ExtensionSettings"> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
</ImportGroup> | |||
<PropertyGroup Label="UserMacros" /> | |||
<PropertyGroup /> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||
<ClCompile> | |||
<WarningLevel>Level3</WarningLevel> | |||
<Optimization>Disabled</Optimization> | |||
<SDLCheck>true</SDLCheck> | |||
</ClCompile> | |||
<Link> | |||
<GenerateDebugInformation>true</GenerateDebugInformation> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||
<ClCompile> | |||
<WarningLevel>Level3</WarningLevel> | |||
<Optimization>MaxSpeed</Optimization> | |||
<FunctionLevelLinking>true</FunctionLevelLinking> | |||
<IntrinsicFunctions>true</IntrinsicFunctions> | |||
<SDLCheck>true</SDLCheck> | |||
</ClCompile> | |||
<Link> | |||
<GenerateDebugInformation>true</GenerateDebugInformation> | |||
<EnableCOMDATFolding>true</EnableCOMDATFolding> | |||
<OptimizeReferences>true</OptimizeReferences> | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemGroup> | |||
<ClCompile Include="pEpEngineTest.cc" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\pEpEngine.vcxproj"> | |||
<Project>{146e69f8-e1da-456a-b048-6dd29d9acf6b}</Project> | |||
</ProjectReference> | |||
</ItemGroup> | |||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | |||
<ImportGroup Label="ExtensionTargets"> | |||
</ImportGroup> | |||
</Project> |