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