src/pgp_sequoia.c
author Neal H. Walfield <neal@pep.foundation>
Thu, 05 Dec 2019 09:31:42 +0100
branchsync
changeset 4236 01980e34ecdf
parent 4235 1daffdbc64aa
permissions -rw-r--r--
Handle PGP_VERIFICATION_RESULT_NOT_ALIVE.
     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 disable 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_GPGME_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     if (sqlite_result != SQLITE_OK)
   365         ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   366                   "creating userids table: %s",
   367                   sqlite3_errmsg(session->key_db));
   368 
   369     sqlite_result
   370         = sqlite3_prepare_v2(session->key_db, "begin transaction",
   371                              -1, &session->sq_sql.begin_transaction, NULL);
   372     assert(sqlite_result == SQLITE_OK);
   373 
   374     sqlite_result
   375         = sqlite3_prepare_v2(session->key_db, "commit transaction",
   376                              -1, &session->sq_sql.commit_transaction, NULL);
   377     assert(sqlite_result == SQLITE_OK);
   378 
   379     sqlite_result
   380         = sqlite3_prepare_v2(session->key_db, "rollback transaction",
   381                              -1, &session->sq_sql.rollback_transaction, NULL);
   382     assert(sqlite_result == SQLITE_OK);
   383 
   384     sqlite_result
   385         = sqlite3_prepare_v2(session->key_db,
   386                              "SELECT tpk, secret FROM keys"
   387                              " WHERE primary_key == ?",
   388                              -1, &session->sq_sql.cert_find, NULL);
   389     assert(sqlite_result == SQLITE_OK);
   390 
   391     sqlite_result
   392         = sqlite3_prepare_v2(session->key_db,
   393                              "SELECT tpk, secret FROM keys"
   394                              " WHERE primary_key == ? and secret == 1",
   395                              -1, &session->sq_sql.tsk_find, NULL);
   396     assert(sqlite_result == SQLITE_OK);
   397 
   398     sqlite_result
   399         = sqlite3_prepare_v2(session->key_db,
   400                              "SELECT tpk, secret FROM subkeys"
   401                              " LEFT JOIN keys"
   402                              "  ON subkeys.primary_key == keys.primary_key"
   403                              " WHERE subkey == ?",
   404                              -1, &session->sq_sql.cert_find_by_keyid, NULL);
   405     assert(sqlite_result == SQLITE_OK);
   406 
   407     sqlite_result
   408         = sqlite3_prepare_v2(session->key_db,
   409                              "SELECT tpk, secret FROM subkeys"
   410                              " LEFT JOIN keys"
   411                              "  ON subkeys.primary_key == keys.primary_key"
   412                              " WHERE subkey == ?",
   413                              -1, &session->sq_sql.cert_find_by_keyid, NULL);
   414     assert(sqlite_result == SQLITE_OK);
   415 
   416     sqlite_result
   417         = sqlite3_prepare_v2(session->key_db,
   418                              "SELECT tpk, secret FROM subkeys"
   419                              " LEFT JOIN keys"
   420                              "  ON subkeys.primary_key == keys.primary_key"
   421                              " WHERE subkey == ? and keys.secret == 1",
   422                              -1, &session->sq_sql.tsk_find_by_keyid, NULL);
   423     assert(sqlite_result == SQLITE_OK);
   424 
   425     sqlite_result
   426         = sqlite3_prepare_v2(session->key_db,
   427                              "SELECT tpk, secret FROM userids"
   428                              " LEFT JOIN keys"
   429                              "  ON userids.primary_key == keys.primary_key"
   430                              " WHERE userid == ?",
   431                              -1, &session->sq_sql.cert_find_by_email, NULL);
   432     assert(sqlite_result == SQLITE_OK);
   433 
   434     sqlite_result
   435         = sqlite3_prepare_v2(session->key_db,
   436                              "SELECT tpk, secret FROM userids"
   437                              " LEFT JOIN keys"
   438                              "  ON userids.primary_key == keys.primary_key"
   439                              " WHERE userid == ? and keys.secret == 1",
   440                              -1, &session->sq_sql.tsk_find_by_email, NULL);
   441     assert(sqlite_result == SQLITE_OK);
   442 
   443     sqlite_result
   444         = sqlite3_prepare_v2(session->key_db,
   445                              "select tpk, secret from keys",
   446                              -1, &session->sq_sql.cert_all, NULL);
   447     assert(sqlite_result == SQLITE_OK);
   448 
   449     sqlite_result
   450         = sqlite3_prepare_v2(session->key_db,
   451                              "select tpk, secret from keys where secret = 1",
   452                              -1, &session->sq_sql.tsk_all, NULL);
   453     assert(sqlite_result == SQLITE_OK);
   454 
   455     sqlite_result
   456         = sqlite3_prepare_v2(session->key_db,
   457                              "INSERT OR REPLACE INTO keys"
   458                              "   (primary_key, secret, tpk)"
   459                              " VALUES (?, ?, ?)",
   460                              -1, &session->sq_sql.cert_save_insert_primary, NULL);
   461     assert(sqlite_result == SQLITE_OK);
   462 
   463     sqlite_result
   464         = sqlite3_prepare_v2(session->key_db,
   465                              "INSERT OR REPLACE INTO subkeys"
   466                              "   (subkey, primary_key)"
   467                              " VALUES (?, ?)",
   468                              -1, &session->sq_sql.cert_save_insert_subkeys, NULL);
   469     assert(sqlite_result == SQLITE_OK);
   470 
   471     sqlite_result
   472         = sqlite3_prepare_v2(session->key_db,
   473                              "INSERT OR REPLACE INTO userids"
   474                              "   (userid, primary_key)"
   475                              " VALUES (?, ?)",
   476                              -1, &session->sq_sql.cert_save_insert_userids, NULL);
   477     assert(sqlite_result == SQLITE_OK);
   478 
   479     sqlite_result
   480         = sqlite3_prepare_v2(session->key_db,
   481                              "DELETE FROM keys WHERE primary_key = ?",
   482                              -1, &session->sq_sql.delete_keypair, NULL);
   483     assert(sqlite_result == SQLITE_OK);
   484 
   485  out:
   486     if (status != PEP_STATUS_OK)
   487         pgp_release(session, in_first);
   488     return status;
   489 }
   490 
   491 void pgp_release(PEP_SESSION session, bool out_last)
   492 {
   493     sqlite3_stmt **stmts = (sqlite3_stmt **) &session->sq_sql;
   494     for (int i = 0; i < sizeof(session->sq_sql) / sizeof(*stmts); i ++)
   495         if (stmts[i]) {
   496             sqlite3_finalize(stmts[i]);
   497             stmts[i] = NULL;
   498         }
   499 
   500     if (session->key_db) {
   501         int result = sqlite3_close_v2(session->key_db);
   502         if (result != 0)
   503             DUMP_ERR(NULL, PEP_UNKNOWN_ERROR,
   504                      "Closing key DB: sqlite3_close_v2: %s",
   505                      sqlite3_errstr(result));
   506         session->key_db = NULL;
   507     }
   508 }
   509 
   510 // Ensures that a fingerprint is in canonical form.  A canonical
   511 // fingerprint doesn't contain any white space.
   512 //
   513 // This function does *not* consume fpr.
   514 static char *pgp_fingerprint_canonicalize(const char *) __attribute__((nonnull));
   515 static char *pgp_fingerprint_canonicalize(const char *fpr)
   516 {
   517     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   518     char *fpr_canonicalized = pgp_fingerprint_to_hex(pgp_fpr);
   519     pgp_fingerprint_free(pgp_fpr);
   520 
   521     return fpr_canonicalized;
   522 }
   523 
   524 // step statement and load the certificate and secret.
   525 static PEP_STATUS key_load(PEP_SESSION, sqlite3_stmt *, pgp_cert_t *, int *)
   526     __attribute__((nonnull(1, 2)));
   527 static PEP_STATUS key_load(PEP_SESSION session, sqlite3_stmt *stmt,
   528                            pgp_cert_t *certp, int *secretp)
   529 {
   530     PEP_STATUS status = PEP_STATUS_OK;
   531     int sqlite_result = sqlite3_step(stmt);
   532     switch (sqlite_result) {
   533     case SQLITE_ROW:
   534         if (certp) {
   535             int data_len = sqlite3_column_bytes(stmt, 0);
   536             const void *data = sqlite3_column_blob(stmt, 0);
   537 
   538             pgp_error_t err = NULL;
   539             *certp = pgp_cert_from_bytes(&err, data, data_len);
   540             if (!*certp)
   541                 ERROR_OUT(err, PEP_GET_KEY_FAILED, "parsing certificate");
   542         }
   543 
   544         if (secretp)
   545             *secretp = sqlite3_column_int(stmt, 1);
   546 
   547         break;
   548     case SQLITE_DONE:
   549         // Got nothing.
   550         status = PEP_KEY_NOT_FOUND;
   551         break;
   552     default:
   553         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   554                   "stepping: %s", sqlite3_errmsg(session->key_db));
   555     }
   556 
   557  out:
   558     T(" -> %s", pEp_status_to_string(status));
   559     return status;
   560 }
   561 
   562 // step statement until exhausted and load the certificates.
   563 static PEP_STATUS key_loadn(PEP_SESSION, sqlite3_stmt *, pgp_cert_t **, int *)
   564     __attribute__((nonnull));
   565 static PEP_STATUS key_loadn(PEP_SESSION session, sqlite3_stmt *stmt,
   566                             pgp_cert_t **certsp, int *certs_countp)
   567 {
   568     PEP_STATUS status = PEP_STATUS_OK;
   569     int certs_count = 0;
   570     int certs_capacity = 8;
   571     pgp_cert_t *certs = calloc(certs_capacity, sizeof(pgp_cert_t));
   572     if (!certs)
   573         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   574 
   575     for (;;) {
   576         pgp_cert_t cert = NULL;
   577         status = key_load(session, stmt, &cert, NULL);
   578         if (status == PEP_KEY_NOT_FOUND) {
   579             status = PEP_STATUS_OK;
   580             break;
   581         }
   582         ERROR_OUT(NULL, status, "loading certificate");
   583 
   584         if (certs_count == certs_capacity) {
   585             certs_capacity *= 2;
   586             certs = realloc(certs, sizeof(certs[0]) * certs_capacity);
   587             if (!certs)
   588                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "certs");
   589         }
   590         certs[certs_count ++] = cert;
   591     }
   592 
   593  out:
   594     if (status != PEP_STATUS_OK) {
   595         for (int i = 0; i < certs_count; i ++)
   596             pgp_cert_free(certs[i]);
   597         free(certs);
   598     } else {
   599         *certsp = certs;
   600         *certs_countp = certs_count;
   601     }
   602 
   603     T(" -> %s (%d certs)", pEp_status_to_string(status), *certs_countp);
   604     return status;
   605 }
   606 
   607 // Returns the certificate identified by the provided fingerprint.
   608 //
   609 // This function only matches on the primary key!
   610 static PEP_STATUS cert_find(PEP_SESSION, pgp_fingerprint_t, int, pgp_cert_t *, int *)
   611     __attribute__((nonnull(1, 2)));
   612 static PEP_STATUS cert_find(PEP_SESSION session,
   613                            pgp_fingerprint_t fpr, int private_only,
   614                            pgp_cert_t *cert, int *secret)
   615 {
   616     PEP_STATUS status = PEP_STATUS_OK;
   617     char *fpr_str = pgp_fingerprint_to_hex(fpr);
   618 
   619     T("(%s, %d)", fpr_str, private_only);
   620 
   621     sqlite3_stmt *stmt
   622         = private_only ? session->sq_sql.tsk_find : session->sq_sql.cert_find;
   623     sqlite3_bind_text(stmt, 1, fpr_str, -1, SQLITE_STATIC);
   624 
   625     status = key_load(session, stmt, cert, secret);
   626     ERROR_OUT(NULL, status, "Looking up %s", fpr_str);
   627 
   628  out:
   629     sqlite3_reset(stmt);
   630     T("(%s, %d) -> %s", fpr_str, private_only, pEp_status_to_string(status));
   631     free(fpr_str);
   632     return status;
   633 }
   634 
   635 // Returns the certificate identified by the provided keyid.
   636 //
   637 // This function matches on both primary keys and subkeys!
   638 //
   639 // Note: There can be multiple certificates for a given keyid.  This can
   640 // occur, because an encryption subkey can be bound to multiple certificates.
   641 // Also, it is possible to collide key ids.  If there are multiple key
   642 // ids for a given key, this just returns one of them.
   643 //
   644 // If private_only is set, this will only consider certificates with some
   645 // secret key material.
   646 static PEP_STATUS cert_find_by_keyid_hex(PEP_SESSION, const char *, int, pgp_cert_t *, int *)
   647   __attribute__((nonnull(1, 2)));
   648 static PEP_STATUS cert_find_by_keyid_hex(
   649         PEP_SESSION session, const char *keyid_hex, int private_only,
   650         pgp_cert_t *certp, int *secretp)
   651 {
   652     PEP_STATUS status = PEP_STATUS_OK;
   653     T("(%s, %d)", keyid_hex, private_only);
   654 
   655     sqlite3_stmt *stmt
   656         = private_only ? session->sq_sql.tsk_find_by_keyid : session->sq_sql.cert_find_by_keyid;
   657     sqlite3_bind_text(stmt, 1, keyid_hex, -1, SQLITE_STATIC);
   658 
   659     status = key_load(session, stmt, certp, secretp);
   660     ERROR_OUT(NULL, status, "Looking up %s", keyid_hex);
   661 
   662  out:
   663     sqlite3_reset(stmt);
   664     T("(%s, %d) -> %s", keyid_hex, private_only, pEp_status_to_string(status));
   665     return status;
   666 }
   667 
   668 // See cert_find_by_keyid_hex.
   669 PEP_STATUS cert_find_by_keyid(PEP_SESSION, pgp_keyid_t, int, pgp_cert_t *, int *)
   670     __attribute__((nonnull(1, 2)));
   671 PEP_STATUS cert_find_by_keyid(PEP_SESSION session,
   672                              pgp_keyid_t keyid, int private_only,
   673                              pgp_cert_t *certp, int *secretp)
   674 {
   675     char *keyid_hex = pgp_keyid_to_hex(keyid);
   676     if (! keyid_hex)
   677         return PEP_OUT_OF_MEMORY;
   678     PEP_STATUS status
   679         = cert_find_by_keyid_hex(session, keyid_hex, private_only, certp, secretp);
   680     free(keyid_hex);
   681     return status;
   682 }
   683 
   684 // See cert_find_by_keyid_hex.
   685 static PEP_STATUS cert_find_by_fpr(PEP_SESSION, pgp_fingerprint_t, int,
   686                                   pgp_cert_t *, int *)
   687     __attribute__((nonnull(1, 2)));
   688 static PEP_STATUS cert_find_by_fpr(
   689     PEP_SESSION session, pgp_fingerprint_t fpr, int private_only,
   690     pgp_cert_t *certp, int *secretp)
   691 {
   692     pgp_keyid_t keyid = pgp_fingerprint_to_keyid(fpr);
   693     if (! keyid)
   694         return PEP_OUT_OF_MEMORY;
   695     PEP_STATUS status
   696         = cert_find_by_keyid(session, keyid, private_only, certp, secretp);
   697     pgp_keyid_free(keyid);
   698     return status;
   699 }
   700 
   701 // See cert_find_by_keyid_hex.
   702 static PEP_STATUS cert_find_by_fpr_hex(PEP_SESSION, const char *, int, pgp_cert_t *, int *secret)
   703     __attribute__((nonnull(1, 2)));
   704 static PEP_STATUS cert_find_by_fpr_hex(
   705     PEP_SESSION session, const char *fpr, int private_only,
   706     pgp_cert_t *certp, int *secretp)
   707 {
   708     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
   709     if (! pgp_fpr)
   710         return PEP_OUT_OF_MEMORY;
   711     PEP_STATUS status
   712         = cert_find_by_fpr(session, pgp_fpr, private_only, certp, secretp);
   713     pgp_fingerprint_free(pgp_fpr);
   714     return status;
   715 }
   716 
   717 // Returns all known certificates.
   718 static PEP_STATUS cert_all(PEP_SESSION, int, pgp_cert_t **, int *) __attribute__((nonnull));
   719 static PEP_STATUS cert_all(PEP_SESSION session, int private_only,
   720                           pgp_cert_t **certsp, int *certs_countp) {
   721     PEP_STATUS status = PEP_STATUS_OK;
   722     sqlite3_stmt *stmt = private_only ? session->sq_sql.tsk_all : session->sq_sql.cert_all;
   723     status = key_loadn(session, stmt, certsp, certs_countp);
   724     ERROR_OUT(NULL, status, "loading certificates");
   725  out:
   726     sqlite3_reset(stmt);
   727     return status;
   728 }
   729 
   730 // Returns keys that have a user id that matches the specified pattern.
   731 //
   732 // The keys returned must be freed using pgp_cert_free.
   733 static PEP_STATUS cert_find_by_email(PEP_SESSION, const char *, int, pgp_cert_t **, int *)
   734     __attribute__((nonnull));
   735 static PEP_STATUS cert_find_by_email(PEP_SESSION session,
   736                                     const char *pattern, int private_only,
   737                                     pgp_cert_t **certsp, int *countp)
   738 {
   739     PEP_STATUS status = PEP_STATUS_OK;
   740     T("(%s)", pattern);
   741 
   742     sqlite3_stmt *stmt
   743         = private_only ? session->sq_sql.tsk_find_by_email : session->sq_sql.cert_find_by_email;
   744     sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_STATIC);
   745 
   746     status = key_loadn(session, stmt, certsp, countp);
   747     ERROR_OUT(NULL, status, "Searching for '%s'", pattern);
   748 
   749  out:
   750     sqlite3_reset(stmt);
   751     T("(%s) -> %s (%d results)", pattern, pEp_status_to_string(status), *countp);
   752     return status;
   753 }
   754 
   755 
   756 // Saves the specified certificates.
   757 //
   758 // This function takes ownership of CERT.
   759 static PEP_STATUS cert_save(PEP_SESSION, pgp_cert_t, identity_list **)
   760     __attribute__((nonnull(1, 2)));
   761 static PEP_STATUS cert_save(PEP_SESSION session, pgp_cert_t cert,
   762                            identity_list **private_idents)
   763 {
   764     PEP_STATUS status = PEP_STATUS_OK;
   765     pgp_error_t err = NULL;
   766     pgp_fingerprint_t pgp_fpr = NULL;
   767     char *fpr = NULL;
   768     void *tsk_buffer = NULL;
   769     size_t tsk_buffer_len = 0;
   770     int tried_commit = 0;
   771     pgp_cert_key_iter_t key_iter = NULL;
   772     pgp_user_id_binding_iter_t user_id_iter = NULL;
   773     char *email = NULL;
   774     char *name = NULL;
   775 
   776     sqlite3_stmt *stmt = session->sq_sql.begin_transaction;
   777     int sqlite_result = sqlite3_step(stmt);
   778     sqlite3_reset(stmt);
   779     if (sqlite_result != SQLITE_DONE)
   780         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   781                   "begin transaction failed: %s",
   782                   sqlite3_errmsg(session->key_db));
   783 
   784     pgp_fpr = pgp_cert_fingerprint(cert);
   785     fpr = pgp_fingerprint_to_hex(pgp_fpr);
   786     T("(%s, private_idents: %s)", fpr, private_idents ? "yes" : "no");
   787 
   788     // Merge any existing data into certificate.
   789     pgp_cert_t current = NULL;
   790     status = cert_find(session, pgp_fpr, false, &current, NULL);
   791     if (status == PEP_KEY_NOT_FOUND)
   792         status = PEP_STATUS_OK;
   793     else
   794         ERROR_OUT(NULL, status, "Looking up %s", fpr);
   795     if (current) {
   796         cert = pgp_cert_merge(&err, cert, current);
   797         if (! cert)
   798             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Merging certificates");
   799     }
   800 
   801     int is_tsk = pgp_cert_is_tsk(cert);
   802 
   803     // Serialize it.
   804     pgp_writer_t writer = pgp_writer_alloc(&tsk_buffer, &tsk_buffer_len);
   805     if (! writer)
   806         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   807 
   808     pgp_status_t pgp_status;
   809     pgp_tsk_t tsk = pgp_cert_as_tsk(cert);
   810     pgp_status = pgp_tsk_serialize(&err, tsk, writer);
   811     pgp_tsk_free(tsk);
   812     pgp_writer_free(writer);
   813     if (pgp_status != 0)
   814         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Serializing certificates");
   815 
   816 
   817     // Insert the TSK into the DB.
   818     stmt = session->sq_sql.cert_save_insert_primary;
   819     sqlite3_bind_text(stmt, 1, fpr, -1, SQLITE_STATIC);
   820     sqlite3_bind_int(stmt, 2, is_tsk);
   821     sqlite3_bind_blob(stmt, 3, tsk_buffer, tsk_buffer_len, SQLITE_STATIC);
   822 
   823     sqlite_result = sqlite3_step(stmt);
   824     sqlite3_reset(stmt);
   825     if (sqlite_result != SQLITE_DONE)
   826         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   827                   "Saving certificate: %s", sqlite3_errmsg(session->key_db));
   828 
   829     // Insert the "subkeys" (the primary key and the subkeys).
   830     stmt = session->sq_sql.cert_save_insert_subkeys;
   831     // This inserts all of the keys in the certificate, i.e., revoked and
   832     // expired keys, which is what we want.
   833     key_iter = pgp_cert_key_iter_all(cert);
   834     pgp_key_t key;
   835     while ((key = pgp_cert_key_iter_next(key_iter, NULL, NULL))) {
   836         pgp_keyid_t keyid = pgp_key_keyid(key);
   837         char *keyid_hex = pgp_keyid_to_hex(keyid);
   838         sqlite3_bind_text(stmt, 1, keyid_hex, -1, SQLITE_STATIC);
   839         sqlite3_bind_text(stmt, 2, fpr, -1, SQLITE_STATIC);
   840 
   841         sqlite_result = sqlite3_step(stmt);
   842         sqlite3_reset(stmt);
   843         free(keyid_hex);
   844         pgp_keyid_free(keyid);
   845         if (sqlite_result != SQLITE_DONE) {
   846             pgp_cert_key_iter_free(key_iter);
   847             ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   848                       "Updating subkeys: %s", sqlite3_errmsg(session->key_db));
   849         }
   850     }
   851     pgp_cert_key_iter_free(key_iter);
   852     key_iter = NULL;
   853 
   854     // Insert the "userids".
   855     stmt = session->sq_sql.cert_save_insert_userids;
   856     user_id_iter = pgp_cert_user_id_binding_iter(cert);
   857     pgp_user_id_binding_t binding;
   858     int first = 1;
   859     while ((binding = pgp_user_id_binding_iter_next(user_id_iter))) {
   860         char *user_id_value = pgp_user_id_binding_user_id(binding);
   861         if (!user_id_value || !*user_id_value)
   862             continue;
   863 
   864         // Ignore bindings with a self-revocation certificate, but no
   865         // self-signature.
   866         if (!pgp_user_id_binding_selfsig(binding)) {
   867             free(user_id_value);
   868             continue;
   869         }
   870 
   871         free(name);
   872         name = NULL;
   873         free(email);
   874         email = NULL;
   875 
   876         pgp_packet_t userid = pgp_user_id_new (user_id_value);
   877         pgp_user_id_name(NULL, userid, &name);
   878         // Try to get the normalized address.
   879         pgp_user_id_email_normalized(NULL, userid, &email);
   880         if (! email)
   881             // Ok, it's not a proper RFC 2822 name-addr.  Perhaps it
   882             // is a URI.
   883             pgp_user_id_uri(NULL, userid, &email);
   884         pgp_packet_free(userid);
   885         free(user_id_value);
   886 
   887         if (email) {
   888             T("  userid: %s", email);
   889 
   890             sqlite3_bind_text(stmt, 1, email, -1, SQLITE_STATIC);
   891             sqlite3_bind_text(stmt, 2, fpr, -1, SQLITE_STATIC);
   892 
   893             sqlite_result = sqlite3_step(stmt);
   894             sqlite3_reset(stmt);
   895 
   896             if (sqlite_result != SQLITE_DONE) {
   897                 pgp_user_id_binding_iter_free(user_id_iter);
   898                 ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   899                           "Updating userids: %s", sqlite3_errmsg(session->key_db));
   900             }
   901         }
   902 
   903         if (first && private_idents && is_tsk) {
   904             first = 0;
   905 
   906             // Create an identity for the primary user id.
   907             pEp_identity *ident = new_identity(email, fpr, NULL, name);
   908             if (ident == NULL)
   909                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_identity");
   910 
   911             *private_idents = identity_list_add(*private_idents, ident);
   912             if (*private_idents == NULL)
   913                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "identity_list_add");
   914         }
   915 
   916     }
   917     pgp_user_id_binding_iter_free(user_id_iter);
   918     user_id_iter = NULL;
   919 
   920  out:
   921     // Prevent ERROR_OUT from causing an infinite loop.
   922     if (! tried_commit) {
   923         tried_commit = 1;
   924         stmt = status == PEP_STATUS_OK
   925             ? session->sq_sql.commit_transaction
   926             : session->sq_sql.rollback_transaction;
   927         int sqlite_result = sqlite3_step(stmt);
   928         sqlite3_reset(stmt);
   929         if (sqlite_result != SQLITE_DONE)
   930             ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
   931                       status == PEP_STATUS_OK
   932                       ? "commit failed: %s" : "rollback failed: %s",
   933                       sqlite3_errmsg(session->key_db));
   934     }
   935 
   936     T("(%s) -> %s", fpr, pEp_status_to_string(status));
   937 
   938     free(email);
   939     free(name);
   940     pgp_user_id_binding_iter_free(user_id_iter);
   941     pgp_cert_key_iter_free(key_iter);
   942     if (stmt)
   943       sqlite3_reset(stmt);
   944     free(tsk_buffer);
   945     pgp_cert_free(cert);
   946     free(fpr);
   947     pgp_fingerprint_free(pgp_fpr);
   948 
   949     return status;
   950 }
   951 
   952 struct decrypt_cookie {
   953     PEP_SESSION session;
   954     int get_secret_keys_called;
   955     stringlist_t *recipient_keylist;
   956     stringlist_t *signer_keylist;
   957     int good_checksums;
   958     int good_but_expired;
   959     int good_but_revoked;
   960     int not_alive;
   961     int missing_keys;
   962     int bad_checksums;
   963 
   964     // Whether we decrypted anything.
   965     int decrypted;
   966 
   967     // The filename stored in the literal data packet.  Note: this is
   968     // *not* protected by the signature and should not be trusted!!!
   969     char *filename;
   970 };
   971 
   972 static pgp_status_t
   973 get_public_keys_cb(void *cookie_raw,
   974                    pgp_keyid_t *keyids, size_t keyids_len,
   975                    pgp_cert_t **certs, size_t *certs_len,
   976                    void (**our_free)(void *))
   977 {
   978     struct decrypt_cookie *cookie = cookie_raw;
   979     PEP_SESSION session = cookie->session;
   980 
   981     *certs = calloc(keyids_len, sizeof(*certs));
   982     if (!*certs)
   983         return PGP_STATUS_UNKNOWN_ERROR;
   984     *our_free = free;
   985 
   986     int i, j;
   987     j = 0;
   988     for (i = 0; i < keyids_len; i ++) {
   989         pgp_cert_t cert = NULL;
   990         PEP_STATUS status
   991             = cert_find_by_keyid(session, keyids[i], false, &cert, NULL);
   992         if (status == PEP_STATUS_OK)
   993             (*certs)[j ++] = cert;
   994     }
   995     *certs_len = j;
   996     return PGP_STATUS_SUCCESS;
   997 }
   998 
   999 static pgp_status_t
  1000 decrypt_cb(void *cookie_opaque,
  1001            pgp_pkesk_t *pkesks, size_t pkesk_count,
  1002            pgp_skesk_t *skesks, size_t skesk_count,
  1003            pgp_decryptor_do_decrypt_cb_t *decrypt,
  1004            void *decrypt_cookie,
  1005            pgp_fingerprint_t *identity_out)
  1006 {
  1007     pgp_error_t err = NULL;
  1008     struct decrypt_cookie *cookie = cookie_opaque;
  1009     PEP_SESSION session = cookie->session;
  1010     pgp_cert_t *tsks = NULL;
  1011     int tsks_count = 0;
  1012     int wildcards = 0;
  1013 
  1014     if (cookie->get_secret_keys_called)
  1015         // Prevent iterations, which isn't needed since we don't
  1016         // support SKESKs.
  1017         return PGP_STATUS_UNKNOWN_ERROR;
  1018     cookie->get_secret_keys_called = 1;
  1019 
  1020     T("%zd PKESKs", pkesk_count);
  1021 
  1022     for (int i = 0; i < pkesk_count; i ++) {
  1023         pgp_pkesk_t pkesk = pkesks[i];
  1024         pgp_keyid_t keyid = pgp_pkesk_recipient(pkesk); /* Reference. */
  1025         char *keyid_str = pgp_keyid_to_hex(keyid);
  1026         pgp_cert_key_iter_t key_iter = NULL;
  1027         pgp_session_key_t sk = NULL;
  1028 
  1029         T("Considering PKESK for %s", keyid_str);
  1030 
  1031         if (strcmp(keyid_str, "0000000000000000") == 0) {
  1032             // Initially ignore wildcards.
  1033             wildcards = 1;
  1034             goto eol;
  1035         }
  1036 
  1037         // Collect the recipients.  Note: we must return the primary
  1038         // key's fingerprint.
  1039         pgp_cert_t cert = NULL;
  1040         int is_tsk = 0;
  1041         if (cert_find_by_keyid(session, keyid, false, &cert, &is_tsk) != PEP_STATUS_OK)
  1042             goto eol;
  1043 
  1044         pgp_fingerprint_t fp = pgp_cert_fingerprint(cert);
  1045         char *fp_string = pgp_fingerprint_to_hex(fp);
  1046         stringlist_add_unique(cookie->recipient_keylist, fp_string);
  1047         free(fp_string);
  1048         pgp_fingerprint_free(fp);
  1049 
  1050         if (cookie->decrypted)
  1051             goto eol;
  1052 
  1053         // See if we have the secret key.
  1054         assert(is_tsk == pgp_cert_is_tsk(cert));
  1055         if (! is_tsk)
  1056             goto eol;
  1057 
  1058         key_iter = pgp_cert_key_iter_all(cert);
  1059         pgp_key_t key;
  1060         while ((key = pgp_cert_key_iter_next(key_iter, NULL, NULL))) {
  1061             pgp_keyid_t this_keyid = pgp_key_keyid(key);
  1062             char *this_keyid_hex = pgp_keyid_to_hex(this_keyid);
  1063             pgp_keyid_free(this_keyid);
  1064 
  1065             int match = strcmp(keyid_str, this_keyid_hex) == 0;
  1066             free(this_keyid_hex);
  1067             if (match)
  1068                 break;
  1069         }
  1070 
  1071         if (key == NULL) {
  1072             assert(!"Inconsistent DB: key doesn't contain a subkey with keyid!");
  1073             goto eol;
  1074         }
  1075 
  1076         uint8_t algo;
  1077         uint8_t session_key[1024];
  1078         size_t session_key_len = sizeof(session_key);
  1079         if (pgp_pkesk_decrypt(&err, pkesk, key, &algo,
  1080                               session_key, &session_key_len) != 0) {
  1081             DUMP_ERR(err, PEP_UNKNOWN_ERROR, "pgp_pkesk_decrypt");
  1082             goto eol;
  1083         }
  1084 
  1085         sk = pgp_session_key_from_bytes (session_key, session_key_len);
  1086         pgp_status_t status;
  1087         if ((status = decrypt (decrypt_cookie, algo, sk))) {
  1088             DUMP_STATUS(status, PEP_UNKNOWN_ERROR, "decrypt_cb");
  1089             goto eol;
  1090         }
  1091 
  1092         T("Decrypted PKESK for %s", keyid_str);
  1093 
  1094         *identity_out = pgp_cert_fingerprint(cert);
  1095         cookie->decrypted = 1;
  1096 
  1097     eol:
  1098         pgp_session_key_free (sk);
  1099         free(keyid_str);
  1100         pgp_cert_key_iter_free(key_iter);
  1101         pgp_cert_free(cert);
  1102     }
  1103 
  1104     // Consider wildcard recipients.
  1105     if (wildcards) for (int i = 0; i < pkesk_count && !cookie->decrypted; i ++) {
  1106         pgp_pkesk_t pkesk = pkesks[i];
  1107         pgp_keyid_t keyid = pgp_pkesk_recipient(pkesk); /* Reference. */
  1108         char *keyid_str = pgp_keyid_to_hex(keyid);
  1109         pgp_cert_key_iter_t key_iter = NULL;
  1110         pgp_session_key_t sk = NULL;
  1111 
  1112         if (strcmp(keyid_str, "0000000000000000") != 0)
  1113             goto eol2;
  1114 
  1115         if (!tsks) {
  1116             if (cert_all(session, true, &tsks, &tsks_count) != PEP_STATUS_OK) {
  1117                 DUMP_ERR(NULL, PEP_UNKNOWN_ERROR, "Getting all tsks");
  1118             }
  1119         }
  1120 
  1121         for (int j = 0; j < tsks_count; j ++) {
  1122             pgp_cert_t tsk = tsks[j];
  1123 
  1124             key_iter = pgp_cert_key_iter_all(tsk);
  1125             pgp_key_t key;
  1126             pgp_signature_t selfsig;
  1127             while ((key = pgp_cert_key_iter_next(key_iter, &selfsig, NULL))) {
  1128                 if (! (pgp_signature_for_storage_encryption(selfsig)
  1129                        || pgp_signature_for_transport_encryption(selfsig)))
  1130                     continue;
  1131 
  1132                 fprintf(stderr, "key: %s\n", pgp_key_debug(key));
  1133 
  1134                 // Note: for decryption to appear to succeed, we must
  1135                 // get a valid algorithm (8 of 256 values) and a
  1136                 // 16-bit checksum must match.  Thus, we have about a
  1137                 // 1 in 2**21 chance of having a false positive here.
  1138                 uint8_t algo;
  1139                 uint8_t session_key[1024];
  1140                 size_t session_key_len = sizeof(session_key);
  1141                 if (pgp_pkesk_decrypt(&err, pkesk, key,
  1142                                       &algo, session_key, &session_key_len)) {
  1143                     pgp_error_free(err);
  1144                     err = NULL;
  1145                     continue;
  1146                 }
  1147 
  1148                 // Add it to the recipient list.
  1149                 pgp_fingerprint_t fp = pgp_cert_fingerprint(tsk);
  1150                 char *fp_string = pgp_fingerprint_to_hex(fp);
  1151                 T("wildcard recipient appears to be %s", fp_string);
  1152                 stringlist_add_unique(cookie->recipient_keylist, fp_string);
  1153                 free(fp_string);
  1154                 pgp_fingerprint_free(fp);
  1155 
  1156                 pgp_session_key_t sk = pgp_session_key_from_bytes (session_key,
  1157                                                                    session_key_len);
  1158                 pgp_status_t status;
  1159                 if ((status = decrypt (decrypt_cookie, algo, sk))) {
  1160                     DUMP_STATUS(status, PEP_UNKNOWN_ERROR, "decrypt_cb");
  1161                     goto eol2;
  1162                 }
  1163 
  1164                 *identity_out = pgp_cert_fingerprint(tsk);
  1165                 cookie->decrypted = 1;
  1166 
  1167                 break;
  1168             }
  1169 
  1170             pgp_cert_key_iter_free(key_iter);
  1171             key_iter = NULL;
  1172         }
  1173     eol2:
  1174         pgp_session_key_free (sk);
  1175         free(keyid_str);
  1176         pgp_cert_key_iter_free(key_iter);
  1177     }
  1178 
  1179     if (tsks) {
  1180         for (int i = 0; i < tsks_count; i ++)
  1181             pgp_cert_free(tsks[i]);
  1182         free(tsks);
  1183     }
  1184 
  1185     return cookie->decrypted ? PGP_STATUS_SUCCESS : PGP_STATUS_UNKNOWN_ERROR;
  1186 }
  1187 
  1188 static pgp_status_t
  1189 check_signatures_cb(void *cookie_opaque, pgp_message_structure_t structure)
  1190 {
  1191     struct decrypt_cookie *cookie = cookie_opaque;
  1192     PEP_SESSION session = cookie->session;
  1193 
  1194     pgp_message_structure_iter_t iter
  1195         = pgp_message_structure_iter (structure);
  1196     for (pgp_message_layer_t layer = pgp_message_structure_iter_next (iter);
  1197          layer;
  1198          layer = pgp_message_structure_iter_next (iter)) {
  1199         pgp_verification_result_iter_t results;
  1200 
  1201         switch (pgp_message_layer_variant (layer)) {
  1202         case PGP_MESSAGE_LAYER_COMPRESSION:
  1203         case PGP_MESSAGE_LAYER_ENCRYPTION:
  1204             break;
  1205 
  1206         case PGP_MESSAGE_LAYER_SIGNATURE_GROUP:
  1207             pgp_message_layer_signature_group(layer, &results);
  1208             pgp_verification_result_t result;
  1209             while ((result = pgp_verification_result_iter_next (results))) {
  1210                 pgp_signature_t sig;
  1211                 pgp_keyid_t keyid = NULL;
  1212                 char *keyid_str = NULL;
  1213 
  1214                 switch (pgp_verification_result_variant (result)) {
  1215                 case PGP_VERIFICATION_RESULT_GOOD_CHECKSUM:
  1216                     // We need to add the fingerprint of the primary
  1217                     // key to cookie->signer_keylist.
  1218 
  1219                     pgp_verification_result_good_checksum (result, &sig, NULL,
  1220                                                            NULL, NULL, NULL);
  1221 
  1222                     // First try looking up by the certificate using the
  1223                     // IssuerFingerprint subpacket.
  1224                     pgp_fingerprint_t fpr
  1225                         = pgp_signature_issuer_fingerprint(sig);
  1226                     if (fpr) {
  1227                         // Even though we have a fingerprint, we have
  1228                         // to look the key up by keyid, because we
  1229                         // want to match on subkeys and we only store
  1230                         // keyids for subkeys.
  1231                         keyid = pgp_fingerprint_to_keyid(fpr);
  1232                         pgp_fingerprint_free(fpr);
  1233                     } else {
  1234                         // That is not available, try using the Issuer
  1235                         // subpacket.
  1236                         keyid = pgp_signature_issuer(sig);
  1237                     }
  1238 
  1239                     if (! keyid) {
  1240                         T("signature with no Issuer or Issuer Fingerprint subpacket!");
  1241                         goto eol;
  1242                     }
  1243 
  1244                     pgp_cert_t cert;
  1245                     if (cert_find_by_keyid(session, keyid, false,
  1246                                           &cert, NULL) != PEP_STATUS_OK)
  1247                         ; // Soft error.  Ignore.
  1248 
  1249                     keyid_str = pgp_keyid_to_string (keyid);
  1250 
  1251                     if (cert) {
  1252                         // Ok, we have a certificate.
  1253 
  1254                         // We need the primary key's fingerprint (not
  1255                         // the issuer fingerprint).
  1256                         pgp_fingerprint_t primary_fpr
  1257                             = pgp_cert_fingerprint(cert);
  1258                         char *primary_fpr_str
  1259                             = pgp_fingerprint_to_hex(primary_fpr);
  1260 
  1261                         bool good = true;
  1262 
  1263                         // Make sure the certificate is not revoked, its
  1264                         // creation time is <= now, and it hasn't
  1265                         // expired.
  1266                         pgp_revocation_status_t rs = pgp_cert_revoked(cert, 0);
  1267                         bool revoked = (pgp_revocation_status_variant(rs)
  1268                                         == PGP_REVOCATION_STATUS_REVOKED);
  1269                         pgp_revocation_status_free(rs);
  1270                         if (revoked) {
  1271                             T("certificate %s is revoked.", primary_fpr_str);
  1272                             good = false;
  1273                             cookie->good_but_revoked ++;
  1274                         } else if (! pgp_cert_alive(cert, 0)) {
  1275                             T("certificate %s is not alive.", primary_fpr_str);
  1276                             good = false;
  1277                             cookie->good_but_expired ++;
  1278                         }
  1279 
  1280                         // Same thing for the signing key.
  1281                         if (good) {
  1282                             pgp_cert_key_iter_t iter = pgp_cert_key_iter_all(cert);
  1283                             pgp_key_t key;
  1284                             pgp_signature_t sig;
  1285                             while ((key = pgp_cert_key_iter_next(iter, &sig, &rs))
  1286                                    && good) {
  1287                                 pgp_keyid_t x = pgp_key_keyid(key);
  1288                                 if (pgp_keyid_equal(keyid, x)) {
  1289                                     // Found the signing key.  Let's make
  1290                                     // sure it is valid.
  1291 
  1292                                     revoked = (pgp_revocation_status_variant(rs)
  1293                                                == PGP_REVOCATION_STATUS_REVOKED);
  1294                                     if (revoked) {
  1295                                         T("certificate %s's signing key %s is revoked.",
  1296                                           primary_fpr_str, keyid_str);
  1297                                         good = false;
  1298                                         cookie->good_but_revoked ++;
  1299                                     } else if (! pgp_signature_key_alive(sig, key, 0)) {
  1300                                         T("certificate %s's signing key %s is expired.",
  1301                                           primary_fpr_str, keyid_str);
  1302                                         good = false;
  1303                                         cookie->good_but_expired ++;
  1304                                     }
  1305                                 }
  1306                                 pgp_keyid_free(x);
  1307                                 pgp_revocation_status_free(rs);
  1308                                 pgp_signature_free(sig);
  1309                                 pgp_key_free(key);
  1310                             }
  1311                             pgp_cert_key_iter_free(iter);
  1312                         }
  1313 
  1314                         if (good) {
  1315                             stringlist_add_unique(cookie->signer_keylist,
  1316                                                   primary_fpr_str);
  1317 
  1318                             T("Good signature from %s", primary_fpr_str);
  1319 
  1320                             cookie->good_checksums ++;
  1321                         }
  1322 
  1323                         free(primary_fpr_str);
  1324                         pgp_fingerprint_free(primary_fpr);
  1325                         pgp_cert_free(cert);
  1326                     } else {
  1327                         // If we get
  1328                         // PGP_VERIFICATION_RESULT_CODE_GOOD_CHECKSUM,
  1329                         // then the CERT should be available.  But,
  1330                         // another process could have deleted the key
  1331                         // from the store in the mean time, so be
  1332                         // tolerant.
  1333                         T("Key to check signature from %s disappeared",
  1334                           keyid_str);
  1335                         cookie->missing_keys ++;
  1336                     }
  1337                     break;
  1338 
  1339                 case PGP_VERIFICATION_RESULT_NOT_ALIVE:
  1340                     pgp_verification_result_not_alive
  1341                         (result, &sig, NULL, NULL, NULL, NULL);
  1342                     keyid = pgp_signature_issuer (sig);
  1343                     keyid_str = pgp_keyid_to_string (keyid);
  1344                     T("Signature from from %s is not alive", keyid_str);
  1345 
  1346                     cookie->not_alive ++;
  1347                     break;
  1348 
  1349                 case PGP_VERIFICATION_RESULT_MISSING_KEY:
  1350                     pgp_verification_result_missing_key (result, &sig);
  1351                     keyid = pgp_signature_issuer (sig);
  1352                     keyid_str = pgp_keyid_to_string (keyid);
  1353                     T("No key to check signature from %s", keyid_str);
  1354 
  1355                     cookie->missing_keys ++;
  1356                     break;
  1357 
  1358                 case PGP_VERIFICATION_RESULT_BAD_CHECKSUM:
  1359                     pgp_verification_result_bad_checksum
  1360                         (result, &sig, NULL, NULL, NULL, NULL);
  1361                     keyid = pgp_signature_issuer (sig);
  1362                     if (keyid) {
  1363                         keyid_str = pgp_keyid_to_string (keyid);
  1364                         T("Bad signature from %s", keyid_str);
  1365                     } else {
  1366                         T("Bad signature without issuer information");
  1367                     }
  1368 
  1369                     cookie->bad_checksums ++;
  1370                     break;
  1371 
  1372                 default:
  1373                     assert (! "reachable");
  1374                 }
  1375 
  1376             eol:
  1377                 free (keyid_str);
  1378                 pgp_signature_free (sig);
  1379                 pgp_verification_result_free (result);
  1380             }
  1381             pgp_verification_result_iter_free (results);
  1382             break;
  1383 
  1384         default:
  1385             assert (! "reachable");
  1386         }
  1387 
  1388         pgp_message_layer_free (layer);
  1389     }
  1390 
  1391     pgp_message_structure_iter_free (iter);
  1392     pgp_message_structure_free (structure);
  1393 
  1394     return PGP_STATUS_SUCCESS;
  1395 }
  1396 
  1397 static pgp_status_t inspect_cb(
  1398     void *cookie_opaque, pgp_packet_parser_t pp)
  1399 {
  1400     struct decrypt_cookie *cookie = cookie_opaque;
  1401 
  1402     pgp_packet_t packet = pgp_packet_parser_packet(pp);
  1403     assert(packet);
  1404 
  1405     pgp_tag_t tag = pgp_packet_tag(packet);
  1406 
  1407     T("%s", pgp_tag_to_string(tag));
  1408 
  1409     if (tag == PGP_TAG_LITERAL) {
  1410         pgp_literal_t literal = pgp_packet_ref_literal(packet);
  1411         cookie->filename = pgp_literal_filename(literal);
  1412         pgp_literal_free(literal);
  1413     }
  1414 
  1415     pgp_packet_free(packet);
  1416 
  1417     return 0;
  1418 }
  1419 
  1420 PEP_STATUS pgp_decrypt_and_verify(
  1421     PEP_SESSION session, const char *ctext, size_t csize,
  1422     const char *dsigtext, size_t dsigsize,
  1423     char **ptext, size_t *psize, stringlist_t **keylist,
  1424     char** filename_ptr)
  1425 {
  1426     PEP_STATUS status = PEP_STATUS_OK;
  1427     struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, NULL };
  1428     pgp_reader_t reader = NULL;
  1429     pgp_writer_t writer = NULL;
  1430     pgp_reader_t decryptor = NULL;
  1431     *ptext = NULL;
  1432     *psize = 0;
  1433 
  1434     // XXX: We don't yet handle detached signatures over encrypted
  1435     // messages.
  1436     assert(!dsigtext);
  1437 
  1438     cookie.recipient_keylist = new_stringlist(NULL);
  1439     if (!cookie.recipient_keylist)
  1440         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "recipient_keylist");
  1441 
  1442     cookie.signer_keylist = new_stringlist(NULL);
  1443     if (!cookie.signer_keylist)
  1444         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "signer_keylist");
  1445 
  1446     reader = pgp_reader_from_bytes((const uint8_t *) ctext, csize);
  1447     if (! reader)
  1448         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating reader");
  1449 
  1450     writer = pgp_writer_alloc((void **) ptext, psize);
  1451     if (! writer)
  1452         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "Creating writer");
  1453 
  1454     pgp_error_t err = NULL;
  1455     decryptor = pgp_decryptor_new(&err, reader,
  1456                                   get_public_keys_cb, decrypt_cb,
  1457                                   check_signatures_cb, inspect_cb,
  1458                                   &cookie, 0);
  1459     if (! decryptor)
  1460         ERROR_OUT(err, PEP_DECRYPT_NO_KEY, "pgp_decryptor_new");
  1461 
  1462     // Copy 128 MB at a time.
  1463     ssize_t nread;
  1464     while ((nread = pgp_reader_copy (&err, decryptor, writer,
  1465                                      128 * 1024 * 1024) > 0))
  1466         ;
  1467     if (nread < 0)
  1468         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "pgp_reader_read");
  1469 
  1470     // Add a terminating NUL for naive users
  1471     pgp_writer_write(&err, writer, (const uint8_t *) &""[0], 1);
  1472 
  1473     if (! cookie.decrypted)
  1474         ERROR_OUT(err, PEP_DECRYPT_NO_KEY, "Decryption failed");
  1475 
  1476     if (! cookie.signer_keylist) {
  1477         cookie.signer_keylist = new_stringlist("");
  1478         if (! cookie.signer_keylist)
  1479             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "cookie.signer_keylist");
  1480     }
  1481     if (!cookie.signer_keylist->value)
  1482         stringlist_add(cookie.signer_keylist, "");
  1483 
  1484     *keylist = cookie.signer_keylist;
  1485     stringlist_append(*keylist, cookie.recipient_keylist);
  1486 
  1487     if (filename_ptr)
  1488         *filename_ptr = cookie.filename;
  1489 
  1490  out:
  1491     if (status == PEP_STATUS_OK) {
  1492         // **********************************
  1493         // Sync changes with pgp_verify_text.
  1494         // **********************************
  1495 
  1496         if (cookie.good_checksums) {
  1497             // If there is at least one signature that we can verify,
  1498             // succeed.
  1499             status = PEP_DECRYPTED_AND_VERIFIED;
  1500         } else if (cookie.good_but_revoked) {
  1501             // If there are any signatures from revoked keys, fail.
  1502             status = PEP_VERIFY_SIGNER_KEY_REVOKED;
  1503         } else if (cookie.bad_checksums) {
  1504             // If there are any bad signatures, fail.
  1505             status = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  1506         } else if (cookie.good_but_expired) {
  1507             // If there are any signatures from expired keys, fail.
  1508             status = PEP_DECRYPTED;
  1509         } else {
  1510             // We couldn't verify any signatures (possibly because we
  1511             // don't have the keys).
  1512             status = PEP_DECRYPTED;
  1513         }
  1514     } else {
  1515         free_stringlist(cookie.recipient_keylist);
  1516         free_stringlist(cookie.signer_keylist);
  1517         free(cookie.filename);
  1518         free(*ptext);
  1519     }
  1520 
  1521     pgp_reader_free(reader);
  1522     pgp_reader_free(decryptor);
  1523     pgp_writer_free(writer);
  1524 
  1525     T("-> %s", pEp_status_to_string(status));
  1526     return status;
  1527 }
  1528 
  1529 PEP_STATUS pgp_verify_text(
  1530     PEP_SESSION session, const char *text, size_t size,
  1531     const char *signature, size_t sig_size, stringlist_t **keylist)
  1532 {
  1533     PEP_STATUS status = PEP_STATUS_OK;
  1534     pgp_error_t err = NULL;
  1535     struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, };
  1536     pgp_reader_t reader = NULL;
  1537     pgp_reader_t dsig_reader = NULL;
  1538     pgp_reader_t verifier = NULL;
  1539 
  1540     if (size == 0 || sig_size == 0)
  1541         return PEP_DECRYPT_WRONG_FORMAT;
  1542 
  1543 #if TRACING > 0
  1544     {
  1545         int cr = 0;
  1546         int crlf = 0;
  1547         int lf = 0;
  1548 
  1549         for (int i = 0; i < size; i ++) {
  1550             // CR
  1551             if (text[i] == '\r') {
  1552                 cr ++;
  1553             }
  1554             // LF
  1555             if (text[i] == '\n') {
  1556                 if (i > 0 && text[i - 1] == '\r') {
  1557                     cr --;
  1558                     crlf ++;
  1559                 } else {
  1560                     lf ++;
  1561                 }
  1562             }
  1563         }
  1564 
  1565         T("Text to verify: %zd bytes with %d crlfs, %d bare crs and %d bare lfs",
  1566           size, crlf, cr, lf);
  1567     }
  1568 #endif
  1569 
  1570     cookie.recipient_keylist = new_stringlist(NULL);
  1571     if (!cookie.recipient_keylist)
  1572         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1573 
  1574     cookie.signer_keylist = new_stringlist(NULL);
  1575     if (!cookie.signer_keylist)
  1576         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1577 
  1578     reader = pgp_reader_from_bytes((const uint8_t *) text, size);
  1579     if (! reader)
  1580         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating reader");
  1581 
  1582     dsig_reader = NULL;
  1583     if (signature) {
  1584         dsig_reader = pgp_reader_from_bytes((uint8_t *) signature, sig_size);
  1585         if (! dsig_reader)
  1586             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating signature reader");
  1587     }
  1588 
  1589     if (dsig_reader)
  1590         verifier = pgp_detached_verifier_new(&err, dsig_reader, reader,
  1591                                              get_public_keys_cb,
  1592                                              check_signatures_cb,
  1593                                              &cookie, 0);
  1594     else
  1595         verifier = pgp_verifier_new(&err, reader,
  1596                                     get_public_keys_cb,
  1597                                     check_signatures_cb,
  1598                                     &cookie, 0);
  1599     if (! verifier)
  1600         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Creating verifier");
  1601     if (pgp_reader_discard(&err, verifier) < 0)
  1602         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "verifier");
  1603 
  1604     if (! cookie.signer_keylist) {
  1605         cookie.signer_keylist = new_stringlist("");
  1606         if (! cookie.signer_keylist)
  1607             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "cookie.signer_keylist");
  1608     }
  1609     if (!cookie.signer_keylist->value)
  1610         stringlist_add(cookie.signer_keylist, "");
  1611 
  1612     *keylist = cookie.signer_keylist;
  1613     stringlist_append(*keylist, cookie.recipient_keylist);
  1614 
  1615  out:
  1616     if (status == PEP_STATUS_OK) {
  1617         // *****************************************
  1618         // Sync changes with pgp_decrypt_and_verify.
  1619         // *****************************************
  1620 
  1621         if (cookie.good_but_expired) {
  1622             // If there are any signatures from expired keys, fail.
  1623             status = PEP_UNENCRYPTED;
  1624         } else if (cookie.good_but_revoked) {
  1625             // If there are any signatures from revoked keys, fail.
  1626             status = PEP_VERIFY_SIGNER_KEY_REVOKED;
  1627         } else if (cookie.bad_checksums) {
  1628             // If there are any bad signatures, fail.
  1629             status = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  1630         } else if (cookie.good_checksums) {
  1631             // If there is at least one signature that we can verify,
  1632             // succeed.
  1633             status = PEP_VERIFIED;
  1634         } else {
  1635             // We couldn't verify any signatures (possibly because we
  1636             // don't have the keys).
  1637             status = PEP_UNENCRYPTED;
  1638         }
  1639     } else {
  1640         free_stringlist(cookie.recipient_keylist);
  1641         free_stringlist(cookie.signer_keylist);
  1642     }
  1643 
  1644     pgp_reader_free(verifier);
  1645     pgp_reader_free(reader);
  1646     pgp_reader_free(dsig_reader);
  1647 
  1648     T("-> %s", pEp_status_to_string(status));
  1649     return status;
  1650 }
  1651 
  1652 
  1653 PEP_STATUS pgp_sign_only(
  1654     PEP_SESSION session, const char* fpr, const char *ptext,
  1655     size_t psize, char **stext, size_t *ssize)
  1656 {
  1657     assert(session);
  1658     assert(fpr && fpr[0]);
  1659     assert(ptext);
  1660     assert(psize);
  1661     assert(stext);
  1662     assert(ssize);
  1663     *stext = NULL;
  1664     *ssize = 0;
  1665 
  1666     PEP_STATUS status = PEP_STATUS_OK;
  1667     pgp_error_t err = NULL;
  1668     pgp_cert_t signer_cert = NULL;
  1669     pgp_cert_key_iter_t iter = NULL;
  1670     pgp_key_pair_t signing_keypair = NULL;
  1671     pgp_signer_t signer = NULL;
  1672     pgp_writer_stack_t ws = NULL;
  1673 
  1674     status = cert_find_by_fpr_hex(session, fpr, true, &signer_cert, NULL);
  1675     ERROR_OUT(NULL, status, "Looking up key '%s'", fpr);
  1676 
  1677     iter = pgp_cert_key_iter_valid(signer_cert);
  1678     pgp_cert_key_iter_for_signing (iter);
  1679     pgp_cert_key_iter_unencrypted_secret (iter);
  1680 
  1681     // If there are multiple signing capable subkeys, we just take
  1682     // the first one, whichever one that happens to be.
  1683     pgp_key_t key = pgp_cert_key_iter_next (iter, NULL, NULL);
  1684     if (! key)
  1685         ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  1686                    "%s has no signing capable key", fpr);
  1687 
  1688     signing_keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  1689     if (! signing_keypair)
  1690         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  1691 
  1692     signer = pgp_key_pair_as_signer (signing_keypair);
  1693     if (! signer)
  1694         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  1695 
  1696 
  1697     pgp_writer_t writer = pgp_writer_alloc((void **) stext, ssize);
  1698     writer = pgp_armor_writer_new(&err, writer,
  1699                                   PGP_ARMOR_KIND_MESSAGE, NULL, 0);
  1700     if (!writer)
  1701         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up armor writer");
  1702 
  1703     ws = pgp_writer_stack_message(writer);
  1704 
  1705     ws = pgp_signer_new_detached(&err, ws, &signer, 1, 0);
  1706     if (!ws)
  1707         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
  1708     // pgp_signer_new_detached consumes signer.
  1709     signer = NULL;
  1710 
  1711     pgp_status_t write_status =
  1712         pgp_writer_stack_write_all (&err, ws,
  1713                                     (uint8_t *) ptext, psize);
  1714     if (write_status != 0)
  1715         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
  1716 
  1717     pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
  1718     ws = NULL;
  1719     if (pgp_status != 0)
  1720         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
  1721 
  1722     // Add a terminating NUL for naive users
  1723     void *t = realloc(*stext, *ssize + 1);
  1724     if (! t)
  1725         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1726     *stext = t;
  1727     (*stext)[*ssize] = 0;
  1728 
  1729  out:
  1730     pgp_signer_free (signer);
  1731     // XXX: pgp_key_pair_as_signer is only supposed to reference
  1732     // signing_keypair, but it consumes it.  If this is fixed, this
  1733     // will become a leak.
  1734     //
  1735     //pgp_key_pair_free (signing_keypair);
  1736     pgp_cert_key_iter_free (iter);
  1737     pgp_cert_free(signer_cert);
  1738 
  1739     T("(%s)-> %s", fpr, pEp_status_to_string(status));
  1740     return status;
  1741 }
  1742 
  1743 static PEP_STATUS pgp_encrypt_sign_optional(
  1744     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  1745     size_t psize, char **ctext, size_t *csize, bool sign)
  1746 {
  1747     PEP_STATUS status = PEP_STATUS_OK;
  1748     pgp_error_t err = NULL;
  1749 
  1750     int recipient_cert_count = 0;
  1751     pgp_cert_t *recipient_certs = NULL;
  1752 
  1753     int recipient_count = 0;
  1754     int recipient_alloc = 0;
  1755     pgp_recipient_t *recipients = NULL;
  1756     int recipient_keys_count = 0;
  1757     pgp_key_t *recipient_keys = NULL;
  1758 
  1759     pgp_cert_t signer_cert = NULL;
  1760     pgp_writer_stack_t ws = NULL;
  1761     pgp_cert_key_iter_t iter = NULL;
  1762     pgp_key_pair_t signing_keypair = NULL;
  1763     pgp_signer_t signer = NULL;
  1764 
  1765     assert(session);
  1766     assert(keylist);
  1767     assert(ptext);
  1768     assert(psize);
  1769     assert(ctext);
  1770     assert(csize);
  1771 
  1772     *ctext = NULL;
  1773     *csize = 0;
  1774 
  1775     int keylist_len = stringlist_length(keylist);
  1776 
  1777     // We don't need to worry about extending recipient_certs, because
  1778     // there will be at most KEYLIST_LEN certs, which we allocate up
  1779     // front.
  1780     recipient_certs = calloc(keylist_len, sizeof(*recipient_certs));
  1781     if (recipient_certs == NULL)
  1782         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1783 
  1784     // Because there may be multiple encryption keys per certificate, we may
  1785     // need to extend recipient_keys and recipients.
  1786     recipient_alloc = keylist_len;
  1787     recipient_keys = calloc(recipient_alloc, sizeof(*recipient_keys));
  1788     if (recipient_keys == NULL)
  1789         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1790 
  1791     recipients = calloc(recipient_alloc, sizeof(*recipients));
  1792     if (recipients == NULL)
  1793         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1794 
  1795 
  1796     // Get the keys for the recipients.
  1797     const stringlist_t *_keylist;
  1798     for (_keylist = keylist; _keylist != NULL; _keylist = _keylist->next) {
  1799         assert(_keylist->value);
  1800 
  1801         pgp_cert_t cert;
  1802         status = cert_find_by_fpr_hex(session, _keylist->value,
  1803                                      false, &cert, NULL);
  1804         // We couldn't find a key for this recipient.
  1805         ERROR_OUT(NULL, status,
  1806                   "Looking up key for recipient '%s'", _keylist->value);
  1807 
  1808         recipient_certs[recipient_cert_count ++] = cert;
  1809 
  1810         // Collect all of the keys that have the encryption for
  1811         // transport capability.
  1812         pgp_cert_key_iter_t iter = pgp_cert_key_iter_valid(cert);
  1813         if (! iter)
  1814             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1815         pgp_cert_key_iter_for_transport_encryption(iter);
  1816 
  1817         pgp_key_t key;
  1818         while ((key = pgp_cert_key_iter_next (iter, NULL, NULL))) {
  1819             assert(recipient_count == recipient_keys_count);
  1820             if (recipient_count == recipient_alloc) {
  1821                 assert(recipient_alloc > 0);
  1822                 recipient_alloc *= 2;
  1823 
  1824                 void *t = _pEp_reallocarray(recipient_keys, recipient_alloc,
  1825                                        sizeof(*recipient_keys));
  1826                 if (! t)
  1827                     ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1828                 recipient_keys = t;
  1829 
  1830                 t = _pEp_reallocarray(recipients, recipient_alloc,
  1831                                  sizeof(*recipients));
  1832                 if (! t)
  1833                     ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1834                 recipients = t;
  1835             }
  1836 
  1837             // pgp_recipient_new consumes the passed key id, but it
  1838             // only references key (i.e., we still have to free key).
  1839             pgp_keyid_t keyid = pgp_key_keyid(key);
  1840             if (! key)
  1841                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1842 
  1843             key = pgp_key_clone(key);
  1844             if (! key)
  1845                 ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1846             recipient_keys[recipient_keys_count++] = key;
  1847 
  1848             recipients[recipient_count++] = pgp_recipient_new(keyid, key);
  1849         }
  1850         pgp_cert_key_iter_free(iter);
  1851     }
  1852 
  1853     if (sign) {
  1854         // The first key in the keylist is the signer.
  1855         status = cert_find_by_fpr_hex(session, keylist->value, true, &signer_cert, NULL);
  1856         ERROR_OUT(NULL, status, "Looking up key for signing '%s'", keylist->value);
  1857     }
  1858 
  1859     pgp_writer_t writer_alloc = pgp_writer_alloc((void **) ctext, csize);
  1860     pgp_writer_t writer = pgp_armor_writer_new(&err, writer_alloc,
  1861                                   PGP_ARMOR_KIND_MESSAGE, NULL, 0);
  1862     if (!writer)
  1863         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up armor writer");
  1864 
  1865     ws = pgp_writer_stack_message(writer);
  1866     ws = pgp_encryptor_new (&err, ws,
  1867                             NULL, 0, recipients, recipient_count,
  1868                             0, 0);
  1869     if (!ws)
  1870         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up encryptor");
  1871 
  1872     // pgp_encrypt_new consumes the recipients (but not the keys).
  1873     recipient_count = 0;
  1874 
  1875     if (sign) {
  1876         iter = pgp_cert_key_iter_valid(signer_cert);
  1877         pgp_cert_key_iter_for_signing (iter);
  1878         pgp_cert_key_iter_unencrypted_secret (iter);
  1879 
  1880         // If there are multiple signing capable subkeys, we just take
  1881         // the first one, whichever one that happens to be.
  1882         pgp_key_t key = pgp_cert_key_iter_next (iter, NULL, NULL);
  1883         if (! key)
  1884             ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  1885                        "%s has no signing capable key", keylist->value);
  1886 
  1887         signing_keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  1888         if (! signing_keypair)
  1889             ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  1890 
  1891         signer = pgp_key_pair_as_signer (signing_keypair);
  1892         if (! signer)
  1893             ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  1894 
  1895         ws = pgp_signer_new(&err, ws, &signer, 1, 0);
  1896         if (!ws)
  1897             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
  1898         // pgp_signer_new consumes signer.
  1899         signer = NULL;
  1900     }
  1901 
  1902     ws = pgp_literal_writer_new (&err, ws);
  1903     if (!ws)
  1904         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up literal writer");
  1905 
  1906     pgp_status_t write_status =
  1907         pgp_writer_stack_write_all (&err, ws,
  1908                                     (uint8_t *) ptext, psize);
  1909     if (write_status != 0)
  1910         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
  1911 
  1912     pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
  1913     ws = NULL;
  1914     if (pgp_status != 0)
  1915         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
  1916 
  1917     pgp_writer_free (writer_alloc);
  1918 
  1919     // Add a terminating NUL for naive users
  1920     void *t = realloc(*ctext, *csize + 1);
  1921     if (! t) {
  1922         free(*ctext);
  1923         *ctext = NULL;
  1924         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1925     }
  1926     *ctext = t;
  1927     (*ctext)[*csize] = 0;
  1928 
  1929  out:
  1930     pgp_signer_free (signer);
  1931     // XXX: pgp_key_pair_as_signer is only supposed to reference
  1932     // signing_keypair, but it consumes it.  If this is fixed, this
  1933     // will become a leak.
  1934     //
  1935     // pgp_key_pair_free (signing_keypair);
  1936     pgp_cert_key_iter_free (iter);
  1937     pgp_cert_free(signer_cert);
  1938 
  1939     for (int i = 0; i < recipient_count; i ++)
  1940         pgp_recipient_free(recipients[i]);
  1941     free(recipients);
  1942     for (int i = 0; i < recipient_keys_count; i ++)
  1943         pgp_key_free(recipient_keys[i]);
  1944     free(recipient_keys);
  1945     for (int i = 0; i < recipient_cert_count; i ++)
  1946         pgp_cert_free(recipient_certs[i]);
  1947     free(recipient_certs);
  1948 
  1949     T("-> %s", pEp_status_to_string(status));
  1950     return status;
  1951 }
  1952 
  1953 PEP_STATUS pgp_encrypt_only(
  1954     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  1955     size_t psize, char **ctext, size_t *csize)
  1956 {
  1957     return pgp_encrypt_sign_optional(session, keylist, ptext,
  1958         psize, ctext, csize, false);
  1959 }
  1960 
  1961 PEP_STATUS pgp_encrypt_and_sign(
  1962     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  1963     size_t psize, char **ctext, size_t *csize)
  1964 {
  1965     return pgp_encrypt_sign_optional(session, keylist, ptext,
  1966         psize, ctext, csize, true);
  1967 }
  1968 
  1969 
  1970 PEP_STATUS pgp_generate_keypair(PEP_SESSION session, pEp_identity *identity)
  1971 {
  1972     PEP_STATUS status = PEP_STATUS_OK;
  1973     pgp_error_t err = NULL;
  1974     pgp_packet_t userid_packet = NULL;
  1975     char *userid = NULL;
  1976     pgp_cert_t cert = NULL;
  1977     pgp_fingerprint_t pgp_fpr = NULL;
  1978     char *fpr = NULL;
  1979 
  1980     assert(session);
  1981     assert(identity);
  1982     assert(identity->address);
  1983     assert(identity->fpr == NULL || identity->fpr[0] == 0);
  1984     assert(identity->username);
  1985 
  1986     userid_packet = pgp_user_id_from_unchecked_address(&err,
  1987                                                        identity->username, NULL,
  1988                                                        identity->address);
  1989     if (!userid_packet)
  1990         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "pgp_user_id_from_other_address");
  1991 
  1992     size_t userid_len = 0;
  1993     const uint8_t *raw = pgp_user_id_value(userid_packet, &userid_len);
  1994 
  1995     // NUL terminate it.
  1996     userid = malloc(userid_len + 1);
  1997     if (!userid)
  1998         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  1999 
  2000     memcpy(userid, raw, userid_len);
  2001     userid[userid_len] = 0;
  2002 
  2003     T("(%s)", userid);
  2004 
  2005     // Generate a key.
  2006     pgp_cert_builder_t certb = pgp_cert_builder_general_purpose(
  2007         cipher_suite(session->cipher_suite), userid);
  2008     pgp_signature_t rev;
  2009     if (pgp_cert_builder_generate(&err, certb, &cert, &rev))
  2010         ERROR_OUT(err, PEP_CANNOT_CREATE_KEY, "Generating a key pair");
  2011 
  2012     // XXX: We should return this.
  2013     pgp_signature_free(rev);
  2014 
  2015     // Get the fingerprint.
  2016     pgp_fpr = pgp_cert_fingerprint(cert);
  2017     fpr = pgp_fingerprint_to_hex(pgp_fpr);
  2018 
  2019     status = cert_save(session, cert, NULL);
  2020     cert = NULL;
  2021     if (status != 0)
  2022         ERROR_OUT(NULL, PEP_CANNOT_CREATE_KEY, "saving TSK");
  2023 
  2024     free(identity->fpr);
  2025     identity->fpr = fpr;
  2026     fpr = NULL;
  2027 
  2028  out:
  2029     pgp_fingerprint_free(pgp_fpr);
  2030     free(fpr);
  2031     pgp_cert_free(cert);
  2032     free(userid);
  2033     pgp_packet_free(userid_packet);
  2034 
  2035     T("-> %s", pEp_status_to_string(status));
  2036     return status;
  2037 }
  2038 
  2039 PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr_raw)
  2040 {
  2041     PEP_STATUS status = PEP_STATUS_OK;
  2042 
  2043     assert(session && fpr_raw && fpr_raw[0]);
  2044     if (!(session && fpr_raw && fpr_raw[0]))
  2045         ERROR_OUT(NULL, PEP_ILLEGAL_VALUE, "invalid arguments");
  2046 
  2047     char *fpr = pgp_fingerprint_canonicalize(fpr_raw);
  2048     if (! fpr)
  2049         ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  2050 
  2051     T("Deleting %s", fpr);
  2052 
  2053     sqlite3_stmt *stmt = session->sq_sql.delete_keypair;
  2054     sqlite3_bind_text(stmt, 1, fpr, -1, free);
  2055 
  2056     int sqlite_result = sqlite3_step(stmt);
  2057     sqlite3_reset(stmt);
  2058     if (sqlite_result != SQLITE_DONE)
  2059         ERROR_OUT(NULL, PEP_CANNOT_DELETE_KEY,
  2060                   "deletion failed: %s", sqlite3_errmsg(session->key_db));
  2061 
  2062     sqlite_result = sqlite3_changes(session->key_db);
  2063     assert(sqlite_result >= 0 && sqlite_result < 2);
  2064     if (sqlite_result < 1)
  2065         ERROR_OUT(NULL, PEP_KEY_NOT_FOUND,
  2066                   "attempt to delete non-existent key: %s", fpr_raw);
  2067 
  2068  out:
  2069     return status;
  2070 }
  2071 
  2072 static unsigned int count_keydata_parts(const char* key_data, size_t size) {
  2073     unsigned int retval = 0;
  2074     
  2075     const char* pgp_begin = "-----BEGIN PGP";
  2076     size_t prefix_len = strlen(pgp_begin);
  2077     size_t size_remaining = size;
  2078     
  2079     while (key_data) {
  2080         if (size_remaining <= prefix_len || key_data[0] == '\0')
  2081             break;
  2082         key_data = strnstr(key_data, pgp_begin, size_remaining);
  2083         if (key_data) {
  2084             retval++;
  2085             key_data += prefix_len;
  2086             size_remaining -= prefix_len;
  2087         }
  2088     }
  2089     return retval;
  2090  }
  2091 
  2092 PEP_STATUS _pgp_import_keydata(PEP_SESSION session, const char *key_data,
  2093                               size_t size, identity_list **private_idents)
  2094 {
  2095     PEP_STATUS status = PEP_NO_KEY_IMPORTED;
  2096     pgp_error_t err;
  2097     pgp_cert_parser_t parser = NULL;
  2098 
  2099     if (private_idents)
  2100         *private_idents = NULL;
  2101 
  2102     T("parsing %zd bytes", size);
  2103 
  2104     pgp_packet_parser_result_t ppr
  2105         = pgp_packet_parser_from_bytes(&err, (uint8_t *) key_data, size);
  2106     if (! ppr)
  2107         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Creating packet parser");
  2108 
  2109     pgp_tag_t tag = pgp_packet_parser_result_tag(ppr);
  2110     switch (tag) {
  2111     case PGP_TAG_SIGNATURE: {
  2112         // The following asserts can't fail, because
  2113         // pgp_packet_parser_result_tag succeeded and the tag is
  2114         // right.
  2115         pgp_packet_parser_t pp = pgp_packet_parser_result_packet_parser (ppr);
  2116         assert(pp);
  2117 
  2118         pgp_packet_t packet = NULL;
  2119         if (pgp_packet_parser_next(&err, pp, &packet, &ppr))
  2120             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Getting signature packet");
  2121 
  2122         pgp_signature_t sig = pgp_packet_ref_signature (packet);
  2123         assert(sig);
  2124 
  2125         pgp_cert_t cert = NULL;
  2126 
  2127         pgp_fingerprint_t issuer_fpr = pgp_signature_issuer_fingerprint(sig);
  2128         if (issuer_fpr) {
  2129             char *issuer_fpr_hex = pgp_fingerprint_to_hex(issuer_fpr);
  2130             T("Importing a signature issued by %s", issuer_fpr_hex);
  2131 
  2132             status = cert_find_by_fpr_hex(session, issuer_fpr_hex,
  2133                                          false, &cert, NULL);
  2134             if (status && status != PEP_KEY_NOT_FOUND)
  2135                 DUMP_ERR(NULL, status, "Looking up %s", issuer_fpr_hex);
  2136 
  2137             free(issuer_fpr_hex);
  2138             pgp_fingerprint_free(issuer_fpr);
  2139         }
  2140 
  2141         if (! cert) {
  2142             pgp_keyid_t issuer = pgp_signature_issuer(sig);
  2143             if (issuer) {
  2144                 char *issuer_hex = pgp_keyid_to_hex(issuer);
  2145                 T("Importing a signature issued by %s", issuer_hex);
  2146 
  2147                 status = cert_find_by_keyid_hex(session, issuer_hex,
  2148                                                false, &cert, NULL);
  2149                 if (status && status != PEP_KEY_NOT_FOUND)
  2150                     DUMP_ERR(NULL, status, "Looking up %s", issuer_hex);
  2151 
  2152                 free(issuer_hex);
  2153                 pgp_keyid_free(issuer);
  2154             }
  2155         }
  2156 
  2157         // We need a packet.  sig is only a reference, so we just need
  2158         // to free it.
  2159         pgp_signature_free(sig);
  2160 
  2161         if (cert) {
  2162             T("Merging packet: %s", pgp_packet_debug(packet));
  2163 
  2164             cert = pgp_cert_merge_packets (&err, cert, &packet, 1);
  2165             if (! cert)
  2166                 ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Merging signature");
  2167 
  2168             status = cert_save(session, cert, NULL);
  2169             if (status)
  2170                 ERROR_OUT(NULL, status, "saving merged CERT");
  2171             status = PEP_KEY_IMPORTED;
  2172         }
  2173         break;
  2174     }
  2175     case PGP_TAG_PUBLIC_KEY:
  2176     case PGP_TAG_SECRET_KEY: {
  2177         parser = pgp_cert_parser_from_packet_parser(ppr);
  2178         pgp_cert_t cert;
  2179         int count = 0;
  2180         err = NULL;
  2181         while ((cert = pgp_cert_parser_next(&err, parser))) {
  2182             count ++;
  2183 
  2184             T("#%d. CERT for %s, %s",
  2185               count, pgp_cert_primary_user_id(cert),
  2186               pgp_fingerprint_to_hex(pgp_cert_fingerprint(cert)));
  2187 
  2188             // If private_idents is not NULL and there is any private key
  2189             // material, it will be saved.
  2190             status = cert_save(session, cert, private_idents);
  2191             if (status == PEP_STATUS_OK)
  2192                 status = PEP_KEY_IMPORTED;
  2193             else
  2194                 ERROR_OUT(NULL, status, "saving certificate");
  2195         }
  2196         if (err || count == 0)
  2197             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "parsing key data");
  2198         break;
  2199     }
  2200     default:
  2201         ERROR_OUT(NULL, PEP_NO_KEY_IMPORTED,
  2202                   "Can't import %s", pgp_tag_to_string(tag));
  2203         break;
  2204     }
  2205 
  2206     int int_result = sqlite3_exec(
  2207         session->key_db,
  2208         "PRAGMA wal_checkpoint(FULL);\n"
  2209         ,
  2210         NULL,
  2211         NULL,
  2212         NULL
  2213     );
  2214     if (int_result != SQLITE_OK)
  2215         status = PEP_UNKNOWN_DB_ERROR;
  2216 
  2217  out:
  2218     pgp_cert_parser_free(parser);
  2219 
  2220     T("-> %s", pEp_status_to_string(status));
  2221     return status;
  2222 }
  2223 
  2224 PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data,
  2225                               size_t size, identity_list **private_idents)
  2226 {
  2227     unsigned int keycount = count_keydata_parts(key_data, size);
  2228     if (keycount < 2)
  2229         return(_pgp_import_keydata(session, key_data, size, private_idents));
  2230 
  2231     const char* pgp_begin = "-----BEGIN PGP";
  2232     size_t prefix_len = strlen(pgp_begin);
  2233         
  2234     unsigned int i;
  2235     const char* curr_begin;
  2236     size_t curr_size;
  2237     
  2238     identity_list* collected_idents = NULL;        
  2239     
  2240     PEP_STATUS retval = PEP_KEY_IMPORTED;
  2241     
  2242     for (i = 0, curr_begin = key_data; i < keycount; i++) {
  2243         const char* next_begin = NULL;
  2244 
  2245         // This is assured to be OK because the count function above 
  2246         // made sure that THIS round contains at least prefix_len chars
  2247         // We used strnstr to count, so we know that strstr will be ok.
  2248         if (strlen(curr_begin + prefix_len) > prefix_len)
  2249             next_begin = strstr(curr_begin + prefix_len, pgp_begin);
  2250 
  2251         if (next_begin)
  2252             curr_size = next_begin - curr_begin;
  2253         else
  2254             curr_size = (key_data + size) - curr_begin;
  2255         
  2256         PEP_STATUS curr_status = _pgp_import_keydata(session, curr_begin, curr_size, private_idents);
  2257         if (private_idents && *private_idents) {
  2258             if (!collected_idents)
  2259                 collected_idents = *private_idents;
  2260             else 
  2261                 identity_list_join(collected_idents, *private_idents);
  2262             *private_idents = NULL;    
  2263         }
  2264         
  2265         if (curr_status != retval) {
  2266             switch (curr_status) {
  2267                 case PEP_NO_KEY_IMPORTED:
  2268                 case PEP_KEY_NOT_FOUND:
  2269                 case PEP_UNKNOWN_ERROR:
  2270                     switch (retval) {
  2271                         case PEP_KEY_IMPORTED:
  2272                             retval = PEP_SOME_KEYS_IMPORTED;
  2273                             break;
  2274                         case PEP_UNKNOWN_ERROR:
  2275                             retval = curr_status;
  2276                             break;
  2277                         default:
  2278                             break;
  2279                     }
  2280                     break;
  2281                 case PEP_KEY_IMPORTED:
  2282                     retval = PEP_SOME_KEYS_IMPORTED;
  2283                 default:
  2284                     break;
  2285             }        
  2286         }        
  2287         curr_begin = next_begin;     
  2288     }
  2289     
  2290     if (private_idents)
  2291         *private_idents = collected_idents;
  2292     
  2293     return retval;    
  2294 }
  2295 
  2296 PEP_STATUS pgp_export_keydata(
  2297         PEP_SESSION session, const char *fpr, char **key_data, size_t *size,
  2298         bool secret)
  2299 {
  2300     PEP_STATUS status = PEP_STATUS_OK;
  2301     pgp_error_t err = NULL;
  2302     pgp_cert_t cert = NULL;
  2303     pgp_writer_t armor_writer = NULL;
  2304     pgp_writer_t memory_writer = NULL;
  2305 
  2306     assert(session);
  2307     assert(fpr);
  2308     assert(key_data);
  2309     assert(*key_data == NULL);
  2310     assert(size);
  2311 
  2312     *size = 0;
  2313 
  2314     T("(%s, %s)", fpr, secret ? "secret" : "public");
  2315 
  2316     // If the caller asks for a secret key and we only have a
  2317     // public key, then we return an error.
  2318     status = cert_find_by_fpr_hex(session, fpr, secret, &cert, NULL);
  2319     ERROR_OUT(NULL, status, "Looking up TSK for %s", fpr);
  2320 
  2321     memory_writer = pgp_writer_alloc((void **) key_data, size);
  2322     if (! memory_writer)
  2323         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "creating memory writer");
  2324     armor_writer = pgp_armor_writer_new(&err, memory_writer,
  2325                                         PGP_ARMOR_KIND_PUBLICKEY, NULL, 0);
  2326     if (! armor_writer) {
  2327         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "creating armored writer");
  2328     }
  2329 
  2330     if (secret) {
  2331         pgp_tsk_t tsk = pgp_cert_as_tsk(cert);
  2332         if (pgp_tsk_serialize(&err, tsk, armor_writer))
  2333             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "serializing TSK");
  2334         pgp_tsk_free(tsk);
  2335     } else {
  2336         if (pgp_cert_serialize(&err, cert, armor_writer))
  2337             ERROR_OUT(err, PEP_UNKNOWN_ERROR, "serializing certificate");
  2338     }
  2339 
  2340  out:
  2341     if (armor_writer)
  2342         pgp_writer_free(armor_writer);
  2343 
  2344     if (memory_writer) {
  2345         if (status == PEP_STATUS_OK) {
  2346             // Add a trailing NUL.
  2347             pgp_writer_write(NULL, memory_writer, (const uint8_t *) "", 1);
  2348         }
  2349 
  2350         pgp_writer_free(memory_writer);
  2351     }
  2352 
  2353     if (cert)
  2354         pgp_cert_free(cert);
  2355 
  2356     (*size)--;  // Sequoia is delivering the 0 byte at the end with size, but
  2357                 // pEp is expecting it without
  2358     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  2359     return status;
  2360 }
  2361 
  2362 static char *_undot_address(const char* address) {
  2363     if (!address)
  2364         return NULL;
  2365 
  2366     int addr_len = strlen(address);
  2367     const char* at = memchr(address, '@', addr_len);
  2368 
  2369     if (!at)
  2370         at = address + addr_len;
  2371 
  2372     char* retval = calloc(1, addr_len + 1);
  2373 
  2374     const char* addr_curr = address;
  2375     char* retval_curr = retval;
  2376 
  2377     while (addr_curr < at) {
  2378         if (*addr_curr == '.') {
  2379             addr_curr++;
  2380             continue;
  2381         }
  2382         *retval_curr = *addr_curr;
  2383         retval_curr++;
  2384         addr_curr++;
  2385     }
  2386     if (*addr_curr == '@')
  2387         strcat(retval_curr, addr_curr);
  2388 
  2389     return retval;
  2390 }
  2391 
  2392 static stringpair_list_t *add_key(PEP_SESSION session,
  2393                                   stringpair_list_t *keyinfo_list,
  2394                                   stringlist_t* keylist,
  2395                                   pgp_cert_t cert, pgp_fingerprint_t fpr) {
  2396     bool revoked = false;
  2397     // Don't add revoked keys to the keyinfo_list.
  2398     if (keyinfo_list) {
  2399         pgp_revocation_status_t rs = pgp_cert_revoked(cert, 0);
  2400         pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
  2401         pgp_revocation_status_free(rs);
  2402         if (rsv == PGP_REVOCATION_STATUS_REVOKED)
  2403             revoked = true;
  2404     }
  2405 
  2406     if (revoked && ! keylist)
  2407         return keyinfo_list;
  2408 
  2409     int dealloc_fpr = 0;
  2410     if (!fpr) {
  2411         dealloc_fpr = 1;
  2412         fpr = pgp_cert_fingerprint(cert);
  2413     }
  2414     char *fpr_str = pgp_fingerprint_to_hex(fpr);
  2415 
  2416     if (!revoked && keyinfo_list) {
  2417         char *user_id = pgp_cert_primary_user_id(cert);
  2418         if (user_id)
  2419             keyinfo_list = stringpair_list_add(keyinfo_list,
  2420                                                new_stringpair(fpr_str, user_id));
  2421         free(user_id);
  2422     }
  2423 
  2424     if (keylist)
  2425         keylist = stringlist_add(keylist, fpr_str);
  2426 
  2427     free(fpr_str);
  2428     if (dealloc_fpr)
  2429         pgp_fingerprint_free(fpr);
  2430 
  2431     return keyinfo_list;
  2432 }
  2433 
  2434 static PEP_STATUS list_keys(PEP_SESSION session,
  2435                             const char* pattern, int private_only,
  2436                             stringpair_list_t** keyinfo_list, stringlist_t** keylist)
  2437 {
  2438     PEP_STATUS status = PEP_STATUS_OK;
  2439     pgp_cert_t cert = NULL;
  2440     pgp_fingerprint_t fpr = NULL;
  2441 
  2442     T("('%s', private: %d)", pattern, private_only);
  2443 
  2444     stringpair_list_t* _keyinfo_list = NULL;
  2445     if (keyinfo_list) {
  2446         _keyinfo_list = new_stringpair_list(NULL);
  2447         if (!_keyinfo_list)
  2448             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_stringpair_list");
  2449     }
  2450     stringlist_t* _keylist = NULL;
  2451     if (keylist) {
  2452         _keylist = new_stringlist(NULL);
  2453         if (!_keylist)
  2454             ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_string_list");
  2455     }
  2456 
  2457     // Trim any leading space.  This also makes it easier to recognize
  2458     // a string that is only whitespace.
  2459     while (*pattern == ' ')
  2460         pattern ++;
  2461 
  2462     if (strchr(pattern, '@')) {
  2463         // Looks like a mailbox.
  2464         pgp_cert_t *certs = NULL;
  2465         int count = 0;
  2466         status = cert_find_by_email(session, pattern, private_only, &certs, &count);
  2467         ERROR_OUT(NULL, status, "Looking up '%s'", pattern);
  2468         for (int i = 0; i < count; i ++) {
  2469             add_key(session, _keyinfo_list, _keylist, certs[i], NULL);
  2470             pgp_cert_free(certs[i]);
  2471         }
  2472         free(certs);
  2473 
  2474         if (count == 0) {
  2475             // If match failed, check to see if we've got a dotted
  2476             // address in the pattern.  If so, try again without dots.
  2477             const char* dotpos = strstr(pattern, ".");
  2478             const char* atpos = strstr(pattern, "@");
  2479             if (dotpos && atpos && (dotpos < atpos)) {
  2480                 char* undotted = _undot_address(pattern);
  2481                 if (undotted) {
  2482                     PEP_STATUS status = list_keys(session, undotted, private_only,
  2483                                                   keyinfo_list, keylist);
  2484                     free(undotted);
  2485                     return status;
  2486                 }
  2487             }
  2488         }
  2489     } else if (// Only hex characters and spaces
  2490                pattern[strspn(pattern, "0123456789aAbBcCdDeEfF ")] == 0
  2491                // And a fair amount of them.
  2492                && strlen(pattern) >= 16) {
  2493         // Fingerprint.  Note: the pep engine never looks keys up by
  2494         // keyid, so we don't handle them.
  2495         fpr = pgp_fingerprint_from_hex(pattern);
  2496         status = cert_find_by_fpr(session, fpr, false, &cert, NULL);
  2497         ERROR_OUT(NULL, status, "Looking up key");
  2498         add_key(session, _keyinfo_list, _keylist, cert, fpr);
  2499     } else if (pattern[0] == 0) {
  2500         // Empty string.
  2501 
  2502         pgp_cert_t *certs = NULL;
  2503         int count = 0;
  2504         status = cert_all(session, private_only, &certs, &count);
  2505         ERROR_OUT(NULL, status, "Looking up '%s'", pattern);
  2506         for (int i = 0; i < count; i ++) {
  2507             add_key(session, _keyinfo_list, _keylist, certs[i], NULL);
  2508             pgp_cert_free(certs[i]);
  2509         }
  2510         free(certs);
  2511     } else {
  2512         T("unsupported pattern '%s'", pattern);
  2513     }
  2514 
  2515  out:
  2516     pgp_cert_free(cert);
  2517     pgp_fingerprint_free(fpr);
  2518 
  2519     if (status == PEP_KEY_NOT_FOUND)
  2520         status = PEP_STATUS_OK;
  2521 
  2522     if (status != PEP_STATUS_OK || (_keyinfo_list && !_keyinfo_list->value)) {
  2523         free_stringpair_list(_keyinfo_list);
  2524         _keyinfo_list = NULL;
  2525     }
  2526     if (keyinfo_list)
  2527         *keyinfo_list = _keyinfo_list;
  2528 
  2529     if (status != PEP_STATUS_OK || (_keylist && !_keylist->value)) {
  2530         free_stringlist(_keylist);
  2531         _keylist = NULL;
  2532     }
  2533     if (keylist)
  2534         *keylist = _keylist;
  2535 
  2536     int len = -1;
  2537     if (keylist)
  2538         len = stringlist_length(*keylist);
  2539     else if (keyinfo_list)
  2540         len = stringpair_list_length(*keyinfo_list);
  2541     T("(%s) -> %s (%d keys)", pattern, pEp_status_to_string(status), len);
  2542     return status;
  2543 }
  2544 
  2545 // pattern could be empty, an fpr, or a mailbox.
  2546 //
  2547 // keyinfo_list is a list of <fpr, openpgp userid> tuples for the
  2548 // matching keys.
  2549 //
  2550 // This function filters out revoked key, but not expired keys.
  2551 PEP_STATUS pgp_list_keyinfo(PEP_SESSION session,
  2552                             const char* pattern,
  2553                             stringpair_list_t** keyinfo_list)
  2554 {
  2555     return list_keys(session, pattern, false, keyinfo_list, NULL);
  2556 }
  2557 
  2558 PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
  2559 {
  2560     assert(!"pgp_recv_key not implemented");
  2561     return PEP_UNKNOWN_ERROR;
  2562 }
  2563 
  2564 // Unlike pgp_list_keyinfo, this function returns revoked keys.
  2565 PEP_STATUS pgp_find_keys(
  2566     PEP_SESSION session, const char *pattern, stringlist_t **keylist)
  2567 {
  2568     return list_keys(session, pattern, false, NULL, keylist);
  2569 }
  2570 
  2571 // Unlike pgp_list_keyinfo, this function returns revoked keys.
  2572 PEP_STATUS pgp_find_private_keys(
  2573     PEP_SESSION session, const char *pattern, stringlist_t **keylist)
  2574 {
  2575     return list_keys(session, pattern, true, NULL, keylist);
  2576 }
  2577 
  2578 PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
  2579 {
  2580     assert(!"pgp_send_key not implemented");
  2581     return PEP_UNKNOWN_ERROR;
  2582 }
  2583 
  2584 
  2585 PEP_STATUS pgp_renew_key(
  2586     PEP_SESSION session, const char *fpr, const timestamp *ts)
  2587 {
  2588     PEP_STATUS status = PEP_STATUS_OK;
  2589     pgp_error_t err = NULL;
  2590     pgp_cert_t cert = NULL;
  2591     pgp_cert_key_iter_t iter = NULL;
  2592     pgp_key_pair_t keypair = NULL;
  2593     pgp_signer_t signer = NULL;
  2594     time_t t = mktime((struct tm *) ts);
  2595 
  2596     T("(%s)", fpr);
  2597 
  2598     status = cert_find_by_fpr_hex(session, fpr, true, &cert, NULL);
  2599     ERROR_OUT(NULL, status, "Looking up '%s'", fpr);
  2600 
  2601     uint32_t creation_time = pgp_key_creation_time(pgp_cert_primary_key(cert));
  2602     if (creation_time > t)
  2603         // The creation time is after the expiration time!
  2604         ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
  2605                   "creation time can't be after expiration time");
  2606 
  2607     uint32_t delta = t - creation_time;
  2608 
  2609 
  2610     iter = pgp_cert_key_iter_valid(cert);
  2611     pgp_cert_key_iter_for_certification (iter);
  2612     pgp_cert_key_iter_unencrypted_secret (iter);
  2613 
  2614     // If there are multiple certification capable subkeys, we just
  2615     // take the first one, whichever one that happens to be.
  2616     pgp_key_t key = pgp_cert_key_iter_next (iter, NULL, NULL);
  2617     if (! key)
  2618         ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  2619                    "%s has no usable certification capable key", fpr);
  2620 
  2621     keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  2622     if (! keypair)
  2623         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  2624 
  2625     signer = pgp_key_pair_as_signer (keypair);
  2626     if (! signer)
  2627         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  2628 
  2629     cert = pgp_cert_set_expiry(&err, cert, signer, delta);
  2630     if (! cert)
  2631         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
  2632 
  2633     status = cert_save(session, cert, NULL);
  2634     cert = NULL;
  2635     ERROR_OUT(NULL, status, "Saving %s", fpr);
  2636 
  2637  out:
  2638     pgp_signer_free (signer);
  2639     // XXX: pgp_key_pair_as_signer is only supposed to reference
  2640     // signing_keypair, but it consumes it.  If this is fixed, this
  2641     // will become a leak.
  2642     //
  2643     pgp_key_pair_free (keypair);
  2644     pgp_cert_key_iter_free (iter);
  2645     pgp_cert_free(cert);
  2646 
  2647     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  2648     return status;
  2649 }
  2650 
  2651 PEP_STATUS pgp_revoke_key(
  2652     PEP_SESSION session, const char *fpr, const char *reason)
  2653 {
  2654     PEP_STATUS status = PEP_STATUS_OK;
  2655     pgp_error_t err = NULL;
  2656     pgp_cert_t cert = NULL;
  2657     pgp_cert_key_iter_t iter = NULL;
  2658     pgp_key_pair_t keypair = NULL;
  2659     pgp_signer_t signer = NULL;
  2660 
  2661     T("(%s)", fpr);
  2662 
  2663     status = cert_find_by_fpr_hex(session, fpr, true, &cert, NULL);
  2664     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  2665 
  2666     iter = pgp_cert_key_iter_valid(cert);
  2667     pgp_cert_key_iter_for_certification (iter);
  2668     pgp_cert_key_iter_unencrypted_secret (iter);
  2669 
  2670     // If there are multiple certification capable subkeys, we just
  2671     // take the first one, whichever one that happens to be.
  2672     pgp_key_t key = pgp_cert_key_iter_next (iter, NULL, NULL);
  2673     if (! key)
  2674         ERROR_OUT (err, PEP_UNKNOWN_ERROR,
  2675                    "%s has no usable certification capable key", fpr);
  2676 
  2677     keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
  2678     if (! keypair)
  2679         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
  2680 
  2681     signer = pgp_key_pair_as_signer (keypair);
  2682     if (! signer)
  2683         ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
  2684 
  2685     cert = pgp_cert_revoke_in_place(&err, cert, signer,
  2686                                   PGP_REASON_FOR_REVOCATION_UNSPECIFIED,
  2687                                   reason);
  2688     if (! cert)
  2689         ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
  2690 
  2691     assert(pgp_revocation_status_variant(pgp_cert_revoked(cert, 0))
  2692            == PGP_REVOCATION_STATUS_REVOKED);
  2693 
  2694     status = cert_save(session, cert, NULL);
  2695     cert = NULL;
  2696     ERROR_OUT(NULL, status, "Saving %s", fpr);
  2697 
  2698  out:
  2699     pgp_signer_free (signer);
  2700     pgp_key_pair_free (keypair);
  2701     pgp_cert_key_iter_free (iter);
  2702     pgp_cert_free(cert);
  2703 
  2704     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  2705     return status;
  2706 }
  2707 
  2708 static void _pgp_key_expired(pgp_cert_t cert, const time_t when, bool* expired)
  2709 {
  2710     // Is the certificate live?
  2711     *expired = !pgp_cert_alive(cert, when);
  2712 
  2713 #ifdef TRACING
  2714     {
  2715         char buffer[26];
  2716         time_t now = time(NULL);
  2717 
  2718         if (when == now || when == now - 1) {
  2719             sprintf(buffer, "now");
  2720         } else {
  2721             struct tm tm;
  2722             gmtime_r(&when, &tm);
  2723             strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm);
  2724         }
  2725 
  2726         T("certificate is %slive as of %s", *expired ? "not " : "", buffer);
  2727     }
  2728 #endif
  2729     if (*expired)
  2730         goto out;
  2731 
  2732     // Are there at least one certification subkey, one signing subkey
  2733     // and one encryption subkey that are live?
  2734     //    int can_certify = 0, can_encrypt = 0, can_sign = 0;
  2735     int can_encrypt = 0, can_sign = 0;
  2736 
  2737     pgp_cert_key_iter_t key_iter = pgp_cert_key_iter_valid(cert);
  2738     pgp_key_t key;
  2739     pgp_signature_t sig;
  2740     pgp_revocation_status_t rev;
  2741     while ((key = pgp_cert_key_iter_next(key_iter, &sig, &rev))) {
  2742         if (! sig)
  2743             continue;
  2744 
  2745         if (pgp_signature_for_transport_encryption(sig)
  2746             || pgp_signature_for_storage_encryption(sig))
  2747             can_encrypt = 1;
  2748         if (pgp_signature_for_signing(sig))
  2749             can_sign = 1;
  2750         // if (pgp_signature_for_certification(sig))
  2751         //     can_certify = 1;
  2752 
  2753 //        if (can_encrypt && can_sign && can_certify)
  2754         if (can_encrypt && can_sign)
  2755             break;
  2756     }
  2757     pgp_cert_key_iter_free(key_iter);
  2758 
  2759 //    *expired = !(can_encrypt && can_sign && can_certify);
  2760     *expired = !(can_encrypt && can_sign);
  2761 
  2762     T("Key can%s encrypt, can%s sign => %s expired",
  2763       can_encrypt ? "" : "not",
  2764       can_sign ? "" : "not",
  2765       *expired ? "" : "not");
  2766 
  2767 out:
  2768     // Er, this might be problematic in terms of internal vs. external in log. FIXME?
  2769     T(" -> expired: %d", *expired);
  2770     return;
  2771 }
  2772 
  2773 PEP_STATUS pgp_key_expired(PEP_SESSION session, const char *fpr,
  2774                            const time_t when, bool *expired)
  2775 {
  2776     PEP_STATUS status = PEP_STATUS_OK;
  2777     pgp_cert_t cert = NULL;
  2778     T("(%s)", fpr);
  2779 
  2780     assert(session);
  2781     assert(fpr);
  2782     assert(expired);
  2783 
  2784     *expired = false;
  2785 
  2786     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  2787     status = cert_find_by_fpr(session, pgp_fpr, false, &cert, NULL);
  2788     pgp_fingerprint_free(pgp_fpr);
  2789     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  2790 
  2791     _pgp_key_expired(cert, when, expired);
  2792  out:
  2793     pgp_cert_free(cert);
  2794     T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
  2795     return status;
  2796 }
  2797 
  2798 PEP_STATUS pgp_key_revoked(PEP_SESSION session, const char *fpr, bool *revoked)
  2799 {
  2800     PEP_STATUS status = PEP_STATUS_OK;
  2801     pgp_cert_t cert;
  2802 
  2803     T("(%s)", fpr);
  2804 
  2805     assert(session);
  2806     assert(fpr);
  2807     assert(revoked);
  2808 
  2809     *revoked = false;
  2810 
  2811     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  2812     status = cert_find_by_fpr(session, pgp_fpr, false, &cert, NULL);
  2813     pgp_fingerprint_free(pgp_fpr);
  2814     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  2815 
  2816     pgp_revocation_status_t rs = pgp_cert_revoked(cert, 0);
  2817     *revoked = pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED;
  2818     pgp_revocation_status_free (rs);
  2819     pgp_cert_free(cert);
  2820 
  2821  out:
  2822     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  2823     return status;
  2824 }
  2825 
  2826 PEP_STATUS pgp_get_key_rating(
  2827     PEP_SESSION session, const char *fpr, PEP_comm_type *comm_type)
  2828 {
  2829     PEP_STATUS status = PEP_STATUS_OK;
  2830     pgp_cert_t cert = NULL;
  2831 
  2832     assert(session);
  2833     assert(fpr);
  2834     assert(comm_type);
  2835 
  2836     *comm_type = PEP_ct_unknown;
  2837 
  2838     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  2839     status = cert_find_by_fpr(session, pgp_fpr, false, &cert, NULL);
  2840     pgp_fingerprint_free(pgp_fpr);
  2841     ERROR_OUT(NULL, status, "Looking up key: %s", fpr);
  2842 
  2843     *comm_type = PEP_ct_OpenPGP_unconfirmed;
  2844 
  2845     bool expired = false;
  2846     
  2847     // MUST guarantee the same behaviour.
  2848     _pgp_key_expired(cert, time(NULL), &expired);
  2849     
  2850     if (expired) {
  2851         *comm_type = PEP_ct_key_expired;
  2852         goto out;        
  2853     }
  2854     
  2855     // if (pgp_cert_expired(cert)) {
  2856     //     *comm_type = PEP_ct_key_expired;
  2857     //     goto out;
  2858     // }
  2859 
  2860     pgp_revocation_status_t rs = pgp_cert_revoked(cert, 0);
  2861     pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
  2862     pgp_revocation_status_free(rs);
  2863     if (rsv == PGP_REVOCATION_STATUS_REVOKED) {
  2864         *comm_type = PEP_ct_key_revoked;
  2865         goto out;
  2866     }
  2867 
  2868     PEP_comm_type best_enc = PEP_ct_no_encryption, best_sign = PEP_ct_no_encryption;
  2869     pgp_cert_key_iter_t key_iter = pgp_cert_key_iter_valid(cert);
  2870     pgp_key_t key;
  2871     pgp_signature_t sig;
  2872     pgp_revocation_status_t rev;
  2873     while ((key = pgp_cert_key_iter_next(key_iter, &sig, &rev))) {
  2874         if (! sig)
  2875             continue;
  2876 
  2877         PEP_comm_type curr = PEP_ct_no_encryption;
  2878 
  2879         int can_enc = pgp_signature_for_transport_encryption(sig)
  2880             || pgp_signature_for_storage_encryption(sig);
  2881         int can_sign = pgp_signature_for_signing(sig);
  2882 
  2883         pgp_public_key_algo_t pk_algo = pgp_key_public_key_algo(key);
  2884         if (pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_ENCRYPT_SIGN
  2885             || pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_ENCRYPT
  2886             || pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_SIGN) {
  2887             int bits = pgp_key_public_key_bits(key);
  2888             if (bits < 1024)
  2889                 curr = PEP_ct_key_too_short;
  2890             else if (bits == 1024)
  2891                 curr = PEP_ct_OpenPGP_weak_unconfirmed;
  2892             else
  2893                 curr = PEP_ct_OpenPGP_unconfirmed;
  2894         } else {
  2895             curr = PEP_ct_OpenPGP_unconfirmed;
  2896         }
  2897 
  2898         if (can_enc)
  2899             best_enc = _MAX(best_enc, curr);
  2900 
  2901         if (can_sign)
  2902             best_sign = _MAX(best_sign, curr);
  2903     }
  2904     pgp_cert_key_iter_free(key_iter);
  2905 
  2906     if (best_enc == PEP_ct_no_encryption || best_sign == PEP_ct_no_encryption) {
  2907         *comm_type = PEP_ct_key_b0rken;
  2908         goto out;
  2909     } else {
  2910         *comm_type = _MIN(best_enc, best_sign);
  2911     }
  2912 
  2913  out:
  2914     pgp_cert_free(cert);
  2915 
  2916     T("(%s) -> %s", fpr, pEp_comm_type_to_string(*comm_type));
  2917     return status;
  2918 }
  2919 
  2920 
  2921 PEP_STATUS pgp_key_created(PEP_SESSION session, const char *fpr, time_t *created)
  2922 {
  2923     PEP_STATUS status = PEP_STATUS_OK;
  2924     pgp_cert_t cert = NULL;
  2925     T("(%s)", fpr);
  2926 
  2927     *created = 0;
  2928 
  2929     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  2930     status = cert_find_by_fpr(session, pgp_fpr, false, &cert, NULL);
  2931     pgp_fingerprint_free(pgp_fpr);
  2932     ERROR_OUT(NULL, status, "Looking up %s", fpr);
  2933 
  2934     pgp_key_t k = pgp_cert_primary_key(cert);
  2935     *created = pgp_key_creation_time(k);
  2936     pgp_cert_free(cert);
  2937 
  2938  out:
  2939     T("(%s) -> %s", fpr, pEp_status_to_string(status));
  2940     return status;
  2941 }
  2942 
  2943 PEP_STATUS pgp_binary(const char **path)
  2944 {
  2945     *path = NULL;
  2946     return PEP_STATUS_OK;
  2947 }
  2948 
  2949 PEP_STATUS pgp_contains_priv_key(PEP_SESSION session, const char *fpr,
  2950                                  bool *has_private)
  2951 {
  2952     T("(%s)", fpr);
  2953     pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  2954     PEP_STATUS status = cert_find_by_fpr(session, pgp_fpr, true, NULL, NULL);
  2955     pgp_fingerprint_free(pgp_fpr);
  2956     if (status == PEP_STATUS_OK) {
  2957         *has_private = 1;
  2958     } else if (status == PEP_KEY_NOT_FOUND) {
  2959         *has_private = 0;
  2960         status = PEP_STATUS_OK;
  2961     }
  2962     T("(%s) -> %s, %s",
  2963       fpr, *has_private ? "priv" : "pub", pEp_status_to_string(status));
  2964     return status;
  2965 }