src/pEpEngine.c
author vb
Mon, 01 Sep 2014 18:36:42 +0200
changeset 26 843e629627bf
parent 24 50887c6ab78f
child 28 7fc9fc3e680c
permissions -rw-r--r--
bugfix: pgp_init
     1 #include "pEp_internal.h"
     2 #ifndef NO_GPG
     3 #include "pgp_gpg.h"
     4 #else
     5 #include "pgp_netpgp.h"
     6 #endif
     7 
     8 DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
     9 {
    10     PEP_STATUS status_result;
    11 	int int_result;
    12 	const char *sql_log;
    13 	const char *sql_safeword;
    14 	const char *sql_get_identity;
    15 	const char *sql_set_person;
    16 	const char *sql_set_pgp_keypair;
    17 	const char *sql_set_identity;
    18 	const char *sql_set_trust;
    19     const char *sql_get_trust;
    20 
    21 	assert(sqlite3_threadsafe());
    22 	if (!sqlite3_threadsafe())
    23 		return PEP_INIT_SQLITE3_WITHOUT_MUTEX;
    24 
    25 	assert(session);
    26 	*session = NULL;
    27 
    28     pEpSession *_session = (pEpSession *) calloc(1, sizeof(pEpSession));
    29 	assert(_session);
    30 	if (_session == NULL)
    31 		return PEP_OUT_OF_MEMORY;
    32 	
    33 	_session->version = PEP_ENGINE_VERSION;
    34 
    35     status_result = pgp_init(_session);
    36     assert(status_result == PEP_STATUS_OK);
    37     if (status_result != PEP_STATUS_OK) {
    38         free(_session);
    39         return status_result;
    40     }
    41 
    42     assert(LOCAL_DB);
    43     if (LOCAL_DB == NULL) {
    44         pgp_release(session);
    45         free(_session);
    46         return PEP_INIT_CANNOT_OPEN_DB;
    47     }
    48 
    49 	int_result = sqlite3_open_v2(
    50 			LOCAL_DB,
    51 			&_session->db,
    52 			SQLITE_OPEN_READWRITE
    53 				| SQLITE_OPEN_CREATE
    54 				| SQLITE_OPEN_FULLMUTEX
    55 				| SQLITE_OPEN_PRIVATECACHE,
    56 			NULL 
    57 		);
    58 
    59 	if (int_result != SQLITE_OK) {
    60 		sqlite3_close_v2(_session->db);
    61         pgp_release(session);
    62         free(_session);
    63 		return PEP_INIT_CANNOT_OPEN_DB;
    64 	}
    65 
    66 	sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
    67 
    68     assert(SYSTEM_DB);
    69     if (SYSTEM_DB == NULL) {
    70 		sqlite3_close_v2(_session->db);
    71         pgp_release(session);
    72         free(_session);
    73 		return PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
    74     }
    75 
    76 	int_result = sqlite3_open_v2(
    77 			SYSTEM_DB, &_session->system_db,
    78 			SQLITE_OPEN_READONLY
    79 				| SQLITE_OPEN_FULLMUTEX
    80 				| SQLITE_OPEN_SHAREDCACHE,
    81 			NULL
    82 		);
    83 
    84 	if (int_result != SQLITE_OK) {
    85 		sqlite3_close_v2(_session->system_db);
    86 		sqlite3_close_v2(_session->db);
    87         pgp_release(session);
    88         free(_session);
    89 		return PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
    90 	}
    91 
    92 	sqlite3_busy_timeout(_session->system_db, 1000);
    93 
    94 	int_result = sqlite3_exec(
    95 		_session->db,
    96 			"create table if not exists version_info ("
    97 			"	id integer primary key,"
    98 			"	timestamp integer default (datetime('now')) ,"
    99 			"	version text,"
   100 			"	comment text"
   101 			");"
   102 			"create table if not exists log ("
   103 			"	timestamp integer default (datetime('now')) ,"
   104 			"	title text not null,"
   105 			"	entity text not null,"
   106 			"	description text,"
   107 			"	comment text"
   108 			");"
   109 			"create index if not exists log_timestamp on log ("
   110 			"	timestamp"
   111 			");"
   112 			"create table if not exists pgp_keypair ("
   113 			"	fpr text primary key,"
   114 			"	public_id text unique,"
   115 			"   private_id text,"
   116 			"	created integer,"
   117 			"	expires integer,"
   118 			"	comment text"
   119 			");"
   120             "create index if not exists pgp_keypair_expires on pgp_keypair ("
   121 			"	expires"
   122 			");"
   123 			"create table if not exists person ("
   124 			"	id text primary key,"
   125 			"	username text not null,"
   126 			"	main_key_id text"
   127 			"		references pgp_keypair (fpr)"
   128 			"		on delete set null,"
   129 			"   lang text,"
   130 			"	comment text"
   131 			");"
   132 			"create table if not exists identity ("
   133 			"	address text primary key,"
   134 			"	user_id text"
   135 			"		references person (id)"
   136 			"		on delete cascade,"
   137 			"	main_key_id text"
   138 			"		references pgp_keypair (fpr)"
   139 			"		on delete set null,"
   140 			"	comment text"
   141 			");"
   142             "create table if not exists trust ("
   143             "   user_id text not null"
   144             "       references person (id)"
   145 			"		on delete cascade,"
   146             "   pgp_keypair_fpr text not null"
   147             "       references pgp_keypair (fpr)"
   148             "       on delete cascade,"
   149             "   comm_type integer not null,"
   150 			"	comment text"
   151             ");"
   152             "create unique index if not exists trust_index on trust ("
   153             "   user_id,"
   154             "   pgp_keypair_fpr"
   155             ");",
   156 		NULL,
   157 		NULL,
   158 		NULL
   159 	);
   160 	assert(int_result == SQLITE_OK);
   161 
   162 	int_result = sqlite3_exec(
   163 		_session->db,
   164         "insert or replace into version_info (id, version) values (1, '1.0');",
   165 		NULL,
   166 		NULL,
   167 		NULL
   168 	);
   169 	assert(int_result == SQLITE_OK);
   170 
   171 	sql_log = "insert into log (title, entity, description, comment)"
   172 			  "values (?1, ?2, ?3, ?4);";
   173     int_result = sqlite3_prepare_v2(_session->db, sql_log, strlen(sql_log),
   174             &_session->log, NULL);
   175 	assert(int_result == SQLITE_OK);
   176 
   177 	sql_safeword = "select id, word from wordlist where lang = lower(?1)"
   178                    "and id = ?2 ;";
   179     int_result = sqlite3_prepare_v2(_session->system_db, sql_safeword,
   180             strlen(sql_safeword), &_session->safeword, NULL);
   181 	assert(int_result == SQLITE_OK);
   182 
   183 	sql_get_identity =	"select fpr, identity.user_id, username, comm_type, lang"
   184                         "   from identity"
   185 						"   join person on id = identity.user_id"
   186 						"   join pgp_keypair on fpr = identity.main_key_id"
   187                         "   join trust on id = trust.user_id"
   188                         "       and pgp_keypair_fpr = identity.main_key_id"
   189 						"   where address = ?1 ;";
   190 
   191     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
   192             strlen(sql_get_identity), &_session->get_identity, NULL);
   193 	assert(int_result == SQLITE_OK);
   194 
   195 	sql_set_person = "insert or replace into person (id, username, lang)"
   196                      "values (?1, ?2, ?3) ;";
   197 	sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr)"
   198                           "values (?1) ;";
   199     sql_set_identity = "insert or replace into identity (address, main_key_id,"
   200                        "user_id) values (?1, ?2, ?3) ;";
   201     sql_set_trust = "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type)"
   202                         "values (?1, ?2, ?3) ;";
   203 	
   204     sql_get_trust = "select user_id, comm_type from trust where user_id = ?1 and pgp_keypair_fpr = ?2 ;";
   205 
   206     int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
   207             strlen(sql_set_person), &_session->set_person, NULL);
   208     assert(int_result == SQLITE_OK);
   209     int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
   210             strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair, NULL);
   211 	assert(int_result == SQLITE_OK);
   212     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity,
   213             strlen(sql_set_identity), &_session->set_identity, NULL);
   214 	assert(int_result == SQLITE_OK);
   215     int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
   216             strlen(sql_set_trust), &_session->set_trust, NULL);
   217 	assert(int_result == SQLITE_OK);
   218     int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
   219             strlen(sql_get_trust), &_session->get_trust, NULL);
   220     assert(int_result == SQLITE_OK);
   221 
   222 	sqlite3_reset(_session->log);
   223     sqlite3_bind_text(_session->log, 1, "init", -1, SQLITE_STATIC);
   224     sqlite3_bind_text(_session->log, 2, "pEp " PEP_ENGINE_VERSION, -1,
   225             SQLITE_STATIC);
   226 	do {
   227 		int_result = sqlite3_step(_session->log);
   228 		assert(int_result == SQLITE_DONE || int_result == SQLITE_BUSY);
   229 	} while (int_result == SQLITE_BUSY);
   230     sqlite3_reset(_session->log);
   231 
   232 	*session = (void *) _session;
   233 	return PEP_STATUS_OK;
   234 }
   235 
   236 DYNAMIC_API void release(PEP_SESSION session)
   237 {
   238 	assert(session);
   239 	pEpSession *_session = (pEpSession *) session;
   240 
   241 	if (_session) {
   242 		if (_session->db) {
   243 			sqlite3_finalize(_session->safeword);
   244 			sqlite3_finalize(_session->log);
   245 			sqlite3_finalize(_session->get_identity);
   246 			sqlite3_finalize(_session->set_identity);
   247             sqlite3_finalize(_session->set_person);
   248             sqlite3_finalize(_session->set_pgp_keypair);
   249             sqlite3_finalize(_session->set_trust);
   250             sqlite3_finalize(_session->get_trust);
   251 
   252 			sqlite3_close_v2(_session->db);
   253 			sqlite3_close_v2(_session->system_db);
   254 		}
   255         pgp_release(session);
   256     }
   257 	free(_session);
   258 }
   259 
   260 stringlist_t *new_stringlist(const char *value)
   261 {
   262     stringlist_t *result = (stringlist_t *) calloc(1, sizeof(stringlist_t));
   263     if (result && value) {
   264         result->value = strdup(value);
   265         assert(result->value);
   266         if (result->value == 0) {
   267             free(result);
   268             return NULL;
   269         }
   270     }
   271     return result;
   272 }
   273 
   274 stringlist_t *stringlist_add(stringlist_t *stringlist, const char *value)
   275 {
   276     assert(value);
   277 
   278     if (stringlist == NULL)
   279         return new_stringlist(value);
   280 
   281     if (stringlist->next != NULL)
   282         return stringlist_add(stringlist->next, value);
   283 
   284     if (stringlist->value == NULL) {
   285         stringlist->value = strdup(value);
   286         assert(stringlist->value);
   287         if (stringlist->value == NULL)
   288             return NULL;
   289         return stringlist;
   290     }
   291 
   292     stringlist->next = new_stringlist(value);
   293     assert(stringlist->next);
   294     if (stringlist->next == NULL)
   295         return NULL;
   296 
   297     return stringlist->next;
   298 }
   299 
   300 int stringlist_length(const stringlist_t *stringlist)
   301 {
   302     int len = 1;
   303     stringlist_t *_stringlist;
   304 
   305     assert(stringlist);
   306 
   307     if (stringlist->value == NULL)
   308         return 0;
   309 
   310     for (_stringlist=stringlist->next; _stringlist!=NULL; _stringlist=_stringlist->next)
   311         len += 1;
   312 
   313     return len;
   314 }
   315 
   316 void free_stringlist(stringlist_t *stringlist)
   317 {
   318     if (stringlist) {
   319         free_stringlist(stringlist->next);
   320         free(stringlist->value);
   321         free(stringlist);
   322     }
   323 }
   324 
   325 DYNAMIC_API PEP_STATUS log_event(
   326         PEP_SESSION session, const char *title, const char *entity,
   327         const char *description, const char *comment
   328     )
   329 {
   330 	pEpSession *_session = (pEpSession *) session;
   331 	PEP_STATUS status = PEP_STATUS_OK;
   332 	int result;
   333 
   334 	assert(_session);
   335 	assert(title);
   336 	assert(entity);
   337 
   338 	sqlite3_reset(_session->log);
   339 	sqlite3_bind_text(_session->log, 1, title, -1, SQLITE_STATIC);
   340 	sqlite3_bind_text(_session->log, 2, entity, -1, SQLITE_STATIC);
   341 	if (description)
   342         sqlite3_bind_text(_session->log, 3, description, -1, SQLITE_STATIC);
   343 	else
   344 		sqlite3_bind_null(_session->log, 3);
   345 	if (comment)
   346 		sqlite3_bind_text(_session->log, 4, comment, -1, SQLITE_STATIC);
   347 	else
   348 		sqlite3_bind_null(_session->log, 4);
   349 	do {
   350 		result = sqlite3_step(_session->log);
   351 		assert(result == SQLITE_DONE || result == SQLITE_BUSY);
   352 		if (result != SQLITE_DONE && result != SQLITE_BUSY)
   353 			status = PEP_UNKNOWN_ERROR;
   354 	} while (result == SQLITE_BUSY);
   355 	sqlite3_reset(_session->log);
   356 
   357 	return status;
   358 }
   359 
   360 DYNAMIC_API PEP_STATUS safeword(
   361             PEP_SESSION session, uint16_t value, const char *lang,
   362             char **word, size_t *wsize
   363         )
   364 {
   365 	pEpSession *_session = (pEpSession *) session;
   366 	PEP_STATUS status = PEP_STATUS_OK;
   367 	int result;
   368 
   369 	assert(_session);
   370 	assert(word);
   371 	assert(wsize);
   372 
   373 	*word = NULL;
   374 	*wsize = 0;
   375 
   376 	if (lang == NULL)
   377 		lang = "en";
   378 
   379 	assert((lang[0] >= 'A' && lang[0] <= 'Z')
   380             || (lang[0] >= 'a' && lang[0] <= 'z'));
   381 	assert((lang[1] >= 'A' && lang[1] <= 'Z')
   382             || (lang[1] >= 'a' && lang[1] <= 'z'));
   383 	assert(lang[2] == 0);
   384 
   385 	sqlite3_reset(_session->safeword);
   386     sqlite3_bind_text(_session->safeword, 1, lang, -1, SQLITE_STATIC);
   387 	sqlite3_bind_int(_session->safeword, 2, value);
   388 
   389 	result = sqlite3_step(_session->safeword);
   390 	if (result == SQLITE_ROW) {
   391         *word = strdup((const char *) sqlite3_column_text(_session->safeword,
   392                     1));
   393 		if (*word)
   394             *wsize = sqlite3_column_bytes(_session->safeword, 1);
   395 		else
   396 			status = PEP_SAFEWORD_NOT_FOUND;
   397 	} else
   398 		status = PEP_SAFEWORD_NOT_FOUND;
   399 
   400 	sqlite3_reset(_session->safeword);
   401 	return status;
   402 }
   403 
   404 DYNAMIC_API PEP_STATUS safewords(
   405         PEP_SESSION session, const char *fingerprint, const char *lang,
   406         char **words, size_t *wsize, int max_words
   407     )
   408 {
   409 	const char *source = fingerprint;
   410 	char *buffer = calloc(1, MAX_SAFEWORDS_SPACE);
   411 	char *dest = buffer;
   412 	size_t fsize;
   413     PEP_STATUS _status;
   414 
   415 	assert(session);
   416 	assert(fingerprint);
   417 	assert(words);
   418 	assert(wsize);
   419 	assert(max_words >= 0);
   420 
   421 	*words = NULL;
   422 	*wsize = 0;
   423 
   424     assert(buffer);
   425     if (buffer == NULL)
   426         return PEP_OUT_OF_MEMORY;
   427 
   428 	fsize = strlen(fingerprint);
   429 
   430 	if (lang == NULL)
   431 		lang = "en";
   432 
   433 	assert((lang[0] >= 'A' && lang[0] <= 'Z')
   434             || (lang[0] >= 'a' && lang[0] <= 'z'));
   435 	assert((lang[1] >= 'A' && lang[1] <= 'Z')
   436             || (lang[1] >= 'a' && lang[1] <= 'z'));
   437 	assert(lang[2] == 0);
   438 
   439 	int n_words = 0;
   440 	while (source < fingerprint + fsize) {
   441 		uint16_t value;
   442 		char *word;
   443 		size_t _wsize;
   444 		int j;
   445 
   446         for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
   447 			if (*source >= 'a' && *source <= 'f')
   448 				value += (*source - 'a' + 10) << (3 - j++) * 4;
   449 			else if (*source >= 'A' && *source <= 'F')
   450 				value += (*source - 'A' + 10) << (3 - j++) * 4;
   451 			else if (*source >= '0' && *source <= '9')
   452 				value += (*source - '0') << (3 - j++) * 4;
   453 			
   454 			source++;
   455 		}
   456 
   457 		_status = safeword(session, value, lang, &word, &_wsize);
   458         if (_status == PEP_OUT_OF_MEMORY) {
   459             free(buffer);
   460             return PEP_OUT_OF_MEMORY;
   461         }
   462 		if (word == NULL) {
   463             free(buffer);
   464 			return PEP_SAFEWORD_NOT_FOUND;
   465         }
   466 
   467 		if (dest + _wsize < buffer + MAX_SAFEWORDS_SPACE - 1) {
   468 			strncpy(dest, word, _wsize);
   469             free(word);
   470 			dest += _wsize;
   471 		}
   472 		else {
   473             free(word);
   474 			break; // buffer full
   475         }
   476 
   477 		if (source < fingerprint + fsize
   478                 && dest + _wsize < buffer + MAX_SAFEWORDS_SPACE - 1)
   479 			*dest++ = ' ';
   480 
   481 		++n_words;
   482 		if (max_words && n_words >= max_words)
   483 			break;
   484 	}
   485 
   486 	*words = buffer;
   487 	*wsize = dest - buffer;
   488 	return PEP_STATUS_OK;
   489 }
   490 
   491 pEp_identity *new_identity(
   492         const char *address, const char *fpr, const char *user_id,
   493         const char *username
   494     )
   495 {
   496     pEp_identity *result = calloc(1, sizeof(pEp_identity));
   497     assert(result);
   498     if (result) {
   499         if (address) {
   500             result->address = strdup(address);
   501             assert(result->address);
   502             if (result->address == NULL) {
   503                 free(result);
   504                 return NULL;
   505             }
   506             result->address_size = strlen(address);
   507         }
   508         if (fpr) {
   509             result->fpr = strdup(fpr);
   510             assert(result->fpr);
   511             if (result->fpr == NULL) {
   512                 free_identity(result);
   513                 return NULL;
   514             }
   515             result->fpr_size = strlen(fpr);
   516         }
   517         if (user_id) {
   518             result->user_id = strdup(user_id);
   519             assert(result->user_id);
   520             if (result->user_id == NULL) {
   521                 free_identity(result);
   522                 return NULL;
   523             }
   524             result->user_id_size = strlen(user_id);
   525         }
   526         if (username) {
   527             result->username = strdup(username);
   528             assert(result->username);
   529             if (result->username == NULL) {
   530                 free_identity(result);
   531                 return NULL;
   532             }
   533             result->username_size = strlen(username);
   534         }
   535         result->struct_size = sizeof(pEp_identity);
   536     }
   537     return result;
   538 }
   539 
   540 void free_identity(pEp_identity *identity)
   541 {
   542     if (identity) {
   543         free(identity->address);
   544         free(identity->fpr);
   545         free(identity->user_id);
   546         free(identity->username);
   547         free(identity);
   548     }
   549 }
   550 
   551 DYNAMIC_API PEP_STATUS get_identity(
   552         PEP_SESSION session, const char *address,
   553         pEp_identity **identity
   554     )
   555 {
   556 	pEpSession *_session = (pEpSession *) session;
   557 	PEP_STATUS status = PEP_STATUS_OK;
   558 	static pEp_identity *_identity;
   559 	int result;
   560 	const char *_lang;
   561 
   562 	assert(session);
   563 	assert(address);
   564     assert(address[0]);
   565 
   566     sqlite3_reset(_session->get_identity);
   567     sqlite3_bind_text(_session->get_identity, 1, address, -1, SQLITE_STATIC);
   568 
   569     result = sqlite3_step(_session->get_identity);
   570 	switch (result) {
   571 	case SQLITE_ROW:
   572         _identity = new_identity(
   573                 address,
   574                 (const char *) sqlite3_column_text(_session->get_identity, 0),
   575                 (const char *) sqlite3_column_text(_session->get_identity, 1),
   576                 (const char *) sqlite3_column_text(_session->get_identity, 2)
   577                 );
   578         assert(_identity);
   579         if (_identity == NULL)
   580             return PEP_OUT_OF_MEMORY;
   581 
   582         _identity->comm_type = (PEP_comm_type) sqlite3_column_int(_session->get_identity, 3);
   583         _lang = (const char *) sqlite3_column_text(_session->get_identity, 4);
   584         if (_lang && _lang[0]) {
   585 			assert(_lang[0] >= 'a' && _lang[0] <= 'z');
   586 			assert(_lang[1] >= 'a' && _lang[1] <= 'z');
   587 			assert(_lang[2] == 0);
   588 			_identity->lang[0] = _lang[0];
   589 			_identity->lang[1] = _lang[1];
   590             _identity->lang[2] = 0;
   591 		}
   592 		*identity = _identity;
   593 		break;
   594 	default:
   595         status = PEP_CANNOT_FIND_IDENTITY;
   596 		*identity = NULL;
   597 	}
   598 
   599     sqlite3_reset(_session->get_identity);
   600 	return status;
   601 }
   602 
   603 DYNAMIC_API PEP_STATUS set_identity(
   604         PEP_SESSION session, const pEp_identity *identity
   605     )
   606 {
   607 	pEpSession *_session = (pEpSession *) session;
   608 	int result;
   609 
   610 	assert(session);
   611 	assert(identity);
   612 	assert(identity->address);
   613 	assert(identity->fpr);
   614 	assert(identity->user_id);
   615 	assert(identity->username);
   616 
   617 	sqlite3_exec(_session->db, "BEGIN ;", NULL, NULL, NULL);
   618 
   619 	sqlite3_reset(_session->set_person);
   620     sqlite3_bind_text(_session->set_person, 1, identity->user_id, -1,
   621             SQLITE_STATIC);
   622     sqlite3_bind_text(_session->set_person, 2, identity->username, -1,
   623             SQLITE_STATIC);
   624 	if (identity->lang[0])
   625         sqlite3_bind_text(_session->set_person, 3, identity->lang, 1,
   626                 SQLITE_STATIC);
   627 	else
   628 		sqlite3_bind_null(_session->set_person, 3);
   629 	result = sqlite3_step(_session->set_person);
   630 	sqlite3_reset(_session->set_person);
   631 	if (result != SQLITE_DONE) {
   632 		sqlite3_exec(_session->db, "ROLLBACK ;", NULL, NULL, NULL);
   633 		return PEP_CANNOT_SET_PERSON;
   634 	}
   635 
   636 	sqlite3_reset(_session->set_pgp_keypair);
   637     sqlite3_bind_text(_session->set_pgp_keypair, 1, identity->fpr, -1,
   638             SQLITE_STATIC);
   639 	result = sqlite3_step(_session->set_pgp_keypair);
   640 	sqlite3_reset(_session->set_pgp_keypair);
   641 	if (result != SQLITE_DONE) {
   642 		sqlite3_exec(_session->db, "ROLLBACK ;", NULL, NULL, NULL);
   643 		return PEP_CANNOT_SET_PGP_KEYPAIR;
   644 	}
   645 
   646 	sqlite3_reset(_session->set_identity);
   647     sqlite3_bind_text(_session->set_identity, 1, identity->address, -1,
   648             SQLITE_STATIC);
   649     sqlite3_bind_text(_session->set_identity, 2, identity->fpr, -1,
   650             SQLITE_STATIC);
   651     sqlite3_bind_text(_session->set_identity, 3, identity->user_id, -1,
   652             SQLITE_STATIC);
   653 	result = sqlite3_step(_session->set_identity);
   654 	sqlite3_reset(_session->set_identity);
   655 	if (result != SQLITE_DONE) {
   656 		sqlite3_exec(_session->db, "ROLLBACK ;", NULL, NULL, NULL);
   657 		return PEP_CANNOT_SET_IDENTITY;
   658 	}
   659 
   660 	sqlite3_reset(_session->set_trust);
   661     sqlite3_bind_text(_session->set_trust, 1, identity->user_id, -1,
   662             SQLITE_STATIC);
   663     sqlite3_bind_text(_session->set_trust, 2, identity->fpr, -1,
   664             SQLITE_STATIC);
   665 	sqlite3_bind_int(_session->set_trust, 3, identity->comm_type);
   666 	result = sqlite3_step(_session->set_trust);
   667 	sqlite3_reset(_session->set_trust);
   668 	if (result != SQLITE_DONE) {
   669 		sqlite3_exec(_session->db, "ROLLBACK ;", NULL, NULL, NULL);
   670 		return PEP_CANNOT_SET_IDENTITY;
   671 	}
   672 
   673     result = sqlite3_exec(_session->db, "COMMIT ;", NULL, NULL, NULL);
   674 	if (result == SQLITE_OK)
   675 		return PEP_STATUS_OK;
   676 	else
   677 		return PEP_COMMIT_FAILED;
   678 }
   679 
   680 void pEp_free(void *p)
   681 {
   682     free(p);
   683 }
   684 
   685 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
   686 {
   687     pEpSession *_session = (pEpSession *) session;
   688     PEP_STATUS status = PEP_STATUS_OK;
   689     int result;
   690 
   691     assert(session);
   692     assert(identity);
   693     assert(identity->user_id);
   694     assert(identity->user_id[0]);
   695     assert(identity->fpr);
   696     assert(identity->fpr[0]);
   697 
   698     identity->comm_type = PEP_ct_unknown;
   699 
   700     sqlite3_reset(_session->get_trust);
   701     sqlite3_bind_text(_session->get_trust, 1, identity->user_id, -1, SQLITE_STATIC);
   702     sqlite3_bind_text(_session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
   703 
   704     result = sqlite3_step(_session->get_trust);
   705     switch (result) {
   706     case SQLITE_ROW: {
   707         const char * user_id = (const char *) sqlite3_column_text(_session->get_trust, 1);
   708         int comm_type = (PEP_comm_type) sqlite3_column_int(_session->get_trust, 2);
   709 
   710         if (strcmp(user_id, identity->user_id) != 0) {
   711             free(identity->user_id);
   712             identity->user_id = strdup(user_id);
   713             assert(identity->user_id);
   714             if (identity->user_id == NULL)
   715                 return PEP_OUT_OF_MEMORY;
   716         }
   717         identity->comm_type = comm_type;
   718         break;
   719     }
   720  
   721     default:
   722         status = PEP_CANNOT_FIND_IDENTITY;
   723     }
   724 
   725     sqlite3_reset(_session->get_trust);
   726     return status;
   727 }
   728 
   729 DYNAMIC_API PEP_STATUS decrypt_and_verify(
   730     PEP_SESSION session, const char *ctext, size_t csize,
   731     char **ptext, size_t *psize, stringlist_t **keylist
   732     )
   733 {
   734     return pgp_decrypt_and_verify(session, ctext, csize, ptext, psize, keylist);
   735 }
   736 
   737 DYNAMIC_API PEP_STATUS encrypt_and_sign(
   738     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
   739     size_t psize, char **ctext, size_t *csize
   740     )
   741 {
   742     return pgp_encrypt_and_sign(session, keylist, ptext, psize, ctext, csize);
   743 }
   744 
   745 DYNAMIC_API PEP_STATUS verify_text(
   746     PEP_SESSION session, const char *text, size_t size,
   747     const char *signature, size_t sig_size, stringlist_t **keylist
   748     )
   749 {
   750     return pgp_verify_text(session, text, size, signature, sig_size, keylist);
   751 }
   752 
   753 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
   754 {
   755     return pgp_delete_keypair(session, fpr);
   756 }
   757 
   758 DYNAMIC_API PEP_STATUS export_key(
   759     PEP_SESSION session, const char *fpr, char **key_data, size_t *size
   760     )
   761 {
   762     return pgp_export_key(session, fpr, key_data, size);
   763 }
   764 
   765 DYNAMIC_API PEP_STATUS find_keys(
   766     PEP_SESSION session, const char *pattern, stringlist_t **keylist
   767     )
   768 {
   769     return pgp_find_keys(session, pattern, keylist);
   770 }
   771 
   772 DYNAMIC_API PEP_STATUS generate_keypair(
   773     PEP_SESSION session, pEp_identity *identity
   774     )
   775 {
   776     return pgp_generate_keypair(session, identity);
   777 }
   778 
   779 DYNAMIC_API PEP_STATUS get_key_rating(
   780     PEP_SESSION session,
   781     const char *fpr,
   782     PEP_comm_type *comm_type
   783     )
   784 {
   785     return pgp_get_key_rating(session, fpr, comm_type);
   786 }
   787 
   788 DYNAMIC_API PEP_STATUS import_key(PEP_SESSION session, const char *key_data, size_t size)
   789 {
   790     return pgp_import_key(session, key_data, size);
   791 }
   792 
   793 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
   794 {
   795     return pgp_recv_key(session, pattern);
   796 }
   797 
   798 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
   799 {
   800     return pgp_send_key(session, pattern);
   801 }