src/pgp_sequoia.c
author Krista 'DarthMama' Bennett <krista@pep.foundation>
Fri, 19 Jun 2020 14:55:47 +0200
changeset 4752 d86aedba2d52
parent 4746 74d6fb83a391
child 4754 455679240e4d
permissions -rw-r--r--
status check fix and ENGINE-762 possible fix (import_key WAL checkpoint removal - it doesn't need to be there explicitly and causes issues)
     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_sequoia.h"
    11 
    12 #include <limits.h>
    13 #include <sys/stat.h>
    14 #include <sys/types.h>
    15 #include <stdlib.h>
    16 
    17 #include "wrappers.h"
    18 
    19 #define TRACING 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 #include "status_to_string.h"
    31 
    32 #  ifdef ANDROID
    33 #    include <android/log.h>
    34 #    define _T(...) do {                                                \
    35         __android_log_print(ANDROID_LOG_DEBUG, "pEpEngine-sequoia",     \
    36                             ##__VA_ARGS__);                             \
    37     } while (0)
    38 #  elif _WIN32
    39 #    define _T(...) do {                        \
    40         char str[256];                          \
    41         snprintf(str, 256, ##__VA_ARGS__);      \
    42         OutputDebugStringA(str);                \
    43         fprintf(stderr, ##__VA_ARGS__);         \
    44     } while (0)
    45 
    46 #  else
    47 #    define _T(...) do {                        \
    48         fprintf(stderr, ##__VA_ARGS__);         \
    49     } while (0)
    50 #  endif
    51 #else
    52 #  define _T(...) do { } while (0)
    53 #endif
    54 
    55 // Show the start of a tracepoint (i.e., don't print a newline).
    56 #define TC(...) do {       \
    57     _T("%s: ", __func__);  \
    58     _T(__VA_ARGS__);       \
    59 } while (0)
    60 
    61 // Show a trace point.
    62 #  define T(...) do {  \
    63     TC(__VA_ARGS__); \
    64     _T("\n");          \
    65 } while(0)
    66 
    67 // Verbosely displays errors.
    68 #  define DUMP_STATUS(__de_sq_status, __de_pep_status, ...) do { \
    69     TC(__VA_ARGS__);                                            \
    70     _T(": ");                                                   \
    71     if (__de_sq_status) {                                       \
    72         _T("Sequoia: %s => ", pgp_status_to_string(__de_sq_status));   \
    73     }                                                           \
    74     _T("%s\n", pEp_status_to_string(__de_pep_status));          \
    75 } while(0)
    76 
    77 #  define DUMP_ERR(__de_err, __de_status, ...) do {             \
    78     TC(__VA_ARGS__);                                            \
    79     _T(": ");                                                   \
    80     if (__de_err) {                                             \
    81         _T("Sequoia: %s => ", pgp_error_to_string(__de_err));   \
    82         pgp_error_free(__de_err);                               \
    83     }                                                           \
    84     _T("%s\n", pEp_status_to_string(__de_status));              \
    85 } while(0)
    86 
    87 // If __ec_status is an error, then dump the error, set 'status' to
    88 // it, and jump to 'out'.
    89 #define ERROR_OUT(__e_err, __ec_status, ...) do {                   \
    90     PEP_STATUS ___ec_status = (__ec_status);                        \
    91     if ((___ec_status) != PEP_STATUS_OK) {                          \
    92         DUMP_ERR((__e_err), (___ec_status), ##__VA_ARGS__);         \
    93         status = (___ec_status);                                    \
    94         goto out;                                                   \
    95     }                                                               \
    96 } while(0)
    97 
    98 #ifdef _PEP_SQLITE_DEBUG
    99 int sq_sql_trace_callback (unsigned trace_constant,
   100                         void* context_ptr,
   101                         void* P,
   102                         void* X) {
   103     switch (trace_constant) {
   104         case SQLITE_TRACE_STMT:
   105             fprintf(stderr, "SEQUOIA_SQL_DEBUG: STMT - ");
   106             const char* X_str = (const char*) X;
   107             if (!EMPTYSTR(X_str) && X_str[0] == '-' && X_str[1] == '-')
   108                 fprintf(stderr, "%s\n", X_str);
   109             else
   110                 fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
   111             break;
   112         case SQLITE_TRACE_ROW:
   113             fprintf(stderr, "SEQUOIA_SQL_DEBUG: ROW - ");
   114             fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
   115             break;
   116         case SQLITE_TRACE_CLOSE:
   117             fprintf(stderr, "SEQUOIA_SQL_DEBUG: CLOSE - ");
   118             break;
   119         default:
   120             break;
   121     }
   122     return 0;
   123 }
   124 #endif
   125 
   126 /* This is reallocarray taken from OpenBSD. See README.md for licensing. */
   127 /* Symbols are renamed for clashes, not to hide source. */
   128 /*
   129  * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
   130  * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
   131  */
   132 #define PEP_MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
   133 static void* _pEp_reallocarray(void *optr, size_t nmemb, size_t size)
   134 {
   135     if ((nmemb >= PEP_MUL_NO_OVERFLOW || size >= PEP_MUL_NO_OVERFLOW) &&
   136         nmemb > 0 && SIZE_MAX / nmemb < size) {
   137             errno = ENOMEM;
   138             return NULL;
   139     }
   140     return realloc(optr, size * nmemb);
   141 }
   142 
   143 
   144 PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session,
   145         PEP_CIPHER_SUITE suite)
   146 {
   147     switch (suite) {
   148         // supported cipher suites
   149         case PEP_CIPHER_SUITE_RSA2K:
   150         case PEP_CIPHER_SUITE_RSA3K:
   151         case PEP_CIPHER_SUITE_CV25519:
   152         case PEP_CIPHER_SUITE_P256:
   153         case PEP_CIPHER_SUITE_P384:
   154         case PEP_CIPHER_SUITE_P521:
   155             session->cipher_suite = suite;
   156             return PEP_STATUS_OK;
   157 
   158         case PEP_CIPHER_SUITE_DEFAULT:
   159             session->cipher_suite = PEP_CIPHER_SUITE_RSA2K;
   160             return PEP_STATUS_OK;
   161 
   162         // unsupported cipher suites
   163         default:
   164             session->cipher_suite = PEP_CIPHER_SUITE_RSA2K;
   165             return PEP_CANNOT_CONFIG;
   166     }
   167 }
   168 
   169 static pgp_cert_cipher_suite_t cipher_suite(PEP_CIPHER_SUITE suite)
   170 {
   171     switch (suite) {
   172         // supported cipher suites
   173         case PEP_CIPHER_SUITE_RSA2K:
   174             return PGP_CERT_CIPHER_SUITE_RSA2K;
   175         case PEP_CIPHER_SUITE_RSA3K:
   176             return PGP_CERT_CIPHER_SUITE_RSA3K;
   177         case PEP_CIPHER_SUITE_CV25519:
   178             return PGP_CERT_CIPHER_SUITE_CV25519;
   179         case PEP_CIPHER_SUITE_P256:
   180             return PGP_CERT_CIPHER_SUITE_P256;
   181         case PEP_CIPHER_SUITE_P384:
   182             return PGP_CERT_CIPHER_SUITE_P384;
   183         case PEP_CIPHER_SUITE_P521:
   184             return PGP_CERT_CIPHER_SUITE_P521;
   185         default:
   186             return PGP_CERT_CIPHER_SUITE_RSA2K;
   187     }
   188 }
   189 
   190 int email_cmp(void *cookie, int a_len, const void *a, int b_len, const void *b)
   191 {
   192     pgp_packet_t a_userid = pgp_user_id_from_raw (a, a_len);
   193     pgp_packet_t b_userid = pgp_user_id_from_raw (b, b_len);
   194 
   195     char *a_email = NULL;
   196     pgp_user_id_email_normalized(NULL, a_userid, &a_email);
   197     if (!a_email)
   198         pgp_user_id_uri(NULL, a_userid, &a_email);
   199 
   200     char *b_email = NULL;
   201     pgp_user_id_email_normalized(NULL, b_userid, &b_email);
   202     if (!b_email)
   203         pgp_user_id_uri(NULL, b_userid, &b_email);
   204 
   205     pgp_packet_free(a_userid);
   206     pgp_packet_free(b_userid);
   207 
   208     // return an integer that is negative, zero, or positive if the
   209     // first string is less than, equal to, or greater than the
   210     // second, respectively.
   211     int result;
   212     if (!a_email && !b_email)
   213         result = 0;
   214     else if (!a_email)
   215         result = -1;
   216     else if (!b_email)
   217         result = 1;
   218     else
   219         result = strcmp(a_email, b_email);
   220 
   221     if (true) {
   222         T("'%s' %s '%s'",
   223           a_email,
   224           result == 0 ? "==" : result < 0 ? "<" : ">",
   225           b_email);
   226     }
   227 
   228     free(a_email);
   229     free(b_email);
   230 
   231     return result;
   232 }
   233 
   234 PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
   235 {
   236     PEP_STATUS status = PEP_STATUS_OK;
   237 
   238 #ifdef _WIN32
   239 	int sqlite_result;
   240 	sqlite_result = sqlite3_open_v2(KEYS_DB,
   241 		&session->key_db,
   242 		SQLITE_OPEN_READWRITE
   243 		| SQLITE_OPEN_CREATE
   244 		| SQLITE_OPEN_FULLMUTEX
   245 		| SQLITE_OPEN_PRIVATECACHE,
   246 		NULL);
   247 #else
   248     // Create the home directory.
   249     char *home_env = NULL;
   250 #ifndef NDEBUG
   251     home_env = getenv("PEP_HOME");
   252 #endif
   253 
   254 #define PEP_KEYS_PATH "/.pEp/keys.db"
   255 
   256     if (!home_env)
   257         home_env = getenv("HOME");
   258 
   259     if (!home_env)
   260         ERROR_OUT(NULL, PEP_INIT_CRYPTO_LIB_INIT_FAILED, "HOME unset");
   261 
   262     // Create the DB and initialize it.
   263     size_t path_size = strlen(home_env) + sizeof(PEP_KEYS_PATH);
   264     char *path = (char *) calloc(path_size, 1);
   265     assert(path);
   266     if (!path)
   267         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   268 
   269 	int r = snprintf(path, path_size, "%s" PEP_KEYS_PATH, home_env);
   270     assert(r >= 0 && r < path_size);
   271     if (r < 0) {
   272         free(path);
   273         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "snprintf");
   274     }
   275 
   276     int sqlite_result;
   277     sqlite_result = sqlite3_open_v2(path,
   278                                     &session->key_db,
   279                                     SQLITE_OPEN_READWRITE
   280                                     | SQLITE_OPEN_CREATE
   281                                     | SQLITE_OPEN_FULLMUTEX
   282                                     | SQLITE_OPEN_PRIVATECACHE,
   283                                     NULL);
   284     free(path);
   285 #endif
   286 
   287 #ifdef _PEP_SQLITE_DEBUG
   288     sqlite3_trace_v2(session->key_db,
   289         SQLITE_TRACE_STMT | SQLITE_TRACE_ROW | SQLITE_TRACE_CLOSE,
   290         sq_sql_trace_callback,
   291         NULL);
   292 #endif
   293 
   294     if (sqlite_result != SQLITE_OK)
   295         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   296                   "opening keys DB: %s", sqlite3_errmsg(session->key_db));
   297 
   298     sqlite_result = sqlite3_exec(session->key_db,
   299                                  "PRAGMA secure_delete=true;\n"
   300                                  "PRAGMA foreign_keys=true;\n"
   301                                  "PRAGMA locking_mode=NORMAL;\n"
   302                                  "PRAGMA journal_mode=WAL;\n",
   303                                  NULL, NULL, NULL);
   304     if (sqlite_result != SQLITE_OK)
   305         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   306                   "setting pragmas: %s", sqlite3_errmsg(session->key_db));
   307 
   308     sqlite3_busy_timeout(session->key_db, BUSY_WAIT_TIME);
   309 
   310     sqlite_result =
   311         sqlite3_create_collation(session->key_db,
   312                                 "EMAIL",
   313                                 SQLITE_UTF8,
   314                                 /* pArg (cookie) */ NULL,
   315                                 email_cmp);
   316     if (sqlite_result != SQLITE_OK)
   317         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   318                   "registering EMAIL collation function: %s",
   319                   sqlite3_errmsg(session->key_db));
   320 
   321     sqlite_result = sqlite3_exec(session->key_db,
   322                                  "CREATE TABLE IF NOT EXISTS keys (\n"
   323                                  "   primary_key TEXT UNIQUE PRIMARY KEY,\n"
   324                                  "   secret BOOLEAN,\n"
   325                                  "   tpk BLOB\n"
   326                                  ");\n"
   327                                  "CREATE INDEX IF NOT EXISTS keys_index\n"
   328                                  "  ON keys (primary_key, secret)\n",
   329                                  NULL, NULL, NULL);
   330     if (sqlite_result != SQLITE_OK)
   331         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   332                   "creating keys table: %s",
   333                   sqlite3_errmsg(session->key_db));
   334 
   335     sqlite_result = sqlite3_exec(session->key_db,
   336                                  "CREATE TABLE IF NOT EXISTS subkeys (\n"
   337                                  "   subkey TEXT NOT NULL,\n"
   338                                  "   primary_key TEXT NOT NULL,\n"
   339                                  "   UNIQUE(subkey, primary_key),\n"
   340                                  "   FOREIGN KEY (primary_key)\n"
   341                                  "       REFERENCES keys(primary_key)\n"
   342                                  "     ON DELETE CASCADE\n"
   343                                  ");\n"
   344                                  "CREATE INDEX IF NOT EXISTS subkeys_index\n"
   345                                  "  ON subkeys (subkey, primary_key)\n",
   346                                  NULL, NULL, NULL);
   347     if (sqlite_result != SQLITE_OK)
   348         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   349                   "creating subkeys table: %s",
   350                   sqlite3_errmsg(session->key_db));
   351 
   352     sqlite_result = sqlite3_exec(session->key_db,
   353                                  "CREATE TABLE IF NOT EXISTS userids (\n"
   354                                  "   userid TEXT NOT NULL COLLATE EMAIL,\n"
   355                                  "   primary_key TEXT NOT NULL,\n"
   356                                  "   UNIQUE(userid, primary_key),\n"
   357                                  "   FOREIGN KEY (primary_key)\n"
   358                                  "       REFERENCES keys(primary_key)\n"
   359                                  "     ON DELETE CASCADE\n"
   360                                  ");\n"
   361                                  "CREATE INDEX IF NOT EXISTS userids_index\n"
   362                                  "  ON userids (userid COLLATE EMAIL, primary_key)\n",
   363                                  NULL, NULL, NULL);
   364 
   365     if (sqlite_result != SQLITE_OK)
   366         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   367                   "creating userids table: %s",
   368                   sqlite3_errmsg(session->key_db));
   369 
   370     sqlite_result
   371         = sqlite3_prepare_v2(session->key_db, "begin transaction",
   372                              -1, &session->sq_sql.begin_transaction, NULL);
   373     assert(sqlite_result == SQLITE_OK);
   374 
   375     sqlite_result
   376         = sqlite3_prepare_v2(session->key_db, "commit transaction",
   377                              -1, &session->sq_sql.commit_transaction, NULL);
   378     assert(sqlite_result == SQLITE_OK);
   379 
   380     sqlite_result
   381         = sqlite3_prepare_v2(session->key_db, "rollback transaction",
   382                              -1, &session->sq_sql.rollback_transaction, NULL);
   383     assert(sqlite_result == SQLITE_OK);
   384 
   385     sqlite_result
   386         = sqlite3_prepare_v2(session->key_db,
   387                              "SELECT tpk, secret FROM keys"
   388                              " WHERE primary_key == ?",
   389                              -1, &session->sq_sql.cert_find, NULL);
   390     assert(sqlite_result == SQLITE_OK);
   391 
   392     sqlite_result
   393         = sqlite3_prepare_v2(session->key_db,
   394                              "SELECT tpk, secret FROM keys"
   395                              " WHERE primary_key == ? and secret == 1",
   396                              -1, &session->sq_sql.tsk_find, NULL);
   397     assert(sqlite_result == SQLITE_OK);
   398 
   399     sqlite_result
   400         = sqlite3_prepare_v2(session->key_db,
   401                              "SELECT tpk, secret FROM subkeys"
   402                              " LEFT JOIN keys"
   403                              "  ON subkeys.primary_key == keys.primary_key"
   404                              " WHERE subkey == ?",
   405                              -1, &session->sq_sql.cert_find_by_keyid, NULL);
   406     assert(sqlite_result == SQLITE_OK);
   407 
   408     sqlite_result
   409         = sqlite3_prepare_v2(session->key_db,
   410                              "SELECT tpk, secret FROM subkeys"
   411                              " LEFT JOIN keys"
   412                              "  ON subkeys.primary_key == keys.primary_key"
   413                              " WHERE subkey == ?",
   414                              -1, &session->sq_sql.cert_find_by_keyid, NULL);
   415     assert(sqlite_result == SQLITE_OK);
   416 
   417     sqlite_result
   418         = sqlite3_prepare_v2(session->key_db,
   419                              "SELECT tpk, secret FROM subkeys"
   420                              " LEFT JOIN keys"
   421                              "  ON subkeys.primary_key == keys.primary_key"
   422                              " WHERE subkey == ? and keys.secret == 1",
   423                              -1, &session->sq_sql.tsk_find_by_keyid, NULL);
   424     assert(sqlite_result == SQLITE_OK);
   425 
   426     sqlite_result
   427         = sqlite3_prepare_v2(session->key_db,
   428                              "SELECT tpk, secret FROM userids"
   429                              " LEFT JOIN keys"
   430                              "  ON userids.primary_key == keys.primary_key"
   431                              " WHERE userid == ?",
   432                              -1, &session->sq_sql.cert_find_by_email, NULL);
   433     assert(sqlite_result == SQLITE_OK);
   434 
   435     sqlite_result
   436         = sqlite3_prepare_v2(session->key_db,
   437                              "SELECT tpk, secret FROM userids"
   438                              " LEFT JOIN keys"
   439                              "  ON userids.primary_key == keys.primary_key"
   440                              " WHERE userid == ? and keys.secret == 1",
   441                              -1, &session->sq_sql.tsk_find_by_email, NULL);
   442     assert(sqlite_result == SQLITE_OK);
   443 
   444     sqlite_result
   445         = sqlite3_prepare_v2(session->key_db,
   446                              "select tpk, secret from keys",
   447                              -1, &session->sq_sql.cert_all, NULL);
   448     assert(sqlite_result == SQLITE_OK);
   449 
   450     sqlite_result
   451         = sqlite3_prepare_v2(session->key_db,
   452                              "select tpk, secret from keys where secret = 1",
   453                              -1, &session->sq_sql.tsk_all, NULL);
   454     assert(sqlite_result == SQLITE_OK);
   455 
   456     sqlite_result
   457         = sqlite3_prepare_v2(session->key_db,
   458                              "INSERT OR REPLACE INTO keys"
   459                              "   (primary_key, secret, tpk)"
   460                              " VALUES (?, ?, ?)",
   461                              -1, &session->sq_sql.cert_save_insert_primary, NULL);
   462     assert(sqlite_result == SQLITE_OK);
   463 
   464     sqlite_result
   465         = sqlite3_prepare_v2(session->key_db,
   466                              "INSERT OR REPLACE INTO subkeys"
   467                              "   (subkey, primary_key)"
   468                              " VALUES (?, ?)",
   469                              -1, &session->sq_sql.cert_save_insert_subkeys, NULL);
   470     assert(sqlite_result == SQLITE_OK);
   471 
   472     sqlite_result
   473         = sqlite3_prepare_v2(session->key_db,
   474                              "INSERT OR REPLACE INTO userids"
   475                              "   (userid, primary_key)"
   476                              " VALUES (?, ?)",
   477                              -1, &session->sq_sql.cert_save_insert_userids, NULL);
   478     assert(sqlite_result == SQLITE_OK);
   479 
   480     sqlite_result
   481         = sqlite3_prepare_v2(session->key_db,
   482                              "DELETE FROM keys WHERE primary_key = ?",
   483                              -1, &session->sq_sql.delete_keypair, NULL);
   484     assert(sqlite_result == SQLITE_OK);
   485 
   486     
   487     session->policy = pgp_null_policy ();
   488     if (! session->policy)
   489         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY,
   490                   "initializing openpgp policy");
   491 
   492  out:
   493     if (status != PEP_STATUS_OK)
   494         pgp_release(session, in_first);
   495     return status;
   496 }
   497 
   498 void pgp_release(PEP_SESSION session, bool out_last)
   499 {
   500     pgp_policy_free (session->policy);
   501     session->policy = NULL;
   502 
   503     sqlite3_stmt **stmts = (sqlite3_stmt **) &session->sq_sql;
   504     for (int i = 0; i < sizeof(session->sq_sql) / sizeof(*stmts); i ++)
   505         if (stmts[i]) {
   506             sqlite3_finalize(stmts[i]);
   507             stmts[i] = NULL;
   508         }
   509 
   510     if (session->key_db) {
   511         int result = sqlite3_close_v2(session->key_db);
   512         if (result != 0)
   513             DUMP_ERR(NULL, PEP_UNKNOWN_ERROR,
   514                      "Closing key DB: sqlite3_close_v2: %s",
   515                      sqlite3_errstr(result));
   516         session->key_db = NULL;
   517     }
   518 }
   519 
   520 // Ensures that a fingerprint is in canonical form.  A canonical
   521 // fingerprint doesn't contain any white space.
   522 //
   523 // This function does *not* consume fpr.
   524 static char *pgp_fingerprint_canonicalize(const char *) __attribute__((nonnull));
   525 static char *pgp_fingerprint_canonicalize(const char *fpr)
   526 {
   527     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   528     char *fpr_canonicalized = pgp_fingerprint_to_hex(pgp_fpr);
   529     pgp_fingerprint_free(pgp_fpr);
   530 
   531     return fpr_canonicalized;
   532 }
   533 
   534 // step statement and load the certificate and secret.
   535 static PEP_STATUS key_load(PEP_SESSION, sqlite3_stmt *, pgp_cert_t *, int *)
   536     __attribute__((nonnull(1, 2)));
   537 static PEP_STATUS key_load(PEP_SESSION session, sqlite3_stmt *stmt,
   538                            pgp_cert_t *certp, int *secretp)
   539 {
   540     PEP_STATUS status = PEP_STATUS_OK;
   541     int sqlite_result = sqlite3_step(stmt);
   542     switch (sqlite_result) {
   543     case SQLITE_ROW:
   544         if (certp) {
   545             int data_len = sqlite3_column_bytes(stmt, 0);
   546             const void *data = sqlite3_column_blob(stmt, 0);
   547 
   548             pgp_error_t err = NULL;
   549             *certp = pgp_cert_from_bytes(&err, data, data_len);
   550             if (!*certp)
   551                 ERROR_OUT(err, PEP_GET_KEY_FAILED, "parsing certificate");
   552         }
   553 
   554         if (secretp)
   555             *secretp = sqlite3_column_int(stmt, 1);
   556 
   557         break;
   558     case SQLITE_DONE:
   559         // Got nothing.
   560         status = PEP_KEY_NOT_FOUND;
   561         break;
   562     default:
   563         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   564                   "stepping: %s", sqlite3_errmsg(session->key_db));
   565     }
   566 
   567  out:
   568     T(" -> %s", pEp_status_to_string(status));
   569     return status;
   570 }
   571 
   572 // step statement until exhausted and load the certificates.
   573 static PEP_STATUS key_loadn(PEP_SESSION, sqlite3_stmt *, pgp_cert_t **, int *)
   574     __attribute__((nonnull));
   575 static PEP_STATUS key_loadn(PEP_SESSION session, sqlite3_stmt *stmt,
   576                             pgp_cert_t **certsp, int *certs_countp)
   577 {
   578     PEP_STATUS status = PEP_STATUS_OK;
   579     int certs_count = 0;
   580     int certs_capacity = 8;
   581     pgp_cert_t *certs = calloc(certs_capacity, sizeof(pgp_cert_t));
   582     if (!certs)
   583         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   584 
   585     for (;;) {
   586         pgp_cert_t cert = NULL;
   587         status = key_load(session, stmt, &cert, NULL);
   588         if (status == PEP_KEY_NOT_FOUND) {
   589             status = PEP_STATUS_OK;
   590             break;
   591         }
   592         ERROR_OUT(NULL, status, "loading certificate");
   593 
   594         if (certs_count == certs_capacity) {
   595             certs_capacity *= 2;
   596             certs = realloc(certs, sizeof(certs[0]) * certs_capacity);
   597             if (!certs)
   598                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "certs");
   599         }
   600         certs[certs_count ++] = cert;
   601     }
   602 
   603  out:
   604     if (status != PEP_STATUS_OK) {
   605         for (int i = 0; i < certs_count; i ++)
   606             pgp_cert_free(certs[i]);
   607         free(certs);
   608     } else {
   609         *certsp = certs;
   610         *certs_countp = certs_count;
   611     }
   612 
   613     T(" -> %s (%d certs)", pEp_status_to_string(status), *certs_countp);
   614     return status;
   615 }
   616 
   617 // Returns the certificate identified by the provided fingerprint.
   618 //
   619 // This function only matches on the primary key!
   620 static PEP_STATUS cert_find(PEP_SESSION, pgp_fingerprint_t, int, pgp_cert_t *, int *)
   621     __attribute__((nonnull(1, 2)));
   622 static PEP_STATUS cert_find(PEP_SESSION session,
   623                            pgp_fingerprint_t fpr, int private_only,
   624                            pgp_cert_t *cert, int *secret)
   625 {
   626     PEP_STATUS status = PEP_STATUS_OK;
   627     char *fpr_str = pgp_fingerprint_to_hex(fpr);
   628 
   629     T("(%s, %d)", fpr_str, private_only);
   630 
   631     sqlite3_stmt *stmt
   632         = private_only ? session->sq_sql.tsk_find : session->sq_sql.cert_find;
   633     sqlite3_bind_text(stmt, 1, fpr_str, -1, SQLITE_STATIC);
   634 
   635     status = key_load(session, stmt, cert, secret);
   636     ERROR_OUT(NULL, status, "Looking up %s", fpr_str);
   637 
   638  out:
   639     sqlite3_reset(stmt);
   640     T("(%s, %d) -> %s", fpr_str, private_only, pEp_status_to_string(status));
   641     free(fpr_str);
   642     return status;
   643 }
   644 
   645 // Returns the certificate identified by the provided keyid.
   646 //
   647 // This function matches on both primary keys and subkeys!
   648 //
   649 // Note: There can be multiple certificates for a given keyid.  This can
   650 // occur, because an encryption subkey can be bound to multiple certificates.
   651 // Also, it is possible to collide key ids.  If there are multiple key
   652 // ids for a given key, this just returns one of them.
   653 //
   654 // If private_only is set, this will only consider certificates with some
   655 // secret key material.
   656 static PEP_STATUS cert_find_by_keyid_hex(PEP_SESSION, const char *, int, pgp_cert_t *, int *)
   657   __attribute__((nonnull(1, 2)));
   658 static PEP_STATUS cert_find_by_keyid_hex(
   659         PEP_SESSION session, const char *keyid_hex, int private_only,
   660         pgp_cert_t *certp, int *secretp)
   661 {
   662     PEP_STATUS status = PEP_STATUS_OK;
   663     T("(%s, %d)", keyid_hex, private_only);
   664 
   665     sqlite3_stmt *stmt
   666         = private_only ? session->sq_sql.tsk_find_by_keyid : session->sq_sql.cert_find_by_keyid;
   667     sqlite3_bind_text(stmt, 1, keyid_hex, -1, SQLITE_STATIC);
   668 
   669     status = key_load(session, stmt, certp, secretp);
   670     ERROR_OUT(NULL, status, "Looking up %s", keyid_hex);
   671 
   672  out:
   673     sqlite3_reset(stmt);
   674     T("(%s, %d) -> %s", keyid_hex, private_only, pEp_status_to_string(status));
   675     return status;
   676 }
   677 
   678 // See cert_find_by_keyid_hex.
   679 PEP_STATUS cert_find_by_keyid(PEP_SESSION, pgp_keyid_t, int, pgp_cert_t *, int *)
   680     __attribute__((nonnull(1, 2)));
   681 PEP_STATUS cert_find_by_keyid(PEP_SESSION session,
   682                              pgp_keyid_t keyid, int private_only,
   683                              pgp_cert_t *certp, int *secretp)
   684 {
   685     char *keyid_hex = pgp_keyid_to_hex(keyid);
   686     if (! keyid_hex)
   687         return PEP_OUT_OF_MEMORY;
   688     PEP_STATUS status
   689         = cert_find_by_keyid_hex(session, keyid_hex, private_only, certp, secretp);
   690     free(keyid_hex);
   691     return status;
   692 }
   693 
   694 // See cert_find_by_keyid_hex.
   695 static PEP_STATUS cert_find_by_fpr(PEP_SESSION, pgp_fingerprint_t, int,
   696                                   pgp_cert_t *, int *)
   697     __attribute__((nonnull(1, 2)));
   698 static PEP_STATUS cert_find_by_fpr(
   699     PEP_SESSION session, pgp_fingerprint_t fpr, int private_only,
   700     pgp_cert_t *certp, int *secretp)
   701 {
   702     pgp_keyid_t keyid = pgp_fingerprint_to_keyid(fpr);
   703     if (! keyid)
   704         return PEP_OUT_OF_MEMORY;
   705     PEP_STATUS status
   706         = cert_find_by_keyid(session, keyid, private_only, certp, secretp);
   707     pgp_keyid_free(keyid);
   708     return status;
   709 }
   710 
   711 // See cert_find_by_keyid_hex.
   712 static PEP_STATUS cert_find_by_fpr_hex(PEP_SESSION, const char *, int, pgp_cert_t *, int *secret)
   713     __attribute__((nonnull(1, 2)));
   714 static PEP_STATUS cert_find_by_fpr_hex(
   715     PEP_SESSION session, const char *fpr, int private_only,
   716     pgp_cert_t *certp, int *secretp)
   717 {
   718     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   719     if (! pgp_fpr)
   720         return PEP_OUT_OF_MEMORY;
   721     PEP_STATUS status
   722         = cert_find_by_fpr(session, pgp_fpr, private_only, certp, secretp);
   723     pgp_fingerprint_free(pgp_fpr);
   724     return status;
   725 }
   726 
   727 // Returns all known certificates.
   728 static PEP_STATUS cert_all(PEP_SESSION, int, pgp_cert_t **, int *) __attribute__((nonnull));
   729 static PEP_STATUS cert_all(PEP_SESSION session, int private_only,
   730                           pgp_cert_t **certsp, int *certs_countp) {
   731     PEP_STATUS status = PEP_STATUS_OK;
   732     sqlite3_stmt *stmt = private_only ? session->sq_sql.tsk_all : session->sq_sql.cert_all;
   733     status = key_loadn(session, stmt, certsp, certs_countp);
   734     ERROR_OUT(NULL, status, "loading certificates");
   735  out:
   736     sqlite3_reset(stmt);
   737     return status;
   738 }
   739 
   740 // Returns keys that have a user id that matches the specified pattern.
   741 //
   742 // The keys returned must be freed using pgp_cert_free.
   743 static PEP_STATUS cert_find_by_email(PEP_SESSION, const char *, int, pgp_cert_t **, int *)
   744     __attribute__((nonnull));
   745 static PEP_STATUS cert_find_by_email(PEP_SESSION session,
   746                                     const char *pattern, int private_only,
   747                                     pgp_cert_t **certsp, int *countp)
   748 {
   749     PEP_STATUS status = PEP_STATUS_OK;
   750     T("(%s)", pattern);
   751 
   752     sqlite3_stmt *stmt
   753         = private_only ? session->sq_sql.tsk_find_by_email : session->sq_sql.cert_find_by_email;
   754     sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_STATIC);
   755 
   756     status = key_loadn(session, stmt, certsp, countp);
   757     ERROR_OUT(NULL, status, "Searching for '%s'", pattern);
   758 
   759  out:
   760     sqlite3_reset(stmt);
   761     T("(%s) -> %s (%d results)", pattern, pEp_status_to_string(status), *countp);
   762     return status;
   763 }
   764 
   765 // end detect possibly changed key stuff
   766 static PEP_STATUS serialize_cert(PEP_SESSION session, pgp_cert_t cert,
   767                                  void** buffer_ptr, size_t* buffer_size_ptr)   {
   768     
   769     if (!session || !cert || !buffer_ptr || !buffer_size_ptr)
   770         return PEP_ILLEGAL_VALUE;
   771         
   772     PEP_STATUS status = PEP_STATUS_OK;
   773         
   774     void* curr_buffer = NULL;
   775     size_t curr_buffer_len = 0;                                 
   776     pgp_status_t pgp_status;
   777     pgp_tsk_t tsk = NULL;
   778     pgp_error_t err = NULL;
   779     
   780     pgp_writer_t writer = pgp_writer_alloc(&curr_buffer, &curr_buffer_len);
   781     if (!writer)
   782         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   783 
   784     tsk = pgp_cert_as_tsk(cert);
   785     pgp_status = pgp_tsk_serialize(&err, tsk, writer);
   786     if (pgp_status != 0)
   787         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Serializing certificates");
   788     
   789 out: 
   790     pgp_tsk_free(tsk);
   791     pgp_writer_free(writer);   
   792 
   793     if (status == PEP_STATUS_OK) {
   794         *buffer_ptr = curr_buffer;
   795         *buffer_size_ptr = curr_buffer_len;
   796     }
   797     else
   798         free(buffer_ptr);
   799         
   800     T(" -> %s", pEp_status_to_string(status));
   801     return status;    
   802 }
   803 
   804 
   805 // Saves the specified certificates.
   806 //
   807 // This function takes ownership of CERT.
   808 static PEP_STATUS cert_save(PEP_SESSION, pgp_cert_t, identity_list **, bool* changed_ptr)
   809     __attribute__((nonnull(1, 2)));
   810 static PEP_STATUS cert_save(PEP_SESSION session, pgp_cert_t cert,
   811                            identity_list **private_idents, bool* changed_ptr)
   812 {
   813     PEP_STATUS status = PEP_STATUS_OK;
   814     pgp_error_t err = NULL;
   815     pgp_fingerprint_t pgp_fpr = NULL;
   816     char *fpr = NULL;
   817     void *tsk_buffer = NULL;
   818     size_t tsk_buffer_len = 0;
   819     void *curr_buffer = NULL;
   820     size_t curr_buffer_len = 0;
   821     int tried_commit = 0;
   822     pgp_cert_key_iter_t key_iter = NULL;
   823     pgp_cert_valid_user_id_iter_t ua_iter = NULL;
   824     pgp_valid_user_id_amalgamation_t ua = NULL;
   825     pgp_packet_t user_id = NULL;
   826     char *email = NULL;
   827     char *name = NULL;
   828     
   829     bool _changed = false;    
   830 
   831     sqlite3_stmt *stmt = session->sq_sql.begin_transaction;
   832     int sqlite_result = sqlite3_step(stmt);
   833     sqlite3_reset(stmt);
   834     if (sqlite_result != SQLITE_DONE)
   835         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   836                   "begin transaction failed: %s",
   837                   sqlite3_errmsg(session->key_db));
   838 
   839     pgp_fpr = pgp_cert_fingerprint(cert);
   840     fpr = pgp_fingerprint_to_hex(pgp_fpr);
   841     T("(%s, private_idents: %s)", fpr, private_idents ? "yes" : "no");
   842 
   843     // Merge any existing data into certificate.
   844     pgp_cert_t current = NULL;
   845     status = cert_find(session, pgp_fpr, false, &current, NULL);
   846     if (status == PEP_KEY_NOT_FOUND)
   847         status = PEP_STATUS_OK;
   848     else
   849         ERROR_OUT(NULL, status, "Looking up %s", fpr);    
   850     
   851     if (current) {
   852         if (changed_ptr) {
   853             // Serialize current for comparison (ugh).        
   854             status = serialize_cert(session, current, &curr_buffer, &curr_buffer_len);
   855             if (status != PEP_STATUS_OK)
   856                 ERROR_OUT(NULL, status, "Could not serialize existing cert for change check");
   857         }        
   858 
   859         cert = pgp_cert_merge(&err, cert, current);
   860         if (! cert)
   861             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Merging certificates");
   862     }
   863     else if (changed_ptr)
   864         _changed = true;
   865 
   866     int is_tsk = pgp_cert_is_tsk(cert);
   867 
   868     // Serialize it.
   869     // NOTE: Just because it's called tsk in tsk_buffer does NOT mean it necessarily 
   870     //       has secret key material; it is just that is could. is_tsk is the 
   871     //       part that asks whether or not it contains such.
   872     status = serialize_cert(session, cert, &tsk_buffer, &tsk_buffer_len);
   873     if (status != PEP_STATUS_OK)
   874         ERROR_OUT(NULL, status, "Could not serialize tsk cert for saving");
   875     
   876     // Before we do anything else, if we need to know if things MAY have changed, 
   877     // we check the key blob (this is not comprehensive and can generate false 
   878     // positives)
   879     //
   880     if (changed_ptr) {
   881         if (!current || !curr_buffer || (curr_buffer_len != tsk_buffer_len))
   882             _changed = true;
   883         else if (memcmp(curr_buffer, tsk_buffer, tsk_buffer_len) != 0)
   884             _changed = true;
   885     }
   886                     
   887     // Insert the TSK into the DB.
   888     stmt = session->sq_sql.cert_save_insert_primary;
   889     sqlite3_bind_text(stmt, 1, fpr, -1, SQLITE_STATIC);
   890     sqlite3_bind_int(stmt, 2, is_tsk);
   891     sqlite3_bind_blob(stmt, 3, tsk_buffer, tsk_buffer_len, SQLITE_STATIC);
   892 
   893     sqlite_result = sqlite3_step(stmt);
   894     sqlite3_reset(stmt);
   895     if (sqlite_result != SQLITE_DONE)
   896         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   897                   "Saving certificate: %s", sqlite3_errmsg(session->key_db));
   898 
   899     // Insert the "subkeys" (the primary key and the subkeys).
   900     stmt = session->sq_sql.cert_save_insert_subkeys;
   901     // This inserts all of the keys in the certificate, i.e.,
   902     // including revoked and expired keys, which is what we want.
   903     key_iter = pgp_cert_key_iter(cert);
   904     pgp_key_amalgamation_t ka;
   905     while ((ka = pgp_cert_key_iter_next(key_iter))) {
   906         pgp_key_t key = pgp_key_amalgamation_key (ka);
   907 
   908         pgp_keyid_t keyid = pgp_key_keyid(key);
   909         char *keyid_hex = pgp_keyid_to_hex(keyid);
   910         sqlite3_bind_text(stmt, 1, keyid_hex, -1, SQLITE_STATIC);
   911         sqlite3_bind_text(stmt, 2, fpr, -1, SQLITE_STATIC);
   912 
   913         pgp_key_free (key);
   914         pgp_key_amalgamation_free (ka);
   915 
   916         sqlite_result = sqlite3_step(stmt);
   917         sqlite3_reset(stmt);
   918         free(keyid_hex);
   919         pgp_keyid_free(keyid);
   920         if (sqlite_result != SQLITE_DONE) {
   921             pgp_cert_key_iter_free(key_iter);
   922             ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   923                       "Updating subkeys: %s", sqlite3_errmsg(session->key_db));
   924         }
   925     }
   926     pgp_cert_key_iter_free(key_iter);
   927     key_iter = NULL;
   928 
   929     // Insert the "userids".
   930     stmt = session->sq_sql.cert_save_insert_userids;
   931     ua_iter = pgp_cert_valid_user_id_iter(cert, session->policy, 0);
   932     int first = 1;
   933     while ((ua = pgp_cert_valid_user_id_iter_next(ua_iter))) {
   934         user_id = pgp_valid_user_id_amalgamation_user_id(ua);
   935 
   936         const uint8_t *user_id_value = pgp_user_id_value(user_id, NULL);
   937         if (!user_id_value || !*user_id_value) {
   938             pgp_packet_free (user_id);
   939             user_id = NULL;
   940             pgp_valid_user_id_amalgamation_free(ua);
   941             ua = NULL;
   942             continue;
   943         }
   944 
   945         free(name);
   946         name = NULL;
   947         free(email);
   948         email = NULL;
   949 
   950         pgp_user_id_name(NULL, user_id, &name);
   951         // Try to get the normalized address.
   952         pgp_user_id_email_normalized(NULL, user_id, &email);
   953         if (! email)
   954             // Ok, it's not a proper RFC 2822 name-addr.  Perhaps it
   955             // is a URI.
   956             pgp_user_id_uri(NULL, user_id, &email);
   957 
   958         if (email) {
   959             T("  userid: %s", email);
   960 
   961             sqlite3_bind_text(stmt, 1, email, -1, SQLITE_STATIC);
   962             sqlite3_bind_text(stmt, 2, fpr, -1, SQLITE_STATIC);
   963 
   964             sqlite_result = sqlite3_step(stmt);
   965             sqlite3_reset(stmt);
   966 
   967             if (sqlite_result != SQLITE_DONE) {
   968                 ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   969                           "Updating userids: %s", sqlite3_errmsg(session->key_db));
   970             }
   971         }
   972 
   973         if (first && private_idents && is_tsk) {
   974             first = 0;
   975 
   976             // Create an identity for the primary user id.
   977             pEp_identity *ident = new_identity(email, fpr, NULL, name);
   978             if (ident == NULL)
   979                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_identity");
   980 
   981             *private_idents = identity_list_add(*private_idents, ident);
   982             if (*private_idents == NULL)
   983                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "identity_list_add");
   984         }
   985 
   986         pgp_packet_free (user_id);
   987         user_id = NULL;
   988         pgp_valid_user_id_amalgamation_free(ua);
   989         ua = NULL;
   990     }
   991 
   992  out:
   993     // Prevent ERROR_OUT from causing an infinite loop.
   994     if (! tried_commit) {
   995         tried_commit = 1;
   996         stmt = status == PEP_STATUS_OK
   997             ? session->sq_sql.commit_transaction
   998             : session->sq_sql.rollback_transaction;
   999         int sqlite_result = sqlite3_step(stmt);
  1000         sqlite3_reset(stmt);
  1001         if (sqlite_result != SQLITE_DONE)
  1002             ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
  1003                       status == PEP_STATUS_OK
  1004                       ? "commit failed: %s" : "rollback failed: %s",
  1005                       sqlite3_errmsg(session->key_db));
  1006     }
  1007 
  1008     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  1009 
  1010     if (changed_ptr)
  1011         *changed_ptr = _changed;
  1012 
  1013     free(email);
  1014     free(name);
  1015     pgp_packet_free(user_id);
  1016     pgp_valid_user_id_amalgamation_free(ua);
  1017     pgp_cert_valid_user_id_iter_free(ua_iter);
  1018     pgp_cert_key_iter_free(key_iter);
  1019     if (stmt)
  1020         sqlite3_reset(stmt);
  1021     free(tsk_buffer);
  1022     free(curr_buffer);
  1023     pgp_cert_free(cert);
  1024     free(fpr);
  1025     pgp_fingerprint_free(pgp_fpr);
  1026 
  1027     return status;
  1028 }
  1029 
  1030 struct decrypt_cookie {
  1031     PEP_SESSION session;
  1032     int get_secret_keys_called;
  1033     stringlist_t *recipient_keylist;
  1034     stringlist_t *signer_keylist;
  1035 
  1036     int good_checksums;
  1037     int malformed_signature;
  1038     int missing_keys;
  1039     int unbound_key;
  1040     int revoked_key;
  1041     int expired_key;
  1042     int bad_key;
  1043     int bad_checksums;
  1044 
  1045     // Whether we decrypted anything.
  1046     int decrypted;
  1047 
  1048     // The filename stored in the literal data packet.  Note: this is
  1049     // *not* protected by the signature and should not be trusted!!!
  1050     char *filename;
  1051 };
  1052 
  1053 static pgp_status_t
  1054 get_public_keys_cb(void *cookie_raw,
  1055                    pgp_keyid_t *keyids, size_t keyids_len,
  1056                    pgp_cert_t **certs, size_t *certs_len,
  1057                    void (**our_free)(void *))
  1058 {
  1059     struct decrypt_cookie *cookie = cookie_raw;
  1060     PEP_SESSION session = cookie->session;
  1061 
  1062     *certs = calloc(keyids_len, sizeof(*certs));
  1063     if (!*certs)
  1064         return PGP_STATUS_UNKNOWN_ERROR;
  1065     *our_free = free;
  1066 
  1067     size_t i;
  1068     int j = 0;
  1069     for (i = 0; i < keyids_len; i ++) {
  1070         pgp_cert_t cert = NULL;
  1071         PEP_STATUS status
  1072             = cert_find_by_keyid(session, keyids[i], false, &cert, NULL);
  1073         if (status == PEP_STATUS_OK)
  1074             (*certs)[j ++] = cert;
  1075     }
  1076     *certs_len = j;
  1077     return PGP_STATUS_SUCCESS;
  1078 }
  1079 
  1080 static pgp_status_t
  1081 decrypt_cb(void *cookie_opaque,
  1082            pgp_pkesk_t *pkesks, size_t pkesk_count,
  1083            pgp_skesk_t *skesks, size_t skesk_count,
  1084            uint8_t symmetric_algo,
  1085            pgp_decryptor_do_decrypt_cb_t *decrypt,
  1086            void *decrypt_cookie,
  1087            pgp_fingerprint_t *identity_out)
  1088 {
  1089     pgp_error_t err = NULL;
  1090     struct decrypt_cookie *cookie = cookie_opaque;
  1091     PEP_SESSION session = cookie->session;
  1092     pgp_cert_t *tsks = NULL;
  1093     int tsks_count = 0;
  1094     int wildcards = 0;
  1095 
  1096     if (cookie->get_secret_keys_called)
  1097         // Prevent iterations, which isn't needed since we don't
  1098         // support SKESKs.
  1099         return PGP_STATUS_UNKNOWN_ERROR;
  1100     cookie->get_secret_keys_called = 1;
  1101 
  1102     T("%zd PKESKs", pkesk_count);
  1103 
  1104     for (size_t i = 0; i < pkesk_count; i ++) {
  1105         pgp_pkesk_t pkesk = pkesks[i];
  1106         pgp_keyid_t keyid = pgp_pkesk_recipient(pkesk); /* Reference. */
  1107         char *keyid_str = pgp_keyid_to_hex(keyid);
  1108         pgp_cert_key_iter_t key_iter = NULL;
  1109         pgp_key_amalgamation_t ka = NULL;
  1110         pgp_key_t key = NULL;
  1111         pgp_session_key_t sk = NULL;
  1112 
  1113         T("Considering PKESK for %s", keyid_str);
  1114 
  1115         if (strcmp(keyid_str, "0000000000000000") == 0) {
  1116             // Initially ignore wildcards.
  1117             wildcards = 1;
  1118             goto eol;
  1119         }
  1120 
  1121         // Collect the recipients.  Note: we must return the primary
  1122         // key's fingerprint.
  1123         pgp_cert_t cert = NULL;
  1124         int is_tsk = 0;
  1125         if (cert_find_by_keyid(session, keyid, false, &cert, &is_tsk) != PEP_STATUS_OK)
  1126             goto eol;
  1127 
  1128         pgp_fingerprint_t fp = pgp_cert_fingerprint(cert);
  1129         char *fp_string = pgp_fingerprint_to_hex(fp);
  1130         stringlist_add_unique(cookie->recipient_keylist, fp_string);
  1131         free(fp_string);
  1132         pgp_fingerprint_free(fp);
  1133 
  1134         if (cookie->decrypted)
  1135             goto eol;
  1136 
  1137         // See if we have the secret key.
  1138         assert(is_tsk == pgp_cert_is_tsk(cert));
  1139         if (! is_tsk)
  1140             goto eol;
  1141 
  1142         key_iter = pgp_cert_key_iter(cert);
  1143         while (key = NULL, (ka = pgp_cert_key_iter_next(key_iter))) {
  1144             key = pgp_key_amalgamation_key (ka);
  1145             pgp_keyid_t this_keyid = pgp_key_keyid(key);
  1146             char *this_keyid_hex = pgp_keyid_to_hex(this_keyid);
  1147             pgp_keyid_free(this_keyid);
  1148 
  1149             int match = strcmp(keyid_str, this_keyid_hex) == 0;
  1150             free(this_keyid_hex);
  1151             if (match)
  1152                 break;
  1153 
  1154             pgp_key_free (key);
  1155             pgp_key_amalgamation_free (ka);
  1156         }
  1157 
  1158         if (key == NULL) {
  1159             assert(!"Inconsistent DB: key doesn't contain a subkey with keyid!");
  1160             goto eol;
  1161         }
  1162 
  1163         uint8_t algo;
  1164         uint8_t session_key[1024];
  1165         size_t session_key_len = sizeof(session_key);
  1166         if (pgp_pkesk_decrypt(&err, pkesk, key, &algo,
  1167                               session_key, &session_key_len) != 0) {
  1168             DUMP_ERR(err, PEP_UNKNOWN_ERROR, "pgp_pkesk_decrypt");
  1169             goto eol;
  1170         }
  1171 
  1172         sk = pgp_session_key_from_bytes (session_key, session_key_len);
  1173         if (! decrypt (decrypt_cookie, algo, sk)) {
  1174             DUMP_STATUS(PGP_STATUS_UNKNOWN_ERROR, PEP_CANNOT_DECRYPT_UNKNOWN, "decrypt_cb");
  1175             goto eol;
  1176         }
  1177 
  1178         T("Decrypted PKESK for %s", keyid_str);
  1179 
  1180         *identity_out = pgp_cert_fingerprint(cert);
  1181         cookie->decrypted = 1;
  1182 
  1183     eol:
  1184         pgp_session_key_free (sk);
  1185         free(keyid_str);
  1186         pgp_key_free (key);
  1187         pgp_key_amalgamation_free (ka);
  1188         pgp_cert_key_iter_free(key_iter);
  1189         pgp_cert_free(cert);
  1190     }
  1191 
  1192     // Consider wildcard recipients.
  1193     if (wildcards) for (size_t i = 0; i < pkesk_count && !cookie->decrypted; i ++) {
  1194         pgp_pkesk_t pkesk = pkesks[i];
  1195         pgp_keyid_t keyid = pgp_pkesk_recipient(pkesk); /* Reference. */
  1196         char *keyid_str = pgp_keyid_to_hex(keyid);
  1197         pgp_cert_key_iter_t key_iter = NULL;
  1198         pgp_key_amalgamation_t ka = NULL;
  1199         pgp_key_t key = NULL;
  1200         pgp_session_key_t sk = NULL;
  1201 
  1202         if (strcmp(keyid_str, "0000000000000000") != 0)
  1203             goto eol2;
  1204 
  1205         if (!tsks) {
  1206             if (cert_all(session, true, &tsks, &tsks_count) != PEP_STATUS_OK) {
  1207                 DUMP_ERR(NULL, PEP_UNKNOWN_ERROR, "Getting all tsks");
  1208             }
  1209         }
  1210 
  1211         for (int j = 0; j < tsks_count; j ++) {
  1212             pgp_cert_t tsk = tsks[j];
  1213 
  1214             key_iter = pgp_cert_key_iter(tsk);
  1215 
  1216             while (key = NULL, (ka = pgp_cert_key_iter_next(key_iter))) {
  1217                 key = pgp_key_amalgamation_key (ka);
  1218 
  1219                 // Note: for decryption to appear to succeed, we must
  1220                 // get a valid algorithm (8 of 256 values) and a
  1221                 // 16-bit checksum must match.  Thus, we have about a
  1222                 // 1 in 2**21 chance of having a false positive here.
  1223                 uint8_t algo;
  1224                 uint8_t session_key[1024];
  1225                 size_t session_key_len = sizeof(session_key);
  1226                 if (pgp_pkesk_decrypt(&err, pkesk, key,
  1227                                       &algo, session_key, &session_key_len)) {
  1228                     pgp_error_free(err);
  1229                     err = NULL;
  1230                     pgp_key_free (key);
  1231                     pgp_key_amalgamation_free (ka);
  1232                     continue;
  1233                 }
  1234 
  1235                 // Add it to the recipient list.
  1236                 pgp_fingerprint_t fp = pgp_cert_fingerprint(tsk);
  1237                 char *fp_string = pgp_fingerprint_to_hex(fp);
  1238                 T("wildcard recipient appears to be %s", fp_string);
  1239                 stringlist_add_unique(cookie->recipient_keylist, fp_string);
  1240                 free(fp_string);
  1241                 pgp_fingerprint_free(fp);
  1242 
  1243                 pgp_session_key_t sk = pgp_session_key_from_bytes (session_key,
  1244                                                                    session_key_len);
  1245                 if (! decrypt (decrypt_cookie, algo, sk)) {
  1246                     DUMP_STATUS(PGP_STATUS_UNKNOWN_ERROR, PEP_CANNOT_DECRYPT_UNKNOWN, "decrypt_cb");
  1247                     goto eol2;
  1248                 }
  1249 
  1250                 *identity_out = pgp_cert_fingerprint(tsk);
  1251                 cookie->decrypted = 1;
  1252 
  1253                 break;
  1254             }
  1255 
  1256             pgp_key_free (key);
  1257             key = NULL;
  1258             pgp_key_amalgamation_free (ka);
  1259             ka = NULL;
  1260             pgp_cert_key_iter_free(key_iter);
  1261             key_iter = NULL;
  1262         }
  1263     eol2:
  1264         pgp_session_key_free (sk);
  1265         free(keyid_str);
  1266         pgp_key_free (key);
  1267         pgp_key_amalgamation_free (ka);
  1268         pgp_cert_key_iter_free(key_iter);
  1269     }
  1270 
  1271     if (tsks) {
  1272         for (int i = 0; i < tsks_count; i ++)
  1273             pgp_cert_free(tsks[i]);
  1274         free(tsks);
  1275     }
  1276 
  1277     return cookie->decrypted ? PGP_STATUS_SUCCESS : PGP_STATUS_UNKNOWN_ERROR;
  1278 }
  1279 
  1280 static pgp_status_t
  1281 check_signatures_cb(void *cookie_opaque, pgp_message_structure_t structure)
  1282 {
  1283     struct decrypt_cookie *cookie = cookie_opaque;
  1284 
  1285     pgp_message_structure_iter_t iter
  1286         = pgp_message_structure_into_iter (structure);
  1287     for (pgp_message_layer_t layer = pgp_message_structure_iter_next (iter);
  1288          layer;
  1289          layer = pgp_message_structure_iter_next (iter)) {
  1290         pgp_verification_result_iter_t results;
  1291 
  1292         switch (pgp_message_layer_variant (layer)) {
  1293         case PGP_MESSAGE_LAYER_COMPRESSION:
  1294         case PGP_MESSAGE_LAYER_ENCRYPTION:
  1295             break;
  1296 
  1297         case PGP_MESSAGE_LAYER_SIGNATURE_GROUP:
  1298             pgp_message_layer_signature_group(layer, &results);
  1299             pgp_verification_result_t result;
  1300             while ((result = pgp_verification_result_iter_next (results))) {
  1301                 pgp_signature_t sig = NULL;
  1302                 pgp_keyid_t keyid = NULL;
  1303                 char *keyid_str = NULL;
  1304                 pgp_error_t error = NULL;
  1305                 char *error_str = NULL;
  1306 
  1307                 switch (pgp_verification_result_variant (result)) {
  1308                 case PGP_VERIFICATION_RESULT_GOOD_CHECKSUM: {
  1309                     // We need to add the fingerprint of the primary
  1310                     // key to cookie->signer_keylist.
  1311 
  1312                     pgp_cert_t cert = NULL;
  1313                     pgp_verification_result_good_checksum (result, &sig,
  1314                                                            &cert,
  1315                                                            NULL, // key
  1316                                                            NULL, // binding
  1317                                                            NULL); // revocation
  1318 
  1319                     // We need the primary key's fingerprint.
  1320                     pgp_fingerprint_t primary_fpr
  1321                         = pgp_cert_fingerprint(cert);
  1322                     char *primary_fpr_str
  1323                         = pgp_fingerprint_to_hex(primary_fpr);
  1324 
  1325                     stringlist_add_unique(cookie->signer_keylist,
  1326                                           primary_fpr_str);
  1327 
  1328                     T("Good signature from %s", primary_fpr_str);
  1329 
  1330                     free (primary_fpr_str);
  1331                     pgp_fingerprint_free (primary_fpr);
  1332                     pgp_cert_free (cert);
  1333 
  1334                     cookie->good_checksums ++;
  1335                     break;
  1336                 }
  1337 
  1338                 case PGP_VERIFICATION_RESULT_MALFORMED_SIGNATURE:
  1339                     if (TRACING) {
  1340                         pgp_verification_result_malformed_signature (result,
  1341                                                                      &sig,
  1342                                                                      &error);
  1343 
  1344                         error_str = pgp_error_to_string(error);
  1345                         keyid = pgp_signature_issuer (sig);
  1346                         keyid_str = pgp_keyid_to_string (keyid);
  1347                         T("Malformed signature from %s: %s",
  1348                           keyid_str, error_str);
  1349                     }
  1350 
  1351                     cookie->malformed_signature ++;
  1352                     break;
  1353 
  1354                 case PGP_VERIFICATION_RESULT_MISSING_KEY:
  1355                     if (TRACING) {
  1356                         pgp_verification_result_missing_key (result, &sig);
  1357                         keyid = pgp_signature_issuer (sig);
  1358                         keyid_str = pgp_keyid_to_string (keyid);
  1359                         T("No key to check signature from %s", keyid_str);
  1360                     }
  1361 
  1362                     cookie->missing_keys ++;
  1363                     break;
  1364 
  1365                 case PGP_VERIFICATION_RESULT_UNBOUND_KEY:
  1366                     // This happens if the key doesn't have a binding
  1367                     // signature.
  1368 
  1369                     if (TRACING) {
  1370                         pgp_verification_result_unbound_key (result,
  1371                                                              &sig,
  1372                                                              NULL,
  1373                                                              &error);
  1374 
  1375                         error_str = pgp_error_to_string(error);
  1376                         keyid = pgp_signature_issuer (sig);
  1377                         keyid_str = pgp_keyid_to_string (keyid);
  1378                         T("key %s has no valid self-signature: %s",
  1379                           keyid_str ? keyid_str : "(missing issuer)",
  1380                           error_str);
  1381                     }
  1382 
  1383                     cookie->unbound_key ++;
  1384                     break;
  1385 
  1386                 case PGP_VERIFICATION_RESULT_BAD_KEY: {
  1387                     // This happens if the certificate is not alive or
  1388                     // revoked, if the key is not alive or revoked, of
  1389                     // if the key is not signing capable.
  1390 
  1391                     pgp_cert_t cert = NULL;
  1392                     pgp_key_t key = NULL;
  1393                     pgp_signature_t selfsig = NULL;
  1394                     pgp_revocation_status_t rs = NULL;
  1395 
  1396                     pgp_verification_result_bad_key (result,
  1397                                                      &sig,
  1398                                                      &cert, // cert
  1399                                                      &key, // key
  1400                                                      &selfsig, // binding
  1401                                                      &rs, // key revocation
  1402                                                      &error);
  1403 
  1404                     if (TRACING) {
  1405                         error_str = pgp_error_to_string(error);
  1406                         keyid = pgp_signature_issuer (sig);
  1407                         keyid_str = pgp_keyid_to_string (keyid);
  1408                         T("key %s is bad: %s",
  1409                           keyid_str ? keyid_str : "(missing issuer)",
  1410                           error_str);
  1411                     }
  1412 
  1413                     // Check if the key or certificate is revoked.
  1414                     if (pgp_revocation_status_variant(rs)
  1415                         == PGP_REVOCATION_STATUS_REVOKED) {
  1416                         // Key is revoked.
  1417                         cookie->revoked_key ++;
  1418                     } else {
  1419                         pgp_revocation_status_free (rs);
  1420                         rs = pgp_cert_revocation_status (cert, cookie->session->policy, 0);
  1421                         if (pgp_revocation_status_variant(rs)
  1422                             == PGP_REVOCATION_STATUS_REVOKED) {
  1423                             // Cert is revoked.
  1424                             cookie->revoked_key ++;
  1425                         }
  1426                         // Check if the key or certificate is expired.
  1427                         else if (pgp_cert_alive(NULL, cert,
  1428                                                 cookie->session->policy, 0)
  1429                                  != PGP_STATUS_SUCCESS) {
  1430                             // Certificate is expired.
  1431                             cookie->expired_key ++;
  1432                             goto out;
  1433                         } else if (pgp_signature_key_alive (NULL, selfsig, key, 0)
  1434                                    != PGP_STATUS_SUCCESS) {
  1435                             // Key is expired.
  1436                             cookie->expired_key ++;
  1437                             goto out;
  1438                         }
  1439                         // Wrong key flags or something similar.
  1440                         else {
  1441                             cookie->bad_key ++;
  1442                         }
  1443                     }
  1444 
  1445                 out:
  1446                     pgp_revocation_status_free (rs);
  1447                     pgp_signature_free (selfsig);
  1448                     pgp_key_free (key);
  1449                     pgp_cert_free (cert);
  1450 
  1451                     break;
  1452                 }
  1453 
  1454                 case PGP_VERIFICATION_RESULT_BAD_SIGNATURE:
  1455                     if (TRACING) {
  1456                         pgp_verification_result_bad_signature
  1457                             (result, &sig, NULL, NULL, NULL, NULL, &error);
  1458                         error_str = pgp_error_to_string(error);
  1459                         keyid = pgp_signature_issuer (sig);
  1460                         if (keyid) {
  1461                             keyid_str = pgp_keyid_to_string (keyid);
  1462                             T("Bad signature from %s: %s",
  1463                               keyid_str, error_str);
  1464                         } else {
  1465                             T("Bad signature without issuer information: %s",
  1466                               error_str);
  1467                         }
  1468                     }
  1469 
  1470                     cookie->bad_checksums ++;
  1471                     break;
  1472 
  1473                 default:
  1474                     assert (! "reachable");
  1475                 }
  1476 
  1477                 free (keyid_str);
  1478                 pgp_signature_free (sig);
  1479                 free (error_str);
  1480                 pgp_error_free (error);
  1481                 pgp_verification_result_free (result);
  1482             }
  1483             pgp_verification_result_iter_free (results);
  1484             break;
  1485 
  1486         default:
  1487             assert (! "reachable");
  1488         }
  1489 
  1490         pgp_message_layer_free (layer);
  1491     }
  1492 
  1493     pgp_message_structure_iter_free (iter);
  1494 
  1495     return PGP_STATUS_SUCCESS;
  1496 }
  1497 
  1498 static pgp_status_t inspect_cb(
  1499     void *cookie_opaque, pgp_packet_parser_t pp)
  1500 {
  1501     struct decrypt_cookie *cookie = cookie_opaque;
  1502 
  1503     pgp_packet_t packet = pgp_packet_parser_packet(pp);
  1504     assert(packet);
  1505 
  1506     pgp_tag_t tag = pgp_packet_tag(packet);
  1507 
  1508     T("%s", pgp_tag_to_string(tag));
  1509 
  1510     if (tag == PGP_TAG_LITERAL) {
  1511         pgp_literal_t literal = pgp_packet_ref_literal(packet);
  1512         cookie->filename = pgp_literal_filename(literal);
  1513         pgp_literal_free(literal);
  1514     }
  1515 
  1516     pgp_packet_free(packet);
  1517 
  1518     return 0;
  1519 }
  1520 
  1521 PEP_STATUS pgp_decrypt_and_verify(
  1522     PEP_SESSION session, const char *ctext, size_t csize,
  1523     const char *dsigtext, size_t dsigsize,
  1524     char **ptext, size_t *psize, stringlist_t **keylist,
  1525     char** filename_ptr)
  1526 {
  1527     PEP_STATUS status = PEP_STATUS_OK;
  1528     struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL };
  1529     pgp_reader_t reader = NULL;
  1530     pgp_writer_t writer = NULL;
  1531     pgp_reader_t decryptor = NULL;
  1532     *ptext = NULL;
  1533     *psize = 0;
  1534 
  1535     // XXX: We don't yet handle detached signatures over encrypted
  1536     // messages.
  1537     assert(!dsigtext);
  1538 
  1539     cookie.recipient_keylist = new_stringlist(NULL);
  1540     if (!cookie.recipient_keylist)
  1541         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "recipient_keylist");
  1542 
  1543     cookie.signer_keylist = new_stringlist(NULL);
  1544     if (!cookie.signer_keylist)
  1545         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "signer_keylist");
  1546 
  1547     reader = pgp_reader_from_bytes((const uint8_t *) ctext, csize);
  1548     if (! reader)
  1549         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating reader");
  1550 
  1551     writer = pgp_writer_alloc((void **) ptext, psize);
  1552     if (! writer)
  1553         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "Creating writer");
  1554 
  1555     pgp_error_t err = NULL;
  1556     decryptor = pgp_decryptor_new(&err, session->policy, reader,
  1557                                   get_public_keys_cb, decrypt_cb,
  1558                                   check_signatures_cb, inspect_cb,
  1559                                   &cookie, 0);
  1560     if (! decryptor)
  1561         ERROR_OUT(err, PEP_DECRYPT_NO_KEY, "pgp_decryptor_new");
  1562 
  1563     // Copy 128 MB at a time.
  1564     ssize_t nread;
  1565     while ((nread = pgp_reader_copy (&err, decryptor, writer,
  1566                                      128 * 1024 * 1024) > 0))
  1567         ;
  1568     if (nread < 0)
  1569         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "pgp_reader_read");
  1570 
  1571     // Add a terminating NUL for naive users
  1572     pgp_writer_write(&err, writer, (const uint8_t *) &""[0], 1);
  1573 
  1574     if (! cookie.decrypted)
  1575         ERROR_OUT(err, PEP_DECRYPT_NO_KEY, "Decryption failed");
  1576 
  1577     if (! cookie.signer_keylist) {
  1578         cookie.signer_keylist = new_stringlist("");
  1579         if (! cookie.signer_keylist)
  1580             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "cookie.signer_keylist");
  1581     }
  1582     if (!cookie.signer_keylist->value)
  1583         stringlist_add(cookie.signer_keylist, "");
  1584 
  1585     *keylist = cookie.signer_keylist;
  1586     stringlist_append(*keylist, cookie.recipient_keylist);
  1587 
  1588     if (filename_ptr)
  1589         *filename_ptr = cookie.filename;
  1590 
  1591  out:
  1592     if (status == PEP_STATUS_OK) {
  1593         // **********************************
  1594         // Sync changes with pgp_verify_text.
  1595         // **********************************
  1596 
  1597         if (cookie.good_checksums) {
  1598             // If there is at least one signature that we can verify,
  1599             // succeed.
  1600             status = PEP_DECRYPTED_AND_VERIFIED;
  1601         } else if (cookie.revoked_key) {
  1602             // If there are any signatures from revoked keys, fail.
  1603             status = PEP_VERIFY_SIGNER_KEY_REVOKED;
  1604         } else if (cookie.expired_key) {
  1605             // If there are any signatures from expired keys, fail.
  1606             status = PEP_DECRYPTED;
  1607         } else if (cookie.bad_key) {
  1608             // If there are any signatures from invalid keys (keys
  1609             // that are not signing capable), fail.
  1610             status = PEP_DECRYPTED;
  1611         } else if (cookie.bad_checksums) {
  1612             // If there are any bad signatures, fail.
  1613             status = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  1614         } else {
  1615             // We couldn't verify any signatures (possibly because we
  1616             // don't have the keys).
  1617             status = PEP_DECRYPTED;
  1618         }
  1619     } else {
  1620         free_stringlist(cookie.recipient_keylist);
  1621         free_stringlist(cookie.signer_keylist);
  1622         free(cookie.filename);
  1623         free(*ptext);
  1624     }
  1625 
  1626     pgp_reader_free(reader);
  1627     pgp_reader_free(decryptor);
  1628     pgp_writer_free(writer);
  1629 
  1630     T("-> %s", pEp_status_to_string(status));
  1631     return status;
  1632 }
  1633 
  1634 PEP_STATUS pgp_verify_text(
  1635     PEP_SESSION session, const char *text, size_t size,
  1636     const char *signature, size_t sig_size, stringlist_t **keylist)
  1637 {
  1638     PEP_STATUS status = PEP_STATUS_OK;
  1639     pgp_error_t err = NULL;
  1640     struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, };
  1641     pgp_reader_t reader = NULL;
  1642     pgp_reader_t dsig_reader = NULL;
  1643 
  1644     if (size == 0 || sig_size == 0)
  1645         return PEP_DECRYPT_WRONG_FORMAT;
  1646 
  1647 #if TRACING > 0
  1648     {
  1649         int cr = 0;
  1650         int crlf = 0;
  1651         int lf = 0;
  1652 
  1653         for (int i = 0; i < size; i ++) {
  1654             // CR
  1655             if (text[i] == '\r') {
  1656                 cr ++;
  1657             }
  1658             // LF
  1659             if (text[i] == '\n') {
  1660                 if (i > 0 && text[i - 1] == '\r') {
  1661                     cr --;
  1662                     crlf ++;
  1663                 } else {
  1664                     lf ++;
  1665                 }
  1666             }
  1667         }
  1668 
  1669         T("Text to verify: %zd bytes with %d crlfs, %d bare crs and %d bare lfs",
  1670           size, crlf, cr, lf);
  1671     }
  1672 #endif
  1673 
  1674     cookie.recipient_keylist = new_stringlist(NULL);
  1675     if (!cookie.recipient_keylist)
  1676         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1677 
  1678     cookie.signer_keylist = new_stringlist(NULL);
  1679     if (!cookie.signer_keylist)
  1680         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1681 
  1682     reader = pgp_reader_from_bytes((const uint8_t *) text, size);
  1683     if (! reader)
  1684         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating reader");
  1685 
  1686     dsig_reader = NULL;
  1687     if (signature) {
  1688         dsig_reader = pgp_reader_from_bytes((uint8_t *) signature, sig_size);
  1689         if (! dsig_reader)
  1690             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating signature reader");
  1691     }
  1692 
  1693     if (dsig_reader) {
  1694         pgp_detached_verifier_t verifier
  1695             = pgp_detached_verifier_new(&err, session->policy,
  1696                                         dsig_reader,
  1697                                         get_public_keys_cb,
  1698                                         check_signatures_cb,
  1699                                         NULL,
  1700                                         &cookie, 0);
  1701         if (! verifier)
  1702             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Creating verifier");
  1703 
  1704         pgp_status_t pgp_status = pgp_detached_verifier_verify (&err, verifier, reader);
  1705         pgp_detached_verifier_free (verifier);
  1706         if (pgp_status)
  1707             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Verifying data");
  1708     } else {
  1709         pgp_reader_t verifier = NULL;
  1710         verifier = pgp_verifier_new(&err, session->policy, reader,
  1711                                     get_public_keys_cb,
  1712                                     check_signatures_cb,
  1713                                     NULL,
  1714                                     &cookie, 0);
  1715         if (! verifier)
  1716             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Creating verifier");
  1717 
  1718         pgp_status_t pgp_status = pgp_reader_discard(&err, verifier);
  1719         pgp_reader_free(verifier);
  1720         if (pgp_status)
  1721             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "verifier");
  1722     }
  1723 
  1724     if (! cookie.signer_keylist) {
  1725         cookie.signer_keylist = new_stringlist("");
  1726         if (! cookie.signer_keylist)
  1727             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "cookie.signer_keylist");
  1728     }
  1729     if (!cookie.signer_keylist->value)
  1730         stringlist_add(cookie.signer_keylist, "");
  1731 
  1732     *keylist = cookie.signer_keylist;
  1733     stringlist_append(*keylist, cookie.recipient_keylist);
  1734 
  1735  out:
  1736     if (status == PEP_STATUS_OK) {
  1737         // *****************************************
  1738         // Sync changes with pgp_decrypt_and_verify.
  1739         // *****************************************
  1740 
  1741         if (cookie.good_checksums) {
  1742             // If there is at least one signature that we can verify,
  1743             // succeed.
  1744             status = PEP_VERIFIED;
  1745         } else if (cookie.revoked_key) {
  1746             // If there are any signatures from revoked keys, fail.
  1747             status = PEP_VERIFY_SIGNER_KEY_REVOKED;
  1748         } else if (cookie.expired_key) {
  1749             // If there are any signatures from expired keys, fail.
  1750             status = PEP_DECRYPTED;
  1751         } else if (cookie.bad_key) {
  1752             // If there are any signatures from invalid keys (keys
  1753             // that are not signing capable), fail.
  1754             status = PEP_DECRYPTED;
  1755         } else if (cookie.bad_checksums) {
  1756             // If there are any bad signatures, fail.
  1757             status = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  1758         } else {
  1759             // We couldn't verify any signatures (possibly because we
  1760             // don't have the keys).
  1761             status = PEP_UNENCRYPTED;
  1762         }
  1763     } else {
  1764         free_stringlist(cookie.recipient_keylist);
  1765         free_stringlist(cookie.signer_keylist);
  1766     }
  1767 
  1768     pgp_reader_free(reader);
  1769     pgp_reader_free(dsig_reader);
  1770 
  1771     T("-> %s", pEp_status_to_string(status));
  1772     return status;
  1773 }
  1774 
  1775 
  1776 PEP_STATUS pgp_sign_only(
  1777     PEP_SESSION session, const char* fpr, const char *ptext,
  1778     size_t psize, char **stext, size_t *ssize)
  1779 {
  1780     assert(session);
  1781     assert(fpr && fpr[0]);
  1782     assert(ptext);
  1783     assert(psize);
  1784     assert(stext);
  1785     assert(ssize);
  1786     *stext = NULL;
  1787     *ssize = 0;
  1788 
  1789     PEP_STATUS status = PEP_STATUS_OK;
  1790     pgp_error_t err = NULL;
  1791     pgp_cert_t signer_cert = NULL;
  1792     pgp_cert_valid_key_iter_t iter = NULL;
  1793     pgp_valid_key_amalgamation_t ka = NULL;
  1794     pgp_key_pair_t signing_keypair = NULL;
  1795     pgp_signer_t signer = NULL;
  1796     pgp_writer_stack_t ws = NULL;
  1797 
  1798     status = cert_find_by_fpr_hex(session, fpr, true, &signer_cert, NULL);
  1799     ERROR_OUT(NULL, status, "Looking up key '%s'", fpr);
  1800 
  1801     iter = pgp_cert_valid_key_iter(signer_cert, session->policy, 0);
  1802     pgp_cert_valid_key_iter_alive(iter);
  1803     pgp_cert_valid_key_iter_revoked(iter, false);
  1804     pgp_cert_valid_key_iter_for_signing (iter);
  1805     pgp_cert_valid_key_iter_unencrypted_secret (iter);
  1806 
  1807     // If there are multiple signing capable subkeys, we just take
  1808     // the first one, whichever one that happens to be.
  1809     ka = pgp_cert_valid_key_iter_next (iter, NULL, NULL);
  1810     if (! ka)
  1811         ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  1812                    "%s has no signing capable key", fpr);
  1813 
  1814     // pgp_key_into_key_pair needs to own the key, but here we
  1815     // only get a reference (which we still need to free).
  1816     pgp_key_t key = pgp_valid_key_amalgamation_key (ka);
  1817     signing_keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  1818     pgp_key_free (key);
  1819     if (! signing_keypair)
  1820         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  1821 
  1822     signer = pgp_key_pair_as_signer (signing_keypair);
  1823     if (! signer)
  1824         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  1825 
  1826 
  1827     pgp_writer_t writer = pgp_writer_alloc((void **) stext, ssize);
  1828     writer = pgp_armor_writer_new(&err, writer,
  1829                                   PGP_ARMOR_KIND_MESSAGE, NULL, 0);
  1830     if (!writer)
  1831         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up armor writer");
  1832 
  1833     ws = pgp_writer_stack_message(writer);
  1834 
  1835     ws = pgp_signer_new_detached(&err, ws, &signer, 1, 0);
  1836     if (!ws)
  1837         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
  1838     // pgp_signer_new_detached consumes signer.
  1839     signer = NULL;
  1840 
  1841     pgp_status_t write_status =
  1842         pgp_writer_stack_write_all (&err, ws,
  1843                                     (uint8_t *) ptext, psize);
  1844     if (write_status != 0)
  1845         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
  1846 
  1847     pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
  1848     ws = NULL;
  1849     if (pgp_status != 0)
  1850         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
  1851 
  1852     pgp_status = pgp_armor_writer_finalize (&err, writer);
  1853     if (pgp_status != 0)
  1854         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing armor writer");
  1855 
  1856     // Add a terminating NUL for naive users
  1857     void *t = realloc(*stext, *ssize + 1);
  1858     if (! t)
  1859         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1860     *stext = t;
  1861     (*stext)[*ssize] = 0;
  1862 
  1863  out:
  1864     pgp_signer_free (signer);
  1865     // XXX: pgp_key_pair_as_signer is only supposed to reference
  1866     // signing_keypair, but it consumes it.  If this is fixed, this
  1867     // will become a leak.
  1868     //
  1869     //pgp_key_pair_free (signing_keypair);
  1870     pgp_valid_key_amalgamation_free (ka);
  1871     pgp_cert_valid_key_iter_free (iter);
  1872     pgp_cert_free(signer_cert);
  1873 
  1874     T("(%s)-> %s", fpr, pEp_status_to_string(status));
  1875     return status;
  1876 }
  1877 
  1878 static PEP_STATUS pgp_encrypt_sign_optional(
  1879     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  1880     size_t psize, char **ctext, size_t *csize, bool sign)
  1881 {
  1882     PEP_STATUS status = PEP_STATUS_OK;
  1883     pgp_error_t err = NULL;
  1884 
  1885     int recipient_cert_count = 0;
  1886     pgp_cert_t *recipient_certs = NULL;
  1887 
  1888     int recipient_count = 0;
  1889     int recipient_alloc = 0;
  1890     pgp_recipient_t *recipients = NULL;
  1891     int recipient_keys_count = 0;
  1892     pgp_key_t *recipient_keys = NULL;
  1893 
  1894     pgp_cert_t signer_cert = NULL;
  1895     pgp_writer_stack_t ws = NULL;
  1896     pgp_cert_valid_key_iter_t iter = NULL;
  1897     pgp_valid_key_amalgamation_t ka = NULL;
  1898     pgp_key_pair_t signing_keypair = NULL;
  1899     pgp_signer_t signer = NULL;
  1900 
  1901     assert(session);
  1902     assert(keylist);
  1903     assert(ptext);
  1904     assert(psize);
  1905     assert(ctext);
  1906     assert(csize);
  1907 
  1908     *ctext = NULL;
  1909     *csize = 0;
  1910 
  1911     int keylist_len = stringlist_length(keylist);
  1912 
  1913     // We don't need to worry about extending recipient_certs, because
  1914     // there will be at most KEYLIST_LEN certs, which we allocate up
  1915     // front.
  1916     recipient_certs = calloc(keylist_len, sizeof(*recipient_certs));
  1917     if (recipient_certs == NULL)
  1918         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1919 
  1920     // Because there may be multiple encryption keys per certificate, we may
  1921     // need to extend recipient_keys and recipients.
  1922     recipient_alloc = keylist_len;
  1923     recipient_keys = calloc(recipient_alloc, sizeof(*recipient_keys));
  1924     if (recipient_keys == NULL)
  1925         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1926 
  1927     recipients = calloc(recipient_alloc, sizeof(*recipients));
  1928     if (recipients == NULL)
  1929         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1930 
  1931 
  1932     // Get the keys for the recipients.
  1933     const stringlist_t *_keylist;
  1934     for (_keylist = keylist; _keylist != NULL; _keylist = _keylist->next) {
  1935         assert(_keylist->value);
  1936 
  1937         pgp_cert_t cert;
  1938         status = cert_find_by_fpr_hex(session, _keylist->value,
  1939                                      false, &cert, NULL);
  1940         // We couldn't find a key for this recipient.
  1941         ERROR_OUT(NULL, status,
  1942                   "Looking up key for recipient '%s'", _keylist->value);
  1943 
  1944         recipient_certs[recipient_cert_count ++] = cert;
  1945 
  1946         // Collect all of the keys that have the encryption for
  1947         // transport capability.
  1948         iter = pgp_cert_valid_key_iter(cert, session->policy, 0);
  1949         if (! iter)
  1950             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1951         pgp_cert_valid_key_iter_alive(iter);
  1952         pgp_cert_valid_key_iter_revoked(iter, false);
  1953         pgp_cert_valid_key_iter_for_transport_encryption(iter);
  1954 
  1955         while ((ka = pgp_cert_valid_key_iter_next (iter, NULL, NULL))) {
  1956             assert(recipient_count == recipient_keys_count);
  1957             if (recipient_count == recipient_alloc) {
  1958                 assert(recipient_alloc > 0);
  1959                 recipient_alloc *= 2;
  1960 
  1961                 void *t = _pEp_reallocarray(recipient_keys, recipient_alloc,
  1962                                             sizeof(*recipient_keys));
  1963                 if (! t)
  1964                     ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1965                 recipient_keys = t;
  1966 
  1967                 t = _pEp_reallocarray(recipients, recipient_alloc,
  1968                                       sizeof(*recipients));
  1969                 if (! t)
  1970                     ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1971                 recipients = t;
  1972             }
  1973 
  1974             // pgp_valid_key_amalgamation_key returns a reference to
  1975             // ka.  We need to keep it around after this iteration.
  1976             // So, we clone it.  Unfortunately, although
  1977             // pgp_recipient_new consumes the passed key id, it only
  1978             // references the key.  So, we need to remember to free it
  1979             // at the end.
  1980             pgp_key_t key = pgp_valid_key_amalgamation_key (ka);
  1981             recipient_keys[recipient_keys_count ++] = pgp_key_clone (key);
  1982             pgp_key_free (key);
  1983 
  1984             pgp_keyid_t keyid = pgp_key_keyid(recipient_keys[recipient_keys_count - 1]);
  1985             if (! keyid)
  1986                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1987 
  1988             recipients[recipient_count++] = pgp_recipient_new(keyid, recipient_keys[recipient_keys_count - 1]);
  1989 
  1990             pgp_valid_key_amalgamation_free (ka);
  1991         }
  1992         pgp_cert_valid_key_iter_free(iter);
  1993         iter = NULL;
  1994     }
  1995 
  1996     if (sign) {
  1997         // The first key in the keylist is the signer.
  1998         status = cert_find_by_fpr_hex(session, keylist->value, true, &signer_cert, NULL);
  1999         ERROR_OUT(NULL, status, "Looking up key for signing '%s'", keylist->value);
  2000     }
  2001 
  2002     pgp_writer_t writer_alloc = pgp_writer_alloc((void **) ctext, csize);
  2003     pgp_writer_t writer = pgp_armor_writer_new(&err, writer_alloc,
  2004                                   PGP_ARMOR_KIND_MESSAGE, NULL, 0);
  2005     if (!writer)
  2006         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up armor writer");
  2007 
  2008     ws = pgp_writer_stack_message(writer);
  2009     ws = pgp_encryptor_new (&err, ws,
  2010                             NULL, 0, recipients, recipient_count,
  2011                             0, 0);
  2012     if (!ws)
  2013         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up encryptor");
  2014 
  2015     // pgp_encrypt_new consumes the recipients (but not the keys).
  2016     recipient_count = 0;
  2017 
  2018     if (sign) {
  2019         iter = pgp_cert_valid_key_iter(signer_cert, session->policy, 0);
  2020         pgp_cert_valid_key_iter_alive(iter);
  2021         pgp_cert_valid_key_iter_revoked(iter, false);
  2022         pgp_cert_valid_key_iter_for_signing (iter);
  2023         pgp_cert_valid_key_iter_unencrypted_secret (iter);
  2024 
  2025         // If there are multiple signing capable subkeys, we just take
  2026         // the first one, whichever one that happens to be.
  2027         ka = pgp_cert_valid_key_iter_next (iter, NULL, NULL);
  2028         if (! ka)
  2029             ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  2030                        "%s has no signing capable key", keylist->value);
  2031 
  2032         // pgp_key_into_key_pair needs to own the key, but here we
  2033         // only get a reference (which we still need to free).
  2034         pgp_key_t key = pgp_valid_key_amalgamation_key (ka);
  2035         signing_keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  2036         pgp_key_free (key);
  2037         if (! signing_keypair)
  2038             ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  2039 
  2040         signer = pgp_key_pair_as_signer (signing_keypair);
  2041         if (! signer)
  2042             ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  2043 
  2044         ws = pgp_signer_new(&err, ws, &signer, 1, 0);
  2045         if (!ws)
  2046             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
  2047         // pgp_signer_new consumes signer.
  2048         signer = NULL;
  2049     }
  2050 
  2051     ws = pgp_literal_writer_new (&err, ws);
  2052     if (!ws)
  2053         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up literal writer");
  2054 
  2055     pgp_status_t write_status =
  2056         pgp_writer_stack_write_all (&err, ws,
  2057                                     (uint8_t *) ptext, psize);
  2058     if (write_status != 0)
  2059         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
  2060 
  2061     pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
  2062     ws = NULL;
  2063     if (pgp_status != 0)
  2064         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
  2065 
  2066     pgp_status = pgp_armor_writer_finalize (&err, writer);
  2067     if (pgp_status != 0)
  2068         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing armor writer");
  2069 
  2070     pgp_writer_free (writer_alloc);
  2071 
  2072     // Add a terminating NUL for naive users
  2073     void *t = realloc(*ctext, *csize + 1);
  2074     if (! t) {
  2075         free(*ctext);
  2076         *ctext = NULL;
  2077         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  2078     }
  2079     *ctext = t;
  2080     (*ctext)[*csize] = 0;
  2081 
  2082  out:
  2083     pgp_signer_free (signer);
  2084     // XXX: pgp_key_pair_as_signer is only supposed to reference
  2085     // signing_keypair, but it consumes it.  If this is fixed, this
  2086     // will become a leak.
  2087     //
  2088     // pgp_key_pair_free (signing_keypair);
  2089     pgp_valid_key_amalgamation_free (ka);
  2090     pgp_cert_valid_key_iter_free (iter);
  2091     pgp_cert_free(signer_cert);
  2092 
  2093     for (int i = 0; i < recipient_count; i ++)
  2094         pgp_recipient_free(recipients[i]);
  2095     free(recipients);
  2096     for (int i = 0; i < recipient_keys_count; i ++)
  2097         pgp_key_free(recipient_keys[i]);
  2098     free(recipient_keys);
  2099     for (int i = 0; i < recipient_cert_count; i ++)
  2100         pgp_cert_free(recipient_certs[i]);
  2101     free(recipient_certs);
  2102 
  2103     T("-> %s", pEp_status_to_string(status));
  2104     return status;
  2105 }
  2106 
  2107 PEP_STATUS pgp_encrypt_only(
  2108     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  2109     size_t psize, char **ctext, size_t *csize)
  2110 {
  2111     return pgp_encrypt_sign_optional(session, keylist, ptext,
  2112         psize, ctext, csize, false);
  2113 }
  2114 
  2115 PEP_STATUS pgp_encrypt_and_sign(
  2116     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  2117     size_t psize, char **ctext, size_t *csize)
  2118 {
  2119     return pgp_encrypt_sign_optional(session, keylist, ptext,
  2120         psize, ctext, csize, true);
  2121 }
  2122 
  2123 static char* _filter_parentheses(const char* input) {
  2124     if (!input)
  2125         return NULL;
  2126     
  2127     int input_len = strlen(input) + 1;
  2128     char* retval = calloc(input_len, 1);
  2129     strlcpy(retval, input, input_len);
  2130 
  2131     char* curr_c;
  2132     
  2133     for (curr_c = retval; curr_c && *curr_c != '\0'; curr_c++) {
  2134         switch(*curr_c) {
  2135             case '(':
  2136                 *curr_c = '[';
  2137                 break;
  2138             case ')':
  2139                 *curr_c = ']';
  2140                 break;
  2141             default:
  2142                 break;
  2143         }
  2144     }  
  2145     
  2146     return retval;
  2147 }
  2148 
  2149 static char* _flatten_to_alphanum(const char* input) {
  2150     if (!input)
  2151         return NULL;
  2152     
  2153     int input_len = strlen(input) + 1;
  2154     char* retval = calloc(input_len, 1);
  2155     strlcpy(retval, input, input_len);
  2156 
  2157     char* curr_c;
  2158     
  2159     for (curr_c = retval; curr_c && *curr_c != '\0'; curr_c++) {
  2160         char c = *curr_c;
  2161 
  2162         if (c == ' ' || (c >= 'A' && c <= 'Z') || 
  2163                         (c >= 'a' && c <= 'z') ||
  2164                         (c >= '0' && c <= '9'))
  2165             continue;           
  2166 
  2167         *curr_c = '_';
  2168     }  
  2169     
  2170     return retval;
  2171 }
  2172 
  2173 PEP_STATUS _pgp_generate_keypair(PEP_SESSION session, pEp_identity *identity, time_t when)
  2174 {
  2175     PEP_STATUS status = PEP_STATUS_OK;
  2176     pgp_error_t err = NULL;
  2177     pgp_packet_t userid_packet = NULL;
  2178     char *userid = NULL;
  2179     pgp_cert_t cert = NULL;
  2180     pgp_fingerprint_t pgp_fpr = NULL;
  2181     char *fpr = NULL;
  2182 
  2183     assert(session);
  2184     assert(identity);
  2185     assert(identity->address);
  2186     assert(identity->fpr == NULL || identity->fpr[0] == 0);
  2187 //    assert(identity->username);
  2188 
  2189     char* cached_username = identity->username;
  2190     
  2191     if (identity->username && strcmp(identity->address, identity->username) == 0) {
  2192         cached_username = identity->username;
  2193         identity->username = NULL;
  2194     }
  2195     
  2196 
  2197     userid_packet = pgp_user_id_from_unchecked_address(&err,
  2198                                                        identity->username, NULL,
  2199                                                        identity->address);           
  2200                                                    
  2201     if (!userid_packet) {
  2202         char* tmpname = _filter_parentheses(identity->username);
  2203         userid_packet = pgp_user_id_from_unchecked_address(&err,
  2204                                                            tmpname, NULL,
  2205                                                            identity->address);               
  2206         free(tmpname);                                                   
  2207     }
  2208 
  2209     if (!userid_packet) {
  2210         char* tmpname = _flatten_to_alphanum(identity->username);
  2211         userid_packet = pgp_user_id_from_unchecked_address(&err,
  2212                                                            tmpname, NULL,
  2213                                                            identity->address);               
  2214         free(tmpname);                                                           
  2215     }
  2216                                             
  2217     identity->username = cached_username;                                                   
  2218     
  2219     if (!userid_packet)
  2220         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "pgp_user_id_from_unchecked_address");
  2221 
  2222     size_t userid_len = 0;
  2223     const uint8_t *raw = pgp_user_id_value(userid_packet, &userid_len);
  2224 
  2225     // NUL terminate it.
  2226     userid = malloc(userid_len + 1);
  2227     if (!userid)
  2228         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  2229 
  2230     memcpy(userid, raw, userid_len);
  2231     userid[userid_len] = 0;
  2232 
  2233     T("(%s)", userid);
  2234 
  2235     // Generate a key.
  2236     pgp_cert_builder_t certb = pgp_cert_builder_general_purpose(
  2237         cipher_suite(session->cipher_suite), userid);
  2238 
  2239     pgp_cert_builder_set_creation_time(&certb, when);
  2240 
  2241     pgp_signature_t rev;
  2242     if (pgp_cert_builder_generate(&err, certb, &cert, &rev))
  2243         ERROR_OUT(err, PEP_CANNOT_CREATE_KEY, "Generating a key pair");
  2244 
  2245     // XXX: We should return this.
  2246     pgp_signature_free(rev);
  2247 
  2248     // Get the fingerprint.
  2249     pgp_fpr = pgp_cert_fingerprint(cert);
  2250     fpr = pgp_fingerprint_to_hex(pgp_fpr);
  2251 
  2252     status = cert_save(session, cert, NULL, NULL);
  2253     cert = NULL;
  2254     if (status != 0)
  2255         ERROR_OUT(NULL, PEP_CANNOT_CREATE_KEY, "saving TSK");
  2256 
  2257     free(identity->fpr);
  2258     identity->fpr = fpr;
  2259     fpr = NULL;
  2260 
  2261  out:
  2262     pgp_fingerprint_free(pgp_fpr);
  2263     free(fpr);
  2264     pgp_cert_free(cert);
  2265     free(userid);
  2266     pgp_packet_free(userid_packet);
  2267 
  2268     T("-> %s", pEp_status_to_string(status));
  2269     return status;
  2270 }
  2271 
  2272 PEP_STATUS pgp_generate_keypair(PEP_SESSION session, pEp_identity *identity)
  2273 {
  2274     return _pgp_generate_keypair(session, identity, 0);
  2275 }
  2276 
  2277 PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr_raw)
  2278 {
  2279     PEP_STATUS status = PEP_STATUS_OK;
  2280 
  2281     assert(session && fpr_raw && fpr_raw[0]);
  2282     if (!(session && fpr_raw && fpr_raw[0]))
  2283         ERROR_OUT(NULL, PEP_ILLEGAL_VALUE, "invalid arguments");
  2284 
  2285     char *fpr = pgp_fingerprint_canonicalize(fpr_raw);
  2286     if (! fpr)
  2287         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  2288 
  2289     T("Deleting %s", fpr);
  2290 
  2291     sqlite3_stmt *stmt = session->sq_sql.delete_keypair;
  2292     sqlite3_bind_text(stmt, 1, fpr, -1, free);
  2293 
  2294     int sqlite_result = sqlite3_step(stmt);
  2295     sqlite3_reset(stmt);
  2296     if (sqlite_result != SQLITE_DONE)
  2297         ERROR_OUT(NULL, PEP_CANNOT_DELETE_KEY,
  2298                   "deletion failed: %s", sqlite3_errmsg(session->key_db));
  2299 
  2300     sqlite_result = sqlite3_changes(session->key_db);
  2301     assert(sqlite_result >= 0 && sqlite_result < 2);
  2302     if (sqlite_result < 1)
  2303         ERROR_OUT(NULL, PEP_KEY_NOT_FOUND,
  2304                   "attempt to delete non-existent key: %s", fpr_raw);
  2305 
  2306  out:
  2307     return status;
  2308 }
  2309 
  2310 static unsigned int count_keydata_parts(const char* key_data, size_t size) {
  2311     unsigned int retval = 0;
  2312 
  2313     const char* pgp_begin = "-----BEGIN PGP";
  2314     size_t prefix_len = strlen(pgp_begin);
  2315     size_t size_remaining = size;
  2316 
  2317     while (key_data) {
  2318         if (size_remaining <= prefix_len || key_data[0] == '\0')
  2319             break;
  2320         key_data = strnstr(key_data, pgp_begin, size_remaining);
  2321         if (key_data) {
  2322             retval++;
  2323             key_data += prefix_len;
  2324             size_remaining -= prefix_len;
  2325         }
  2326     }
  2327     return retval;
  2328  }
  2329 
  2330 // This is for single keys, which is why we're using a boolean here.
  2331 PEP_STATUS _pgp_import_keydata(PEP_SESSION session, const char *key_data,
  2332                                size_t size, identity_list **private_idents,
  2333                                stringlist_t** imported_keys,
  2334                                uint64_t* changed_bitvec)
  2335 {
  2336     PEP_STATUS status = PEP_NO_KEY_IMPORTED;
  2337     pgp_error_t err;
  2338     pgp_cert_parser_t parser = NULL;
  2339     char* issuer_fpr_hex = NULL;
  2340     char* cert_fpr_hex = NULL;
  2341     
  2342     if (changed_bitvec && !imported_keys)
  2343         return PEP_ILLEGAL_VALUE;    
  2344 
  2345     if (private_idents)
  2346         *private_idents = NULL;
  2347 
  2348     stringlist_t* _import_keylist = imported_keys ? *imported_keys : NULL;    
  2349     int _import_keylist_len = stringlist_length(_import_keylist);    
  2350         
  2351     T("parsing %zd bytes", size);
  2352 
  2353     pgp_packet_parser_result_t ppr
  2354         = pgp_packet_parser_from_bytes(&err, (uint8_t *) key_data, size);
  2355     if (! ppr)
  2356         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Creating packet parser");
  2357 
  2358     pgp_tag_t tag = pgp_packet_parser_result_tag(ppr);
  2359     switch (tag) {
  2360     case PGP_TAG_SIGNATURE: {
  2361         // The following asserts can't fail, because
  2362         // pgp_packet_parser_result_tag succeeded and the tag is
  2363         // right.
  2364         pgp_packet_parser_t pp = pgp_packet_parser_result_packet_parser (ppr);
  2365         assert(pp);
  2366 
  2367         pgp_packet_t packet = NULL;
  2368         if (pgp_packet_parser_next(&err, pp, &packet, &ppr))
  2369             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Getting signature packet");
  2370 
  2371         pgp_signature_t sig = pgp_packet_ref_signature (packet);
  2372         assert(sig);
  2373 
  2374         pgp_cert_t cert = NULL;
  2375 
  2376         pgp_fingerprint_t issuer_fpr = pgp_signature_issuer_fingerprint(sig);
  2377         
  2378         char* issuer_fpr_hex = NULL;
  2379 
  2380         if (issuer_fpr) {
  2381             issuer_fpr_hex = pgp_fingerprint_to_hex(issuer_fpr);
  2382             T("Importing a signature issued by %s", issuer_fpr_hex);
  2383 
  2384             status = cert_find_by_fpr_hex(session, issuer_fpr_hex,
  2385                                          false, &cert, NULL);
  2386             if (status && status != PEP_KEY_NOT_FOUND)
  2387                 DUMP_ERR(NULL, status, "Looking up %s", issuer_fpr_hex);
  2388 
  2389             pgp_fingerprint_free(issuer_fpr);
  2390         }
  2391 
  2392         if (! cert) {
  2393             pgp_keyid_t issuer = pgp_signature_issuer(sig);
  2394             if (issuer) {
  2395                 issuer_fpr_hex = pgp_keyid_to_hex(issuer);
  2396                 T("Importing a signature issued by %s", issuer_fpr_hex);
  2397 
  2398                 status = cert_find_by_keyid_hex(session, issuer_fpr_hex,
  2399                                                false, &cert, NULL);
  2400                 if (status && status != PEP_KEY_NOT_FOUND)
  2401                     DUMP_ERR(NULL, status, "Looking up %s", issuer_fpr_hex);
  2402 
  2403                 pgp_keyid_free(issuer);
  2404             }
  2405         }
  2406 
  2407         // We need a packet.  sig is only a reference, so we just need
  2408         // to free it.
  2409         pgp_signature_free(sig);
  2410 
  2411         if (cert) {
  2412             T("Merging packet: %s", pgp_packet_debug(packet));
  2413 
  2414             cert = pgp_cert_merge_packets (&err, cert, &packet, 1);
  2415             if (! cert)
  2416                 ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Merging signature");
  2417 
  2418             bool changed = false;  
  2419               
  2420             status = cert_save(session, cert, NULL, changed_bitvec ? &changed : NULL);
  2421             if (imported_keys) {
  2422                 if (_import_keylist)
  2423                     stringlist_add(_import_keylist, issuer_fpr_hex);
  2424                 else 
  2425                     _import_keylist = new_stringlist(issuer_fpr_hex);
  2426                 
  2427                 if (changed_bitvec && changed)
  2428                     *changed_bitvec |= 1 << _import_keylist_len;
  2429             }
  2430             if (status)
  2431                 ERROR_OUT(NULL, status, "saving merged CERT");
  2432             status = PEP_KEY_IMPORTED;
  2433         }
  2434         break;
  2435     }
  2436     case PGP_TAG_PUBLIC_KEY:
  2437     case PGP_TAG_SECRET_KEY: {
  2438         parser = pgp_cert_parser_from_packet_parser(ppr);
  2439         pgp_cert_t cert;
  2440         int count = 0;
  2441         err = NULL;
  2442         
  2443         while ((cert = pgp_cert_parser_next(&err, parser))) {
  2444             count ++;
  2445 
  2446             char* cert_fpr_hex = pgp_fingerprint_to_hex(pgp_cert_fingerprint(cert)); 
  2447             T("#%d. CERT for %s, %s",
  2448               count, pgp_cert_primary_user_id(cert, session->policy, 0),
  2449               cert_fpr_hex);
  2450 
  2451             // If private_idents is not NULL and there is any private key
  2452             // material, then we'll put an entry for it into private_idents 
  2453             bool changed = false;
  2454             status = cert_save(session, cert, private_idents, changed_bitvec ? &changed : NULL);
  2455             if (status == PEP_STATUS_OK) {
  2456                 status = PEP_KEY_IMPORTED;
  2457                 if (imported_keys) {
  2458                     if (_import_keylist)
  2459                         stringlist_add(_import_keylist, cert_fpr_hex);
  2460                     else
  2461                         _import_keylist = new_stringlist(cert_fpr_hex);
  2462                         
  2463                     if (_import_keylist_len < 64 && changed) {
  2464                         *changed_bitvec |= 1 << _import_keylist_len;
  2465                     }   
  2466                     _import_keylist_len++;
  2467                 }    
  2468             }    
  2469             else
  2470                 ERROR_OUT(NULL, status, "saving certificate");
  2471             
  2472             free(cert_fpr_hex);
  2473             cert_fpr_hex = NULL;
  2474         }
  2475         if (err || count == 0)
  2476             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "parsing key data");
  2477         break;
  2478     }
  2479     default:
  2480         ERROR_OUT(NULL, PEP_NO_KEY_IMPORTED,
  2481                   "Can't import %s", pgp_tag_to_string(tag));
  2482         break;
  2483     }
  2484 
  2485  out:
  2486     pgp_cert_parser_free(parser);
  2487 
  2488     if (imported_keys && status == PEP_KEY_IMPORTED)
  2489         *imported_keys = _import_keylist;
  2490     
  2491     free(issuer_fpr_hex);
  2492     free(cert_fpr_hex);    
  2493         
  2494     T("-> %s", pEp_status_to_string(status));
  2495     return status;
  2496 }
  2497 
  2498 PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data,
  2499                               size_t size, identity_list **private_idents,
  2500                               stringlist_t** imported_keys,
  2501                               uint64_t* changed_key_index)
  2502 {
  2503     if (!imported_keys && changed_key_index)
  2504         return PEP_ILLEGAL_VALUE;
  2505         
  2506     const char* pgp_begin = "-----BEGIN PGP";
  2507     size_t prefix_len = strlen(pgp_begin);
  2508     
  2509     PEP_STATUS retval = PEP_STATUS_OK;
  2510 
  2511     // Because we also import binary keys we have to be careful with this.
  2512     // 
  2513     if (strlen(key_data + prefix_len) > prefix_len) {
  2514         const char* subtract_junk = strnstr(key_data, pgp_begin, size);
  2515         // If it's not in there, we just try to import it as is...
  2516         if (subtract_junk) {
  2517             size -= (subtract_junk - key_data);
  2518             key_data = subtract_junk;
  2519         }    
  2520     }
  2521 
  2522     unsigned int keycount = count_keydata_parts(key_data, size);
  2523     if (keycount < 2) {
  2524         retval = _pgp_import_keydata(session, key_data, size, private_idents,
  2525                                      imported_keys, changed_key_index);        
  2526         return retval;    
  2527     }        
  2528 
  2529     unsigned int i;
  2530     const char* curr_begin;
  2531     size_t curr_size;
  2532 
  2533     identity_list* collected_idents = NULL;
  2534 
  2535     retval = PEP_KEY_IMPORTED;
  2536             
  2537     for (i = 0, curr_begin = key_data; i < keycount; i++) {
  2538         const char* next_begin = NULL;
  2539 
  2540         // This is assured to be OK because the count function above
  2541         // made sure that THIS round contains at least prefix_len chars
  2542         // We used strnstr to count, so we know that strstr will be ok.
  2543         if (strlen(curr_begin + prefix_len) > prefix_len)
  2544             next_begin = strstr(curr_begin + prefix_len, pgp_begin);
  2545 
  2546         if (next_begin)
  2547             curr_size = next_begin - curr_begin;
  2548         else
  2549             curr_size = (key_data + size) - curr_begin;
  2550 
  2551         PEP_STATUS curr_status = _pgp_import_keydata(session, 
  2552                                                      curr_begin, 
  2553                                                      curr_size, 
  2554                                                      private_idents,
  2555                                                      imported_keys,
  2556                                                      changed_key_index);
  2557         if (private_idents && *private_idents) {
  2558             if (!collected_idents)
  2559                 collected_idents = *private_idents;
  2560             else
  2561                 identity_list_join(collected_idents, *private_idents);
  2562             *private_idents = NULL;
  2563         }
  2564 
  2565         if (curr_status != retval) {
  2566             switch (curr_status) {
  2567                 case PEP_NO_KEY_IMPORTED:
  2568                 case PEP_KEY_NOT_FOUND:
  2569                 case PEP_UNKNOWN_ERROR:
  2570                     switch (retval) {
  2571                         case PEP_KEY_IMPORTED:
  2572                             retval = PEP_SOME_KEYS_IMPORTED;
  2573                             break;
  2574                         case PEP_UNKNOWN_ERROR:
  2575                             retval = curr_status;
  2576                             break;
  2577                         default:
  2578                             break;
  2579                     }
  2580                     break;
  2581                 case PEP_KEY_IMPORTED:
  2582                     retval = PEP_SOME_KEYS_IMPORTED;
  2583                 default:
  2584                     break;
  2585             }
  2586         }
  2587         curr_begin = next_begin;
  2588     }
  2589 
  2590     if (private_idents)
  2591         *private_idents = collected_idents;
  2592 
  2593     return retval;
  2594 }
  2595 
  2596 PEP_STATUS pgp_export_keydata(
  2597         PEP_SESSION session, const char *fpr, char **key_data, size_t *size,
  2598         bool secret)
  2599 {
  2600     PEP_STATUS status = PEP_STATUS_OK;
  2601     pgp_error_t err = NULL;
  2602     pgp_cert_t cert = NULL;
  2603     pgp_writer_t armor_writer = NULL;
  2604     pgp_writer_t memory_writer = NULL;
  2605 
  2606     assert(session);
  2607     assert(fpr);
  2608     assert(key_data);
  2609     assert(*key_data == NULL);
  2610     assert(size);
  2611 
  2612     *size = 0;
  2613 
  2614     T("(%s, %s)", fpr, secret ? "secret" : "public");
  2615 
  2616     // If the caller asks for a secret key and we only have a
  2617     // public key, then we return an error.
  2618     status = cert_find_by_fpr_hex(session, fpr, secret, &cert, NULL);
  2619     ERROR_OUT(NULL, status, "Looking up TSK for %s", fpr);
  2620 
  2621     memory_writer = pgp_writer_alloc((void **) key_data, size);
  2622     if (! memory_writer)
  2623         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "creating memory writer");
  2624     armor_writer = pgp_armor_writer_new(&err, memory_writer,
  2625                                         PGP_ARMOR_KIND_PUBLICKEY, NULL, 0);
  2626     if (! armor_writer) {
  2627         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "creating armored writer");
  2628     }
  2629 
  2630     if (secret) {
  2631         pgp_tsk_t tsk = pgp_cert_as_tsk(cert);
  2632         if (pgp_tsk_serialize(&err, tsk, armor_writer))
  2633             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "serializing TSK");
  2634         pgp_tsk_free(tsk);
  2635     } else {
  2636         if (pgp_cert_serialize(&err, cert, armor_writer))
  2637             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "serializing certificate");
  2638     }
  2639 
  2640     if (pgp_armor_writer_finalize(&err, armor_writer))
  2641         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "flushing armored data");
  2642 
  2643 
  2644  out:
  2645     if (memory_writer) {
  2646         if (status == PEP_STATUS_OK) {
  2647             // Add a trailing NUL.
  2648             pgp_writer_write(NULL, memory_writer, (const uint8_t *) "", 1);
  2649         }
  2650 
  2651         pgp_writer_free(memory_writer);
  2652     }
  2653 
  2654     if (cert)
  2655         pgp_cert_free(cert);
  2656 
  2657     (*size)--;  // Sequoia is delivering the 0 byte at the end with size, but
  2658                 // pEp is expecting it without
  2659     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  2660     return status;
  2661 }
  2662 
  2663 static char *_undot_address(const char* address) {
  2664     if (!address)
  2665         return NULL;
  2666 
  2667     int addr_len = strlen(address);
  2668     const char* at = memchr(address, '@', addr_len);
  2669 
  2670     if (!at)
  2671         at = address + addr_len;
  2672 
  2673     char* retval = calloc(1, addr_len + 1);
  2674 
  2675     const char* addr_curr = address;
  2676     char* retval_curr = retval;
  2677 
  2678     while (addr_curr < at) {
  2679         if (*addr_curr == '.') {
  2680             addr_curr++;
  2681             continue;
  2682         }
  2683         *retval_curr = *addr_curr;
  2684         retval_curr++;
  2685         addr_curr++;
  2686     }
  2687     if (*addr_curr == '@')
  2688         strcat(retval_curr, addr_curr);
  2689 
  2690     return retval;
  2691 }
  2692 
  2693 static stringpair_list_t *add_key(PEP_SESSION session,
  2694                                   stringpair_list_t *keyinfo_list,
  2695                                   stringlist_t* keylist,
  2696                                   pgp_cert_t cert, pgp_fingerprint_t fpr) {
  2697     bool revoked = false;
  2698     // Don't add revoked keys to the keyinfo_list.
  2699     if (keyinfo_list) {
  2700         pgp_revocation_status_t rs = pgp_cert_revocation_status(cert, session->policy, 0);
  2701         pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
  2702         pgp_revocation_status_free(rs);
  2703         if (rsv == PGP_REVOCATION_STATUS_REVOKED)
  2704             revoked = true;
  2705     }
  2706 
  2707     if (revoked && ! keylist)
  2708         return keyinfo_list;
  2709 
  2710     int dealloc_fpr = 0;
  2711     if (!fpr) {
  2712         dealloc_fpr = 1;
  2713         fpr = pgp_cert_fingerprint(cert);
  2714     }
  2715     char *fpr_str = pgp_fingerprint_to_hex(fpr);
  2716 
  2717     if (!revoked && keyinfo_list) {
  2718         char *user_id = pgp_cert_primary_user_id(cert, session->policy, 0);
  2719         if (user_id)
  2720             keyinfo_list = stringpair_list_add(keyinfo_list,
  2721                                                new_stringpair(fpr_str, user_id));
  2722         free(user_id);
  2723     }
  2724 
  2725     if (keylist)
  2726         keylist = stringlist_add(keylist, fpr_str);
  2727 
  2728     free(fpr_str);
  2729     if (dealloc_fpr)
  2730         pgp_fingerprint_free(fpr);
  2731 
  2732     return keyinfo_list;
  2733 }
  2734 
  2735 static PEP_STATUS list_keys(PEP_SESSION session,
  2736                             const char* pattern, int private_only,
  2737                             stringpair_list_t** keyinfo_list, stringlist_t** keylist)
  2738 {
  2739     PEP_STATUS status = PEP_STATUS_OK;
  2740     pgp_cert_t cert = NULL;
  2741     pgp_fingerprint_t fpr = NULL;
  2742 
  2743     T("('%s', private: %d)", pattern, private_only);
  2744 
  2745     stringpair_list_t* _keyinfo_list = NULL;
  2746     if (keyinfo_list) {
  2747         _keyinfo_list = new_stringpair_list(NULL);
  2748         if (!_keyinfo_list)
  2749             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_stringpair_list");
  2750     }
  2751     stringlist_t* _keylist = NULL;
  2752     if (keylist) {
  2753         _keylist = new_stringlist(NULL);
  2754         if (!_keylist)
  2755             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_string_list");
  2756     }
  2757 
  2758     // Trim any leading space.  This also makes it easier to recognize
  2759     // a string that is only whitespace.
  2760     while (*pattern == ' ')
  2761         pattern ++;
  2762 
  2763     if (strchr(pattern, '@') || strchr(pattern, ':')) {
  2764         // Looks like a mailbox or URI.
  2765         pgp_cert_t *certs = NULL;
  2766         int count = 0;
  2767         status = cert_find_by_email(session, pattern, private_only, &certs, &count);
  2768         ERROR_OUT(NULL, status, "Looking up '%s'", pattern);
  2769         for (int i = 0; i < count; i ++) {
  2770             add_key(session, _keyinfo_list, _keylist, certs[i], NULL);
  2771             pgp_cert_free(certs[i]);
  2772         }
  2773         free(certs);
  2774 
  2775         if (count == 0) {
  2776             // If match failed, check to see if we've got a dotted
  2777             // address in the pattern.  If so, try again without dots.
  2778             const char* dotpos = strstr(pattern, ".");
  2779             const char* atpos = strstr(pattern, "@");
  2780             if (dotpos && atpos && (dotpos < atpos)) {
  2781                 char* undotted = _undot_address(pattern);
  2782                 if (undotted) {
  2783                     PEP_STATUS status = list_keys(session, undotted, private_only,
  2784                                                   keyinfo_list, keylist);
  2785                     free(undotted);
  2786                     return status;
  2787                 }
  2788             }
  2789         }
  2790     } else if (// Only hex characters and spaces
  2791                pattern[strspn(pattern, "0123456789aAbBcCdDeEfF ")] == 0
  2792                // And a fair amount of them.
  2793                && strlen(pattern) >= 16) {
  2794         // Fingerprint.  Note: the pep engine never looks keys up by
  2795         // keyid, so we don't handle them.
  2796         fpr = pgp_fingerprint_from_hex(pattern);
  2797         status = cert_find_by_fpr(session, fpr, false, &cert, NULL);
  2798         ERROR_OUT(NULL, status, "Looking up key");
  2799         add_key(session, _keyinfo_list, _keylist, cert, fpr);
  2800     } else if (pattern[0] == 0) {
  2801         // Empty string.
  2802 
  2803         pgp_cert_t *certs = NULL;
  2804         int count = 0;
  2805         status = cert_all(session, private_only, &certs, &count);
  2806         ERROR_OUT(NULL, status, "Looking up '%s'", pattern);
  2807         for (int i = 0; i < count; i ++) {
  2808             add_key(session, _keyinfo_list, _keylist, certs[i], NULL);
  2809             pgp_cert_free(certs[i]);
  2810         }
  2811         free(certs);
  2812     } else {
  2813         T("unsupported pattern '%s'", pattern);
  2814     }
  2815 
  2816  out:
  2817     pgp_cert_free(cert);
  2818     pgp_fingerprint_free(fpr);
  2819 
  2820     if (status == PEP_KEY_NOT_FOUND)
  2821         status = PEP_STATUS_OK;
  2822 
  2823     if (status != PEP_STATUS_OK || (_keyinfo_list && !_keyinfo_list->value)) {
  2824         free_stringpair_list(_keyinfo_list);
  2825         _keyinfo_list = NULL;
  2826     }
  2827     if (keyinfo_list)
  2828         *keyinfo_list = _keyinfo_list;
  2829 
  2830     if (status != PEP_STATUS_OK || (_keylist && !_keylist->value)) {
  2831         free_stringlist(_keylist);
  2832         _keylist = NULL;
  2833     }
  2834     if (keylist)
  2835         *keylist = _keylist;
  2836 
  2837     int len = -1;
  2838     if (keylist)
  2839         len = stringlist_length(*keylist);
  2840     else if (keyinfo_list)
  2841         len = stringpair_list_length(*keyinfo_list);
  2842     T("(%s) -> %s (%d keys)", pattern, pEp_status_to_string(status), len);
  2843     return status;
  2844 }
  2845 
  2846 // pattern could be empty, an fpr, or a mailbox.
  2847 //
  2848 // keyinfo_list is a list of <fpr, openpgp userid> tuples for the
  2849 // matching keys.
  2850 //
  2851 // This function filters out revoked key, but not expired keys.
  2852 PEP_STATUS pgp_list_keyinfo(PEP_SESSION session,
  2853                             const char* pattern,
  2854                             stringpair_list_t** keyinfo_list)
  2855 {
  2856     return list_keys(session, pattern, false, keyinfo_list, NULL);
  2857 }
  2858 
  2859 PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
  2860 {
  2861     assert(!"pgp_recv_key not implemented");
  2862     return PEP_UNKNOWN_ERROR;
  2863 }
  2864 
  2865 // Unlike pgp_list_keyinfo, this function returns revoked keys.
  2866 PEP_STATUS pgp_find_keys(
  2867     PEP_SESSION session, const char *pattern, stringlist_t **keylist)
  2868 {
  2869     return list_keys(session, pattern, false, NULL, keylist);
  2870 }
  2871 
  2872 // Unlike pgp_list_keyinfo, this function returns revoked keys.
  2873 PEP_STATUS pgp_find_private_keys(
  2874     PEP_SESSION session, const char *pattern, stringlist_t **keylist)
  2875 {
  2876     return list_keys(session, pattern, true, NULL, keylist);
  2877 }
  2878 
  2879 PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
  2880 {
  2881     assert(!"pgp_send_key not implemented");
  2882     return PEP_UNKNOWN_ERROR;
  2883 }
  2884 
  2885 
  2886 PEP_STATUS pgp_renew_key(
  2887     PEP_SESSION session, const char *fpr, const timestamp *ts)
  2888 {
  2889     PEP_STATUS status = PEP_STATUS_OK;
  2890     pgp_error_t err = NULL;
  2891     pgp_cert_t cert = NULL;
  2892     pgp_cert_valid_key_iter_t iter = NULL;
  2893     pgp_valid_key_amalgamation_t primary = NULL;
  2894     pgp_key_pair_t keypair = NULL;
  2895     pgp_signer_t signer = NULL;
  2896     time_t t = timegm((timestamp *) ts); // timestamp because of Windows
  2897     pgp_cert_valid_key_iter_t key_iter = NULL;
  2898     pgp_valid_key_amalgamation_t ka = NULL;
  2899     pgp_packet_t *packets = NULL;
  2900     size_t packet_count = 0;
  2901     size_t packet_capacity = 0;
  2902 
  2903     T("(%s)", fpr);
  2904 
  2905     status = cert_find_by_fpr_hex(session, fpr, true, &cert, NULL);
  2906     ERROR_OUT(NULL, status, "Looking up '%s'", fpr);
  2907 
  2908     time_t creation_time = pgp_key_creation_time(pgp_cert_primary_key(cert));
  2909     if (creation_time > t)
  2910         // The creation time is after the expiration time!
  2911         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
  2912                   "creation time can't be after expiration time");
  2913 
  2914     iter = pgp_cert_valid_key_iter(cert, session->policy, 0);
  2915     pgp_cert_valid_key_iter_for_certification (iter);
  2916     pgp_cert_valid_key_iter_unencrypted_secret (iter);
  2917     pgp_cert_valid_key_iter_revoked(iter, false);
  2918 
  2919     // If there are multiple certification capable subkeys, we just
  2920     // take the first one, whichever one that happens to be.
  2921     primary = pgp_cert_valid_key_iter_next (iter, NULL, NULL);
  2922     if (! primary)
  2923         ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  2924                    "%s has no usable certification capable key", fpr);
  2925 
  2926     // pgp_key_into_key_pair needs to own the key, but here we
  2927     // only get a reference (which we still need to free).
  2928     pgp_key_t key = pgp_valid_key_amalgamation_key (primary);
  2929     keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  2930     pgp_key_free (key);
  2931     if (! keypair)
  2932         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  2933 
  2934     signer = pgp_key_pair_as_signer (keypair);
  2935     if (! signer)
  2936         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  2937 
  2938     // Set the expiration for all non-revoked keys.
  2939     key_iter = pgp_cert_valid_key_iter(cert, session->policy, 0);
  2940     pgp_cert_valid_key_iter_revoked(key_iter, false);
  2941 
  2942     while ((ka = pgp_cert_valid_key_iter_next(key_iter, NULL, NULL))) {
  2943         pgp_status_t sq_status;
  2944         pgp_error_t err;
  2945         pgp_signature_t *sigs = NULL;
  2946         size_t sig_count = 0;
  2947 
  2948         sq_status = pgp_valid_key_amalgamation_set_expiration_time
  2949             (&err, ka, signer, t, &sigs, &sig_count);
  2950         if (sq_status)
  2951             ERROR_OUT(err, PEP_UNKNOWN_ERROR,
  2952                       "setting expiration (generating self signatures)");
  2953 
  2954         if (packet_capacity - packet_count < sig_count) {
  2955             // Grow the array.
  2956             int c = packet_capacity;
  2957             if (c == 0) {
  2958                 c = 1;
  2959             }
  2960             while (c < packet_count + sig_count) {
  2961                 c *= 2;
  2962             }
  2963 
  2964             void * tmp = _pEp_reallocarray(packets, c, sizeof (*packets));
  2965             if (! tmp)
  2966                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY,
  2967                           "setting expiration (resizing buffer)");
  2968 
  2969             packets = tmp;
  2970             packet_capacity = c;
  2971         }
  2972 
  2973         int i;
  2974         for (i = 0; i < sig_count; i ++) {
  2975             packets[packet_count + i] = pgp_signature_into_packet(sigs[i]);
  2976         }
  2977         packet_count += sig_count;
  2978 
  2979         free (sigs);
  2980         pgp_valid_key_amalgamation_free (ka);
  2981     }
  2982 
  2983     // We're going to mutate cert, which key_iter references.
  2984     // Deallocate it first.
  2985     pgp_cert_valid_key_iter_free (key_iter);
  2986     key_iter = NULL;
  2987 
  2988     cert = pgp_cert_merge_packets (&err, cert, packets, packet_count);
  2989     // The packets (but not the array) are now owned by cert.
  2990     packet_count = 0;
  2991     if (! cert)
  2992         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration (updating cert)");
  2993 
  2994     status = cert_save(session, cert, NULL, NULL);
  2995     cert = NULL;
  2996     ERROR_OUT(NULL, status, "Saving %s", fpr);
  2997 
  2998  out:
  2999     if (packets) {
  3000         for (int i = 0; i < packet_count; i ++) {
  3001             pgp_packet_free (packets[i]);
  3002         }
  3003         free (packets);
  3004     }
  3005 
  3006     pgp_valid_key_amalgamation_free (ka);
  3007     pgp_cert_valid_key_iter_free (key_iter);
  3008     pgp_signer_free (signer);
  3009     // XXX: pgp_key_pair_as_signer is only supposed to reference
  3010     // signing_keypair, but it consumes it.  If this is fixed, this
  3011     // will become a leak.
  3012     //
  3013     pgp_key_pair_free (keypair);
  3014     pgp_valid_key_amalgamation_free (primary);
  3015     pgp_cert_valid_key_iter_free (iter);
  3016     pgp_cert_free(cert);
  3017 
  3018     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  3019     return status;
  3020 }
  3021 
  3022 PEP_STATUS pgp_revoke_key(
  3023     PEP_SESSION session, const char *fpr, const char *reason)
  3024 {
  3025     PEP_STATUS status = PEP_STATUS_OK;
  3026     pgp_error_t err = NULL;
  3027     pgp_cert_t cert = NULL;
  3028     pgp_cert_valid_key_iter_t iter = NULL;
  3029     pgp_valid_key_amalgamation_t ka = NULL;
  3030     pgp_key_pair_t keypair = NULL;
  3031     pgp_signer_t signer = NULL;
  3032 
  3033     T("(%s)", fpr);
  3034 
  3035     status = cert_find_by_fpr_hex(session, fpr, true, &cert, NULL);
  3036     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  3037 
  3038     iter = pgp_cert_valid_key_iter(cert, session->policy, 0);
  3039     pgp_cert_valid_key_iter_alive(iter);
  3040     pgp_cert_valid_key_iter_revoked(iter, false);
  3041     pgp_cert_valid_key_iter_for_certification (iter);
  3042     pgp_cert_valid_key_iter_unencrypted_secret (iter);
  3043 
  3044     // If there are multiple certification capable subkeys, we just
  3045     // take the first one, whichever one that happens to be.
  3046     ka = pgp_cert_valid_key_iter_next (iter, NULL, NULL);
  3047     if (! ka)
  3048         ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  3049                    "%s has no usable certification capable key", fpr);
  3050 
  3051     // pgp_key_into_key_pair needs to own the key, but here we
  3052     // only get a reference (which we still need to free).
  3053     pgp_key_t key = pgp_valid_key_amalgamation_key (ka);
  3054     keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  3055     pgp_key_free (key);
  3056     if (! keypair)
  3057         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  3058 
  3059     signer = pgp_key_pair_as_signer (keypair);
  3060     if (! signer)
  3061         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  3062 
  3063     cert = pgp_cert_revoke_in_place(&err, cert, signer,
  3064                                     PGP_REASON_FOR_REVOCATION_UNSPECIFIED,
  3065                                     reason);
  3066     if (! cert)
  3067         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
  3068 
  3069     assert(pgp_revocation_status_variant(pgp_cert_revocation_status(cert, session->policy, 0))
  3070            == PGP_REVOCATION_STATUS_REVOKED);
  3071 
  3072     status = cert_save(session, cert, NULL, NULL);
  3073     cert = NULL;
  3074     ERROR_OUT(NULL, status, "Saving %s", fpr);
  3075 
  3076  out:
  3077     pgp_signer_free (signer);
  3078     pgp_key_pair_free (keypair);
  3079     pgp_valid_key_amalgamation_free (ka);
  3080     pgp_cert_valid_key_iter_free (iter);
  3081     pgp_cert_free(cert);
  3082 
  3083     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  3084     return status;
  3085 }
  3086 
  3087 // NOTE: Doesn't check the *validity* of these subkeys. Just checks to see 
  3088 // if they exist.
  3089 static void _pgp_contains_encryption_subkey(PEP_SESSION session, pgp_cert_t cert, bool* has_subkey) {
  3090     pgp_cert_valid_key_iter_t key_iter
  3091         = pgp_cert_valid_key_iter(cert, session->policy, 0);
  3092 
  3093     // Calling these two allegedly gives the union, I think? :)
  3094     pgp_cert_valid_key_iter_for_transport_encryption(key_iter);
  3095     pgp_cert_valid_key_iter_for_storage_encryption(key_iter);
  3096 
  3097     pgp_valid_key_amalgamation_t ka
  3098         = pgp_cert_valid_key_iter_next(key_iter, NULL, NULL);
  3099     *has_subkey = ka != NULL;
  3100     pgp_valid_key_amalgamation_free (ka);
  3101     pgp_cert_valid_key_iter_free(key_iter);
  3102 }
  3103 
  3104 // NOTE: Doesn't check the *validity* of these subkeys. Just checks to see 
  3105 // if they exist.
  3106 static void _pgp_contains_sig_subkey(PEP_SESSION session, pgp_cert_t cert, bool* has_subkey) {
  3107     pgp_cert_valid_key_iter_t key_iter
  3108         = pgp_cert_valid_key_iter(cert, session->policy, 0);
  3109 
  3110     pgp_cert_valid_key_iter_for_signing(key_iter);
  3111 
  3112     pgp_valid_key_amalgamation_t ka
  3113         = pgp_cert_valid_key_iter_next(key_iter, NULL, NULL);
  3114     *has_subkey = ka != NULL;
  3115     pgp_valid_key_amalgamation_free (ka);
  3116     pgp_cert_valid_key_iter_free(key_iter);
  3117 }
  3118 
  3119 // Check to see that key, at a minimum, even contains encryption or signing subkeys
  3120 static void _pgp_key_broken(PEP_SESSION session, pgp_cert_t cert, bool* is_broken) {
  3121     *is_broken = false;
  3122     bool unbroken = false;
  3123     _pgp_contains_sig_subkey(session, cert, &unbroken);
  3124     if (!unbroken)
  3125         *is_broken = true;
  3126     else {
  3127         _pgp_contains_encryption_subkey(session, cert, &unbroken);
  3128         if (!unbroken)
  3129             *is_broken = true;
  3130     }
  3131 }
  3132 
  3133 static void _pgp_key_expired(PEP_SESSION session, pgp_cert_t cert, const time_t when, bool* expired)
  3134 {
  3135     // Is the certificate live?
  3136     *expired = pgp_cert_alive(NULL, cert, session->policy, when) != PGP_STATUS_SUCCESS;
  3137 
  3138     if (TRACING) {
  3139         char buffer[26];
  3140         time_t now = time(NULL);
  3141 
  3142         if (when == now || when == now - 1) {
  3143             sprintf(buffer, "now");
  3144         } else {
  3145             struct tm tm;
  3146             gmtime_r(&when, &tm);
  3147             strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm);
  3148         }
  3149 
  3150         T("certificate is %slive as of %s", *expired ? "not " : "", buffer);
  3151     }
  3152     if (*expired)
  3153         goto out;
  3154 
  3155     // Check to see if the key is broken. Ideally, we'd do this in one pass below, but 
  3156     // givem the choice for how to check for expiry, this is the simplest solutiom.
  3157     bool broken = false;
  3158     _pgp_key_broken(session, cert, &broken);
  3159     if (broken)
  3160         goto out; // still isn't expired. is broken. there's a difference and a different check.    
  3161         
  3162     // Why is this an indicator of just an expired key and not a broken one?
  3163     // This will also reject keys that are not expired, but rather missing 
  3164     // subkeys.
  3165     //    
  3166     // Are there at least one certification subkey, one signing subkey
  3167     // and one encryption subkey that are live?
  3168     //    int can_certify = 0, can_encrypt = 0, can_sign = 0;
  3169     int can_encrypt = 0, can_sign = 0;
  3170 
  3171     pgp_cert_valid_key_iter_t key_iter
  3172         = pgp_cert_valid_key_iter(cert, session->policy, 0);
  3173     pgp_cert_valid_key_iter_alive(key_iter);
  3174     pgp_cert_valid_key_iter_revoked(key_iter, false);
  3175 
  3176     pgp_valid_key_amalgamation_t ka;
  3177     pgp_signature_t sig;
  3178     while ((ka = pgp_cert_valid_key_iter_next(key_iter, &sig, NULL))) {
  3179         if (pgp_signature_for_transport_encryption(sig)
  3180             || pgp_signature_for_storage_encryption(sig))
  3181             can_encrypt = 1;
  3182         if (pgp_signature_for_signing(sig))
  3183             can_sign = 1;
  3184         // if (pgp_signature_for_certification(sig))
  3185         //     can_certify = 1;
  3186 
  3187         pgp_signature_free (sig);
  3188         pgp_valid_key_amalgamation_free (ka);
  3189 
  3190 //        if (can_encrypt && can_sign && can_certify)
  3191         if (can_encrypt && can_sign)
  3192             break;
  3193     }
  3194     pgp_cert_valid_key_iter_free(key_iter);
  3195 
  3196 //    *expired = !(can_encrypt && can_sign && can_certify);
  3197     *expired = !(can_encrypt && can_sign);
  3198 
  3199     T("Key can%s encrypt, can%s sign => %s expired",
  3200       can_encrypt ? "" : "not",
  3201       can_sign ? "" : "not",
  3202       *expired ? "" : "not");
  3203 
  3204 out:
  3205     // Er, this might be problematic in terms of internal vs. external in log. FIXME?
  3206     T(" -> expired: %d", *expired);
  3207     return;
  3208 }
  3209 
  3210 PEP_STATUS pgp_key_expired(PEP_SESSION session, const char *fpr,
  3211                            const time_t when, bool *expired)
  3212 {
  3213     PEP_STATUS status = PEP_STATUS_OK;
  3214     pgp_cert_t cert = NULL;
  3215     T("(%s)", fpr);
  3216 
  3217     assert(session);
  3218     assert(fpr);
  3219     assert(expired);
  3220 
  3221     *expired = false;
  3222 
  3223     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  3224     status = cert_find_by_fpr(session, pgp_fpr, false, &cert, NULL);
  3225     pgp_fingerprint_free(pgp_fpr);
  3226     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  3227 
  3228     _pgp_key_expired(session, cert, when, expired);
  3229  out:
  3230     pgp_cert_free(cert);
  3231     T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
  3232     return status;
  3233 }
  3234 
  3235 static void _pgp_key_revoked(PEP_SESSION session, pgp_cert_t cert, bool* revoked) {
  3236     pgp_revocation_status_t rs = pgp_cert_revocation_status(cert, session->policy, 0);
  3237     *revoked = pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED;
  3238     pgp_revocation_status_free (rs); 
  3239     
  3240     if (*revoked)
  3241         return;
  3242         
  3243     // Ok, at this point, we need to know if for signing or encryption there is
  3244     // ONLY a revoked key available. If so, this key is also considered revoked 
  3245     pgp_cert_valid_key_iter_t key_iter
  3246         = pgp_cert_valid_key_iter(cert, session->policy, 0);
  3247     pgp_cert_valid_key_iter_for_signing(key_iter);
  3248 
  3249     bool has_non_revoked_sig_key = false;
  3250     bool has_revoked_sig_key = false;
  3251 
  3252     pgp_valid_key_amalgamation_t ka;
  3253     while (!has_non_revoked_sig_key
  3254            && (ka = pgp_cert_valid_key_iter_next(key_iter, NULL, &rs))) {
  3255         if (pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED)
  3256             has_revoked_sig_key = true;
  3257         else
  3258             has_non_revoked_sig_key = true;
  3259 
  3260         pgp_revocation_status_free(rs);
  3261         pgp_valid_key_amalgamation_free (ka);
  3262     }
  3263     pgp_cert_valid_key_iter_free(key_iter);
  3264 
  3265     if (has_non_revoked_sig_key) {
  3266         key_iter = pgp_cert_valid_key_iter(cert, session->policy, 0);
  3267         pgp_cert_valid_key_iter_for_transport_encryption(key_iter);
  3268         pgp_cert_valid_key_iter_for_storage_encryption(key_iter);
  3269 
  3270         bool has_non_revoked_enc_key = false;
  3271         bool has_revoked_enc_key = false;
  3272 
  3273         pgp_valid_key_amalgamation_t ka;
  3274         while (!has_non_revoked_enc_key
  3275                && (ka = pgp_cert_valid_key_iter_next(key_iter, NULL, &rs))) {
  3276             if (pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED)
  3277                 has_revoked_enc_key = true;
  3278             else
  3279                 has_non_revoked_enc_key = true;
  3280 
  3281             pgp_revocation_status_free(rs);
  3282             pgp_valid_key_amalgamation_free (ka);
  3283         }
  3284         if (!has_non_revoked_enc_key) { // this does NOT mean revoked. it MAY mean broken.
  3285             if (has_revoked_enc_key)
  3286                 *revoked = true;
  3287         }
  3288         pgp_cert_valid_key_iter_free (key_iter);
  3289     }
  3290     else if (has_revoked_sig_key) {
  3291         *revoked = true;
  3292     }
  3293 }
  3294 
  3295 PEP_STATUS pgp_key_revoked(PEP_SESSION session, const char *fpr, bool *revoked)
  3296 {
  3297     PEP_STATUS status = PEP_STATUS_OK;
  3298     pgp_cert_t cert;
  3299 
  3300     T("(%s)", fpr);
  3301 
  3302     assert(session);
  3303     assert(fpr);
  3304     assert(revoked);
  3305 
  3306     *revoked = false;
  3307 
  3308     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  3309     status = cert_find_by_fpr(session, pgp_fpr, false, &cert, NULL);
  3310     pgp_fingerprint_free(pgp_fpr);
  3311     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  3312 
  3313     // pgp_revocation_status_t rs = pgp_cert_revocation_status(cert, 0);
  3314     // *revoked = pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED;
  3315     // pgp_revocation_status_free (rs);
  3316     _pgp_key_revoked(session, cert, revoked);
  3317     pgp_cert_free(cert);
  3318 
  3319  out:
  3320     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  3321     return status;
  3322 }
  3323 
  3324 PEP_STATUS pgp_get_key_rating(
  3325     PEP_SESSION session, const char *fpr, PEP_comm_type *comm_type)
  3326 {
  3327     PEP_STATUS status = PEP_STATUS_OK;
  3328     pgp_cert_t cert = NULL;
  3329 
  3330     assert(session);
  3331     assert(fpr);
  3332     assert(comm_type);
  3333 
  3334     *comm_type = PEP_ct_unknown;
  3335 
  3336     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  3337     status = cert_find_by_fpr(session, pgp_fpr, false, &cert, NULL);
  3338     pgp_fingerprint_free(pgp_fpr);
  3339     ERROR_OUT(NULL, status, "Looking up key: %s", fpr);
  3340 
  3341     *comm_type = PEP_ct_OpenPGP_unconfirmed;
  3342 
  3343     // pgp_revocation_status_t rs = pgp_cert_revocation_status(cert, 0);
  3344     // pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
  3345     // pgp_revocation_status_free(rs);
  3346     // if (rsv == PGP_REVOCATION_STATUS_REVOKED) {
  3347     //     *comm_type = PEP_ct_key_revoked;
  3348     //     goto out;
  3349     // }
  3350 
  3351     bool revoked = false;
  3352     _pgp_key_revoked(session, cert, &revoked);
  3353     
  3354     if (revoked) {
  3355         *comm_type = PEP_ct_key_revoked;
  3356         goto out;
  3357     }    
  3358 
  3359     bool broken = false;
  3360     _pgp_key_broken(session, cert, &broken);
  3361     if (broken) {
  3362         *comm_type = PEP_ct_key_b0rken;
  3363         goto out;
  3364     }
  3365             
  3366     bool expired = false;
  3367     // MUST guarantee the same behaviour.
  3368     _pgp_key_expired(session, cert, time(NULL), &expired);
  3369 
  3370     if (expired) {
  3371         *comm_type = PEP_ct_key_expired;
  3372         goto out;
  3373     }
  3374 
  3375     PEP_comm_type worst_enc = PEP_ct_no_encryption, worst_sign = PEP_ct_no_encryption;
  3376     pgp_cert_valid_key_iter_t key_iter
  3377         = pgp_cert_valid_key_iter(cert, session->policy, 0);
  3378     pgp_cert_valid_key_iter_alive(key_iter);
  3379     pgp_cert_valid_key_iter_revoked(key_iter, false);
  3380 
  3381     pgp_valid_key_amalgamation_t ka;
  3382     pgp_signature_t sig;
  3383     while ((ka = pgp_cert_valid_key_iter_next(key_iter, &sig, NULL))) {
  3384         pgp_key_t key = pgp_valid_key_amalgamation_key (ka);
  3385 
  3386         PEP_comm_type curr = PEP_ct_no_encryption;
  3387 
  3388         int can_enc = pgp_signature_for_transport_encryption(sig)
  3389             || pgp_signature_for_storage_encryption(sig);
  3390         int can_sign = pgp_signature_for_signing(sig);
  3391 
  3392         pgp_public_key_algo_t pk_algo = pgp_key_public_key_algo(key);
  3393 
  3394         if (pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_ENCRYPT_SIGN
  3395             || pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_ENCRYPT
  3396             || pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_SIGN) {
  3397             int bits = pgp_key_public_key_bits(key);
  3398             if (bits < 1024)
  3399                 curr = PEP_ct_key_too_short;
  3400             else if (bits == 1024)
  3401                 curr = PEP_ct_OpenPGP_weak_unconfirmed;
  3402             else
  3403                 curr = PEP_ct_OpenPGP_unconfirmed;
  3404         } else {
  3405             curr = PEP_ct_OpenPGP_unconfirmed;
  3406         }
  3407 
  3408         if (can_enc)
  3409             worst_enc = (worst_enc == PEP_ct_no_encryption ? curr : _MIN(worst_enc, curr));
  3410             
  3411         if (can_sign)
  3412             worst_sign = (worst_sign == PEP_ct_no_encryption ? curr : _MIN(worst_sign, curr));
  3413 
  3414         pgp_key_free (key);
  3415         pgp_signature_free (sig);
  3416         pgp_valid_key_amalgamation_free (ka);
  3417     }
  3418     pgp_cert_valid_key_iter_free(key_iter);
  3419 
  3420     // This may be redundant because of the broken check above; we should revisit later.
  3421     // But because this case was falling under expired because of how that is written, this 
  3422     // was probably never hiit here
  3423     if (worst_enc == PEP_ct_no_encryption || worst_sign == PEP_ct_no_encryption) {
  3424         *comm_type = PEP_ct_key_b0rken;
  3425         goto out;
  3426     } else {
  3427         *comm_type = _MIN(worst_enc, worst_sign);
  3428     }
  3429 
  3430  out:
  3431     pgp_cert_free(cert);
  3432 
  3433     T("(%s) -> %s", fpr, pEp_comm_type_to_string(*comm_type));
  3434     return status;
  3435 }
  3436 
  3437 
  3438 PEP_STATUS pgp_key_created(PEP_SESSION session, const char *fpr, time_t *created)
  3439 {
  3440     PEP_STATUS status = PEP_STATUS_OK;
  3441     pgp_cert_t cert = NULL;
  3442     T("(%s)", fpr);
  3443 
  3444     *created = 0;
  3445 
  3446     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  3447     status = cert_find_by_fpr(session, pgp_fpr, false, &cert, NULL);
  3448     pgp_fingerprint_free(pgp_fpr);
  3449     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  3450 
  3451     pgp_key_t k = pgp_cert_primary_key(cert);
  3452     *created = pgp_key_creation_time(k);
  3453     pgp_cert_free(cert);
  3454 
  3455  out:
  3456     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  3457     return status;
  3458 }
  3459 
  3460 PEP_STATUS pgp_binary(const char **path)
  3461 {
  3462     *path = NULL;
  3463     return PEP_STATUS_OK;
  3464 }
  3465 
  3466 PEP_STATUS pgp_contains_priv_key(PEP_SESSION session, const char *fpr,
  3467                                  bool *has_private)
  3468 {
  3469     T("(%s)", fpr);
  3470     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  3471     PEP_STATUS status = cert_find_by_fpr(session, pgp_fpr, true, NULL, NULL);
  3472     pgp_fingerprint_free(pgp_fpr);
  3473     if (status == PEP_STATUS_OK) {
  3474         *has_private = 1;
  3475     } else if (status == PEP_KEY_NOT_FOUND) {
  3476         *has_private = 0;
  3477         status = PEP_STATUS_OK;
  3478     }
  3479     T("(%s) -> %s, %s",
  3480       fpr, *has_private ? "priv" : "pub", pEp_status_to_string(status));
  3481     return status;
  3482 }