merged in parent ENGINE-553
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Thu, 16 May 2019 17:54:45 +0200
branchENGINE-553
changeset 3713cb1ecf67cb7b
parent 3711 2899189816c1
parent 3712 2af31507d5d8
child 3716 55f1a6d89704
merged in parent
src/message_api.c
     1.1 --- a/src/cryptotech.c	Thu May 16 17:53:08 2019 +0200
     1.2 +++ b/src/cryptotech.c	Thu May 16 17:54:45 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	Thu May 16 17:53:08 2019 +0200
     2.2 +++ b/src/cryptotech.h	Thu May 16 17:54:45 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	Thu May 16 17:53:08 2019 +0200
     3.2 +++ b/src/message_api.c	Thu May 16 17:54:45 2019 +0200
     3.3 @@ -985,7 +985,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 @@ -996,6 +997,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 @@ -1003,7 +1007,30 @@
    3.24              return PEP_OUT_OF_MEMORY;
    3.25      }
    3.26  
    3.27 -    dst->longmsg = ctext;
    3.28 +    // id is staying the same
    3.29 +    if (src->id) {
    3.30 +        dst->id = strdup(src->id);
    3.31 +        assert(dst->id);
    3.32 +        if (!dst->id)
    3.33 +            return PEP_OUT_OF_MEMORY;
    3.34 +    }
    3.35 +
    3.36 +    char *_ctext = realloc(ctext, csize + 1);
    3.37 +    assert(_ctext);
    3.38 +    if (!_ctext)
    3.39 +        return PEP_OUT_OF_MEMORY;
    3.40 +    _ctext[csize] = 0;
    3.41 +
    3.42 +    dst->longmsg = _ctext;
    3.43 +
    3.44 +    // longmsg_formatted is unsupported
    3.45 +
    3.46 +    // attachments are going unencrypted
    3.47 +    bloblist_t *bl = bloblist_dup(src->attachments);
    3.48 +    if (!bl)
    3.49 +        return PEP_OUT_OF_MEMORY;
    3.50 +    dst->attachments = bl;
    3.51 +
    3.52      return PEP_STATUS_OK;
    3.53  }
    3.54  
    3.55 @@ -1927,7 +1954,7 @@
    3.56      }
    3.57      else {
    3.58          // FIXME - we need to deal with transport types (via flag)
    3.59 -        if ((!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
    3.60 +        if ((enc_format != PEP_enc_inline) && (!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
    3.61              message_wrap_type wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
    3.62              _src = wrap_message_as_attachment(NULL, src, wrap_type, false);
    3.63              if (!_src)
    3.64 @@ -1935,7 +1962,7 @@
    3.65          }
    3.66          else {
    3.67              // hide subject
    3.68 -            if (!session->unencrypted_subject) {
    3.69 +            if (enc_format != PEP_enc_inline && !session->unencrypted_subject) {
    3.70                  status = replace_subject(_src);
    3.71                  if (status == PEP_OUT_OF_MEMORY)
    3.72                      goto enomem;
    3.73 @@ -1957,7 +1984,7 @@
    3.74                  break;
    3.75  
    3.76              case PEP_enc_inline:
    3.77 -                status = encrypt_PGP_inline(session, _src, keys, msg);
    3.78 +                status = encrypt_PGP_inline(session, _src, keys, msg, flags);
    3.79                  break;
    3.80  
    3.81              default:
    3.82 @@ -2292,7 +2319,7 @@
    3.83              break;
    3.84  
    3.85          case PEP_enc_inline:
    3.86 -            status = encrypt_PGP_inline(session, _src, keys, msg);
    3.87 +            status = encrypt_PGP_inline(session, _src, keys, msg, flags);
    3.88              break;
    3.89  
    3.90          default:
     4.1 --- a/src/pEpEngine.c	Thu May 16 17:53:08 2019 +0200
     4.2 +++ b/src/pEpEngine.c	Thu May 16 17:54:45 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	Thu May 16 17:53:08 2019 +0200
     5.2 +++ b/src/pEpEngine.h	Thu May 16 17:54:45 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	Thu May 16 17:53:08 2019 +0200
     6.2 +++ b/src/pEp_internal.h	Thu May 16 17:54:45 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	Thu May 16 17:53:08 2019 +0200
     7.2 +++ b/src/pgp_gpg.c	Thu May 16 17:54:45 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	Thu May 16 17:53:08 2019 +0200
     8.2 +++ b/src/pgp_gpg.h	Thu May 16 17:54:45 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	Thu May 16 17:53:08 2019 +0200
     9.2 +++ b/src/pgp_sequoia.c	Thu May 16 17:54:45 2019 +0200
     9.3 @@ -27,9 +27,18 @@
     9.4  // enable tracing if in debugging mode
     9.5  #if TRACING
     9.6  #include "status_to_string.h"
     9.7 -#  define _T(...) do {                          \
     9.8 +
     9.9 +#  ifdef ANDROID
    9.10 +#    include <android/log.h>
    9.11 +#    define _T(...) do {                                                \
    9.12 +        __android_log_print(ANDROID_LOG_DEBUG, "pEpEngine-sequoia",     \
    9.13 +                            ##__VA_ARGS__);                             \
    9.14 +    } while (0)
    9.15 +#  else
    9.16 +#    define _T(...) do {                        \
    9.17          fprintf(stderr, ##__VA_ARGS__);         \
    9.18      } while (0)
    9.19 +#  endif
    9.20  #else
    9.21  #  define _T(...) do { } while (0)
    9.22  #endif
    9.23 @@ -77,6 +86,52 @@
    9.24      }                                                               \
    9.25  } while(0)
    9.26  
    9.27 +PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session,
    9.28 +        PEP_CIPHER_SUITE suite)
    9.29 +{
    9.30 +    switch (suite) {
    9.31 +        // supported cipher suites
    9.32 +        case PEP_CIPHER_SUITE_RSA2K:
    9.33 +        case PEP_CIPHER_SUITE_RSA3K:
    9.34 +        case PEP_CIPHER_SUITE_CV25519:
    9.35 +        case PEP_CIPHER_SUITE_P256:
    9.36 +        case PEP_CIPHER_SUITE_P384:
    9.37 +        case PEP_CIPHER_SUITE_P521:
    9.38 +            session->cipher_suite = suite;
    9.39 +            return PEP_STATUS_OK;
    9.40 +
    9.41 +        case PEP_CIPHER_SUITE_DEFAULT:
    9.42 +            session->cipher_suite = PEP_CIPHER_SUITE_RSA2K;
    9.43 +            return PEP_STATUS_OK;
    9.44 +
    9.45 +        // unsupported cipher suites
    9.46 +        default:
    9.47 +            session->cipher_suite = PEP_CIPHER_SUITE_RSA2K;
    9.48 +            return PEP_CANNOT_CONFIG;
    9.49 +    }
    9.50 +}
    9.51 +
    9.52 +static pgp_tpk_cipher_suite_t cipher_suite(PEP_CIPHER_SUITE suite)
    9.53 +{
    9.54 +    switch (suite) {
    9.55 +        // supported cipher suites
    9.56 +        case PEP_CIPHER_SUITE_RSA2K:
    9.57 +            return PGP_TPK_CIPHER_SUITE_RSA2K;
    9.58 +        case PEP_CIPHER_SUITE_RSA3K:
    9.59 +            return PGP_TPK_CIPHER_SUITE_RSA3K;
    9.60 +        case PEP_CIPHER_SUITE_CV25519:
    9.61 +            return PGP_TPK_CIPHER_SUITE_CV25519;
    9.62 +        case PEP_CIPHER_SUITE_P256:
    9.63 +            return PGP_TPK_CIPHER_SUITE_P256;
    9.64 +        case PEP_CIPHER_SUITE_P384:
    9.65 +            return PGP_TPK_CIPHER_SUITE_P384;
    9.66 +        case PEP_CIPHER_SUITE_P521:
    9.67 +            return PGP_TPK_CIPHER_SUITE_P521;
    9.68 +        default:
    9.69 +            return PGP_TPK_CIPHER_SUITE_RSA2K;
    9.70 +    }
    9.71 +}
    9.72 +
    9.73  int email_cmp(void *cookie, int a_len, const void *a, int b_len, const void *b)
    9.74  {
    9.75      pgp_packet_t a_userid = pgp_user_id_from_raw (a, a_len);
    9.76 @@ -121,10 +176,10 @@
    9.77  
    9.78  PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
    9.79  {
    9.80 -    #define PATH "/.pEp_keys.db"
    9.81 - 
    9.82      PEP_STATUS status = PEP_STATUS_OK;
    9.83  
    9.84 +#define PEP_KEYS_PATH "/.pEp_keys.db"
    9.85 +
    9.86      // Create the home directory.
    9.87      char *home_env = NULL;
    9.88  #ifndef NDEBUG
    9.89 @@ -136,13 +191,13 @@
    9.90          ERROR_OUT(NULL, PEP_INIT_GPGME_INIT_FAILED, "HOME unset");
    9.91  
    9.92      // Create the DB and initialize it.
    9.93 -    size_t path_size = strlen(home_env) + sizeof(PATH);
    9.94 +    size_t path_size = strlen(home_env) + sizeof(PEP_KEYS_PATH);
    9.95      char *path = (char *) calloc(1, path_size);
    9.96      assert(path);
    9.97      if (!path)
    9.98          ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
    9.99  
   9.100 -    int r = snprintf(path, path_size, "%s/.pEp_keys.db", home_env);
   9.101 +    int r = snprintf(path, path_size, "%s" PEP_KEYS_PATH, home_env);
   9.102      assert(r >= 0 && r < path_size);
   9.103      if (r < 0)
   9.104          ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "snprintf");
   9.105 @@ -863,7 +918,13 @@
   9.106      int good_but_revoked;
   9.107      int missing_keys;
   9.108      int bad_checksums;
   9.109 +
   9.110 +    // Whether we decrypted anything.
   9.111      int decrypted;
   9.112 +
   9.113 +    // The filename stored in the literal data packet.  Note: this is
   9.114 +    // *not* protected by the signature and should not be trusted!!!
   9.115 +    char *filename;
   9.116  };
   9.117  
   9.118  static pgp_status_t
   9.119 @@ -1285,6 +1346,29 @@
   9.120      return PGP_STATUS_SUCCESS;
   9.121  }
   9.122  
   9.123 +static pgp_status_t inspect_cb(
   9.124 +    void *cookie_opaque, pgp_packet_parser_t pp)
   9.125 +{
   9.126 +    struct decrypt_cookie *cookie = cookie_opaque;
   9.127 +
   9.128 +    pgp_packet_t packet = pgp_packet_parser_packet(pp);
   9.129 +    assert(packet);
   9.130 +
   9.131 +    pgp_tag_t tag = pgp_packet_tag(packet);
   9.132 +
   9.133 +    T("%s", pgp_tag_to_string(tag));
   9.134 +
   9.135 +    if (tag == PGP_TAG_LITERAL) {
   9.136 +        pgp_literal_t literal = pgp_packet_ref_literal(packet);
   9.137 +        cookie->filename = pgp_literal_filename(literal);
   9.138 +        pgp_literal_free(literal);
   9.139 +    }
   9.140 +
   9.141 +    pgp_packet_free(packet);
   9.142 +
   9.143 +    return 0;
   9.144 +}
   9.145 +
   9.146  PEP_STATUS pgp_decrypt_and_verify(
   9.147      PEP_SESSION session, const char *ctext, size_t csize,
   9.148      const char *dsigtext, size_t dsigsize,
   9.149 @@ -1292,7 +1376,7 @@
   9.150      char** filename_ptr)
   9.151  {
   9.152      PEP_STATUS status = PEP_STATUS_OK;
   9.153 -    struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, };
   9.154 +    struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL };
   9.155      pgp_reader_t reader = NULL;
   9.156      pgp_writer_t writer = NULL;
   9.157      pgp_reader_t decryptor = NULL;
   9.158 @@ -1322,7 +1406,8 @@
   9.159      pgp_error_t err = NULL;
   9.160      decryptor = pgp_decryptor_new(&err, reader,
   9.161                                    get_public_keys_cb, decrypt_cb,
   9.162 -                                  check_signatures_cb, &cookie, 0);
   9.163 +                                  check_signatures_cb, inspect_cb,
   9.164 +                                  &cookie, 0);
   9.165      if (! decryptor)
   9.166          ERROR_OUT(err, PEP_DECRYPT_NO_KEY, "pgp_decryptor_new");
   9.167  
   9.168 @@ -1351,6 +1436,9 @@
   9.169      *keylist = cookie.signer_keylist;
   9.170      stringlist_append(*keylist, cookie.recipient_keylist);
   9.171  
   9.172 +    if (filename_ptr)
   9.173 +        *filename_ptr = cookie.filename;
   9.174 +
   9.175   out:
   9.176      if (status == PEP_STATUS_OK) {
   9.177          // **********************************
   9.178 @@ -1378,6 +1466,7 @@
   9.179      } else {
   9.180          free_stringlist(cookie.recipient_keylist);
   9.181          free_stringlist(cookie.signer_keylist);
   9.182 +        free(cookie.filename);
   9.183          free(*ptext);
   9.184      }
   9.185  
   9.186 @@ -1752,8 +1841,8 @@
   9.187      T("(%s)", userid);
   9.188  
   9.189      // Generate a key.
   9.190 -    pgp_tpk_builder_t tpkb = pgp_tpk_builder_general_purpose
   9.191 -        (PGP_TPK_CIPHER_SUITE_RSA3K, userid);
   9.192 +    pgp_tpk_builder_t tpkb = pgp_tpk_builder_general_purpose(
   9.193 +        cipher_suite(session->cipher_suite), userid);
   9.194      pgp_signature_t rev;
   9.195      if (pgp_tpk_builder_generate(&err, tpkb, &tpk, &rev))
   9.196          ERROR_OUT(err, PEP_CANNOT_CREATE_KEY, "Generating a key pair");
   9.197 @@ -2566,3 +2655,4 @@
   9.198        fpr, *has_private ? "priv" : "pub", pEp_status_to_string(status));
   9.199      return status;
   9.200  }
   9.201 +
    10.1 --- a/src/pgp_sequoia.h	Thu May 16 17:53:08 2019 +0200
    10.2 +++ b/src/pgp_sequoia.h	Thu May 16 17:54:45 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 17:54:45 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 17:54:45 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 17:54:45 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 17:54:45 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-----