initial commit
commit
7feceb3f9f
|
@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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'">
|
||||