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