src/pEpEngine.c
author vb
Tue, 23 Sep 2014 23:17:45 +0200
changeset 31 132481aa7ed0
parent 28 7fc9fc3e680c
child 37 7928e0e6eee9
permissions -rw-r--r--
release transport system
     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_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 	pEpSession *_session = (pEpSession *) session;
   236 
   237 	if (_session) {
   238 		if (_session->db) {
   239 			sqlite3_finalize(_session->safeword);
   240 			sqlite3_finalize(_session->log);
   241 			sqlite3_finalize(_session->get_identity);
   242 			sqlite3_finalize(_session->set_identity);
   243             sqlite3_finalize(_session->set_person);
   244             sqlite3_finalize(_session->set_pgp_keypair);
   245             sqlite3_finalize(_session->set_trust);
   246             sqlite3_finalize(_session->get_trust);
   247 
   248 			sqlite3_close_v2(_session->db);
   249 			sqlite3_close_v2(_session->system_db);
   250 		}
   251 
   252         release_transport_system(_session);
   253         release_cryptotech(_session);
   254     }
   255 	free(_session);
   256 }
   257 
   258 stringlist_t *new_stringlist(const char *value)
   259 {
   260     stringlist_t *result = (stringlist_t *) calloc(1, sizeof(stringlist_t));
   261     if (result && value) {
   262         result->value = strdup(value);
   263         assert(result->value);
   264         if (result->value == 0) {
   265             free(result);
   266             return NULL;
   267         }
   268     }
   269     return result;
   270 }
   271 
   272 stringlist_t *stringlist_add(stringlist_t *stringlist, const char *value)
   273 {
   274     assert(value);
   275 
   276     if (stringlist == NULL)
   277         return new_stringlist(value);
   278 
   279     if (stringlist->next != NULL)
   280         return stringlist_add(stringlist->next, value);
   281     if (stringlist->value == NULL) {
   282         stringlist->value = strdup(value);
   283         assert(stringlist->value);
   284         if (stringlist->value == NULL)
   285             return NULL;
   286         return stringlist;
   287     }
   288 
   289     stringlist->next = new_stringlist(value);
   290     assert(stringlist->next);
   291     if (stringlist->next == NULL)
   292         return NULL;
   293 
   294     return stringlist->next;
   295 }
   296 
   297 int stringlist_length(const stringlist_t *stringlist)
   298 {
   299     int len = 1;
   300     stringlist_t *_stringlist;
   301 
   302     assert(stringlist);
   303 
   304     if (stringlist->value == NULL)
   305         return 0;
   306 
   307     for (_stringlist=stringlist->next; _stringlist!=NULL; _stringlist=_stringlist->next)
   308         len += 1;
   309 
   310     return len;
   311 }
   312 
   313 void free_stringlist(stringlist_t *stringlist)
   314 {
   315     if (stringlist) {
   316         free_stringlist(stringlist->next);
   317         free(stringlist->value);
   318         free(stringlist);
   319     }
   320 }
   321 
   322 DYNAMIC_API PEP_STATUS log_event(
   323         PEP_SESSION session, const char *title, const char *entity,
   324         const char *description, const char *comment
   325     )
   326 {
   327 	pEpSession *_session = (pEpSession *) session;
   328 	PEP_STATUS status = PEP_STATUS_OK;
   329 	int result;
   330 
   331 	assert(_session);
   332 	assert(title);
   333 	assert(entity);
   334 
   335 	sqlite3_reset(_session->log);
   336 	sqlite3_bind_text(_session->log, 1, title, -1, SQLITE_STATIC);
   337 	sqlite3_bind_text(_session->log, 2, entity, -1, SQLITE_STATIC);
   338 	if (description)
   339         sqlite3_bind_text(_session->log, 3, description, -1, SQLITE_STATIC);
   340 	else
   341 		sqlite3_bind_null(_session->log, 3);
   342 	if (comment)
   343 		sqlite3_bind_text(_session->log, 4, comment, -1, SQLITE_STATIC);
   344 	else
   345 		sqlite3_bind_null(_session->log, 4);
   346 	do {
   347 		result = sqlite3_step(_session->log);
   348 		assert(result == SQLITE_DONE || result == SQLITE_BUSY);
   349 		if (result != SQLITE_DONE && result != SQLITE_BUSY)
   350 			status = PEP_UNKNOWN_ERROR;
   351 	} while (result == SQLITE_BUSY);
   352 	sqlite3_reset(_session->log);
   353 
   354 	return status;
   355 }
   356 
   357 DYNAMIC_API PEP_STATUS safeword(
   358             PEP_SESSION session, uint16_t value, const char *lang,
   359             char **word, size_t *wsize
   360         )
   361 {
   362 	pEpSession *_session = (pEpSession *) session;
   363 	PEP_STATUS status = PEP_STATUS_OK;
   364 	int result;
   365 
   366 	assert(_session);
   367 	assert(word);
   368 	assert(wsize);
   369 
   370 	*word = NULL;
   371 	*wsize = 0;
   372 
   373 	if (lang == NULL)
   374 		lang = "en";
   375 
   376 	assert((lang[0] >= 'A' && lang[0] <= 'Z')
   377             || (lang[0] >= 'a' && lang[0] <= 'z'));
   378 	assert((lang[1] >= 'A' && lang[1] <= 'Z')
   379             || (lang[1] >= 'a' && lang[1] <= 'z'));
   380 	assert(lang[2] == 0);
   381 
   382 	sqlite3_reset(_session->safeword);
   383     sqlite3_bind_text(_session->safeword, 1, lang, -1, SQLITE_STATIC);
   384 	sqlite3_bind_int(_session->safeword, 2, value);
   385 
   386 	result = sqlite3_step(_session->safeword);
   387 	if (result == SQLITE_ROW) {
   388         *word = strdup((const char *) sqlite3_column_text(_session->safeword,
   389                     1));
   390 		if (*word)
   391             *wsize = sqlite3_column_bytes(_session->safeword, 1);
   392 		else
   393 			status = PEP_SAFEWORD_NOT_FOUND;
   394 	} else
   395 		status = PEP_SAFEWORD_NOT_FOUND;
   396 
   397 	sqlite3_reset(_session->safeword);
   398 	return status;
   399 }
   400 
   401 DYNAMIC_API PEP_STATUS safewords(
   402         PEP_SESSION session, const char *fingerprint, const char *lang,
   403         char **words, size_t *wsize, int max_words
   404     )
   405 {
   406 	const char *source = fingerprint;
   407 	char *buffer = calloc(1, MAX_SAFEWORDS_SPACE);
   408 	char *dest = buffer;
   409 	size_t fsize;
   410     PEP_STATUS _status;
   411 
   412 	assert(session);
   413 	assert(fingerprint);
   414 	assert(words);
   415 	assert(wsize);
   416 	assert(max_words >= 0);
   417 
   418 	*words = NULL;
   419 	*wsize = 0;
   420 
   421     assert(buffer);
   422     if (buffer == NULL)
   423         return PEP_OUT_OF_MEMORY;
   424 
   425 	fsize = strlen(fingerprint);
   426 
   427 	if (lang == NULL)
   428 		lang = "en";
   429 
   430 	assert((lang[0] >= 'A' && lang[0] <= 'Z')
   431             || (lang[0] >= 'a' && lang[0] <= 'z'));
   432 	assert((lang[1] >= 'A' && lang[1] <= 'Z')
   433             || (lang[1] >= 'a' && lang[1] <= 'z'));
   434 	assert(lang[2] == 0);
   435 
   436 	int n_words = 0;
   437 	while (source < fingerprint + fsize) {
   438 		uint16_t value;
   439 		char *word;
   440 		size_t _wsize;
   441 		int j;
   442 
   443         for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
   444 			if (*source >= 'a' && *source <= 'f')
   445 				value += (*source - 'a' + 10) << (3 - j++) * 4;
   446 			else if (*source >= 'A' && *source <= 'F')
   447 				value += (*source - 'A' + 10) << (3 - j++) * 4;
   448 			else if (*source >= '0' && *source <= '9')
   449 				value += (*source - '0') << (3 - j++) * 4;
   450 			
   451 			source++;
   452 		}
   453 
   454 		_status = safeword(session, value, lang, &word, &_wsize);
   455         if (_status == PEP_OUT_OF_MEMORY) {
   456             free(buffer);
   457             return PEP_OUT_OF_MEMORY;
   458         }
   459 		if (word == NULL) {
   460             free(buffer);
   461 			return PEP_SAFEWORD_NOT_FOUND;
   462         }
   463 
   464 		if (dest + _wsize < buffer + MAX_SAFEWORDS_SPACE - 1) {
   465 			strncpy(dest, word, _wsize);
   466             free(word);
   467 			dest += _wsize;
   468 		}
   469 		else {
   470             free(word);
   471 			break; // buffer full
   472         }
   473 
   474 		if (source < fingerprint + fsize
   475                 && dest + _wsize < buffer + MAX_SAFEWORDS_SPACE - 1)
   476 			*dest++ = ' ';
   477 
   478 		++n_words;
   479 		if (max_words && n_words >= max_words)
   480 			break;
   481 	}
   482 
   483 	*words = buffer;
   484 	*wsize = dest - buffer;
   485 	return PEP_STATUS_OK;
   486 }
   487 
   488 pEp_identity *new_identity(
   489         const char *address, const char *fpr, const char *user_id,
   490         const char *username
   491     )
   492 {
   493     pEp_identity *result = calloc(1, sizeof(pEp_identity));
   494     assert(result);
   495     if (result) {
   496         if (address) {
   497             result->address = strdup(address);
   498             assert(result->address);
   499             if (result->address == NULL) {
   500                 free(result);
   501                 return NULL;
   502             }
   503             result->address_size = strlen(address);
   504         }
   505         if (fpr) {
   506             result->fpr = strdup(fpr);
   507             assert(result->fpr);
   508             if (result->fpr == NULL) {
   509                 free_identity(result);
   510                 return NULL;
   511             }
   512             result->fpr_size = strlen(fpr);
   513         }
   514         if (user_id) {
   515             result->user_id = strdup(user_id);
   516             assert(result->user_id);
   517             if (result->user_id == NULL) {
   518                 free_identity(result);
   519                 return NULL;
   520             }
   521             result->user_id_size = strlen(user_id);
   522         }
   523         if (username) {
   524             result->username = strdup(username);
   525             assert(result->username);
   526             if (result->username == NULL) {
   527                 free_identity(result);
   528                 return NULL;
   529             }
   530             result->username_size = strlen(username);
   531         }
   532         result->struct_size = sizeof(pEp_identity);
   533     }
   534     return result;
   535 }
   536 
   537 void free_identity(pEp_identity *identity)
   538 {
   539     if (identity) {
   540         free(identity->address);
   541         free(identity->fpr);
   542         free(identity->user_id);
   543         free(identity->username);
   544         free(identity);
   545     }
   546 }
   547 
   548 DYNAMIC_API PEP_STATUS get_identity(
   549         PEP_SESSION session, const char *address,
   550         pEp_identity **identity
   551     )
   552 {
   553 	pEpSession *_session = (pEpSession *) session;
   554 	PEP_STATUS status = PEP_STATUS_OK;
   555 	static pEp_identity *_identity;
   556 	int result;
   557 	const char *_lang;
   558 
   559 	assert(session);
   560 	assert(address);
   561     assert(address[0]);
   562 
   563     sqlite3_reset(_session->get_identity);
   564     sqlite3_bind_text(_session->get_identity, 1, address, -1, SQLITE_STATIC);
   565 
   566     result = sqlite3_step(_session->get_identity);
   567 	switch (result) {
   568 	case SQLITE_ROW:
   569         _identity = new_identity(
   570                 address,
   571                 (const char *) sqlite3_column_text(_session->get_identity, 0),
   572                 (const char *) sqlite3_column_text(_session->get_identity, 1),
   573                 (const char *) sqlite3_column_text(_session->get_identity, 2)
   574                 );
   575         assert(_identity);
   576         if (_identity == NULL)
   577             return PEP_OUT_OF_MEMORY;
   578 
   579         _identity->comm_type = (PEP_comm_type) sqlite3_column_int(_session->get_identity, 3);
   580         _lang = (const char *) sqlite3_column_text(_session->get_identity, 4);
   581         if (_lang && _lang[0]) {
   582 			assert(_lang[0] >= 'a' && _lang[0] <= 'z');
   583 			assert(_lang[1] >= 'a' && _lang[1] <= 'z');
   584 			assert(_lang[2] == 0);
   585 			_identity->lang[0] = _lang[0];
   586 			_identity->lang[1] = _lang[1];
   587             _identity->lang[2] = 0;
   588 		}
   589 		*identity = _identity;
   590 		break;
   591 	default:
   592         status = PEP_CANNOT_FIND_IDENTITY;
   593 		*identity = NULL;
   594 	}
   595 
   596     sqlite3_reset(_session->get_identity);
   597 	return status;
   598 }
   599 
   600 DYNAMIC_API PEP_STATUS set_identity(
   601         PEP_SESSION session, const pEp_identity *identity
   602     )
   603 {
   604 	pEpSession *_session = (pEpSession *) session;
   605 	int result;
   606 
   607 	assert(session);
   608 	assert(identity);
   609 	assert(identity->address);
   610 	assert(identity->fpr);
   611 	assert(identity->user_id);
   612 	assert(identity->username);
   613 
   614 	sqlite3_exec(_session->db, "BEGIN ;", NULL, NULL, NULL);
   615 
   616 	sqlite3_reset(_session->set_person);
   617     sqlite3_bind_text(_session->set_person, 1, identity->user_id, -1,
   618             SQLITE_STATIC);
   619     sqlite3_bind_text(_session->set_person, 2, identity->username, -1,
   620             SQLITE_STATIC);
   621 	if (identity->lang[0])
   622         sqlite3_bind_text(_session->set_person, 3, identity->lang, 1,
   623                 SQLITE_STATIC);
   624 	else
   625 		sqlite3_bind_null(_session->set_person, 3);
   626 	result = sqlite3_step(_session->set_person);
   627 	sqlite3_reset(_session->set_person);
   628 	if (result != SQLITE_DONE) {
   629 		sqlite3_exec(_session->db, "ROLLBACK ;", NULL, NULL, NULL);
   630 		return PEP_CANNOT_SET_PERSON;
   631 	}
   632 
   633 	sqlite3_reset(_session->set_pgp_keypair);
   634     sqlite3_bind_text(_session->set_pgp_keypair, 1, identity->fpr, -1,
   635             SQLITE_STATIC);
   636 	result = sqlite3_step(_session->set_pgp_keypair);
   637 	sqlite3_reset(_session->set_pgp_keypair);
   638 	if (result != SQLITE_DONE) {
   639 		sqlite3_exec(_session->db, "ROLLBACK ;", NULL, NULL, NULL);
   640 		return PEP_CANNOT_SET_PGP_KEYPAIR;
   641 	}
   642 
   643 	sqlite3_reset(_session->set_identity);
   644     sqlite3_bind_text(_session->set_identity, 1, identity->address, -1,
   645             SQLITE_STATIC);
   646     sqlite3_bind_text(_session->set_identity, 2, identity->fpr, -1,
   647             SQLITE_STATIC);
   648     sqlite3_bind_text(_session->set_identity, 3, identity->user_id, -1,
   649             SQLITE_STATIC);
   650 	result = sqlite3_step(_session->set_identity);
   651 	sqlite3_reset(_session->set_identity);
   652 	if (result != SQLITE_DONE) {
   653 		sqlite3_exec(_session->db, "ROLLBACK ;", NULL, NULL, NULL);
   654 		return PEP_CANNOT_SET_IDENTITY;
   655 	}
   656 
   657 	sqlite3_reset(_session->set_trust);
   658     sqlite3_bind_text(_session->set_trust, 1, identity->user_id, -1,
   659             SQLITE_STATIC);
   660     sqlite3_bind_text(_session->set_trust, 2, identity->fpr, -1,
   661             SQLITE_STATIC);
   662 	sqlite3_bind_int(_session->set_trust, 3, identity->comm_type);
   663 	result = sqlite3_step(_session->set_trust);
   664 	sqlite3_reset(_session->set_trust);
   665 	if (result != SQLITE_DONE) {
   666 		sqlite3_exec(_session->db, "ROLLBACK ;", NULL, NULL, NULL);
   667 		return PEP_CANNOT_SET_IDENTITY;
   668 	}
   669 
   670     result = sqlite3_exec(_session->db, "COMMIT ;", NULL, NULL, NULL);
   671 	if (result == SQLITE_OK)
   672 		return PEP_STATUS_OK;
   673 	else
   674 		return PEP_COMMIT_FAILED;
   675 }
   676 
   677 void pEp_free(void *p)
   678 {
   679     free(p);
   680 }
   681 
   682 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
   683 {
   684     pEpSession *_session = (pEpSession *) session;
   685     PEP_STATUS status = PEP_STATUS_OK;
   686     int result;
   687 
   688     assert(session);
   689     assert(identity);
   690     assert(identity->user_id);
   691     assert(identity->user_id[0]);
   692     assert(identity->fpr);
   693     assert(identity->fpr[0]);
   694 
   695     identity->comm_type = PEP_ct_unknown;
   696 
   697     sqlite3_reset(_session->get_trust);
   698     sqlite3_bind_text(_session->get_trust, 1, identity->user_id, -1, SQLITE_STATIC);
   699     sqlite3_bind_text(_session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
   700 
   701     result = sqlite3_step(_session->get_trust);
   702     switch (result) {
   703     case SQLITE_ROW: {
   704         const char * user_id = (const char *) sqlite3_column_text(_session->get_trust, 1);
   705         int comm_type = (PEP_comm_type) sqlite3_column_int(_session->get_trust, 2);
   706 
   707         if (strcmp(user_id, identity->user_id) != 0) {
   708             free(identity->user_id);
   709             identity->user_id = strdup(user_id);
   710             assert(identity->user_id);
   711             if (identity->user_id == NULL)
   712                 return PEP_OUT_OF_MEMORY;
   713         }
   714         identity->comm_type = comm_type;
   715         break;
   716     }
   717  
   718     default:
   719         status = PEP_CANNOT_FIND_IDENTITY;
   720     }
   721 
   722     sqlite3_reset(_session->get_trust);
   723     return status;
   724 }
   725 
   726 DYNAMIC_API PEP_STATUS decrypt_and_verify(
   727     PEP_SESSION session, const char *ctext, size_t csize,
   728     char **ptext, size_t *psize, stringlist_t **keylist
   729     )
   730 {
   731     pEpSession *_session = (pEpSession *) session;
   732     return _session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(session, ctext, csize, ptext, psize, keylist);
   733 }
   734 
   735 DYNAMIC_API PEP_STATUS encrypt_and_sign(
   736     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
   737     size_t psize, char **ctext, size_t *csize
   738     )
   739 {
   740     pEpSession *_session = (pEpSession *) session;
   741     return _session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session, keylist, ptext, psize, ctext, csize);
   742 }
   743 
   744 DYNAMIC_API PEP_STATUS verify_text(
   745     PEP_SESSION session, const char *text, size_t size,
   746     const char *signature, size_t sig_size, stringlist_t **keylist
   747     )
   748 {
   749     pEpSession *_session = (pEpSession *) session;
   750     return _session->cryptotech[PEP_crypt_OpenPGP].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     pEpSession *_session = (pEpSession *) session;
   756     return _session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
   757 }
   758 
   759 DYNAMIC_API PEP_STATUS export_key(
   760     PEP_SESSION session, const char *fpr, char **key_data, size_t *size
   761     )
   762 {
   763     pEpSession *_session = (pEpSession *) session;
   764     return _session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr, key_data, size);
   765 }
   766 
   767 DYNAMIC_API PEP_STATUS find_keys(
   768     PEP_SESSION session, const char *pattern, stringlist_t **keylist
   769     )
   770 {
   771     pEpSession *_session = (pEpSession *) session;
   772     return _session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern, keylist);
   773 }
   774 
   775 DYNAMIC_API PEP_STATUS generate_keypair(
   776     PEP_SESSION session, pEp_identity *identity
   777     )
   778 {
   779     pEpSession *_session = (pEpSession *) session;
   780     return _session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session, identity);
   781 }
   782 
   783 DYNAMIC_API PEP_STATUS get_key_rating(
   784     PEP_SESSION session,
   785     const char *fpr,
   786     PEP_comm_type *comm_type
   787     )
   788 {
   789     pEpSession *_session = (pEpSession *) session;
   790     return _session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr, comm_type);
   791 }
   792 
   793 DYNAMIC_API PEP_STATUS import_key(PEP_SESSION session, const char *key_data, size_t size)
   794 {
   795     pEpSession *_session = (pEpSession *) session;
   796     return _session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data, size);
   797 }
   798 
   799 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
   800 {
   801     pEpSession *_session = (pEpSession *) session;
   802     return _session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
   803 }
   804 
   805 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
   806 {
   807     pEpSession *_session = (pEpSession *) session;
   808     return _session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
   809 }