1 // This file is under GNU General Public License 3.0
12 #include "pEp_internal.h"
13 #include "keymanagement.h"
15 #include "blacklist.h"
17 static bool key_matches_address(PEP_SESSION session, const char* address,
19 if (!session || !address || !fpr)
23 stringlist_t *keylist = NULL;
24 PEP_STATUS status = find_keys(session, address, &keylist);
25 if (status == PEP_STATUS_OK && keylist) {
26 stringlist_t* curr = keylist;
29 if (strcasecmp(curr->value, fpr)) {
38 free_stringlist(keylist);
42 PEP_STATUS elect_pubkey(
43 PEP_SESSION session, pEp_identity * identity, bool check_blacklist
47 stringlist_t *keylist = NULL;
49 identity->comm_type = PEP_ct_unknown;
51 status = find_keys(session, identity->address, &keylist);
52 assert(status != PEP_OUT_OF_MEMORY);
53 if (status == PEP_OUT_OF_MEMORY)
54 return PEP_OUT_OF_MEMORY;
56 if (!keylist || !keylist->value)
57 identity->comm_type = PEP_ct_key_not_found;
59 stringlist_t *_keylist;
60 for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
61 PEP_comm_type _comm_type_key;
63 status = get_key_rating(session, _keylist->value, &_comm_type_key);
64 assert(status != PEP_OUT_OF_MEMORY);
65 if (status == PEP_OUT_OF_MEMORY) {
66 free_stringlist(keylist);
67 return PEP_OUT_OF_MEMORY;
70 if (_comm_type_key != PEP_ct_compromised &&
71 _comm_type_key != PEP_ct_unknown)
73 if (identity->comm_type == PEP_ct_unknown ||
74 _comm_type_key > identity->comm_type)
76 bool blacklisted = false;
77 bool mistrusted = false;
78 status = is_mistrusted_key(session, _keylist->value, &mistrusted);
79 if (status == PEP_STATUS_OK && check_blacklist)
80 status = blacklist_is_listed(session, _keylist->value, &blacklisted);
81 if (status == PEP_STATUS_OK && !mistrusted && !blacklisted) {
82 identity->comm_type = _comm_type_key;
83 _fpr = _keylist->value;
91 if (!_fpr || _fpr[0] == '\0')
94 identity->fpr = strdup(_fpr);
95 if (identity->fpr == NULL) {
96 free_stringlist(keylist);
97 return PEP_OUT_OF_MEMORY;
101 free_stringlist(keylist);
102 return PEP_STATUS_OK;
106 // own_must_contain_private is usually true when calling;
107 // we only set it to false when we have the idea of
108 // possibly having an own pubkey that we need to check on its own
109 static PEP_STATUS validate_fpr(PEP_SESSION session,
111 bool check_blacklist,
112 bool own_must_contain_private) {
114 PEP_STATUS status = PEP_STATUS_OK;
116 if (!session || !ident || !ident->fpr || !ident->fpr[0])
117 return PEP_ILLEGAL_VALUE;
119 char* fpr = ident->fpr;
121 bool has_private = false;
122 status = contains_priv_key(session, fpr, &has_private);
124 if (ident->me && own_must_contain_private) {
125 if (status != PEP_STATUS_OK || !has_private)
126 return PEP_KEY_UNSUITABLE;
128 else if (status != PEP_STATUS_OK && has_private) // should never happen
131 status = get_trust(session, ident);
132 if (status != PEP_STATUS_OK)
133 ident->comm_type = PEP_ct_unknown;
135 PEP_comm_type ct = ident->comm_type;
137 if (ct == PEP_ct_unknown) {
138 // If status is bad, it's ok, we get the rating
139 // we should use then (PEP_ct_unknown)
140 get_key_rating(session, fpr, &ct);
141 ident->comm_type = ct;
143 else if (ct == PEP_ct_key_expired || ct == PEP_ct_key_expired_but_confirmed) {
144 PEP_comm_type ct_expire_check = PEP_ct_unknown;
145 get_key_rating(session, fpr, &ct_expire_check);
146 if (ct_expire_check >= PEP_ct_strong_but_unconfirmed) {
147 ident->comm_type = ct_expire_check;
148 if (ct == PEP_ct_key_expired_but_confirmed)
149 ident->comm_type |= PEP_ct_confirmed;
150 ct = ident->comm_type;
151 // We need to fix this trust in the DB.
152 status = set_trust(session, ident);
157 bool pEp_user = false;
159 is_pEp_user(session, ident, &pEp_user);
164 case PEP_ct_OpenPGP_unconfirmed:
165 ct += 0x47; // difference between PEP and OpenPGP values;
166 ident->comm_type = ct;
173 bool revoked, expired;
174 bool blacklisted = false;
176 status = key_revoked(session, fpr, &revoked);
178 if (status != PEP_STATUS_OK) {
183 time_t exp_time = (ident->me ?
184 time(NULL) + (7*24*3600) : time(NULL));
186 status = key_expired(session, fpr,
190 assert(status == PEP_STATUS_OK);
191 if (status != PEP_STATUS_OK)
194 if (check_blacklist && IS_PGP_CT(ct) &&
196 status = blacklist_is_listed(session,
200 if (status != PEP_STATUS_OK)
205 if (ident->me && has_private &&
206 (ct >= PEP_ct_strong_but_unconfirmed) &&
207 !revoked && expired) {
209 timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
210 status = renew_key(session, fpr, ts);
213 if (status == PEP_STATUS_OK) {
214 // if key is valid (second check because pEp key might be extended above)
216 status = key_expired(session, fpr, time(NULL), &expired);
217 if (status != PEP_STATUS_OK)
221 if (ident->comm_type & PEP_ct_confirmed || (ident->comm_type == PEP_ct_key_expired_but_confirmed))
222 ident->comm_type = PEP_ct_key_expired_but_confirmed;
224 ident->comm_type = PEP_ct_key_expired;
227 // communicate key(?)
232 ct = PEP_ct_key_revoked;
234 if (ident->comm_type & PEP_ct_confirmed || (ident->comm_type == PEP_ct_key_expired_but_confirmed))
235 ct = PEP_ct_key_expired_but_confirmed;
237 ct = PEP_ct_key_expired;
239 else if (blacklisted) { // never true for .me
240 ident->comm_type = ct = PEP_ct_key_not_found;
242 ident->fpr = strdup("");
243 status = PEP_KEY_BLACKLISTED;
247 case PEP_ct_key_expired:
248 case PEP_ct_key_expired_but_confirmed:
249 case PEP_ct_key_revoked:
250 case PEP_ct_key_b0rken:
251 // delete key from being default key for all users/identities
252 status = remove_fpr_as_default(session, fpr);
253 status = update_trust_for_fpr(session,
256 case PEP_ct_mistrusted:
259 ident->comm_type = ct;
260 status = PEP_KEY_UNSUITABLE;
268 PEP_STATUS get_all_keys_for_user(PEP_SESSION session,
270 stringlist_t** keys) {
272 if (!session || EMPTYSTR(user_id) || !keys)
273 return PEP_ILLEGAL_VALUE;
275 PEP_STATUS status = PEP_STATUS_OK;
278 stringlist_t* _kl = NULL;
280 sqlite3_reset(session->get_all_keys_for_user);
281 sqlite3_bind_text(session->get_all_keys_for_user, 1, user_id, -1, SQLITE_STATIC);
285 while ((result = sqlite3_step(session->get_all_keys_for_user)) == SQLITE_ROW) {
286 const char* keyres = (const char *) sqlite3_column_text(session->get_all_keys_for_user, 0);
289 stringlist_add(_kl, keyres);
291 _kl = new_stringlist(keyres);
296 return PEP_KEY_NOT_FOUND;
300 sqlite3_reset(session->get_all_keys_for_user);
305 PEP_STATUS get_user_default_key(PEP_SESSION session, const char* user_id,
306 char** default_key) {
310 if (!session || !user_id)
311 return PEP_ILLEGAL_VALUE;
313 PEP_STATUS status = PEP_STATUS_OK;
315 // try to get default key for user_data
316 sqlite3_reset(session->get_user_default_key);
317 sqlite3_bind_text(session->get_user_default_key, 1, user_id,
320 const int result = sqlite3_step(session->get_user_default_key);
321 char* user_fpr = NULL;
322 if (result == SQLITE_ROW) {
324 (char *) sqlite3_column_text(session->get_user_default_key, 0);
326 user_fpr = strdup(u_fpr);
329 status = PEP_GET_KEY_FAILED;
331 sqlite3_reset(session->get_user_default_key);
333 *default_key = user_fpr;
337 // Only call on retrieval of previously stored identity!
338 // Also, we presume that if the stored_identity was sent in
339 // without an fpr, there wasn't one in the trust DB for this
341 PEP_STATUS get_valid_pubkey(PEP_SESSION session,
342 pEp_identity* stored_identity,
343 bool* is_identity_default,
344 bool* is_user_default,
345 bool* is_address_default,
346 bool check_blacklist) {
348 PEP_STATUS status = PEP_STATUS_OK;
350 if (!stored_identity || EMPTYSTR(stored_identity->user_id)
351 || !is_identity_default || !is_user_default || !is_address_default)
352 return PEP_ILLEGAL_VALUE;
354 *is_identity_default = *is_user_default = *is_address_default = false;
356 PEP_comm_type first_reject_comm_type = PEP_ct_key_not_found;
357 PEP_STATUS first_reject_status = PEP_KEY_NOT_FOUND;
359 char* stored_fpr = stored_identity->fpr;
360 // Input: stored identity retrieved from database
361 // if stored identity contains a default key
362 if (!EMPTYSTR(stored_fpr)) {
363 status = validate_fpr(session, stored_identity, check_blacklist, true);
364 if (status == PEP_STATUS_OK && !EMPTYSTR(stored_identity->fpr)) {
365 *is_identity_default = *is_address_default = true;
368 else if (status != PEP_KEY_NOT_FOUND) {
369 first_reject_status = status;
370 first_reject_comm_type = stored_identity->comm_type;
373 // if no valid default stored identity key found
374 free(stored_identity->fpr);
375 stored_identity->fpr = NULL;
377 char* user_fpr = NULL;
378 status = get_user_default_key(session, stored_identity->user_id, &user_fpr);
380 if (!EMPTYSTR(user_fpr)) {
381 // There exists a default key for user, so validate
382 stored_identity->fpr = user_fpr;
383 status = validate_fpr(session, stored_identity, check_blacklist, true);
384 if (status == PEP_STATUS_OK && stored_identity->fpr) {
385 *is_user_default = true;
386 *is_address_default = key_matches_address(session,
387 stored_identity->address,
388 stored_identity->fpr);
391 else if (status != PEP_KEY_NOT_FOUND && first_reject_status != PEP_KEY_NOT_FOUND) {
392 first_reject_status = status;
393 first_reject_comm_type = stored_identity->comm_type;
397 status = elect_pubkey(session, stored_identity, check_blacklist);
398 if (status == PEP_STATUS_OK) {
399 if (!EMPTYSTR(stored_identity->fpr))
400 validate_fpr(session, stored_identity, false, true); // blacklist already filtered of needed
402 else if (status != PEP_KEY_NOT_FOUND && first_reject_status != PEP_KEY_NOT_FOUND) {
403 first_reject_status = status;
404 first_reject_comm_type = stored_identity->comm_type;
407 switch (stored_identity->comm_type) {
408 case PEP_ct_key_revoked:
409 case PEP_ct_key_b0rken:
410 case PEP_ct_key_expired:
411 case PEP_ct_key_expired_but_confirmed:
412 case PEP_ct_compromised:
413 case PEP_ct_mistrusted:
414 // this only happens when it's all there is
415 status = first_reject_status;
416 free(stored_identity->fpr);
417 stored_identity->fpr = NULL;
418 stored_identity->comm_type = first_reject_comm_type;
421 if (check_blacklist && status == PEP_KEY_BLACKLISTED) {
422 free(stored_identity->fpr);
423 stored_identity->fpr = NULL;
424 stored_identity->comm_type = PEP_ct_key_not_found;
431 static void transfer_ident_lang_and_flags(pEp_identity* new_ident,
432 pEp_identity* stored_ident) {
433 if (new_ident->lang[0] == 0) {
434 new_ident->lang[0] = stored_ident->lang[0];
435 new_ident->lang[1] = stored_ident->lang[1];
436 new_ident->lang[2] = 0;
439 new_ident->flags = stored_ident->flags;
440 new_ident->me = new_ident->me || stored_ident->me;
443 static void adjust_pEp_trust_status(PEP_SESSION session, pEp_identity* identity) {
447 if (identity->comm_type < PEP_ct_strong_but_unconfirmed ||
448 (identity->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
453 is_pEp_user(session, identity, &pEp_user);
456 PEP_comm_type confirmation_status = identity->comm_type & PEP_ct_confirmed;
457 identity->comm_type = PEP_ct_pEp_unconfirmed | confirmation_status;
462 static PEP_STATUS prepare_updated_identity(PEP_SESSION session,
463 pEp_identity* return_id,
464 pEp_identity* stored_ident,
467 if (!session || !return_id || !stored_ident)
468 return PEP_ILLEGAL_VALUE;
472 bool is_identity_default, is_user_default, is_address_default;
473 status = get_valid_pubkey(session, stored_ident,
474 &is_identity_default,
479 if (status == PEP_STATUS_OK && stored_ident->fpr && *(stored_ident->fpr) != '\0') {
480 // set identity comm_type from trust db (user_id, FPR)
481 status = get_trust(session, stored_ident);
482 if (status == PEP_CANNOT_FIND_IDENTITY || stored_ident->comm_type == PEP_ct_unknown) {
483 // This is OK - there is no trust DB entry, but we
484 // found a key. We won't store this, but we'll
486 PEP_comm_type ct = PEP_ct_unknown;
487 status = get_key_rating(session, stored_ident->fpr, &ct);
488 stored_ident->comm_type = ct;
492 if (stored_ident->comm_type == PEP_ct_unknown)
493 stored_ident->comm_type = PEP_ct_key_not_found;
495 free(return_id->fpr);
496 return_id->fpr = NULL;
497 if (status == PEP_STATUS_OK && !EMPTYSTR(stored_ident->fpr))
498 return_id->fpr = strdup(stored_ident->fpr);
500 return_id->comm_type = stored_ident->comm_type;
502 // We patch the DB with the input username, but if we didn't have
503 // one, we pull it out of storage if available.
504 // (also, if the input username is "anonymous" and there exists
505 // a DB username, we replace)
506 if (!EMPTYSTR(stored_ident->username)) {
507 if (!EMPTYSTR(return_id->username) &&
508 (strcasecmp(return_id->username, return_id->address) == 0)) {
509 free(return_id->username);
510 return_id->username = NULL;
512 if (EMPTYSTR(return_id->username)) {
513 free(return_id->username);
514 return_id->username = strdup(stored_ident->username);
518 if (EMPTYSTR(return_id->username))
519 return_id->username = strdup(return_id->address);
522 return_id->me = stored_ident->me;
524 // FIXME: Do we ALWAYS do this? We probably should...
525 if (EMPTYSTR(return_id->user_id)) {
526 free(return_id->user_id);
527 return_id->user_id = strdup(stored_ident->user_id);
530 adjust_pEp_trust_status(session, return_id);
532 // Call set_identity() to store
533 if ((is_identity_default || is_user_default) &&
534 is_address_default) {
535 // if we got an fpr which is default for either user
536 // or identity AND is valid for this address, set in DB
538 status = set_identity(session, return_id);
541 // Store without default fpr/ct, but return the fpr and ct
543 char* save_fpr = return_id->fpr;
544 PEP_comm_type save_ct = return_id->comm_type;
545 return_id->fpr = NULL;
546 return_id->comm_type = PEP_ct_unknown;
547 PEP_STATUS save_status = status;
548 status = set_identity(session, return_id);
549 if (save_status != PEP_STATUS_OK)
550 status = save_status;
551 return_id->fpr = save_fpr;
552 return_id->comm_type = save_ct;
555 transfer_ident_lang_and_flags(return_id, stored_ident);
557 if (return_id->comm_type == PEP_ct_unknown)
558 return_id->comm_type = PEP_ct_key_not_found;
563 DYNAMIC_API PEP_STATUS update_identity(
564 PEP_SESSION session, pEp_identity * identity
571 assert(!EMPTYSTR(identity->address));
573 if (!(session && identity && !EMPTYSTR(identity->address)))
574 return PEP_ILLEGAL_VALUE;
576 char* default_own_id = NULL;
577 status = get_default_own_userid(session, &default_own_id);
579 bool is_own_user = identity->me;
581 // Is this me, temporary or not? If so, BAIL.
583 if (default_own_id) {
584 if (!EMPTYSTR(identity->user_id)) {
585 if (strcmp(default_own_id, identity->user_id) == 0) {
590 if (get_userid_alias_default(session, identity->user_id, &alias) == PEP_STATUS_OK) {
591 if (alias && strcmp(default_own_id, alias) == 0)
598 // Check if own address. For now, this is a special case;
599 // we try to require apps to send in user_ids, but must prevent
600 // writes to an own identity from within THIS function
601 // NOTE: These semantics MAY CHANGE.
602 bool _own_addr = false;
603 is_own_address(session, identity->address, &_own_addr);
605 // N.B. KB: I would prefer consistent semantics here - that is to say,
606 // we also set is_own_user here and force PEP_ILLEGAL_VALUE
608 free(identity->user_id);
609 identity->user_id = strdup(default_own_id);
610 return _myself(session, identity, false, false, true);
614 // Otherwise, we don't even HAVE an own user yet, so we're ok.
618 free(default_own_id);
619 return PEP_ILLEGAL_VALUE;
622 // We have, at least, an address.
623 // Retrieve stored identity information!
624 pEp_identity* stored_ident = NULL;
626 if (!EMPTYSTR(identity->user_id)) {
627 // (we're gonna update the trust/fpr anyway, so we use the no-fpr-from-trust-db variant)
628 // * do get_identity() to retrieve stored identity information
629 status = get_identity_without_trust_check(session, identity->address, identity->user_id, &stored_ident);
631 // Before we start - if there was no stored identity, we should check to make sure we don't
632 // have a stored identity with a temporary user_id that differs from the input user_id. This
633 // happens in multithreaded environments sometimes.
635 identity_list* id_list = NULL;
636 status = get_identities_by_address(session, identity->address, &id_list);
639 identity_list* id_curr = id_list;
640 bool input_is_TOFU = (strstr(identity->user_id, "TOFU_") == identity->user_id);
642 pEp_identity* this_id = id_curr->ident;
644 char* this_uid = this_id->user_id;
645 bool curr_is_TOFU = false;
646 // this_uid should never be NULL, as this is half of the ident
648 assert(!EMPTYSTR(this_uid));
650 curr_is_TOFU = (strstr(this_uid, "TOFU_") == this_uid);
651 if (curr_is_TOFU && !input_is_TOFU) {
652 // FIXME: should we also be fixing pEp_own_userId in this
655 // if usernames match, we replace the userid. Or if the temp username
657 // FIXME: do we need to create an address match function which
658 // matches the whole dot-and-case rigamarole from
659 if (EMPTYSTR(this_id->username) ||
660 strcasecmp(this_id->username, this_id->address) == 0 ||
661 (identity->username &&
662 strcasecmp(identity->username,
663 this_id->username) == 0)) {
665 // Ok, we have a temp ID. We have to replace this
667 status = replace_userid(session,
670 if (status != PEP_STATUS_OK) {
671 free_identity_list(id_list);
672 free(default_own_id);
679 // Reflect the change we just made to the DB
680 this_id->user_id = strdup(identity->user_id);
681 stored_ident = this_id;
686 else if (input_is_TOFU && !curr_is_TOFU) {
687 // Replace ruthlessly - this is NOT supposed to happen.
688 // BAD APP BEHAVIOUR.
689 free(identity->user_id);
690 identity->user_id = strdup(this_id->user_id);
691 stored_ident = this_id;
696 id_curr = id_curr->next;
701 if (status == PEP_STATUS_OK && stored_ident) {
702 // * if identity available
703 // * patch it with username
704 // (note: this will happen when
705 // setting automatically below...)
706 // * elect valid key for identity
707 // * if valid key exists
708 // * set return value's fpr
709 status = prepare_updated_identity(session,
713 // * else (identity unavailable)
715 status = PEP_STATUS_OK;
717 // FIXME: We may need to roll this back.
718 // FIXME: change docs if we don't
719 // if we only have user_id and address and identity not available
720 // * return error status (identity not found)
721 if (EMPTYSTR(identity->username)) {
722 free(identity->username);
723 identity->username = strdup(identity->address);
726 // Otherwise, if we had user_id, address, and username:
727 // * create identity with user_id, address, username
728 // (this is the input id without the fpr + comm type!)
730 elect_pubkey(session, identity, false);
732 // * We've already checked and retrieved
733 // any applicable temporary identities above. If we're
734 // here, none of them fit.
735 // * call set_identity() to store
736 // FIXME: Do we set if we had to copy in the address?
737 adjust_pEp_trust_status(session, identity);
738 status = set_identity(session, identity);
739 // * Return: created identity
742 else if (!EMPTYSTR(identity->username)) {
744 * Temporary identity information with username supplied
745 * Input: address, username (no others)
748 // * See if there is an own identity that uses this address. If so, we'll
752 if (default_own_id) {
753 status = get_identity(session,
758 // If there isn't an own identity, search for a non-temp stored ident
759 // with this address.
760 if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) {
762 identity_list* id_list = NULL;
763 status = get_identities_by_address(session, identity->address, &id_list);
766 identity_list* id_curr = id_list;
768 pEp_identity* this_id = id_curr->ident;
770 char* this_uid = this_id->user_id;
771 assert(!EMPTYSTR(this_uid));
772 // Should never be NULL - DB primary key
774 if (strstr(this_uid, "TOFU_") != this_uid) {
775 // if usernames match, we replace the userid.
776 if (identity->username &&
777 strcasecmp(identity->username,
778 this_id->username) == 0) {
780 // Ok, we have a real ID. Copy it!
781 identity->user_id = strdup(this_uid);
782 assert(identity->user_id);
783 if (!identity->user_id)
786 stored_ident = this_id;
792 id_curr = id_curr->next;
798 status = prepare_updated_identity(session,
803 identity->user_id = calloc(1, strlen(identity->address) + 6);
804 if (!identity->user_id)
807 snprintf(identity->user_id, strlen(identity->address) + 6,
808 "TOFU_%s", identity->address);
810 status = get_identity(session,
815 if (status == PEP_STATUS_OK && stored_ident) {
816 status = prepare_updated_identity(session,
822 // * We've already checked and retrieved
823 // any applicable temporary identities above. If we're
824 // here, none of them fit.
826 status = elect_pubkey(session, identity, false);
828 // * call set_identity() to store
830 // it is still possible we have DB information on this key. Better check.
831 status = get_trust(session, identity);
832 PEP_comm_type db_ct = identity->comm_type;
833 status = get_key_rating(session, identity->fpr, &identity->comm_type);
834 PEP_comm_type key_ct = identity->comm_type;
836 if (status == PEP_STATUS_OK) {
838 case PEP_ct_key_expired:
839 if (db_ct == PEP_ct_key_expired_but_confirmed)
840 identity->comm_type = db_ct;
844 case PEP_ct_key_expired_but_confirmed:
845 if (key_ct >= PEP_ct_strong_but_unconfirmed)
846 identity->comm_type |= PEP_ct_confirmed;
848 case PEP_ct_mistrusted:
849 case PEP_ct_compromised:
850 case PEP_ct_key_b0rken:
851 identity->comm_type = db_ct;
859 // * call set_identity() to store
860 adjust_pEp_trust_status(session, identity);
861 status = set_identity(session, identity);
867 * Input: address (no others)
868 * Temporary identity information without username suplied
871 // * Again, see if there is an own identity that uses this address. If so, we'll
875 if (default_own_id) {
876 status = get_identity(session,
881 // If there isn't an own identity, search for a non-temp stored ident
882 // with this address.
883 if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) {
885 identity_list* id_list = NULL;
886 // * Search for identity with this address
887 status = get_identities_by_address(session, identity->address, &id_list);
889 // Results are ordered by timestamp descending, so this covers
890 // both the one-result and multi-result cases
892 if (stored_ident) // unlikely
893 free_identity(stored_ident);
894 stored_ident = id_list->ident;
898 status = prepare_updated_identity(session, identity,
899 stored_ident, false);
901 // too little info. BUT. We see if we can find a key; if so, we create a
902 // temp identity, look for a key, and store.
904 // create temporary identity, store it, and Return this
905 // This means TOFU_ user_id
906 identity->user_id = calloc(1, strlen(identity->address) + 6);
907 if (!identity->user_id)
910 snprintf(identity->user_id, strlen(identity->address) + 6,
911 "TOFU_%s", identity->address);
913 identity->username = strdup(identity->address);
914 if (!identity->address)
918 identity->fpr = NULL;
919 identity->comm_type = PEP_ct_unknown;
921 status = elect_pubkey(session, identity, false);
924 status = get_key_rating(session, identity->fpr, &identity->comm_type);
926 // * call set_identity() to store
927 adjust_pEp_trust_status(session, identity);
928 status = set_identity(session, identity);
933 // FIXME: This is legacy. I presume it's a notification for the caller...
934 // Revisit once I can talk to Volker
935 if (identity->comm_type != PEP_ct_compromised &&
936 identity->comm_type < PEP_ct_strong_but_unconfirmed)
937 if (session->examine_identity)
938 session->examine_identity(identity, session->examine_management);
943 status = PEP_OUT_OF_MEMORY;
946 free(default_own_id);
947 free_identity(stored_ident);
951 PEP_STATUS elect_ownkey(
952 PEP_SESSION session, pEp_identity * identity
956 stringlist_t *keylist = NULL;
959 identity->fpr = NULL;
961 status = find_private_keys(session, identity->address, &keylist);
962 assert(status != PEP_OUT_OF_MEMORY);
963 if (status == PEP_OUT_OF_MEMORY)
964 return PEP_OUT_OF_MEMORY;
966 if (keylist != NULL && keylist->value != NULL)
969 identity->comm_type = PEP_ct_unknown;
971 stringlist_t *_keylist;
972 for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
975 status = own_key_is_listed(session, _keylist->value, &is_own);
976 assert(status == PEP_STATUS_OK);
977 if (status != PEP_STATUS_OK) {
978 free_stringlist(keylist);
984 PEP_comm_type _comm_type_key;
986 status = get_key_rating(session, _keylist->value, &_comm_type_key);
987 assert(status != PEP_OUT_OF_MEMORY);
988 if (status == PEP_OUT_OF_MEMORY) {
989 free_stringlist(keylist);
990 return PEP_OUT_OF_MEMORY;
993 if (_comm_type_key != PEP_ct_compromised &&
994 _comm_type_key != PEP_ct_unknown)
996 if (identity->comm_type == PEP_ct_unknown ||
997 _comm_type_key > identity->comm_type)
999 identity->comm_type = _comm_type_key;
1000 _fpr = _keylist->value;
1008 identity->fpr = strdup(_fpr);
1009 assert(identity->fpr);
1010 if (identity->fpr == NULL)
1012 free_stringlist(keylist);
1013 return PEP_OUT_OF_MEMORY;
1016 free_stringlist(keylist);
1018 return PEP_STATUS_OK;
1021 PEP_STATUS _has_usable_priv_key(PEP_SESSION session, char* fpr,
1024 bool has_private = false;
1025 PEP_STATUS status = contains_priv_key(session, fpr, &has_private);
1027 *is_usable = has_private;
1032 PEP_STATUS _myself(PEP_SESSION session,
1033 pEp_identity * identity,
1043 assert(!EMPTYSTR(identity->address));
1044 assert(!EMPTYSTR(identity->user_id));
1046 if (!session || !identity || EMPTYSTR(identity->address) ||
1047 EMPTYSTR(identity->user_id))
1048 return PEP_ILLEGAL_VALUE;
1050 pEp_identity *stored_identity = NULL;
1051 char* revoked_fpr = NULL;
1052 bool valid_key_found = false;
1054 char* default_own_id = NULL;
1055 status = get_default_own_userid(session, &default_own_id);
1057 // Deal with non-default user_ids.
1058 // FIXME: if non-default and read-only, reject totally?
1059 if (default_own_id && strcmp(default_own_id, identity->user_id) != 0) {
1061 free(identity->user_id);
1062 identity->user_id = strdup(default_own_id);
1065 status = set_userid_alias(session, default_own_id, identity->user_id);
1066 // Do we want this to be fatal? For now, we'll do it...
1067 if (status != PEP_STATUS_OK)
1070 free(identity->user_id);
1071 identity->user_id = strdup(default_own_id);
1072 if (identity->user_id == NULL) {
1073 status = PEP_OUT_OF_MEMORY;
1079 // NOTE: IF WE DON'T YET HAVE AN OWN_ID, WE IGNORE REFERENCES TO THIS ADDRESS IN THE
1080 // DB (WHICH MAY HAVE BEEN SET BEFORE MYSELF WAS CALLED BY RECEIVING AN EMAIL FROM
1081 // THIS ADDRESS), AS IT IS NOT AN OWN_IDENTITY AND HAS NO INFORMATION WE NEED OR WHAT TO
1084 // Ok, so now, set up the own_identity:
1085 identity->comm_type = PEP_ct_pEp;
1086 identity->me = true;
1088 identity->flags = 0;
1090 // Let's see if we have an identity record in the DB for
1091 // this user_id + address
1092 // DEBUG_LOG("myself", "debug", identity->address);
1094 status = get_identity(session,
1099 assert(status != PEP_OUT_OF_MEMORY);
1100 if (status == PEP_OUT_OF_MEMORY) {
1101 status = PEP_OUT_OF_MEMORY;
1105 // Set usernames - priority is input username > stored name > address
1106 // If there's an input username, we always patch the username with that
1108 if (EMPTYSTR(identity->username) || read_only) {
1109 bool stored_uname = (stored_identity && !EMPTYSTR(stored_identity->username));
1110 char* uname = (stored_uname ? stored_identity->username : identity->address);
1111 free(identity->username);
1112 identity->username = strdup(uname);
1113 if (identity->username == NULL) {
1114 status = PEP_OUT_OF_MEMORY;
1121 if (identity->fpr) {
1122 free(identity->fpr);
1123 identity->fpr = NULL;
1126 // check stored identity
1127 if (stored_identity) {
1128 if (!EMPTYSTR(stored_identity->fpr)) {
1129 // Fall back / retrieve
1130 status = validate_fpr(session, stored_identity, false, true);
1131 if (status == PEP_OUT_OF_MEMORY)
1133 if (status == PEP_STATUS_OK) {
1134 if (stored_identity->comm_type >= PEP_ct_strong_but_unconfirmed) {
1135 identity->fpr = strdup(stored_identity->fpr);
1136 assert(identity->fpr);
1137 if (!identity->fpr) {
1138 status = PEP_OUT_OF_MEMORY;
1141 valid_key_found = true;
1144 bool revoked = false;
1145 status = key_revoked(session, stored_identity->fpr, &revoked);
1149 revoked_fpr = strdup(stored_identity->fpr);
1150 assert(revoked_fpr);
1152 status = PEP_OUT_OF_MEMORY;
1159 // reconcile language, flags
1160 transfer_ident_lang_and_flags(identity, stored_identity);
1163 // Nothing left to do but generate a key
1164 if (!valid_key_found) {
1165 if (!do_keygen || read_only)
1166 status = PEP_GET_KEY_FAILED;
1168 // / DEBUG_LOG("Generating key pair", "debug", identity->address);
1170 free(identity->fpr);
1171 identity->fpr = NULL;
1172 status = generate_keypair(session, identity);
1173 assert(status != PEP_OUT_OF_MEMORY);
1175 if (status != PEP_STATUS_OK) {
1177 snprintf(buf, 11, "%d", status); // uh, this is kludgey. FIXME
1178 // DEBUG_LOG("Generating key pair failed", "debug", buf);
1181 valid_key_found = true;
1183 status = set_revoked(session, revoked_fpr,
1184 stored_identity->fpr, time(NULL));
1185 assert(status == PEP_STATUS_OK);
1191 if (valid_key_found) {
1192 identity->comm_type = PEP_ct_pEp;
1193 status = PEP_STATUS_OK;
1196 free(identity->fpr);
1197 identity->fpr = NULL;
1198 identity->comm_type = PEP_ct_unknown;
1201 // We want to set an identity in the DB even if a key isn't found, but we have to preserve the status if
1204 PEP_STATUS set_id_status = set_identity(session, identity);
1205 if (set_id_status == PEP_STATUS_OK)
1206 set_id_status = set_as_pEp_user(session, identity);
1208 status = (status == PEP_STATUS_OK ? set_id_status : status);
1212 free(default_own_id);
1214 free_identity(stored_identity);
1218 DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
1220 return _myself(session, identity, true, false, false);
1223 DYNAMIC_API PEP_STATUS register_examine_function(
1224 PEP_SESSION session,
1225 examine_identity_t examine_identity,
1231 return PEP_ILLEGAL_VALUE;
1233 session->examine_management = management;
1234 session->examine_identity = examine_identity;
1236 return PEP_STATUS_OK;
1239 DYNAMIC_API PEP_STATUS do_keymanagement(
1240 retrieve_next_identity_t retrieve_next_identity,
1244 PEP_SESSION session;
1245 pEp_identity *identity;
1246 PEP_STATUS status = init(&session, NULL, NULL);
1251 assert(session && retrieve_next_identity);
1252 if (!(session && retrieve_next_identity))
1253 return PEP_ILLEGAL_VALUE;
1255 log_event(session, "keymanagement thread started", "pEp engine", NULL, NULL);
1257 while ((identity = retrieve_next_identity(management)))
1259 assert(identity->address);
1260 if(identity->address)
1262 DEBUG_LOG("do_keymanagement", "retrieve_next_identity", identity->address);
1265 status = myself(session, identity);
1267 status = recv_key(session, identity->address);
1270 assert(status != PEP_OUT_OF_MEMORY);
1271 if(status == PEP_OUT_OF_MEMORY)
1272 return PEP_OUT_OF_MEMORY;
1274 free_identity(identity);
1277 log_event(session, "keymanagement thread shutdown", "pEp engine", NULL, NULL);
1279 return PEP_STATUS_OK;
1282 DYNAMIC_API PEP_STATUS key_mistrusted(
1283 PEP_SESSION session,
1287 PEP_STATUS status = PEP_STATUS_OK;
1291 assert(!EMPTYSTR(ident->fpr));
1293 if (!(session && ident && ident->fpr))
1294 return PEP_ILLEGAL_VALUE;
1296 bool has_private = false;
1298 status = contains_priv_key(session, ident->fpr, &has_private);
1300 if (status != PEP_STATUS_OK && status != PEP_KEY_NOT_FOUND)
1303 // See if key is revoked already
1305 bool revoked = false;
1306 status = key_revoked(session, ident->fpr, &revoked);
1309 revoke_key(session, ident->fpr, NULL);
1312 // double-check to be sure key is even in the DB
1314 status = set_pgp_keypair(session, ident->fpr);
1316 // We set this temporarily but will grab it back from the cache afterwards
1317 ident->comm_type = PEP_ct_mistrusted;
1318 status = set_trust(session, ident);
1320 if (status == PEP_STATUS_OK)
1321 // cascade that mistrust for anyone using this key
1322 status = mark_as_compromised(session, ident->fpr);
1323 if (status == PEP_STATUS_OK)
1324 status = add_mistrusted_key(session, ident->fpr);
1329 DYNAMIC_API PEP_STATUS key_reset_trust(
1330 PEP_SESSION session,
1334 PEP_STATUS status = PEP_STATUS_OK;
1338 assert(!EMPTYSTR(ident->fpr));
1339 assert(!EMPTYSTR(ident->address));
1340 assert(!EMPTYSTR(ident->user_id));
1342 if (!(session && ident && ident->fpr && ident->fpr[0] != '\0' && ident->address &&
1344 return PEP_ILLEGAL_VALUE;
1346 // we do not change the input struct at ALL.
1347 pEp_identity* input_copy = identity_dup(ident);
1349 pEp_identity* tmp_ident = NULL;
1351 status = get_trust(session, input_copy);
1353 if (status != PEP_STATUS_OK)
1356 PEP_comm_type new_trust = PEP_ct_unknown;
1357 status = get_key_rating(session, ident->fpr, &new_trust);
1358 if (status != PEP_STATUS_OK)
1361 bool pEp_user = false;
1363 status = is_pEp_user(session, ident, &pEp_user);
1365 if (pEp_user && new_trust >= PEP_ct_unconfirmed_encryption)
1366 input_copy->comm_type = PEP_ct_pEp_unconfirmed;
1368 input_copy->comm_type = new_trust;
1370 status = set_trust(session, input_copy);
1372 if (status != PEP_STATUS_OK)
1375 bool mistrusted_key = false;
1377 status = is_mistrusted_key(session, ident->fpr, &mistrusted_key);
1379 if (status != PEP_STATUS_OK)
1383 status = delete_mistrusted_key(session, ident->fpr);
1385 if (status != PEP_STATUS_OK)
1388 tmp_ident = new_identity(ident->address, NULL, ident->user_id, NULL);
1391 return PEP_OUT_OF_MEMORY;
1393 if (is_me(session, tmp_ident))
1394 status = myself(session, tmp_ident);
1396 status = update_identity(session, tmp_ident);
1398 if (status != PEP_STATUS_OK)
1401 // remove as default if necessary
1402 if (!EMPTYSTR(tmp_ident->fpr) && strcmp(tmp_ident->fpr, ident->fpr) == 0) {
1403 free(tmp_ident->fpr);
1404 tmp_ident->fpr = NULL;
1405 tmp_ident->comm_type = PEP_ct_unknown;
1406 status = set_identity(session, tmp_ident);
1407 if (status != PEP_STATUS_OK)
1411 char* user_default = NULL;
1412 get_main_user_fpr(session, tmp_ident->user_id, &user_default);
1414 if (!EMPTYSTR(user_default)) {
1415 if (strcmp(user_default, ident->fpr) == 0)
1416 status = refresh_userid_default_key(session, ident->user_id);
1417 if (status != PEP_STATUS_OK)
1422 free_identity(tmp_ident);
1423 free_identity(input_copy);
1427 DYNAMIC_API PEP_STATUS trust_personal_key(
1428 PEP_SESSION session,
1432 PEP_STATUS status = PEP_STATUS_OK;
1436 assert(!EMPTYSTR(ident->address));
1437 assert(!EMPTYSTR(ident->user_id));
1438 assert(!EMPTYSTR(ident->fpr));
1440 if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
1441 EMPTYSTR(ident->fpr))
1442 return PEP_ILLEGAL_VALUE;
1444 if (is_me(session, ident))
1445 return PEP_ILLEGAL_VALUE;
1447 char* ident_default_fpr = NULL;
1449 // Before we do anything, be sure the input fpr is even eligible to be trusted
1450 PEP_comm_type input_default_ct = PEP_ct_unknown;
1451 status = get_key_rating(session, ident->fpr, &input_default_ct);
1452 if (input_default_ct < PEP_ct_strong_but_unconfirmed)
1453 return PEP_KEY_UNSUITABLE;
1455 status = set_pgp_keypair(session, ident->fpr);
1456 if (status != PEP_STATUS_OK)
1459 pEp_identity* ident_copy = identity_dup(ident);
1460 char* cached_fpr = NULL;
1462 // for setting up a temp trusted identity for the input fpr
1463 pEp_identity* tmp_id = NULL;
1465 // For later, in case we need to check the user default key
1466 pEp_identity* tmp_user_ident = NULL;
1468 // Save the input fpr, which we already tested as non-NULL
1469 cached_fpr = strdup(ident->fpr);
1471 // Set up a temp trusted identity for the input fpr without a comm type;
1472 tmp_id = new_identity(ident->address, ident->fpr, ident->user_id, NULL);
1474 status = validate_fpr(session, tmp_id, false, true);
1476 if (status == PEP_STATUS_OK) {
1477 // Validate fpr gets trust DB or, when that fails, key comm type. we checked
1478 // above that the key was ok. (not revoked or expired), but we want the max.
1479 tmp_id->comm_type = _MAX(tmp_id->comm_type, input_default_ct) | PEP_ct_confirmed;
1481 // Get the default identity without setting the fpr
1482 status = update_identity(session, ident_copy);
1484 ident_default_fpr = (EMPTYSTR(ident_copy->fpr) ? NULL : strdup(ident_copy->fpr));
1486 if (status == PEP_STATUS_OK) {
1487 bool trusted_default = false;
1489 // If there's no default, or the default is different from the input...
1490 if (EMPTYSTR(ident_default_fpr) || strcmp(cached_fpr, ident_default_fpr) != 0) {
1492 // If the default fpr (if there is one) is trusted and key is strong enough,
1493 // don't replace, we just set the trusted bit on this key for this user_id...
1494 // (If there's no default fpr, this won't be true anyway.)
1495 if ((ident_copy->comm_type >= PEP_ct_strong_but_unconfirmed &&
1496 (ident_copy->comm_type & PEP_ct_confirmed))) {
1498 trusted_default = true;
1500 status = set_trust(session, tmp_id);
1501 input_default_ct = tmp_id->comm_type;
1504 free(ident_copy->fpr);
1505 ident_copy->fpr = strdup(cached_fpr);
1506 ident_copy->comm_type = tmp_id->comm_type;
1507 status = set_identity(session, ident_copy); // replace identity default
1508 if (status == PEP_STATUS_OK) {
1509 if ((ident_copy->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
1510 status = set_as_pEp_user(session, ident_copy);
1514 else { // we're setting this on the default fpr
1515 ident->comm_type = tmp_id->comm_type;
1516 status = set_identity(session, ident);
1517 trusted_default = true;
1519 if (status == PEP_STATUS_OK && !trusted_default) {
1520 // Ok, there wasn't a trusted default, so we replaced. Thus, we also
1521 // make sure there's a trusted default on the user_id. If there
1522 // is not, we make this the default.
1523 char* user_default = NULL;
1524 status = get_main_user_fpr(session, ident->user_id, &user_default);
1526 if (status == PEP_STATUS_OK && user_default) {
1527 tmp_user_ident = new_identity(ident->address,
1531 if (!tmp_user_ident)
1532 status = PEP_OUT_OF_MEMORY;
1534 status = validate_fpr(session, tmp_user_ident, false, true);
1536 if (status != PEP_STATUS_OK ||
1537 tmp_user_ident->comm_type < PEP_ct_strong_but_unconfirmed ||
1538 !(tmp_user_ident->comm_type & PEP_ct_confirmed))
1540 char* trusted_fpr = (trusted_default ? ident_default_fpr : cached_fpr);
1541 status = replace_main_user_fpr(session, ident->user_id, trusted_fpr);
1549 free(ident_default_fpr);
1551 free_identity(tmp_id);
1552 free_identity(ident_copy);
1553 free_identity(tmp_user_ident);
1557 DYNAMIC_API PEP_STATUS trust_own_key(
1558 PEP_SESSION session,
1564 assert(!EMPTYSTR(ident->address));
1565 assert(!EMPTYSTR(ident->user_id));
1566 assert(!EMPTYSTR(ident->fpr));
1568 if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
1569 EMPTYSTR(ident->fpr))
1570 return PEP_ILLEGAL_VALUE;
1572 if (!is_me(session, ident))
1573 return PEP_ILLEGAL_VALUE;
1575 // don't check blacklist or require a private key
1576 PEP_STATUS status = validate_fpr(session, ident, false, false);
1578 if (status != PEP_STATUS_OK)
1581 status = set_pgp_keypair(session, ident->fpr);
1582 if (status != PEP_STATUS_OK)
1585 if (ident->comm_type < PEP_ct_strong_but_unconfirmed)
1586 return PEP_KEY_UNSUITABLE;
1588 ident->comm_type |= PEP_ct_confirmed;
1590 status = set_trust(session, ident);
1596 DYNAMIC_API PEP_STATUS own_key_is_listed(
1597 PEP_SESSION session,
1602 PEP_STATUS status = PEP_STATUS_OK;
1605 assert(session && fpr && fpr[0] && listed);
1607 if (!(session && fpr && fpr[0] && listed))
1608 return PEP_ILLEGAL_VALUE;
1612 sqlite3_reset(session->own_key_is_listed);
1613 sqlite3_bind_text(session->own_key_is_listed, 1, fpr, -1, SQLITE_STATIC);
1617 result = sqlite3_step(session->own_key_is_listed);
1620 count = sqlite3_column_int(session->own_key_is_listed, 0);
1621 *listed = count > 0;
1622 status = PEP_STATUS_OK;
1626 status = PEP_UNKNOWN_ERROR;
1629 sqlite3_reset(session->own_key_is_listed);
1633 PEP_STATUS _own_identities_retrieve(
1634 PEP_SESSION session,
1635 identity_list **own_identities,
1636 identity_flags_t excluded_flags
1639 PEP_STATUS status = PEP_STATUS_OK;
1641 assert(session && own_identities);
1642 if (!(session && own_identities))
1643 return PEP_ILLEGAL_VALUE;
1645 *own_identities = NULL;
1646 identity_list *_own_identities = new_identity_list(NULL);
1647 if (_own_identities == NULL)
1650 sqlite3_reset(session->own_identities_retrieve);
1653 // address, fpr, username, user_id, comm_type, lang, flags
1654 const char *address = NULL;
1655 const char *fpr = NULL;
1656 const char *username = NULL;
1657 const char *user_id = NULL;
1658 PEP_comm_type comm_type = PEP_ct_unknown;
1659 const char *lang = NULL;
1660 unsigned int flags = 0;
1662 identity_list *_bl = _own_identities;
1664 sqlite3_bind_int(session->own_identities_retrieve, 1, excluded_flags);
1667 result = sqlite3_step(session->own_identities_retrieve);
1670 address = (const char *)
1671 sqlite3_column_text(session->own_identities_retrieve, 0);
1672 fpr = (const char *)
1673 sqlite3_column_text(session->own_identities_retrieve, 1);
1674 user_id = (const char *)
1675 sqlite3_column_text(session->own_identities_retrieve, 2);
1676 username = (const char *)
1677 sqlite3_column_text(session->own_identities_retrieve, 3);
1678 comm_type = PEP_ct_pEp;
1679 lang = (const char *)
1680 sqlite3_column_text(session->own_identities_retrieve, 4);
1681 flags = (unsigned int)
1682 sqlite3_column_int(session->own_identities_retrieve, 5);
1684 pEp_identity *ident = new_identity(address, fpr, user_id, username);
1687 ident->comm_type = comm_type;
1688 if (lang && lang[0]) {
1689 ident->lang[0] = lang[0];
1690 ident->lang[1] = lang[1];
1694 ident->flags = flags;
1696 _bl = identity_list_add(_bl, ident);
1698 free_identity(ident);
1708 status = PEP_UNKNOWN_ERROR;
1709 result = SQLITE_DONE;
1711 } while (result != SQLITE_DONE);
1713 sqlite3_reset(session->own_identities_retrieve);
1714 if (status == PEP_STATUS_OK)
1715 *own_identities = _own_identities;
1717 free_identity_list(_own_identities);
1722 free_identity_list(_own_identities);
1723 status = PEP_OUT_OF_MEMORY;
1729 DYNAMIC_API PEP_STATUS own_identities_retrieve(
1730 PEP_SESSION session,
1731 identity_list **own_identities
1734 return _own_identities_retrieve(session, own_identities, 0);
1737 PEP_STATUS _own_keys_retrieve(
1738 PEP_SESSION session,
1739 stringlist_t **keylist,
1740 identity_flags_t excluded_flags,
1744 PEP_STATUS status = PEP_STATUS_OK;
1746 assert(session && keylist);
1747 if (!(session && keylist))
1748 return PEP_ILLEGAL_VALUE;
1751 stringlist_t *_keylist = NULL;
1753 sqlite3_reset(session->own_keys_retrieve);
1758 stringlist_t *_bl = _keylist;
1759 sqlite3_bind_int(session->own_keys_retrieve, 1, excluded_flags);
1762 result = sqlite3_step(session->own_keys_retrieve);
1765 _bl = stringlist_add(_bl, (const char *) sqlite3_column_text(session->own_keys_retrieve, 0));
1768 if (_keylist == NULL)
1776 status = PEP_UNKNOWN_ERROR;
1777 result = SQLITE_DONE;
1779 } while (result != SQLITE_DONE);
1781 sqlite3_reset(session->own_keys_retrieve);
1782 if (status == PEP_STATUS_OK) {
1783 dedup_stringlist(_keylist);
1785 stringlist_t* _kl = _keylist;
1786 stringlist_t* _kl_prev = NULL;
1788 bool has_private = false;
1789 contains_priv_key(session, _kl->value, &has_private);
1791 stringlist_t* _kl_tmp = _kl;
1793 _kl_prev->next = _kl->next;
1795 _keylist = _kl->next;
1799 _kl_tmp->next = NULL;
1800 free_stringlist(_kl_tmp);
1807 *keylist = _keylist;
1810 free_stringlist(_keylist);
1815 free_stringlist(_keylist);
1816 status = PEP_OUT_OF_MEMORY;
1822 DYNAMIC_API PEP_STATUS own_keys_retrieve(PEP_SESSION session, stringlist_t **keylist)
1824 return _own_keys_retrieve(session, keylist, 0, true);
1827 DYNAMIC_API PEP_STATUS set_own_key(
1828 PEP_SESSION session,
1833 PEP_STATUS status = PEP_STATUS_OK;
1835 assert(session && me);
1836 assert(!EMPTYSTR(fpr));
1837 assert(!EMPTYSTR(me->address));
1838 assert(!EMPTYSTR(me->user_id));
1839 assert(!EMPTYSTR(me->username));
1841 if (!session || !me || EMPTYSTR(fpr) || EMPTYSTR(me->address) ||
1842 EMPTYSTR(me->user_id) || EMPTYSTR(me->username))
1843 return PEP_ILLEGAL_VALUE;
1845 status = _myself(session, me, false, true, false);
1846 // we do not need a valid key but dislike other errors
1847 if (status != PEP_STATUS_OK && status != PEP_GET_KEY_FAILED && status != PEP_KEY_UNSUITABLE)
1849 status = PEP_STATUS_OK;
1851 bool private = false;
1852 status = contains_priv_key(session, fpr, &private);
1854 if (status != PEP_STATUS_OK)
1858 return PEP_KEY_UNSUITABLE;
1862 me->fpr = strdup(fpr);
1865 return PEP_OUT_OF_MEMORY;
1867 status = validate_fpr(session, me, false, true);
1871 me->comm_type = PEP_ct_pEp;
1872 status = set_identity(session, me);
1876 PEP_STATUS contains_priv_key(PEP_SESSION session, const char *fpr,
1877 bool *has_private) {
1881 assert(has_private);
1883 if (!(session && fpr && has_private))
1884 return PEP_ILLEGAL_VALUE;
1886 return session->cryptotech[PEP_crypt_OpenPGP].contains_priv_key(session, fpr, has_private);
1889 PEP_STATUS add_mistrusted_key(PEP_SESSION session, const char* fpr)
1893 assert(!EMPTYSTR(fpr));
1895 if (!(session) || EMPTYSTR(fpr))
1896 return PEP_ILLEGAL_VALUE;
1898 sqlite3_reset(session->add_mistrusted_key);
1899 sqlite3_bind_text(session->add_mistrusted_key, 1, fpr, -1,
1902 result = sqlite3_step(session->add_mistrusted_key);
1903 sqlite3_reset(session->add_mistrusted_key);
1905 if (result != SQLITE_DONE)
1906 return PEP_CANNOT_SET_PGP_KEYPAIR; // FIXME: Better status?
1908 return PEP_STATUS_OK;
1911 PEP_STATUS delete_mistrusted_key(PEP_SESSION session, const char* fpr)
1915 assert(!EMPTYSTR(fpr));
1917 if (!(session) || EMPTYSTR(fpr))
1918 return PEP_ILLEGAL_VALUE;
1920 sqlite3_reset(session->delete_mistrusted_key);
1921 sqlite3_bind_text(session->delete_mistrusted_key, 1, fpr, -1,
1924 result = sqlite3_step(session->delete_mistrusted_key);
1925 sqlite3_reset(session->delete_mistrusted_key);
1927 if (result != SQLITE_DONE)
1928 return PEP_UNKNOWN_ERROR; // FIXME: Better status?
1930 return PEP_STATUS_OK;
1933 PEP_STATUS is_mistrusted_key(PEP_SESSION session, const char* fpr,
1936 PEP_STATUS status = PEP_STATUS_OK;
1939 assert(!EMPTYSTR(fpr));
1941 if (!(session && fpr))
1942 return PEP_ILLEGAL_VALUE;
1944 *mistrusted = false;
1946 sqlite3_reset(session->is_mistrusted_key);
1947 sqlite3_bind_text(session->is_mistrusted_key, 1, fpr, -1, SQLITE_STATIC);
1951 result = sqlite3_step(session->is_mistrusted_key);
1954 *mistrusted = sqlite3_column_int(session->is_mistrusted_key, 0);
1955 status = PEP_STATUS_OK;
1959 status = PEP_UNKNOWN_ERROR;
1962 sqlite3_reset(session->is_mistrusted_key);
1967 PEP_STATUS pgp_find_trusted_private_keys(
1968 PEP_SESSION session, stringlist_t **keylist
1978 static enum _pgp_thing _pgp_thing_next(enum _pgp_thing thing)
1992 PEP_STATUS pgp_import_ultimately_trusted_keypairs(PEP_SESSION session) {
1995 return PEP_ILLEGAL_VALUE;
1997 stringlist_t* priv_keylist = NULL;
1998 PEP_STATUS status = PEP_STATUS_OK;
2001 status = pgp_find_trusted_private_keys(session, &priv_keylist);
2005 pEp_identity *identity = NULL;
2009 enum _pgp_thing thing = _pgp_none;
2010 for (_sl = priv_keylist; _sl && _sl->value; _sl = _sl->next) {
2011 thing = _pgp_thing_next(thing);
2014 // PEP_OWN_USERID is ok here because this is only run on first use!
2015 identity = new_identity(NULL, NULL, PEP_OWN_USERID, NULL);
2017 status = PEP_OUT_OF_MEMORY;
2020 identity->me = true;
2021 fpr = strdup(_sl->value);
2024 status = PEP_OUT_OF_MEMORY;
2025 free_identity(identity);
2030 identity->address = strdup(_sl->value);
2031 assert(identity->address);
2032 if (!identity->address) {
2033 status = PEP_OUT_OF_MEMORY;
2034 free_identity(identity);
2039 identity->username = strdup(_sl->value);
2040 assert(identity->username);
2041 if (!identity->username)
2042 status = PEP_OUT_OF_MEMORY;
2044 status = set_own_key(session, identity, fpr);
2045 free_identity(identity);
2050 free_identity(identity);
2051 status = PEP_UNKNOWN_ERROR;
2057 free_stringlist(priv_keylist);