You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1998 lines
66 KiB

8 years ago
8 years ago
7 years ago
8 years ago
8 years ago
4 years ago
4 years ago
4 years ago
8 years ago
7 years ago
6 years ago
6 years ago
8 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
8 years ago
4 years ago
4 years ago
4 years ago
4 years ago
8 years ago
8 years ago
8 years ago
7 years ago
8 years ago
8 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
8 years ago
8 years ago
4 years ago
7 years ago
8 years ago
8 years ago
8 years ago
4 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
7 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
  1. // This file is under GNU General Public License 3.0
  2. // see LICENSE.txt
  3. #include "platform.h"
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <assert.h>
  8. #include <ctype.h>
  9. #include "pEp_internal.h"
  10. #include "keymanagement.h"
  11. #include "blacklist.h"
  12. static bool key_matches_address(PEP_SESSION session, const char* address,
  13. const char* fpr) {
  14. if (!session || !address || !fpr)
  15. return false;
  16. bool retval = false;
  17. stringlist_t *keylist = NULL;
  18. PEP_STATUS status = find_keys(session, address, &keylist);
  19. if (status == PEP_STATUS_OK && keylist) {
  20. stringlist_t* curr = keylist;
  21. while (curr) {
  22. if (curr->value) {
  23. if (strcasecmp(curr->value, fpr)) {
  24. retval = true;
  25. break;
  26. }
  27. }
  28. curr = curr->next;
  29. }
  30. }
  31. free_stringlist(keylist);
  32. return retval;
  33. }
  34. PEP_STATUS elect_pubkey(
  35. PEP_SESSION session, pEp_identity * identity, bool check_blacklist
  36. )
  37. {
  38. PEP_STATUS status;
  39. stringlist_t *keylist = NULL;
  40. char *_fpr = "";
  41. identity->comm_type = PEP_ct_unknown;
  42. status = find_keys(session, identity->address, &keylist);
  43. assert(status != PEP_OUT_OF_MEMORY);
  44. if (status == PEP_OUT_OF_MEMORY)
  45. return PEP_OUT_OF_MEMORY;
  46. if (!keylist || !keylist->value)
  47. identity->comm_type = PEP_ct_key_not_found;
  48. else {
  49. stringlist_t *_keylist;
  50. for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
  51. PEP_comm_type _comm_type_key;
  52. status = get_key_rating(session, _keylist->value, &_comm_type_key);
  53. assert(status != PEP_OUT_OF_MEMORY);
  54. if (status == PEP_OUT_OF_MEMORY) {
  55. free_stringlist(keylist);
  56. return PEP_OUT_OF_MEMORY;
  57. }
  58. if (_comm_type_key != PEP_ct_compromised &&
  59. _comm_type_key != PEP_ct_unknown)
  60. {
  61. if (identity->comm_type == PEP_ct_unknown ||
  62. _comm_type_key > identity->comm_type)
  63. {
  64. bool blacklisted = false;
  65. bool mistrusted = false;
  66. status = is_mistrusted_key(session, _keylist->value, &mistrusted);
  67. if (status == PEP_STATUS_OK && check_blacklist)
  68. status = blacklist_is_listed(session, _keylist->value, &blacklisted);
  69. if (status == PEP_STATUS_OK && !mistrusted && !blacklisted) {
  70. identity->comm_type = _comm_type_key;
  71. _fpr = _keylist->value;
  72. }
  73. }
  74. }
  75. }
  76. }
  77. free(identity->fpr);
  78. if (!_fpr || _fpr[0] == '\0')
  79. identity->fpr = NULL;
  80. else {
  81. identity->fpr = strdup(_fpr);
  82. if (identity->fpr == NULL) {
  83. free_stringlist(keylist);
  84. return PEP_OUT_OF_MEMORY;
  85. }
  86. }
  87. free_stringlist(keylist);
  88. return PEP_STATUS_OK;
  89. }
  90. // own_must_contain_private is usually true when calling;
  91. // we only set it to false when we have the idea of
  92. // possibly having an own pubkey that we need to check on its own
  93. static PEP_STATUS validate_fpr(PEP_SESSION session,
  94. pEp_identity* ident,
  95. bool check_blacklist,
  96. bool own_must_contain_private) {
  97. PEP_STATUS status = PEP_STATUS_OK;
  98. if (!session || !ident || !ident->fpr || !ident->fpr[0])
  99. return PEP_ILLEGAL_VALUE;
  100. char* fpr = ident->fpr;
  101. bool has_private = false;
  102. status = contains_priv_key(session, fpr, &has_private);
  103. if (ident->me && own_must_contain_private) {
  104. if (status != PEP_STATUS_OK || !has_private)
  105. return PEP_KEY_UNSUITABLE;
  106. }
  107. else if (status != PEP_STATUS_OK && has_private) // should never happen
  108. has_private = false;
  109. status = get_trust(session, ident);
  110. if (status != PEP_STATUS_OK)
  111. ident->comm_type = PEP_ct_unknown;
  112. PEP_comm_type ct = ident->comm_type;
  113. if (ct == PEP_ct_unknown) {
  114. // If status is bad, it's ok, we get the rating
  115. // we should use then (PEP_ct_unknown)
  116. get_key_rating(session, fpr, &ct);
  117. ident->comm_type = ct;
  118. }
  119. else if (ct == PEP_ct_key_expired || ct == PEP_ct_key_expired_but_confirmed) {
  120. PEP_comm_type ct_expire_check = PEP_ct_unknown;
  121. get_key_rating(session, fpr, &ct_expire_check);
  122. if (ct_expire_check >= PEP_ct_strong_but_unconfirmed) {
  123. ident->comm_type = ct_expire_check;
  124. if (ct == PEP_ct_key_expired_but_confirmed)
  125. ident->comm_type |= PEP_ct_confirmed;
  126. ct = ident->comm_type;
  127. // We need to fix this trust in the DB.
  128. status = set_trust(session, ident);
  129. }
  130. }
  131. bool pEp_user = false;
  132. is_pEp_user(session, ident, &pEp_user);
  133. if (pEp_user) {
  134. switch (ct) {
  135. case PEP_ct_OpenPGP:
  136. case PEP_ct_OpenPGP_unconfirmed:
  137. ct += 0x47; // difference between PEP and OpenPGP values;
  138. ident->comm_type = ct;
  139. break;
  140. default:
  141. break;
  142. }
  143. }
  144. bool revoked, expired;
  145. bool blacklisted = false;
  146. status = key_revoked(session, fpr, &revoked);
  147. if (status != PEP_STATUS_OK) {
  148. return status;
  149. }
  150. if (!revoked) {
  151. time_t exp_time = (ident->me ?
  152. time(NULL) + (7*24*3600) : time(NULL));
  153. status = key_expired(session, fpr,
  154. exp_time,
  155. &expired);
  156. assert(status == PEP_STATUS_OK);
  157. if (status != PEP_STATUS_OK)
  158. return status;
  159. if (check_blacklist && IS_PGP_CT(ct) &&
  160. !ident->me) {
  161. status = blacklist_is_listed(session,
  162. fpr,
  163. &blacklisted);
  164. if (status != PEP_STATUS_OK)
  165. return status;
  166. }
  167. }
  168. if (ident->me && has_private &&
  169. (ct >= PEP_ct_strong_but_unconfirmed) &&
  170. !revoked && expired) {
  171. // extend key
  172. timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
  173. status = renew_key(session, fpr, ts);
  174. free_timestamp(ts);
  175. if (status == PEP_STATUS_OK) {
  176. // if key is valid (second check because pEp key might be extended above)
  177. // Return fpr
  178. status = key_expired(session, fpr, time(NULL), &expired);
  179. if (status != PEP_STATUS_OK)
  180. return status;
  181. if (expired) {
  182. if (ident->comm_type & PEP_ct_confirmed || (ident->comm_type == PEP_ct_key_expired_but_confirmed))
  183. ident->comm_type = PEP_ct_key_expired_but_confirmed;
  184. else
  185. ident->comm_type = PEP_ct_key_expired;
  186. return status;
  187. }
  188. // communicate key(?)
  189. }
  190. }
  191. if (revoked)
  192. ct = PEP_ct_key_revoked;
  193. else if (expired) {
  194. if (ident->comm_type & PEP_ct_confirmed || (ident->comm_type == PEP_ct_key_expired_but_confirmed))
  195. ct = PEP_ct_key_expired_but_confirmed;
  196. else
  197. ct = PEP_ct_key_expired;
  198. }
  199. else if (blacklisted) { // never true for .me
  200. ident->comm_type = ct = PEP_ct_key_not_found;
  201. free(ident->fpr);
  202. ident->fpr = strdup("");
  203. status = PEP_KEY_BLACKLISTED;
  204. }
  205. switch (ct) {
  206. case PEP_ct_key_expired:
  207. case PEP_ct_key_expired_but_confirmed:
  208. case PEP_ct_key_revoked:
  209. case PEP_ct_key_b0rken:
  210. // delete key from being default key for all users/identities
  211. status = remove_fpr_as_default(session, fpr);
  212. status = update_trust_for_fpr(session,
  213. fpr,
  214. ct);
  215. case PEP_ct_mistrusted:
  216. free(ident->fpr);
  217. ident->fpr = NULL;
  218. ident->comm_type = ct;
  219. status = PEP_KEY_UNSUITABLE;
  220. default:
  221. break;
  222. }
  223. return status;
  224. }
  225. PEP_STATUS get_all_keys_for_user(PEP_SESSION session,
  226. const char* user_id,
  227. stringlist_t** keys) {
  228. if (!session || EMPTYSTR(user_id) || !keys)
  229. return PEP_ILLEGAL_VALUE;
  230. PEP_STATUS status = PEP_STATUS_OK;
  231. *keys = NULL;
  232. stringlist_t* _kl = NULL;
  233. sqlite3_reset(session->get_all_keys_for_user);
  234. sqlite3_bind_text(session->get_all_keys_for_user, 1, user_id, -1, SQLITE_STATIC);
  235. int result = -1;
  236. while ((result = sqlite3_step(session->get_all_keys_for_user)) == SQLITE_ROW) {
  237. const char* keyres = (const char *) sqlite3_column_text(session->get_all_keys_for_user, 0);
  238. if (keyres) {
  239. if (_kl)
  240. stringlist_add(_kl, keyres);
  241. else
  242. _kl = new_stringlist(keyres);
  243. }
  244. }
  245. if (!_kl)
  246. return PEP_KEY_NOT_FOUND;
  247. *keys = _kl;
  248. sqlite3_reset(session->get_all_keys_for_user);
  249. return status;
  250. }
  251. PEP_STATUS get_user_default_key(PEP_SESSION session, const char* user_id,
  252. char** default_key) {
  253. assert(session);
  254. assert(user_id);
  255. if (!session || !user_id)
  256. return PEP_ILLEGAL_VALUE;
  257. PEP_STATUS status = PEP_STATUS_OK;
  258. // try to get default key for user_data
  259. sqlite3_reset(session->get_user_default_key);
  260. sqlite3_bind_text(session->get_user_default_key, 1, user_id,
  261. -1, SQLITE_STATIC);
  262. const int result = sqlite3_step(session->get_user_default_key);
  263. char* user_fpr = NULL;
  264. if (result == SQLITE_ROW) {
  265. const char* u_fpr =
  266. (char *) sqlite3_column_text(session->get_user_default_key, 0);
  267. if (u_fpr)
  268. user_fpr = strdup(u_fpr);
  269. }
  270. else
  271. status = PEP_GET_KEY_FAILED;
  272. sqlite3_reset(session->get_user_default_key);
  273. *default_key = user_fpr;
  274. return status;
  275. }
  276. // Only call on retrieval of previously stored identity!
  277. // Also, we presume that if the stored_identity was sent in
  278. // without an fpr, there wasn't one in the trust DB for this
  279. // identity.
  280. PEP_STATUS get_valid_pubkey(PEP_SESSION session,
  281. pEp_identity* stored_identity,
  282. bool* is_identity_default,
  283. bool* is_user_default,
  284. bool* is_address_default,
  285. bool check_blacklist) {
  286. PEP_STATUS status = PEP_STATUS_OK;
  287. if (!stored_identity || EMPTYSTR(stored_identity->user_id)
  288. || !is_identity_default || !is_user_default || !is_address_default)
  289. return PEP_ILLEGAL_VALUE;
  290. *is_identity_default = *is_user_default = *is_address_default = false;
  291. PEP_comm_type first_reject_comm_type = PEP_ct_key_not_found;
  292. PEP_STATUS first_reject_status = PEP_KEY_NOT_FOUND;
  293. char* stored_fpr = stored_identity->fpr;
  294. // Input: stored identity retrieved from database
  295. // if stored identity contains a default key
  296. if (!EMPTYSTR(stored_fpr)) {
  297. status = validate_fpr(session, stored_identity, check_blacklist, true);
  298. if (status == PEP_STATUS_OK && !EMPTYSTR(stored_identity->fpr)) {
  299. *is_identity_default = *is_address_default = true;
  300. return status;
  301. }
  302. else if (status != PEP_KEY_NOT_FOUND) {
  303. first_reject_status = status;
  304. first_reject_comm_type = stored_identity->comm_type;
  305. }
  306. }
  307. // if no valid default stored identity key found
  308. free(stored_identity->fpr);
  309. stored_identity->fpr = NULL;
  310. char* user_fpr = NULL;
  311. status = get_user_default_key(session, stored_identity->user_id, &user_fpr);
  312. if (!EMPTYSTR(user_fpr)) {
  313. // There exists a default key for user, so validate
  314. stored_identity->fpr = user_fpr;
  315. status = validate_fpr(session, stored_identity, check_blacklist, true);
  316. if (status == PEP_STATUS_OK && stored_identity->fpr) {
  317. *is_user_default = true;
  318. *is_address_default = key_matches_address(session,
  319. stored_identity->address,
  320. stored_identity->fpr);
  321. return status;
  322. }
  323. else if (status != PEP_KEY_NOT_FOUND && first_reject_status != PEP_KEY_NOT_FOUND) {
  324. first_reject_status = status;
  325. first_reject_comm_type = stored_identity->comm_type;
  326. }
  327. }
  328. status = elect_pubkey(session, stored_identity, check_blacklist);
  329. if (status == PEP_STATUS_OK) {
  330. if (!EMPTYSTR(stored_identity->fpr))
  331. validate_fpr(session, stored_identity, false, true); // blacklist already filtered of needed
  332. }
  333. else if (status != PEP_KEY_NOT_FOUND && first_reject_status != PEP_KEY_NOT_FOUND) {
  334. first_reject_status = status;
  335. first_reject_comm_type = stored_identity->comm_type;
  336. }
  337. switch (stored_identity->comm_type) {
  338. case PEP_ct_key_revoked:
  339. case PEP_ct_key_b0rken:
  340. case PEP_ct_key_expired:
  341. case PEP_ct_key_expired_but_confirmed:
  342. case PEP_ct_compromised:
  343. case PEP_ct_mistrusted:
  344. // this only happens when it's all there is
  345. status = first_reject_status;
  346. free(stored_identity->fpr);
  347. stored_identity->fpr = NULL;
  348. stored_identity->comm_type = first_reject_comm_type;
  349. break;
  350. default:
  351. if (check_blacklist && status == PEP_KEY_BLACKLISTED) {
  352. free(stored_identity->fpr);
  353. stored_identity->fpr = NULL;
  354. stored_identity->comm_type = PEP_ct_key_not_found;
  355. }
  356. break;
  357. }
  358. return status;
  359. }
  360. static void transfer_ident_lang_and_flags(pEp_identity* new_ident,
  361. pEp_identity* stored_ident) {
  362. if (new_ident->lang[0] == 0) {
  363. new_ident->lang[0] = stored_ident->lang[0];
  364. new_ident->lang[1] = stored_ident->lang[1];
  365. new_ident->lang[2] = 0;
  366. }
  367. new_ident->flags = stored_ident->flags;
  368. new_ident->me = new_ident->me || stored_ident->me;
  369. }
  370. static void adjust_pEp_trust_status(PEP_SESSION session, pEp_identity* identity) {
  371. assert(session);
  372. assert(identity);
  373. if (identity->comm_type < PEP_ct_strong_but_unconfirmed ||
  374. (identity->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
  375. return;
  376. bool pEp_user;
  377. is_pEp_user(session, identity, &pEp_user);
  378. if (pEp_user) {
  379. PEP_comm_type confirmation_status = identity->comm_type & PEP_ct_confirmed;
  380. identity->comm_type = PEP_ct_pEp_unconfirmed | confirmation_status;
  381. }
  382. }
  383. static PEP_STATUS prepare_updated_identity(PEP_SESSION session,
  384. pEp_identity* return_id,
  385. pEp_identity* stored_ident,
  386. bool store) {
  387. if (!session || !return_id || !stored_ident)
  388. return PEP_ILLEGAL_VALUE;
  389. PEP_STATUS status;
  390. bool is_identity_default, is_user_default, is_address_default;
  391. status = get_valid_pubkey(session, stored_ident,
  392. &is_identity_default,
  393. &is_user_default,
  394. &is_address_default,
  395. false);
  396. if (status == PEP_STATUS_OK && stored_ident->fpr && *(stored_ident->fpr) != '\0') {
  397. // set identity comm_type from trust db (user_id, FPR)
  398. status = get_trust(session, stored_ident);
  399. if (status == PEP_CANNOT_FIND_IDENTITY || stored_ident->comm_type == PEP_ct_unknown) {
  400. // This is OK - there is no trust DB entry, but we
  401. // found a key. We won't store this, but we'll
  402. // use it.
  403. PEP_comm_type ct = PEP_ct_unknown;
  404. status = get_key_rating(session, stored_ident->fpr, &ct);
  405. stored_ident->comm_type = ct;
  406. }
  407. }
  408. else {
  409. if (stored_ident->comm_type == PEP_ct_unknown)
  410. stored_ident->comm_type = PEP_ct_key_not_found;
  411. }
  412. free(return_id->fpr);
  413. return_id->fpr = NULL;
  414. if (status == PEP_STATUS_OK && !EMPTYSTR(stored_ident->fpr))
  415. return_id->fpr = strdup(stored_ident->fpr);
  416. return_id->comm_type = stored_ident->comm_type;
  417. // We patch the DB with the input username, but if we didn't have
  418. // one, we pull it out of storage if available.
  419. // (also, if the input username is "anonymous" and there exists
  420. // a DB username, we replace)
  421. if (!EMPTYSTR(stored_ident->username)) {
  422. if (!EMPTYSTR(return_id->username) &&
  423. (strcasecmp(return_id->username, return_id->address) == 0)) {
  424. free(return_id->username);
  425. return_id->username = NULL;
  426. }
  427. if (EMPTYSTR(return_id->username)) {
  428. free(return_id->username);
  429. return_id->username = strdup(stored_ident->username);
  430. }
  431. }
  432. else {
  433. if (EMPTYSTR(return_id->username))
  434. return_id->username = strdup(return_id->address);
  435. }
  436. return_id->me = stored_ident->me;
  437. // FIXME: Do we ALWAYS do this? We probably should...
  438. if (EMPTYSTR(return_id->user_id)) {
  439. free(return_id->user_id);
  440. return_id->user_id = strdup(stored_ident->user_id);
  441. }
  442. adjust_pEp_trust_status(session, return_id);
  443. // Call set_identity() to store
  444. if ((is_identity_default || is_user_default) &&
  445. is_address_default) {
  446. // if we got an fpr which is default for either user
  447. // or identity AND is valid for this address, set in DB
  448. // as default
  449. status = set_identity(session, return_id);
  450. }
  451. else {
  452. // Store without default fpr/ct, but return the fpr and ct
  453. // for current use
  454. char* save_fpr = return_id->fpr;
  455. PEP_comm_type save_ct = return_id->comm_type;
  456. return_id->fpr = NULL;
  457. return_id->comm_type = PEP_ct_unknown;
  458. PEP_STATUS save_status = status;
  459. status = set_identity(session, return_id);
  460. if (save_status != PEP_STATUS_OK)
  461. status = save_status;
  462. return_id->fpr = save_fpr;
  463. return_id->comm_type = save_ct;
  464. }
  465. transfer_ident_lang_and_flags(return_id, stored_ident);
  466. if (return_id->comm_type == PEP_ct_unknown)
  467. return_id->comm_type = PEP_ct_key_not_found;
  468. return status;
  469. }
  470. DYNAMIC_API PEP_STATUS update_identity(
  471. PEP_SESSION session, pEp_identity * identity
  472. )
  473. {
  474. PEP_STATUS status;
  475. assert(session);
  476. assert(identity);
  477. assert(!EMPTYSTR(identity->address));
  478. if (!(session && identity && !EMPTYSTR(identity->address)))
  479. return PEP_ILLEGAL_VALUE;
  480. char* default_own_id = NULL;
  481. status = get_default_own_userid(session, &default_own_id);
  482. // Is this me, temporary or not? If so, BAIL.
  483. if (identity->me ||
  484. (default_own_id && identity->user_id && (strcmp(default_own_id, identity->user_id) == 0)))
  485. {
  486. free(default_own_id);
  487. return PEP_ILLEGAL_VALUE;
  488. }
  489. // We have, at least, an address.
  490. // Retrieve stored identity information!
  491. pEp_identity* stored_ident = NULL;
  492. if (!EMPTYSTR(identity->user_id)) {
  493. // (we're gonna update the trust/fpr anyway, so we use the no-fpr-from-trust-db variant)
  494. // * do get_identity() to retrieve stored identity information
  495. status = get_identity_without_trust_check(session, identity->address, identity->user_id, &stored_ident);
  496. // Before we start - if there was no stored identity, we should check to make sure we don't
  497. // have a stored identity with a temporary user_id that differs from the input user_id. This
  498. // happens in multithreaded environments sometimes.
  499. if (!stored_ident) {
  500. identity_list* id_list = NULL;
  501. status = get_identities_by_address(session, identity->address, &id_list);
  502. if (id_list) {
  503. identity_list* id_curr = id_list;
  504. bool input_is_TOFU = (strstr(identity->user_id, "TOFU_") == identity->user_id);
  505. while (id_curr) {
  506. pEp_identity* this_id = id_curr->ident;
  507. if (this_id) {
  508. char* this_uid = this_id->user_id;
  509. bool curr_is_TOFU = false;
  510. // this_uid should never be NULL, as this is half of the ident
  511. // DB primary key
  512. assert(!EMPTYSTR(this_uid));
  513. curr_is_TOFU = (strstr(this_uid, "TOFU_") == this_uid);
  514. if (curr_is_TOFU && !input_is_TOFU) {
  515. // FIXME: should we also be fixing pEp_own_userId in this
  516. // function here?
  517. // if usernames match, we replace the userid. Or if the temp username
  518. // is anonymous.
  519. // FIXME: do we need to create an address match function which
  520. // matches the whole dot-and-case rigamarole from
  521. if (EMPTYSTR(this_id->username) ||
  522. strcasecmp(this_id->username, this_id->address) == 0 ||
  523. (identity->username &&
  524. strcasecmp(identity->username,
  525. this_id->username) == 0)) {
  526. // Ok, we have a temp ID. We have to replace this
  527. // with the real ID.
  528. status = replace_userid(session,
  529. this_uid,
  530. identity->user_id);
  531. if (status != PEP_STATUS_OK) {
  532. free_identity_list(id_list);
  533. free(default_own_id);
  534. return status;
  535. }
  536. free(this_uid);
  537. this_uid = NULL;
  538. // Reflect the change we just made to the DB
  539. this_id->user_id = strdup(identity->user_id);
  540. stored_ident = this_id;
  541. // FIXME: free list.
  542. break;
  543. }
  544. }
  545. else if (input_is_TOFU && !curr_is_TOFU) {
  546. // Replace ruthlessly - this is NOT supposed to happen.
  547. // BAD APP BEHAVIOUR.
  548. free(identity->user_id);
  549. identity->user_id = strdup(this_id->user_id);
  550. stored_ident = this_id;
  551. // FIXME: free list.
  552. break;
  553. }
  554. }
  555. id_curr = id_curr->next;
  556. }
  557. }
  558. }
  559. if (status == PEP_STATUS_OK && stored_ident) {
  560. // * if identity available
  561. // * patch it with username
  562. // (note: this will happen when
  563. // setting automatically below...)
  564. // * elect valid key for identity
  565. // * if valid key exists
  566. // * set return value's fpr
  567. status = prepare_updated_identity(session,
  568. identity,
  569. stored_ident, true);
  570. }
  571. // * else (identity unavailable)
  572. else {
  573. status = PEP_STATUS_OK;
  574. // FIXME: We may need to roll this back.
  575. // FIXME: change docs if we don't
  576. // if we only have user_id and address and identity not available
  577. // * return error status (identity not found)
  578. if (EMPTYSTR(identity->username)) {
  579. free(identity->username);
  580. identity->username = strdup(identity->address);
  581. }
  582. // Otherwise, if we had user_id, address, and username:
  583. // * create identity with user_id, address, username
  584. // (this is the input id without the fpr + comm type!)
  585. elect_pubkey(session, identity, false);
  586. // * We've already checked and retrieved
  587. // any applicable temporary identities above. If we're
  588. // here, none of them fit.
  589. // * call set_identity() to store
  590. // FIXME: Do we set if we had to copy in the address?
  591. adjust_pEp_trust_status(session, identity);
  592. status = set_identity(session, identity);
  593. // * Return: created identity
  594. }
  595. }
  596. else if (!EMPTYSTR(identity->username)) {
  597. /*
  598. * Temporary identity information with username supplied
  599. * Input: address, username (no others)
  600. */
  601. // * See if there is an own identity that uses this address. If so, we'll
  602. // prefer that
  603. stored_ident = NULL;
  604. if (default_own_id) {
  605. status = get_identity(session,
  606. identity->address,
  607. default_own_id,
  608. &stored_ident);
  609. }
  610. // If there isn't an own identity, search for a non-temp stored ident
  611. // with this address.
  612. if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) {
  613. identity_list* id_list = NULL;
  614. status = get_identities_by_address(session, identity->address, &id_list);
  615. if (id_list) {
  616. identity_list* id_curr = id_list;
  617. while (id_curr) {
  618. pEp_identity* this_id = id_curr->ident;
  619. if (this_id) {
  620. char* this_uid = this_id->user_id;
  621. assert(!EMPTYSTR(this_uid));
  622. // Should never be NULL - DB primary key
  623. if (strstr(this_uid, "TOFU_") != this_uid) {
  624. // if usernames match, we replace the userid.
  625. if (identity->username &&
  626. strcasecmp(identity->username,
  627. this_id->username) == 0) {
  628. // Ok, we have a real ID. Copy it!
  629. identity->user_id = strdup(this_uid);
  630. assert(identity->user_id);
  631. if (!identity->user_id)
  632. goto enomem;
  633. stored_ident = this_id;
  634. break;
  635. }
  636. }
  637. }
  638. id_curr = id_curr->next;
  639. }
  640. }
  641. }
  642. if (stored_ident) {
  643. status = prepare_updated_identity(session,
  644. identity,
  645. stored_ident, true);
  646. }
  647. else {
  648. identity->user_id = calloc(1, strlen(identity->address) + 6);
  649. if (!identity->user_id)
  650. goto enomem;
  651. snprintf(identity->user_id, strlen(identity->address) + 6,
  652. "TOFU_%s", identity->address);
  653. status = get_identity(session,
  654. identity->address,
  655. identity->user_id,
  656. &stored_ident);
  657. if (status == PEP_STATUS_OK && stored_ident) {
  658. status = prepare_updated_identity(session,
  659. identity,
  660. stored_ident, true);
  661. }
  662. else {
  663. // * We've already checked and retrieved
  664. // any applicable temporary identities above. If we're
  665. // here, none of them fit.
  666. status = elect_pubkey(session, identity, false);
  667. // * call set_identity() to store
  668. if (identity->fpr) {
  669. // it is still possible we have DB information on this key. Better check.
  670. status = get_trust(session, identity);
  671. PEP_comm_type db_ct = identity->comm_type;
  672. status = get_key_rating(session, identity->fpr, &identity->comm_type);
  673. PEP_comm_type key_ct = identity->comm_type;
  674. if (status == PEP_STATUS_OK) {
  675. switch (key_ct) {
  676. case PEP_ct_key_expired:
  677. if (db_ct == PEP_ct_key_expired_but_confirmed)
  678. identity->comm_type = db_ct;
  679. break;
  680. default:
  681. switch(db_ct) {
  682. case PEP_ct_key_expired_but_confirmed:
  683. if (key_ct >= PEP_ct_strong_but_unconfirmed)
  684. identity->comm_type |= PEP_ct_confirmed;
  685. break;
  686. case PEP_ct_mistrusted:
  687. case PEP_ct_compromised:
  688. case PEP_ct_key_b0rken:
  689. identity->comm_type = db_ct;
  690. default:
  691. break;
  692. }
  693. break;
  694. }
  695. }
  696. }
  697. // * call set_identity() to store
  698. adjust_pEp_trust_status(session, identity);
  699. status = set_identity(session, identity);
  700. }
  701. }
  702. }
  703. else {
  704. /*
  705. * Input: address (no others)
  706. * Temporary identity information without username suplied
  707. */
  708. // * Again, see if there is an own identity that uses this address. If so, we'll
  709. // prefer that
  710. stored_ident = NULL;
  711. if (default_own_id) {
  712. status = get_identity(session,
  713. identity->address,
  714. default_own_id,
  715. &stored_ident);
  716. }
  717. // If there isn't an own identity, search for a non-temp stored ident
  718. // with this address.
  719. if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) {
  720. identity_list* id_list = NULL;
  721. // * Search for identity with this address
  722. status = get_identities_by_address(session, identity->address, &id_list);
  723. // Results are ordered by timestamp descending, so this covers
  724. // both the one-result and multi-result cases
  725. if (id_list) {
  726. if (stored_ident) // unlikely
  727. free_identity(stored_ident);
  728. stored_ident = id_list->ident;
  729. }
  730. }
  731. if (stored_ident)
  732. status = prepare_updated_identity(session, identity,
  733. stored_ident, false);
  734. else {
  735. // too little info. BUT. We see if we can find a key; if so, we create a
  736. // temp identity, look for a key, and store.
  737. // create temporary identity, store it, and Return this
  738. // This means TOFU_ user_id
  739. identity->user_id = calloc(1, strlen(identity->address) + 6);
  740. if (!identity->user_id)
  741. goto enomem;
  742. snprintf(identity->user_id, strlen(identity->address) + 6,
  743. "TOFU_%s", identity->address);
  744. identity->username = strdup(identity->address);
  745. if (!identity->address)
  746. goto enomem;
  747. free(identity->fpr);
  748. identity->fpr = NULL;
  749. identity->comm_type = PEP_ct_unknown;
  750. status = elect_pubkey(session, identity, false);
  751. if (identity->fpr)
  752. status = get_key_rating(session, identity->fpr, &identity->comm_type);
  753. // * call set_identity() to store
  754. adjust_pEp_trust_status(session, identity);
  755. status = set_identity(session, identity);
  756. }
  757. }
  758. // FIXME: This is legacy. I presume it's a notification for the caller...
  759. // Revisit once I can talk to Volker
  760. if (identity->comm_type != PEP_ct_compromised &&
  761. identity->comm_type < PEP_ct_strong_but_unconfirmed)
  762. if (session->examine_identity)
  763. session->examine_identity(identity, session->examine_management);
  764. goto pEp_free;
  765. enomem:
  766. status = PEP_OUT_OF_MEMORY;
  767. pEp_free:
  768. free(default_own_id);
  769. free_identity(stored_ident);
  770. return status;
  771. }
  772. PEP_STATUS elect_ownkey(
  773. PEP_SESSION session, pEp_identity * identity
  774. )
  775. {
  776. PEP_STATUS status;
  777. stringlist_t *keylist = NULL;
  778. free(identity->fpr);
  779. identity->fpr = NULL;
  780. status = find_private_keys(session, identity->address, &keylist);
  781. assert(status != PEP_OUT_OF_MEMORY);
  782. if (status == PEP_OUT_OF_MEMORY)
  783. return PEP_OUT_OF_MEMORY;
  784. if (keylist != NULL && keylist->value != NULL)
  785. {
  786. char *_fpr = NULL;
  787. identity->comm_type = PEP_ct_unknown;
  788. stringlist_t *_keylist;
  789. for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
  790. bool is_own = false;
  791. status = own_key_is_listed(session, _keylist->value, &is_own);
  792. assert(status == PEP_STATUS_OK);
  793. if (status != PEP_STATUS_OK) {
  794. free_stringlist(keylist);
  795. return status;
  796. }
  797. if (is_own)
  798. {
  799. PEP_comm_type _comm_type_key;
  800. status = get_key_rating(session, _keylist->value, &_comm_type_key);
  801. assert(status != PEP_OUT_OF_MEMORY);
  802. if (status == PEP_OUT_OF_MEMORY) {
  803. free_stringlist(keylist);
  804. return PEP_OUT_OF_MEMORY;
  805. }
  806. if (_comm_type_key != PEP_ct_compromised &&
  807. _comm_type_key != PEP_ct_unknown)
  808. {
  809. if (identity->comm_type == PEP_ct_unknown ||
  810. _comm_type_key > identity->comm_type)
  811. {
  812. identity->comm_type = _comm_type_key;
  813. _fpr = _keylist->value;
  814. }
  815. }
  816. }
  817. }
  818. if (_fpr)
  819. {
  820. identity->fpr = strdup(_fpr);
  821. assert(identity->fpr);
  822. if (identity->fpr == NULL)
  823. {
  824. free_stringlist(keylist);
  825. return PEP_OUT_OF_MEMORY;
  826. }
  827. }
  828. free_stringlist(keylist);
  829. }
  830. return PEP_STATUS_OK;
  831. }
  832. PEP_STATUS _has_usable_priv_key(PEP_SESSION session, char* fpr,
  833. bool* is_usable) {
  834. bool has_private = false;
  835. PEP_STATUS status = contains_priv_key(session, fpr, &has_private);
  836. *is_usable = has_private;
  837. return status;
  838. }
  839. PEP_STATUS _myself(PEP_SESSION session,
  840. pEp_identity * identity,
  841. bool do_keygen,
  842. bool ignore_flags,
  843. bool read_only)
  844. {
  845. PEP_STATUS status;
  846. assert(session);
  847. assert(identity);
  848. assert(!EMPTYSTR(identity->address));
  849. assert(!EMPTYSTR(identity->user_id));
  850. if (!session || !identity || EMPTYSTR(identity->address) ||
  851. EMPTYSTR(identity->user_id))
  852. return PEP_ILLEGAL_VALUE;
  853. pEp_identity *stored_identity = NULL;
  854. char* revoked_fpr = NULL;
  855. bool valid_key_found = false;
  856. char* default_own_id = NULL;
  857. status = get_default_own_userid(session, &default_own_id);
  858. // Deal with non-default user_ids.
  859. // FIXME: if non-default and read-only, reject totally?
  860. if (default_own_id && strcmp(default_own_id, identity->user_id) != 0) {
  861. if (read_only) {
  862. free(identity->user_id);
  863. identity->user_id = strdup(default_own_id);
  864. }
  865. else {
  866. status = set_userid_alias(session, default_own_id, identity->user_id);
  867. // Do we want this to be fatal? For now, we'll do it...
  868. if (status != PEP_STATUS_OK)
  869. goto pEp_free;
  870. free(identity->user_id);
  871. identity->user_id = strdup(default_own_id);
  872. if (identity->user_id == NULL) {
  873. status = PEP_OUT_OF_MEMORY;
  874. goto pEp_free;
  875. }
  876. }
  877. }
  878. // NOTE: IF WE DON'T YET HAVE AN OWN_ID, WE IGNORE REFERENCES TO THIS ADDRESS IN THE
  879. // DB (WHICH MAY HAVE BEEN SET BEFORE MYSELF WAS CALLED BY RECEIVING AN EMAIL FROM
  880. // THIS ADDRESS), AS IT IS NOT AN OWN_IDENTITY AND HAS NO INFORMATION WE NEED OR WHAT TO
  881. // SET FOR MYSELF
  882. // Ok, so now, set up the own_identity:
  883. identity->comm_type = PEP_ct_pEp;
  884. identity->me = true;
  885. if(ignore_flags)
  886. identity->flags = 0;
  887. // Let's see if we have an identity record in the DB for
  888. // this user_id + address
  889. // DEBUG_LOG("myself", "debug", identity->address);
  890. status = get_identity(session,
  891. identity->address,
  892. identity->user_id,
  893. &stored_identity);
  894. assert(status != PEP_OUT_OF_MEMORY);
  895. if (status == PEP_OUT_OF_MEMORY) {
  896. status = PEP_OUT_OF_MEMORY;
  897. goto pEp_free;
  898. }
  899. // Set usernames - priority is input username > stored name > address
  900. // If there's an input username, we always patch the username with that
  901. // input.
  902. if (EMPTYSTR(identity->username) || read_only) {
  903. bool stored_uname = (stored_identity && !EMPTYSTR(stored_identity->username));
  904. char* uname = (stored_uname ? stored_identity->username : identity->address);
  905. free(identity->username);
  906. identity->username = strdup(uname);
  907. if (identity->username == NULL) {
  908. status = PEP_OUT_OF_MEMORY;
  909. goto pEp_free;
  910. }
  911. }
  912. // ignore input fpr
  913. if (identity->fpr) {
  914. free(identity->fpr);
  915. identity->fpr = NULL;
  916. }
  917. // check stored identity
  918. if (stored_identity && !EMPTYSTR(stored_identity->fpr)) {
  919. // Fall back / retrieve
  920. status = validate_fpr(session, stored_identity, false, true);
  921. if (status == PEP_OUT_OF_MEMORY)
  922. goto pEp_free;
  923. if (status == PEP_STATUS_OK) {
  924. if (stored_identity->comm_type >= PEP_ct_strong_but_unconfirmed) {
  925. identity->fpr = strdup(stored_identity->fpr);
  926. assert(identity->fpr);
  927. if (!identity->fpr) {
  928. status = PEP_OUT_OF_MEMORY;
  929. goto pEp_free;
  930. }
  931. valid_key_found = true;
  932. }
  933. else {
  934. bool revoked = false;
  935. status = key_revoked(session, stored_identity->fpr, &revoked);
  936. if (status)
  937. goto pEp_free;
  938. if (revoked) {
  939. revoked_fpr = strdup(stored_identity->fpr);
  940. assert(revoked_fpr);
  941. if (!revoked_fpr) {
  942. status = PEP_OUT_OF_MEMORY;
  943. goto pEp_free;
  944. }
  945. }
  946. }
  947. }
  948. }
  949. // Nothing left to do but generate a key
  950. if (!valid_key_found) {
  951. if (!do_keygen || read_only)
  952. status = PEP_GET_KEY_FAILED;
  953. else {
  954. // / DEBUG_LOG("Generating key pair", "debug", identity->address);
  955. free(identity->fpr);
  956. identity->fpr = NULL;
  957. status = generate_keypair(session, identity);
  958. assert(status != PEP_OUT_OF_MEMORY);
  959. if (status != PEP_STATUS_OK) {
  960. char buf[11];
  961. snprintf(buf, 11, "%d", status); // uh, this is kludgey. FIXME
  962. // DEBUG_LOG("Generating key pair failed", "debug", buf);
  963. }
  964. else {
  965. valid_key_found = true;
  966. if (revoked_fpr) {
  967. status = set_revoked(session, revoked_fpr,
  968. stored_identity->fpr, time(NULL));
  969. assert(status == PEP_STATUS_OK);
  970. }
  971. }
  972. }
  973. }
  974. if (valid_key_found) {
  975. identity->comm_type = PEP_ct_pEp;
  976. status = PEP_STATUS_OK;
  977. }
  978. else {
  979. free(identity->fpr);
  980. identity->fpr = NULL;
  981. identity->comm_type = PEP_ct_unknown;
  982. }
  983. // We want to set an identity in the DB even if a key isn't found, but we have to preserve the status if
  984. // it's NOT ok
  985. if (!read_only) {
  986. PEP_STATUS set_id_status = set_identity(session, identity);
  987. if (set_id_status == PEP_STATUS_OK)
  988. set_id_status = set_as_pEp_user(session, identity);
  989. status = (status == PEP_STATUS_OK ? set_id_status : status);
  990. }
  991. pEp_free:
  992. free(default_own_id);
  993. free(revoked_fpr);
  994. free_identity(stored_identity);
  995. return status;
  996. }
  997. DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
  998. {
  999. return _myself(session, identity, true, false, false);
  1000. }
  1001. DYNAMIC_API PEP_STATUS register_examine_function(
  1002. PEP_SESSION session,
  1003. examine_identity_t examine_identity,
  1004. void *management
  1005. )
  1006. {
  1007. assert(session);
  1008. if (!session)
  1009. return PEP_ILLEGAL_VALUE;
  1010. session->examine_management = management;
  1011. session->examine_identity = examine_identity;
  1012. return PEP_STATUS_OK;
  1013. }
  1014. DYNAMIC_API PEP_STATUS do_keymanagement(
  1015. retrieve_next_identity_t retrieve_next_identity,
  1016. void *management
  1017. )
  1018. {
  1019. PEP_SESSION session;
  1020. pEp_identity *identity;
  1021. PEP_STATUS status = init(&session, NULL, NULL);
  1022. assert(!status);
  1023. if (status)
  1024. return status;
  1025. assert(session && retrieve_next_identity);
  1026. if (!(session && retrieve_next_identity))
  1027. return PEP_ILLEGAL_VALUE;
  1028. log_event(session, "keymanagement thread started", "pEp engine", NULL, NULL);
  1029. while ((identity = retrieve_next_identity(management)))
  1030. {
  1031. assert(identity->address);
  1032. if(identity->address)
  1033. {
  1034. DEBUG_LOG("do_keymanagement", "retrieve_next_identity", identity->address);
  1035. if (identity->me) {
  1036. status = myself(session, identity);
  1037. } else {
  1038. status = recv_key(session, identity->address);
  1039. }
  1040. assert(status != PEP_OUT_OF_MEMORY);
  1041. if(status == PEP_OUT_OF_MEMORY)
  1042. return PEP_OUT_OF_MEMORY;
  1043. }
  1044. free_identity(identity);
  1045. }
  1046. log_event(session, "keymanagement thread shutdown", "pEp engine", NULL, NULL);
  1047. release(session);
  1048. return PEP_STATUS_OK;
  1049. }
  1050. DYNAMIC_API PEP_STATUS key_mistrusted(
  1051. PEP_SESSION session,
  1052. pEp_identity *ident
  1053. )
  1054. {
  1055. PEP_STATUS status = PEP_STATUS_OK;
  1056. assert(session);
  1057. assert(ident);
  1058. assert(!EMPTYSTR(ident->fpr));
  1059. if (!(session && ident && ident->fpr))
  1060. return PEP_ILLEGAL_VALUE;
  1061. bool has_private = false;
  1062. status = contains_priv_key(session, ident->fpr, &has_private);
  1063. if (status != PEP_STATUS_OK && status != PEP_KEY_NOT_FOUND)
  1064. return status;
  1065. // See if key is revoked already
  1066. if (has_private) {
  1067. bool revoked = false;
  1068. status = key_revoked(session, ident->fpr, &revoked);
  1069. if (!revoked)
  1070. revoke_key(session, ident->fpr, NULL);
  1071. }
  1072. // double-check to be sure key is even in the DB
  1073. if (ident->fpr)
  1074. status = set_pgp_keypair(session, ident->fpr);
  1075. // We set this temporarily but will grab it back from the cache afterwards
  1076. ident->comm_type = PEP_ct_mistrusted;
  1077. status = set_trust(session, ident);
  1078. if (status == PEP_STATUS_OK)
  1079. // cascade that mistrust for anyone using this key
  1080. status = mark_as_compromised(session, ident->fpr);
  1081. if (status == PEP_STATUS_OK)
  1082. status = add_mistrusted_key(session, ident->fpr);
  1083. return status;
  1084. }
  1085. DYNAMIC_API PEP_STATUS key_reset_trust(
  1086. PEP_SESSION session,
  1087. pEp_identity *ident
  1088. )
  1089. {
  1090. PEP_STATUS status = PEP_STATUS_OK;
  1091. assert(session);
  1092. assert(ident);
  1093. assert(!EMPTYSTR(ident->fpr));
  1094. assert(!EMPTYSTR(ident->address));
  1095. assert(!EMPTYSTR(ident->user_id));
  1096. if (!(session && ident && ident->fpr && ident->fpr[0] != '\0' && ident->address &&
  1097. ident->user_id))
  1098. return PEP_ILLEGAL_VALUE;
  1099. // we do not change the input struct at ALL.
  1100. pEp_identity* input_copy = identity_dup(ident);
  1101. pEp_identity* tmp_ident = NULL;
  1102. status = get_trust(session, input_copy);
  1103. if (status != PEP_STATUS_OK)
  1104. goto pEp_free;
  1105. PEP_comm_type new_trust = PEP_ct_unknown;
  1106. status = get_key_rating(session, ident->fpr, &new_trust);
  1107. if (status != PEP_STATUS_OK)
  1108. goto pEp_free;
  1109. bool pEp_user = false;
  1110. status = is_pEp_user(session, ident, &pEp_user);
  1111. if (pEp_user && new_trust >= PEP_ct_unconfirmed_encryption)
  1112. input_copy->comm_type = PEP_ct_pEp_unconfirmed;
  1113. else
  1114. input_copy->comm_type = new_trust;
  1115. status = set_trust(session, input_copy);
  1116. if (status != PEP_STATUS_OK)
  1117. goto pEp_free;
  1118. bool mistrusted_key = false;
  1119. status = is_mistrusted_key(session, ident->fpr, &mistrusted_key);
  1120. if (status != PEP_STATUS_OK)
  1121. goto pEp_free;
  1122. if (mistrusted_key)
  1123. status = delete_mistrusted_key(session, ident->fpr);
  1124. if (status != PEP_STATUS_OK)
  1125. goto pEp_free;
  1126. tmp_ident = new_identity(ident->address, NULL, ident->user_id, NULL);
  1127. if (!tmp_ident)
  1128. return PEP_OUT_OF_MEMORY;
  1129. if (is_me(session, tmp_ident))
  1130. status = myself(session, tmp_ident);
  1131. else
  1132. status = update_identity(session, tmp_ident);
  1133. if (status != PEP_STATUS_OK)
  1134. goto pEp_free;
  1135. // remove as default if necessary
  1136. if (!EMPTYSTR(tmp_ident->fpr) && strcmp(tmp_ident->fpr, ident->fpr) == 0) {
  1137. free(tmp_ident->fpr);
  1138. tmp_ident->fpr = NULL;
  1139. tmp_ident->comm_type = PEP_ct_unknown;
  1140. status = set_identity(session, tmp_ident);
  1141. if (status != PEP_STATUS_OK)
  1142. goto pEp_free;
  1143. }
  1144. char* user_default = NULL;
  1145. get_main_user_fpr(session, tmp_ident->user_id, &user_default);
  1146. if (!EMPTYSTR(user_default)) {
  1147. if (strcmp(user_default, ident->fpr) == 0)
  1148. status = refresh_userid_default_key(session, ident->user_id);
  1149. if (status != PEP_STATUS_OK)
  1150. goto pEp_free;
  1151. }
  1152. pEp_free:
  1153. free_identity(tmp_ident);
  1154. free_identity(input_copy);
  1155. return status;
  1156. }
  1157. DYNAMIC_API PEP_STATUS trust_personal_key(
  1158. PEP_SESSION session,
  1159. pEp_identity *ident
  1160. )
  1161. {
  1162. PEP_STATUS status = PEP_STATUS_OK;
  1163. assert(session);
  1164. assert(ident);
  1165. assert(!EMPTYSTR(ident->address));
  1166. assert(!EMPTYSTR(ident->user_id));
  1167. assert(!EMPTYSTR(ident->fpr));
  1168. if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
  1169. EMPTYSTR(ident->fpr))
  1170. return PEP_ILLEGAL_VALUE;
  1171. if (is_me(session, ident))
  1172. return PEP_ILLEGAL_VALUE;
  1173. char* ident_default_fpr = NULL;
  1174. // Before we do anything, be sure the input fpr is even eligible to be trusted
  1175. PEP_comm_type input_default_ct = PEP_ct_unknown;
  1176. status = get_key_rating(session, ident->fpr, &input_default_ct);
  1177. if (input_default_ct < PEP_ct_strong_but_unconfirmed)
  1178. return PEP_KEY_UNSUITABLE;
  1179. status = set_pgp_keypair(session, ident->fpr);
  1180. if (status != PEP_STATUS_OK)
  1181. return status;
  1182. pEp_identity* ident_copy = identity_dup(ident);
  1183. char* cached_fpr = NULL;
  1184. // for setting up a temp trusted identity for the input fpr
  1185. pEp_identity* tmp_id = NULL;
  1186. // For later, in case we need to check the user default key
  1187. pEp_identity* tmp_user_ident = NULL;
  1188. // Save the input fpr, which we already tested as non-NULL
  1189. cached_fpr = strdup(ident->fpr);
  1190. // Set up a temp trusted identity for the input fpr without a comm type;
  1191. tmp_id = new_identity(ident->address, ident->fpr, ident->user_id, NULL);
  1192. status = validate_fpr(session, tmp_id, false, true);
  1193. if (status == PEP_STATUS_OK) {
  1194. // Validate fpr gets trust DB or, when that fails, key comm type. we checked
  1195. // above that the key was ok. (not revoked or expired), but we want the max.
  1196. tmp_id->comm_type = _MAX(tmp_id->comm_type, input_default_ct) | PEP_ct_confirmed;
  1197. // Get the default identity without setting the fpr
  1198. status = update_identity(session, ident_copy);
  1199. ident_default_fpr = (EMPTYSTR(ident_copy->fpr) ? NULL : strdup(ident_copy->fpr));
  1200. if (status == PEP_STATUS_OK) {
  1201. bool trusted_default = false;
  1202. // If there's no default, or the default is different from the input...
  1203. if (EMPTYSTR(ident_default_fpr) || strcmp(cached_fpr, ident_default_fpr) != 0) {
  1204. // If the default fpr (if there is one) is trusted and key is strong enough,
  1205. // don't replace, we just set the trusted bit on this key for this user_id...
  1206. // (If there's no default fpr, this won't be true anyway.)
  1207. if ((ident_copy->comm_type >= PEP_ct_strong_but_unconfirmed &&
  1208. (ident_copy->comm_type & PEP_ct_confirmed))) {
  1209. trusted_default = true;
  1210. status = set_trust(session, tmp_id);
  1211. input_default_ct = tmp_id->comm_type;
  1212. }
  1213. else {
  1214. free(ident_copy->fpr);
  1215. ident_copy->fpr = strdup(cached_fpr);
  1216. ident_copy->comm_type = tmp_id->comm_type;
  1217. status = set_identity(session, ident_copy); // replace identity default
  1218. if (status == PEP_STATUS_OK) {
  1219. if ((ident_copy->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
  1220. status = set_as_pEp_user(session, ident_copy);
  1221. }
  1222. }
  1223. }
  1224. else { // we're setting this on the default fpr
  1225. ident->comm_type = tmp_id->comm_type;
  1226. status = set_identity(session, ident);
  1227. trusted_default = true;
  1228. }
  1229. if (status == PEP_STATUS_OK && !trusted_default) {
  1230. // Ok, there wasn't a trusted default, so we replaced. Thus, we also
  1231. // make sure there's a trusted default on the user_id. If there
  1232. // is not, we make this the default.
  1233. char* user_default = NULL;
  1234. status = get_main_user_fpr(session, ident->user_id, &user_default);
  1235. if (status == PEP_STATUS_OK && user_default) {
  1236. tmp_user_ident = new_identity(ident->address,
  1237. user_default,
  1238. ident->user_id,
  1239. NULL);
  1240. if (!tmp_user_ident)
  1241. status = PEP_OUT_OF_MEMORY;
  1242. else {
  1243. status = validate_fpr(session, tmp_user_ident, false, true);
  1244. if (status != PEP_STATUS_OK ||
  1245. tmp_user_ident->comm_type < PEP_ct_strong_but_unconfirmed ||
  1246. !(tmp_user_ident->comm_type & PEP_ct_confirmed))
  1247. {
  1248. char* trusted_fpr = (trusted_default ? ident_default_fpr : cached_fpr);
  1249. status = replace_main_user_fpr(session, ident->user_id, trusted_fpr);
  1250. }
  1251. }
  1252. }
  1253. }
  1254. }
  1255. }
  1256. free(ident_default_fpr);
  1257. free(cached_fpr);
  1258. free_identity(tmp_id);
  1259. free_identity(ident_copy);
  1260. free_identity(tmp_user_ident);
  1261. return status;
  1262. }
  1263. DYNAMIC_API PEP_STATUS trust_own_key(
  1264. PEP_SESSION session,
  1265. pEp_identity* ident
  1266. )
  1267. {
  1268. assert(session);
  1269. assert(ident);
  1270. assert(!EMPTYSTR(ident->address));
  1271. assert(!EMPTYSTR(ident->user_id));
  1272. assert(!EMPTYSTR(ident->fpr));
  1273. if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
  1274. EMPTYSTR(ident->fpr))
  1275. return PEP_ILLEGAL_VALUE;
  1276. if (!is_me(session, ident))
  1277. return PEP_ILLEGAL_VALUE;
  1278. // don't check blacklist or require a private key
  1279. PEP_STATUS status = validate_fpr(session, ident, false, false);
  1280. if (status != PEP_STATUS_OK)
  1281. return status;
  1282. status = set_pgp_keypair(session, ident->fpr);
  1283. if (status != PEP_STATUS_OK)
  1284. return status;
  1285. if (ident->comm_type < PEP_ct_strong_but_unconfirmed)
  1286. return PEP_KEY_UNSUITABLE;
  1287. ident->comm_type |= PEP_ct_confirmed;
  1288. status = set_trust(session, ident);
  1289. return status;
  1290. }
  1291. DYNAMIC_API PEP_STATUS own_key_is_listed(
  1292. PEP_SESSION session,
  1293. const char *fpr,
  1294. bool *listed
  1295. )
  1296. {
  1297. PEP_STATUS status = PEP_STATUS_OK;
  1298. int count;
  1299. assert(session && fpr && fpr[0] && listed);
  1300. if (!(session && fpr && fpr[0] && listed))
  1301. return PEP_ILLEGAL_VALUE;
  1302. *listed = false;
  1303. sqlite3_reset(session->own_key_is_listed);
  1304. sqlite3_bind_text(session->own_key_is_listed, 1, fpr, -1, SQLITE_STATIC);
  1305. int result;
  1306. result = sqlite3_step(session->own_key_is_listed);
  1307. switch (result) {
  1308. case SQLITE_ROW:
  1309. count = sqlite3_column_int(session->own_key_is_listed, 0);
  1310. *listed = count > 0;
  1311. status = PEP_STATUS_OK;
  1312. break;
  1313. default:
  1314. status = PEP_UNKNOWN_ERROR;
  1315. }
  1316. sqlite3_reset(session->own_key_is_listed);
  1317. return status;
  1318. }
  1319. PEP_STATUS _own_identities_retrieve(
  1320. PEP_SESSION session,
  1321. identity_list **own_identities,
  1322. identity_flags_t excluded_flags
  1323. )
  1324. {
  1325. PEP_STATUS status = PEP_STATUS_OK;
  1326. assert(session && own_identities);
  1327. if (!(session && own_identities))
  1328. return PEP_ILLEGAL_VALUE;
  1329. *own_identities = NULL;
  1330. identity_list *_own_identities = new_identity_list(NULL);
  1331. if (_own_identities == NULL)
  1332. goto enomem;
  1333. sqlite3_reset(session->own_identities_retrieve);
  1334. int result;
  1335. // address, fpr, username, user_id, comm_type, lang, flags
  1336. const char *address = NULL;
  1337. const char *fpr = NULL;
  1338. const char *username = NULL;
  1339. const char *user_id = NULL;
  1340. PEP_comm_type comm_type = PEP_ct_unknown;
  1341. const char *lang = NULL;
  1342. unsigned int flags = 0;
  1343. identity_list *_bl = _own_identities;
  1344. do {
  1345. sqlite3_bind_int(session->own_identities_retrieve, 1, excluded_flags);
  1346. result = sqlite3_step(session->own_identities_retrieve);
  1347. switch (result) {
  1348. case SQLITE_ROW:
  1349. address = (const char *)
  1350. sqlite3_column_text(session->own_identities_retrieve, 0);
  1351. fpr = (const char *)
  1352. sqlite3_column_text(session->own_identities_retrieve, 1);
  1353. user_id = (const char *)
  1354. sqlite3_column_text(session->own_identities_retrieve, 2);
  1355. username = (const char *)
  1356. sqlite3_column_text(session->own_identities_retrieve, 3);
  1357. comm_type = PEP_ct_pEp;
  1358. lang = (const char *)
  1359. sqlite3_column_text(session->own_identities_retrieve, 4);
  1360. flags = (unsigned int)
  1361. sqlite3_column_int(session->own_identities_retrieve, 5);
  1362. pEp_identity *ident = new_identity(address, fpr, user_id, username);
  1363. if (!ident)
  1364. goto enomem;
  1365. ident->comm_type = comm_type;
  1366. if (lang && lang[0]) {
  1367. ident->lang[0] = lang[0];
  1368. ident->lang[1] = lang[1];
  1369. ident->lang[2] = 0;
  1370. }
  1371. ident->me = true;
  1372. ident->flags = flags;
  1373. _bl = identity_list_add(_bl, ident);
  1374. if (_bl == NULL) {
  1375. free_identity(ident);
  1376. goto enomem;
  1377. }
  1378. break;
  1379. case SQLITE_DONE:
  1380. break;
  1381. default:
  1382. status = PEP_UNKNOWN_ERROR;
  1383. result = SQLITE_DONE;
  1384. }
  1385. } while (result != SQLITE_DONE);
  1386. sqlite3_reset(session->own_identities_retrieve);
  1387. if (status == PEP_STATUS_OK)
  1388. *own_identities = _own_identities;
  1389. else
  1390. free_identity_list(_own_identities);
  1391. goto the_end;
  1392. enomem:
  1393. free_identity_list(_own_identities);
  1394. status = PEP_OUT_OF_MEMORY;
  1395. the_end:
  1396. return status;
  1397. }
  1398. DYNAMIC_API PEP_STATUS own_identities_retrieve(
  1399. PEP_SESSION session,
  1400. identity_list **own_identities
  1401. )
  1402. {
  1403. return _own_identities_retrieve(session, own_identities, 0);
  1404. }
  1405. PEP_STATUS _own_keys_retrieve(
  1406. PEP_SESSION session,
  1407. stringlist_t **keylist,
  1408. identity_flags_t excluded_flags
  1409. )
  1410. {
  1411. PEP_STATUS status = PEP_STATUS_OK;
  1412. assert(session && keylist);
  1413. if (!(session && keylist))
  1414. return PEP_ILLEGAL_VALUE;
  1415. *keylist = NULL;
  1416. stringlist_t *_keylist = NULL;
  1417. sqlite3_reset(session->own_keys_retrieve);
  1418. int result;
  1419. char *fpr = NULL;
  1420. stringlist_t *_bl = _keylist;
  1421. do {
  1422. sqlite3_bind_int(session->own_keys_retrieve, 1, excluded_flags);
  1423. result = sqlite3_step(session->own_keys_retrieve);
  1424. switch (result) {
  1425. case SQLITE_ROW:
  1426. fpr = strdup((const char *) sqlite3_column_text(session->own_keys_retrieve, 0));
  1427. if(fpr == NULL)
  1428. goto enomem;
  1429. _bl = stringlist_add(_bl, fpr);
  1430. if (_bl == NULL) {
  1431. free(fpr);
  1432. goto enomem;
  1433. }
  1434. if (_keylist == NULL)
  1435. _keylist = _bl;
  1436. break;
  1437. case SQLITE_DONE:
  1438. break;
  1439. default:
  1440. status = PEP_UNKNOWN_ERROR;
  1441. result = SQLITE_DONE;
  1442. }
  1443. } while (result != SQLITE_DONE);
  1444. sqlite3_reset(session->own_keys_retrieve);
  1445. if (status == PEP_STATUS_OK)
  1446. *keylist = _keylist;
  1447. else
  1448. free_stringlist(_keylist);
  1449. goto the_end;
  1450. enomem:
  1451. free_stringlist(_keylist);
  1452. status = PEP_OUT_OF_MEMORY;
  1453. the_end:
  1454. return status;
  1455. }
  1456. DYNAMIC_API PEP_STATUS own_keys_retrieve(PEP_SESSION session, stringlist_t **keylist)
  1457. {
  1458. return _own_keys_retrieve(session, keylist, 0);
  1459. }
  1460. DYNAMIC_API PEP_STATUS set_own_key(
  1461. PEP_SESSION session,
  1462. pEp_identity *me,
  1463. const char *fpr
  1464. )
  1465. {
  1466. PEP_STATUS status = PEP_STATUS_OK;
  1467. assert(session && me);
  1468. assert(!EMPTYSTR(fpr));
  1469. assert(!EMPTYSTR(me->address));
  1470. assert(!EMPTYSTR(me->user_id));
  1471. assert(!EMPTYSTR(me->username));
  1472. if (!session || !me || EMPTYSTR(fpr) || EMPTYSTR(me->address) ||
  1473. EMPTYSTR(me->user_id) || EMPTYSTR(me->username))
  1474. return PEP_ILLEGAL_VALUE;
  1475. status = _myself(session, me, false, true, false);
  1476. // we do not need a valid key but dislike other errors
  1477. if (status != PEP_STATUS_OK && status != PEP_GET_KEY_FAILED && status != PEP_KEY_UNSUITABLE)
  1478. return status;
  1479. status = PEP_STATUS_OK;
  1480. bool private = false;
  1481. status = contains_priv_key(session, fpr, &private);
  1482. if (status != PEP_STATUS_OK)
  1483. return status;
  1484. if (!private)
  1485. return PEP_KEY_UNSUITABLE;
  1486. if (me->fpr)
  1487. free(me->fpr);
  1488. me->fpr = strdup(fpr);
  1489. assert(me->fpr);
  1490. if (!me->fpr)
  1491. return PEP_OUT_OF_MEMORY;
  1492. status = validate_fpr(session, me, false, true);
  1493. if (status)
  1494. return status;
  1495. me->comm_type = PEP_ct_pEp;
  1496. status = set_identity(session, me);
  1497. return status;
  1498. }
  1499. PEP_STATUS contains_priv_key(PEP_SESSION session, const char *fpr,
  1500. bool *has_private) {
  1501. assert(session);
  1502. assert(fpr);
  1503. assert(has_private);
  1504. if (!(session && fpr && has_private))
  1505. return PEP_ILLEGAL_VALUE;
  1506. return session->cryptotech[PEP_crypt_OpenPGP].contains_priv_key(session, fpr, has_private);
  1507. }
  1508. PEP_STATUS add_mistrusted_key(PEP_SESSION session, const char* fpr)
  1509. {
  1510. int result;
  1511. assert(!EMPTYSTR(fpr));
  1512. if (!(session) || EMPTYSTR(fpr))
  1513. return PEP_ILLEGAL_VALUE;
  1514. sqlite3_reset(session->add_mistrusted_key);
  1515. sqlite3_bind_text(session->add_mistrusted_key, 1, fpr, -1,
  1516. SQLITE_STATIC);
  1517. result = sqlite3_step(session->add_mistrusted_key);
  1518. sqlite3_reset(session->add_mistrusted_key);
  1519. if (result != SQLITE_DONE)
  1520. return PEP_CANNOT_SET_PGP_KEYPAIR; // FIXME: Better status?
  1521. return PEP_STATUS_OK;
  1522. }
  1523. PEP_STATUS delete_mistrusted_key(PEP_SESSION session, const char* fpr)
  1524. {
  1525. int result;
  1526. assert(!EMPTYSTR(fpr));
  1527. if (!(session) || EMPTYSTR(fpr))
  1528. return PEP_ILLEGAL_VALUE;
  1529. sqlite3_reset(session->delete_mistrusted_key);
  1530. sqlite3_bind_text(session->delete_mistrusted_key, 1, fpr, -1,
  1531. SQLITE_STATIC);
  1532. result = sqlite3_step(session->delete_mistrusted_key);
  1533. sqlite3_reset(session->delete_mistrusted_key);
  1534. if (result != SQLITE_DONE)
  1535. return PEP_UNKNOWN_ERROR; // FIXME: Better status?
  1536. return PEP_STATUS_OK;
  1537. }
  1538. PEP_STATUS is_mistrusted_key(PEP_SESSION session, const char* fpr,
  1539. bool* mistrusted)
  1540. {
  1541. PEP_STATUS status = PEP_STATUS_OK;
  1542. assert(session);
  1543. assert(!EMPTYSTR(fpr));
  1544. if (!(session && fpr))
  1545. return PEP_ILLEGAL_VALUE;
  1546. *mistrusted = false;
  1547. sqlite3_reset(session->is_mistrusted_key);
  1548. sqlite3_bind_text(session->is_mistrusted_key, 1, fpr, -1, SQLITE_STATIC);
  1549. int result;
  1550. result = sqlite3_step(session->is_mistrusted_key);
  1551. switch (result) {
  1552. case SQLITE_ROW:
  1553. *mistrusted = sqlite3_column_int(session->is_mistrusted_key, 0);
  1554. status = PEP_STATUS_OK;
  1555. break;
  1556. default:
  1557. status = PEP_UNKNOWN_ERROR;
  1558. }
  1559. sqlite3_reset(session->is_mistrusted_key);
  1560. return status;
  1561. }
  1562. #ifdef USE_GPG
  1563. PEP_STATUS pgp_find_trusted_private_keys(
  1564. PEP_SESSION session, stringlist_t **keylist
  1565. );
  1566. enum _pgp_thing {
  1567. _pgp_none = 0,
  1568. _pgp_fpr,
  1569. _pgp_email,
  1570. _pgp_name
  1571. };
  1572. static enum _pgp_thing _pgp_thing_next(enum _pgp_thing thing)
  1573. {
  1574. switch (thing) {
  1575. case _pgp_fpr:
  1576. return _pgp_email;
  1577. case _pgp_email:
  1578. return _pgp_name;
  1579. case _pgp_name:
  1580. return _pgp_fpr;
  1581. default:
  1582. return _pgp_fpr;
  1583. }
  1584. }
  1585. PEP_STATUS pgp_import_ultimately_trusted_keypairs(PEP_SESSION session) {
  1586. assert(session);
  1587. if (!session)
  1588. return PEP_ILLEGAL_VALUE;
  1589. stringlist_t* priv_keylist = NULL;
  1590. PEP_STATUS status = PEP_STATUS_OK;
  1591. // 1. get keys
  1592. status = pgp_find_trusted_private_keys(session, &priv_keylist);
  1593. if (status)
  1594. return status;
  1595. pEp_identity *identity = NULL;
  1596. stringlist_t *_sl;
  1597. char *fpr = NULL;
  1598. enum _pgp_thing thing = _pgp_none;
  1599. for (_sl = priv_keylist; _sl && _sl->value; _sl = _sl->next) {
  1600. thing = _pgp_thing_next(thing);
  1601. switch (thing) {
  1602. case _pgp_fpr:
  1603. identity = new_identity(NULL, NULL, PEP_OWN_USERID, NULL);
  1604. if (!identity) {
  1605. status = PEP_OUT_OF_MEMORY;
  1606. break;
  1607. }
  1608. identity->me = true;
  1609. fpr = strdup(_sl->value);
  1610. assert(fpr);
  1611. if (!fpr) {
  1612. status = PEP_OUT_OF_MEMORY;
  1613. free_identity(identity);
  1614. }
  1615. break;
  1616. case _pgp_email:
  1617. assert(identity);
  1618. identity->address = strdup(_sl->value);
  1619. assert(identity->address);
  1620. if (!identity->address) {
  1621. status = PEP_OUT_OF_MEMORY;
  1622. free_identity(identity);
  1623. }
  1624. break;
  1625. case _pgp_name:
  1626. assert(identity);
  1627. identity->username = strdup(_sl->value);
  1628. assert(identity->username);
  1629. if (!identity->username)
  1630. status = PEP_OUT_OF_MEMORY;
  1631. else
  1632. status = set_own_key(session, identity, fpr);
  1633. free_identity(identity);
  1634. identity = NULL;
  1635. break;
  1636. default:
  1637. assert(0);
  1638. free_identity(identity);
  1639. status = PEP_UNKNOWN_ERROR;
  1640. }
  1641. if (status)
  1642. break;
  1643. }
  1644. free_stringlist(priv_keylist);
  1645. return status;
  1646. }
  1647. #endif // USE_GPG