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.

841 lines
22 KiB

8 years ago
8 years ago
2 years ago
8 years ago
8 years ago
8 years ago
8 years ago
2 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
3 years ago
4 years ago
8 years ago
7 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
4 years ago
8 years ago
ENGINE-866 feature branch merge (squashed commit) of functionality to set the sticky bit for manually imported keys, to query for that bit in the trust database, and prevention of automatic reset of sticky keys by key reset when devices leave a device group. Squashed commit of the following: commit c64d850dc4bfe5a9dfd54aa94eea08a75ff69191 Author: Krista Bennett <krista@pep.foundation> Date: Fri Feb 26 15:29:32 2021 +0100 ENGINE-866: doc'd bit getter function commit ad725b5b7c742300a6a182ad8b058db23dbc3cfb Author: Krista Bennett <krista@pep.foundation> Date: Fri Feb 26 15:23:49 2021 +0100 ENGINE-866: Key reset tested on mixed sticky and not sticky keys and does what it should. commit 0ffbdde7b598c7c3fff5d797e732dec07685f9be Author: Krista Bennett <krista@pep.foundation> Date: Fri Feb 26 15:13:53 2021 +0100 ENGINE-866: Add boolean for whether to set the sticky bit or not with set_own_imported_key. the adapter should filter this out for apps, I guess, according to Volker commit 23fec59a9a4ede0682a9ebcb9a61e78456e7d8d4 Author: Krista Bennett <krista@pep.foundation> Date: Fri Feb 26 14:53:19 2021 +0100 ENGINE-866: Test and use the sticky bit commit 562239fda874623c40893c382a8f82df9e002ef5 Author: Krista Bennett <krista@pep.foundation> Date: Thu Feb 25 16:47:47 2021 +0100 ENGINE-866: moved bit from key to trust, created set_own_imported_key to replace set_own_key FOR MAIL APPS (does NOT replace it for key reset, as the new function can generate a passphrase error, whereas set_own_key cannot), and did an initial test to ensure the setter/getter functions work on the DB. commit 594133cfdee966adbaa66c62133ede1ca917bca0 Author: Krista Bennett <krista@pep.foundation> Date: Wed Feb 24 11:16:21 2021 +0100 Commented out the or'd identity.flags / pgp_keypair.flags in the sql code for the get_identity functions; we've never HAD a pgp_keypair flag before, so it never hurt before, but at this point, we're going to introduce them, and I don't want trouble. If fdik wants them or'd, fine, we'll have to change the values in the keyflags to be disjoint from the identity flags so they can coexist, but for now, they are out. commit 99831445b3e22e1386aa0f86414fdb6939e5ebaf Merge: 8ba53ece d1664cf5 Author: Krista Bennett <krista@pep.foundation> Date: Wed Feb 24 10:15:53 2021 +0100 Merge branch 'master' into ENGINE-866 commit 8ba53ece06773168a9188373d1be5f13d99b2f6e Merge: 168e2cf9 c52f4d39 Author: Krista Bennett <krista@pep.foundation> Date: Mon Feb 22 20:06:08 2021 +0100 Merged in engine_sql changes commit 168e2cf9578b12157b98da8b26e598f0a1448d9e Author: Krista Bennett <krista@pep.foundation> Date: Mon Feb 22 19:03:35 2021 +0100 ENGINE-866: Added sticky bit in database for manually set keys
11 months ago
8 years ago
4 years ago
8 years ago
ENGINE-866 feature branch merge (squashed commit) of functionality to set the sticky bit for manually imported keys, to query for that bit in the trust database, and prevention of automatic reset of sticky keys by key reset when devices leave a device group. Squashed commit of the following: commit c64d850dc4bfe5a9dfd54aa94eea08a75ff69191 Author: Krista Bennett <krista@pep.foundation> Date: Fri Feb 26 15:29:32 2021 +0100 ENGINE-866: doc'd bit getter function commit ad725b5b7c742300a6a182ad8b058db23dbc3cfb Author: Krista Bennett <krista@pep.foundation> Date: Fri Feb 26 15:23:49 2021 +0100 ENGINE-866: Key reset tested on mixed sticky and not sticky keys and does what it should. commit 0ffbdde7b598c7c3fff5d797e732dec07685f9be Author: Krista Bennett <krista@pep.foundation> Date: Fri Feb 26 15:13:53 2021 +0100 ENGINE-866: Add boolean for whether to set the sticky bit or not with set_own_imported_key. the adapter should filter this out for apps, I guess, according to Volker commit 23fec59a9a4ede0682a9ebcb9a61e78456e7d8d4 Author: Krista Bennett <krista@pep.foundation> Date: Fri Feb 26 14:53:19 2021 +0100 ENGINE-866: Test and use the sticky bit commit 562239fda874623c40893c382a8f82df9e002ef5 Author: Krista Bennett <krista@pep.foundation> Date: Thu Feb 25 16:47:47 2021 +0100 ENGINE-866: moved bit from key to trust, created set_own_imported_key to replace set_own_key FOR MAIL APPS (does NOT replace it for key reset, as the new function can generate a passphrase error, whereas set_own_key cannot), and did an initial test to ensure the setter/getter functions work on the DB. commit 594133cfdee966adbaa66c62133ede1ca917bca0 Author: Krista Bennett <krista@pep.foundation> Date: Wed Feb 24 11:16:21 2021 +0100 Commented out the or'd identity.flags / pgp_keypair.flags in the sql code for the get_identity functions; we've never HAD a pgp_keypair flag before, so it never hurt before, but at this point, we're going to introduce them, and I don't want trouble. If fdik wants them or'd, fine, we'll have to change the values in the keyflags to be disjoint from the identity flags so they can coexist, but for now, they are out. commit 99831445b3e22e1386aa0f86414fdb6939e5ebaf Merge: 8ba53ece d1664cf5 Author: Krista Bennett <krista@pep.foundation> Date: Wed Feb 24 10:15:53 2021 +0100 Merge branch 'master' into ENGINE-866 commit 8ba53ece06773168a9188373d1be5f13d99b2f6e Merge: 168e2cf9 c52f4d39 Author: Krista Bennett <krista@pep.foundation> Date: Mon Feb 22 20:06:08 2021 +0100 Merged in engine_sql changes commit 168e2cf9578b12157b98da8b26e598f0a1448d9e Author: Krista Bennett <krista@pep.foundation> Date: Mon Feb 22 19:03:35 2021 +0100 ENGINE-866: Added sticky bit in database for manually set keys
11 months ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
4 years ago
6 years ago
4 years ago
4 years ago
6 years ago
6 years ago
2 years ago
7 years ago
10 months ago
10 months ago
10 months ago
7 years ago
10 months ago
10 months ago
10 months ago
10 months ago
4 years ago
4 years ago
4 years ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
  1. /**
  2. * @file pEp_internal.h
  3. * @brief pEp internal structs, functions, defines, and values
  4. * @license GNU General Public License 3.0 - see LICENSE.txt
  5. */
  6. #ifndef PEP_INTERNAL_H
  7. #define PEP_INTERNAL_H
  8. // maximum attachment size to import as key 25MB, maximum of 20 attachments
  9. #define MAX_KEY_SIZE (25 * 1024 * 1024)
  10. #define MAX_KEYS_TO_IMPORT 20
  11. #define KEY_EXPIRE_DELTA (60 * 60 * 24 * 365)
  12. // this is 20 trustwords with 79 chars max
  13. #define MAX_TRUSTWORDS_SPACE (20 * 80)
  14. // XML parameters string
  15. #define PARMS_MAX 32768
  16. // maximum busy wait time in ms
  17. #define BUSY_WAIT_TIME 5000
  18. // default keyserver
  19. #ifndef DEFAULT_KEYSERVER
  20. #define DEFAULT_KEYSERVER "hkps://keys.openpgp.org"
  21. #endif
  22. // crashdump constants
  23. #ifndef CRASHDUMP_DEFAULT_LINES
  24. #define CRASHDUMP_DEFAULT_LINES 100
  25. #endif
  26. #define CRASHDUMP_MAX_LINES 32767
  27. // p≡p full string, NUL-terminated
  28. #ifndef PEP_SUBJ_STRING
  29. #define PEP_SUBJ_STRING {0x70,0xE2,0x89,0xA1,0x70,0x00}
  30. #define PEP_SUBJ_BYTELEN 5
  31. #endif
  32. #ifndef PEP_SUBJ_KEY
  33. #define PEP_SUBJ_KEY "Subject: "
  34. #define PEP_SUBJ_KEY_LC "subject: "
  35. #define PEP_SUBJ_KEY_LEN 9
  36. #endif
  37. #ifndef PEP_MSG_WRAP_KEY
  38. #define PEP_MSG_WRAP_KEY "pEp-Wrapped-Message-Info: "
  39. #define PEP_MSG_WRAP_KEY_LC "pep-wrapped-message-info: "
  40. #define PEP_MSG_WRAP_KEY_LEN 26
  41. #endif
  42. #ifndef X_PEP_MSG_WRAP_KEY
  43. #define X_PEP_MSG_WRAP_KEY "X-pEp-Wrapped-Message-Info"
  44. #endif
  45. #ifndef X_PEP_SNDR_FPR_KEY
  46. #define X_PEP_SNDR_FPR_KEY "X-pEp-Sender-FPR"
  47. #endif
  48. #ifndef X_PEP_MSG_VER_KEY
  49. #define X_PEP_MSG_VER_KEY "X-pEp-Message-Version"
  50. #endif
  51. #define VER_1_0 "1.0"
  52. #define VER_2_0 "2.0"
  53. #define VER_2_1 "2.1"
  54. #define VER_2_2 "2.2"
  55. #include "platform.h"
  56. #ifdef WIN32
  57. #define KEYS_DB windoze_keys_db()
  58. #define LOCAL_DB windoze_local_db()
  59. #define SYSTEM_DB windoze_system_db()
  60. #else // UNIX
  61. #define _POSIX_C_SOURCE 200809L
  62. #include <dlfcn.h>
  63. #ifdef NDEBUG
  64. #define LOCAL_DB unix_local_db()
  65. #else
  66. #define LOCAL_DB unix_local_db(false)
  67. #define LOCAL_DB_RESET unix_local_db(true)
  68. #endif
  69. #ifdef ANDROID
  70. #define SYSTEM_DB android_system_db()
  71. #else
  72. #define SYSTEM_DB unix_system_db()
  73. #endif
  74. #endif
  75. #include <locale.h>
  76. #include <stdlib.h>
  77. #include <string.h>
  78. #include <assert.h>
  79. #include <stdio.h>
  80. #include <ctype.h>
  81. #include <math.h>
  82. #ifdef SQLITE3_FROM_OS
  83. #include <sqlite3.h>
  84. #else
  85. #include "sqlite3.h"
  86. #endif
  87. #include "pEpEngine.h"
  88. #include "key_reset.h"
  89. #include "pEpEngine_internal.h"
  90. #include "key_reset_internal.h"
  91. #include "group_internal.h"
  92. #include "keymanagement_internal.h"
  93. #include "message_api_internal.h"
  94. // If not specified, build for Sequoia
  95. #ifndef USE_SEQUOIA
  96. #define USE_SEQUOIA
  97. #endif
  98. #if defined(USE_SEQUOIA)
  99. #include "pgp_sequoia_internal.h"
  100. #endif
  101. #include "../asn.1/Distribution.h"
  102. #include "../asn.1/Sync.h"
  103. #include "keymanagement.h"
  104. #include "cryptotech.h"
  105. #include "transport.h"
  106. #include "sync_api.h"
  107. #include "Sync_func.h"
  108. #define NOT_IMPLEMENTED assert(0); return PEP_UNKNOWN_ERROR;
  109. struct _pEpSession;
  110. typedef struct _pEpSession pEpSession;
  111. /**
  112. * @struct _pEpSession
  113. *
  114. * @brief TODO
  115. *
  116. */
  117. struct _pEpSession {
  118. const char *version;
  119. messageToSend_t messageToSend;
  120. #if defined(USE_SEQUOIA)
  121. sqlite3 *key_db;
  122. struct {
  123. sqlite3_stmt *begin_transaction;
  124. sqlite3_stmt *commit_transaction;
  125. sqlite3_stmt *rollback_transaction;
  126. sqlite3_stmt *cert_find;
  127. sqlite3_stmt *tsk_find;
  128. sqlite3_stmt *cert_find_by_keyid;
  129. sqlite3_stmt *tsk_find_by_keyid;
  130. sqlite3_stmt *cert_find_by_email;
  131. sqlite3_stmt *tsk_find_by_email;
  132. sqlite3_stmt *cert_all;
  133. sqlite3_stmt *tsk_all;
  134. sqlite3_stmt *cert_save_insert_primary;
  135. sqlite3_stmt *cert_save_insert_subkeys;
  136. sqlite3_stmt *cert_save_insert_userids;
  137. sqlite3_stmt *delete_keypair;
  138. } sq_sql;
  139. pgp_policy_t policy;
  140. #endif
  141. PEP_cryptotech_t *cryptotech;
  142. PEP_CIPHER_SUITE cipher_suite;
  143. char* curr_passphrase;
  144. bool new_key_pass_enable;
  145. char* generation_passphrase;
  146. PEP_transport_t *transports;
  147. sqlite3 *db;
  148. sqlite3 *system_db;
  149. sqlite3_stmt *log;
  150. sqlite3_stmt *trustword;
  151. sqlite3_stmt *get_identity;
  152. sqlite3_stmt *get_identity_without_trust_check;
  153. sqlite3_stmt *get_identities_by_address;
  154. sqlite3_stmt *get_identities_by_userid;
  155. sqlite3_stmt *get_identities_by_main_key_id;
  156. sqlite3_stmt *replace_identities_fpr;
  157. sqlite3_stmt *replace_main_user_fpr;
  158. sqlite3_stmt *replace_main_user_fpr_if_equal;
  159. sqlite3_stmt *get_main_user_fpr;
  160. sqlite3_stmt *set_default_identity_fpr;
  161. sqlite3_stmt *get_default_identity_fpr;
  162. sqlite3_stmt *refresh_userid_default_key;
  163. sqlite3_stmt *delete_key;
  164. sqlite3_stmt *remove_fpr_as_identity_default;
  165. sqlite3_stmt *remove_fpr_as_user_default;
  166. sqlite3_stmt *set_person;
  167. sqlite3_stmt *update_person;
  168. sqlite3_stmt *delete_person;
  169. sqlite3_stmt *exists_person;
  170. sqlite3_stmt *set_as_pEp_user;
  171. sqlite3_stmt *is_pEp_user;
  172. sqlite3_stmt *upgrade_pEp_version_by_user_id;
  173. sqlite3_stmt *add_into_social_graph;
  174. sqlite3_stmt *get_own_address_binding_from_contact;
  175. sqlite3_stmt *set_revoke_contact_as_notified;
  176. sqlite3_stmt *get_contacted_ids_from_revoke_fpr;
  177. sqlite3_stmt *was_id_for_revoke_contacted;
  178. sqlite3_stmt *has_id_contacted_address;
  179. sqlite3_stmt *get_last_contacted;
  180. // sqlite3_stmt *set_device_group;
  181. // sqlite3_stmt *get_device_group;
  182. sqlite3_stmt *set_pgp_keypair;
  183. sqlite3_stmt *set_pgp_keypair_flags;
  184. sqlite3_stmt *unset_pgp_keypair_flags;
  185. sqlite3_stmt *set_identity_entry;
  186. sqlite3_stmt *update_identity_entry;
  187. sqlite3_stmt *exists_identity_entry;
  188. sqlite3_stmt *force_set_identity_username;
  189. sqlite3_stmt *set_identity_flags;
  190. sqlite3_stmt *unset_identity_flags;
  191. sqlite3_stmt *set_ident_enc_format;
  192. sqlite3_stmt *set_pEp_version;
  193. sqlite3_stmt *clear_trust_info;
  194. sqlite3_stmt *set_trust;
  195. sqlite3_stmt *update_trust;
  196. sqlite3_stmt *exists_trust_entry;
  197. sqlite3_stmt *update_trust_to_pEp;
  198. sqlite3_stmt *update_trust_for_fpr;
  199. sqlite3_stmt *get_trust;
  200. sqlite3_stmt *get_trust_by_userid;
  201. sqlite3_stmt *least_trust;
  202. sqlite3_stmt *update_key_sticky_bit_for_user;
  203. sqlite3_stmt *is_key_sticky_for_user;
  204. sqlite3_stmt *mark_compromised;
  205. sqlite3_stmt *reset_trust;
  206. sqlite3_stmt *crashdump;
  207. sqlite3_stmt *languagelist;
  208. sqlite3_stmt *i18n_token;
  209. sqlite3_stmt *replace_userid;
  210. // Keys
  211. sqlite3_stmt *own_key_is_listed;
  212. sqlite3_stmt *is_own_address;
  213. sqlite3_stmt *own_identities_retrieve;
  214. sqlite3_stmt *own_keys_retrieve;
  215. sqlite3_stmt *key_identities_retrieve;
  216. sqlite3_stmt *get_user_default_key;
  217. sqlite3_stmt *get_all_keys_for_user;
  218. sqlite3_stmt *get_default_own_userid;
  219. // groups
  220. sqlite3_stmt *create_group;
  221. sqlite3_stmt *enable_group;
  222. sqlite3_stmt *disable_group;
  223. sqlite3_stmt *exists_group_entry;
  224. sqlite3_stmt *group_add_member;
  225. sqlite3_stmt *group_delete_member;
  226. sqlite3_stmt *group_join;
  227. sqlite3_stmt *leave_group;
  228. sqlite3_stmt *set_group_member_status;
  229. sqlite3_stmt *get_all_members;
  230. sqlite3_stmt *get_active_members;
  231. sqlite3_stmt *get_active_groups;
  232. sqlite3_stmt *get_all_groups;
  233. sqlite3_stmt *add_own_membership_entry;
  234. sqlite3_stmt *get_own_membership_status;
  235. sqlite3_stmt *retrieve_own_membership_info_for_group_and_ident;
  236. sqlite3_stmt *retrieve_own_membership_info_for_group;
  237. sqlite3_stmt *get_group_manager;
  238. sqlite3_stmt *is_invited_group_member;
  239. sqlite3_stmt *is_active_group_member;
  240. sqlite3_stmt *is_group_active;
  241. // sqlite3_stmt *set_own_key;
  242. // sequence value
  243. sqlite3_stmt *sequence_value1;
  244. sqlite3_stmt *sequence_value2;
  245. // revoked keys
  246. sqlite3_stmt *set_revoked;
  247. sqlite3_stmt *get_revoked;
  248. sqlite3_stmt *get_replacement_fpr;
  249. // mistrusted
  250. sqlite3_stmt* add_mistrusted_key;
  251. sqlite3_stmt* is_mistrusted_key;
  252. sqlite3_stmt* delete_mistrusted_key;
  253. // aliases
  254. sqlite3_stmt *get_userid_alias_default;
  255. sqlite3_stmt *add_userid_alias;
  256. // callbacks
  257. notifyHandshake_t notifyHandshake;
  258. inject_sync_event_t inject_sync_event;
  259. retrieve_next_sync_event_t retrieve_next_sync_event;
  260. ensure_passphrase_t ensure_passphrase;
  261. // pEp Sync
  262. void *sync_management;
  263. void *sync_obj;
  264. struct Sync_state_s sync_state;
  265. // void* sync_state_payload;
  266. // char sync_uuid[37];
  267. // time_t LastCannotDecrypt;
  268. // time_t LastUpdateRequest;
  269. // runtime config
  270. bool passive_mode;
  271. bool unencrypted_subject;
  272. bool service_log;
  273. #ifndef NDEBUG
  274. int debug_color;
  275. #endif
  276. };
  277. /**
  278. * <!-- init_transport_system() -->
  279. *
  280. * @brief TODO
  281. *
  282. * @param[in] session session handle
  283. * @param[in] in_first bool
  284. *
  285. * @retval PEP_STATUS_OK
  286. */
  287. PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first);
  288. /**
  289. * <!-- release_transport_system() -->
  290. *
  291. * @brief TODO
  292. *
  293. * @param[in] session session handle
  294. * @param[in] out_last bool
  295. *
  296. */
  297. void release_transport_system(PEP_SESSION session, bool out_last);
  298. /**
  299. * @internal
  300. *
  301. * <!-- encrypt_only() -->
  302. *
  303. * @brief TODO
  304. *
  305. * @param[in] session session handle
  306. * @param[in] keylist const stringlist_t*
  307. * @param[in] ptext const char*
  308. * @param[in] psize size_t
  309. * @param[in] ctext char**
  310. * @param[in] csize size_t*
  311. *
  312. * @warning NOT to be exposed to the outside!!!!!
  313. */
  314. PEP_STATUS encrypt_only(
  315. PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  316. size_t psize, char **ctext, size_t *csize
  317. );
  318. /**
  319. * <!-- decorate_message() -->
  320. *
  321. * @brief TODO
  322. *
  323. * @param[in] msg message*
  324. * @param[in] rating PEP_rating
  325. * @param[in] keylist stringlist_t*
  326. * @param[in] add_version bool
  327. * @param[in] clobber bool
  328. *
  329. */
  330. void decorate_message(
  331. PEP_SESSION session,
  332. message *msg,
  333. PEP_rating rating,
  334. stringlist_t *keylist,
  335. bool add_version,
  336. bool clobber);
  337. #if defined(NDEBUG) || defined(NOLOG)
  338. #define DEBUG_LOG(TITLE, ENTITY, DESC)
  339. #else
  340. #ifdef ANDROID
  341. #include <android/log.h>
  342. #define LOG_MORE(...) __android_log_print(ANDROID_LOG_DEBUG, "pEpEngine", " %s :: %s :: %s :: %s ", __VA_ARGS__);
  343. #else
  344. #include <stdio.h>
  345. #define LOG_MORE(...) fprintf(stderr, "pEpEngine DEBUG_LOG('%s','%s','%s','%s')\n", __VA_ARGS__);
  346. #endif
  347. #define DEBUG_LOG(TITLE, ENTITY, DESC) {\
  348. log_event(session, (TITLE), (ENTITY), (DESC), "debug " __FILE__ ":" S_LINE);\
  349. LOG_MORE((TITLE), (ENTITY), (DESC), __FILE__ ":" S_LINE)\
  350. }
  351. #endif
  352. /**
  353. * @enum normalize_hex_res_t
  354. *
  355. * @brief TODO
  356. *
  357. */
  358. typedef enum _normalize_hex_rest_t {
  359. accept_hex,
  360. ignore_hex,
  361. reject_hex
  362. } normalize_hex_res_t;
  363. /**
  364. * <!-- _normalize_hex() -->
  365. *
  366. * @brief TODO
  367. *
  368. * @param[in] hex char*
  369. *
  370. * @retval accept_hex
  371. * @retval irgnore_hex
  372. * @retval reject_hex
  373. */
  374. static inline normalize_hex_res_t _normalize_hex(char *hex)
  375. {
  376. if (*hex >= '0' && *hex <= '9')
  377. return accept_hex;
  378. if (*hex >= 'A' && *hex <= 'F') {
  379. *hex += 'a' - 'A';
  380. return accept_hex;
  381. }
  382. if (*hex >= 'a' && *hex <= 'f')
  383. return accept_hex;
  384. if (*hex == ' ')
  385. return ignore_hex;
  386. return reject_hex;
  387. }
  388. // Space tolerant and case insensitive fingerprint string compare
  389. /**
  390. * <!-- _compare_fprs() -->
  391. *
  392. * @brief TODO
  393. *
  394. * @param[in] fpra const char*
  395. * @param[in] fpras size_t
  396. * @param[in] fprb const char*
  397. * @param[in] fprbs size_t
  398. * @param[in] comparison int*
  399. *
  400. * @retval PEP_STATUS_OK
  401. * @retval PEP_ILLEGAL_VALUE illegal parameter values
  402. * @retval PEP_TRUSTWORDS_FPR_WRONG_LENGTH
  403. */
  404. static inline PEP_STATUS _compare_fprs(
  405. const char* fpra,
  406. size_t fpras,
  407. const char* fprb,
  408. size_t fprbs,
  409. int* comparison)
  410. {
  411. size_t ai = 0;
  412. size_t bi = 0;
  413. size_t significant = 0;
  414. int _comparison = 0;
  415. const int _FULL_FINGERPRINT_LENGTH = 40;
  416. // First compare every non-ignored chars until an end is reached
  417. while(ai < fpras && bi < fprbs)
  418. {
  419. char fprac = fpra[ai];
  420. char fprbc = fprb[bi];
  421. normalize_hex_res_t fprah = _normalize_hex(&fprac);
  422. normalize_hex_res_t fprbh = _normalize_hex(&fprbc);
  423. if(fprah == reject_hex || fprbh == reject_hex)
  424. return PEP_ILLEGAL_VALUE;
  425. if ( fprah == ignore_hex )
  426. {
  427. ai++;
  428. }
  429. else if ( fprbh == ignore_hex )
  430. {
  431. bi++;
  432. }
  433. else
  434. {
  435. if(fprac != fprbc && _comparison == 0 )
  436. {
  437. _comparison = fprac > fprbc ? 1 : -1;
  438. }
  439. significant++;
  440. ai++;
  441. bi++;
  442. }
  443. }
  444. // Bail out if we didn't got enough significnt chars
  445. if (significant != _FULL_FINGERPRINT_LENGTH )
  446. return PEP_TRUSTWORDS_FPR_WRONG_LENGTH;
  447. // Then purge remaining chars, all must be ignored chars
  448. while ( ai < fpras )
  449. {
  450. char fprac = fpra[ai];
  451. normalize_hex_res_t fprah = _normalize_hex(&fprac);
  452. if( fprah == reject_hex )
  453. return PEP_ILLEGAL_VALUE;
  454. if ( fprah != ignore_hex )
  455. return PEP_TRUSTWORDS_FPR_WRONG_LENGTH;
  456. ai++;
  457. }
  458. while ( bi < fprbs )
  459. {
  460. char fprbc = fprb[bi];
  461. normalize_hex_res_t fprbh = _normalize_hex(&fprbc);
  462. if( fprbh == reject_hex )
  463. return PEP_ILLEGAL_VALUE;
  464. if ( fprbh != ignore_hex )
  465. return PEP_TRUSTWORDS_FPR_WRONG_LENGTH;
  466. bi++;
  467. }
  468. *comparison = _comparison;
  469. return PEP_STATUS_OK;
  470. }
  471. /**
  472. * <!-- _same_fpr() -->
  473. *
  474. * @brief TODO
  475. *
  476. * @param[in] fpra const char*
  477. * @param[in] fpras size_t
  478. * @param[in] fprb const char*
  479. * @param[in] fprbs size_t
  480. *
  481. * @retval 0 on equal fingerprints
  482. * @retval non-zero if not equal
  483. */
  484. static inline int _same_fpr(
  485. const char* fpra,
  486. size_t fpras,
  487. const char* fprb,
  488. size_t fprbs
  489. )
  490. {
  491. // illegal values are ignored, and considered not same.
  492. int comparison = 1;
  493. _compare_fprs(fpra, fpras, fprb, fprbs, &comparison);
  494. return comparison == 0;
  495. }
  496. // size is the length of the bytestr that's coming in. This is really only intended
  497. // for comparing two full strings. If charstr's length is different from bytestr_size,
  498. // we'll return a non-zero value.
  499. /**
  500. * @internal
  501. *
  502. * <!-- _unsigned_signed_strcmp() -->
  503. *
  504. * @brief Compare an unsigned sequence of bytes with the input string.
  505. * This is really only intended for comparing two full strings.
  506. * If charstr's length is different from bytestr_size,
  507. * we'll return a non-zero value.
  508. *
  509. * @param[in] bytestr byte string (unsigned char data)
  510. * @param[in] charstr character string (NUL-terminated)
  511. * @param[in] bytestr_size length of byte string passed in
  512. *
  513. * @retval 0 if equal
  514. * @retval non-zero if not equal
  515. *
  516. */
  517. static inline int _unsigned_signed_strcmp(const unsigned char* bytestr, const char* charstr, int bytestr_size) {
  518. int charstr_len = strlen(charstr);
  519. if (charstr_len != bytestr_size)
  520. return -1; // we don't actually care except that it's non-zero
  521. return memcmp(bytestr, charstr, bytestr_size);
  522. }
  523. // This is just a horrible example of C type madness. UTF-8 made me do it.
  524. /**
  525. * <!-- _pEp_subj_copy() -->
  526. *
  527. * @brief TODO
  528. *
  529. *
  530. */
  531. static inline char* _pEp_subj_copy() {
  532. #ifndef WIN32
  533. unsigned char pEpstr[] = PEP_SUBJ_STRING;
  534. void* retval = calloc(1, sizeof(unsigned char)*PEP_SUBJ_BYTELEN + 1);
  535. memcpy(retval, pEpstr, PEP_SUBJ_BYTELEN);
  536. return (char*)retval;
  537. #else
  538. return strdup("pEp");
  539. #endif
  540. }
  541. /**
  542. * <!-- is_me() -->
  543. *
  544. * @brief TODO
  545. *
  546. * @param[in] session session handle
  547. * @param[in] test_ident const pEp_identity*
  548. *
  549. * @retval true
  550. * @retval false
  551. */
  552. static inline bool is_me(PEP_SESSION session, const pEp_identity* test_ident) {
  553. bool retval = false;
  554. if (test_ident && test_ident->user_id) {
  555. char* def_id = NULL;
  556. get_default_own_userid(session, &def_id);
  557. if (test_ident->me ||
  558. (def_id && strcmp(def_id, test_ident->user_id) == 0)) {
  559. retval = true;
  560. }
  561. free(def_id);
  562. }
  563. return retval;
  564. }
  565. /**
  566. * <!-- pEp_version_numeric() -->
  567. *
  568. * @brief
  569. *
  570. * @param[in] version_str const char*
  571. *
  572. * @retval float version number
  573. * @retval 0 on failure
  574. */
  575. static inline float pEp_version_numeric(const char* version_str) {
  576. float retval = 0;
  577. if (!version_str || sscanf(version_str, "%f", &retval) != 1)
  578. return 0;
  579. return retval;
  580. }
  581. /**
  582. * <!-- pEp_version_major_minor() -->
  583. *
  584. * @brief get major and minor numbers as integers from version string
  585. *
  586. * @param[in] version_str const char*
  587. * @param[out] major unsigned int*
  588. * @param[out] minor unsigned int*
  589. *
  590. */
  591. static inline void pEp_version_major_minor(const char* version_str, unsigned int* major, unsigned int* minor) {
  592. if (!major || !minor)
  593. return;
  594. if (!version_str || sscanf(version_str, "%u.%u", major, minor) != 2) {
  595. *major = 0;
  596. *minor = 0;
  597. }
  598. return;
  599. }
  600. /**
  601. * <!-- compare_versions() -->
  602. *
  603. * @brief compares two versions by major and minor version numbers
  604. *
  605. * @param[in] first_maj unsigned int
  606. * @param[in] first_min unsigned int
  607. * @param[in] second_maj unsigned int
  608. * @param[in] second_min unsigned int
  609. *
  610. * @retval 1 when first is higher version
  611. * @retval -1 when first is lower version
  612. * @retval 0 when versions are equal
  613. */
  614. static inline int compare_versions(unsigned int first_maj, unsigned int first_min,
  615. unsigned int second_maj, unsigned int second_min) {
  616. if (first_maj > second_maj)
  617. return 1;
  618. if (first_maj < second_maj)
  619. return -1;
  620. if (first_min > second_min)
  621. return 1;
  622. if (first_min < second_min)
  623. return -1;
  624. return 0;
  625. }
  626. /**
  627. * <!-- set_min_version() -->
  628. *
  629. * @brief determine the smaler version from two versions
  630. *
  631. * @param[in] first_maj unsigned int
  632. * @param[in] first_minor unsigned int
  633. * @param[in] second_maj unsigned int
  634. * @param[in] second_minor unsigned int
  635. * @param[out] result_maj unsigned int*
  636. * @param[out] result_minor unsigned int*
  637. *
  638. */
  639. static inline void set_min_version(unsigned int first_maj, unsigned int first_minor,
  640. unsigned int second_maj, unsigned int second_minor,
  641. unsigned int* result_maj, unsigned int* result_minor) {
  642. int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
  643. if (result < 0) {
  644. *result_maj = first_maj;
  645. *result_minor = first_minor;
  646. }
  647. else {
  648. *result_maj = second_maj;
  649. *result_minor = second_minor;
  650. }
  651. }
  652. /**
  653. * <!-- set_max_version() -->
  654. *
  655. * @brief determine the greater version out of two versions
  656. *
  657. * @param[in] first_maj unsigned int
  658. * @param[in] first_minor unsigned int
  659. * @param[in] second_maj unsigned int
  660. * @param[in] second_minor unsigned int
  661. * @param[out] result_maj unsigned int*
  662. * @param[out] result_minor unsigned int*
  663. *
  664. */
  665. static inline void set_max_version(unsigned int first_maj, unsigned int first_minor,
  666. unsigned int second_maj, unsigned int second_minor,
  667. unsigned int* result_maj, unsigned int* result_minor) {
  668. int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
  669. if (result > 0) {
  670. *result_maj = first_maj;
  671. *result_minor = first_minor;
  672. }
  673. else {
  674. *result_maj = second_maj;
  675. *result_minor = second_minor;
  676. }
  677. }
  678. #ifndef EMPTYSTR
  679. #define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
  680. #endif
  681. #ifndef PASS_ERROR
  682. #define PASS_ERROR(ST) (ST == PEP_PASSPHRASE_REQUIRED || ST == PEP_WRONG_PASSPHRASE || ST == PEP_PASSPHRASE_FOR_NEW_KEYS_REQUIRED)
  683. #endif
  684. #ifndef IS_PGP_CT
  685. #define IS_PGP_CT(CT) (((CT) | PEP_ct_confirmed) == PEP_ct_OpenPGP)
  686. #endif
  687. #ifndef _MIN
  688. #define _MIN(A, B) ((B) > (A) ? (A) : (B))
  689. #endif
  690. #ifndef _MAX
  691. #define _MAX(A, B) ((B) > (A) ? (B) : (A))
  692. #endif
  693. // These are globals used in generating message IDs and should only be
  694. // computed once, as they're either really constants or OS-dependent
  695. extern int _pEp_rand_max_bits;
  696. extern double _pEp_log2_36;
  697. /**
  698. * <!-- _init_globals() -->
  699. *
  700. * @internal
  701. *
  702. * @brief TODO
  703. *
  704. * Please leave _patch_asn1_codec COMMENTED OUT unless you're working
  705. * in a branch or patching the asn1 is a solution
  706. */
  707. static inline void _init_globals() {
  708. _pEp_rand_max_bits = (int) ceil(log2((double) RAND_MAX));
  709. _pEp_log2_36 = log2(36);
  710. }
  711. // spinlock implementation
  712. /**
  713. * <!-- Sqlite3_step() -->
  714. *
  715. * @brief TODO
  716. *
  717. * @param[in] stmt sqlite3_stmt*
  718. *
  719. */
  720. static inline int Sqlite3_step(sqlite3_stmt* stmt)
  721. {
  722. int rc;
  723. do {
  724. rc = sqlite3_step(stmt);
  725. } while (rc == SQLITE_BUSY || rc == SQLITE_LOCKED);
  726. return rc;
  727. }
  728. /**
  729. * @internal
  730. *
  731. * <!-- _add_auto_consume() -->
  732. *
  733. * @brief TODO
  734. *
  735. * @param[in] *msg message
  736. *
  737. */
  738. static inline void _add_auto_consume(message* msg) {
  739. add_opt_field(msg, "pEp-auto-consume", "yes");
  740. msg->in_reply_to = stringlist_add(msg->in_reply_to, "pEp-auto-consume@pEp.foundation");
  741. }
  742. #endif