pEpMIME is compiled with -fsanitize=address, so the Engine must be linked with it, too.
2 /** @brief File description for doxygen missing. FIXME */
4 // This file is under GNU General Public License 3.0
15 #include "pEp_internal.h"
16 #include "keymanagement.h"
17 #include "KeySync_fsm.h"
19 #include "blacklist.h"
21 static bool key_matches_address(PEP_SESSION session, const char* address,
23 if (!session || !address || !fpr)
27 stringlist_t *keylist = NULL;
28 PEP_STATUS status = find_keys(session, address, &keylist);
29 if (status == PEP_STATUS_OK && keylist) {
30 stringlist_t* curr = keylist;
33 if (strcasecmp(curr->value, fpr)) {
42 free_stringlist(keylist);
46 // Does not return PASSPHRASE errors
50 * <!-- elect_pubkey() -->
54 * @param[in] session PEP_SESSION
55 * @param[in] *identity pEp_identity
56 * @param[in] check_blacklist bool
59 PEP_STATUS elect_pubkey(
60 PEP_SESSION session, pEp_identity * identity, bool check_blacklist
64 stringlist_t *keylist = NULL;
66 identity->comm_type = PEP_ct_unknown;
68 status = find_keys(session, identity->address, &keylist);
69 assert(status != PEP_OUT_OF_MEMORY);
70 if (status == PEP_OUT_OF_MEMORY)
71 return PEP_OUT_OF_MEMORY;
73 if (!keylist || !keylist->value)
74 identity->comm_type = PEP_ct_key_not_found;
76 stringlist_t *_keylist;
77 for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
78 PEP_comm_type _comm_type_key;
80 status = get_key_rating(session, _keylist->value, &_comm_type_key);
81 if (status == PEP_OUT_OF_MEMORY) {
82 free_stringlist(keylist);
83 return PEP_OUT_OF_MEMORY;
86 if (_comm_type_key != PEP_ct_compromised &&
87 _comm_type_key != PEP_ct_unknown)
89 if (identity->comm_type == PEP_ct_unknown ||
90 _comm_type_key > identity->comm_type)
92 bool blacklisted = false;
93 bool mistrusted = false;
94 status = is_mistrusted_key(session, _keylist->value, &mistrusted);
95 if (status == PEP_STATUS_OK && check_blacklist)
96 status = blacklist_is_listed(session, _keylist->value, &blacklisted);
97 if (status == PEP_STATUS_OK && !mistrusted && !blacklisted) {
98 identity->comm_type = _comm_type_key;
99 _fpr = _keylist->value;
107 if (!_fpr || _fpr[0] == '\0')
108 identity->fpr = NULL;
110 identity->fpr = strdup(_fpr);
111 if (identity->fpr == NULL) {
112 free_stringlist(keylist);
113 return PEP_OUT_OF_MEMORY;
117 free_stringlist(keylist);
118 return PEP_STATUS_OK;
122 // own_must_contain_private is usually true when calling;
123 // we only set it to false when we have the idea of
124 // possibly having an own pubkey that we need to check on its own
125 // N.B. Checked for PASSPHRASE errors - will now return them always
126 // False value of "renew_private" prevents their possibility, though.
130 * <!-- validate_fpr() -->
134 * @param[in] session PEP_SESSION
135 * @param[in] *ident pEp_identity
136 * @param[in] check_blacklist bool
137 * @param[in] own_must_contain_private bool
138 * @param[in] renew_private bool
141 static PEP_STATUS validate_fpr(PEP_SESSION session,
143 bool check_blacklist,
144 bool own_must_contain_private,
145 bool renew_private) {
147 PEP_STATUS status = PEP_STATUS_OK;
149 if (!session || !ident || !ident->fpr || !ident->fpr[0])
150 return PEP_ILLEGAL_VALUE;
152 char* fpr = ident->fpr;
154 bool has_private = false;
155 status = contains_priv_key(session, fpr, &has_private);
157 // N.B. Will not contain PEP_PASSPHRASE related returns here
158 if (ident->me && own_must_contain_private) {
159 if (status != PEP_STATUS_OK || !has_private)
160 return PEP_KEY_UNSUITABLE;
162 else if (status != PEP_STATUS_OK && has_private) // should never happen
165 status = get_trust(session, ident);
166 if (status != PEP_STATUS_OK)
167 ident->comm_type = PEP_ct_unknown;
169 PEP_comm_type ct = ident->comm_type;
171 if (ct == PEP_ct_unknown) {
172 // If status is bad, it's ok, we get the rating
173 // we should use then (PEP_ct_unknown).
174 // Only one we really care about here is PEP_OUT_OF_MEMORY
175 status = get_key_rating(session, fpr, &ct);
176 if (status == PEP_OUT_OF_MEMORY)
177 return PEP_OUT_OF_MEMORY;
179 ident->comm_type = ct;
181 else if (ct == PEP_ct_key_expired || ct == PEP_ct_key_expired_but_confirmed) {
182 PEP_comm_type ct_expire_check = PEP_ct_unknown;
183 status = get_key_rating(session, fpr, &ct_expire_check);
184 if (status == PEP_OUT_OF_MEMORY)
185 return PEP_OUT_OF_MEMORY;
187 if (ct_expire_check >= PEP_ct_strong_but_unconfirmed) {
188 ident->comm_type = ct_expire_check;
189 if (ct == PEP_ct_key_expired_but_confirmed)
190 ident->comm_type |= PEP_ct_confirmed;
191 ct = ident->comm_type;
192 // We need to fix this trust in the DB.
193 status = set_trust(session, ident);
198 bool pEp_user = false;
200 status = is_pEp_user(session, ident, &pEp_user);
201 if (status == PEP_OUT_OF_MEMORY)
202 return PEP_OUT_OF_MEMORY;
207 case PEP_ct_OpenPGP_unconfirmed:
208 ct += 0x47; // difference between PEP and OpenPGP values;
209 ident->comm_type = ct;
216 bool revoked, expired;
217 bool blacklisted = false;
219 // Should not need to decrypt key material
220 status = key_revoked(session, fpr, &revoked);
222 if (status != PEP_STATUS_OK) {
227 time_t exp_time = (ident->me ?
228 time(NULL) + (7*24*3600) : time(NULL));
230 // Should not need to decrypt key material
231 status = key_expired(session, fpr,
235 assert(status == PEP_STATUS_OK);
236 if (status != PEP_STATUS_OK)
239 if (check_blacklist && IS_PGP_CT(ct) &&
241 status = blacklist_is_listed(session,
245 if (status != PEP_STATUS_OK)
250 // Renew key if it's expired, our own, has a private part,
251 // isn't too weak, and we didn't say "DON'T DO THIS"
252 if (renew_private && ident->me && has_private &&
253 (ct >= PEP_ct_strong_but_unconfirmed) &&
254 !revoked && expired) {
256 timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
257 status = renew_key(session, fpr, ts);
260 if (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE)
263 if (status == PEP_STATUS_OK) {
264 // if key is valid (second check because pEp key might be extended above)
266 status = key_expired(session, fpr, time(NULL), &expired);
267 if (status != PEP_STATUS_OK)
271 if (ident->comm_type & PEP_ct_confirmed || (ident->comm_type == PEP_ct_key_expired_but_confirmed))
272 ident->comm_type = PEP_ct_key_expired_but_confirmed;
274 ident->comm_type = PEP_ct_key_expired;
277 // communicate key(?)
282 ct = PEP_ct_key_revoked;
284 if (ident->comm_type & PEP_ct_confirmed || (ident->comm_type == PEP_ct_key_expired_but_confirmed))
285 ct = PEP_ct_key_expired_but_confirmed;
287 ct = PEP_ct_key_expired;
289 else if (blacklisted) { // never true for .me
290 ident->comm_type = ct = PEP_ct_key_not_found;
292 ident->fpr = strdup("");
293 status = PEP_KEY_BLACKLISTED;
297 case PEP_ct_key_expired:
298 case PEP_ct_key_expired_but_confirmed:
299 case PEP_ct_key_revoked:
300 case PEP_ct_key_b0rken:
301 // delete key from being default key for all users/identities
302 status = remove_fpr_as_default(session, fpr);
303 status = update_trust_for_fpr(session,
306 case PEP_ct_mistrusted:
309 ident->comm_type = ct;
310 status = PEP_KEY_UNSUITABLE;
318 PEP_STATUS get_all_keys_for_user(PEP_SESSION session,
320 stringlist_t** keys) {
322 if (!session || EMPTYSTR(user_id) || !keys)
323 return PEP_ILLEGAL_VALUE;
325 PEP_STATUS status = PEP_STATUS_OK;
328 stringlist_t* _kl = NULL;
330 sqlite3_reset(session->get_all_keys_for_user);
331 sqlite3_bind_text(session->get_all_keys_for_user, 1, user_id, -1, SQLITE_STATIC);
335 while ((result = sqlite3_step(session->get_all_keys_for_user)) == SQLITE_ROW) {
336 const char* keyres = (const char *) sqlite3_column_text(session->get_all_keys_for_user, 0);
339 stringlist_add(_kl, keyres);
341 _kl = new_stringlist(keyres);
346 return PEP_KEY_NOT_FOUND;
350 sqlite3_reset(session->get_all_keys_for_user);
355 PEP_STATUS get_user_default_key(PEP_SESSION session, const char* user_id,
356 char** default_key) {
360 if (!session || !user_id)
361 return PEP_ILLEGAL_VALUE;
363 PEP_STATUS status = PEP_STATUS_OK;
365 // try to get default key for user_data
366 sqlite3_reset(session->get_user_default_key);
367 sqlite3_bind_text(session->get_user_default_key, 1, user_id,
370 const int result = sqlite3_step(session->get_user_default_key);
371 char* user_fpr = NULL;
372 if (result == SQLITE_ROW) {
374 (char *) sqlite3_column_text(session->get_user_default_key, 0);
376 user_fpr = strdup(u_fpr);
379 status = PEP_GET_KEY_FAILED;
381 sqlite3_reset(session->get_user_default_key);
383 *default_key = user_fpr;
387 // Only call on retrieval of previously stored identity!
388 // Also, we presume that if the stored_identity was sent in
389 // without an fpr, there wasn't one in the trust DB for this
392 // Will now NOT return passphrase errors, as we tell
393 // validate_fpr NOT to renew it. And we specifically suppress them
394 // with "PEP_KEY_UNSUITABLE"
396 PEP_STATUS get_valid_pubkey(PEP_SESSION session,
397 pEp_identity* stored_identity,
398 bool* is_identity_default,
399 bool* is_user_default,
400 bool* is_address_default,
401 bool check_blacklist) {
404 return PEP_ILLEGAL_VALUE;
406 PEP_STATUS status = PEP_STATUS_OK;
408 if (!stored_identity || EMPTYSTR(stored_identity->user_id)
409 || !is_identity_default || !is_user_default || !is_address_default)
410 return PEP_ILLEGAL_VALUE;
412 *is_identity_default = *is_user_default = *is_address_default = false;
414 PEP_comm_type first_reject_comm_type = PEP_ct_key_not_found;
415 PEP_STATUS first_reject_status = PEP_KEY_NOT_FOUND;
417 char* stored_fpr = stored_identity->fpr;
419 // Input: stored identity retrieved from database
420 // if stored identity contains a default key
421 if (!EMPTYSTR(stored_fpr)) {
423 // Won't ask for passphrase, won't return PASSPHRASE status
424 // Because of non-renewal
425 status = validate_fpr(session, stored_identity, check_blacklist, true, false);
428 if (!EMPTYSTR(stored_identity->fpr)) {
429 *is_identity_default = *is_address_default = true;
433 case PEP_KEY_NOT_FOUND:
436 first_reject_status = status;
437 first_reject_comm_type = stored_identity->comm_type;
440 // if no valid default stored identity key found
441 free(stored_identity->fpr);
442 stored_identity->fpr = NULL;
444 char* user_fpr = NULL;
445 status = get_user_default_key(session, stored_identity->user_id, &user_fpr);
447 if (!EMPTYSTR(user_fpr)) {
448 // There exists a default key for user, so validate
449 stored_identity->fpr = user_fpr;
451 // Won't ask for passphrase, won't return PASSPHRASE status
452 // Because of non-renewal
453 status = validate_fpr(session, stored_identity, check_blacklist, true, false);
457 if (!EMPTYSTR(stored_identity->fpr)) {
458 *is_user_default = true;
459 *is_address_default = key_matches_address(session,
460 stored_identity->address,
461 stored_identity->fpr);
465 case PEP_KEY_NOT_FOUND:
468 if (first_reject_status != PEP_KEY_NOT_FOUND) {
469 first_reject_status = status;
470 first_reject_comm_type = stored_identity->comm_type;
475 status = elect_pubkey(session, stored_identity, check_blacklist);
476 if (status == PEP_STATUS_OK) {
477 if (!EMPTYSTR(stored_identity->fpr)) {
478 // Won't ask for passphrase, won't return PASSPHRASE status
479 // Because of non-renewal
480 status = validate_fpr(session, stored_identity, false, true, false); // blacklist already filtered of needed
483 else if (status != PEP_KEY_NOT_FOUND && first_reject_status != PEP_KEY_NOT_FOUND) {
484 first_reject_status = status;
485 first_reject_comm_type = stored_identity->comm_type;
488 switch (stored_identity->comm_type) {
489 case PEP_ct_key_revoked:
490 case PEP_ct_key_b0rken:
491 case PEP_ct_key_expired:
492 case PEP_ct_key_expired_but_confirmed:
493 case PEP_ct_compromised:
494 case PEP_ct_mistrusted:
495 // this only happens when it's all there is
496 status = first_reject_status;
497 free(stored_identity->fpr);
498 stored_identity->fpr = NULL;
499 stored_identity->comm_type = first_reject_comm_type;
502 if (check_blacklist && status == PEP_KEY_BLACKLISTED) {
503 free(stored_identity->fpr);
504 stored_identity->fpr = NULL;
505 stored_identity->comm_type = PEP_ct_key_not_found;
510 // should never happen, but we will MAKE sure
511 if (PASS_ERROR(status))
512 status = PEP_KEY_UNSUITABLE; // renew it on your own time, baby
520 * <!-- transfer_ident_lang_and_flags() -->
524 * @param[in] *new_ident pEp_identity
525 * @param[in] *stored_ident pEp_identity
528 static void transfer_ident_lang_and_flags(pEp_identity* new_ident,
529 pEp_identity* stored_ident) {
531 if (!(new_ident && stored_ident))
534 if (new_ident->lang[0] == 0) {
535 new_ident->lang[0] = stored_ident->lang[0];
536 new_ident->lang[1] = stored_ident->lang[1];
537 new_ident->lang[2] = 0;
540 new_ident->flags = stored_ident->flags;
541 new_ident->me = new_ident->me || stored_ident->me;
547 * <!-- adjust_pEp_trust_status() -->
551 * @param[in] session PEP_SESSION
552 * @param[in] *identity pEp_identity
555 static void adjust_pEp_trust_status(PEP_SESSION session, pEp_identity* identity) {
559 if (!session || !identity ||
560 identity->comm_type < PEP_ct_strong_but_unconfirmed ||
561 ((identity->comm_type | PEP_ct_confirmed) == PEP_ct_pEp) )
566 is_pEp_user(session, identity, &pEp_user);
569 PEP_comm_type confirmation_status = identity->comm_type & PEP_ct_confirmed;
570 identity->comm_type = PEP_ct_pEp_unconfirmed | confirmation_status;
571 if (identity->major_ver == 0) {
572 identity->major_ver = 2;
573 identity->minor_ver = 0;
579 // NEVER called on an own identity.
580 // But we also make sure get_valid_pubkey
581 // and friends NEVER return with a password error.
582 // (get_valid_pubkey tells validate_fpr not to try renewal)
583 // Will not return PASSPHRASE errors.
587 * <!-- prepare_updated_identity() -->
591 * @param[in] session PEP_SESSION
592 * @param[in] *return_id pEp_identity
593 * @param[in] *stored_ident pEp_identity
594 * @param[in] store bool
597 static PEP_STATUS prepare_updated_identity(PEP_SESSION session,
598 pEp_identity* return_id,
599 pEp_identity* stored_ident,
602 if (!session || !return_id || !stored_ident)
603 return PEP_ILLEGAL_VALUE;
607 bool is_identity_default, is_user_default, is_address_default;
608 bool no_stored_default = EMPTYSTR(stored_ident->fpr);
610 status = get_valid_pubkey(session, stored_ident,
611 &is_identity_default,
618 if (!EMPTYSTR(stored_ident->fpr)) {
619 // set identity comm_type from trust db (user_id, FPR)
620 status = get_trust(session, stored_ident);
621 if (status == PEP_CANNOT_FIND_IDENTITY || stored_ident->comm_type == PEP_ct_unknown) {
622 // This is OK - there is no trust DB entry, but we
623 // found a key. We won't store this, but we'll
625 PEP_comm_type ct = PEP_ct_unknown;
626 status = get_key_rating(session, stored_ident->fpr, &ct);
627 stored_ident->comm_type = ct;
630 else if (stored_ident->comm_type == PEP_ct_unknown)
631 stored_ident->comm_type = PEP_ct_key_not_found;
634 free(stored_ident->fpr);
635 stored_ident->fpr = NULL;
636 stored_ident->comm_type = PEP_ct_key_not_found;
639 free(return_id->fpr);
640 return_id->fpr = NULL;
641 if (status == PEP_STATUS_OK && !EMPTYSTR(stored_ident->fpr))
642 return_id->fpr = strdup(stored_ident->fpr);
644 return_id->comm_type = stored_ident->comm_type;
646 // We patch the DB with the input username, but if we didn't have
647 // one, we pull it out of storage if available.
648 if (!EMPTYSTR(stored_ident->username)) {
649 if (!EMPTYSTR(return_id->username) &&
650 (strcasecmp(return_id->username, return_id->address) == 0)) {
651 free(return_id->username);
652 return_id->username = NULL;
654 if (EMPTYSTR(return_id->username)) {
655 free(return_id->username);
656 return_id->username = strdup(stored_ident->username);
660 if (EMPTYSTR(return_id->username))
661 return_id->username = strdup(return_id->address);
664 return_id->me = stored_ident->me;
666 return_id->major_ver = stored_ident->major_ver;
667 return_id->minor_ver = stored_ident->minor_ver;
669 // FIXME: Do we ALWAYS do this? We probably should...
670 if (EMPTYSTR(return_id->user_id)) {
671 free(return_id->user_id);
672 return_id->user_id = strdup(stored_ident->user_id);
675 adjust_pEp_trust_status(session, return_id);
677 // Call set_identity() to store
678 if ((is_identity_default || is_user_default) &&
679 is_address_default) {
680 // if we got an fpr which is default for either user
681 // or identity AND is valid for this address, set in DB
683 status = set_identity(session, return_id);
685 else if (no_stored_default && !EMPTYSTR(return_id->fpr)
686 && return_id->comm_type != PEP_ct_key_revoked
687 && return_id->comm_type != PEP_ct_key_expired
688 && return_id->comm_type != PEP_ct_key_expired_but_confirmed
689 && return_id->comm_type != PEP_ct_mistrusted
690 && return_id->comm_type != PEP_ct_key_b0rken) {
691 // We would have stored this anyway for a first-time elected key. We just have an ident w/ no default already.
692 status = set_identity(session, return_id);
694 else { // this is a key other than the default, but there IS a default (FIXME: fdik, do we really want behaviour below?)
695 // Store without default fpr/ct, but return the fpr and ct
697 char* save_fpr = return_id->fpr;
698 PEP_comm_type save_ct = return_id->comm_type;
699 return_id->fpr = NULL;
700 return_id->comm_type = PEP_ct_unknown;
701 PEP_STATUS save_status = status;
702 status = set_identity(session, return_id);
703 if (save_status != PEP_STATUS_OK)
704 status = save_status;
705 return_id->fpr = save_fpr;
706 return_id->comm_type = save_ct;
709 transfer_ident_lang_and_flags(return_id, stored_ident);
710 return_id->enc_format = stored_ident->enc_format;
712 if (return_id->comm_type == PEP_ct_unknown)
713 return_id->comm_type = PEP_ct_key_not_found;
718 // Should not return PASSPHRASE errors because we force
719 // calls that can cause key renewal not to.
720 DYNAMIC_API PEP_STATUS update_identity(
721 PEP_SESSION session, pEp_identity * identity
728 assert(!EMPTYSTR(identity->address));
730 if (!(session && identity && !EMPTYSTR(identity->address)))
731 return PEP_ILLEGAL_VALUE;
733 char* default_own_id = NULL;
734 status = get_default_own_userid(session, &default_own_id);
736 bool is_own_user = identity->me;
738 // Is this me, temporary or not? If so, BAIL.
740 if (default_own_id) {
741 if (!EMPTYSTR(identity->user_id)) {
742 if (strcmp(default_own_id, identity->user_id) == 0) {
747 if (get_userid_alias_default(session, identity->user_id, &alias) == PEP_STATUS_OK) {
748 if (alias && strcmp(default_own_id, alias) == 0)
755 // Check if own address. For now, this is a special case;
756 // we try to require apps to send in user_ids, but must prevent
757 // writes to an own identity from within THIS function
758 // NOTE: These semantics MAY CHANGE.
759 bool _own_addr = false;
760 is_own_address(session, identity->address, &_own_addr);
762 // N.B. KB: I would prefer consistent semantics here - that is to say,
763 // we also set is_own_user here and force PEP_ILLEGAL_VALUE
765 free(identity->user_id);
766 identity->user_id = strdup(default_own_id);
767 // Do not renew, do not generate
768 return _myself(session, identity, false, false, false, true);
772 // Otherwise, we don't even HAVE an own user yet, so we're ok.
776 free(default_own_id);
777 return PEP_ILLEGAL_VALUE;
780 // We have, at least, an address.
781 // Retrieve stored identity information!
782 pEp_identity* stored_ident = NULL;
784 if (!EMPTYSTR(identity->user_id)) {
785 // (we're gonna update the trust/fpr anyway, so we use the no-fpr-from-trust-db variant)
786 // * do get_identity() to retrieve stored identity information
787 status = get_identity_without_trust_check(session, identity->address, identity->user_id, &stored_ident);
789 // Before we start - if there was no stored identity, we should check to make sure we don't
790 // have a stored identity with a temporary user_id that differs from the input user_id. This
791 // happens in multithreaded environments sometimes.
793 identity_list* id_list = NULL;
794 status = get_identities_by_address(session, identity->address, &id_list);
797 identity_list* id_curr = id_list;
798 bool input_is_TOFU = (strstr(identity->user_id, "TOFU_") == identity->user_id);
800 pEp_identity* this_id = id_curr->ident;
802 char* this_uid = this_id->user_id;
803 bool curr_is_TOFU = false;
804 // this_uid should never be NULL, as this is half of the ident
806 assert(!EMPTYSTR(this_uid));
808 curr_is_TOFU = (strstr(this_uid, "TOFU_") == this_uid);
809 if (curr_is_TOFU && !input_is_TOFU) {
810 // FIXME: should we also be fixing pEp_own_userId in this
813 // if usernames match, we replace the userid.
814 // FIXME: do we need to create an address match function which
815 // matches the whole dot-and-case rigamarole from
816 if (EMPTYSTR(this_id->username) ||
817 strcasecmp(this_id->username, this_id->address) == 0 ||
818 (identity->username &&
819 strcasecmp(identity->username,
820 this_id->username) == 0)) {
822 // Ok, we have a temp ID. We have to replace this
824 status = replace_userid(session,
827 if (status != PEP_STATUS_OK) {
828 free_identity_list(id_list);
829 free(default_own_id);
836 // Reflect the change we just made to the DB
837 this_id->user_id = NULL;
839 stored_ident = identity_dup(this_id);
842 stored_ident->user_id = strdup(identity->user_id);
846 else if (input_is_TOFU && !curr_is_TOFU) {
847 // Replace ruthlessly - this is NOT supposed to happen.
848 // BAD APP BEHAVIOUR.
849 free(identity->user_id);
850 identity->user_id = strdup(this_id->user_id);
851 stored_ident = identity_dup(this_id);
858 id_curr = id_curr->next;
860 free_identity_list(id_list);
865 if (status == PEP_STATUS_OK && stored_ident) {
866 // * if identity available
867 // * patch it with username
868 // (note: this will happen when
869 // setting automatically below...)
870 // * elect valid key for identity
871 // * if valid key exists
872 // * set return value's fpr
873 status = prepare_updated_identity(session,
877 // * else (identity unavailable)
879 status = PEP_STATUS_OK;
881 // FIXME: We may need to roll this back.
882 // FIXME: change docs if we don't
883 // if we only have user_id and address and identity not available
884 // * return error status (identity not found)
885 if (EMPTYSTR(identity->username)) {
886 free(identity->username);
887 identity->username = strdup(identity->address);
890 // Otherwise, if we had user_id, address, and username:
891 // * create identity with user_id, address, username
892 // (this is the input id without the fpr + comm type!)
894 // the only non-OK status which must be addressed here
895 // (and is possible) is PEP_OUT_OF_MEMORY. This function will
896 // disappear in the next release, so we check for this and
897 // handle it explicitly.
898 status = elect_pubkey(session, identity, false);
899 if (status == PEP_OUT_OF_MEMORY)
902 // * We've already checked and retrieved
903 // any applicable temporary identities above. If we're
904 // here, none of them fit.
905 // * call set_identity() to store
906 // FIXME: Do we set if we had to copy in the address?
907 adjust_pEp_trust_status(session, identity);
908 status = set_identity(session, identity);
909 // * Return: created identity
912 else if (!EMPTYSTR(identity->username)) {
914 * Temporary identity information with username supplied
915 * Input: address, username (no others)
918 // * See if there is an own identity that uses this address. If so, we'll
922 if (default_own_id) {
923 status = get_identity(session,
928 // If there isn't an own identity, search for a non-temp stored ident
929 // with this address.
930 if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) {
932 identity_list* id_list = NULL;
933 status = get_identities_by_address(session, identity->address, &id_list);
936 identity_list* id_curr = id_list;
938 pEp_identity* this_id = id_curr->ident;
940 char* this_uid = this_id->user_id;
941 assert(!EMPTYSTR(this_uid));
942 // Should never be NULL - DB primary key
944 if (strstr(this_uid, "TOFU_") != this_uid) {
945 // if usernames match, we replace the userid.
946 if (identity->username &&
947 strcasecmp(identity->username,
948 this_id->username) == 0) {
950 // Ok, we have a real ID. Copy it!
951 identity->user_id = strdup(this_uid);
952 assert(identity->user_id);
953 if (!identity->user_id)
956 stored_ident = identity_dup(this_id);
961 id_curr = id_curr->next;
963 free_identity_list(id_list);
969 status = prepare_updated_identity(session,
974 identity->user_id = calloc(1, strlen(identity->address) + 6);
975 if (!identity->user_id)
978 snprintf(identity->user_id, strlen(identity->address) + 6,
979 "TOFU_%s", identity->address);
981 status = get_identity(session,
986 if (status == PEP_STATUS_OK && stored_ident) {
987 status = prepare_updated_identity(session,
993 // * We've already checked and retrieved
994 // any applicable temporary identities above. If we're
995 // here, none of them fit.
997 status = elect_pubkey(session, identity, false);
999 // * call set_identity() to store
1000 if (identity->fpr) {
1001 // it is still possible we have DB information on this key. Better check.
1002 status = get_trust(session, identity);
1003 PEP_comm_type db_ct = identity->comm_type;
1004 status = get_key_rating(session, identity->fpr, &identity->comm_type);
1005 PEP_comm_type key_ct = identity->comm_type;
1007 if (status == PEP_STATUS_OK) {
1009 case PEP_ct_key_expired:
1010 if (db_ct == PEP_ct_key_expired_but_confirmed)
1011 identity->comm_type = db_ct;
1015 case PEP_ct_key_expired_but_confirmed:
1016 if (key_ct >= PEP_ct_strong_but_unconfirmed)
1017 identity->comm_type |= PEP_ct_confirmed;
1019 case PEP_ct_mistrusted:
1020 case PEP_ct_compromised:
1021 case PEP_ct_key_b0rken:
1022 identity->comm_type = db_ct;
1030 // * call set_identity() to store
1031 adjust_pEp_trust_status(session, identity);
1032 status = set_identity(session, identity);
1038 * Input: address (no others)
1039 * Temporary identity information without username suplied
1042 // * Again, see if there is an own identity that uses this address. If so, we'll
1044 stored_ident = NULL;
1046 if (default_own_id) {
1047 status = get_identity(session,
1052 // If there isn't an own identity, search for a non-temp stored ident
1053 // with this address.
1054 if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) {
1056 identity_list* id_list = NULL;
1057 // * Search for identity with this address
1058 status = get_identities_by_address(session, identity->address, &id_list);
1060 // Results are ordered by timestamp descending, so this covers
1061 // both the one-result and multi-result cases
1062 if (id_list && id_list->ident) {
1063 if (stored_ident) // unlikely
1064 free_identity(stored_ident);
1065 stored_ident = identity_dup(id_list->ident);
1066 free_identity_list(id_list);
1071 status = prepare_updated_identity(session, identity,
1072 stored_ident, false);
1074 // too little info. BUT. We see if we can find a key; if so, we create a
1075 // temp identity, look for a key, and store.
1077 // create temporary identity, store it, and Return this
1078 // This means TOFU_ user_id
1079 identity->user_id = calloc(1, strlen(identity->address) + 6);
1080 if (!identity->user_id)
1083 snprintf(identity->user_id, strlen(identity->address) + 6,
1084 "TOFU_%s", identity->address);
1086 identity->username = strdup(identity->address);
1087 if (!identity->address)
1090 free(identity->fpr);
1091 identity->fpr = NULL;
1092 identity->comm_type = PEP_ct_unknown;
1094 status = elect_pubkey(session, identity, false);
1097 status = get_key_rating(session, identity->fpr, &identity->comm_type);
1099 // * call set_identity() to store
1100 adjust_pEp_trust_status(session, identity);
1101 status = set_identity(session, identity);
1106 // FIXME: This is legacy. I presume it's a notification for the caller...
1107 // Revisit once I can talk to Volker
1108 if (identity->comm_type != PEP_ct_compromised &&
1109 identity->comm_type < PEP_ct_strong_but_unconfirmed)
1110 if (session->examine_identity)
1111 session->examine_identity(identity, session->examine_management);
1116 status = PEP_OUT_OF_MEMORY;
1119 free(default_own_id);
1120 free_identity(stored_ident);
1127 * <!-- elect_ownkey() -->
1131 * @param[in] session PEP_SESSION
1132 * @param[in] *identity pEp_identity
1135 PEP_STATUS elect_ownkey(
1136 PEP_SESSION session, pEp_identity * identity
1139 if (!(session && identity))
1140 return PEP_ILLEGAL_VALUE;
1143 stringlist_t *keylist = NULL;
1145 free(identity->fpr);
1146 identity->fpr = NULL;
1148 status = find_private_keys(session, identity->address, &keylist);
1149 assert(status != PEP_OUT_OF_MEMORY);
1150 if (status == PEP_OUT_OF_MEMORY)
1151 return PEP_OUT_OF_MEMORY;
1153 if (keylist != NULL && keylist->value != NULL)
1156 identity->comm_type = PEP_ct_unknown;
1158 stringlist_t *_keylist;
1159 for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
1160 bool is_own = false;
1162 status = own_key_is_listed(session, _keylist->value, &is_own);
1163 assert(status == PEP_STATUS_OK);
1164 if (status != PEP_STATUS_OK) {
1165 free_stringlist(keylist);
1171 PEP_comm_type _comm_type_key;
1173 status = get_key_rating(session, _keylist->value, &_comm_type_key);
1174 assert(status != PEP_OUT_OF_MEMORY);
1175 if (status == PEP_OUT_OF_MEMORY) {
1176 free_stringlist(keylist);
1177 return PEP_OUT_OF_MEMORY;
1180 if (_comm_type_key != PEP_ct_compromised &&
1181 _comm_type_key != PEP_ct_unknown)
1183 if (identity->comm_type == PEP_ct_unknown ||
1184 _comm_type_key > identity->comm_type)
1186 identity->comm_type = _comm_type_key;
1187 _fpr = _keylist->value;
1195 identity->fpr = strdup(_fpr);
1196 assert(identity->fpr);
1197 if (identity->fpr == NULL)
1199 free_stringlist(keylist);
1200 return PEP_OUT_OF_MEMORY;
1203 free_stringlist(keylist);
1205 return PEP_STATUS_OK;
1211 * <!-- _has_usable_priv_key() -->
1215 * @param[in] session PEP_SESSION
1216 * @param[in] *fpr char
1217 * @param[in] *is_usable bool
1220 PEP_STATUS _has_usable_priv_key(PEP_SESSION session, char* fpr,
1223 bool has_private = false;
1224 PEP_STATUS status = contains_priv_key(session, fpr, &has_private);
1226 *is_usable = has_private;
1231 PEP_STATUS _myself(PEP_SESSION session,
1232 pEp_identity * identity,
1243 assert(!EMPTYSTR(identity->address));
1245 if (!session || !identity || EMPTYSTR(identity->address))
1246 return PEP_ILLEGAL_VALUE;
1248 // this is leading to crashes otherwise
1250 if (!(identity->user_id && identity->user_id[0])) {
1251 free(identity->user_id);
1252 identity->user_id = strdup(PEP_OWN_USERID);
1253 assert(identity->user_id);
1254 if (!identity->user_id)
1255 return PEP_OUT_OF_MEMORY;
1258 pEp_identity *stored_identity = NULL;
1259 char* revoked_fpr = NULL;
1260 bool valid_key_found = false;
1262 char* default_own_id = NULL;
1263 status = get_default_own_userid(session, &default_own_id);
1265 // Deal with non-default user_ids.
1266 // FIXME: if non-default and read-only, reject totally?
1267 if (default_own_id && strcmp(default_own_id, identity->user_id) != 0) {
1269 free(identity->user_id);
1270 identity->user_id = strdup(default_own_id);
1271 assert(identity->user_id);
1272 if (!identity->user_id)
1273 return PEP_OUT_OF_MEMORY;
1276 status = set_userid_alias(session, default_own_id, identity->user_id);
1277 // Do we want this to be fatal? For now, we'll do it...
1278 if (status != PEP_STATUS_OK)
1281 free(identity->user_id);
1282 identity->user_id = strdup(default_own_id);
1283 assert(identity->user_id);
1284 if (identity->user_id == NULL) {
1285 status = PEP_OUT_OF_MEMORY;
1291 // NOTE: IF WE DON'T YET HAVE AN OWN_ID, WE IGNORE REFERENCES TO THIS ADDRESS IN THE
1292 // DB (WHICH MAY HAVE BEEN SET BEFORE MYSELF WAS CALLED BY RECEIVING AN EMAIL FROM
1293 // THIS ADDRESS), AS IT IS NOT AN OWN_IDENTITY AND HAS NO INFORMATION WE NEED OR WHAT TO
1296 // Ok, so now, set up the own_identity:
1297 identity->comm_type = PEP_ct_pEp;
1298 identity->me = true;
1300 identity->flags = 0;
1302 // Let's see if we have an identity record in the DB for
1303 // this user_id + address
1304 // DEBUG_LOG("myself", "debug", identity->address);
1306 // This will grab the actual flags from the db
1307 status = get_identity(session,
1312 assert(status != PEP_OUT_OF_MEMORY);
1313 if (status == PEP_OUT_OF_MEMORY) {
1314 status = PEP_OUT_OF_MEMORY;
1318 // Set usernames - priority is input username > stored name > address
1319 // If there's an input username, we always patch the username with that
1321 // N.B. there was an || read_only here, but why? read_only ONLY means
1322 // we don't write to the DB! So... removed. But how this managed to work
1323 // before I don't know.
1324 if (EMPTYSTR(identity->username)) {
1325 bool stored_uname = (stored_identity && !EMPTYSTR(stored_identity->username));
1326 char* uname = (stored_uname ? stored_identity->username : identity->address);
1328 free(identity->username);
1329 identity->username = strdup(uname);
1330 assert(identity->username);
1331 if (identity->username == NULL) {
1332 status = PEP_OUT_OF_MEMORY;
1340 if (identity->fpr) {
1341 free(identity->fpr);
1342 identity->fpr = NULL;
1345 // check stored identity
1346 if (stored_identity) {
1347 if (!EMPTYSTR(stored_identity->fpr)) {
1348 // Fall back / retrieve
1349 status = validate_fpr(session, stored_identity, false, true, do_renew);
1352 // Only possible if we called this with do_renew = true
1353 case PEP_OUT_OF_MEMORY:
1354 case PEP_PASSPHRASE_REQUIRED:
1355 case PEP_WRONG_PASSPHRASE:
1359 if (stored_identity->comm_type >= PEP_ct_strong_but_unconfirmed) {
1360 identity->fpr = strdup(stored_identity->fpr);
1361 assert(identity->fpr);
1362 if (!identity->fpr) {
1363 status = PEP_OUT_OF_MEMORY;
1366 valid_key_found = true;
1369 bool revoked = false;
1370 status = key_revoked(session, stored_identity->fpr, &revoked);
1374 revoked_fpr = strdup(stored_identity->fpr);
1375 assert(revoked_fpr);
1377 status = PEP_OUT_OF_MEMORY;
1387 // reconcile language, flags
1388 transfer_ident_lang_and_flags(identity, stored_identity);
1391 // Nothing left to do but generate a key
1392 if (!valid_key_found) {
1393 if (!do_keygen || read_only)
1394 status = PEP_GET_KEY_FAILED;
1396 // / DEBUG_LOG("Generating key pair", "debug", identity->address);
1398 free(identity->fpr);
1399 identity->fpr = NULL;
1400 status = generate_keypair(session, identity);
1401 assert(status != PEP_OUT_OF_MEMORY);
1403 if (status == PEP_PASSPHRASE_FOR_NEW_KEYS_REQUIRED)
1406 if (status != PEP_STATUS_OK) {
1408 snprintf(buf, 11, "%d", status); // uh, this is kludgey. FIXME
1409 // DEBUG_LOG("Generating key pair failed", "debug", buf);
1412 valid_key_found = true;
1414 status = set_revoked(session, revoked_fpr,
1415 stored_identity->fpr, time(NULL));
1416 assert(status == PEP_STATUS_OK);
1422 if (valid_key_found) {
1423 identity->comm_type = PEP_ct_pEp;
1424 status = PEP_STATUS_OK;
1427 free(identity->fpr);
1428 identity->fpr = NULL;
1429 identity->comm_type = PEP_ct_unknown;
1432 unsigned int major_ver = 0;
1433 unsigned int minor_ver = 0;
1434 pEp_version_major_minor(PEP_VERSION, &major_ver, &minor_ver);
1435 identity->major_ver = major_ver;
1436 identity->minor_ver = minor_ver;
1438 // We want to set an identity in the DB even if a key isn't found, but we have to preserve the status if
1441 PEP_STATUS set_id_status = set_identity(session, identity);
1442 if (set_id_status == PEP_STATUS_OK)
1443 set_id_status = set_as_pEp_user(session, identity);
1445 status = (status == PEP_STATUS_OK ? set_id_status : status);
1449 free(default_own_id);
1451 free_identity(stored_identity);
1455 DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
1457 return _myself(session, identity, true, true, false, false);
1460 DYNAMIC_API PEP_STATUS register_examine_function(
1461 PEP_SESSION session,
1462 examine_identity_t examine_identity,
1468 return PEP_ILLEGAL_VALUE;
1470 session->examine_management = management;
1471 session->examine_identity = examine_identity;
1473 return PEP_STATUS_OK;
1476 DYNAMIC_API PEP_STATUS do_keymanagement(
1477 retrieve_next_identity_t retrieve_next_identity,
1481 PEP_SESSION session;
1482 pEp_identity *identity;
1483 // FIXME_NOW: ensure_decrypt callback???
1484 PEP_STATUS status = init(&session, NULL, NULL, NULL);
1489 assert(session && retrieve_next_identity);
1490 if (!(session && retrieve_next_identity))
1491 return PEP_ILLEGAL_VALUE;
1493 log_event(session, "keymanagement thread started", "pEp engine", NULL, NULL);
1495 while ((identity = retrieve_next_identity(management)))
1497 assert(identity->address);
1498 if(identity->address)
1500 DEBUG_LOG("do_keymanagement", "retrieve_next_identity", identity->address);
1503 status = myself(session, identity);
1505 status = recv_key(session, identity->address);
1508 assert(status != PEP_OUT_OF_MEMORY);
1509 if(status == PEP_OUT_OF_MEMORY)
1510 return PEP_OUT_OF_MEMORY;
1512 free_identity(identity);
1515 log_event(session, "keymanagement thread shutdown", "pEp engine", NULL, NULL);
1517 return PEP_STATUS_OK;
1520 DYNAMIC_API PEP_STATUS key_mistrusted(
1521 PEP_SESSION session,
1525 PEP_STATUS status = PEP_STATUS_OK;
1529 assert(!EMPTYSTR(ident->fpr));
1531 if (!(session && ident && ident->fpr))
1532 return PEP_ILLEGAL_VALUE;
1534 bool has_private = false;
1536 status = contains_priv_key(session, ident->fpr, &has_private);
1538 if (status != PEP_STATUS_OK && status != PEP_KEY_NOT_FOUND)
1541 // See if key is revoked already
1543 bool revoked = false;
1544 status = key_revoked(session, ident->fpr, &revoked);
1547 revoke_key(session, ident->fpr, NULL);
1551 // Make sure there was a default in the DB for this identity;
1552 // if not, set one, even though we're going to mistrust this. Otherwise,
1554 pEp_identity* stored_ident = NULL;
1555 get_identity(session, ident->address, ident->user_id, &stored_ident);
1556 bool set_in_db = true;
1558 stored_ident = identity_dup(ident);
1559 else if (!stored_ident->fpr)
1560 stored_ident->fpr = strdup(ident->fpr);
1565 status = set_identity(session, stored_ident);
1567 free_identity(stored_ident);
1568 if (status != PEP_STATUS_OK)
1573 // double-check to be sure key is even in the DB
1575 status = set_pgp_keypair(session, ident->fpr);
1577 // We set this temporarily but will grab it back from the cache afterwards
1578 ident->comm_type = PEP_ct_mistrusted;
1579 status = set_trust(session, ident);
1581 if (status == PEP_STATUS_OK)
1582 // cascade that mistrust for anyone using this key
1583 status = mark_as_compromised(session, ident->fpr);
1584 if (status == PEP_STATUS_OK)
1585 status = add_mistrusted_key(session, ident->fpr);
1590 DYNAMIC_API PEP_STATUS key_reset_trust(
1591 PEP_SESSION session,
1595 PEP_STATUS status = PEP_STATUS_OK;
1599 assert(!EMPTYSTR(ident->fpr));
1600 assert(!EMPTYSTR(ident->address));
1601 assert(!EMPTYSTR(ident->user_id));
1603 if (!(session && ident && ident->fpr && ident->fpr[0] != '\0' && ident->address &&
1605 return PEP_ILLEGAL_VALUE;
1607 // we do not change the input struct at ALL.
1608 pEp_identity* input_copy = identity_dup(ident);
1610 pEp_identity* tmp_ident = NULL;
1612 status = get_trust(session, input_copy);
1614 if (status != PEP_STATUS_OK)
1617 PEP_comm_type new_trust = PEP_ct_unknown;
1618 status = get_key_rating(session, ident->fpr, &new_trust);
1619 if (status != PEP_STATUS_OK)
1622 bool pEp_user = false;
1624 status = is_pEp_user(session, ident, &pEp_user);
1626 if (pEp_user && new_trust >= PEP_ct_unconfirmed_encryption)
1627 input_copy->comm_type = PEP_ct_pEp_unconfirmed;
1629 input_copy->comm_type = new_trust;
1631 status = set_trust(session, input_copy);
1633 if (status != PEP_STATUS_OK)
1636 bool mistrusted_key = false;
1638 status = is_mistrusted_key(session, ident->fpr, &mistrusted_key);
1640 if (status != PEP_STATUS_OK)
1644 status = delete_mistrusted_key(session, ident->fpr);
1646 if (status != PEP_STATUS_OK)
1649 tmp_ident = new_identity(ident->address, NULL, ident->user_id, NULL);
1652 return PEP_OUT_OF_MEMORY;
1654 if (is_me(session, tmp_ident))
1655 status = myself(session, tmp_ident);
1657 status = update_identity(session, tmp_ident);
1659 if (status != PEP_STATUS_OK)
1662 // remove as default if necessary
1663 if (!EMPTYSTR(tmp_ident->fpr) && strcmp(tmp_ident->fpr, ident->fpr) == 0) {
1664 free(tmp_ident->fpr);
1665 tmp_ident->fpr = NULL;
1666 tmp_ident->comm_type = PEP_ct_unknown;
1667 status = set_identity(session, tmp_ident);
1668 if (status != PEP_STATUS_OK)
1672 char* user_default = NULL;
1673 get_main_user_fpr(session, tmp_ident->user_id, &user_default);
1675 if (!EMPTYSTR(user_default)) {
1676 if (strcmp(user_default, ident->fpr) == 0)
1677 status = refresh_userid_default_key(session, ident->user_id);
1678 if (status != PEP_STATUS_OK)
1683 free_identity(tmp_ident);
1684 free_identity(input_copy);
1688 // Technically speaking, this should not EVER
1689 // return PASSPHRASE errors, because
1690 // this is never for an own identity (enforced), and thus
1691 // validate_fpr will not call renew_key.
1692 // If it ever does, the status gets propagated, but
1693 // it is distinctly not OK.
1694 DYNAMIC_API PEP_STATUS trust_personal_key(
1695 PEP_SESSION session,
1699 PEP_STATUS status = PEP_STATUS_OK;
1703 assert(!EMPTYSTR(ident->address));
1704 assert(!EMPTYSTR(ident->user_id));
1705 assert(!EMPTYSTR(ident->fpr));
1707 if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
1708 EMPTYSTR(ident->fpr))
1709 return PEP_ILLEGAL_VALUE;
1711 if (is_me(session, ident))
1712 return PEP_ILLEGAL_VALUE;
1714 char* ident_default_fpr = NULL;
1716 // Before we do anything, be sure the input fpr is even eligible to be trusted
1717 PEP_comm_type input_default_ct = PEP_ct_unknown;
1718 status = get_key_rating(session, ident->fpr, &input_default_ct);
1719 if (input_default_ct < PEP_ct_strong_but_unconfirmed)
1720 return PEP_KEY_UNSUITABLE;
1722 status = set_pgp_keypair(session, ident->fpr);
1723 if (status != PEP_STATUS_OK)
1726 pEp_identity* ident_copy = identity_dup(ident);
1727 char* cached_fpr = NULL;
1729 // for setting up a temp trusted identity for the input fpr
1730 pEp_identity* tmp_id = NULL;
1732 // For later, in case we need to check the user default key
1733 pEp_identity* tmp_user_ident = NULL;
1735 // Save the input fpr, which we already tested as non-NULL
1736 cached_fpr = strdup(ident->fpr);
1738 // Set up a temp trusted identity for the input fpr without a comm type;
1739 tmp_id = new_identity(ident->address, ident->fpr, ident->user_id, NULL);
1741 status = validate_fpr(session, tmp_id, false, true, false);
1743 if (status == PEP_STATUS_OK) {
1744 // Validate fpr gets trust DB or, when that fails, key comm type. we checked
1745 // above that the key was ok. (not revoked or expired), but we want the max.
1746 tmp_id->comm_type = _MAX(tmp_id->comm_type, input_default_ct) | PEP_ct_confirmed;
1748 // Get the default identity without setting the fpr
1749 status = update_identity(session, ident_copy);
1751 ident_default_fpr = (EMPTYSTR(ident_copy->fpr) ? NULL : strdup(ident_copy->fpr));
1753 if (status == PEP_STATUS_OK) {
1754 bool trusted_default = false;
1756 // If there's no default, or the default is different from the input...
1757 if (EMPTYSTR(ident_default_fpr) || strcmp(cached_fpr, ident_default_fpr) != 0) {
1759 // If the default fpr (if there is one) is trusted and key is strong enough,
1760 // don't replace, we just set the trusted bit on this key for this user_id...
1761 // (If there's no default fpr, this won't be true anyway.)
1762 if ((ident_copy->comm_type >= PEP_ct_strong_but_unconfirmed &&
1763 (ident_copy->comm_type & PEP_ct_confirmed))) {
1765 trusted_default = true;
1767 status = set_trust(session, tmp_id);
1768 input_default_ct = tmp_id->comm_type;
1771 free(ident_copy->fpr);
1772 ident_copy->fpr = strdup(cached_fpr);
1773 ident_copy->comm_type = tmp_id->comm_type;
1774 status = set_identity(session, ident_copy); // replace identity default
1775 if (status == PEP_STATUS_OK) {
1776 if ((ident_copy->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
1777 status = set_as_pEp_user(session, ident_copy);
1781 else { // we're setting this on the default fpr
1782 ident->comm_type = tmp_id->comm_type;
1783 status = set_identity(session, ident);
1784 trusted_default = true;
1786 if (status == PEP_STATUS_OK && !trusted_default) {
1787 // Ok, there wasn't a trusted default, so we replaced. Thus, we also
1788 // make sure there's a trusted default on the user_id. If there
1789 // is not, we make this the default.
1790 char* user_default = NULL;
1791 status = get_main_user_fpr(session, ident->user_id, &user_default);
1793 if (status == PEP_STATUS_OK && user_default) {
1794 tmp_user_ident = new_identity(ident->address,
1798 if (!tmp_user_ident)
1799 status = PEP_OUT_OF_MEMORY;
1801 status = validate_fpr(session, tmp_user_ident, false, true, false);
1803 if (status != PEP_STATUS_OK ||
1804 tmp_user_ident->comm_type < PEP_ct_strong_but_unconfirmed ||
1805 !(tmp_user_ident->comm_type & PEP_ct_confirmed))
1807 char* trusted_fpr = (trusted_default ? ident_default_fpr : cached_fpr);
1808 status = replace_main_user_fpr(session, ident->user_id, trusted_fpr);
1816 free(ident_default_fpr);
1818 free_identity(tmp_id);
1819 free_identity(ident_copy);
1820 free_identity(tmp_user_ident);
1824 DYNAMIC_API PEP_STATUS trust_own_key(
1825 PEP_SESSION session,
1831 assert(!EMPTYSTR(ident->address));
1832 assert(!EMPTYSTR(ident->user_id));
1833 assert(!EMPTYSTR(ident->fpr));
1835 if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
1836 EMPTYSTR(ident->fpr))
1837 return PEP_ILLEGAL_VALUE;
1839 if (!is_me(session, ident))
1840 return PEP_ILLEGAL_VALUE;
1842 // don't check blacklist or require a private key
1843 PEP_STATUS status = validate_fpr(session, ident, false, false, true);
1845 if (status != PEP_STATUS_OK)
1848 status = set_pgp_keypair(session, ident->fpr);
1849 if (status != PEP_STATUS_OK)
1852 if (ident->comm_type < PEP_ct_strong_but_unconfirmed)
1853 return PEP_KEY_UNSUITABLE;
1855 ident->comm_type |= PEP_ct_confirmed;
1857 status = set_trust(session, ident);
1863 DYNAMIC_API PEP_STATUS own_key_is_listed(
1864 PEP_SESSION session,
1869 PEP_STATUS status = PEP_STATUS_OK;
1872 assert(session && fpr && fpr[0] && listed);
1874 if (!(session && fpr && fpr[0] && listed))
1875 return PEP_ILLEGAL_VALUE;
1879 sqlite3_reset(session->own_key_is_listed);
1880 sqlite3_bind_text(session->own_key_is_listed, 1, fpr, -1, SQLITE_STATIC);
1884 result = sqlite3_step(session->own_key_is_listed);
1887 count = sqlite3_column_int(session->own_key_is_listed, 0);
1888 *listed = count > 0;
1889 status = PEP_STATUS_OK;
1893 status = PEP_UNKNOWN_ERROR;
1896 sqlite3_reset(session->own_key_is_listed);
1900 PEP_STATUS _own_identities_retrieve(
1901 PEP_SESSION session,
1902 identity_list **own_identities,
1903 identity_flags_t excluded_flags
1906 PEP_STATUS status = PEP_STATUS_OK;
1908 assert(session && own_identities);
1909 if (!(session && own_identities))
1910 return PEP_ILLEGAL_VALUE;
1912 *own_identities = NULL;
1913 identity_list *_own_identities = new_identity_list(NULL);
1914 if (_own_identities == NULL)
1917 sqlite3_reset(session->own_identities_retrieve);
1920 // address, fpr, username, user_id, comm_type, lang, flags
1921 const char *address = NULL;
1922 const char *fpr = NULL;
1923 const char *username = NULL;
1924 const char *user_id = NULL;
1925 PEP_comm_type comm_type = PEP_ct_unknown;
1926 const char *lang = NULL;
1927 unsigned int flags = 0;
1929 identity_list *_bl = _own_identities;
1931 sqlite3_bind_int(session->own_identities_retrieve, 1, excluded_flags);
1934 result = sqlite3_step(session->own_identities_retrieve);
1937 address = (const char *)
1938 sqlite3_column_text(session->own_identities_retrieve, 0);
1939 fpr = (const char *)
1940 sqlite3_column_text(session->own_identities_retrieve, 1);
1941 user_id = (const char *)
1942 sqlite3_column_text(session->own_identities_retrieve, 2);
1943 username = (const char *)
1944 sqlite3_column_text(session->own_identities_retrieve, 3);
1945 comm_type = PEP_ct_pEp;
1946 lang = (const char *)
1947 sqlite3_column_text(session->own_identities_retrieve, 4);
1948 flags = (unsigned int)
1949 sqlite3_column_int(session->own_identities_retrieve, 5);
1951 pEp_identity *ident = new_identity(address, fpr, user_id, username);
1954 ident->comm_type = comm_type;
1955 if (lang && lang[0]) {
1956 ident->lang[0] = lang[0];
1957 ident->lang[1] = lang[1];
1961 ident->flags = flags;
1963 _bl = identity_list_add(_bl, ident);
1965 free_identity(ident);
1975 status = PEP_UNKNOWN_ERROR;
1976 result = SQLITE_DONE;
1978 } while (result != SQLITE_DONE);
1980 sqlite3_reset(session->own_identities_retrieve);
1981 if (status == PEP_STATUS_OK)
1982 *own_identities = _own_identities;
1984 free_identity_list(_own_identities);
1989 free_identity_list(_own_identities);
1990 status = PEP_OUT_OF_MEMORY;
1996 DYNAMIC_API PEP_STATUS own_identities_retrieve(
1997 PEP_SESSION session,
1998 identity_list **own_identities
2001 return _own_identities_retrieve(session, own_identities, 0);
2004 PEP_STATUS _own_keys_retrieve(
2005 PEP_SESSION session,
2006 stringlist_t **keylist,
2007 identity_flags_t excluded_flags,
2011 PEP_STATUS status = PEP_STATUS_OK;
2013 assert(session && keylist);
2014 if (!(session && keylist))
2015 return PEP_ILLEGAL_VALUE;
2018 stringlist_t *_keylist = NULL;
2020 sqlite3_reset(session->own_keys_retrieve);
2024 stringlist_t *_bl = _keylist;
2025 sqlite3_bind_int(session->own_keys_retrieve, 1, excluded_flags);
2028 result = sqlite3_step(session->own_keys_retrieve);
2031 _bl = stringlist_add(_bl, (const char *)
2032 sqlite3_column_text(session->own_keys_retrieve, 0));
2035 if (_keylist == NULL)
2043 status = PEP_UNKNOWN_ERROR;
2044 result = SQLITE_DONE;
2046 } while (result != SQLITE_DONE);
2048 sqlite3_reset(session->own_keys_retrieve);
2049 if (status == PEP_STATUS_OK) {
2050 dedup_stringlist(_keylist);
2052 stringlist_t* _kl = _keylist;
2053 stringlist_t* _kl_prev = NULL;
2055 bool has_private = false;
2056 contains_priv_key(session, _kl->value, &has_private);
2058 stringlist_t* _kl_tmp = _kl;
2060 _kl_prev->next = _kl->next;
2062 _keylist = _kl->next;
2066 _kl_tmp->next = NULL;
2067 free_stringlist(_kl_tmp);
2074 *keylist = _keylist;
2077 free_stringlist(_keylist);
2082 free_stringlist(_keylist);
2083 status = PEP_OUT_OF_MEMORY;
2089 DYNAMIC_API PEP_STATUS own_keys_retrieve(PEP_SESSION session, stringlist_t **keylist)
2091 return _own_keys_retrieve(session, keylist, 0, true);
2094 // Returns PASSPHRASE errors when necessary
2095 DYNAMIC_API PEP_STATUS set_own_key(
2096 PEP_SESSION session,
2101 PEP_STATUS status = PEP_STATUS_OK;
2103 assert(session && me);
2104 assert(!EMPTYSTR(fpr));
2105 assert(!EMPTYSTR(me->address));
2106 assert(!EMPTYSTR(me->user_id));
2107 assert(!EMPTYSTR(me->username));
2109 if (!session || !me || EMPTYSTR(fpr) || EMPTYSTR(me->address) ||
2110 EMPTYSTR(me->user_id) || EMPTYSTR(me->username))
2111 return PEP_ILLEGAL_VALUE;
2116 // renew if needed, but do not generate
2117 status = _myself(session, me, false, true, true, false);
2118 // we do not need a valid key but dislike other errors
2119 if (status != PEP_STATUS_OK && status != PEP_GET_KEY_FAILED && status != PEP_KEY_UNSUITABLE)
2121 status = PEP_STATUS_OK;
2123 bool private = false;
2124 status = contains_priv_key(session, fpr, &private);
2126 if (status != PEP_STATUS_OK)
2130 return PEP_KEY_UNSUITABLE;
2134 me->fpr = strdup(fpr);
2137 return PEP_OUT_OF_MEMORY;
2139 status = validate_fpr(session, me, false, true, true);
2143 me->comm_type = PEP_ct_pEp;
2144 status = set_identity(session, me);
2145 if (status == PEP_STATUS_OK)
2146 signal_Sync_event(session, Sync_PR_keysync, SynchronizeGroupKeys, NULL);
2151 PEP_STATUS contains_priv_key(PEP_SESSION session, const char *fpr,
2152 bool *has_private) {
2156 assert(has_private);
2158 if (!(session && fpr && has_private))
2159 return PEP_ILLEGAL_VALUE;
2161 return session->cryptotech[PEP_crypt_OpenPGP].contains_priv_key(session, fpr, has_private);
2164 PEP_STATUS add_mistrusted_key(PEP_SESSION session, const char* fpr)
2168 assert(!EMPTYSTR(fpr));
2170 if (!(session) || EMPTYSTR(fpr))
2171 return PEP_ILLEGAL_VALUE;
2173 sqlite3_reset(session->add_mistrusted_key);
2174 sqlite3_bind_text(session->add_mistrusted_key, 1, fpr, -1,
2177 result = sqlite3_step(session->add_mistrusted_key);
2178 sqlite3_reset(session->add_mistrusted_key);
2180 if (result != SQLITE_DONE)
2181 return PEP_CANNOT_SET_PGP_KEYPAIR; // FIXME: Better status?
2183 return PEP_STATUS_OK;
2186 PEP_STATUS delete_mistrusted_key(PEP_SESSION session, const char* fpr)
2190 assert(!EMPTYSTR(fpr));
2192 if (!(session) || EMPTYSTR(fpr))
2193 return PEP_ILLEGAL_VALUE;
2195 sqlite3_reset(session->delete_mistrusted_key);
2196 sqlite3_bind_text(session->delete_mistrusted_key, 1, fpr, -1,
2199 result = sqlite3_step(session->delete_mistrusted_key);
2200 sqlite3_reset(session->delete_mistrusted_key);
2202 if (result != SQLITE_DONE)
2203 return PEP_UNKNOWN_ERROR; // FIXME: Better status?
2205 return PEP_STATUS_OK;
2208 PEP_STATUS is_mistrusted_key(PEP_SESSION session, const char* fpr,
2211 PEP_STATUS status = PEP_STATUS_OK;
2214 assert(!EMPTYSTR(fpr));
2216 if (!(session && fpr))
2217 return PEP_ILLEGAL_VALUE;
2219 *mistrusted = false;
2221 sqlite3_reset(session->is_mistrusted_key);
2222 sqlite3_bind_text(session->is_mistrusted_key, 1, fpr, -1, SQLITE_STATIC);
2226 result = sqlite3_step(session->is_mistrusted_key);
2229 *mistrusted = sqlite3_column_int(session->is_mistrusted_key, 0);
2230 status = PEP_STATUS_OK;
2234 status = PEP_UNKNOWN_ERROR;
2237 sqlite3_reset(session->is_mistrusted_key);
2244 * <!-- _wipe_default_key_if_invalid() -->
2248 * @param[in] session PEP_SESSION
2249 * @param[in] *ident pEp_identity
2252 static PEP_STATUS _wipe_default_key_if_invalid(PEP_SESSION session,
2253 pEp_identity* ident) {
2255 if (!(session && ident))
2256 return PEP_ILLEGAL_VALUE;
2258 PEP_STATUS status = PEP_STATUS_OK;
2260 if (!ident->user_id)
2261 return PEP_ILLEGAL_VALUE;
2266 char* cached_fpr = strdup(ident->fpr);
2268 return PEP_OUT_OF_MEMORY;
2270 PEP_STATUS keystatus = validate_fpr(session, ident, true, false, true);
2271 if (PASS_ERROR(status))
2274 switch (keystatus) {
2276 // Check for non-renewable expiry and
2277 // if so, fallthrough
2278 if (ident->comm_type != PEP_ct_key_expired_but_confirmed &&
2279 ident->comm_type != PEP_ct_key_expired) {
2282 case PEP_KEY_UNSUITABLE:
2283 case PEP_KEY_BLACKLISTED:
2284 // Remove key as default for all identities and users
2285 status = remove_fpr_as_default(session, cached_fpr);
2292 // This may have been for a user default, not an identity default.
2293 if (status == PEP_STATUS_OK && !(EMPTYSTR(ident->address)))
2294 status = myself(session, ident);
2299 DYNAMIC_API PEP_STATUS clean_own_key_defaults(PEP_SESSION session) {
2302 return PEP_ILLEGAL_VALUE;
2304 identity_list* idents = NULL;
2305 PEP_STATUS status = own_identities_retrieve(session, &idents);
2306 if (status != PEP_STATUS_OK)
2310 return PEP_STATUS_OK;
2312 if (!idents->ident && !idents->next) {
2313 free_identity_list(idents);
2314 return PEP_STATUS_OK;
2315 } // Kludge: FIX own_identities_retrieve. Should return NULL, not empty list
2317 identity_list* curr = idents;
2319 for ( ; curr ; curr = curr->next) {
2320 pEp_identity* ident = curr->ident;
2324 status = _wipe_default_key_if_invalid(session, ident);
2325 if (PASS_ERROR(status))
2329 free_identity_list(idents);
2331 // Also remove invalid default user key
2332 char* own_id = NULL;
2334 status = get_default_own_userid(session, &own_id);
2336 if (status != PEP_STATUS_OK)
2340 char* user_default_key = NULL;
2341 status = get_user_default_key(session, own_id, &user_default_key);
2342 if (status != PEP_STATUS_OK) {
2344 if (status == PEP_KEY_NOT_FOUND)
2345 status = PEP_STATUS_OK;
2349 else if (user_default_key) {
2350 pEp_identity* empty_user = new_identity(NULL, user_default_key, own_id, NULL);
2351 status = _wipe_default_key_if_invalid(session, empty_user);
2352 if (PASS_ERROR(status))
2355 free(user_default_key);