src/pgp_sequoia.c
author Neal H. Walfield <neal@pep.foundation>
Wed, 08 May 2019 12:20:37 +0200
branchemail_comparison
changeset 3649 1dd837adc30b
parent 3648 f7f07e2825d1
permissions -rw-r--r--
Fix public key.
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
     5 
     6 #define _GNU_SOURCE 1
     7 
     8 #include "platform.h"
     9 #include "pEp_internal.h"
    10 #include "pgp_gpg.h"
    11 
    12 #include <limits.h>
    13 #include <sys/stat.h>
    14 #include <sys/types.h>
    15 
    16 #include "wrappers.h"
    17 
    18 #define TRACING 0
    19 #ifndef TRACING
    20 #  ifndef NDEBUG
    21 #    define TRACING 0
    22 #  else
    23 #    define TRACING 1
    24 #  endif
    25 #endif
    26 
    27 // enable tracing if in debugging mode
    28 #if TRACING
    29 #include "status_to_string.h"
    30 #  define _T(...) do {                          \
    31         fprintf(stderr, ##__VA_ARGS__);         \
    32     } while (0)
    33 #else
    34 #  define _T(...) do { } while (0)
    35 #endif
    36 
    37 // Show the start of a tracepoint (i.e., don't print a newline).
    38 #define TC(...) do {       \
    39     _T("%s: ", __func__);  \
    40     _T(__VA_ARGS__);       \
    41 } while (0)
    42 
    43 // Show a trace point.
    44 #  define T(...) do {  \
    45     TC(__VA_ARGS__); \
    46     _T("\n");          \
    47 } while(0)
    48 
    49 // Verbosely displays errors.
    50 #  define DUMP_STATUS(__de_sq_status, __de_pep_status, ...) do { \
    51     TC(__VA_ARGS__);                                            \
    52     _T(": ");                                                   \
    53     if (__de_sq_status) {                                       \
    54         _T("Sequoia: %s => ", pgp_status_to_string(__de_sq_status));   \
    55     }                                                           \
    56     _T("%s\n", pEp_status_to_string(__de_pep_status));          \
    57 } while(0)
    58 
    59 #  define DUMP_ERR(__de_err, __de_status, ...) do {             \
    60     TC(__VA_ARGS__);                                            \
    61     _T(": ");                                                   \
    62     if (__de_err) {                                             \
    63         _T("Sequoia: %s => ", pgp_error_to_string(__de_err));   \
    64         pgp_error_free(__de_err);                               \
    65     }                                                           \
    66     _T("%s\n", pEp_status_to_string(__de_status));              \
    67 } while(0)
    68 
    69 // If __ec_status is an error, then disable the error, set 'status' to
    70 // it, and jump to 'out'.
    71 #define ERROR_OUT(__e_err, __ec_status, ...) do {                   \
    72     PEP_STATUS ___ec_status = (__ec_status);                        \
    73     if ((___ec_status) != PEP_STATUS_OK) {                          \
    74         DUMP_ERR((__e_err), (___ec_status), ##__VA_ARGS__);         \
    75         status = (___ec_status);                                    \
    76         goto out;                                                   \
    77     }                                                               \
    78 } while(0)
    79 
    80 int email_cmp(void *cookie, int a_len, const void *a, int b_len, const void *b)
    81 {
    82     pgp_packet_t a_userid = pgp_user_id_from_raw (a, a_len);
    83     pgp_packet_t b_userid = pgp_user_id_from_raw (b, b_len);
    84 
    85     T("(%.*s, %.*s)", a_len, a, b_len, b);
    86 
    87     char *a_address = NULL;
    88     pgp_user_id_address_normalized(NULL, a_userid, &a_address);
    89 
    90     char *b_address = NULL;
    91     pgp_user_id_address_normalized(NULL, b_userid, &b_address);
    92 
    93     pgp_packet_free(a_userid);
    94     pgp_packet_free(b_userid);
    95 
    96     // return an integer that is negative, zero, or positive if the
    97     // first string is less than, equal to, or greater than the
    98     // second, respectively.
    99     int result;
   100     if (!a_address && !b_address)
   101         result = 0;
   102     else if (!a_address)
   103         result = -1;
   104     else if (!b_address)
   105         result = 1;
   106     else
   107         result = strcmp(a_address, b_address);
   108 
   109     if (true) {
   110         T("'%s' %s '%s'",
   111           a_address,
   112           result == 0 ? "==" : result < 0 ? "<" : ">",
   113           b_address);
   114     }
   115 
   116     free(a_address);
   117     free(b_address);
   118 
   119     return result;
   120 }
   121 
   122 PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
   123 {
   124     PEP_STATUS status = PEP_STATUS_OK;
   125 
   126     // Create the home directory.
   127     char *home_env = getenv("HOME");
   128     if (!home_env)
   129         ERROR_OUT(NULL, PEP_INIT_GPGME_INIT_FAILED, "HOME unset");
   130 
   131     // Create the DB and initialize it.
   132     size_t path_size = strlen(home_env)+13+1;
   133     char *path = (char *) calloc(1, path_size);
   134     assert(path);
   135     if (!path)
   136         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   137 
   138     int r = snprintf(path, path_size, "%s/.pEp_keys.db", home_env);
   139     assert(r >= 0 && r < path_size);
   140     if (r < 0)
   141         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "snprintf");
   142 
   143     int sqlite_result;
   144     sqlite_result = sqlite3_open_v2(path,
   145                                     &session->key_db,
   146                                     SQLITE_OPEN_READWRITE
   147                                     | SQLITE_OPEN_CREATE
   148                                     | SQLITE_OPEN_FULLMUTEX
   149                                     | SQLITE_OPEN_PRIVATECACHE,
   150                                     NULL);
   151     free(path);
   152     if (sqlite_result != SQLITE_OK)
   153         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   154                   "opening keys DB: %s", sqlite3_errmsg(session->key_db));
   155 
   156     sqlite_result = sqlite3_exec(session->key_db,
   157                                  "PRAGMA secure_delete=true;\n"
   158                                  "PRAGMA foreign_keys=true;\n"
   159                                  "PRAGMA locking_mode=NORMAL;\n"
   160                                  "PRAGMA journal_mode=WAL;\n",
   161                                  NULL, NULL, NULL);
   162     if (sqlite_result != SQLITE_OK)
   163         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   164                   "setting pragmas: %s", sqlite3_errmsg(session->key_db));
   165 
   166     sqlite3_busy_timeout(session->key_db, BUSY_WAIT_TIME);
   167 
   168     sqlite_result =
   169         sqlite3_create_collation(session->key_db,
   170                                 "EMAIL",
   171                                 SQLITE_UTF8,
   172                                 /* pArg (cookie) */ NULL,
   173                                 email_cmp);
   174     if (sqlite_result != SQLITE_OK)
   175         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   176                   "registering EMAIL collation function: %s",
   177                   sqlite3_errmsg(session->key_db));
   178 
   179     sqlite_result = sqlite3_exec(session->key_db,
   180                                  "CREATE TABLE IF NOT EXISTS keys (\n"
   181                                  "   primary_key TEXT UNIQUE PRIMARY KEY,\n"
   182                                  "   secret BOOLEAN,\n"
   183                                  "   tpk BLOB\n"
   184                                  ");\n"
   185                                  "CREATE INDEX IF NOT EXISTS keys_index\n"
   186                                  "  ON keys (primary_key, secret)\n",
   187                                  NULL, NULL, NULL);
   188     if (sqlite_result != SQLITE_OK)
   189         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   190                   "creating keys table: %s",
   191                   sqlite3_errmsg(session->key_db));
   192 
   193     sqlite_result = sqlite3_exec(session->key_db,
   194                                  "CREATE TABLE IF NOT EXISTS subkeys (\n"
   195                                  "   subkey TEXT NOT NULL,\n"
   196                                  "   primary_key TEXT NOT NULL,\n"
   197                                  "   UNIQUE(subkey, primary_key),\n"
   198                                  "   FOREIGN KEY (primary_key)\n"
   199                                  "       REFERENCES keys(primary_key)\n"
   200                                  "     ON DELETE CASCADE\n"
   201                                  ");\n"
   202                                  "CREATE INDEX IF NOT EXISTS subkeys_index\n"
   203                                  "  ON subkeys (subkey, primary_key)\n",
   204                                  NULL, NULL, NULL);
   205     if (sqlite_result != SQLITE_OK)
   206         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   207                   "creating subkeys table: %s",
   208                   sqlite3_errmsg(session->key_db));
   209 
   210     sqlite_result = sqlite3_exec(session->key_db,
   211                                  "CREATE TABLE IF NOT EXISTS userids (\n"
   212                                  "   userid TEXT NOT NULL COLLATE EMAIL,\n"
   213                                  "   primary_key TEXT NOT NULL,\n"
   214                                  "   UNIQUE(userid, primary_key),\n"
   215                                  "   FOREIGN KEY (primary_key)\n"
   216                                  "       REFERENCES keys(primary_key)\n"
   217                                  "     ON DELETE CASCADE\n"
   218                                  ");\n"
   219                                  "CREATE INDEX IF NOT EXISTS userids_index\n"
   220                                  "  ON userids (userid COLLATE EMAIL, primary_key)\n",
   221                                  NULL, NULL, NULL);
   222     if (sqlite_result != SQLITE_OK)
   223         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   224                   "creating userids table: %s",
   225                   sqlite3_errmsg(session->key_db));
   226 
   227     sqlite_result
   228         = sqlite3_prepare_v2(session->key_db, "begin transaction",
   229                              -1, &session->sq_sql.begin_transaction, NULL);
   230     assert(sqlite_result == SQLITE_OK);
   231 
   232     sqlite_result
   233         = sqlite3_prepare_v2(session->key_db, "commit transaction",
   234                              -1, &session->sq_sql.commit_transaction, NULL);
   235     assert(sqlite_result == SQLITE_OK);
   236 
   237     sqlite_result
   238         = sqlite3_prepare_v2(session->key_db, "rollback transaction",
   239                              -1, &session->sq_sql.rollback_transaction, NULL);
   240     assert(sqlite_result == SQLITE_OK);
   241 
   242     sqlite_result
   243         = sqlite3_prepare_v2(session->key_db,
   244                              "SELECT tpk, secret FROM keys"
   245                              " WHERE primary_key == ?",
   246                              -1, &session->sq_sql.tpk_find, NULL);
   247     assert(sqlite_result == SQLITE_OK);
   248 
   249     sqlite_result
   250         = sqlite3_prepare_v2(session->key_db,
   251                              "SELECT tpk, secret FROM keys"
   252                              " WHERE primary_key == ? and secret == 1",
   253                              -1, &session->sq_sql.tsk_find, NULL);
   254     assert(sqlite_result == SQLITE_OK);
   255 
   256     sqlite_result
   257         = sqlite3_prepare_v2(session->key_db,
   258                              "SELECT tpk, secret FROM subkeys"
   259                              " LEFT JOIN keys"
   260                              "  ON subkeys.primary_key == keys.primary_key"
   261                              " WHERE subkey == ?",
   262                              -1, &session->sq_sql.tpk_find_by_keyid, NULL);
   263     assert(sqlite_result == SQLITE_OK);
   264 
   265     sqlite_result
   266         = sqlite3_prepare_v2(session->key_db,
   267                              "SELECT tpk, secret FROM subkeys"
   268                              " LEFT JOIN keys"
   269                              "  ON subkeys.primary_key == keys.primary_key"
   270                              " WHERE subkey == ?",
   271                              -1, &session->sq_sql.tpk_find_by_keyid, NULL);
   272     assert(sqlite_result == SQLITE_OK);
   273 
   274     sqlite_result
   275         = sqlite3_prepare_v2(session->key_db,
   276                              "SELECT tpk, secret FROM subkeys"
   277                              " LEFT JOIN keys"
   278                              "  ON subkeys.primary_key == keys.primary_key"
   279                              " WHERE subkey == ? and keys.secret == 1",
   280                              -1, &session->sq_sql.tsk_find_by_keyid, NULL);
   281     assert(sqlite_result == SQLITE_OK);
   282 
   283     sqlite_result
   284         = sqlite3_prepare_v2(session->key_db,
   285                              "SELECT tpk, secret FROM userids"
   286                              " LEFT JOIN keys"
   287                              "  ON userids.primary_key == keys.primary_key"
   288                              " WHERE userid == ?",
   289                              -1, &session->sq_sql.tpk_find_by_email, NULL);
   290     assert(sqlite_result == SQLITE_OK);
   291 
   292     sqlite_result
   293         = sqlite3_prepare_v2(session->key_db,
   294                              "SELECT tpk, secret FROM userids"
   295                              " LEFT JOIN keys"
   296                              "  ON userids.primary_key == keys.primary_key"
   297                              " WHERE userid == ? and keys.secret == 1",
   298                              -1, &session->sq_sql.tsk_find_by_email, NULL);
   299     assert(sqlite_result == SQLITE_OK);
   300 
   301     sqlite_result
   302         = sqlite3_prepare_v2(session->key_db,
   303                              "select tpk, secret from keys",
   304                              -1, &session->sq_sql.tpk_all, NULL);
   305     assert(sqlite_result == SQLITE_OK);
   306 
   307     sqlite_result
   308         = sqlite3_prepare_v2(session->key_db,
   309                              "select tpk, secret from keys where secret = 1",
   310                              -1, &session->sq_sql.tsk_all, NULL);
   311     assert(sqlite_result == SQLITE_OK);
   312 
   313     sqlite_result
   314         = sqlite3_prepare_v2(session->key_db,
   315                              "INSERT OR REPLACE INTO keys"
   316                              "   (primary_key, secret, tpk)"
   317                              " VALUES (?, ?, ?)",
   318                              -1, &session->sq_sql.tpk_save_insert_primary, NULL);
   319     assert(sqlite_result == SQLITE_OK);
   320 
   321     sqlite_result
   322         = sqlite3_prepare_v2(session->key_db,
   323                              "INSERT OR REPLACE INTO subkeys"
   324                              "   (subkey, primary_key)"
   325                              " VALUES (?, ?)",
   326                              -1, &session->sq_sql.tpk_save_insert_subkeys, NULL);
   327     assert(sqlite_result == SQLITE_OK);
   328 
   329     sqlite_result
   330         = sqlite3_prepare_v2(session->key_db,
   331                              "INSERT OR REPLACE INTO userids"
   332                              "   (userid, primary_key)"
   333                              " VALUES (?, ?)",
   334                              -1, &session->sq_sql.tpk_save_insert_userids, NULL);
   335     assert(sqlite_result == SQLITE_OK);
   336 
   337  out:
   338     if (status != PEP_STATUS_OK)
   339         pgp_release(session, in_first);
   340     return status;
   341 }
   342 
   343 void pgp_release(PEP_SESSION session, bool out_last)
   344 {
   345     sqlite3_stmt **stmts = (sqlite3_stmt **) &session->sq_sql;
   346     for (int i = 0; i < sizeof(session->sq_sql) / sizeof(*stmts); i ++)
   347         if (stmts[i]) {
   348             sqlite3_finalize(stmts[i]);
   349             stmts[i] = NULL;
   350         }
   351 
   352     if (session->key_db) {
   353         int result = sqlite3_close_v2(session->key_db);
   354         if (result != 0)
   355             DUMP_ERR(NULL, PEP_UNKNOWN_ERROR,
   356                      "Closing key DB: sqlite3_close_v2: %s",
   357                      sqlite3_errstr(result));
   358         session->key_db = NULL;
   359     }
   360 }
   361 
   362 /* commented out to omit compiler warning about unused function
   363 
   364 // Ensures that a fingerprint is in canonical form.  A canonical
   365 // fingerprint doesn't contain any white space.
   366 //
   367 // This function does *not* consume fpr.
   368 static char *pgp_fingerprint_canonicalize(const char *) __attribute__((nonnull));
   369 static char *pgp_fingerprint_canonicalize(const char *fpr)
   370 {
   371     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   372     char *fpr_canonicalized = pgp_fingerprint_to_hex(pgp_fpr);
   373     pgp_fingerprint_free(pgp_fpr);
   374 
   375     return fpr_canonicalized;
   376 }
   377 
   378 */
   379 
   380 // Splits an OpenPGP user id into its name and email components.  A
   381 // user id looks like:
   382 //
   383 //   Name (comment) <email>
   384 //
   385 // This function takes ownership of user_id!!!
   386 //
   387 // namep and emailp may be NULL if they are not required.
   388 static void user_id_split(char *, char **, char **) __attribute__((nonnull(1)));
   389 static void user_id_split(char *user_id, char **namep, char **emailp)
   390 {
   391     if (namep)
   392         *namep = NULL;
   393     if (emailp)
   394         *emailp = NULL;
   395 
   396     char *email = strchr(user_id, '<');
   397     if (email) {
   398         // NUL terminate the string here so that user_id now points at
   399         // most to: "Name (comment)"
   400         *email = 0;
   401 
   402         if (emailp && email[1]) {
   403             email = email + 1;
   404             char *end = strchr(email, '>');
   405             if (end) {
   406                 *end = 0;
   407                 *emailp = strdup(email);
   408             }
   409         }
   410     }
   411 
   412     if (!namep)
   413         return;
   414 
   415     char *comment = strchr(user_id, '(');
   416     if (comment)
   417         *comment = 0;
   418 
   419     // Kill any trailing white space.
   420     for (size_t l = strlen(user_id); l > 0 && user_id[l - 1] == ' '; l --)
   421         user_id[l - 1] = 0;
   422 
   423     // Kill any leading whitespace.
   424     char *start = user_id;
   425     while (*start == ' ')
   426         start ++;
   427     if (start[0])
   428         *namep = strdup(start);
   429 
   430     free(user_id);
   431 }
   432 
   433 // step statement and load the tpk and secret.
   434 static PEP_STATUS key_load(PEP_SESSION, sqlite3_stmt *, pgp_tpk_t *, int *)
   435     __attribute__((nonnull(1, 2)));
   436 static PEP_STATUS key_load(PEP_SESSION session, sqlite3_stmt *stmt,
   437                            pgp_tpk_t *tpkp, int *secretp)
   438 {
   439     PEP_STATUS status = PEP_STATUS_OK;
   440     int sqlite_result = sqlite3_step(stmt);
   441     switch (sqlite_result) {
   442     case SQLITE_ROW:
   443         if (tpkp) {
   444             int data_len = sqlite3_column_bytes(stmt, 0);
   445             const void *data = sqlite3_column_blob(stmt, 0);
   446 
   447             pgp_error_t err = NULL;
   448             *tpkp = pgp_tpk_from_bytes(&err, data, data_len);
   449             if (!*tpkp)
   450                 ERROR_OUT(err, PEP_GET_KEY_FAILED, "parsing TPK");
   451         }
   452 
   453         if (secretp)
   454             *secretp = sqlite3_column_int(stmt, 1);
   455 
   456         break;
   457     case SQLITE_DONE:
   458         // Got nothing.
   459         status = PEP_KEY_NOT_FOUND;
   460         break;
   461     default:
   462         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   463                   "stepping: %s", sqlite3_errmsg(session->key_db));
   464     }
   465 
   466  out:
   467     T(" -> %s", pEp_status_to_string(status));
   468     return status;
   469 }
   470 
   471 // step statement until exhausted and load the tpks.
   472 static PEP_STATUS key_loadn(PEP_SESSION, sqlite3_stmt *, pgp_tpk_t **, int *)
   473     __attribute__((nonnull));
   474 static PEP_STATUS key_loadn(PEP_SESSION session, sqlite3_stmt *stmt,
   475                             pgp_tpk_t **tpksp, int *tpks_countp)
   476 {
   477     PEP_STATUS status = PEP_STATUS_OK;
   478     int tpks_count = 0;
   479     int tpks_capacity = 8;
   480     pgp_tpk_t *tpks = calloc(tpks_capacity, sizeof(pgp_tpk_t));
   481     if (!tpks)
   482         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   483 
   484     for (;;) {
   485         pgp_tpk_t tpk = NULL;
   486         status = key_load(session, stmt, &tpk, NULL);
   487         if (status == PEP_KEY_NOT_FOUND) {
   488             status = PEP_STATUS_OK;
   489             break;
   490         }
   491         ERROR_OUT(NULL, status, "loading TPK");
   492 
   493         if (tpks_count == tpks_capacity) {
   494             tpks_capacity *= 2;
   495             tpks = realloc(tpks, sizeof(tpks[0]) * tpks_capacity);
   496             if (!tpks)
   497                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "tpks");
   498         }
   499         tpks[tpks_count ++] = tpk;
   500     }
   501 
   502  out:
   503     if (status != PEP_STATUS_OK) {
   504         for (int i = 0; i < tpks_count; i ++)
   505             pgp_tpk_free(tpks[i]);
   506         free(tpks);
   507     } else {
   508         *tpksp = tpks;
   509         *tpks_countp = tpks_count;
   510     }
   511 
   512     T(" -> %s (%d tpks)", pEp_status_to_string(status), *tpks_countp);
   513     return status;
   514 }
   515 
   516 // Returns the TPK identified by the provided fingerprint.
   517 //
   518 // This function only matches on the primary key!
   519 static PEP_STATUS tpk_find(PEP_SESSION, pgp_fingerprint_t, int, pgp_tpk_t *, int *)
   520     __attribute__((nonnull(1, 2)));
   521 static PEP_STATUS tpk_find(PEP_SESSION session,
   522                            pgp_fingerprint_t fpr, int private_only,
   523                            pgp_tpk_t *tpk, int *secret)
   524 {
   525     PEP_STATUS status = PEP_STATUS_OK;
   526     char *fpr_str = pgp_fingerprint_to_hex(fpr);
   527 
   528     T("(%s, %d)", fpr_str, private_only);
   529 
   530     sqlite3_stmt *stmt
   531         = private_only ? session->sq_sql.tsk_find : session->sq_sql.tpk_find;
   532     sqlite3_bind_text(stmt, 1, fpr_str, -1, SQLITE_STATIC);
   533 
   534     status = key_load(session, stmt, tpk, secret);
   535     ERROR_OUT(NULL, status, "Looking up %s", fpr_str);
   536 
   537  out:
   538     sqlite3_reset(stmt);
   539     T("(%s, %d) -> %s", fpr_str, private_only, pEp_status_to_string(status));
   540     free(fpr_str);
   541     return status;
   542 }
   543 
   544 // Returns the TPK identified by the provided keyid.
   545 //
   546 // This function matches on both primary keys and subkeys!
   547 //
   548 // Note: There can be multiple TPKs for a given keyid.  This can
   549 // occur, because an encryption subkey can be bound to multiple TPKs.
   550 // Also, it is possible to collide key ids.  If there are multiple key
   551 // ids for a given key, this just returns one of them.
   552 //
   553 // If private_only is set, this will only consider TPKs with some
   554 // secret key material.
   555 static PEP_STATUS tpk_find_by_keyid_hex(PEP_SESSION, const char *, int, pgp_tpk_t *, int *)
   556   __attribute__((nonnull(1, 2)));
   557 static PEP_STATUS tpk_find_by_keyid_hex(
   558         PEP_SESSION session, const char *keyid_hex, int private_only,
   559         pgp_tpk_t *tpkp, int *secretp)
   560 {
   561     PEP_STATUS status = PEP_STATUS_OK;
   562     T("(%s, %d)", keyid_hex, private_only);
   563 
   564     sqlite3_stmt *stmt
   565         = private_only ? session->sq_sql.tsk_find_by_keyid : session->sq_sql.tpk_find_by_keyid;
   566     sqlite3_bind_text(stmt, 1, keyid_hex, -1, SQLITE_STATIC);
   567 
   568     status = key_load(session, stmt, tpkp, secretp);
   569     ERROR_OUT(NULL, status, "Looking up %s", keyid_hex);
   570 
   571  out:
   572     sqlite3_reset(stmt);
   573     T("(%s, %d) -> %s", keyid_hex, private_only, pEp_status_to_string(status));
   574     return status;
   575 }
   576 
   577 // See tpk_find_by_keyid_hex.
   578 PEP_STATUS tpk_find_by_keyid(PEP_SESSION, pgp_keyid_t, int, pgp_tpk_t *, int *)
   579     __attribute__((nonnull(1, 2)));
   580 PEP_STATUS tpk_find_by_keyid(PEP_SESSION session,
   581                              pgp_keyid_t keyid, int private_only,
   582                              pgp_tpk_t *tpkp, int *secretp)
   583 {
   584     char *keyid_hex = pgp_keyid_to_hex(keyid);
   585     if (! keyid_hex)
   586         return PEP_OUT_OF_MEMORY;
   587     PEP_STATUS status
   588         = tpk_find_by_keyid_hex(session, keyid_hex, private_only, tpkp, secretp);
   589     free(keyid_hex);
   590     return status;
   591 }
   592 
   593 // See tpk_find_by_keyid_hex.
   594 static PEP_STATUS tpk_find_by_fpr(PEP_SESSION, pgp_fingerprint_t, int,
   595                                   pgp_tpk_t *, int *)
   596     __attribute__((nonnull(1, 2)));
   597 static PEP_STATUS tpk_find_by_fpr(
   598     PEP_SESSION session, pgp_fingerprint_t fpr, int private_only,
   599     pgp_tpk_t *tpkp, int *secretp)
   600 {
   601     pgp_keyid_t keyid = pgp_fingerprint_to_keyid(fpr);
   602     if (! keyid)
   603         return PEP_OUT_OF_MEMORY;
   604     PEP_STATUS status
   605         = tpk_find_by_keyid(session, keyid, private_only, tpkp, secretp);
   606     pgp_keyid_free(keyid);
   607     return status;
   608 }
   609 
   610 // See tpk_find_by_keyid_hex.
   611 static PEP_STATUS tpk_find_by_fpr_hex(PEP_SESSION, const char *, int, pgp_tpk_t *, int *secret)
   612     __attribute__((nonnull(1, 2)));
   613 static PEP_STATUS tpk_find_by_fpr_hex(
   614     PEP_SESSION session, const char *fpr, int private_only,
   615     pgp_tpk_t *tpkp, int *secretp)
   616 {
   617     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   618     if (! pgp_fpr)
   619         return PEP_OUT_OF_MEMORY;
   620     PEP_STATUS status
   621         = tpk_find_by_fpr(session, pgp_fpr, private_only, tpkp, secretp);
   622     pgp_fingerprint_free(pgp_fpr);
   623     return status;
   624 }
   625 
   626 // Returns all known TPKs.
   627 static PEP_STATUS tpk_all(PEP_SESSION, int, pgp_tpk_t **, int *) __attribute__((nonnull));
   628 static PEP_STATUS tpk_all(PEP_SESSION session, int private_only,
   629                           pgp_tpk_t **tpksp, int *tpks_countp) {
   630     PEP_STATUS status = PEP_STATUS_OK;
   631     sqlite3_stmt *stmt = private_only ? session->sq_sql.tsk_all : session->sq_sql.tpk_all;
   632     status = key_loadn(session, stmt, tpksp, tpks_countp);
   633     ERROR_OUT(NULL, status, "loading TPKs");
   634  out:
   635     sqlite3_reset(stmt);
   636     return status;
   637 }
   638 
   639 // Returns keys that have a user id that matches the specified pattern.
   640 //
   641 // The keys returned must be freed using pgp_tpk_free.
   642 static PEP_STATUS tpk_find_by_email(PEP_SESSION, const char *, int, pgp_tpk_t **, int *)
   643     __attribute__((nonnull));
   644 static PEP_STATUS tpk_find_by_email(PEP_SESSION session,
   645                                     const char *pattern, int private_only,
   646                                     pgp_tpk_t **tpksp, int *countp)
   647 {
   648     PEP_STATUS status = PEP_STATUS_OK;
   649     T("(%s)", pattern);
   650 
   651     sqlite3_stmt *stmt
   652         = private_only ? session->sq_sql.tsk_find_by_email : session->sq_sql.tpk_find_by_email;
   653     sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_STATIC);
   654 
   655     status = key_loadn(session, stmt, tpksp, countp);
   656     ERROR_OUT(NULL, status, "Searching for '%s'", pattern);
   657 
   658  out:
   659     sqlite3_reset(stmt);
   660     T("(%s) -> %s (%d results)", pattern, pEp_status_to_string(status), *countp);
   661     return status;
   662 }
   663 
   664 
   665 // Saves the specified TPK.
   666 //
   667 // This function takes ownership of TPK.
   668 static PEP_STATUS tpk_save(PEP_SESSION, pgp_tpk_t, identity_list **)
   669     __attribute__((nonnull(1, 2)));
   670 static PEP_STATUS tpk_save(PEP_SESSION session, pgp_tpk_t tpk,
   671                            identity_list **private_idents)
   672 {
   673     PEP_STATUS status = PEP_STATUS_OK;
   674     pgp_error_t err = NULL;
   675     pgp_fingerprint_t pgp_fpr = NULL;
   676     char *fpr = NULL;
   677     void *tsk_buffer = NULL;
   678     size_t tsk_buffer_len = 0;
   679     int tried_commit = 0;
   680     pgp_tpk_key_iter_t key_iter = NULL;
   681     pgp_user_id_binding_iter_t user_id_iter = NULL;
   682 
   683     sqlite3_stmt *stmt = session->sq_sql.begin_transaction;
   684     int sqlite_result = sqlite3_step(stmt);
   685     sqlite3_reset(stmt);
   686     if (sqlite_result != SQLITE_DONE)
   687         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   688                   "begin transaction failed: %s",
   689                   sqlite3_errmsg(session->key_db));
   690 
   691     pgp_fpr = pgp_tpk_fingerprint(tpk);
   692     fpr = pgp_fingerprint_to_hex(pgp_fpr);
   693     T("(%s, private_idents: %s)", fpr, private_idents ? "yes" : "no");
   694 
   695     // Merge any existing data into TPK.
   696     pgp_tpk_t current = NULL;
   697     status = tpk_find(session, pgp_fpr, false, &current, NULL);
   698     if (status == PEP_KEY_NOT_FOUND)
   699         status = PEP_STATUS_OK;
   700     else
   701         ERROR_OUT(NULL, status, "Looking up %s", fpr);
   702     if (current) {
   703         tpk = pgp_tpk_merge(&err, tpk, current);
   704         if (! tpk)
   705             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Merging TPKs");
   706     }
   707 
   708     int is_tsk = pgp_tpk_is_tsk(tpk);
   709 
   710     // Serialize it.
   711     pgp_writer_t writer = pgp_writer_alloc(&tsk_buffer, &tsk_buffer_len);
   712     if (! writer)
   713         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   714 
   715     pgp_status_t pgp_status;
   716     pgp_tsk_t tsk = pgp_tpk_as_tsk(tpk);
   717     pgp_status = pgp_tsk_serialize(&err, tsk, writer);
   718     pgp_tsk_free(tsk);
   719     //pgp_writer_free(writer);
   720     if (pgp_status != 0)
   721         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Serializing TPK");
   722 
   723 
   724     // Insert the TSK into the DB.
   725     stmt = session->sq_sql.tpk_save_insert_primary;
   726     sqlite3_bind_text(stmt, 1, fpr, -1, SQLITE_STATIC);
   727     sqlite3_bind_int(stmt, 2, is_tsk);
   728     sqlite3_bind_blob(stmt, 3, tsk_buffer, tsk_buffer_len, SQLITE_STATIC);
   729 
   730     sqlite_result = sqlite3_step(stmt);
   731     sqlite3_reset(stmt);
   732     if (sqlite_result != SQLITE_DONE)
   733         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   734                   "Saving TPK: %s", sqlite3_errmsg(session->key_db));
   735 
   736     // Insert the "subkeys" (the primary key and the subkeys).
   737     stmt = session->sq_sql.tpk_save_insert_subkeys;
   738     // This inserts all of the keys in the TPK, i.e., revoked and
   739     // expired keys, which is what we want.
   740     key_iter = pgp_tpk_key_iter_all(tpk);
   741     pgp_key_t key;
   742     while ((key = pgp_tpk_key_iter_next(key_iter, NULL, NULL))) {
   743         pgp_keyid_t keyid = pgp_key_keyid(key);
   744         char *keyid_hex = pgp_keyid_to_hex(keyid);
   745         sqlite3_bind_text(stmt, 1, keyid_hex, -1, SQLITE_STATIC);
   746         sqlite3_bind_text(stmt, 2, fpr, -1, SQLITE_STATIC);
   747 
   748         sqlite_result = sqlite3_step(stmt);
   749         sqlite3_reset(stmt);
   750         free(keyid_hex);
   751         pgp_keyid_free(keyid);
   752         if (sqlite_result != SQLITE_DONE) {
   753             pgp_tpk_key_iter_free(key_iter);
   754             ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   755                       "Updating subkeys: %s", sqlite3_errmsg(session->key_db));
   756         }
   757     }
   758     pgp_tpk_key_iter_free(key_iter);
   759     key_iter = NULL;
   760 
   761     // Insert the "userids".
   762     stmt = session->sq_sql.tpk_save_insert_userids;
   763     user_id_iter = pgp_tpk_user_id_binding_iter(tpk);
   764     pgp_user_id_binding_t binding;
   765     int first = 1;
   766     while ((binding = pgp_user_id_binding_iter_next(user_id_iter))) {
   767         char *user_id = pgp_user_id_binding_user_id(binding);
   768         if (!user_id || !*user_id)
   769             continue;
   770 
   771         // Ignore bindings with a self-revocation certificate, but no
   772         // self-signature.
   773         if (!pgp_user_id_binding_selfsig(binding)) {
   774             free(user_id);
   775             continue;
   776         }
   777 
   778         char *name, *email;
   779         user_id_split(user_id, &name, &email); /* user_id is comsumed.  */
   780         // XXX: Correctly clean up name and email on error...
   781 
   782         if (email) {
   783             T("  userid: %s", email);
   784 
   785             sqlite3_bind_text(stmt, 1, email, -1, SQLITE_STATIC);
   786             sqlite3_bind_text(stmt, 2, fpr, -1, SQLITE_STATIC);
   787 
   788             sqlite_result = sqlite3_step(stmt);
   789             sqlite3_reset(stmt);
   790 
   791             if (sqlite_result != SQLITE_DONE) {
   792                 pgp_user_id_binding_iter_free(user_id_iter);
   793                 free(name);
   794                 ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   795                           "Updating userids: %s", sqlite3_errmsg(session->key_db));
   796             }
   797         }
   798 
   799         if (first && private_idents && is_tsk) {
   800             first = 0;
   801 
   802             // Create an identity for the primary user id.
   803             pEp_identity *ident = new_identity(email, fpr, NULL, name);
   804             if (ident == NULL)
   805                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_identity");
   806 
   807             *private_idents = identity_list_add(*private_idents, ident);
   808             if (*private_idents == NULL)
   809                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "identity_list_add");
   810         }
   811         free(email);
   812         free(name);
   813 
   814     }
   815     pgp_user_id_binding_iter_free(user_id_iter);
   816     user_id_iter = NULL;
   817 
   818  out:
   819     // Prevent ERROR_OUT from causing an infinite loop.
   820     if (! tried_commit) {
   821         tried_commit = 1;
   822         stmt = status == PEP_STATUS_OK
   823             ? session->sq_sql.commit_transaction
   824             : session->sq_sql.rollback_transaction;
   825         int sqlite_result = sqlite3_step(stmt);
   826         sqlite3_reset(stmt);
   827         if (sqlite_result != SQLITE_DONE)
   828             ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   829                       status == PEP_STATUS_OK
   830                       ? "commit failed: %s" : "rollback failed: %s",
   831                       sqlite3_errmsg(session->key_db));
   832     }
   833 
   834     T("(%s) -> %s", fpr, pEp_status_to_string(status));
   835 
   836     if (user_id_iter)
   837         pgp_user_id_binding_iter_free(user_id_iter);
   838     if (key_iter)
   839         pgp_tpk_key_iter_free(key_iter);
   840     if (stmt)
   841       sqlite3_reset(stmt);
   842     free(tsk_buffer);
   843     if (tpk)
   844         pgp_tpk_free(tpk);
   845     free(fpr);
   846     pgp_fingerprint_free(pgp_fpr);
   847 
   848     return status;
   849 }
   850 
   851 struct decrypt_cookie {
   852     PEP_SESSION session;
   853     int get_secret_keys_called;
   854     stringlist_t *recipient_keylist;
   855     stringlist_t *signer_keylist;
   856     int good_checksums;
   857     int missing_keys;
   858     int bad_checksums;
   859     int decrypted;
   860 };
   861 
   862 static pgp_status_t
   863 get_public_keys_cb(void *cookie_raw,
   864                    pgp_keyid_t *keyids, size_t keyids_len,
   865                    pgp_tpk_t **tpks, size_t *tpk_len,
   866                    void (**our_free)(void *))
   867 {
   868     struct decrypt_cookie *cookie = cookie_raw;
   869     PEP_SESSION session = cookie->session;
   870 
   871     *tpks = calloc(keyids_len, sizeof(*tpks));
   872     if (!*tpks)
   873         return PGP_STATUS_UNKNOWN_ERROR;
   874     *our_free = free;
   875 
   876     int i, j;
   877     j = 0;
   878     for (i = 0; i < keyids_len; i ++) {
   879         pgp_tpk_t tpk = NULL;
   880         PEP_STATUS status
   881             = tpk_find_by_keyid(session, keyids[i], false, &tpk, NULL);
   882         if (status == PEP_STATUS_OK)
   883             (*tpks)[j ++] = tpk;
   884     }
   885     *tpk_len = j;
   886     return PGP_STATUS_SUCCESS;
   887 }
   888 
   889 static pgp_status_t
   890 decrypt_cb(void *cookie_opaque,
   891            pgp_pkesk_t *pkesks, size_t pkesk_count,
   892            pgp_skesk_t *skesks, size_t skesk_count,
   893            pgp_decryptor_do_decrypt_cb_t *decrypt,
   894            void *decrypt_cookie,
   895            pgp_fingerprint_t *identity_out)
   896 {
   897     pgp_error_t err = NULL;
   898     struct decrypt_cookie *cookie = cookie_opaque;
   899     PEP_SESSION session = cookie->session;
   900     pgp_tpk_t *tsks = NULL;
   901     int tsks_count = 0;
   902     int wildcards = 0;
   903 
   904     if (cookie->get_secret_keys_called)
   905         // Prevent iterations, which isn't needed since we don't
   906         // support SKESKs.
   907         return PGP_STATUS_UNKNOWN_ERROR;
   908     cookie->get_secret_keys_called = 1;
   909 
   910     T("%zd PKESKs", pkesk_count);
   911 
   912     for (int i = 0; i < pkesk_count; i ++) {
   913         pgp_pkesk_t pkesk = pkesks[i];
   914         pgp_keyid_t keyid = pgp_pkesk_recipient(pkesk); /* Reference. */
   915         char *keyid_str = pgp_keyid_to_hex(keyid);
   916         pgp_tpk_key_iter_t key_iter = NULL;
   917         pgp_session_key_t sk = NULL;
   918 
   919         T("Considering PKESK for %s", keyid_str);
   920 
   921         if (strcmp(keyid_str, "0000000000000000") == 0) {
   922             // Initially ignore wildcards.
   923             wildcards = 1;
   924             goto eol;
   925         }
   926 
   927         // Collect the recipients.  Note: we must return the primary
   928         // key's fingerprint.
   929         pgp_tpk_t tpk = NULL;
   930         int is_tsk = 0;
   931         if (tpk_find_by_keyid(session, keyid, false, &tpk, &is_tsk) != PEP_STATUS_OK)
   932             goto eol;
   933 
   934         pgp_fingerprint_t fp = pgp_tpk_fingerprint(tpk);
   935         char *fp_string = pgp_fingerprint_to_hex(fp);
   936         stringlist_add_unique(cookie->recipient_keylist, fp_string);
   937         free(fp_string);
   938         pgp_fingerprint_free(fp);
   939 
   940         if (cookie->decrypted)
   941             goto eol;
   942 
   943         // See if we have the secret key.
   944         assert(is_tsk == pgp_tpk_is_tsk(tpk));
   945         if (! is_tsk)
   946             goto eol;
   947 
   948         key_iter = pgp_tpk_key_iter_all(tpk);
   949         pgp_key_t key;
   950         while ((key = pgp_tpk_key_iter_next(key_iter, NULL, NULL))) {
   951             pgp_keyid_t this_keyid = pgp_key_keyid(key);
   952             char *this_keyid_hex = pgp_keyid_to_hex(this_keyid);
   953             pgp_keyid_free(this_keyid);
   954 
   955             int match = strcmp(keyid_str, this_keyid_hex) == 0;
   956             free(this_keyid_hex);
   957             if (match)
   958                 break;
   959         }
   960 
   961         if (key == NULL) {
   962             assert(!"Inconsistent DB: key doesn't contain a subkey with keyid!");
   963             goto eol;
   964         }
   965 
   966         uint8_t algo;
   967         uint8_t session_key[1024];
   968         size_t session_key_len = sizeof(session_key);
   969         if (pgp_pkesk_decrypt(&err, pkesk, key, &algo,
   970                               session_key, &session_key_len) != 0) {
   971             DUMP_ERR(err, PEP_UNKNOWN_ERROR, "pgp_pkesk_decrypt");
   972             goto eol;
   973         }
   974 
   975         sk = pgp_session_key_from_bytes (session_key, session_key_len);
   976         pgp_status_t status;
   977         if ((status = decrypt (decrypt_cookie, algo, sk))) {
   978             DUMP_STATUS(status, PEP_UNKNOWN_ERROR, "decrypt_cb");
   979             goto eol;
   980         }
   981 
   982         T("Decrypted PKESK for %s", keyid_str);
   983 
   984         *identity_out = pgp_tpk_fingerprint(tpk);
   985         cookie->decrypted = 1;
   986 
   987     eol:
   988         if (sk)
   989             pgp_session_key_free (sk);
   990         free(keyid_str);
   991         if (key_iter)
   992             pgp_tpk_key_iter_free(key_iter);
   993         if (tpk)
   994             pgp_tpk_free(tpk);
   995     }
   996 
   997     // Consider wildcard recipients.
   998     if (wildcards) for (int i = 0; i < pkesk_count && !cookie->decrypted; i ++) {
   999         pgp_pkesk_t pkesk = pkesks[i];
  1000         pgp_keyid_t keyid = pgp_pkesk_recipient(pkesk); /* Reference. */
  1001         char *keyid_str = pgp_keyid_to_hex(keyid);
  1002         pgp_tpk_key_iter_t key_iter = NULL;
  1003         pgp_session_key_t sk = NULL;
  1004 
  1005         if (strcmp(keyid_str, "0000000000000000") != 0)
  1006             goto eol2;
  1007 
  1008         if (!tsks) {
  1009             if (tpk_all(session, true, &tsks, &tsks_count) != PEP_STATUS_OK) {
  1010                 DUMP_ERR(NULL, PEP_UNKNOWN_ERROR, "Getting all tsks");
  1011             }
  1012         }
  1013 
  1014         for (int j = 0; j < tsks_count; j ++) {
  1015             pgp_tpk_t tsk = tsks[j];
  1016 
  1017             key_iter = pgp_tpk_key_iter_all(tsk);
  1018             pgp_key_t key;
  1019             pgp_signature_t selfsig;
  1020             while ((key = pgp_tpk_key_iter_next(key_iter, &selfsig, NULL))) {
  1021                 if (! (pgp_signature_can_encrypt_at_rest(selfsig)
  1022                        || pgp_signature_can_encrypt_for_transport(selfsig)))
  1023                     continue;
  1024 
  1025                 fprintf(stderr, "key: %s\n", pgp_key_debug(key));
  1026 
  1027                 // Note: for decryption to appear to succeed, we must
  1028                 // get a valid algorithm (8 of 256 values) and a
  1029                 // 16-bit checksum must match.  Thus, we have about a
  1030                 // 1 in 2**21 chance of having a false positive here.
  1031                 uint8_t algo;
  1032                 uint8_t session_key[1024];
  1033                 size_t session_key_len = sizeof(session_key);
  1034                 if (pgp_pkesk_decrypt(&err, pkesk, key,
  1035                                       &algo, session_key, &session_key_len)) {
  1036                     pgp_error_free(err);
  1037                     err = NULL;
  1038                     continue;
  1039                 }
  1040 
  1041                 // Add it to the recipient list.
  1042                 pgp_fingerprint_t fp = pgp_tpk_fingerprint(tsk);
  1043                 char *fp_string = pgp_fingerprint_to_hex(fp);
  1044                 T("wildcard recipient appears to be %s", fp_string);
  1045                 stringlist_add_unique(cookie->recipient_keylist, fp_string);
  1046                 free(fp_string);
  1047                 pgp_fingerprint_free(fp);
  1048 
  1049                 pgp_session_key_t sk = pgp_session_key_from_bytes (session_key,
  1050                                                                    session_key_len);
  1051                 pgp_status_t status;
  1052                 if ((status = decrypt (decrypt_cookie, algo, sk))) {
  1053                     DUMP_STATUS(status, PEP_UNKNOWN_ERROR, "decrypt_cb");
  1054                     goto eol2;
  1055                 }
  1056 
  1057                 *identity_out = pgp_tpk_fingerprint(tsk);
  1058                 cookie->decrypted = 1;
  1059 
  1060                 break;
  1061             }
  1062 
  1063             pgp_tpk_key_iter_free(key_iter);
  1064             key_iter = NULL;
  1065         }
  1066     eol2:
  1067         if (sk)
  1068             pgp_session_key_free (sk);
  1069         free(keyid_str);
  1070         if (key_iter)
  1071             pgp_tpk_key_iter_free(key_iter);
  1072     }
  1073 
  1074     if (tsks) {
  1075         for (int i = 0; i < tsks_count; i ++)
  1076             pgp_tpk_free(tsks[i]);
  1077         free(tsks);
  1078     }
  1079 
  1080     return cookie->decrypted ? PGP_STATUS_SUCCESS : PGP_STATUS_UNKNOWN_ERROR;
  1081 }
  1082 
  1083 static pgp_status_t
  1084 check_signatures_cb(void *cookie_opaque,
  1085                    pgp_verification_results_t results, size_t levels)
  1086 {
  1087     struct decrypt_cookie *cookie = cookie_opaque;
  1088     PEP_SESSION session = cookie->session;
  1089 
  1090     int level;
  1091     for (level = 0; level < levels; level ++) {
  1092         pgp_verification_result_t *vrs;
  1093         size_t vr_count;
  1094         pgp_verification_results_at_level(results, level, &vrs, &vr_count);
  1095 
  1096         int i;
  1097         for (i = 0; i < vr_count; i ++) {
  1098             pgp_tpk_t tpk = NULL;
  1099             pgp_verification_result_code_t code
  1100                 = pgp_verification_result_code(vrs[i]);
  1101 
  1102             if (code == PGP_VERIFICATION_RESULT_CODE_BAD_CHECKSUM) {
  1103                 cookie->bad_checksums ++;
  1104                 continue;
  1105             }
  1106             if (code == PGP_VERIFICATION_RESULT_CODE_MISSING_KEY) {
  1107                 // No key, nothing we can do.
  1108                 cookie->missing_keys ++;
  1109                 continue;
  1110             }
  1111 
  1112             // We need to add the fingerprint of the primary key to
  1113             // cookie->signer_keylist.
  1114             pgp_signature_t sig = pgp_verification_result_signature(vrs[i]);
  1115 
  1116             // First try looking up by the TPK using the
  1117             // IssuerFingerprint subpacket.
  1118             pgp_fingerprint_t issuer_fp = pgp_signature_issuer_fingerprint(sig);
  1119             if (issuer_fp) {
  1120                 pgp_keyid_t issuer = pgp_fingerprint_to_keyid(issuer_fp);
  1121                 if (tpk_find_by_keyid(session, issuer, false, &tpk, NULL) != PEP_STATUS_OK)
  1122                     ; // Soft error.  Ignore.
  1123                 pgp_keyid_free(issuer);
  1124                 pgp_fingerprint_free(issuer_fp);
  1125             }
  1126 
  1127             // If that is not available, try using the Issuer subpacket.
  1128             if (!tpk) {
  1129                 pgp_keyid_t issuer = pgp_signature_issuer(sig);
  1130                 if (issuer) {
  1131                     if (tpk_find_by_keyid(session, issuer, false, &tpk, NULL) != PEP_STATUS_OK)
  1132                         ; // Soft error.  Ignore.
  1133                 }
  1134                 pgp_keyid_free(issuer);
  1135             }
  1136 
  1137             if (tpk) {
  1138                 // Ok, we have a TPK.
  1139                 pgp_fingerprint_t fp = pgp_tpk_fingerprint(tpk);
  1140                 char *fp_str = pgp_fingerprint_to_hex(fp);
  1141                 stringlist_add_unique(cookie->signer_keylist, fp_str);
  1142 
  1143                 // XXX: Check that the TPK and the key used to make
  1144                 // the signature and the signature itself are alive
  1145                 // and not revoked.  Revoked =>
  1146                 // PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH; Expired key
  1147                 // or sig => PEP_DECRYPTED.
  1148                 cookie->good_checksums ++;
  1149 
  1150                 free(fp_str);
  1151                 pgp_fingerprint_free(fp);
  1152                 pgp_tpk_free(tpk);
  1153             } else {
  1154                 // If we get
  1155                 // PGP_VERIFICATION_RESULT_CODE_GOOD_CHECKSUM, then the
  1156                 // TPK should be available.  But, another process
  1157                 // could have deleted the key from the store in the
  1158                 // mean time, so be tolerant.
  1159                 cookie->missing_keys ++;
  1160             }
  1161         }
  1162     }
  1163 
  1164     return PGP_STATUS_SUCCESS;
  1165 }
  1166 
  1167 PEP_STATUS pgp_decrypt_and_verify(
  1168     PEP_SESSION session, const char *ctext, size_t csize,
  1169     const char *dsigtext, size_t dsigsize,
  1170     char **ptext, size_t *psize, stringlist_t **keylist,
  1171     char** filename_ptr)
  1172 {
  1173     PEP_STATUS status = PEP_STATUS_OK;
  1174     struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, };
  1175     pgp_reader_t reader = NULL;
  1176     pgp_writer_t writer = NULL;
  1177     pgp_reader_t decryptor = NULL;
  1178     *ptext = NULL;
  1179     *psize = 0;
  1180 
  1181     // XXX: We don't yet handle detached signatures over encrypted
  1182     // messages.
  1183     assert(!dsigtext);
  1184 
  1185     cookie.recipient_keylist = new_stringlist(NULL);
  1186     if (!cookie.recipient_keylist)
  1187         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "recipient_keylist");
  1188 
  1189     cookie.signer_keylist = new_stringlist(NULL);
  1190     if (!cookie.signer_keylist)
  1191         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "signer_keylist");
  1192 
  1193     reader = pgp_reader_from_bytes((const uint8_t *) ctext, csize);
  1194     if (! reader)
  1195         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating reader");
  1196 
  1197     writer = pgp_writer_alloc((void **) ptext, psize);
  1198     if (! writer)
  1199         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "Creating writer");
  1200 
  1201     pgp_error_t err = NULL;
  1202     decryptor = pgp_decryptor_new(&err, reader,
  1203                                   get_public_keys_cb, decrypt_cb,
  1204                                   check_signatures_cb, &cookie, 0);
  1205     if (! decryptor)
  1206         ERROR_OUT(err, PEP_DECRYPT_NO_KEY, "pgp_decryptor_new");
  1207 
  1208     // Copy 128 MB at a time.
  1209     ssize_t nread;
  1210     while ((nread = pgp_reader_copy (&err, decryptor, writer,
  1211                                      128 * 1024 * 1024) > 0))
  1212         ;
  1213     if (nread < 0)
  1214         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "pgp_reader_read");
  1215 
  1216     // Add a terminating NUL for naive users
  1217     pgp_writer_write(&err, writer, (const uint8_t *) &""[0], 1);
  1218 
  1219     if (! cookie.decrypted)
  1220         ERROR_OUT(err, PEP_DECRYPT_NO_KEY, "Decryption failed");
  1221 
  1222     if (! cookie.signer_keylist) {
  1223         cookie.signer_keylist = new_stringlist("");
  1224         if (! cookie.signer_keylist)
  1225             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "cookie.signer_keylist");
  1226     }
  1227     if (!cookie.signer_keylist->value)
  1228         stringlist_add(cookie.signer_keylist, "");
  1229 
  1230     *keylist = cookie.signer_keylist;
  1231     stringlist_append(*keylist, cookie.recipient_keylist);
  1232 
  1233  out:
  1234     if (status == PEP_STATUS_OK) {
  1235         if (cookie.bad_checksums) {
  1236             // If there are any bad signatures, fail.
  1237             status = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  1238         } else if (cookie.good_checksums) {
  1239             // If there is at least one signature that we can verify,
  1240             // succeed.
  1241             status = PEP_DECRYPTED_AND_VERIFIED;
  1242         } else {
  1243             // We couldn't verify any signatures (possibly because we
  1244             // don't have the keys).
  1245             status = PEP_DECRYPTED;
  1246         }
  1247     } else {
  1248         free_stringlist(cookie.recipient_keylist);
  1249         free_stringlist(cookie.signer_keylist);
  1250         free(*ptext);
  1251     }
  1252 
  1253     if (reader)
  1254         pgp_reader_free(reader);
  1255     if (decryptor)
  1256         pgp_reader_free(decryptor);
  1257     if (writer)
  1258         pgp_writer_free(writer);
  1259 
  1260     T("-> %s", pEp_status_to_string(status));
  1261     return status;
  1262 }
  1263 
  1264 PEP_STATUS pgp_verify_text(
  1265     PEP_SESSION session, const char *text, size_t size,
  1266     const char *signature, size_t sig_size, stringlist_t **keylist)
  1267 {
  1268     PEP_STATUS status = PEP_STATUS_OK;
  1269     pgp_error_t err = NULL;
  1270     struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, };
  1271     pgp_reader_t reader = NULL;
  1272     pgp_reader_t dsig_reader = NULL;
  1273     pgp_reader_t verifier = NULL;
  1274 
  1275     if (size == 0 || sig_size == 0)
  1276         return PEP_DECRYPT_WRONG_FORMAT;
  1277 
  1278     cookie.recipient_keylist = new_stringlist(NULL);
  1279     if (!cookie.recipient_keylist)
  1280         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1281 
  1282     cookie.signer_keylist = new_stringlist(NULL);
  1283     if (!cookie.signer_keylist)
  1284         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1285 
  1286     reader = pgp_reader_from_bytes((const uint8_t *) text, size);
  1287     if (! reader)
  1288         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating reader");
  1289 
  1290     dsig_reader = NULL;
  1291     if (signature) {
  1292         dsig_reader = pgp_reader_from_bytes((uint8_t *) signature, sig_size);
  1293         if (! dsig_reader)
  1294             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating signature reader");
  1295     }
  1296 
  1297     if (dsig_reader)
  1298         verifier = pgp_detached_verifier_new(&err, dsig_reader, reader,
  1299                                              get_public_keys_cb,
  1300                                              check_signatures_cb,
  1301                                              &cookie, 0);
  1302     else
  1303         verifier = pgp_verifier_new(&err, reader,
  1304                                     get_public_keys_cb,
  1305                                     check_signatures_cb,
  1306                                     &cookie, 0);
  1307     if (! verifier)
  1308         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Creating verifier");
  1309     if (pgp_reader_discard(&err, verifier) < 0)
  1310         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "verifier");
  1311 
  1312     if (! cookie.signer_keylist) {
  1313         cookie.signer_keylist = new_stringlist("");
  1314         if (! cookie.signer_keylist)
  1315             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "cookie.signer_keylist");
  1316     }
  1317     if (!cookie.signer_keylist->value)
  1318         stringlist_add(cookie.signer_keylist, "");
  1319 
  1320     *keylist = cookie.signer_keylist;
  1321     stringlist_append(*keylist, cookie.recipient_keylist);
  1322 
  1323  out:
  1324     if (status == PEP_STATUS_OK) {
  1325         if (cookie.bad_checksums) {
  1326             // If there are any bad signatures, fail.
  1327             status = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  1328         } else if (cookie.good_checksums) {
  1329             // If there is at least one signature that we can verify,
  1330             // succeed.
  1331             status = PEP_VERIFIED;
  1332         } else {
  1333             // We couldn't verify any signatures (possibly because we
  1334             // don't have the keys).
  1335             status = PEP_UNENCRYPTED;
  1336         }
  1337     } else {
  1338         free_stringlist(cookie.recipient_keylist);
  1339         free_stringlist(cookie.signer_keylist);
  1340     }
  1341 
  1342     if (verifier)
  1343         pgp_reader_free(verifier);
  1344     if (reader)
  1345         pgp_reader_free(reader);
  1346     if (dsig_reader)
  1347         pgp_reader_free(dsig_reader);
  1348 
  1349     T("-> %s", pEp_status_to_string(status));
  1350     return status;
  1351 }
  1352 
  1353 
  1354 PEP_STATUS pgp_sign_only(
  1355     PEP_SESSION session, const char* fpr, const char *ptext,
  1356     size_t psize, char **stext, size_t *ssize)
  1357 {
  1358     assert(session);
  1359     assert(fpr && fpr[0]);
  1360     assert(ptext);
  1361     assert(psize);
  1362     assert(stext);
  1363     assert(ssize);
  1364     *stext = NULL;
  1365     *ssize = 0;
  1366 
  1367     PEP_STATUS status = PEP_STATUS_OK;
  1368     pgp_error_t err = NULL;
  1369     pgp_tpk_t signer_tpk = NULL;
  1370     pgp_tpk_key_iter_t iter = NULL;
  1371     pgp_key_pair_t signing_keypair = NULL;
  1372     pgp_signer_t signer = NULL;
  1373     pgp_writer_stack_t ws = NULL;
  1374 
  1375     status = tpk_find_by_fpr_hex(session, fpr, true, &signer_tpk, NULL);
  1376     ERROR_OUT(NULL, status, "Looking up key '%s'", fpr);
  1377 
  1378     iter = pgp_tpk_key_iter_valid(signer_tpk);
  1379     pgp_tpk_key_iter_signing_capable (iter);
  1380     pgp_tpk_key_iter_unencrypted_secret (iter, true);
  1381 
  1382     // If there are multiple signing capable subkeys, we just take
  1383     // the first one, whichever one that happens to be.
  1384     pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
  1385     if (! key)
  1386         ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  1387                    "%s has no signing capable key", fpr);
  1388 
  1389     signing_keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  1390     if (! signing_keypair)
  1391         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  1392 
  1393     signer = pgp_key_pair_as_signer (signing_keypair);
  1394     if (! signer)
  1395         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  1396 
  1397 
  1398     pgp_writer_t writer = pgp_writer_alloc((void **) stext, ssize);
  1399     writer = pgp_armor_writer_new(&err, writer,
  1400                                   PGP_ARMOR_KIND_MESSAGE, NULL, 0);
  1401     if (!writer)
  1402         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up armor writer");
  1403 
  1404     ws = pgp_writer_stack_message(writer);
  1405 
  1406     ws = pgp_signer_new_detached(&err, ws, &signer, 1, 0);
  1407     if (!ws)
  1408         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
  1409 
  1410     pgp_status_t write_status =
  1411         pgp_writer_stack_write_all (&err, ws,
  1412                                     (uint8_t *) ptext, psize);
  1413     if (write_status != 0)
  1414         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
  1415 
  1416     // Add a terminating NUL for naive users
  1417     void *t = realloc(*stext, *ssize + 1);
  1418     if (! t)
  1419         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1420     *stext = t;
  1421     (*stext)[*ssize] = 0;
  1422 
  1423  out:
  1424     if (ws) {
  1425         pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
  1426         ws = NULL;
  1427         if (pgp_status != 0)
  1428             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
  1429     }
  1430 
  1431     if (signer)
  1432         pgp_signer_free (signer);
  1433     if (signing_keypair)
  1434         pgp_key_pair_free (signing_keypair);
  1435     if (iter)
  1436         pgp_tpk_key_iter_free (iter);
  1437     if (signer_tpk)
  1438         pgp_tpk_free(signer_tpk);
  1439 
  1440     T("(%s)-> %s", fpr, pEp_status_to_string(status));
  1441     return status;
  1442 }
  1443 
  1444 static PEP_STATUS pgp_encrypt_sign_optional(
  1445     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  1446     size_t psize, char **ctext, size_t *csize, bool sign)
  1447 {
  1448     PEP_STATUS status = PEP_STATUS_OK;
  1449     pgp_error_t err = NULL;
  1450     int keys_count = 0;
  1451     pgp_tpk_t *keys = NULL;
  1452     pgp_tpk_t signer_tpk = NULL;
  1453     pgp_writer_stack_t ws = NULL;
  1454     pgp_tpk_key_iter_t iter = NULL;
  1455     pgp_key_pair_t signing_keypair = NULL;
  1456     pgp_signer_t signer = NULL;
  1457 
  1458     assert(session);
  1459     assert(keylist);
  1460     assert(ptext);
  1461     assert(psize);
  1462     assert(ctext);
  1463     assert(csize);
  1464 
  1465     *ctext = NULL;
  1466     *csize = 0;
  1467 
  1468     keys = calloc(stringlist_length(keylist), sizeof(*keys));
  1469     if (keys == NULL)
  1470         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1471 
  1472     // Get the keys for the recipients.
  1473     const stringlist_t *_keylist;
  1474     for (_keylist = keylist; _keylist != NULL; _keylist = _keylist->next) {
  1475         assert(_keylist->value);
  1476         pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(_keylist->value);
  1477         status = tpk_find_by_fpr(session, pgp_fpr, false, &keys[keys_count ++], NULL);
  1478         pgp_fingerprint_free(pgp_fpr);
  1479         ERROR_OUT(NULL, status, "Looking up key for recipient '%s'", _keylist->value);
  1480     }
  1481 
  1482     if (sign) {
  1483         // The first key in the keylist is the signer.
  1484         status = tpk_find_by_fpr_hex(session, keylist->value, true, &signer_tpk, NULL);
  1485         ERROR_OUT(NULL, status, "Looking up key for signing '%s'", keylist->value);
  1486     }
  1487 
  1488     pgp_writer_t writer = pgp_writer_alloc((void **) ctext, csize);
  1489     writer = pgp_armor_writer_new(&err, writer,
  1490                                   PGP_ARMOR_KIND_MESSAGE, NULL, 0);
  1491     if (!writer)
  1492         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up armor writer");
  1493 
  1494     ws = pgp_writer_stack_message(writer);
  1495     ws = pgp_encryptor_new (&err, ws,
  1496                             NULL, 0, keys, keys_count,
  1497                             PGP_ENCRYPTION_MODE_FOR_TRANSPORT, 0);
  1498     if (!ws)
  1499         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up encryptor");
  1500 
  1501     if (sign) {
  1502         iter = pgp_tpk_key_iter_valid(signer_tpk);
  1503         pgp_tpk_key_iter_signing_capable (iter);
  1504         pgp_tpk_key_iter_unencrypted_secret (iter, true);
  1505 
  1506         // If there are multiple signing capable subkeys, we just take
  1507         // the first one, whichever one that happens to be.
  1508         pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
  1509         if (! key)
  1510             ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  1511                        "%s has no signing capable key", keylist->value);
  1512 
  1513         signing_keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  1514         if (! signing_keypair)
  1515             ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  1516 
  1517         signer = pgp_key_pair_as_signer (signing_keypair);
  1518         if (! signer)
  1519             ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  1520 
  1521         ws = pgp_signer_new(&err, ws, &signer, 1, 0);
  1522         if (!ws)
  1523             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
  1524     }
  1525 
  1526     ws = pgp_literal_writer_new (&err, ws);
  1527     if (!ws)
  1528         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up literal writer");
  1529 
  1530     pgp_status_t write_status =
  1531         pgp_writer_stack_write_all (&err, ws,
  1532                                     (uint8_t *) ptext, psize);
  1533     if (write_status != 0)
  1534         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
  1535 
  1536     // Add a terminating NUL for naive users
  1537     void *t = realloc(*ctext, *csize + 1);
  1538     if (! t)
  1539         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1540     *ctext = t;
  1541     (*ctext)[*csize] = 0;
  1542 
  1543  out:
  1544     if (ws) {
  1545         pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
  1546         ws = NULL;
  1547         if (pgp_status != 0)
  1548             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
  1549     }
  1550 
  1551     if (signer)
  1552         pgp_signer_free (signer);
  1553     if (signing_keypair)
  1554         pgp_key_pair_free (signing_keypair);
  1555     if (iter)
  1556         pgp_tpk_key_iter_free (iter);
  1557     if (signer_tpk)
  1558         pgp_tpk_free(signer_tpk);
  1559 
  1560     for (int i = 0; i < keys_count; i ++)
  1561         pgp_tpk_free(keys[i]);
  1562     free(keys);
  1563 
  1564     T("-> %s", pEp_status_to_string(status));
  1565     return status;
  1566 }
  1567 
  1568 PEP_STATUS pgp_encrypt_only(
  1569     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  1570     size_t psize, char **ctext, size_t *csize)
  1571 {
  1572     return pgp_encrypt_sign_optional(session, keylist, ptext,
  1573         psize, ctext, csize, false);
  1574 }
  1575 
  1576 PEP_STATUS pgp_encrypt_and_sign(
  1577     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  1578     size_t psize, char **ctext, size_t *csize)
  1579 {
  1580     return pgp_encrypt_sign_optional(session, keylist, ptext,
  1581         psize, ctext, csize, true);
  1582 }
  1583 
  1584 
  1585 PEP_STATUS pgp_generate_keypair(PEP_SESSION session, pEp_identity *identity)
  1586 {
  1587     PEP_STATUS status = PEP_STATUS_OK;
  1588     pgp_error_t err = NULL;
  1589     char *userid = NULL;
  1590     pgp_tpk_t tpk = NULL;
  1591     pgp_fingerprint_t pgp_fpr = NULL;
  1592     char *fpr = NULL;
  1593 
  1594     assert(session);
  1595     assert(identity);
  1596     assert(identity->address);
  1597     assert(identity->fpr == NULL || identity->fpr[0] == 0);
  1598     assert(identity->username);
  1599 
  1600     size_t userid_size = strlen(identity->username)+strlen(identity->address)+3+1;
  1601     userid = (char *) calloc(1, userid_size);
  1602     assert(userid);
  1603     if (!userid)
  1604         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1605 
  1606     int r = snprintf(userid, userid_size, "%s <%s>", identity->username, identity->address);
  1607     assert(r >= 0 && r < userid_size);
  1608     if (r < 0)
  1609         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "snprintf");
  1610 
  1611     T("(%s)", userid);
  1612 
  1613     // Generate a key.
  1614     pgp_tpk_builder_t tpkb = pgp_tpk_builder_general_purpose
  1615         (PGP_TPK_CIPHER_SUITE_RSA3K, userid);
  1616     pgp_signature_t rev;
  1617     if (pgp_tpk_builder_generate(&err, tpkb, &tpk, &rev))
  1618         ERROR_OUT(err, PEP_CANNOT_CREATE_KEY, "Generating a key pair");
  1619 
  1620     // XXX: We should return this.
  1621     pgp_signature_free(rev);
  1622 
  1623     // Get the fingerprint.
  1624     pgp_fpr = pgp_tpk_fingerprint(tpk);
  1625     fpr = pgp_fingerprint_to_hex(pgp_fpr);
  1626 
  1627     status = tpk_save(session, tpk, NULL);
  1628     tpk = NULL;
  1629     if (status != 0)
  1630         ERROR_OUT(NULL, PEP_CANNOT_CREATE_KEY, "saving TSK");
  1631 
  1632     free(identity->fpr);
  1633     identity->fpr = fpr;
  1634     fpr = NULL;
  1635 
  1636  out:
  1637     if (pgp_fpr)
  1638         pgp_fingerprint_free(pgp_fpr);
  1639     free(fpr);
  1640     if (tpk)
  1641         pgp_tpk_free(tpk);
  1642     free(userid);
  1643 
  1644     T("-> %s", pEp_status_to_string(status));
  1645     return status;
  1646 }
  1647 
  1648 #define SQL_DELETE "DELETE FROM keys WHERE primary_key = '%s' ;"
  1649 static const char *sql_delete = SQL_DELETE;
  1650 static const size_t sql_delete_size = sizeof(SQL_DELETE);
  1651 
  1652 // FIXME: this is deleting the key from the index but not the key data
  1653 
  1654 PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr)
  1655 {
  1656     assert(session && fpr && fpr[0]);
  1657     if (!(session && fpr && fpr[0]))
  1658         return PEP_ILLEGAL_VALUE;
  1659 
  1660     size_t sql_size = sql_delete_size + strlen(fpr);
  1661     char *sql = calloc(1, sql_size);
  1662     assert(sql);
  1663     if (!sql)
  1664         return PEP_OUT_OF_MEMORY;
  1665 
  1666     int r = snprintf(sql, sql_size, sql_delete, fpr);
  1667     assert(r > 0 && r < sql_size);
  1668     if (r < 0)
  1669         return PEP_UNKNOWN_ERROR;
  1670 
  1671     int sqlite_result = sqlite3_exec(session->key_db, sql, NULL, NULL, NULL);
  1672     assert(sqlite_result == SQLITE_OK);
  1673     if (sqlite_result != SQLITE_OK)
  1674         return PEP_CANNOT_DELETE_KEY;
  1675 
  1676     sqlite_result = sqlite3_changes(session->key_db);
  1677     assert(sqlite_result >= 0 && sqlite_result < 2);
  1678     if (sqlite_result < 1)
  1679         return PEP_KEY_NOT_FOUND;
  1680 
  1681     return PEP_STATUS_OK;
  1682 }
  1683 
  1684 // XXX: This needs to handle not only TPKs, but also keyrings and
  1685 // revocation certificates.  Right now, we only import a single TPK
  1686 // and ignore everything else.
  1687 PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data,
  1688                               size_t size, identity_list **private_idents)
  1689 {
  1690     PEP_STATUS status = PEP_STATUS_OK;
  1691     pgp_error_t err;
  1692 
  1693     if (private_idents)
  1694         *private_idents = NULL;
  1695 
  1696     T("parsing %zd bytes", size);
  1697 
  1698     pgp_packet_parser_result_t ppr
  1699         = pgp_packet_parser_from_bytes(&err, (uint8_t *) key_data, size);
  1700     if (! ppr)
  1701         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Creating packet parser");
  1702 
  1703     pgp_tag_t tag = pgp_packet_parser_result_tag(ppr);
  1704     switch (tag) {
  1705     case PGP_TAG_SIGNATURE:
  1706         // XXX: Implement me.
  1707         // assert(!"Have possible revocation certificate!");
  1708 		ERROR_OUT(NULL, PEP_NO_KEY_IMPORTED, "Implement me: Have possible revocation certificate!");
  1709         break;
  1710 
  1711     case PGP_TAG_PUBLIC_KEY:
  1712     case PGP_TAG_SECRET_KEY: {
  1713         pgp_tpk_t tpk = pgp_tpk_from_packet_parser(&err, ppr);
  1714         if (! tpk)
  1715             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "parsing key data");
  1716 
  1717         // If private_idents is not NULL and there is any private key
  1718         // material, it will be saved.
  1719         status = tpk_save(session, tpk, private_idents);
  1720         if (status == PEP_STATUS_OK)
  1721             status = PEP_KEY_IMPORTED;
  1722         ERROR_OUT(NULL, status, "saving TPK");
  1723         break;
  1724     }
  1725     default:
  1726         ERROR_OUT(NULL, PEP_NO_KEY_IMPORTED,
  1727                   "Can't import %s", pgp_tag_to_string(tag));
  1728         break;
  1729     }
  1730 
  1731  out:
  1732     T("-> %s", pEp_status_to_string(status));
  1733     return status;
  1734 }
  1735 
  1736 PEP_STATUS pgp_export_keydata(
  1737         PEP_SESSION session, const char *fpr, char **key_data, size_t *size,
  1738         bool secret)
  1739 {
  1740     PEP_STATUS status = PEP_STATUS_OK;
  1741     pgp_error_t err = NULL;
  1742     pgp_tpk_t tpk = NULL;
  1743     pgp_writer_t armor_writer = NULL;
  1744 
  1745     assert(session);
  1746     assert(fpr);
  1747     assert(key_data);
  1748     assert(*key_data == NULL);
  1749     assert(size);
  1750 
  1751     *size = 0;
  1752 
  1753     T("(%s, %s)", fpr, secret ? "secret" : "public");
  1754 
  1755     // If the caller asks for a secret key and we only have a
  1756     // public key, then we return an error.
  1757     status = tpk_find_by_fpr_hex(session, fpr, secret, &tpk, NULL);
  1758     ERROR_OUT(NULL, status, "Looking up TSK for %s", fpr);
  1759 
  1760     pgp_writer_t memory_writer = pgp_writer_alloc((void **) key_data, size);
  1761     if (! memory_writer)
  1762         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "creating memory writer");
  1763     armor_writer = pgp_armor_writer_new(&err, memory_writer,
  1764                                         PGP_ARMOR_KIND_PUBLICKEY, NULL, 0);
  1765     if (! armor_writer) {
  1766         pgp_writer_free(memory_writer);
  1767         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "creating armored writer");
  1768     }
  1769 
  1770     if (secret) {
  1771         pgp_tsk_t tsk = pgp_tpk_as_tsk(tpk);
  1772         if (pgp_tsk_serialize(&err, tsk, armor_writer))
  1773             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "serializing TSK");
  1774         pgp_tsk_free(tsk);
  1775     } else {
  1776         if (pgp_tpk_serialize(&err, tpk, armor_writer))
  1777             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "serializing TPK");
  1778     }
  1779 
  1780  out:
  1781     if (armor_writer)
  1782         pgp_writer_free(armor_writer);
  1783 
  1784     if (tpk)
  1785         pgp_tpk_free(tpk);
  1786 
  1787     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  1788     return status;
  1789 }
  1790 
  1791 char* _undot_address(const char* address) {
  1792     if (!address)
  1793         return NULL;
  1794 
  1795     int addr_len = strlen(address);
  1796     const char* at = strstr(address, "@");
  1797 
  1798     if (!at)
  1799         at = address + addr_len;
  1800 
  1801     char* retval = calloc(1, addr_len + 1);
  1802 
  1803     const char* addr_curr = address;
  1804     char* retval_curr = retval;
  1805 
  1806     while (addr_curr < at) {
  1807         if (*addr_curr == '.') {
  1808             addr_curr++;
  1809             continue;
  1810         }
  1811         *retval_curr = *addr_curr;
  1812         retval_curr++;
  1813         addr_curr++;
  1814     }
  1815     if (*addr_curr == '@')
  1816         strcat(retval_curr, addr_curr);
  1817 
  1818     return retval;
  1819 }
  1820 
  1821 static stringpair_list_t *add_key(PEP_SESSION session,
  1822                                   stringpair_list_t *keyinfo_list,
  1823                                   stringlist_t* keylist,
  1824                                   pgp_tpk_t tpk, pgp_fingerprint_t fpr) {
  1825     bool revoked = false;
  1826     // Don't add revoked keys to the keyinfo_list.
  1827     if (keyinfo_list) {
  1828         pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
  1829         pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
  1830         pgp_revocation_status_free(rs);
  1831         if (rsv == PGP_REVOCATION_STATUS_REVOKED)
  1832             revoked = true;
  1833     }
  1834 
  1835     if (revoked && ! keylist)
  1836         return keyinfo_list;
  1837 
  1838     int dealloc_fpr = 0;
  1839     if (!fpr) {
  1840         dealloc_fpr = 1;
  1841         fpr = pgp_tpk_fingerprint(tpk);
  1842     }
  1843     char *fpr_str = pgp_fingerprint_to_hex(fpr);
  1844 
  1845     if (!revoked && keyinfo_list) {
  1846         char *user_id = pgp_tpk_primary_user_id(tpk);
  1847         if (user_id)
  1848             keyinfo_list = stringpair_list_add(keyinfo_list,
  1849                                                new_stringpair(fpr_str, user_id));
  1850         free(user_id);
  1851     }
  1852 
  1853     if (keylist)
  1854         keylist = stringlist_add(keylist, fpr_str);
  1855 
  1856     free(fpr_str);
  1857     if (dealloc_fpr)
  1858         pgp_fingerprint_free(fpr);
  1859 
  1860     return keyinfo_list;
  1861 }
  1862 
  1863 static PEP_STATUS list_keys(PEP_SESSION session,
  1864                             const char* pattern, int private_only,
  1865                             stringpair_list_t** keyinfo_list, stringlist_t** keylist)
  1866 {
  1867     PEP_STATUS status = PEP_STATUS_OK;
  1868     pgp_tpk_t tpk = NULL;
  1869     pgp_fingerprint_t fpr = NULL;
  1870 
  1871     T("('%s', private: %d)", pattern, private_only);
  1872 
  1873     stringpair_list_t* _keyinfo_list = NULL;
  1874     if (keyinfo_list) {
  1875         _keyinfo_list = new_stringpair_list(NULL);
  1876         if (!_keyinfo_list)
  1877             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_stringpair_list");
  1878     }
  1879     stringlist_t* _keylist = NULL;
  1880     if (keylist) {
  1881         _keylist = new_stringlist(NULL);
  1882         if (!_keylist)
  1883             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_string_list");
  1884     }
  1885 
  1886     // Trim any leading space.  This also makes it easier to recognize
  1887     // a string that is only whitespace.
  1888     while (*pattern == ' ')
  1889         pattern ++;
  1890 
  1891     if (strchr(pattern, '@')) {
  1892         // Looks like a mailbox.
  1893         pgp_tpk_t *tpks = NULL;
  1894         int count = 0;
  1895         status = tpk_find_by_email(session, pattern, private_only, &tpks, &count);
  1896         ERROR_OUT(NULL, status, "Looking up '%s'", pattern);
  1897         for (int i = 0; i < count; i ++) {
  1898             add_key(session, _keyinfo_list, _keylist, tpks[i], NULL);
  1899             pgp_tpk_free(tpks[i]);
  1900         }
  1901         free(tpks);
  1902 
  1903         if (count == 0) {
  1904             // If match failed, check to see if we've got a dotted
  1905             // address in the pattern.  If so, try again without dots.
  1906             const char* dotpos = strstr(pattern, ".");
  1907             const char* atpos = strstr(pattern, "@");
  1908             if (dotpos && atpos && (dotpos < atpos)) {
  1909                 char* undotted = _undot_address(pattern);
  1910                 if (undotted) {
  1911                     PEP_STATUS status = list_keys(session, undotted, private_only,
  1912                                                   keyinfo_list, keylist);
  1913                     free(undotted);
  1914                     return status;
  1915                 }
  1916             }
  1917         }
  1918     } else if (// Only hex characters and spaces
  1919                pattern[strspn(pattern, "0123456789aAbBcCdDeEfF ")] == 0
  1920                // And a fair amount of them.
  1921                && strlen(pattern) >= 16) {
  1922         // Fingerprint.  Note: the pep engine never looks keys up by
  1923         // keyid, so we don't handle them.
  1924         fpr = pgp_fingerprint_from_hex(pattern);
  1925         status = tpk_find_by_fpr(session, fpr, false, &tpk, NULL);
  1926         ERROR_OUT(NULL, status, "Looking up key");
  1927         add_key(session, _keyinfo_list, _keylist, tpk, fpr);
  1928     } else if (pattern[0] == 0) {
  1929         // Empty string.
  1930 
  1931         pgp_tpk_t *tpks = NULL;
  1932         int count = 0;
  1933         status = tpk_all(session, private_only, &tpks, &count);
  1934         ERROR_OUT(NULL, status, "Looking up '%s'", pattern);
  1935         for (int i = 0; i < count; i ++) {
  1936             add_key(session, _keyinfo_list, _keylist, tpks[i], NULL);
  1937             pgp_tpk_free(tpks[i]);
  1938         }
  1939         free(tpks);
  1940     } else {
  1941         T("unsupported pattern '%s'", pattern);
  1942     }
  1943 
  1944  out:
  1945     if (tpk)
  1946         pgp_tpk_free(tpk);
  1947     if (fpr)
  1948         pgp_fingerprint_free(fpr);
  1949 
  1950     if (status == PEP_KEY_NOT_FOUND)
  1951         status = PEP_STATUS_OK;
  1952 
  1953     if (status != PEP_STATUS_OK || (_keyinfo_list && !_keyinfo_list->value)) {
  1954         free_stringpair_list(_keyinfo_list);
  1955         _keyinfo_list = NULL;
  1956     }
  1957     if (keyinfo_list)
  1958         *keyinfo_list = _keyinfo_list;
  1959 
  1960     if (status != PEP_STATUS_OK || (_keylist && !_keylist->value)) {
  1961         free_stringlist(_keylist);
  1962         _keylist = NULL;
  1963     }
  1964     if (keylist)
  1965         *keylist = _keylist;
  1966 
  1967     int len = -1;
  1968     if (keylist)
  1969         len = stringlist_length(*keylist);
  1970     else if (keyinfo_list)
  1971         len = stringpair_list_length(*keyinfo_list);
  1972     T("(%s) -> %s (%d keys)", pattern, pEp_status_to_string(status), len);
  1973     return status;
  1974 }
  1975 
  1976 // pattern could be empty, an fpr, or a mailbox.
  1977 //
  1978 // keyinfo_list is a list of <fpr, openpgp userid> tuples for the
  1979 // matching keys.
  1980 //
  1981 // This function filters out revoked key, but not expired keys.
  1982 PEP_STATUS pgp_list_keyinfo(PEP_SESSION session,
  1983                             const char* pattern,
  1984                             stringpair_list_t** keyinfo_list)
  1985 {
  1986     return list_keys(session, pattern, false, keyinfo_list, NULL);
  1987 }
  1988 
  1989 PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
  1990 {
  1991     assert(!"pgp_recv_key not implemented");
  1992     return PEP_UNKNOWN_ERROR;
  1993 }
  1994 
  1995 // Unlike pgp_list_keyinfo, this function returns revoked keys.
  1996 PEP_STATUS pgp_find_keys(
  1997     PEP_SESSION session, const char *pattern, stringlist_t **keylist)
  1998 {
  1999     return list_keys(session, pattern, false, NULL, keylist);
  2000 }
  2001 
  2002 // Unlike pgp_list_keyinfo, this function returns revoked keys.
  2003 PEP_STATUS pgp_find_private_keys(
  2004     PEP_SESSION session, const char *pattern, stringlist_t **keylist)
  2005 {
  2006     return list_keys(session, pattern, true, NULL, keylist);
  2007 }
  2008 
  2009 PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
  2010 {
  2011     assert(!"pgp_send_key not implemented");
  2012     return PEP_UNKNOWN_ERROR;
  2013 }
  2014 
  2015 PEP_STATUS pgp_get_key_rating(
  2016     PEP_SESSION session, const char *fpr, PEP_comm_type *comm_type)
  2017 {
  2018     PEP_STATUS status = PEP_STATUS_OK;
  2019     pgp_tpk_t tpk = NULL;
  2020 
  2021     assert(session);
  2022     assert(fpr);
  2023     assert(comm_type);
  2024 
  2025     *comm_type = PEP_ct_unknown;
  2026 
  2027     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  2028     status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
  2029     pgp_fingerprint_free(pgp_fpr);
  2030     ERROR_OUT(NULL, status, "Looking up key: %s", fpr);
  2031 
  2032     *comm_type = PEP_ct_OpenPGP_unconfirmed;
  2033 
  2034     if (pgp_tpk_expired(tpk)) {
  2035         *comm_type = PEP_ct_key_expired;
  2036         goto out;
  2037     }
  2038 
  2039     pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
  2040     pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
  2041     pgp_revocation_status_free(rs);
  2042     if (rsv == PGP_REVOCATION_STATUS_REVOKED) {
  2043         *comm_type = PEP_ct_key_revoked;
  2044         goto out;
  2045     }
  2046 
  2047     PEP_comm_type best_enc = PEP_ct_no_encryption, best_sign = PEP_ct_no_encryption;
  2048     pgp_tpk_key_iter_t key_iter = pgp_tpk_key_iter_valid(tpk);
  2049     pgp_key_t key;
  2050     pgp_signature_t sig;
  2051     pgp_revocation_status_t rev;
  2052     while ((key = pgp_tpk_key_iter_next(key_iter, &sig, &rev))) {
  2053         if (! sig)
  2054             continue;
  2055 
  2056         PEP_comm_type curr = PEP_ct_no_encryption;
  2057 
  2058         int can_enc = pgp_signature_can_encrypt_for_transport(sig)
  2059             || pgp_signature_can_encrypt_at_rest(sig);
  2060         int can_sign = pgp_signature_can_sign(sig);
  2061 
  2062         pgp_public_key_algo_t pk_algo = pgp_key_public_key_algo(key);
  2063         if (pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_ENCRYPT_SIGN
  2064             || pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_ENCRYPT
  2065             || pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_SIGN) {
  2066             int bits = pgp_key_public_key_bits(key);
  2067             if (bits < 1024)
  2068                 curr = PEP_ct_key_too_short;
  2069             else if (bits == 1024)
  2070                 curr = PEP_ct_OpenPGP_weak_unconfirmed;
  2071             else
  2072                 curr = PEP_ct_OpenPGP_unconfirmed;
  2073         } else {
  2074             curr = PEP_ct_OpenPGP_unconfirmed;
  2075         }
  2076 
  2077         if (can_enc)
  2078             best_enc = _MAX(best_enc, curr);
  2079 
  2080         if (can_sign)
  2081             best_sign = _MAX(best_sign, curr);
  2082     }
  2083     pgp_tpk_key_iter_free(key_iter);
  2084 
  2085     if (best_enc == PEP_ct_no_encryption || best_sign == PEP_ct_no_encryption) {
  2086         *comm_type = PEP_ct_key_b0rken;
  2087         goto out;
  2088     } else {
  2089         *comm_type = _MIN(best_enc, best_sign);
  2090     }
  2091 
  2092  out:
  2093     if (tpk)
  2094         pgp_tpk_free(tpk);
  2095 
  2096     T("(%s) -> %s", fpr, pep_comm_type_to_string(*comm_type));
  2097     return status;
  2098 }
  2099 
  2100 
  2101 PEP_STATUS pgp_renew_key(
  2102     PEP_SESSION session, const char *fpr, const timestamp *ts)
  2103 {
  2104     PEP_STATUS status = PEP_STATUS_OK;
  2105     pgp_error_t err = NULL;
  2106     pgp_tpk_t tpk = NULL;
  2107     pgp_tpk_key_iter_t iter = NULL;
  2108     pgp_key_pair_t keypair = NULL;
  2109     pgp_signer_t signer = NULL;
  2110     time_t t = mktime((struct tm *) ts);
  2111 
  2112     T("(%s)", fpr);
  2113 
  2114     status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
  2115     ERROR_OUT(NULL, status, "Looking up '%s'", fpr);
  2116 
  2117     uint32_t creation_time = pgp_key_creation_time(pgp_tpk_primary(tpk));
  2118     if (creation_time > t)
  2119         // The creation time is after the expiration time!
  2120         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
  2121                   "creation time can't be after expiration time");
  2122 
  2123     uint32_t delta = t - creation_time;
  2124 
  2125 
  2126     iter = pgp_tpk_key_iter_valid(tpk);
  2127     pgp_tpk_key_iter_certification_capable (iter);
  2128     pgp_tpk_key_iter_unencrypted_secret (iter, true);
  2129 
  2130     // If there are multiple certification capable subkeys, we just
  2131     // take the first one, whichever one that happens to be.
  2132     pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
  2133     if (! key)
  2134         ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  2135                    "%s has no usable certification capable key", fpr);
  2136 
  2137     keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  2138     if (! keypair)
  2139         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  2140 
  2141     signer = pgp_key_pair_as_signer (keypair);
  2142     if (! signer)
  2143         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  2144 
  2145     tpk = pgp_tpk_set_expiry(&err, tpk, signer, delta);
  2146     if (! tpk)
  2147         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
  2148 
  2149     status = tpk_save(session, tpk, NULL);
  2150     tpk = NULL;
  2151     ERROR_OUT(NULL, status, "Saving %s", fpr);
  2152 
  2153  out:
  2154     if (signer)
  2155         pgp_signer_free (signer);
  2156     if (keypair)
  2157         pgp_key_pair_free (keypair);
  2158     if (iter)
  2159         pgp_tpk_key_iter_free (iter);
  2160     if (tpk)
  2161         pgp_tpk_free(tpk);
  2162 
  2163     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  2164     return status;
  2165 }
  2166 
  2167 PEP_STATUS pgp_revoke_key(
  2168     PEP_SESSION session, const char *fpr, const char *reason)
  2169 {
  2170     PEP_STATUS status = PEP_STATUS_OK;
  2171     pgp_error_t err = NULL;
  2172     pgp_tpk_t tpk = NULL;
  2173     pgp_tpk_key_iter_t iter = NULL;
  2174     pgp_key_pair_t keypair = NULL;
  2175     pgp_signer_t signer = NULL;
  2176 
  2177     T("(%s)", fpr);
  2178 
  2179     status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
  2180     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  2181 
  2182     iter = pgp_tpk_key_iter_valid(tpk);
  2183     pgp_tpk_key_iter_certification_capable (iter);
  2184     pgp_tpk_key_iter_unencrypted_secret (iter, true);
  2185 
  2186     // If there are multiple certification capable subkeys, we just
  2187     // take the first one, whichever one that happens to be.
  2188     pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
  2189     if (! key)
  2190         ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  2191                    "%s has no usable certification capable key", fpr);
  2192 
  2193     keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  2194     if (! keypair)
  2195         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  2196 
  2197     signer = pgp_key_pair_as_signer (keypair);
  2198     if (! signer)
  2199         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  2200 
  2201     tpk = pgp_tpk_revoke_in_place(&err, tpk, signer,
  2202                                   PGP_REASON_FOR_REVOCATION_UNSPECIFIED,
  2203                                   reason);
  2204     if (! tpk)
  2205         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
  2206 
  2207     assert(pgp_revocation_status_variant(pgp_tpk_revocation_status(tpk))
  2208            == PGP_REVOCATION_STATUS_REVOKED);
  2209 
  2210     status = tpk_save(session, tpk, NULL);
  2211     tpk = NULL;
  2212     ERROR_OUT(NULL, status, "Saving %s", fpr);
  2213 
  2214  out:
  2215     if (signer)
  2216         pgp_signer_free (signer);
  2217     if (keypair)
  2218         pgp_key_pair_free (keypair);
  2219     if (iter)
  2220         pgp_tpk_key_iter_free (iter);
  2221     if (tpk)
  2222         pgp_tpk_free(tpk);
  2223 
  2224     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  2225     return status;
  2226 }
  2227 
  2228 PEP_STATUS pgp_key_expired(PEP_SESSION session, const char *fpr,
  2229                            const time_t when, bool *expired)
  2230 {
  2231     PEP_STATUS status = PEP_STATUS_OK;
  2232     pgp_tpk_t tpk = NULL;
  2233     T("(%s)", fpr);
  2234 
  2235     assert(session);
  2236     assert(fpr);
  2237     assert(expired);
  2238 
  2239     *expired = false;
  2240 
  2241     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  2242     status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
  2243     pgp_fingerprint_free(pgp_fpr);
  2244     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  2245 
  2246     // Is the TPK live?
  2247     *expired = !pgp_tpk_alive_at(tpk, when);
  2248     if (*expired)
  2249         goto out;
  2250 
  2251     // Are there at least one certification subkey, one signing subkey
  2252     // and one encryption subkey that are live?
  2253     int can_certify = 0, can_encrypt = 0, can_sign = 0;
  2254 
  2255     pgp_tpk_key_iter_t key_iter = pgp_tpk_key_iter_valid(tpk);
  2256     pgp_key_t key;
  2257     pgp_signature_t sig;
  2258     pgp_revocation_status_t rev;
  2259     while ((key = pgp_tpk_key_iter_next(key_iter, &sig, &rev))) {
  2260         if (! sig)
  2261             continue;
  2262 
  2263         if (pgp_signature_can_encrypt_for_transport(sig)
  2264             || pgp_signature_can_encrypt_at_rest(sig))
  2265             can_encrypt = 1;
  2266         if (pgp_signature_can_sign(sig))
  2267             can_sign = 1;
  2268         if (pgp_signature_can_certify(sig))
  2269             can_certify = 1;
  2270 
  2271         if (can_encrypt && can_sign && can_certify)
  2272             break;
  2273     }
  2274     pgp_tpk_key_iter_free(key_iter);
  2275 
  2276     *expired = !(can_encrypt && can_sign && can_certify);
  2277 
  2278  out:
  2279     if (tpk)
  2280         pgp_tpk_free(tpk);
  2281     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  2282     return status;
  2283 }
  2284 
  2285 PEP_STATUS pgp_key_revoked(PEP_SESSION session, const char *fpr, bool *revoked)
  2286 {
  2287     PEP_STATUS status = PEP_STATUS_OK;
  2288     pgp_tpk_t tpk;
  2289 
  2290     T("(%s)", fpr);
  2291 
  2292     assert(session);
  2293     assert(fpr);
  2294     assert(revoked);
  2295 
  2296     *revoked = false;
  2297 
  2298     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  2299     status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
  2300     pgp_fingerprint_free(pgp_fpr);
  2301     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  2302 
  2303     pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
  2304     *revoked = pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED;
  2305     pgp_revocation_status_free (rs);
  2306     pgp_tpk_free(tpk);
  2307 
  2308  out:
  2309     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  2310     return status;
  2311 }
  2312 
  2313 PEP_STATUS pgp_key_created(PEP_SESSION session, const char *fpr, time_t *created)
  2314 {
  2315     PEP_STATUS status = PEP_STATUS_OK;
  2316     pgp_tpk_t tpk = NULL;
  2317     T("(%s)", fpr);
  2318 
  2319     *created = 0;
  2320 
  2321     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  2322     status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
  2323     pgp_fingerprint_free(pgp_fpr);
  2324     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  2325 
  2326     pgp_key_t k = pgp_tpk_primary(tpk);
  2327     *created = pgp_key_creation_time(k);
  2328     pgp_tpk_free(tpk);
  2329 
  2330  out:
  2331     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  2332     return status;
  2333 }
  2334 
  2335 PEP_STATUS pgp_binary(const char **path)
  2336 {
  2337     *path = NULL;
  2338     return PEP_STATUS_OK;
  2339 }
  2340 
  2341 PEP_STATUS pgp_contains_priv_key(PEP_SESSION session, const char *fpr,
  2342                                  bool *has_private)
  2343 {
  2344     T("(%s)", fpr);
  2345     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  2346     PEP_STATUS status = tpk_find_by_fpr(session, pgp_fpr, true, NULL, NULL);
  2347     pgp_fingerprint_free(pgp_fpr);
  2348     if (status == PEP_STATUS_OK) {
  2349         *has_private = 1;
  2350     } else if (status == PEP_KEY_NOT_FOUND) {
  2351         *has_private = 0;
  2352         status = PEP_STATUS_OK;
  2353     }
  2354     T("(%s) -> %s, %s",
  2355       fpr, *has_private ? "priv" : "pub", pEp_status_to_string(status));
  2356     return status;
  2357 }