initial commit

doc_update_sequoia
vb 2014-06-25 18:44:58 +02:00
commit 7feceb3f9f
12 changed files with 156097 additions and 0 deletions

98
pEpEngine.vcxproj Normal file
View File

@ -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>

45
pEpEngine.vcxproj.filters Normal file
View File

@ -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>

210
src/keymanagement.c Normal file
View File

@ -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;
}

103
src/keymanagement.h Normal file
View File

@ -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

1869
src/pEpEngine.c Normal file

File diff suppressed because it is too large Load Diff

583
src/pEpEngine.h Normal file
View File

@ -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

189
src/platform_windows.cpp Normal file
View File

@ -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"

29
src/platform_windows.h Normal file
View File

@ -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

145295
src/sqlite3.c Normal file

File diff suppressed because it is too large Load Diff

7338
src/sqlite3.h Normal file

File diff suppressed because it is too large Load Diff

261
test/pEpEngineTest.cc Normal file
View File

@ -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;
}

View File

@ -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'">