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