src/pgp_sequoia.c
author Neal H. Walfield <neal@pep.foundation>
Sat, 01 Jun 2019 21:24:45 +0200
branchsync
changeset 3799 5f0990b24c15
parent 3797 657dc02b1cc3
child 3798 8c5a4548b7d1
child 3800 fb9769f33508
child 3801 8854f7fd79a8
child 3840 bfef390b48e2
permissions -rw-r--r--
Add benchmark

- By default, this is just a normal test.

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