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;
458 if (identity->major_ver == 0) {
459 identity->major_ver = 2;
460 identity->minor_ver = 0;
466 static PEP_STATUS prepare_updated_identity(PEP_SESSION session,
467 pEp_identity* return_id,
468 pEp_identity* stored_ident,
471 if (!session || !return_id || !stored_ident)
472 return PEP_ILLEGAL_VALUE;
476 bool is_identity_default, is_user_default, is_address_default;
477 bool no_stored_default = EMPTYSTR(stored_ident->fpr);
479 status = get_valid_pubkey(session, stored_ident,
480 &is_identity_default,
485 if (status == PEP_STATUS_OK && stored_ident->fpr && *(stored_ident->fpr) != '\0') {
486 // set identity comm_type from trust db (user_id, FPR)
487 status = get_trust(session, stored_ident);
488 if (status == PEP_CANNOT_FIND_IDENTITY || stored_ident->comm_type == PEP_ct_unknown) {
489 // This is OK - there is no trust DB entry, but we
490 // found a key. We won't store this, but we'll
492 PEP_comm_type ct = PEP_ct_unknown;
493 status = get_key_rating(session, stored_ident->fpr, &ct);
494 stored_ident->comm_type = ct;
497 else if (status != PEP_STATUS_OK) {
498 free(stored_ident->fpr);
499 stored_ident->fpr = NULL;
500 stored_ident->comm_type = PEP_ct_key_not_found;
502 else { // no key returned, but status ok?
503 if (stored_ident->comm_type == PEP_ct_unknown)
504 stored_ident->comm_type = PEP_ct_key_not_found;
506 free(return_id->fpr);
507 return_id->fpr = NULL;
508 if (status == PEP_STATUS_OK && !EMPTYSTR(stored_ident->fpr))
509 return_id->fpr = strdup(stored_ident->fpr);
511 return_id->comm_type = stored_ident->comm_type;
513 // We patch the DB with the input username, but if we didn't have
514 // one, we pull it out of storage if available.
515 if (!EMPTYSTR(stored_ident->username)) {
516 if (!EMPTYSTR(return_id->username) &&
517 (strcasecmp(return_id->username, return_id->address) == 0)) {
518 free(return_id->username);
519 return_id->username = NULL;
521 if (EMPTYSTR(return_id->username)) {
522 free(return_id->username);
523 return_id->username = strdup(stored_ident->username);
527 if (EMPTYSTR(return_id->username))
528 return_id->username = strdup(return_id->address);
531 return_id->me = stored_ident->me;
533 return_id->major_ver = stored_ident->major_ver;
534 return_id->minor_ver = stored_ident->minor_ver;
536 // FIXME: Do we ALWAYS do this? We probably should...
537 if (EMPTYSTR(return_id->user_id)) {
538 free(return_id->user_id);
539 return_id->user_id = strdup(stored_ident->user_id);
542 adjust_pEp_trust_status(session, return_id);
544 // Call set_identity() to store
545 if ((is_identity_default || is_user_default) &&
546 is_address_default) {
547 // if we got an fpr which is default for either user
548 // or identity AND is valid for this address, set in DB
550 status = set_identity(session, return_id);
552 else if (no_stored_default && !EMPTYSTR(return_id->fpr)
553 && return_id->comm_type != PEP_ct_key_revoked
554 && return_id->comm_type != PEP_ct_key_expired
555 && return_id->comm_type != PEP_ct_key_expired_but_confirmed
556 && return_id->comm_type != PEP_ct_mistrusted
557 && return_id->comm_type != PEP_ct_key_b0rken) {
558 // We would have stored this anyway for a first-time elected key. We just have an ident w/ no default already.
559 status = set_identity(session, return_id);
561 else { // this is a key other than the default, but there IS a default (FIXME: fdik, do we really want behaviour below?)
562 // Store without default fpr/ct, but return the fpr and ct
564 char* save_fpr = return_id->fpr;
565 PEP_comm_type save_ct = return_id->comm_type;
566 return_id->fpr = NULL;
567 return_id->comm_type = PEP_ct_unknown;
568 PEP_STATUS save_status = status;
569 status = set_identity(session, return_id);
570 if (save_status != PEP_STATUS_OK)
571 status = save_status;
572 return_id->fpr = save_fpr;
573 return_id->comm_type = save_ct;
576 transfer_ident_lang_and_flags(return_id, stored_ident);
578 if (return_id->comm_type == PEP_ct_unknown)
579 return_id->comm_type = PEP_ct_key_not_found;
584 DYNAMIC_API PEP_STATUS update_identity(
585 PEP_SESSION session, pEp_identity * identity
592 assert(!EMPTYSTR(identity->address));
594 if (!(session && identity && !EMPTYSTR(identity->address)))
595 return PEP_ILLEGAL_VALUE;
597 char* default_own_id = NULL;
598 status = get_default_own_userid(session, &default_own_id);
600 bool is_own_user = identity->me;
602 // Is this me, temporary or not? If so, BAIL.
604 if (default_own_id) {
605 if (!EMPTYSTR(identity->user_id)) {
606 if (strcmp(default_own_id, identity->user_id) == 0) {
611 if (get_userid_alias_default(session, identity->user_id, &alias) == PEP_STATUS_OK) {
612 if (alias && strcmp(default_own_id, alias) == 0)
619 // Check if own address. For now, this is a special case;
620 // we try to require apps to send in user_ids, but must prevent
621 // writes to an own identity from within THIS function
622 // NOTE: These semantics MAY CHANGE.
623 bool _own_addr = false;
624 is_own_address(session, identity->address, &_own_addr);
626 // N.B. KB: I would prefer consistent semantics here - that is to say,
627 // we also set is_own_user here and force PEP_ILLEGAL_VALUE
629 free(identity->user_id);
630 identity->user_id = strdup(default_own_id);
631 return _myself(session, identity, false, false, true);
635 // Otherwise, we don't even HAVE an own user yet, so we're ok.
639 free(default_own_id);
640 return PEP_ILLEGAL_VALUE;
643 // We have, at least, an address.
644 // Retrieve stored identity information!
645 pEp_identity* stored_ident = NULL;
647 if (!EMPTYSTR(identity->user_id)) {
648 // (we're gonna update the trust/fpr anyway, so we use the no-fpr-from-trust-db variant)
649 // * do get_identity() to retrieve stored identity information
650 status = get_identity_without_trust_check(session, identity->address, identity->user_id, &stored_ident);
652 // Before we start - if there was no stored identity, we should check to make sure we don't
653 // have a stored identity with a temporary user_id that differs from the input user_id. This
654 // happens in multithreaded environments sometimes.
656 identity_list* id_list = NULL;
657 status = get_identities_by_address(session, identity->address, &id_list);
660 identity_list* id_curr = id_list;
661 bool input_is_TOFU = (strstr(identity->user_id, "TOFU_") == identity->user_id);
663 pEp_identity* this_id = id_curr->ident;
665 char* this_uid = this_id->user_id;
666 bool curr_is_TOFU = false;
667 // this_uid should never be NULL, as this is half of the ident
669 assert(!EMPTYSTR(this_uid));
671 curr_is_TOFU = (strstr(this_uid, "TOFU_") == this_uid);
672 if (curr_is_TOFU && !input_is_TOFU) {
673 // FIXME: should we also be fixing pEp_own_userId in this
676 // if usernames match, we replace the userid.
677 // FIXME: do we need to create an address match function which
678 // matches the whole dot-and-case rigamarole from
679 if (EMPTYSTR(this_id->username) ||
680 strcasecmp(this_id->username, this_id->address) == 0 ||
681 (identity->username &&
682 strcasecmp(identity->username,
683 this_id->username) == 0)) {
685 // Ok, we have a temp ID. We have to replace this
687 status = replace_userid(session,
690 if (status != PEP_STATUS_OK) {
691 free_identity_list(id_list);
692 free(default_own_id);
699 // Reflect the change we just made to the DB
700 this_id->user_id = strdup(identity->user_id);
701 stored_ident = this_id;
706 else if (input_is_TOFU && !curr_is_TOFU) {
707 // Replace ruthlessly - this is NOT supposed to happen.
708 // BAD APP BEHAVIOUR.
709 free(identity->user_id);
710 identity->user_id = strdup(this_id->user_id);
711 stored_ident = this_id;
716 id_curr = id_curr->next;
721 if (status == PEP_STATUS_OK && stored_ident) {
722 // * if identity available
723 // * patch it with username
724 // (note: this will happen when
725 // setting automatically below...)
726 // * elect valid key for identity
727 // * if valid key exists
728 // * set return value's fpr
729 status = prepare_updated_identity(session,
733 // * else (identity unavailable)
735 status = PEP_STATUS_OK;
737 // FIXME: We may need to roll this back.
738 // FIXME: change docs if we don't
739 // if we only have user_id and address and identity not available
740 // * return error status (identity not found)
741 if (EMPTYSTR(identity->username)) {
742 free(identity->username);
743 identity->username = strdup(identity->address);
746 // Otherwise, if we had user_id, address, and username:
747 // * create identity with user_id, address, username
748 // (this is the input id without the fpr + comm type!)
750 elect_pubkey(session, identity, false);
752 // * We've already checked and retrieved
753 // any applicable temporary identities above. If we're
754 // here, none of them fit.
755 // * call set_identity() to store
756 // FIXME: Do we set if we had to copy in the address?
757 adjust_pEp_trust_status(session, identity);
758 status = set_identity(session, identity);
759 // * Return: created identity
762 else if (!EMPTYSTR(identity->username)) {
764 * Temporary identity information with username supplied
765 * Input: address, username (no others)
768 // * See if there is an own identity that uses this address. If so, we'll
772 if (default_own_id) {
773 status = get_identity(session,
778 // If there isn't an own identity, search for a non-temp stored ident
779 // with this address.
780 if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) {
782 identity_list* id_list = NULL;
783 status = get_identities_by_address(session, identity->address, &id_list);
786 identity_list* id_curr = id_list;
788 pEp_identity* this_id = id_curr->ident;
790 char* this_uid = this_id->user_id;
791 assert(!EMPTYSTR(this_uid));
792 // Should never be NULL - DB primary key
794 if (strstr(this_uid, "TOFU_") != this_uid) {
795 // if usernames match, we replace the userid.
796 if (identity->username &&
797 strcasecmp(identity->username,
798 this_id->username) == 0) {
800 // Ok, we have a real ID. Copy it!
801 identity->user_id = strdup(this_uid);
802 assert(identity->user_id);
803 if (!identity->user_id)
806 stored_ident = this_id;
812 id_curr = id_curr->next;
818 status = prepare_updated_identity(session,
823 identity->user_id = calloc(1, strlen(identity->address) + 6);
824 if (!identity->user_id)
827 snprintf(identity->user_id, strlen(identity->address) + 6,
828 "TOFU_%s", identity->address);
830 status = get_identity(session,
835 if (status == PEP_STATUS_OK && stored_ident) {
836 status = prepare_updated_identity(session,
842 // * We've already checked and retrieved
843 // any applicable temporary identities above. If we're
844 // here, none of them fit.
846 status = elect_pubkey(session, identity, false);
848 // * call set_identity() to store
850 // it is still possible we have DB information on this key. Better check.
851 status = get_trust(session, identity);
852 PEP_comm_type db_ct = identity->comm_type;
853 status = get_key_rating(session, identity->fpr, &identity->comm_type);
854 PEP_comm_type key_ct = identity->comm_type;
856 if (status == PEP_STATUS_OK) {
858 case PEP_ct_key_expired:
859 if (db_ct == PEP_ct_key_expired_but_confirmed)
860 identity->comm_type = db_ct;
864 case PEP_ct_key_expired_but_confirmed:
865 if (key_ct >= PEP_ct_strong_but_unconfirmed)
866 identity->comm_type |= PEP_ct_confirmed;
868 case PEP_ct_mistrusted:
869 case PEP_ct_compromised:
870 case PEP_ct_key_b0rken:
871 identity->comm_type = db_ct;
879 // * call set_identity() to store
880 adjust_pEp_trust_status(session, identity);
881 status = set_identity(session, identity);
887 * Input: address (no others)
888 * Temporary identity information without username suplied
891 // * Again, see if there is an own identity that uses this address. If so, we'll
895 if (default_own_id) {
896 status = get_identity(session,
901 // If there isn't an own identity, search for a non-temp stored ident
902 // with this address.
903 if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) {
905 identity_list* id_list = NULL;
906 // * Search for identity with this address
907 status = get_identities_by_address(session, identity->address, &id_list);
909 // Results are ordered by timestamp descending, so this covers
910 // both the one-result and multi-result cases
912 if (stored_ident) // unlikely
913 free_identity(stored_ident);
914 stored_ident = id_list->ident;
918 status = prepare_updated_identity(session, identity,
919 stored_ident, false);
921 // too little info. BUT. We see if we can find a key; if so, we create a
922 // temp identity, look for a key, and store.
924 // create temporary identity, store it, and Return this
925 // This means TOFU_ user_id
926 identity->user_id = calloc(1, strlen(identity->address) + 6);
927 if (!identity->user_id)
930 snprintf(identity->user_id, strlen(identity->address) + 6,
931 "TOFU_%s", identity->address);
933 identity->username = strdup(identity->address);
934 if (!identity->address)
938 identity->fpr = NULL;
939 identity->comm_type = PEP_ct_unknown;
941 status = elect_pubkey(session, identity, false);
944 status = get_key_rating(session, identity->fpr, &identity->comm_type);
946 // * call set_identity() to store
947 adjust_pEp_trust_status(session, identity);
948 status = set_identity(session, identity);
953 // FIXME: This is legacy. I presume it's a notification for the caller...
954 // Revisit once I can talk to Volker
955 if (identity->comm_type != PEP_ct_compromised &&
956 identity->comm_type < PEP_ct_strong_but_unconfirmed)
957 if (session->examine_identity)
958 session->examine_identity(identity, session->examine_management);
963 status = PEP_OUT_OF_MEMORY;
966 free(default_own_id);
967 free_identity(stored_ident);
971 PEP_STATUS elect_ownkey(
972 PEP_SESSION session, pEp_identity * identity
976 stringlist_t *keylist = NULL;
979 identity->fpr = NULL;
981 status = find_private_keys(session, identity->address, &keylist);
982 assert(status != PEP_OUT_OF_MEMORY);
983 if (status == PEP_OUT_OF_MEMORY)
984 return PEP_OUT_OF_MEMORY;
986 if (keylist != NULL && keylist->value != NULL)
989 identity->comm_type = PEP_ct_unknown;
991 stringlist_t *_keylist;
992 for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
995 status = own_key_is_listed(session, _keylist->value, &is_own);
996 assert(status == PEP_STATUS_OK);
997 if (status != PEP_STATUS_OK) {
998 free_stringlist(keylist);
1004 PEP_comm_type _comm_type_key;
1006 status = get_key_rating(session, _keylist->value, &_comm_type_key);
1007 assert(status != PEP_OUT_OF_MEMORY);
1008 if (status == PEP_OUT_OF_MEMORY) {
1009 free_stringlist(keylist);
1010 return PEP_OUT_OF_MEMORY;
1013 if (_comm_type_key != PEP_ct_compromised &&
1014 _comm_type_key != PEP_ct_unknown)
1016 if (identity->comm_type == PEP_ct_unknown ||
1017 _comm_type_key > identity->comm_type)
1019 identity->comm_type = _comm_type_key;
1020 _fpr = _keylist->value;
1028 identity->fpr = strdup(_fpr);
1029 assert(identity->fpr);
1030 if (identity->fpr == NULL)
1032 free_stringlist(keylist);
1033 return PEP_OUT_OF_MEMORY;
1036 free_stringlist(keylist);
1038 return PEP_STATUS_OK;
1041 PEP_STATUS _has_usable_priv_key(PEP_SESSION session, char* fpr,
1044 bool has_private = false;
1045 PEP_STATUS status = contains_priv_key(session, fpr, &has_private);
1047 *is_usable = has_private;
1052 PEP_STATUS _myself(PEP_SESSION session,
1053 pEp_identity * identity,
1063 assert(!EMPTYSTR(identity->address));
1065 if (!session || EMPTYSTR(identity->address))
1066 return PEP_ILLEGAL_VALUE;
1068 // this is leading to crashes otherwise
1070 if (!(identity->user_id && identity->user_id[0])) {
1071 free(identity->user_id);
1072 identity->user_id = strdup(PEP_OWN_USERID);
1073 assert(identity->user_id);
1074 if (!identity->user_id)
1075 return PEP_OUT_OF_MEMORY;
1078 pEp_identity *stored_identity = NULL;
1079 char* revoked_fpr = NULL;
1080 bool valid_key_found = false;
1082 char* default_own_id = NULL;
1083 status = get_default_own_userid(session, &default_own_id);
1085 // Deal with non-default user_ids.
1086 // FIXME: if non-default and read-only, reject totally?
1087 if (default_own_id && strcmp(default_own_id, identity->user_id) != 0) {
1089 free(identity->user_id);
1090 identity->user_id = strdup(default_own_id);
1091 assert(identity->user_id);
1092 if (!identity->user_id)
1093 return PEP_OUT_OF_MEMORY;
1096 status = set_userid_alias(session, default_own_id, identity->user_id);
1097 // Do we want this to be fatal? For now, we'll do it...
1098 if (status != PEP_STATUS_OK)
1101 free(identity->user_id);
1102 identity->user_id = strdup(default_own_id);
1103 assert(identity->user_id);
1104 if (identity->user_id == NULL) {
1105 status = PEP_OUT_OF_MEMORY;
1111 // NOTE: IF WE DON'T YET HAVE AN OWN_ID, WE IGNORE REFERENCES TO THIS ADDRESS IN THE
1112 // DB (WHICH MAY HAVE BEEN SET BEFORE MYSELF WAS CALLED BY RECEIVING AN EMAIL FROM
1113 // THIS ADDRESS), AS IT IS NOT AN OWN_IDENTITY AND HAS NO INFORMATION WE NEED OR WHAT TO
1116 // Ok, so now, set up the own_identity:
1117 identity->comm_type = PEP_ct_pEp;
1118 identity->me = true;
1120 identity->flags = 0;
1122 // Let's see if we have an identity record in the DB for
1123 // this user_id + address
1124 // DEBUG_LOG("myself", "debug", identity->address);
1126 // This will grab the actual flags from the db
1127 status = get_identity(session,
1132 assert(status != PEP_OUT_OF_MEMORY);
1133 if (status == PEP_OUT_OF_MEMORY) {
1134 status = PEP_OUT_OF_MEMORY;
1138 // Set usernames - priority is input username > stored name > address
1139 // If there's an input username, we always patch the username with that
1141 if (EMPTYSTR(identity->username) || read_only) {
1142 bool stored_uname = (stored_identity && !EMPTYSTR(stored_identity->username));
1143 char* uname = (stored_uname ? stored_identity->username : identity->address);
1145 free(identity->username);
1146 identity->username = strdup(uname);
1147 assert(identity->username);
1148 if (identity->username == NULL) {
1149 status = PEP_OUT_OF_MEMORY;
1157 if (identity->fpr) {
1158 free(identity->fpr);
1159 identity->fpr = NULL;
1162 // check stored identity
1163 if (stored_identity) {
1164 if (!EMPTYSTR(stored_identity->fpr)) {
1165 // Fall back / retrieve
1166 status = validate_fpr(session, stored_identity, false, true);
1167 if (status == PEP_OUT_OF_MEMORY)
1169 if (status == PEP_STATUS_OK) {
1170 if (stored_identity->comm_type >= PEP_ct_strong_but_unconfirmed) {
1171 identity->fpr = strdup(stored_identity->fpr);
1172 assert(identity->fpr);
1173 if (!identity->fpr) {
1174 status = PEP_OUT_OF_MEMORY;
1177 valid_key_found = true;
1180 bool revoked = false;
1181 status = key_revoked(session, stored_identity->fpr, &revoked);
1185 revoked_fpr = strdup(stored_identity->fpr);
1186 assert(revoked_fpr);
1188 status = PEP_OUT_OF_MEMORY;
1195 // reconcile language, flags
1196 transfer_ident_lang_and_flags(identity, stored_identity);
1199 // Nothing left to do but generate a key
1200 if (!valid_key_found) {
1201 if (!do_keygen || read_only)
1202 status = PEP_GET_KEY_FAILED;
1204 // / DEBUG_LOG("Generating key pair", "debug", identity->address);
1206 free(identity->fpr);
1207 identity->fpr = NULL;
1208 status = generate_keypair(session, identity);
1209 assert(status != PEP_OUT_OF_MEMORY);
1211 if (status != PEP_STATUS_OK) {
1213 snprintf(buf, 11, "%d", status); // uh, this is kludgey. FIXME
1214 // DEBUG_LOG("Generating key pair failed", "debug", buf);
1217 valid_key_found = true;
1219 status = set_revoked(session, revoked_fpr,
1220 stored_identity->fpr, time(NULL));
1221 assert(status == PEP_STATUS_OK);
1227 if (valid_key_found) {
1228 identity->comm_type = PEP_ct_pEp;
1229 status = PEP_STATUS_OK;
1232 free(identity->fpr);
1233 identity->fpr = NULL;
1234 identity->comm_type = PEP_ct_unknown;
1237 unsigned int major_ver = 0;
1238 unsigned int minor_ver = 0;
1239 pEp_version_major_minor(PEP_VERSION, &major_ver, &minor_ver);
1240 identity->major_ver = major_ver;
1241 identity->minor_ver = minor_ver;
1243 // We want to set an identity in the DB even if a key isn't found, but we have to preserve the status if
1246 PEP_STATUS set_id_status = set_identity(session, identity);
1247 if (set_id_status == PEP_STATUS_OK)
1248 set_id_status = set_as_pEp_user(session, identity);
1250 status = (status == PEP_STATUS_OK ? set_id_status : status);
1254 free(default_own_id);
1256 free_identity(stored_identity);
1260 DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
1262 return _myself(session, identity, true, false, false);
1265 DYNAMIC_API PEP_STATUS register_examine_function(
1266 PEP_SESSION session,
1267 examine_identity_t examine_identity,
1273 return PEP_ILLEGAL_VALUE;
1275 session->examine_management = management;
1276 session->examine_identity = examine_identity;
1278 return PEP_STATUS_OK;
1281 DYNAMIC_API PEP_STATUS do_keymanagement(
1282 retrieve_next_identity_t retrieve_next_identity,
1286 PEP_SESSION session;
1287 pEp_identity *identity;
1288 PEP_STATUS status = init(&session, NULL, NULL);
1293 assert(session && retrieve_next_identity);
1294 if (!(session && retrieve_next_identity))
1295 return PEP_ILLEGAL_VALUE;
1297 log_event(session, "keymanagement thread started", "pEp engine", NULL, NULL);
1299 while ((identity = retrieve_next_identity(management)))
1301 assert(identity->address);
1302 if(identity->address)
1304 DEBUG_LOG("do_keymanagement", "retrieve_next_identity", identity->address);
1307 status = myself(session, identity);
1309 status = recv_key(session, identity->address);
1312 assert(status != PEP_OUT_OF_MEMORY);
1313 if(status == PEP_OUT_OF_MEMORY)
1314 return PEP_OUT_OF_MEMORY;
1316 free_identity(identity);
1319 log_event(session, "keymanagement thread shutdown", "pEp engine", NULL, NULL);
1321 return PEP_STATUS_OK;
1324 DYNAMIC_API PEP_STATUS key_mistrusted(
1325 PEP_SESSION session,
1329 PEP_STATUS status = PEP_STATUS_OK;
1333 assert(!EMPTYSTR(ident->fpr));
1335 if (!(session && ident && ident->fpr))
1336 return PEP_ILLEGAL_VALUE;
1338 bool has_private = false;
1340 status = contains_priv_key(session, ident->fpr, &has_private);
1342 if (status != PEP_STATUS_OK && status != PEP_KEY_NOT_FOUND)
1345 // See if key is revoked already
1347 bool revoked = false;
1348 status = key_revoked(session, ident->fpr, &revoked);
1351 revoke_key(session, ident->fpr, NULL);
1355 // Make sure there was a default in the DB for this identity;
1356 // if not, set one, even though we're going to mistrust this. Otherwise,
1358 pEp_identity* stored_ident = NULL;
1359 get_identity(session, ident->address, ident->user_id, &stored_ident);
1360 bool set_in_db = true;
1362 stored_ident = identity_dup(ident);
1363 else if (!stored_ident->fpr)
1364 stored_ident->fpr = strdup(ident->fpr);
1369 status = set_identity(session, stored_ident);
1371 free_identity(stored_ident);
1372 if (status != PEP_STATUS_OK)
1377 // double-check to be sure key is even in the DB
1379 status = set_pgp_keypair(session, ident->fpr);
1381 // We set this temporarily but will grab it back from the cache afterwards
1382 ident->comm_type = PEP_ct_mistrusted;
1383 status = set_trust(session, ident);
1385 if (status == PEP_STATUS_OK)
1386 // cascade that mistrust for anyone using this key
1387 status = mark_as_compromised(session, ident->fpr);
1388 if (status == PEP_STATUS_OK)
1389 status = add_mistrusted_key(session, ident->fpr);
1394 DYNAMIC_API PEP_STATUS key_reset_trust(
1395 PEP_SESSION session,
1399 PEP_STATUS status = PEP_STATUS_OK;
1403 assert(!EMPTYSTR(ident->fpr));
1404 assert(!EMPTYSTR(ident->address));
1405 assert(!EMPTYSTR(ident->user_id));
1407 if (!(session && ident && ident->fpr && ident->fpr[0] != '\0' && ident->address &&
1409 return PEP_ILLEGAL_VALUE;
1411 // we do not change the input struct at ALL.
1412 pEp_identity* input_copy = identity_dup(ident);
1414 pEp_identity* tmp_ident = NULL;
1416 status = get_trust(session, input_copy);
1418 if (status != PEP_STATUS_OK)
1421 PEP_comm_type new_trust = PEP_ct_unknown;
1422 status = get_key_rating(session, ident->fpr, &new_trust);
1423 if (status != PEP_STATUS_OK)
1426 bool pEp_user = false;
1428 status = is_pEp_user(session, ident, &pEp_user);
1430 if (pEp_user && new_trust >= PEP_ct_unconfirmed_encryption)
1431 input_copy->comm_type = PEP_ct_pEp_unconfirmed;
1433 input_copy->comm_type = new_trust;
1435 status = set_trust(session, input_copy);
1437 if (status != PEP_STATUS_OK)
1440 bool mistrusted_key = false;
1442 status = is_mistrusted_key(session, ident->fpr, &mistrusted_key);
1444 if (status != PEP_STATUS_OK)
1448 status = delete_mistrusted_key(session, ident->fpr);
1450 if (status != PEP_STATUS_OK)
1453 tmp_ident = new_identity(ident->address, NULL, ident->user_id, NULL);
1456 return PEP_OUT_OF_MEMORY;
1458 if (is_me(session, tmp_ident))
1459 status = myself(session, tmp_ident);
1461 status = update_identity(session, tmp_ident);
1463 if (status != PEP_STATUS_OK)
1466 // remove as default if necessary
1467 if (!EMPTYSTR(tmp_ident->fpr) && strcmp(tmp_ident->fpr, ident->fpr) == 0) {
1468 free(tmp_ident->fpr);
1469 tmp_ident->fpr = NULL;
1470 tmp_ident->comm_type = PEP_ct_unknown;
1471 status = set_identity(session, tmp_ident);
1472 if (status != PEP_STATUS_OK)
1476 char* user_default = NULL;
1477 get_main_user_fpr(session, tmp_ident->user_id, &user_default);
1479 if (!EMPTYSTR(user_default)) {
1480 if (strcmp(user_default, ident->fpr) == 0)
1481 status = refresh_userid_default_key(session, ident->user_id);
1482 if (status != PEP_STATUS_OK)
1487 free_identity(tmp_ident);
1488 free_identity(input_copy);
1492 DYNAMIC_API PEP_STATUS trust_personal_key(
1493 PEP_SESSION session,
1497 PEP_STATUS status = PEP_STATUS_OK;
1501 assert(!EMPTYSTR(ident->address));
1502 assert(!EMPTYSTR(ident->user_id));
1503 assert(!EMPTYSTR(ident->fpr));
1505 if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
1506 EMPTYSTR(ident->fpr))
1507 return PEP_ILLEGAL_VALUE;
1509 if (is_me(session, ident))
1510 return PEP_ILLEGAL_VALUE;
1512 char* ident_default_fpr = NULL;
1514 // Before we do anything, be sure the input fpr is even eligible to be trusted
1515 PEP_comm_type input_default_ct = PEP_ct_unknown;
1516 status = get_key_rating(session, ident->fpr, &input_default_ct);
1517 if (input_default_ct < PEP_ct_strong_but_unconfirmed)
1518 return PEP_KEY_UNSUITABLE;
1520 status = set_pgp_keypair(session, ident->fpr);
1521 if (status != PEP_STATUS_OK)
1524 pEp_identity* ident_copy = identity_dup(ident);
1525 char* cached_fpr = NULL;
1527 // for setting up a temp trusted identity for the input fpr
1528 pEp_identity* tmp_id = NULL;
1530 // For later, in case we need to check the user default key
1531 pEp_identity* tmp_user_ident = NULL;
1533 // Save the input fpr, which we already tested as non-NULL
1534 cached_fpr = strdup(ident->fpr);
1536 // Set up a temp trusted identity for the input fpr without a comm type;
1537 tmp_id = new_identity(ident->address, ident->fpr, ident->user_id, NULL);
1539 status = validate_fpr(session, tmp_id, false, true);
1541 if (status == PEP_STATUS_OK) {
1542 // Validate fpr gets trust DB or, when that fails, key comm type. we checked
1543 // above that the key was ok. (not revoked or expired), but we want the max.
1544 tmp_id->comm_type = _MAX(tmp_id->comm_type, input_default_ct) | PEP_ct_confirmed;
1546 // Get the default identity without setting the fpr
1547 status = update_identity(session, ident_copy);
1549 ident_default_fpr = (EMPTYSTR(ident_copy->fpr) ? NULL : strdup(ident_copy->fpr));
1551 if (status == PEP_STATUS_OK) {
1552 bool trusted_default = false;
1554 // If there's no default, or the default is different from the input...
1555 if (EMPTYSTR(ident_default_fpr) || strcmp(cached_fpr, ident_default_fpr) != 0) {
1557 // If the default fpr (if there is one) is trusted and key is strong enough,
1558 // don't replace, we just set the trusted bit on this key for this user_id...
1559 // (If there's no default fpr, this won't be true anyway.)
1560 if ((ident_copy->comm_type >= PEP_ct_strong_but_unconfirmed &&
1561 (ident_copy->comm_type & PEP_ct_confirmed))) {
1563 trusted_default = true;
1565 status = set_trust(session, tmp_id);
1566 input_default_ct = tmp_id->comm_type;
1569 free(ident_copy->fpr);
1570 ident_copy->fpr = strdup(cached_fpr);
1571 ident_copy->comm_type = tmp_id->comm_type;
1572 status = set_identity(session, ident_copy); // replace identity default
1573 if (status == PEP_STATUS_OK) {
1574 if ((ident_copy->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
1575 status = set_as_pEp_user(session, ident_copy);
1579 else { // we're setting this on the default fpr
1580 ident->comm_type = tmp_id->comm_type;
1581 status = set_identity(session, ident);
1582 trusted_default = true;
1584 if (status == PEP_STATUS_OK && !trusted_default) {
1585 // Ok, there wasn't a trusted default, so we replaced. Thus, we also
1586 // make sure there's a trusted default on the user_id. If there
1587 // is not, we make this the default.
1588 char* user_default = NULL;
1589 status = get_main_user_fpr(session, ident->user_id, &user_default);
1591 if (status == PEP_STATUS_OK && user_default) {
1592 tmp_user_ident = new_identity(ident->address,
1596 if (!tmp_user_ident)
1597 status = PEP_OUT_OF_MEMORY;
1599 status = validate_fpr(session, tmp_user_ident, false, true);
1601 if (status != PEP_STATUS_OK ||
1602 tmp_user_ident->comm_type < PEP_ct_strong_but_unconfirmed ||
1603 !(tmp_user_ident->comm_type & PEP_ct_confirmed))
1605 char* trusted_fpr = (trusted_default ? ident_default_fpr : cached_fpr);
1606 status = replace_main_user_fpr(session, ident->user_id, trusted_fpr);
1614 free(ident_default_fpr);
1616 free_identity(tmp_id);
1617 free_identity(ident_copy);
1618 free_identity(tmp_user_ident);
1622 DYNAMIC_API PEP_STATUS trust_own_key(
1623 PEP_SESSION session,
1629 assert(!EMPTYSTR(ident->address));
1630 assert(!EMPTYSTR(ident->user_id));
1631 assert(!EMPTYSTR(ident->fpr));
1633 if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
1634 EMPTYSTR(ident->fpr))
1635 return PEP_ILLEGAL_VALUE;
1637 if (!is_me(session, ident))
1638 return PEP_ILLEGAL_VALUE;
1640 // don't check blacklist or require a private key
1641 PEP_STATUS status = validate_fpr(session, ident, false, false);
1643 if (status != PEP_STATUS_OK)
1646 status = set_pgp_keypair(session, ident->fpr);
1647 if (status != PEP_STATUS_OK)
1650 if (ident->comm_type < PEP_ct_strong_but_unconfirmed)
1651 return PEP_KEY_UNSUITABLE;
1653 ident->comm_type |= PEP_ct_confirmed;
1655 status = set_trust(session, ident);
1661 DYNAMIC_API PEP_STATUS own_key_is_listed(
1662 PEP_SESSION session,
1667 PEP_STATUS status = PEP_STATUS_OK;
1670 assert(session && fpr && fpr[0] && listed);
1672 if (!(session && fpr && fpr[0] && listed))
1673 return PEP_ILLEGAL_VALUE;
1677 sqlite3_reset(session->own_key_is_listed);
1678 sqlite3_bind_text(session->own_key_is_listed, 1, fpr, -1, SQLITE_STATIC);
1682 result = sqlite3_step(session->own_key_is_listed);
1685 count = sqlite3_column_int(session->own_key_is_listed, 0);
1686 *listed = count > 0;
1687 status = PEP_STATUS_OK;
1691 status = PEP_UNKNOWN_ERROR;
1694 sqlite3_reset(session->own_key_is_listed);
1698 PEP_STATUS _own_identities_retrieve(
1699 PEP_SESSION session,
1700 identity_list **own_identities,
1701 identity_flags_t excluded_flags
1704 PEP_STATUS status = PEP_STATUS_OK;
1706 assert(session && own_identities);
1707 if (!(session && own_identities))
1708 return PEP_ILLEGAL_VALUE;
1710 *own_identities = NULL;
1711 identity_list *_own_identities = new_identity_list(NULL);
1712 if (_own_identities == NULL)
1715 sqlite3_reset(session->own_identities_retrieve);
1718 // address, fpr, username, user_id, comm_type, lang, flags
1719 const char *address = NULL;
1720 const char *fpr = NULL;
1721 const char *username = NULL;
1722 const char *user_id = NULL;
1723 PEP_comm_type comm_type = PEP_ct_unknown;
1724 const char *lang = NULL;
1725 unsigned int flags = 0;
1727 identity_list *_bl = _own_identities;
1729 sqlite3_bind_int(session->own_identities_retrieve, 1, excluded_flags);
1732 result = sqlite3_step(session->own_identities_retrieve);
1735 address = (const char *)
1736 sqlite3_column_text(session->own_identities_retrieve, 0);
1737 fpr = (const char *)
1738 sqlite3_column_text(session->own_identities_retrieve, 1);
1739 user_id = (const char *)
1740 sqlite3_column_text(session->own_identities_retrieve, 2);
1741 username = (const char *)
1742 sqlite3_column_text(session->own_identities_retrieve, 3);
1743 comm_type = PEP_ct_pEp;
1744 lang = (const char *)
1745 sqlite3_column_text(session->own_identities_retrieve, 4);
1746 flags = (unsigned int)
1747 sqlite3_column_int(session->own_identities_retrieve, 5);
1749 pEp_identity *ident = new_identity(address, fpr, user_id, username);
1752 ident->comm_type = comm_type;
1753 if (lang && lang[0]) {
1754 ident->lang[0] = lang[0];
1755 ident->lang[1] = lang[1];
1759 ident->flags = flags;
1761 _bl = identity_list_add(_bl, ident);
1763 free_identity(ident);
1773 status = PEP_UNKNOWN_ERROR;
1774 result = SQLITE_DONE;
1776 } while (result != SQLITE_DONE);
1778 sqlite3_reset(session->own_identities_retrieve);
1779 if (status == PEP_STATUS_OK)
1780 *own_identities = _own_identities;
1782 free_identity_list(_own_identities);
1787 free_identity_list(_own_identities);
1788 status = PEP_OUT_OF_MEMORY;
1794 DYNAMIC_API PEP_STATUS own_identities_retrieve(
1795 PEP_SESSION session,
1796 identity_list **own_identities
1799 return _own_identities_retrieve(session, own_identities, 0);
1802 PEP_STATUS _own_keys_retrieve(
1803 PEP_SESSION session,
1804 stringlist_t **keylist,
1805 identity_flags_t excluded_flags,
1809 PEP_STATUS status = PEP_STATUS_OK;
1811 assert(session && keylist);
1812 if (!(session && keylist))
1813 return PEP_ILLEGAL_VALUE;
1816 stringlist_t *_keylist = NULL;
1818 sqlite3_reset(session->own_keys_retrieve);
1822 stringlist_t *_bl = _keylist;
1823 sqlite3_bind_int(session->own_keys_retrieve, 1, excluded_flags);
1826 result = sqlite3_step(session->own_keys_retrieve);
1829 _bl = stringlist_add(_bl, (const char *)
1830 sqlite3_column_text(session->own_keys_retrieve, 0));
1833 if (_keylist == NULL)
1841 status = PEP_UNKNOWN_ERROR;
1842 result = SQLITE_DONE;
1844 } while (result != SQLITE_DONE);
1846 sqlite3_reset(session->own_keys_retrieve);
1847 if (status == PEP_STATUS_OK) {
1848 dedup_stringlist(_keylist);
1850 stringlist_t* _kl = _keylist;
1851 stringlist_t* _kl_prev = NULL;
1853 bool has_private = false;
1854 contains_priv_key(session, _kl->value, &has_private);
1856 stringlist_t* _kl_tmp = _kl;
1858 _kl_prev->next = _kl->next;
1860 _keylist = _kl->next;
1864 _kl_tmp->next = NULL;
1865 free_stringlist(_kl_tmp);
1872 *keylist = _keylist;
1875 free_stringlist(_keylist);
1880 free_stringlist(_keylist);
1881 status = PEP_OUT_OF_MEMORY;
1887 DYNAMIC_API PEP_STATUS own_keys_retrieve(PEP_SESSION session, stringlist_t **keylist)
1889 return _own_keys_retrieve(session, keylist, 0, true);
1892 DYNAMIC_API PEP_STATUS set_own_key(
1893 PEP_SESSION session,
1898 PEP_STATUS status = PEP_STATUS_OK;
1900 assert(session && me);
1901 assert(!EMPTYSTR(fpr));
1902 assert(!EMPTYSTR(me->address));
1903 assert(!EMPTYSTR(me->user_id));
1904 assert(!EMPTYSTR(me->username));
1906 if (!session || !me || EMPTYSTR(fpr) || EMPTYSTR(me->address) ||
1907 EMPTYSTR(me->user_id) || EMPTYSTR(me->username))
1908 return PEP_ILLEGAL_VALUE;
1913 status = _myself(session, me, false, true, false);
1914 // we do not need a valid key but dislike other errors
1915 if (status != PEP_STATUS_OK && status != PEP_GET_KEY_FAILED && status != PEP_KEY_UNSUITABLE)
1917 status = PEP_STATUS_OK;
1919 bool private = false;
1920 status = contains_priv_key(session, fpr, &private);
1922 if (status != PEP_STATUS_OK)
1926 return PEP_KEY_UNSUITABLE;
1930 me->fpr = strdup(fpr);
1933 return PEP_OUT_OF_MEMORY;
1935 status = validate_fpr(session, me, false, true);
1939 me->comm_type = PEP_ct_pEp;
1940 status = set_identity(session, me);
1944 PEP_STATUS contains_priv_key(PEP_SESSION session, const char *fpr,
1945 bool *has_private) {
1949 assert(has_private);
1951 if (!(session && fpr && has_private))
1952 return PEP_ILLEGAL_VALUE;
1954 return session->cryptotech[PEP_crypt_OpenPGP].contains_priv_key(session, fpr, has_private);
1957 PEP_STATUS add_mistrusted_key(PEP_SESSION session, const char* fpr)
1961 assert(!EMPTYSTR(fpr));
1963 if (!(session) || EMPTYSTR(fpr))
1964 return PEP_ILLEGAL_VALUE;
1966 sqlite3_reset(session->add_mistrusted_key);
1967 sqlite3_bind_text(session->add_mistrusted_key, 1, fpr, -1,
1970 result = sqlite3_step(session->add_mistrusted_key);
1971 sqlite3_reset(session->add_mistrusted_key);
1973 if (result != SQLITE_DONE)
1974 return PEP_CANNOT_SET_PGP_KEYPAIR; // FIXME: Better status?
1976 return PEP_STATUS_OK;
1979 PEP_STATUS delete_mistrusted_key(PEP_SESSION session, const char* fpr)
1983 assert(!EMPTYSTR(fpr));
1985 if (!(session) || EMPTYSTR(fpr))
1986 return PEP_ILLEGAL_VALUE;
1988 sqlite3_reset(session->delete_mistrusted_key);
1989 sqlite3_bind_text(session->delete_mistrusted_key, 1, fpr, -1,
1992 result = sqlite3_step(session->delete_mistrusted_key);
1993 sqlite3_reset(session->delete_mistrusted_key);
1995 if (result != SQLITE_DONE)
1996 return PEP_UNKNOWN_ERROR; // FIXME: Better status?
1998 return PEP_STATUS_OK;
2001 PEP_STATUS is_mistrusted_key(PEP_SESSION session, const char* fpr,
2004 PEP_STATUS status = PEP_STATUS_OK;
2007 assert(!EMPTYSTR(fpr));
2009 if (!(session && fpr))
2010 return PEP_ILLEGAL_VALUE;
2012 *mistrusted = false;
2014 sqlite3_reset(session->is_mistrusted_key);
2015 sqlite3_bind_text(session->is_mistrusted_key, 1, fpr, -1, SQLITE_STATIC);
2019 result = sqlite3_step(session->is_mistrusted_key);
2022 *mistrusted = sqlite3_column_int(session->is_mistrusted_key, 0);
2023 status = PEP_STATUS_OK;
2027 status = PEP_UNKNOWN_ERROR;
2030 sqlite3_reset(session->is_mistrusted_key);
2034 static PEP_STATUS _wipe_default_key_if_invalid(PEP_SESSION session,
2035 pEp_identity* ident) {
2037 PEP_STATUS status = PEP_STATUS_OK;
2039 if (!ident->user_id)
2040 return PEP_ILLEGAL_VALUE;
2045 char* cached_fpr = strdup(ident->fpr);
2047 return PEP_OUT_OF_MEMORY;
2049 PEP_STATUS keystatus = validate_fpr(session, ident, true, false);
2050 switch (keystatus) {
2052 // Check for non-renewable expiry and
2053 // if so, fallthrough
2054 if (ident->comm_type != PEP_ct_key_expired_but_confirmed &&
2055 ident->comm_type != PEP_ct_key_expired) {
2058 case PEP_KEY_UNSUITABLE:
2059 case PEP_KEY_BLACKLISTED:
2060 // Remove key as default for all identities and users
2061 status = remove_fpr_as_default(session, cached_fpr);
2068 if (status == PEP_STATUS_OK)
2069 status = myself(session, ident);
2074 PEP_STATUS clean_own_key_defaults(PEP_SESSION session) {
2075 identity_list* idents = NULL;
2076 PEP_STATUS status = own_identities_retrieve(session, &idents);
2077 if (status != PEP_STATUS_OK)
2081 return PEP_STATUS_OK;
2083 if (!idents->ident && !idents->next) {
2084 free_identity_list(idents);
2085 return PEP_STATUS_OK;
2086 } // Kludge: FIX own_identities_retrieve. Should return NULL, not empty list
2088 identity_list* curr = idents;
2090 for ( ; curr ; curr = curr->next) {
2091 pEp_identity* ident = curr->ident;
2095 _wipe_default_key_if_invalid(session, ident);
2098 free_identity_list(idents);
2100 // Also remove invalid default user key
2101 char* own_id = NULL;
2103 status = get_default_own_userid(session, &own_id);
2105 if (status != PEP_STATUS_OK)
2109 char* user_default_key = NULL;
2110 status = get_user_default_key(session, own_id, &user_default_key);
2111 if (status != PEP_STATUS_OK) {
2113 if (status == PEP_KEY_NOT_FOUND)
2114 status = PEP_STATUS_OK;
2118 else if (user_default_key) {
2119 pEp_identity* empty_user = new_identity(NULL, user_default_key, NULL, own_id);
2120 _wipe_default_key_if_invalid(session, empty_user);
2121 free(user_default_key);