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