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