Merge with sync sequoia_windows
authorThomas
Thu, 16 May 2019 08:14:02 +0200
branchsequoia_windows
changeset 37011f717dccd337
parent 3687 8e04a1fb8bf7
parent 3700 55e7a6770c47
child 3704 ce00fd902b41
Merge with sync
src/pgp_sequoia.c
     1.1 --- a/src/cryptotech.c	Wed May 15 14:20:48 2019 +0200
     1.2 +++ b/src/cryptotech.c	Thu May 16 08:14:02 2019 +0200
     1.3 @@ -58,6 +58,7 @@
     1.4          cryptotech[PEP_crypt_OpenPGP].key_created = pgp_key_created;
     1.5          cryptotech[PEP_crypt_OpenPGP].contains_priv_key = pgp_contains_priv_key;
     1.6          cryptotech[PEP_crypt_OpenPGP].find_private_keys = pgp_find_private_keys;
     1.7 +        cryptotech[PEP_crypt_OpenPGP].config_cipher_suite = pgp_config_cipher_suite;
     1.8  #ifdef PGP_BINARY_PATH
     1.9          cryptotech[PEP_crypt_OpenPGP].binary_path = PGP_BINARY_PATH;
    1.10  #endif
     2.1 --- a/src/cryptotech.h	Wed May 15 14:20:48 2019 +0200
     2.2 +++ b/src/cryptotech.h	Thu May 16 08:14:02 2019 +0200
     2.3 @@ -95,6 +95,9 @@
     2.4      PEP_SESSION session, const char *pattern, stringlist_t **keylist
     2.5  );
     2.6  
     2.7 +typedef PEP_STATUS (*config_cipher_suite_t)(PEP_SESSION session,
     2.8 +        PEP_CIPHER_SUITE suite);
     2.9 +
    2.10  typedef struct _PEP_cryptotech_t {
    2.11      uint8_t id;
    2.12      // the following are default values; comm_type may vary with key length or b0rken crypto
    2.13 @@ -121,6 +124,7 @@
    2.14      binary_path_t binary_path;
    2.15      contains_priv_key_t contains_priv_key;
    2.16      find_private_keys_t find_private_keys;
    2.17 +    config_cipher_suite_t config_cipher_suite;
    2.18  } PEP_cryptotech_t;
    2.19  
    2.20  extern PEP_cryptotech_t cryptotech[PEP_crypt__count];
    2.21 @@ -129,3 +133,4 @@
    2.22  
    2.23  PEP_STATUS init_cryptotech(PEP_SESSION session, bool in_first);
    2.24  void release_cryptotech(PEP_SESSION session, bool out_last);
    2.25 +
     3.1 --- a/src/message_api.c	Wed May 15 14:20:48 2019 +0200
     3.2 +++ b/src/message_api.c	Thu May 16 08:14:02 2019 +0200
     3.3 @@ -975,7 +975,8 @@
     3.4          PEP_SESSION session,
     3.5          const message *src,
     3.6          stringlist_t *keys,
     3.7 -        message *dst
     3.8 +        message *dst,
     3.9 +        PEP_encrypt_flags_t flags
    3.10      )
    3.11  {
    3.12      char *ctext = NULL;
    3.13 @@ -986,6 +987,9 @@
    3.14      if (status)
    3.15          return status;
    3.16  
    3.17 +    dst->enc_format = PEP_enc_inline;
    3.18 +
    3.19 +    // shortmsg is being copied
    3.20      if (src->shortmsg) {
    3.21          dst->shortmsg = strdup(src->shortmsg);
    3.22          assert(dst->shortmsg);
    3.23 @@ -993,6 +997,14 @@
    3.24              return PEP_OUT_OF_MEMORY;
    3.25      }
    3.26  
    3.27 +    // id is staying the same
    3.28 +    if (src->id) {
    3.29 +        dst->id = strdup(src->id);
    3.30 +        assert(dst->id);
    3.31 +        if (!dst->id)
    3.32 +            return PEP_OUT_OF_MEMORY;
    3.33 +    }
    3.34 +
    3.35      char *_ctext = realloc(ctext, csize + 1);
    3.36      assert(_ctext);
    3.37      if (!_ctext)
    3.38 @@ -1000,6 +1012,15 @@
    3.39      _ctext[csize] = 0;
    3.40  
    3.41      dst->longmsg = _ctext;
    3.42 +
    3.43 +    // longmsg_formatted is unsupported
    3.44 +
    3.45 +    // attachments are going unencrypted
    3.46 +    bloblist_t *bl = bloblist_dup(src->attachments);
    3.47 +    if (!bl)
    3.48 +        return PEP_OUT_OF_MEMORY;
    3.49 +    dst->attachments = bl;
    3.50 +
    3.51      return PEP_STATUS_OK;
    3.52  }
    3.53  
    3.54 @@ -1917,7 +1938,7 @@
    3.55      }
    3.56      else {
    3.57          // FIXME - we need to deal with transport types (via flag)
    3.58 -        if ((!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
    3.59 +        if ((enc_format != PEP_enc_inline) && (!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
    3.60              message_wrap_type wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
    3.61              _src = wrap_message_as_attachment(NULL, src, wrap_type, false);
    3.62              if (!_src)
    3.63 @@ -1925,7 +1946,7 @@
    3.64          }
    3.65          else {
    3.66              // hide subject
    3.67 -            if (!session->unencrypted_subject) {
    3.68 +            if (enc_format != PEP_enc_inline && !session->unencrypted_subject) {
    3.69                  status = replace_subject(_src);
    3.70                  if (status == PEP_OUT_OF_MEMORY)
    3.71                      goto enomem;
    3.72 @@ -1947,7 +1968,7 @@
    3.73                  break;
    3.74  
    3.75              case PEP_enc_inline:
    3.76 -                status = encrypt_PGP_inline(session, _src, keys, msg);
    3.77 +                status = encrypt_PGP_inline(session, _src, keys, msg, flags);
    3.78                  break;
    3.79  
    3.80              default:
    3.81 @@ -2282,7 +2303,7 @@
    3.82              break;
    3.83  
    3.84          case PEP_enc_inline:
    3.85 -            status = encrypt_PGP_inline(session, _src, keys, msg);
    3.86 +            status = encrypt_PGP_inline(session, _src, keys, msg, flags);
    3.87              break;
    3.88  
    3.89          default:
     4.1 --- a/src/pEpEngine.c	Wed May 15 14:20:48 2019 +0200
     4.2 +++ b/src/pEpEngine.c	Thu May 16 08:14:02 2019 +0200
     4.3 @@ -1985,19 +1985,22 @@
     4.4  DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
     4.5  {
     4.6      assert(session);
     4.7 -    session->passive_mode = enable;
     4.8 +    if (session)
     4.9 +        session->passive_mode = enable;
    4.10  }
    4.11  
    4.12  DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
    4.13  {
    4.14      assert(session);
    4.15 -    session->unencrypted_subject = enable;
    4.16 +    if (session)
    4.17 +        session->unencrypted_subject = enable;
    4.18  }
    4.19  
    4.20  DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
    4.21  {
    4.22      assert(session);
    4.23 -    session->service_log = enable;
    4.24 +    if (session)
    4.25 +        session->service_log = enable;
    4.26  }
    4.27  
    4.28  DYNAMIC_API PEP_STATUS log_event(
    4.29 @@ -4399,6 +4402,16 @@
    4.30              revoked);
    4.31  }
    4.32  
    4.33 +DYNAMIC_API PEP_STATUS config_cipher_suite(PEP_SESSION session,
    4.34 +        PEP_CIPHER_SUITE suite)
    4.35 +{
    4.36 +    assert(session);
    4.37 +    if (!session)
    4.38 +        return PEP_ILLEGAL_VALUE;
    4.39 +
    4.40 +    return session->cryptotech[PEP_crypt_OpenPGP].config_cipher_suite(session, suite);
    4.41 +}
    4.42 +
    4.43  static void _clean_log_value(char *text)
    4.44  {
    4.45      if (text) {
     5.1 --- a/src/pEpEngine.h	Wed May 15 14:20:48 2019 +0200
     5.2 +++ b/src/pEpEngine.h	Thu May 16 08:14:02 2019 +0200
     5.3 @@ -118,6 +118,7 @@
     5.4      PEP_COMMIT_FAILED                               = 0xff01,
     5.5      PEP_MESSAGE_CONSUME                             = 0xff02,
     5.6      PEP_MESSAGE_IGNORE                              = 0xff03,
     5.7 +    PEP_CANNOT_CONFIG                               = 0xff04,
     5.8  
     5.9      PEP_RECORD_NOT_FOUND                            = -6,
    5.10      PEP_CANNOT_CREATE_TEMP_FILE                     = -5,
    5.11 @@ -278,6 +279,35 @@
    5.12  DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable);
    5.13  
    5.14  
    5.15 +typedef enum {
    5.16 +    PEP_CIPHER_SUITE_DEFAULT = 0,
    5.17 +    PEP_CIPHER_SUITE_CV25519 = 1,
    5.18 +    PEP_CIPHER_SUITE_P256 = 2,
    5.19 +    PEP_CIPHER_SUITE_P384 = 3,
    5.20 +    PEP_CIPHER_SUITE_P521 = 4,
    5.21 +    PEP_CIPHER_SUITE_RSA2K = 5,
    5.22 +    PEP_CIPHER_SUITE_RSA3K = 6,
    5.23 +    PEP_CIPHER_SUITE_RSA4K = 7,
    5.24 +    PEP_CIPHER_SUITE_RSA8K = 8
    5.25 +} PEP_CIPHER_SUITE;
    5.26 +
    5.27 +// config_cipher_suite() - cipher suite being used when encrypting
    5.28 +//
    5.29 +//  parameters:
    5.30 +//      session (in)            session handle
    5.31 +//      cipher_suite (in)       cipher suite to use
    5.32 +//
    5.33 +//  return value:
    5.34 +//      PEP_STATUS_OK           cipher suite configured
    5.35 +//      PEP_CANNOT_CONFIG       configuration failed; falling back to default
    5.36 +//
    5.37 +//  caveat: the default ciphersuite for a crypt tech implementation is
    5.38 +//  implementation defined
    5.39 +
    5.40 +DYNAMIC_API PEP_STATUS config_cipher_suite(PEP_SESSION session,
    5.41 +        PEP_CIPHER_SUITE suite);
    5.42 +
    5.43 +
    5.44  // decrypt_and_verify() - decrypt and/or verify a message
    5.45  //
    5.46  //    parameters:
     6.1 --- a/src/pEp_internal.h	Wed May 15 14:20:48 2019 +0200
     6.2 +++ b/src/pEp_internal.h	Thu May 16 08:14:02 2019 +0200
     6.3 @@ -148,6 +148,8 @@
     6.4  #endif
     6.5  
     6.6      PEP_cryptotech_t *cryptotech;
     6.7 +    PEP_CIPHER_SUITE cipher_suite;
     6.8 +
     6.9      PEP_transport_t *transports;
    6.10  
    6.11      sqlite3 *db;
     7.1 --- a/src/pgp_gpg.c	Wed May 15 14:20:48 2019 +0200
     7.2 +++ b/src/pgp_gpg.c	Thu May 16 08:14:02 2019 +0200
     7.3 @@ -3116,3 +3116,17 @@
     7.4      }
     7.5      return status;
     7.6  }
     7.7 +
     7.8 +PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session,
     7.9 +        PEP_CIPHER_SUITE suite)
    7.10 +{
    7.11 +    // functionaliy unsupported; use gpg.conf
    7.12 +
    7.13 +    switch (suite) {
    7.14 +        case PEP_CIPHER_SUITE_DEFAULT:
    7.15 +            return PEP_STATUS_OK;
    7.16 +        default:
    7.17 +            return PEP_CANNOT_CONFIG;
    7.18 +    }
    7.19 +}
    7.20 +
     8.1 --- a/src/pgp_gpg.h	Wed May 15 14:20:48 2019 +0200
     8.2 +++ b/src/pgp_gpg.h	Thu May 16 08:14:02 2019 +0200
     8.3 @@ -28,7 +28,7 @@
     8.4  void pgp_release(PEP_SESSION session, bool out_last);
     8.5  
     8.6  
     8.7 -// pgp_decrypt_and_verify() - decrypt and verify cyphertext
     8.8 +// pgp_decrypt_and_verify() - decrypt and verify ciphertext
     8.9  //
    8.10  //  parameters:
    8.11  //      session (in)        session handle
    8.12 @@ -37,8 +37,8 @@
    8.13  //      dsigtext (in)       pointer to bytes with detached signature
    8.14  //                          or NULL if no detached signature
    8.15  //      dsigsize (in)       size of detached signature in bytes
    8.16 -//      ptext (out)         bytes with cyphertext
    8.17 -//      psize (out)         size of cyphertext in bytes
    8.18 +//      ptext (out)         bytes with ciphertext
    8.19 +//      psize (out)         size of ciphertext in bytes
    8.20  //      keylist (out)       list of keys being used; first is the key being
    8.21  //                          used for signing
    8.22  //	filename (out)	    PGP filename, when rendered (Optional, only necessary for some PGP implementations (e.g. Symantec),
    8.23 @@ -299,4 +299,7 @@
    8.24          const char* email
    8.25      );
    8.26  
    8.27 +PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session,
    8.28 +        PEP_CIPHER_SUITE suite);
    8.29 +
    8.30  #define PGP_BINARY_PATH pgp_binary
     9.1 --- a/src/pgp_sequoia.c	Wed May 15 14:20:48 2019 +0200
     9.2 +++ b/src/pgp_sequoia.c	Thu May 16 08:14:02 2019 +0200
     9.3 @@ -85,6 +85,52 @@
     9.4      }                                                               \
     9.5  } while(0)
     9.6  
     9.7 +DYNAMIC_API PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session,
     9.8 +        PEP_CIPHER_SUITE suite)
     9.9 +{
    9.10 +    switch (suite) {
    9.11 +        // supported cipher suites
    9.12 +        case PEP_CIPHER_SUITE_RSA2K:
    9.13 +        case PEP_CIPHER_SUITE_RSA3K:
    9.14 +        case PEP_CIPHER_SUITE_CV25519:
    9.15 +        case PEP_CIPHER_SUITE_P256:
    9.16 +        case PEP_CIPHER_SUITE_P384:
    9.17 +        case PEP_CIPHER_SUITE_P521:
    9.18 +            session->cipher_suite = suite;
    9.19 +            return PEP_STATUS_OK;
    9.20 +
    9.21 +        case PEP_CIPHER_SUITE_DEFAULT:
    9.22 +            session->cipher_suite = PEP_CIPHER_SUITE_RSA2K;
    9.23 +            return PEP_STATUS_OK;
    9.24 +
    9.25 +        // unsupported cipher suites
    9.26 +        default:
    9.27 +            session->cipher_suite = PEP_CIPHER_SUITE_RSA2K;
    9.28 +            return PEP_CANNOT_CONFIG;
    9.29 +    }
    9.30 +}
    9.31 +
    9.32 +static pgp_tpk_cipher_suite_t cipher_suite(PEP_CIPHER_SUITE suite)
    9.33 +{
    9.34 +    switch (suite) {
    9.35 +        // supported cipher suites
    9.36 +        case PEP_CIPHER_SUITE_RSA2K:
    9.37 +            return PGP_TPK_CIPHER_SUITE_RSA2K;
    9.38 +        case PEP_CIPHER_SUITE_RSA3K:
    9.39 +            return PGP_TPK_CIPHER_SUITE_RSA3K;
    9.40 +        case PEP_CIPHER_SUITE_CV25519:
    9.41 +            return PGP_TPK_CIPHER_SUITE_CV25519;
    9.42 +        case PEP_CIPHER_SUITE_P256:
    9.43 +            return PGP_TPK_CIPHER_SUITE_P256;
    9.44 +        case PEP_CIPHER_SUITE_P384:
    9.45 +            return PGP_TPK_CIPHER_SUITE_P384;
    9.46 +        case PEP_CIPHER_SUITE_P521:
    9.47 +            return PGP_TPK_CIPHER_SUITE_P521;
    9.48 +        default:
    9.49 +            return PGP_TPK_CIPHER_SUITE_RSA2K;
    9.50 +    }
    9.51 +}
    9.52 +
    9.53  int email_cmp(void *cookie, int a_len, const void *a, int b_len, const void *b)
    9.54  {
    9.55      pgp_packet_t a_userid = pgp_user_id_from_raw (a, a_len);
    9.56 @@ -884,7 +930,13 @@
    9.57      int good_but_revoked;
    9.58      int missing_keys;
    9.59      int bad_checksums;
    9.60 +
    9.61 +    // Whether we decrypted anything.
    9.62      int decrypted;
    9.63 +
    9.64 +    // The filename stored in the literal data packet.  Note: this is
    9.65 +    // *not* protected by the signature and should not be trusted!!!
    9.66 +    char *filename;
    9.67  };
    9.68  
    9.69  static pgp_status_t
    9.70 @@ -1306,6 +1358,29 @@
    9.71      return PGP_STATUS_SUCCESS;
    9.72  }
    9.73  
    9.74 +static pgp_status_t inspect_cb(
    9.75 +    void *cookie_opaque, pgp_packet_parser_t pp)
    9.76 +{
    9.77 +    struct decrypt_cookie *cookie = cookie_opaque;
    9.78 +
    9.79 +    pgp_packet_t packet = pgp_packet_parser_packet(pp);
    9.80 +    assert(packet);
    9.81 +
    9.82 +    pgp_tag_t tag = pgp_packet_tag(packet);
    9.83 +
    9.84 +    T("%s", pgp_tag_to_string(tag));
    9.85 +
    9.86 +    if (tag == PGP_TAG_LITERAL) {
    9.87 +        pgp_literal_t literal = pgp_packet_ref_literal(packet);
    9.88 +        cookie->filename = pgp_literal_filename(literal);
    9.89 +        pgp_literal_free(literal);
    9.90 +    }
    9.91 +
    9.92 +    pgp_packet_free(packet);
    9.93 +
    9.94 +    return 0;
    9.95 +}
    9.96 +
    9.97  PEP_STATUS pgp_decrypt_and_verify(
    9.98      PEP_SESSION session, const char *ctext, size_t csize,
    9.99      const char *dsigtext, size_t dsigsize,
   9.100 @@ -1313,7 +1388,7 @@
   9.101      char** filename_ptr)
   9.102  {
   9.103      PEP_STATUS status = PEP_STATUS_OK;
   9.104 -    struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, };
   9.105 +    struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL };
   9.106      pgp_reader_t reader = NULL;
   9.107      pgp_writer_t writer = NULL;
   9.108      pgp_reader_t decryptor = NULL;
   9.109 @@ -1343,7 +1418,8 @@
   9.110      pgp_error_t err = NULL;
   9.111      decryptor = pgp_decryptor_new(&err, reader,
   9.112                                    get_public_keys_cb, decrypt_cb,
   9.113 -                                  check_signatures_cb, &cookie, 0);
   9.114 +                                  check_signatures_cb, inspect_cb,
   9.115 +                                  &cookie, 0);
   9.116      if (! decryptor)
   9.117          ERROR_OUT(err, PEP_DECRYPT_NO_KEY, "pgp_decryptor_new");
   9.118  
   9.119 @@ -1372,6 +1448,9 @@
   9.120      *keylist = cookie.signer_keylist;
   9.121      stringlist_append(*keylist, cookie.recipient_keylist);
   9.122  
   9.123 +    if (filename_ptr)
   9.124 +        *filename_ptr = cookie.filename;
   9.125 +
   9.126   out:
   9.127      if (status == PEP_STATUS_OK) {
   9.128          // **********************************
   9.129 @@ -1399,6 +1478,7 @@
   9.130      } else {
   9.131          free_stringlist(cookie.recipient_keylist);
   9.132          free_stringlist(cookie.signer_keylist);
   9.133 +        free(cookie.filename);
   9.134          free(*ptext);
   9.135      }
   9.136  
   9.137 @@ -1773,8 +1853,8 @@
   9.138      T("(%s)", userid);
   9.139  
   9.140      // Generate a key.
   9.141 -    pgp_tpk_builder_t tpkb = pgp_tpk_builder_general_purpose
   9.142 -        (PGP_TPK_CIPHER_SUITE_RSA3K, userid);
   9.143 +    pgp_tpk_builder_t tpkb = pgp_tpk_builder_general_purpose(
   9.144 +        cipher_suite(session->cipher_suite), userid);
   9.145      pgp_signature_t rev;
   9.146      if (pgp_tpk_builder_generate(&err, tpkb, &tpk, &rev))
   9.147          ERROR_OUT(err, PEP_CANNOT_CREATE_KEY, "Generating a key pair");
   9.148 @@ -2587,3 +2667,4 @@
   9.149        fpr, *has_private ? "priv" : "pub", pEp_status_to_string(status));
   9.150      return status;
   9.151  }
   9.152 +
    10.1 --- a/src/pgp_sequoia.h	Wed May 15 14:20:48 2019 +0200
    10.2 +++ b/src/pgp_sequoia.h	Thu May 16 08:14:02 2019 +0200
    10.3 @@ -112,4 +112,7 @@
    10.4  
    10.5  PEP_STATUS pgp_binary(const char **path);
    10.6  
    10.7 +PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session,
    10.8 +        PEP_CIPHER_SUITE suite);
    10.9 +
   10.10  #define PGP_BINARY_PATH pgp_binary
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/include/LiteralFilenameTests.h	Thu May 16 08:14:02 2019 +0200
    11.3 @@ -0,0 +1,19 @@
    11.4 +// This file is under GNU General Public License 3.0
    11.5 +// see LICENSE.txt
    11.6 +
    11.7 +#ifndef LITERAL_FILENAME_H
    11.8 +#define LITERAL_FILENAME_H
    11.9 +
   11.10 +#include <string>
   11.11 +#include "EngineTestIndividualSuite.h"
   11.12 +
   11.13 +using namespace std;
   11.14 +
   11.15 +class LiteralFilenameTests : public EngineTestIndividualSuite {
   11.16 +    public:
   11.17 +        LiteralFilenameTests(string test_suite, string test_home_dir);
   11.18 +    private:
   11.19 +        void check();
   11.20 +};
   11.21 +
   11.22 +#endif
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/test/src/engine_tests/LiteralFilenameTests.cc	Thu May 16 08:14:02 2019 +0200
    12.3 @@ -0,0 +1,44 @@
    12.4 +// This file is under GNU General Public License 3.0
    12.5 +// see LICENSE.txt
    12.6 +
    12.7 +#include <stdlib.h>
    12.8 +#include <string>
    12.9 +#include <cstring>
   12.10 +#include <cpptest.h>
   12.11 +#include <fstream>
   12.12 +
   12.13 +#include "pEpEngine.h"
   12.14 +
   12.15 +#include "test_util.h"
   12.16 +#include "EngineTestIndividualSuite.h"
   12.17 +#include "LiteralFilenameTests.h"
   12.18 +
   12.19 +using namespace std;
   12.20 +
   12.21 +LiteralFilenameTests::LiteralFilenameTests(string suitename, string test_home_dir) :
   12.22 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   12.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("LiteralFilenameTests::check"),
   12.24 +                                                                      static_cast<Func>(&LiteralFilenameTests::check)));
   12.25 +}
   12.26 +
   12.27 +void LiteralFilenameTests::check() {
   12.28 +    slurp_and_import_key(session, "test_keys/priv/pep-test-lisa-0xBA0997C1514E70EB_priv.asc");
   12.29 +
   12.30 +    string ciphertext = slurp("test_files/literal-packet-with-filename.pgp");
   12.31 +
   12.32 +    // Decrypt and verify it.
   12.33 +    char *plaintext = NULL;
   12.34 +    size_t plaintext_size = 0;
   12.35 +    stringlist_t *keylist = NULL;
   12.36 +    char *filename = NULL;
   12.37 +    PEP_STATUS status = decrypt_and_verify(session,
   12.38 +                                           ciphertext.c_str(),
   12.39 +                                           ciphertext.size(),
   12.40 +                                           NULL, 0,
   12.41 +                                           &plaintext, &plaintext_size,
   12.42 +                                           &keylist, &filename);
   12.43 +
   12.44 +    TEST_ASSERT_MSG(status == PEP_DECRYPTED_AND_VERIFIED, tl_status_string(status));
   12.45 +    TEST_ASSERT_MSG(filename, "filename");
   12.46 +    TEST_ASSERT_MSG((strcmp(filename, "filename.txt") == 0), "strcmp(filename, \"filename.txt\") == 0");
   12.47 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/test/test_files/literal-packet-with-filename.pgp	Thu May 16 08:14:02 2019 +0200
    13.3 @@ -0,0 +1,25 @@
    13.4 +-----BEGIN PGP MESSAGE-----
    13.5 +
    13.6 +wcDMA9wGqgE3hB2PAQv/Z9pFeIVERgTJJqSY0pWiGdbknsSjkTrkhJVPkMZ0LEJ7
    13.7 +A+sj0tXxRtFpEk2U4TLpoN3zlYsD0+ATTqVMGP7WKRm/EyuP40j6jWoGtxU4E3Vh
    13.8 +BL2+fLkqx5i+MV3JDNwILPb+ZQU1qRWn2Ocvu3akTiC7AwApX5GW2x1WmUbhkHjI
    13.9 +Ynwp+VDkdteL/kMP5UFiN3V+WicXBOhST/X0tz7mzq/UHpPN2e4T8Sb48ImKTlop
   13.10 +wBO3lqC23YHTVl87bGm4yeM5XrzK/0yO+pAUQ53G2aFkjNHfcqtkAGcazmOqXhXF
   13.11 +EhT1Qo6Pfu7ZXBPsBLHj8eRjBqf0HXVxv35//BSjAhUOmzMa81OQHHfD2wpuiwLB
   13.12 +yKgjvjphUQydgzTjHAI9/dkcDMM4MQkp6rbJU10dwhGqcx1rD1tmznMMdHup7lfA
   13.13 +Np6UAhvxJPAxjGtGiWfj7xi9D63TgFOoh4fboBgSd1s9X5rH6u9+9dNOPLEOPHMP
   13.14 +hgRTxqJxie3PDALN6kdL1MFyAQkBBoNRgvuptD0v1VFYsy6+w+tG3LFw/NoKC8pv
   13.15 +dcSBormmdWLNF3SLDm0ECp27x8U9tYxqjqX4J7XCv7ipcqa3cifPIafMpxCCicMP
   13.16 +hHcl5zgyMrVtlqUbgrrmlQF4+lVL64+mqo0jDJqU3C9TWUZmNJJ3B/f12ZrpbV+3
   13.17 +h8UBRUQyq85shpoCEdBCYLULvH2K7BA28RDj2kCr6RM+jOJO3UYthwJv7ebqXL/Q
   13.18 +oqmgdiZxFEl8WjQPxFL7S1fSoqkFRklSr5zaD8JNdzw8NYlgroulRVQgLKFHRjZb
   13.19 +mGvMywHSQfylbBVhx3k5JiGkPUE8jRMvibty5we/4ENAxNY4ihDlZ4LUtU/aPkND
   13.20 +QMul8MUjIWVF+ZpTF3Z6zz6cbXB8FJWiDw3+Ak0Z+sHR8TfVIhtJWQkaKO3WUJ/1
   13.21 +zaHUpfssL+n55as7H59YURYyMQFAgWcuOtqqt+pulWuv64GXWBjpYeOwds4rBb5i
   13.22 +erJ6GUZW0Or+yA+XPC15uRcJh23oef7zQoRaIyJVv9Dr4NinsMUfi3Rp8x2w53Gr
   13.23 +9K/HCZh7OPs4Ym+sKXi+lBOUhkmtc5ZRqh6SbAm/2MC5bvSPh+tswN/8mP/ejhuH
   13.24 +OVf/lXdPzmQl1vt9kuDVsj1iy20MjL9F2TXNkdkPOAOCBblUCo2GqrfImzVdL+wO
   13.25 +CrqnO063T9LexQ3Un7w8XnUnd+zvr1qck50KQ/8tDtIaNnK7u05oxw7Z9aG5fqlD
   13.26 +pCoGqA==
   13.27 +=P6SJ
   13.28 +-----END PGP MESSAGE-----
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/test_keys/priv/pep-test-lisa-0xBA0997C1514E70EB_priv.asc	Thu May 16 08:14:02 2019 +0200
    14.3 @@ -0,0 +1,139 @@
    14.4 +-----BEGIN PGP PRIVATE KEY BLOCK-----
    14.5 +
    14.6 +xcSYBFzcgtABDACkdvhKd5Kj/9qF81vu83NfXp+1+RMyhzShP7xPA1cwTmYaORUw
    14.7 +/gaPBaCc5eNW9F5NHsWOkgHRTBIC2VFXrHmxHx4PNsaDvO1C2nkVbiTggf1f299P
    14.8 +QXornJrQwAXAW8hA4ahDGznhSqI5rGNn2/vGnPhN/YmN5AxRPfIg0nteCxkz8X6u
    14.9 +Dlt8AzNnGOehEizm0nxVAEqWt1XYavASb8sFIpXAOOFw9crASw0tLzXBrdx1kFep
   14.10 +APo7RS6EBBG4nJYOicTwT6q1htpLHaicJnpuU6fNZEBtheGwyevXsh6vGC9C/0bq
   14.11 +5aSs0JtqSduzbdqnZOItaNGqxvo2Wxg8IppnYB2WuE8pwuNcxop1tfPasnW63ScX
   14.12 +64i4fqndG3BpNHMaA9ROld87SSCYjKut646sq9JOa6fqnJiDHN4R+qRAoPe1vnra
   14.13 ++ct5RenE95gcNDX4S/RZx3XpIF/SPtbUgVqsw1dkOns0Rz/C6dIhMhM9Q2btT9sg
   14.14 +6TP1Xh8m5ihgaykAEQEAAQAL/jk02LCuXueEu3IUcEnxjJQDyfH2LWNJ/FiKXuns
   14.15 +84rt+j3s1R4xff6JqpBotmcsoRCaP4WT6+XtW+Z5yP2CFOIzPLV2DB8OvEigzbVS
   14.16 +lqkxDf0l8csTr3c0BfXOlTGPu1w2Id0Vv1BKMZt2By29Kxquxv/5zLr6M/6eWXZp
   14.17 +QFg57A5RVgsdG11Lj7mwxAEW3V98n5rBezBpnQamS9Nd53Rlz0kJgAFWvaudb3vk
   14.18 +DALOgvyxtIwotuGe8ssgzzkz3b9PooDHODA0hHIdXEKWKIr80AjXM55Cbx4TkB0D
   14.19 +NQMw5yqoEHkL4s+iFYR34HXJwtGOxSwqzocUVgnoceZ0+CDN7WlgMu8v3oKnoIGv
   14.20 +VHho08gJPCadHpeCPLAGslkuo5nEVggxFuMptmILHS+W6GImO00olywUGRw0wvH8
   14.21 +D7GF0wn1ElJxIx5lmBD34AUOcLXqizXtazX4eoOasr8lXtigko1GiLC9lYLWSI6l
   14.22 +6RqO0HXtnMwYP8AG5vI+NxCD8QYAw5JOBZjr4A/uuJLCjCFt+ItKjcdukdsy68Dq
   14.23 +ZCoi5EPjJzmXrt4JsO3d4evQQbPZ/AINf+5Jr8hMw0HywEU4JjSg5g+dn0uNPu7A
   14.24 +8tyxpkrNW4JqQ3UdcOEzGv7xeALhEOeNeRYDbB6N7ADhNskWF7lInQhrP8ZqvIDM
   14.25 +JZQ9Q72PtyyJzKGPv+iP1nSY8lTjCTRnt7SXASNeHRpeWvmxUQVQHR2PxedyUU5l
   14.26 +mwpsS/kcghYPC0uA4Nrh2oMDEZlfBgDXSB7p4s0f+qnqHdnMysCIOslxTYfQMGUB
   14.27 +SbYGHQGD4Pu00uaby6N6r225zw2r6wxyOtI4DrzJDm6Uwq1hMeT/SziCVAP57TAV
   14.28 +9TgifytjYHfk2IMQdi5Q5314ifwL0fi38MBWS6B3hTRYK0+fj86XkX54QBsPPcvY
   14.29 +sQMopiuKaikQT/NluG9MM15CmlgYU2w4UfpSpdYy1Cs2f7jTGXM1BxPsrS5ezmpj
   14.30 +3SYfqg7h7a0lIIV+5anSz0GCDchh4HcGAIlR8tGkBmF4XV2yC+2jQWUxDOsNx5UK
   14.31 +irZOogvmZa7I5cqaRDcXRGpRxgQ6h1bU8CF9C30CGExQtoa6DK5TZd+oRH1gFujW
   14.32 +CUvu56w/ud3bxM9rmpNFN1vqHDMHSZJgAxotEWDQBYYYjIEELqmadDb/H3tLRoZR
   14.33 +SA7HbaUTaeVe5YpQQoeCRHdxME+eWWQiXTIbiBbT/DOh2hauAxYzZVREuAivohXn
   14.34 +c9Ref+jhMAdAfAPaLe+63re7uXa7PYmuEdGywsD8BB8BCgAwAh4DApsBBYJc3ILQ
   14.35 +FiEEEBKCMYcIEkqSW9rougmXwVFOcOsJELoJl8FRTnDrAhUKAAAdZAv+KzUDchOn
   14.36 +JRQbNn3HS4GoI5GiwxHEBAp0khU7jAiBhWUHBiYNsw76DsGy1C3udLUFrquHJaRX
   14.37 +2KLHLjpcGq+Qd++jKzXAJpnWN6x5GWMQCKJqt2++ABeCwPWZW2gZOMs+T8z6Zim9
   14.38 +mZ1lwgPk/zhIq5EfP7/kfTjr/NG6+9ucmRYalpYShfoZMgGEYX/oau4FlTR5l8Ga
   14.39 +9hAYhknwEqrK1XjfWH/G8/uuX+RHgIP+0R5tO9POs8KxbrX6Lnt1pXwPDNeBEgpg
   14.40 +Yr14zsni0askfqS4bv/eoWJbmQ2p5eZMBaCMoLof0kBAA3RTQ2l6Ks5G0XEHfCuA
   14.41 +GYPzvy2xwZhw7JrB2Jj+h5F28ZRwBEbqODPwE59UBE3Mz6ocSXSNVT8ZXNRir5xl
   14.42 +H7GMTXGryyZSvedXh4IrFPbglXd1+7DGIOrlBqr4iBxAxPXmjcbZK3bqm+WuIo+2
   14.43 +sgo1DU8aqISNNSfjEHf5J+EXBNQfVCKYJokyiqVIpY6ZcsmKO2WrqarMzV9MaXNh
   14.44 +IE1hcnkgU3VzYW4gS2FyZW4gS2ltYmVybHkgUGF0cmljaWEgTGluZGEgRG9ubmEg
   14.45 +TWljaGVsbGUgQ3ludGhpYSBKb2huc29uIDwxOTYwQGV4YW1wbGUub3JnPsLA/AQT
   14.46 +AQoAMAIeAwKbAQIVCgWCXNyC0BYhBBASgjGHCBJKklva6LoJl8FRTnDrCRC6CZfB
   14.47 +UU5w6wAAWsUL/3EkmeLQk6j34YhyHXr3bUJvLrhTDfk+W2k91p9VUmrhRleLFJpS
   14.48 +PJVPFFm9APvtZmQrrKt+YKTZEu09Oh2DbowRULisOj8EOrTOiiheBJ8YTnBxGyiI
   14.49 +Kb7ZRmVPIuYnnQSn+i5I1Ca4Wij5NvBQ8kf23C7xPzPeE/uy6m19L0nw0gtl47xQ
   14.50 +rfjVtfTqWYCrS7FQSNS5opiaJ/8Pq7x1BagMv/vrvAN7qulmWyyj3fLzM9tyVoil
   14.51 +Al6WV85qcNU7cG13gasaEPaG93dvbw/0HnQYvxf6LUxaguFUuixD6R3wnAGTYQpd
   14.52 +htbqn2HjNdXAaVu+nNc77fLqZQRK48Mpeo1m4A5+2ymcMpWgeqTG/Bz3dedH3D/g
   14.53 +Fmkc/AF3hM9K3nzSdO7jmoVWQl8OM7gs39+6swWQ1s/qHncr/R56J50VyBOomm0m
   14.54 +nK0GObGCOlCetrrobMutAWHoWUx5Hk/Mvgwy0D4gAMBG9mZ495iEotc8tYCvs+xg
   14.55 +Y33FwKdv+9RFGcfEmARc3ILQAQwAoe7NBS5Gd+rlRl+GeMLxL8AyWYe0dbznaPSM
   14.56 +S1k+hgFbU4a1pgHem5cxtzKg+9CAIcUePd9wgQDzGHboRR+dp3ImhMmwbD6ynY5i
   14.57 +TnTKxDJZ3D1CE0VqGzpgvrGFODhfu5z3GzpUEF3WGX6GPqnOfk5zH+PO01lksPyf
   14.58 +S6A6P5in/oaVnzUxxg82fDyyHq5ME0wOTrjwD4woa+ODO6We7F6+uJs+mpmL5vCS
   14.59 +nYWcn8DVLZsXj60lSNjbf+9fcVAgNMbljk/wFUdXrjADdV7TIXMgM3qJPjp8QY16
   14.60 +CJv2R9eDOEFndllPaKPsZnjqmwbBka71WSmo0aTADODo+M46kAJPZk1I9PvCAGMn
   14.61 +O78tEc2Js7j/+6ujYXUKp52jjUtqoyPX7WrqlzKFMGF129HwIyYELYel8SB6tq3V
   14.62 +knh5ARP4a1W+G+bhcOo97RA12WP+3Jnfz5sd6P/yMmM3MO+eD4xmLEs03Tvwv3eB
   14.63 +8rgltx1CVj/9+OxH4DTWs4/2j1ZNABEBAAEADACOVDmpuxG/JxwcbavhCt847EKV
   14.64 +BL0t2zq+umtxcuCMojamRLn2TqBdu1e8QOjUTF/CzuIU2galrLL+pszirLZCTgfj
   14.65 +IO9LRRRzfYmUkf0C04q+FK22CIYJppcQJTIFxy8F1SIwsWTf+cpMIDRYcaIIzGVN
   14.66 ++0p345OoKHLO4ucvrLrD8YEjLXsxLX/jVOnuI57EO048DTsbP0LsCU34qEr2URRr
   14.67 +aDBvbFRWSM9lWuHeXHxDGJVt+G7UB59uZHRMQXKXZWD1mlS3NRL1YfkXDs+TOKlq
   14.68 +VKulz6NB7Y+OLywfXcMyR4NN7mhRxX6+c/jt6qagb+vJezEzK/mgRc+jrUkNGLWG
   14.69 +Rqc6DtWSv5VPU5PopJr0rSZGjTZxXyUXKQh/mMR29XQt/3qDNQC/mN6NxhrQvY3t
   14.70 +xo2cDohhSPs5U+EOsVSvpQ/MUzJBikl6HWrTA2AzWDLNEdvKRjGrWx80BTY86kHI
   14.71 +pWNM0lMz9W4W6vf9HTxXgeCD/dj61NCVT0UgKuEGAMrWQcuA5Y5Ou4q+hBfDcMbe
   14.72 +q3212N+nLwj7QJ0E2/GeAlZJlnDbvTLH9SCjyhmEtHU/gaSfkokkufcIXlxyHvyx
   14.73 +cZuq8vPXK4dX4IUusZ/EF1UHHhdDCJL12a6JyMmEfoO6kcXILFOcXm6HEEQcoArZ
   14.74 +qHmEI7+OZo+6YP7pgFYFG3ZFiPWXogKEaBTEkIYvr1Lj+iaG3Z06cNxh4UO+IXDf
   14.75 +n6+Yx+Gipp7sdtqzU7uJ3wkvROzvw/wQVofwhSToRQYAzGAATq4gOLNZvovzqoch
   14.76 +DOhHoeXaDLCDXePae+/w+yQX2jf3Uvsotn5NRL61ays3v5tNUZtb0fe75sQxGQQP
   14.77 +Z87f9LhUAFxHpKrxddANGoKiIpK02fivpbteSy8QRA26Ly39+Ewng2TtcAO+wQXu
   14.78 +xrbWrXKMylXabnhZMbkeWkKy4AjPe2uzlPidQUStc5oNFblD4q6bsfCIynif7lH+
   14.79 +vKdC68nHwULik2D4QfjRHH0Tb2sJvI2orEQzC4OX+eppBgC/98U0K4GxSZKgT3Oe
   14.80 +59rfANg81hYkFIUR1MGD4PWE9BI0h/MULkvOX9ATRV1cQ53BylwP5EYb4Fjc5iMA
   14.81 +TBPBnHSYQFqRPNMpTTJzIPi3D2gdFdz7/jKAbUF3ASIeE1A9ACKlBn4nzh7MGJLr
   14.82 +NQSbQbBqLzMMaVsA8yV0Qt7Iee9wtf2R6utHYrHMG6C9r6OmIMwM1gMBjEXqxQ5c
   14.83 +7C5t9gPhGVtUpCmK2QPXF1v1Y03BV4/rhp99tAJGjkkG4NriFsLA/AQYAQoAMAIe
   14.84 +AwKbDAILCQWCXNyC0BYhBBASgjGHCBJKklva6LoJl8FRTnDrCRC6CZfBUU5w6wAA
   14.85 +ElYL/RZwStIiGdLdI8fDVofuUTLaBZeenzTuKmFuwhldo7ECZYB0ZrmdXkFTj6RC
   14.86 +WOUyh29OwvW7h82EMUJIx/UYMs85oQaQtVLo0DMAfoxp9rt9UAVXh022zQBjwb8b
   14.87 +axN+Bo1xncNr50xigk6UUsk5QOP6kDqd+AYUyUTTK5ZJnS10RIgrOzddVfmlplTR
   14.88 +Su3P5VyqxcbY6LDTFSrLXmQDxkTgQJYmVV4t/doKyHlnNOLC3CA6n7FxgjhocqLi
   14.89 +zOsrg5KbDmtxeA0mcOfVam7TrrwrLtUYVWUhj/xkUXpWi7U4t1aSF1aQQBZG/KZy
   14.90 +WL9pI7ClJBiXBIGDXvBFke/iMmaRjVnVnDsu9ITYAYd3unV/rb7A+KWe/59rq4xP
   14.91 +Aup0EghWZoEtOE12yVvz17gzYvWOWF+phltYobTRrvwYUA1P3MBpNtl5L7XcCOg5
   14.92 +Dm6DnJOPvt+Ds4FNyFYVUOJZ294Xv1sgesuQWRf3CTRuHGQzrukuXPLeRuNKzJmU
   14.93 +QHY7xcfEmARc3ILQAQwAusNsIouqhxHJCDDRkHFVzoPA+Pk7Wj1kfWm7e2lHvXy2
   14.94 +DKKGHkoGjz2kITeK+I8KoyTU4EXihGtOuHwHXbLzzsxk8Ae4FzBo2+UQUYEzYBaV
   14.95 +vLYuDQ8LFNHYAocLKgfI71vyCTXFvuw4vpS3ueKO4Iqw9PdCmcOuiYOO4yGsqKlL
   14.96 +5EiKRcyO4K9JFJmAUVMQ4TIdfRtevDhKAKGQts5x5emr+ty9GL6Yv6SNXQhRo4Eo
   14.97 +jmVokdylJVadO5IfETSk7kTRQbGrExh198mKTjH/1gOf9sdFtTAU+eOYSkGlB82t
   14.98 +leLPFP8zXtJ/RvNv+xE/j00vE7s4rBvLNf+eLWpjjkYU7mjqduSUx4TCwtze321k
   14.99 +fzl+fQjTRJAMJmrSn9RrFIg3OjTzKM6iZnkIL0Yi+I7Tu00ouz4knYIOBxrTwLTj
  14.100 +PcqIGl25DvaO2+eKrG/LQKmoW7/xZ3LuFYfikqK9rFHrZ0esO6lzLGXxTBGuBzGI
  14.101 +RgrPWtCWb4rApw8zFuvNABEBAAEADACk+5l88vBTnWx/pdCazuPEKTPBPTonP3CU
  14.102 +MWEDZj+PrqmLg88C1tXwl71z8oL7jDETaaf77wBphfnmkvpW1Yz3NCw+tjLzmToo
  14.103 +drPxrDbcPVdNe4o20wExBSbTJMTB/lqMyCaJ6EylmjuOcAXVWcRpq1sjK4JUHz8C
  14.104 +D4ucLdU+sT9vjH1Jp6jX50Chx/BI5x5UMVdHe3Q2xWrqH8+dDcYkGkZot7L8NvLs
  14.105 +6MpQUtb7n09aa07y+32P/HGtfCmho2RDjU96S8evtzb2cf7qRHpltDZdjnanFh65
  14.106 +Hnnkz7hddisyajfPbVNjnnQUCGcw6yeyCLsv3xVsiRhpGrjYe0Q469A78h5WweZq
  14.107 +ME4ym8kgV9IHCUGJwmlMthBxVHm5GFT3cKXdRVC2IMmpCVuHsGAh+MfEIz1+zVL0
  14.108 +oF1pLE/wGLGNqWcQUEjLyEdw5MGltsnRVjJ4SGw5zSjKSa9V8XebX+R2QdCrIFzq
  14.109 +qraC3P5RxXgYPpjIbYHkFD5tKmFoeGkGAMfarnMcyc0E1lXUcYKmN9yHyIpuo6NH
  14.110 +r3NlstH5QO17Sw6DhG33zBOpAOvCHd6wbyEl8DJENc0TyA1sWWUVqxKzEVanne9a
  14.111 +lNt5V/3hAX1q+aPR24b//ZNtPoFERfmrc/U1EsOICU1fiuI4/NyFk+JORYuYGqc/
  14.112 +8bwhQ9Fwcb6dUTpk+iFIQD8oGkK/P4cSjId1BNb5LWRf81WxEbfX+jUyH/mP7Qi9
  14.113 +CcswSws1dVLGYU1AhjXY3oqpKH+QCrq1NwYA7ztCcVqil2rffGuY2fbJnmGwso2W
  14.114 +qduQrWhmzdI7vBbdELET3fPR39E+PuiBNzVlwrTdMKRLWPCpINT8nv6otGLoY/bq
  14.115 +1mgUJ/m6VSebbPQtZeau7lc2UpcaMwSX9k1ExYAiN7YqBWHPOoPtJMzsXEObkBmD
  14.116 +RDSZBF3xKNfljqATPtKM8sf6Y9rbmuYT97zG+oH+8XZP1Kfw5Brw3uRZucpkKxZ1
  14.117 +lpaFXZpbWUMoUqAVKWs8xrx4/8iHaCZYoCkbBgCME81XiNkdKZ+PeoX3u4jxC/Aj
  14.118 +6srcR6ZavvvmrzzV8AclVn2PVpf0SGVG0D/IMvPb62hxf0geCoF3SJPiW5Iena21
  14.119 +zRSDW0KBeAc32+YwWNmNRm0CCwpBb3vA+0v0uVw71CG24IeX4ZjTnXpn1ywd177M
  14.120 +Y4e8Ebc/bQETaQy+kPja5ieGbI2pyUkVGJ3zxev64VM1f+znItOHYWrX9J4wngr0
  14.121 +rCpQ4zYrfBjBSy762kcSZ8WQrahMYJ9HFei9NeTrScLCsgQYAQoAMAIeAwKbAgIV
  14.122 +CgWCXNyC0BYhBBASgjGHCBJKklva6LoJl8FRTnDrCRC6CZfBUU5w6wG2wPSgBBkB
  14.123 +CgAnBYJc3ILQFiEEdxDh/7TuDwfji0GMwvGfZi2wcf8JEMLxn2YtsHH/AADrkwv/
  14.124 +dRccKQN7JOWanhIkYZYk/wuc1vrvg6a+VPPiMMCiqR8DFjGUXAIq0VcCseR2tiZV
  14.125 +zG9AwgZOZTU8ENHVGiaHi2PMiEK+JZabIubQtKgSW5StuLGKnVjFIU0pSOsWeYdU
  14.126 +2kBZ9muLilZ942tTRC4oNrWKOP22TQ5iVcl476MeJw/YVpqzvMBpmGWF5CAJlYHJ
  14.127 +H1gjChX70DRsfGZdpxFgjgSlf6L15xQhOoHEGYHeop4PZrH73Fx8KRsFh6BG720z
  14.128 +JOViDWZ1d3/w8Rp8bZ7n7X30aQNQq0vVIP1I7Hg5OHDqN0AZZ0Ugp8HEHMwlBQf7
  14.129 +qpMIf0qTznTYr1eUjsGHx/Ys0mPtB5OWMheOF9+0Pyrl5vI/KJg6GgR/v+vGQDMb
  14.130 +eDVLZeCdoqfD5l2CxkCyPPDiieQHuYU6PSo/tc64oRsqjHcfmsT7icX2K0DdgFfc
  14.131 +33jZIZtV5vp2xU+AQUOKe8B+mnb0crAq6FruZv6+gBUTKGjn+346xwg2zBiMaiCL
  14.132 +AXkMAIygwJlq+Eb3KOBqrRoxS2fDBQCMOn6pbrls9LdwoZyq8g6iId2KcRX6snvr
  14.133 +/TX5yM0Gbo3+s0tHXI+US5JnP6Gx0CKtXrKYt6TG86UvmyxP50Yb3i7plgwniRpx
  14.134 +HUtYb0Bf+4uzEAMn4BCHxZvD4bZ6FHr5OPFol5At8Zxv8juCLQbmbVxUhX0qbqEl
  14.135 +ipLbGn9PsGoarAUX669//kYmOfO6cNwE5BtSponN3w7dSjsFsyJqdAHqHzMonRRv
  14.136 +PuSwUxZlQmyuTCqxflkf8otWAf6p4Cps2ZRrxJja7A7LynrX5H4NmQWsB5EAR0Gt
  14.137 +YHgpjWwBMF62/34vlEwVktJS7hMvoqgDx6hnymo4gYS7V6U0h3EhQUpSdAuT0NtT
  14.138 +dRFJ6M2QAwrTDLTjZFuQz8Yxqn5dwcUv24hPiwdrWb80Slv7SD0JeHcyW3XHqLek
  14.139 +nj3vs3qQ36S0d8+yi+PmoexhJmcn70PvtxIjW6t07z33FplTAZ/VRfFpzNWmqPWr
  14.140 +b4PD8Q==
  14.141 +=1d3v
  14.142 +-----END PGP PRIVATE KEY BLOCK-----