1 // This file is under GNU General Public License 3.0
12 #include "pEp_internal.h"
13 #include "keymanagement.h"
16 #include "blacklist.h"
19 #define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
22 #define KEY_EXPIRE_DELTA (60 * 60 * 24 * 365)
24 PEP_STATUS elect_pubkey(
25 PEP_SESSION session, pEp_identity * identity
29 stringlist_t *keylist;
31 identity->comm_type = PEP_ct_unknown;
33 status = find_keys(session, identity->address, &keylist);
34 assert(status != PEP_OUT_OF_MEMORY);
35 if (status == PEP_OUT_OF_MEMORY)
36 return PEP_OUT_OF_MEMORY;
38 stringlist_t *_keylist;
39 for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
40 PEP_comm_type _comm_type_key;
42 status = get_key_rating(session, _keylist->value, &_comm_type_key);
43 assert(status != PEP_OUT_OF_MEMORY);
44 if (status == PEP_OUT_OF_MEMORY) {
45 free_stringlist(keylist);
46 return PEP_OUT_OF_MEMORY;
49 if (_comm_type_key != PEP_ct_compromized &&
50 _comm_type_key != PEP_ct_unknown)
52 if (identity->comm_type == PEP_ct_unknown ||
53 _comm_type_key > identity->comm_type)
56 status = blacklist_is_listed(session, _keylist->value, &blacklisted);
57 if (status == PEP_STATUS_OK && !blacklisted) {
58 identity->comm_type = _comm_type_key;
59 _fpr = _keylist->value;
69 identity->fpr = strdup(_fpr);
70 if (identity->fpr == NULL) {
71 free_stringlist(keylist);
72 return PEP_OUT_OF_MEMORY;
75 free_stringlist(keylist);
79 PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags);
81 DYNAMIC_API PEP_STATUS update_identity(
82 PEP_SESSION session, pEp_identity * identity
85 pEp_identity *stored_identity;
86 pEp_identity* temp_id = NULL;
91 assert(!EMPTYSTR(identity->address));
93 if (!(session && identity && !EMPTYSTR(identity->address)))
94 return PEP_ILLEGAL_VALUE;
96 if (identity->me || (identity->user_id && strcmp(identity->user_id, PEP_OWN_USERID) == 0)) {
98 return _myself(session, identity, false, true);
101 int _no_user_id = EMPTYSTR(identity->user_id);
102 int _did_elect_new_key = 0;
106 status = get_identity(session, identity->address, PEP_OWN_USERID,
108 if (status == PEP_STATUS_OK) {
109 free_identity(stored_identity);
110 return _myself(session, identity, false, true);
113 free(identity->user_id);
115 identity->user_id = calloc(1, strlen(identity->address) + 6);
116 if (!identity->user_id)
118 return PEP_OUT_OF_MEMORY;
120 snprintf(identity->user_id, strlen(identity->address) + 6,
121 "TOFU_%s", identity->address);
124 status = get_identity(session,
129 assert(status != PEP_OUT_OF_MEMORY);
130 if (status == PEP_OUT_OF_MEMORY)
133 temp_id = identity_dup(identity);
135 /* We don't take given fpr.
136 In case there's no acceptable stored fpr, it will be elected. */
139 temp_id->comm_type = PEP_ct_unknown;
141 if (stored_identity) {
143 bool dont_use_stored_fpr = true;
145 /* if we have a stored_identity fpr */
146 if (!EMPTYSTR(stored_identity->fpr)) {
147 status = blacklist_is_listed(session, stored_identity->fpr, &dont_use_stored_fpr);
148 if (status != PEP_STATUS_OK)
149 dont_use_stored_fpr = true;
153 if (!dont_use_stored_fpr) {
154 temp_id->fpr = strdup(stored_identity->fpr);
155 assert(temp_id->fpr);
156 if (temp_id->fpr == NULL) {
157 status = PEP_OUT_OF_MEMORY;
161 /* Check stored comm_type */
162 PEP_comm_type _comm_type_key;
163 status = get_key_rating(session, temp_id->fpr, &_comm_type_key);
164 assert(status != PEP_OUT_OF_MEMORY);
165 if (status == PEP_OUT_OF_MEMORY)
167 if (_comm_type_key < PEP_ct_unconfirmed_encryption) {
168 /* if key not good anymore,
169 downgrade eventually trusted comm_type */
170 temp_id->comm_type = _comm_type_key;
172 /* otherwise take stored comm_type as-is */
173 temp_id->comm_type = stored_identity->comm_type;
174 if (temp_id->comm_type == PEP_ct_unknown) {
175 /* except if unknown */
176 temp_id->comm_type = _comm_type_key;
181 status = elect_pubkey(session, temp_id);
182 if (status != PEP_STATUS_OK)
185 _did_elect_new_key = 1;
189 /* ok, from here on out, use temp_id */
192 /* At this point, we either have a non-blacklisted fpr we can work */
193 /* with, or we've got nada. */
195 if (EMPTYSTR(temp_id->fpr)) {
196 /* nada : set comm_type accordingly */
197 temp_id->comm_type = PEP_ct_key_not_found;
200 if (EMPTYSTR(temp_id->username)) {
201 free(temp_id->username);
202 temp_id->username = strdup(stored_identity->username);
203 assert(temp_id->username);
204 if (temp_id->username == NULL){
205 status = PEP_OUT_OF_MEMORY;
210 if (temp_id->lang[0] == 0) {
211 temp_id->lang[0] = stored_identity->lang[0];
212 temp_id->lang[1] = stored_identity->lang[1];
213 temp_id->lang[2] = 0;
216 temp_id->flags = stored_identity->flags;
218 else /* stored_identity == NULL */ {
221 /* We elect a pubkey */
222 status = elect_pubkey(session, temp_id);
223 if (status != PEP_STATUS_OK)
226 /* Work with the elected key */
227 if (!EMPTYSTR(temp_id->fpr)) {
229 PEP_comm_type _comm_type_key = temp_id->comm_type;
231 _did_elect_new_key = 1;
233 // We don't want to lose a previous trust entry!!!
234 status = get_trust(session, temp_id);
236 bool has_trust_status = (status == PEP_STATUS_OK);
238 if (!has_trust_status)
239 temp_id->comm_type = _comm_type_key;
243 if (temp_id->fpr == NULL) {
244 temp_id->fpr = strdup("");
245 if (temp_id->fpr == NULL) {
246 status = PEP_OUT_OF_MEMORY;
252 status = PEP_STATUS_OK;
254 if (temp_id->comm_type != PEP_ct_unknown && !EMPTYSTR(temp_id->user_id)) {
255 assert(!EMPTYSTR(temp_id->username)); // this should not happen
257 if (EMPTYSTR(temp_id->username)) { // mitigate
258 free(temp_id->username);
259 temp_id->username = strdup("anonymous");
260 assert(temp_id->username);
261 if (temp_id->username == NULL){
262 status = PEP_OUT_OF_MEMORY;
267 // Identity doesn't get stored if call was just about checking existing
268 // user by address (i.e. no user id given but already stored)
269 if (!(_no_user_id && stored_identity) || _did_elect_new_key)
271 status = set_identity(session, temp_id);
272 assert(status == PEP_STATUS_OK);
273 if (status != PEP_STATUS_OK) {
279 if (temp_id->comm_type != PEP_ct_compromized &&
280 temp_id->comm_type < PEP_ct_strong_but_unconfirmed)
281 if (session->examine_identity)
282 session->examine_identity(temp_id, session->examine_management);
284 /* ok, we got to the end. So we can assign the output identity */
285 free(identity->address);
286 identity->address = strdup(temp_id->address);
288 identity->fpr = strdup(temp_id->fpr);
289 free(identity->user_id);
290 identity->user_id = strdup(temp_id->user_id);
291 free(identity->username);
292 identity->username = strdup(temp_id->username ? temp_id->username : "anonymous");
293 identity->comm_type = temp_id->comm_type;
294 identity->lang[0] = temp_id->lang[0];
295 identity->lang[1] = temp_id->lang[1];
296 identity->lang[2] = 0;
297 identity->me = temp_id->me;
298 identity->flags = temp_id->flags;
302 if (stored_identity){
303 free_identity(stored_identity);
307 free_identity(temp_id);
312 PEP_STATUS elect_ownkey(
313 PEP_SESSION session, pEp_identity * identity
317 stringlist_t *keylist = NULL;
320 identity->fpr = NULL;
322 status = find_private_keys(session, identity->address, &keylist);
323 assert(status != PEP_OUT_OF_MEMORY);
324 if (status == PEP_OUT_OF_MEMORY)
325 return PEP_OUT_OF_MEMORY;
327 if (keylist != NULL && keylist->value != NULL)
330 identity->comm_type = PEP_ct_unknown;
332 stringlist_t *_keylist;
333 for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
336 if (session->use_only_own_private_keys)
338 status = own_key_is_listed(session, _keylist->value, &is_own);
339 assert(status == PEP_STATUS_OK);
340 if (status != PEP_STATUS_OK) {
341 free_stringlist(keylist);
346 // TODO : also accept synchronized device group keys ?
348 if (!session->use_only_own_private_keys || is_own)
350 PEP_comm_type _comm_type_key;
352 status = get_key_rating(session, _keylist->value, &_comm_type_key);
353 assert(status != PEP_OUT_OF_MEMORY);
354 if (status == PEP_OUT_OF_MEMORY) {
355 free_stringlist(keylist);
356 return PEP_OUT_OF_MEMORY;
359 if (_comm_type_key != PEP_ct_compromized &&
360 _comm_type_key != PEP_ct_unknown)
362 if (identity->comm_type == PEP_ct_unknown ||
363 _comm_type_key > identity->comm_type)
365 identity->comm_type = _comm_type_key;
366 _fpr = _keylist->value;
374 identity->fpr = strdup(_fpr);
375 assert(identity->fpr);
376 if (identity->fpr == NULL)
378 free_stringlist(keylist);
379 return PEP_OUT_OF_MEMORY;
382 free_stringlist(keylist);
384 return PEP_STATUS_OK;
387 PEP_STATUS _has_usable_priv_key(PEP_SESSION session, char* fpr,
390 bool dont_use_fpr = true;
392 PEP_STATUS status = blacklist_is_listed(session, fpr, &dont_use_fpr);
393 if (status == PEP_STATUS_OK && !dont_use_fpr) {
394 // Make sure there is a *private* key associated with this fpr
395 bool has_private = false;
396 status = contains_priv_key(session, fpr, &has_private);
398 if (status == PEP_STATUS_OK)
399 dont_use_fpr = !has_private;
402 *is_usable = !dont_use_fpr;
407 PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags)
409 pEp_identity *stored_identity;
414 assert(!EMPTYSTR(identity->address));
416 assert(EMPTYSTR(identity->user_id) ||
417 strcmp(identity->user_id, PEP_OWN_USERID) == 0);
419 if (!(session && identity && !EMPTYSTR(identity->address) &&
420 (EMPTYSTR(identity->user_id) ||
421 strcmp(identity->user_id, PEP_OWN_USERID) == 0)))
422 return PEP_ILLEGAL_VALUE;
424 identity->comm_type = PEP_ct_pEp;
429 if (EMPTYSTR(identity->user_id))
431 free(identity->user_id);
432 identity->user_id = strdup(PEP_OWN_USERID);
433 assert(identity->user_id);
434 if (identity->user_id == NULL)
435 return PEP_OUT_OF_MEMORY;
438 if (EMPTYSTR(identity->username))
440 free(identity->username);
441 identity->username = strdup("anonymous");
442 assert(identity->username);
443 if (identity->username == NULL)
444 return PEP_OUT_OF_MEMORY;
447 DEBUG_LOG("myself", "debug", identity->address);
449 status = get_identity(session,
454 assert(status != PEP_OUT_OF_MEMORY);
455 if (status == PEP_OUT_OF_MEMORY)
456 return PEP_OUT_OF_MEMORY;
458 bool dont_use_stored_fpr = true;
459 bool dont_use_input_fpr = true;
463 if (EMPTYSTR(identity->fpr)) {
465 bool has_private = false;
467 status = _has_usable_priv_key(session, stored_identity->fpr, &has_private);
469 // N.B. has_private is never true if the returned status is not PEP_STATUS_OK
471 identity->fpr = strdup(stored_identity->fpr);
472 assert(identity->fpr);
473 if (identity->fpr == NULL)
475 return PEP_OUT_OF_MEMORY;
477 dont_use_stored_fpr = false;
481 identity->flags = (identity->flags & 255) | stored_identity->flags;
483 free_identity(stored_identity);
486 if (dont_use_stored_fpr && !EMPTYSTR(identity->fpr))
488 // App must have a good reason to give fpr, such as explicit
489 // import of private key, or similar.
491 // Take given fpr as-is.
494 // First check to see if it's blacklisted or private part is missing?
495 bool has_private = false;
497 status = _has_usable_priv_key(session, identity->fpr, &has_private);
499 // N.B. has_private is never true if the returned status is not PEP_STATUS_OK
501 dont_use_input_fpr = false;
505 // Ok, we failed to get keys either way, so let's elect one.
506 if (dont_use_input_fpr && dont_use_stored_fpr)
508 status = elect_ownkey(session, identity);
509 assert(status == PEP_STATUS_OK);
510 if (status != PEP_STATUS_OK) {
514 bool has_private = false;
516 // ok, we elected something.
517 // elect_ownkey only returns private keys, so we don't check again.
518 // Check to see if it's blacklisted
520 status = blacklist_is_listed(session, identity->fpr, &listed);
522 if (status == PEP_STATUS_OK)
523 has_private = !listed;
527 dont_use_input_fpr = false;
529 else { // OK, we've tried everything. Time to generate new keys.
530 free(identity->fpr); // It can stay in this state (unallocated) because we'll generate a new key
531 identity->fpr = NULL;
535 bool revoked = false;
537 if (!EMPTYSTR(identity->fpr))
539 status = key_revoked(session, identity->fpr, &revoked);
541 // Forces re-election if key is missing and own-key-only not forced
542 if (!session->use_only_own_private_keys && status == PEP_KEY_NOT_FOUND)
544 status = elect_ownkey(session, identity);
545 assert(status == PEP_STATUS_OK);
546 if (status != PEP_STATUS_OK) {
550 else if (status != PEP_STATUS_OK)
556 bool new_key_generated = false;
558 if (EMPTYSTR(identity->fpr) || revoked)
561 return PEP_GET_KEY_FAILED;
566 r_fpr = identity->fpr;
567 identity->fpr = NULL;
570 DEBUG_LOG("generating key pair", "debug", identity->address);
571 status = generate_keypair(session, identity);
572 assert(status != PEP_OUT_OF_MEMORY);
573 if (status != PEP_STATUS_OK) {
575 snprintf(buf, 11, "%d", status);
576 DEBUG_LOG("generating key pair failed", "debug", buf);
582 new_key_generated = true;
586 status = set_revoked(session, r_fpr,
587 identity->fpr, time(NULL));
589 if (status != PEP_STATUS_OK) {
597 status = key_expired(session, identity->fpr,
598 time(NULL) + (7*24*3600), // In a week
601 assert(status == PEP_STATUS_OK);
602 if (status != PEP_STATUS_OK) {
606 if (status == PEP_STATUS_OK && expired) {
607 timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
608 renew_key(session, identity->fpr, ts);
613 if (!identity->username)
614 identity->username = strdup("");
616 status = set_identity(session, identity);
617 assert(status == PEP_STATUS_OK);
618 if (status != PEP_STATUS_OK) {
622 if(new_key_generated)
624 // if a state machine for keysync is in place, inject notify
625 status = inject_DeviceState_event(session, KeyGen, NULL, NULL);
626 if (status == PEP_OUT_OF_MEMORY){
627 return PEP_OUT_OF_MEMORY;
631 return PEP_STATUS_OK;
635 DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
637 return _myself(session, identity, true, false);
640 DYNAMIC_API PEP_STATUS register_examine_function(
642 examine_identity_t examine_identity,
648 return PEP_ILLEGAL_VALUE;
650 session->examine_management = management;
651 session->examine_identity = examine_identity;
653 return PEP_STATUS_OK;
656 DYNAMIC_API PEP_STATUS do_keymanagement(
657 retrieve_next_identity_t retrieve_next_identity,
662 pEp_identity *identity;
665 assert(retrieve_next_identity);
668 if (!retrieve_next_identity || !management)
669 return PEP_ILLEGAL_VALUE;
671 status = init(&session);
672 assert(status == PEP_STATUS_OK);
673 if (status != PEP_STATUS_OK)
676 log_event(session, "keymanagement thread started", "pEp engine", NULL, NULL);
678 while ((identity = retrieve_next_identity(management)))
680 assert(identity->address);
681 if(identity->address)
683 DEBUG_LOG("do_keymanagement", "retrieve_next_identity", identity->address);
686 status = myself(session, identity);
688 status = recv_key(session, identity->address);
691 assert(status != PEP_OUT_OF_MEMORY);
692 if(status == PEP_OUT_OF_MEMORY)
693 return PEP_OUT_OF_MEMORY;
695 free_identity(identity);
698 log_event(session, "keymanagement thread shutdown", "pEp engine", NULL, NULL);
701 return PEP_STATUS_OK;
704 DYNAMIC_API PEP_STATUS key_mistrusted(
709 PEP_STATUS status = PEP_STATUS_OK;
713 assert(!EMPTYSTR(ident->fpr));
715 if (!(session && ident && ident->fpr))
716 return PEP_ILLEGAL_VALUE;
720 revoke_key(session, ident->fpr, NULL);
721 myself(session, ident);
725 status = mark_as_compromized(session, ident->fpr);
731 DYNAMIC_API PEP_STATUS key_reset_trust(
736 PEP_STATUS status = PEP_STATUS_OK;
741 assert(!EMPTYSTR(ident->fpr));
742 assert(!EMPTYSTR(ident->address));
743 assert(!EMPTYSTR(ident->user_id));
745 if (!(session && ident && !ident->me && ident->fpr && ident->address &&
747 return PEP_ILLEGAL_VALUE;
749 status = update_identity(session, ident);
750 if (status != PEP_STATUS_OK)
753 if (ident->comm_type == PEP_ct_mistrusted)
754 ident->comm_type = PEP_ct_unknown;
756 ident->comm_type &= ~PEP_ct_confirmed;
758 status = set_identity(session, ident);
759 if (status != PEP_STATUS_OK)
762 if (ident->comm_type == PEP_ct_unknown)
763 status = update_identity(session, ident);
767 DYNAMIC_API PEP_STATUS trust_personal_key(
772 PEP_STATUS status = PEP_STATUS_OK;
776 assert(!EMPTYSTR(ident->address));
777 assert(!EMPTYSTR(ident->user_id));
778 assert(!EMPTYSTR(ident->fpr));
781 if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
782 EMPTYSTR(ident->fpr) || ident->me)
783 return PEP_ILLEGAL_VALUE;
785 status = update_identity(session, ident);
786 if (status != PEP_STATUS_OK)
789 if (ident->comm_type > PEP_ct_strong_but_unconfirmed) {
790 ident->comm_type |= PEP_ct_confirmed;
791 status = set_identity(session, ident);
794 // MISSING: S/MIME has to be handled depending on trusted CAs
795 status = PEP_CANNOT_SET_TRUST;
801 DYNAMIC_API PEP_STATUS own_key_is_listed(
807 PEP_STATUS status = PEP_STATUS_OK;
810 assert(session && fpr && fpr[0] && listed);
812 if (!(session && fpr && fpr[0] && listed))
813 return PEP_ILLEGAL_VALUE;
817 sqlite3_reset(session->own_key_is_listed);
818 sqlite3_bind_text(session->own_key_is_listed, 1, fpr, -1, SQLITE_STATIC);
822 result = sqlite3_step(session->own_key_is_listed);
825 count = sqlite3_column_int(session->own_key_is_listed, 0);
827 status = PEP_STATUS_OK;
831 status = PEP_UNKNOWN_ERROR;
834 sqlite3_reset(session->own_key_is_listed);
838 PEP_STATUS _own_identities_retrieve(
840 identity_list **own_identities,
841 identity_flags_t excluded_flags
844 PEP_STATUS status = PEP_STATUS_OK;
846 assert(session && own_identities);
847 if (!(session && own_identities))
848 return PEP_ILLEGAL_VALUE;
850 *own_identities = NULL;
851 identity_list *_own_identities = new_identity_list(NULL);
852 if (_own_identities == NULL)
855 sqlite3_reset(session->own_identities_retrieve);
858 // address, fpr, username, user_id, comm_type, lang, flags
859 const char *address = NULL;
860 const char *fpr = NULL;
861 const char *username = NULL;
862 const char *user_id = NULL;
863 PEP_comm_type comm_type = PEP_ct_unknown;
864 const char *lang = NULL;
865 unsigned int flags = 0;
867 identity_list *_bl = _own_identities;
869 sqlite3_bind_int(session->own_identities_retrieve, 1, excluded_flags);
870 result = sqlite3_step(session->own_identities_retrieve);
873 address = (const char *)
874 sqlite3_column_text(session->own_identities_retrieve, 0);
876 sqlite3_column_text(session->own_identities_retrieve, 1);
877 user_id = PEP_OWN_USERID;
878 username = (const char *)
879 sqlite3_column_text(session->own_identities_retrieve, 2);
880 comm_type = PEP_ct_pEp;
881 lang = (const char *)
882 sqlite3_column_text(session->own_identities_retrieve, 3);
883 flags = (unsigned int)
884 sqlite3_column_int(session->own_identities_retrieve, 4);
886 pEp_identity *ident = new_identity(address, fpr, user_id, username);
889 ident->comm_type = comm_type;
890 if (lang && lang[0]) {
891 ident->lang[0] = lang[0];
892 ident->lang[1] = lang[1];
896 ident->flags = flags;
898 _bl = identity_list_add(_bl, ident);
900 free_identity(ident);
910 status = PEP_UNKNOWN_ERROR;
911 result = SQLITE_DONE;
913 } while (result != SQLITE_DONE);
915 sqlite3_reset(session->own_identities_retrieve);
916 if (status == PEP_STATUS_OK)
917 *own_identities = _own_identities;
919 free_identity_list(_own_identities);
924 free_identity_list(_own_identities);
925 status = PEP_OUT_OF_MEMORY;
931 DYNAMIC_API PEP_STATUS own_identities_retrieve(
933 identity_list **own_identities
936 return _own_identities_retrieve(session, own_identities, 0);
939 PEP_STATUS _own_keys_retrieve(
941 stringlist_t **keylist,
942 identity_flags_t excluded_flags
945 PEP_STATUS status = PEP_STATUS_OK;
947 assert(session && keylist);
948 if (!(session && keylist))
949 return PEP_ILLEGAL_VALUE;
952 stringlist_t *_keylist = NULL;
954 sqlite3_reset(session->own_keys_retrieve);
959 stringlist_t *_bl = _keylist;
961 sqlite3_bind_int(session->own_keys_retrieve, 1, excluded_flags);
962 result = sqlite3_step(session->own_keys_retrieve);
965 fpr = strdup((const char *) sqlite3_column_text(session->own_keys_retrieve, 0));
969 _bl = stringlist_add(_bl, fpr);
974 if (_keylist == NULL)
983 status = PEP_UNKNOWN_ERROR;
984 result = SQLITE_DONE;
986 } while (result != SQLITE_DONE);
988 sqlite3_reset(session->own_keys_retrieve);
989 if (status == PEP_STATUS_OK)
992 free_stringlist(_keylist);
997 free_stringlist(_keylist);
998 status = PEP_OUT_OF_MEMORY;
1004 DYNAMIC_API PEP_STATUS own_keys_retrieve(PEP_SESSION session, stringlist_t **keylist)
1006 return _own_keys_retrieve(session, keylist, 0);
1009 // TODO: Unused for now, but should be used when sync receive old keys (ENGINE-145)
1010 DYNAMIC_API PEP_STATUS set_own_key(
1011 PEP_SESSION session,
1012 const char *address,
1016 PEP_STATUS status = PEP_STATUS_OK;
1019 address && address[0] &&
1024 address && address[0] &&
1027 return PEP_ILLEGAL_VALUE;
1029 sqlite3_reset(session->set_own_key);
1030 sqlite3_bind_text(session->set_own_key, 1, address, -1, SQLITE_STATIC);
1031 sqlite3_bind_text(session->set_own_key, 2, fpr, -1, SQLITE_STATIC);
1035 result = sqlite3_step(session->set_own_key);
1038 status = PEP_STATUS_OK;
1042 status = PEP_UNKNOWN_ERROR;
1045 sqlite3_reset(session->set_own_key);
1049 PEP_STATUS contains_priv_key(PEP_SESSION session, const char *fpr,
1050 bool *has_private) {
1054 assert(has_private);
1056 if (!(session && fpr && has_private))
1057 return PEP_ILLEGAL_VALUE;
1059 return session->cryptotech[PEP_crypt_OpenPGP].contains_priv_key(session, fpr, has_private);