Engine/Basic Concepts of the pEp Engine

Strings

p≡p engine uses UTF-8 strings which are NFC normalized.

p≡p engine does not actually do the normalization. It has to be done by the adapter which uses p≡p engine. Usually an adapter is supporting a Unicode environment for the application programmer. But this environment can use other Unicode representations like UTF-16 and other forms of normalization. So the adapter has to convert all string data.

Data structures

p≡p engine introduces a couple of data structures which are used in the API. The data structures all have a set of functions to deal with them. Using these functions is mandatory; for security reasons p≡p engine’s data structures never should be used without them. These functions are:

Constructor

<STRUCTTYPE> *new_<STRUCTTYPE>(...);

This is the constructor of a data structure. The tag <STRUCTTYPE> will be replaced by the concrete name of the data structure. There may be initializing arguments. I.e. for stringlists it is:

stringlist_t *new_stringlist(const char *value);

Destructor

There is always a destructor:

void free_<STRUCTTYPE>(<STRUCTTYPE> *);

For our stringlist example, it is:

void free_stringlist(stringlist_t *stringlist);

The destructor does not only free the complete data structure including substructures, it additionally frees all objects the data structure has ownership for.

Duplicator

Additionally, there is a duplicator. The duplicator makes a deep copy; that means, it does not only copy the data structure including substructures, additionally it copies all objects owned by the data structure. For collections that means if (and only if) they’re owning the collected objects, the collected objects will be copied, too.

<STRUCTTYPE> *<STRUCTTYPE>_dup(const <STRUCTTYPE> *src);

For our stringlist example, this is:

stringlist_t *stringlist_dup(const stringlist_t *src);

For collections: Adder

If the data structure is a collection of other data, then there is an adder. The adder adds new collected elements to the collection.

<STRUCTTYPE> *<STRUCTTYPE>_add(<STRUCTTYPE> *, ...);

For our stringlist example, it is:

stringlist_t *stringlist_add(stringlist_t *stringlist, const char *value);

The reason why a pointer is given as the return value is that you can use this pointer to consecutively add new elements quickly. Just add always on the returned object of the last adder call. To add the first time, use a pointer to the data structure you have.

There may be more functions. Please read the documentation for each data structure you’re using before actually using them. The mandatory documentation is directly in the corresponding header file for any data structure – there is exactly one header file for each of them. For the stringlist example it is stringlist.h.

There are usage caveats mentioned with nearly each function. Please read them carefully before using any API!

APIs - How to use the pEp Engine

First of all: don’t use p≡p engine directly from your application!

p≡p engine is meant to be used by an adapter to the application development environment. Even if you’re using C/C++ for application development, don’t use it directly!

The reason for adapters is that in such an environment the application programmer is using some framework or library which helps to construct an application quickly. An example for that is the Qt environment for C++ – and that’s the reason for the wiki:“Qt Adapter”.

If the application developer is using another language, the adapter is meant to support using all of the native concepts. This way we’re avoiding lots of security risks and misunderstandings – the adapter has to behave as it would offer native objects in the environment the programmer is used to – see wiki:“How to write an adapter”?

Sessions and concurrency

Prior to any call to pEpEngine API, a PEP_SESSION handle must be initialized through a successful call to :

PEP_STATUS init(PEP_SESSION *)

Session is to be discarded by calling :

void release(PEP_SESSION *)

Adapter must ensure that no concurrent calls to pEpEngine API are issued with the same PEP_SESSION handle. Calls referring to different session can safely be issued concurrently.

Highlevel

  • SendReceive API
  • Message API
  • Keymanagement API

Lowlevel

Avoid using lowlevel APIs wherever you can. You’re introducing mistakes and security holes which could be avoided by just being more lazy.

  • MIME API
  • Basic API