WIP: ENGINE-524: merge with sync ENGINE-524
authorClaudio Luck <claudio.luck@pep.foundation>
Mon, 20 May 2019 12:26:41 +0200
branchENGINE-524
changeset 373525b31318dcdc
parent 3734 73fbd2821d46
parent 3722 0f31947b826d
child 3736 b28bcc5b8c0c
WIP: ENGINE-524: merge with sync
src/pEpEngine.c
src/pEp_internal.h
src/pgp_sequoia.c
     1.1 --- a/src/cryptotech.c	Thu May 16 14:15:12 2019 +0200
     1.2 +++ b/src/cryptotech.c	Mon May 20 12:26:41 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 14:15:12 2019 +0200
     2.2 +++ b/src/cryptotech.h	Mon May 20 12:26:41 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/etpan_mime.c	Thu May 16 14:15:12 2019 +0200
     3.2 +++ b/src/etpan_mime.c	Mon May 20 12:26:41 2019 +0200
     3.3 @@ -1853,7 +1853,7 @@
     3.4              status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode);
     3.5              break;
     3.6  
     3.7 -        case PEP_enc_pieces:
     3.8 +        case PEP_enc_inline:
     3.9              status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode);
    3.10              break;
    3.11  
     4.1 --- a/src/keymanagement.c	Thu May 16 14:15:12 2019 +0200
     4.2 +++ b/src/keymanagement.c	Mon May 20 12:26:41 2019 +0200
     4.3 @@ -1060,6 +1060,9 @@
     4.4          if (read_only) {
     4.5              free(identity->user_id);
     4.6              identity->user_id = strdup(default_own_id);
     4.7 +            assert(identity->user_id);
     4.8 +            if (!identity->user_id)
     4.9 +                return PEP_OUT_OF_MEMORY;
    4.10          }
    4.11          else {
    4.12              status = set_userid_alias(session, default_own_id, identity->user_id);
    4.13 @@ -1069,6 +1072,7 @@
    4.14                  
    4.15              free(identity->user_id);
    4.16              identity->user_id = strdup(default_own_id);
    4.17 +            assert(identity->user_id);
    4.18              if (identity->user_id == NULL) {
    4.19                  status = PEP_OUT_OF_MEMORY;
    4.20                  goto pEp_free;
    4.21 @@ -1108,11 +1112,14 @@
    4.22      if (EMPTYSTR(identity->username) || read_only) {
    4.23          bool stored_uname = (stored_identity && !EMPTYSTR(stored_identity->username));
    4.24          char* uname = (stored_uname ? stored_identity->username : identity->address);
    4.25 -        free(identity->username);
    4.26 -        identity->username = strdup(uname);
    4.27 -        if (identity->username == NULL) {
    4.28 -            status = PEP_OUT_OF_MEMORY;
    4.29 -            goto pEp_free;
    4.30 +        if (uname) {
    4.31 +            free(identity->username);
    4.32 +            identity->username = strdup(uname);
    4.33 +            assert(identity->username);
    4.34 +            if (identity->username == NULL) {
    4.35 +                status = PEP_OUT_OF_MEMORY;
    4.36 +                goto pEp_free;
    4.37 +            }
    4.38          }
    4.39      }
    4.40  
     5.1 --- a/src/message.h	Thu May 16 14:15:12 2019 +0200
     5.2 +++ b/src/message.h	Mon May 20 12:26:41 2019 +0200
     5.3 @@ -30,7 +30,8 @@
     5.4  
     5.5  typedef enum _PEP_enc_format {
     5.6      PEP_enc_none = 0,                       // message is not encrypted
     5.7 -    PEP_enc_pieces,                         // inline PGP + PGP extensions
     5.8 +    PEP_enc_pieces = 1,                     // inline PGP + PGP extensions, was removed
     5.9 +    PEP_enc_inline = 1,                     // still there
    5.10      PEP_enc_S_MIME,                         // RFC5751
    5.11      PEP_enc_PGP_MIME,                       // RFC3156
    5.12      PEP_enc_PEP,                            // pEp encryption format
     6.1 --- a/src/message_api.c	Thu May 16 14:15:12 2019 +0200
     6.2 +++ b/src/message_api.c	Mon May 20 12:26:41 2019 +0200
     6.3 @@ -971,6 +971,59 @@
     6.4      return NULL;    
     6.5  }
     6.6  
     6.7 +static PEP_STATUS encrypt_PGP_inline(
     6.8 +        PEP_SESSION session,
     6.9 +        const message *src,
    6.10 +        stringlist_t *keys,
    6.11 +        message *dst,
    6.12 +        PEP_encrypt_flags_t flags
    6.13 +    )
    6.14 +{
    6.15 +    char *ctext = NULL;
    6.16 +    size_t csize = 0;
    6.17 +
    6.18 +    PEP_STATUS status = encrypt_and_sign(session, keys, src->longmsg,
    6.19 +            strlen(src->longmsg), &ctext, &csize);
    6.20 +    if (status)
    6.21 +        return status;
    6.22 +
    6.23 +    dst->enc_format = PEP_enc_inline;
    6.24 +
    6.25 +    // shortmsg is being copied
    6.26 +    if (src->shortmsg) {
    6.27 +        dst->shortmsg = strdup(src->shortmsg);
    6.28 +        assert(dst->shortmsg);
    6.29 +        if (!dst->shortmsg)
    6.30 +            return PEP_OUT_OF_MEMORY;
    6.31 +    }
    6.32 +
    6.33 +    // id is staying the same
    6.34 +    if (src->id) {
    6.35 +        dst->id = strdup(src->id);
    6.36 +        assert(dst->id);
    6.37 +        if (!dst->id)
    6.38 +            return PEP_OUT_OF_MEMORY;
    6.39 +    }
    6.40 +
    6.41 +    char *_ctext = realloc(ctext, csize + 1);
    6.42 +    assert(_ctext);
    6.43 +    if (!_ctext)
    6.44 +        return PEP_OUT_OF_MEMORY;
    6.45 +    _ctext[csize] = 0;
    6.46 +
    6.47 +    dst->longmsg = _ctext;
    6.48 +
    6.49 +    // longmsg_formatted is unsupported
    6.50 +
    6.51 +    // attachments are going unencrypted
    6.52 +    bloblist_t *bl = bloblist_dup(src->attachments);
    6.53 +    if (!bl)
    6.54 +        return PEP_OUT_OF_MEMORY;
    6.55 +    dst->attachments = bl;
    6.56 +
    6.57 +    return PEP_STATUS_OK;
    6.58 +}
    6.59 +
    6.60  static PEP_STATUS encrypt_PGP_MIME(
    6.61      PEP_SESSION session,
    6.62      const message *src,
    6.63 @@ -1575,7 +1628,7 @@
    6.64      assert(msg);
    6.65  
    6.66      if (is_PGP_message_text(msg->longmsg)) {
    6.67 -        msg->enc_format = PEP_enc_pieces;
    6.68 +        msg->enc_format = PEP_enc_inline;
    6.69          return PEP_crypt_OpenPGP;
    6.70      }
    6.71      else if (msg->attachments && msg->attachments->next &&
    6.72 @@ -1885,7 +1938,7 @@
    6.73      }
    6.74      else {
    6.75          // FIXME - we need to deal with transport types (via flag)
    6.76 -        if ((!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
    6.77 +        if ((enc_format != PEP_enc_inline) && (!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
    6.78              message_wrap_type wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
    6.79              _src = wrap_message_as_attachment(NULL, src, wrap_type, false);
    6.80              if (!_src)
    6.81 @@ -1893,7 +1946,7 @@
    6.82          }
    6.83          else {
    6.84              // hide subject
    6.85 -            if (!session->unencrypted_subject) {
    6.86 +            if (enc_format != PEP_enc_inline && !session->unencrypted_subject) {
    6.87                  status = replace_subject(_src);
    6.88                  if (status == PEP_OUT_OF_MEMORY)
    6.89                      goto enomem;
    6.90 @@ -1914,9 +1967,9 @@
    6.91                  status = encrypt_PGP_MIME(session, _src, keys, msg, flags);
    6.92                  break;
    6.93  
    6.94 -            /* case PEP_enc_PEP:
    6.95 -                // TODO: implement
    6.96 -                NOT_IMPLEMENTED */
    6.97 +            case PEP_enc_inline:
    6.98 +                status = encrypt_PGP_inline(session, _src, keys, msg, flags);
    6.99 +                break;
   6.100  
   6.101              default:
   6.102                  assert(0);
   6.103 @@ -2249,6 +2302,10 @@
   6.104                  _cleanup_src(src, false);
   6.105              break;
   6.106  
   6.107 +        case PEP_enc_inline:
   6.108 +            status = encrypt_PGP_inline(session, _src, keys, msg, flags);
   6.109 +            break;
   6.110 +
   6.111          default:
   6.112              assert(0);
   6.113              status = PEP_ILLEGAL_VALUE;
   6.114 @@ -2589,7 +2646,7 @@
   6.115      
   6.116      switch (src->enc_format) {
   6.117          case PEP_enc_PGP_MIME:
   6.118 -        case PEP_enc_pieces:
   6.119 +        case PEP_enc_inline:
   6.120          case PEP_enc_PGP_MIME_Outlook1:
   6.121  //        case PEP_enc_none: // FIXME - this is wrong
   6.122  
   6.123 @@ -2681,7 +2738,7 @@
   6.124              *text_size = src->attachments->size;
   6.125              break;
   6.126  
   6.127 -        case PEP_enc_pieces:
   6.128 +        case PEP_enc_inline:
   6.129              *crypto_text = src->longmsg;
   6.130              *text_size = strlen(*crypto_text);
   6.131              break;
   6.132 @@ -3458,7 +3515,7 @@
   6.133                  }
   6.134                  break;
   6.135  
   6.136 -            case PEP_enc_pieces:
   6.137 +            case PEP_enc_inline:
   6.138                  status = PEP_STATUS_OK;
   6.139                  
   6.140                  _decrypt_in_pieces_status = _decrypt_in_pieces(session, src, &msg, ptext, psize);
     7.1 --- a/src/pEpEngine.c	Thu May 16 14:15:12 2019 +0200
     7.2 +++ b/src/pEpEngine.c	Mon May 20 12:26:41 2019 +0200
     7.3 @@ -1991,19 +1991,22 @@
     7.4  DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
     7.5  {
     7.6      assert(session);
     7.7 -    session->passive_mode = enable;
     7.8 +    if (session)
     7.9 +        session->passive_mode = enable;
    7.10  }
    7.11  
    7.12  DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
    7.13  {
    7.14      assert(session);
    7.15 -    session->unencrypted_subject = enable;
    7.16 +    if (session)
    7.17 +        session->unencrypted_subject = enable;
    7.18  }
    7.19  
    7.20  DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
    7.21  {
    7.22      assert(session);
    7.23 -    session->service_log = enable;
    7.24 +    if (session)
    7.25 +        session->service_log = enable;
    7.26  }
    7.27  
    7.28  DYNAMIC_API PEP_STATUS log_event(
    7.29 @@ -4405,6 +4408,16 @@
    7.30              revoked);
    7.31  }
    7.32  
    7.33 +DYNAMIC_API PEP_STATUS config_cipher_suite(PEP_SESSION session,
    7.34 +        PEP_CIPHER_SUITE suite)
    7.35 +{
    7.36 +    assert(session);
    7.37 +    if (!session)
    7.38 +        return PEP_ILLEGAL_VALUE;
    7.39 +
    7.40 +    return session->cryptotech[PEP_crypt_OpenPGP].config_cipher_suite(session, suite);
    7.41 +}
    7.42 +
    7.43  static void _clean_log_value(char *text)
    7.44  {
    7.45      if (text) {
    7.46 @@ -4990,6 +5003,9 @@
    7.47      return PEP_ENGINE_VERSION;
    7.48  }
    7.49  
    7.50 +DYNAMIC_API const char* get_protocol_version() {
    7.51 +    return PEP_VERSION;
    7.52 +}
    7.53  
    7.54  DYNAMIC_API PEP_STATUS reset_pEptest_hack(PEP_SESSION session)
    7.55  {
     8.1 --- a/src/pEpEngine.h	Thu May 16 14:15:12 2019 +0200
     8.2 +++ b/src/pEpEngine.h	Mon May 20 12:26:41 2019 +0200
     8.3 @@ -118,6 +118,7 @@
     8.4      PEP_COMMIT_FAILED                               = 0xff01,
     8.5      PEP_MESSAGE_CONSUME                             = 0xff02,
     8.6      PEP_MESSAGE_IGNORE                              = 0xff03,
     8.7 +    PEP_CANNOT_CONFIG                               = 0xff04,
     8.8  
     8.9      PEP_RECORD_NOT_FOUND                            = -6,
    8.10      PEP_CANNOT_CREATE_TEMP_FILE                     = -5,
    8.11 @@ -278,6 +279,35 @@
    8.12  DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable);
    8.13  
    8.14  
    8.15 +typedef enum {
    8.16 +    PEP_CIPHER_SUITE_DEFAULT = 0,
    8.17 +    PEP_CIPHER_SUITE_CV25519 = 1,
    8.18 +    PEP_CIPHER_SUITE_P256 = 2,
    8.19 +    PEP_CIPHER_SUITE_P384 = 3,
    8.20 +    PEP_CIPHER_SUITE_P521 = 4,
    8.21 +    PEP_CIPHER_SUITE_RSA2K = 5,
    8.22 +    PEP_CIPHER_SUITE_RSA3K = 6,
    8.23 +    PEP_CIPHER_SUITE_RSA4K = 7,
    8.24 +    PEP_CIPHER_SUITE_RSA8K = 8
    8.25 +} PEP_CIPHER_SUITE;
    8.26 +
    8.27 +// config_cipher_suite() - cipher suite being used when encrypting
    8.28 +//
    8.29 +//  parameters:
    8.30 +//      session (in)            session handle
    8.31 +//      cipher_suite (in)       cipher suite to use
    8.32 +//
    8.33 +//  return value:
    8.34 +//      PEP_STATUS_OK           cipher suite configured
    8.35 +//      PEP_CANNOT_CONFIG       configuration failed; falling back to default
    8.36 +//
    8.37 +//  caveat: the default ciphersuite for a crypt tech implementation is
    8.38 +//  implementation defined
    8.39 +
    8.40 +DYNAMIC_API PEP_STATUS config_cipher_suite(PEP_SESSION session,
    8.41 +        PEP_CIPHER_SUITE suite);
    8.42 +
    8.43 +
    8.44  // decrypt_and_verify() - decrypt and/or verify a message
    8.45  //
    8.46  //    parameters:
    8.47 @@ -1270,6 +1300,10 @@
    8.48  //
    8.49  DYNAMIC_API const char* get_engine_version();
    8.50  
    8.51 +// get_protocol_version() - returns the pEp protocol version
    8.52 +
    8.53 +DYNAMIC_API const char *get_protocol_version();
    8.54 +
    8.55  // is_pEp_user() - returns true if the USER corresponding to this identity 
    8.56  //                 has been listed in the *person* table as a pEp user. 
    8.57  //
     9.1 --- a/src/pEp_internal.h	Thu May 16 14:15:12 2019 +0200
     9.2 +++ b/src/pEp_internal.h	Mon May 20 12:26:41 2019 +0200
     9.3 @@ -155,6 +155,8 @@
     9.4  #endif
     9.5  
     9.6      PEP_cryptotech_t *cryptotech;
     9.7 +    PEP_CIPHER_SUITE cipher_suite;
     9.8 +
     9.9      PEP_transport_t *transports;
    9.10  
    9.11      sqlite3 *db;
    10.1 --- a/src/pgp_gpg.c	Thu May 16 14:15:12 2019 +0200
    10.2 +++ b/src/pgp_gpg.c	Mon May 20 12:26:41 2019 +0200
    10.3 @@ -3116,3 +3116,17 @@
    10.4      }
    10.5      return status;
    10.6  }
    10.7 +
    10.8 +PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session,
    10.9 +        PEP_CIPHER_SUITE suite)
   10.10 +{
   10.11 +    // functionaliy unsupported; use gpg.conf
   10.12 +
   10.13 +    switch (suite) {
   10.14 +        case PEP_CIPHER_SUITE_DEFAULT:
   10.15 +            return PEP_STATUS_OK;
   10.16 +        default:
   10.17 +            return PEP_CANNOT_CONFIG;
   10.18 +    }
   10.19 +}
   10.20 +
    11.1 --- a/src/pgp_gpg.h	Thu May 16 14:15:12 2019 +0200
    11.2 +++ b/src/pgp_gpg.h	Mon May 20 12:26:41 2019 +0200
    11.3 @@ -28,7 +28,7 @@
    11.4  void pgp_release(PEP_SESSION session, bool out_last);
    11.5  
    11.6  
    11.7 -// pgp_decrypt_and_verify() - decrypt and verify cyphertext
    11.8 +// pgp_decrypt_and_verify() - decrypt and verify ciphertext
    11.9  //
   11.10  //  parameters:
   11.11  //      session (in)        session handle
   11.12 @@ -37,8 +37,8 @@
   11.13  //      dsigtext (in)       pointer to bytes with detached signature
   11.14  //                          or NULL if no detached signature
   11.15  //      dsigsize (in)       size of detached signature in bytes
   11.16 -//      ptext (out)         bytes with cyphertext
   11.17 -//      psize (out)         size of cyphertext in bytes
   11.18 +//      ptext (out)         bytes with ciphertext
   11.19 +//      psize (out)         size of ciphertext in bytes
   11.20  //      keylist (out)       list of keys being used; first is the key being
   11.21  //                          used for signing
   11.22  //	filename (out)	    PGP filename, when rendered (Optional, only necessary for some PGP implementations (e.g. Symantec),
   11.23 @@ -299,4 +299,7 @@
   11.24          const char* email
   11.25      );
   11.26  
   11.27 +PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session,
   11.28 +        PEP_CIPHER_SUITE suite);
   11.29 +
   11.30  #define PGP_BINARY_PATH pgp_binary
    12.1 --- a/src/pgp_netpgp.h	Thu May 16 14:15:12 2019 +0200
    12.2 +++ b/src/pgp_netpgp.h	Mon May 20 12:26:41 2019 +0200
    12.3 @@ -108,3 +108,11 @@
    12.4  
    12.5  // Stub - just returns PEP_STATUS_OK, as netpgp isn't sufficient to do this.
    12.6  PEP_STATUS pgp_import_ultimately_trusted_keypairs(PEP_SESSION session);
    12.7 +
    12.8 +PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session, PEP_CIPHER_SUITE suite) {
    12.9 +    if (suite == PEP_CIPHER_SUITE_DEFAULT) {
   12.10 +        return PEP_STATUS_OK;
   12.11 +    } else {
   12.12 +        return PEP_CANNOT_CONFIG;
   12.13 +    }
   12.14 +}
    13.1 --- a/src/pgp_sequoia.c	Thu May 16 14:15:12 2019 +0200
    13.2 +++ b/src/pgp_sequoia.c	Mon May 20 12:26:41 2019 +0200
    13.3 @@ -29,9 +29,18 @@
    13.4  // enable tracing if in debugging mode
    13.5  #if TRACING
    13.6  #include "status_to_string.h"
    13.7 -#  define _T(...) do {                          \
    13.8 +
    13.9 +#  ifdef ANDROID
   13.10 +#    include <android/log.h>
   13.11 +#    define _T(...) do {                                                \
   13.12 +        __android_log_print(ANDROID_LOG_DEBUG, "pEpEngine-sequoia",     \
   13.13 +                            ##__VA_ARGS__);                             \
   13.14 +    } while (0)
   13.15 +#  else
   13.16 +#    define _T(...) do {                        \
   13.17          fprintf(stderr, ##__VA_ARGS__);         \
   13.18      } while (0)
   13.19 +#  endif
   13.20  #else
   13.21  #  define _T(...) do { } while (0)
   13.22  #endif
   13.23 @@ -79,6 +88,52 @@
   13.24      }                                                               \
   13.25  } while(0)
   13.26  
   13.27 +PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session,
   13.28 +        PEP_CIPHER_SUITE suite)
   13.29 +{
   13.30 +    switch (suite) {
   13.31 +        // supported cipher suites
   13.32 +        case PEP_CIPHER_SUITE_RSA2K:
   13.33 +        case PEP_CIPHER_SUITE_RSA3K:
   13.34 +        case PEP_CIPHER_SUITE_CV25519:
   13.35 +        case PEP_CIPHER_SUITE_P256:
   13.36 +        case PEP_CIPHER_SUITE_P384:
   13.37 +        case PEP_CIPHER_SUITE_P521:
   13.38 +            session->cipher_suite = suite;
   13.39 +            return PEP_STATUS_OK;
   13.40 +
   13.41 +        case PEP_CIPHER_SUITE_DEFAULT:
   13.42 +            session->cipher_suite = PEP_CIPHER_SUITE_RSA2K;
   13.43 +            return PEP_STATUS_OK;
   13.44 +
   13.45 +        // unsupported cipher suites
   13.46 +        default:
   13.47 +            session->cipher_suite = PEP_CIPHER_SUITE_RSA2K;
   13.48 +            return PEP_CANNOT_CONFIG;
   13.49 +    }
   13.50 +}
   13.51 +
   13.52 +static pgp_tpk_cipher_suite_t cipher_suite(PEP_CIPHER_SUITE suite)
   13.53 +{
   13.54 +    switch (suite) {
   13.55 +        // supported cipher suites
   13.56 +        case PEP_CIPHER_SUITE_RSA2K:
   13.57 +            return PGP_TPK_CIPHER_SUITE_RSA2K;
   13.58 +        case PEP_CIPHER_SUITE_RSA3K:
   13.59 +            return PGP_TPK_CIPHER_SUITE_RSA3K;
   13.60 +        case PEP_CIPHER_SUITE_CV25519:
   13.61 +            return PGP_TPK_CIPHER_SUITE_CV25519;
   13.62 +        case PEP_CIPHER_SUITE_P256:
   13.63 +            return PGP_TPK_CIPHER_SUITE_P256;
   13.64 +        case PEP_CIPHER_SUITE_P384:
   13.65 +            return PGP_TPK_CIPHER_SUITE_P384;
   13.66 +        case PEP_CIPHER_SUITE_P521:
   13.67 +            return PGP_TPK_CIPHER_SUITE_P521;
   13.68 +        default:
   13.69 +            return PGP_TPK_CIPHER_SUITE_RSA2K;
   13.70 +    }
   13.71 +}
   13.72 +
   13.73  int email_cmp(void *cookie, int a_len, const void *a, int b_len, const void *b)
   13.74  {
   13.75      pgp_packet_t a_userid = pgp_user_id_from_raw (a, a_len);
   13.76 @@ -722,6 +777,49 @@
   13.77          pgp_packet_t userid = pgp_user_id_new (user_id_value);
   13.78          pgp_user_id_name(NULL, userid, &name);
   13.79          pgp_user_id_address(NULL, userid, &email);
   13.80 +                
   13.81 +        if (!email || email[0] == '\0') {
   13.82 +            size_t uid_value_len;
   13.83 +            const char* uid_value = (const char*)pgp_user_id_value(userid, &uid_value_len);
   13.84 +            if (!uid_value) {
   13.85 +                // We need some kind of an error here, maybe?
   13.86 +                 
   13.87 +            }
   13.88 +            else {
   13.89 +                const char* split = strstr(uid_value, "<");
   13.90 +                if (split != uid_value) {       
   13.91 +                    while (split) {
   13.92 +                        if (isspace(*(split - 1)))
   13.93 +                            break;
   13.94 +                        split = strstr(split + 1, "<");
   13.95 +                    }
   13.96 +                }
   13.97 +                if (split) {
   13.98 +                    char* stopchr = strrchr(split, '>');
   13.99 +                    if (stopchr) {
  13.100 +                        int email_len = stopchr - split - 1;
  13.101 +                        email = calloc(email_len + 1, 1); 
  13.102 +                        strlcpy(email, split + 1, email_len + 1);
  13.103 +                        const char* last = NULL;
  13.104 +                        if (split != uid_value) {
  13.105 +                            for (last = split - 1; last > uid_value; last--) {
  13.106 +                                if (!isspace(*last))
  13.107 +                                    break;
  13.108 +                            }
  13.109 +                            int name_len = (last - uid_value) + 1;
  13.110 +                            name = calloc(name_len + 1, 1);
  13.111 +                            strlcpy(name, uid_value, name_len + 1);
  13.112 +                        }
  13.113 +                    }
  13.114 +                    else  
  13.115 +                        split = NULL;
  13.116 +                }
  13.117 +                if (split == NULL) {
  13.118 +                    email = strdup(uid_value);
  13.119 +                }
  13.120 +            }
  13.121 +        }
  13.122 +        
  13.123          pgp_packet_free(userid);
  13.124          free(user_id_value);
  13.125  
  13.126 @@ -799,9 +897,17 @@
  13.127      stringlist_t *recipient_keylist;
  13.128      stringlist_t *signer_keylist;
  13.129      int good_checksums;
  13.130 +    int good_but_expired;
  13.131 +    int good_but_revoked;
  13.132      int missing_keys;
  13.133      int bad_checksums;
  13.134 +
  13.135 +    // Whether we decrypted anything.
  13.136      int decrypted;
  13.137 +
  13.138 +    // The filename stored in the literal data packet.  Note: this is
  13.139 +    // *not* protected by the signature and should not be trusted!!!
  13.140 +    char *filename;
  13.141  };
  13.142  
  13.143  static pgp_status_t
  13.144 @@ -1086,6 +1192,8 @@
  13.145                                            &tpk, NULL) != PEP_STATUS_OK)
  13.146                          ; // Soft error.  Ignore.
  13.147  
  13.148 +                    keyid_str = pgp_keyid_to_string (keyid);
  13.149 +
  13.150                      if (tpk) {
  13.151                          // Ok, we have a TPK.
  13.152  
  13.153 @@ -1095,27 +1203,79 @@
  13.154                              = pgp_tpk_fingerprint(tpk);
  13.155                          char *primary_fpr_str
  13.156                              = pgp_fingerprint_to_hex(primary_fpr);
  13.157 -                        stringlist_add_unique(cookie->signer_keylist,
  13.158 -                                              primary_fpr_str);
  13.159 -
  13.160 -                        T("Good signature from %s", primary_fpr_str);
  13.161 -
  13.162 -                        // XXX: Check that the TPK and the key used to make
  13.163 -                        // the signature and the signature itself are alive
  13.164 -                        // and not revoked.  Revoked =>
  13.165 -                        // PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH; Expired key
  13.166 -                        // or sig => PEP_DECRYPTED.
  13.167 -                        cookie->good_checksums ++;
  13.168 +
  13.169 +                        bool good = true;
  13.170 +
  13.171 +                        // Make sure the TPK is not revoked, it's
  13.172 +                        // creation time is <= now, and it hasn't
  13.173 +                        // expired.
  13.174 +                        pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
  13.175 +                        bool revoked = (pgp_revocation_status_variant(rs)
  13.176 +                                        == PGP_REVOCATION_STATUS_REVOKED);
  13.177 +                        pgp_revocation_status_free(rs);
  13.178 +                        if (revoked) {
  13.179 +                            T("TPK %s is revoked.", primary_fpr_str);
  13.180 +                            good = false;
  13.181 +                            cookie->good_but_revoked ++;
  13.182 +                        } else if (! pgp_tpk_alive(tpk)) {
  13.183 +                            T("TPK %s is not alive.", primary_fpr_str);
  13.184 +                            good = false;
  13.185 +                            cookie->good_but_expired ++;
  13.186 +                        }
  13.187 +
  13.188 +                        // Same thing for the signing key.
  13.189 +                        if (good) {
  13.190 +                            pgp_tpk_key_iter_t iter = pgp_tpk_key_iter_all(tpk);
  13.191 +                            pgp_key_t key;
  13.192 +                            pgp_signature_t sig;
  13.193 +                            while ((key = pgp_tpk_key_iter_next(iter, &sig, &rs))
  13.194 +                                   && good) {
  13.195 +                                pgp_keyid_t x = pgp_key_keyid(key);
  13.196 +                                if (pgp_keyid_equal(keyid, x)) {
  13.197 +                                    // Found the signing key.  Let's make
  13.198 +                                    // sure it is valid.
  13.199 +
  13.200 +                                    revoked = (pgp_revocation_status_variant(rs)
  13.201 +                                               == PGP_REVOCATION_STATUS_REVOKED);
  13.202 +                                    if (revoked) {
  13.203 +                                        T("TPK %s's signing key %s is revoked.",
  13.204 +                                          primary_fpr_str, keyid_str);
  13.205 +                                        good = false;
  13.206 +                                        cookie->good_but_revoked ++;
  13.207 +                                    } else if (! pgp_signature_key_alive(sig, key)) {
  13.208 +                                        T("TPK %s's signing key %s is expired.",
  13.209 +                                          primary_fpr_str, keyid_str);
  13.210 +                                        good = false;
  13.211 +                                        cookie->good_but_expired ++;
  13.212 +                                    }
  13.213 +                                }
  13.214 +                                pgp_keyid_free(x);
  13.215 +                                pgp_revocation_status_free(rs);
  13.216 +                                pgp_signature_free(sig);
  13.217 +                                pgp_key_free(key);
  13.218 +                            }
  13.219 +                            pgp_tpk_key_iter_free(iter);
  13.220 +                        }
  13.221 +
  13.222 +                        if (good) {
  13.223 +                            stringlist_add_unique(cookie->signer_keylist,
  13.224 +                                                  primary_fpr_str);
  13.225 +
  13.226 +                            T("Good signature from %s", primary_fpr_str);
  13.227 +
  13.228 +                            cookie->good_checksums ++;
  13.229 +                        }
  13.230  
  13.231                          free(primary_fpr_str);
  13.232                          pgp_fingerprint_free(primary_fpr);
  13.233                          pgp_tpk_free(tpk);
  13.234                      } else {
  13.235                          // If we get
  13.236 -                        // PGP_VERIFICATION_RESULT_CODE_GOOD_CHECKSUM, then the
  13.237 -                        // TPK should be available.  But, another process
  13.238 -                        // could have deleted the key from the store in the
  13.239 -                        // mean time, so be tolerant.
  13.240 +                        // PGP_VERIFICATION_RESULT_CODE_GOOD_CHECKSUM,
  13.241 +                        // then the TPK should be available.  But,
  13.242 +                        // another process could have deleted the key
  13.243 +                        // from the store in the mean time, so be
  13.244 +                        // tolerant.
  13.245                          T("Key to check signature from %s disappeared",
  13.246                            keyid_str);
  13.247                          cookie->missing_keys ++;
  13.248 @@ -1169,6 +1329,29 @@
  13.249      return PGP_STATUS_SUCCESS;
  13.250  }
  13.251  
  13.252 +static pgp_status_t inspect_cb(
  13.253 +    void *cookie_opaque, pgp_packet_parser_t pp)
  13.254 +{
  13.255 +    struct decrypt_cookie *cookie = cookie_opaque;
  13.256 +
  13.257 +    pgp_packet_t packet = pgp_packet_parser_packet(pp);
  13.258 +    assert(packet);
  13.259 +
  13.260 +    pgp_tag_t tag = pgp_packet_tag(packet);
  13.261 +
  13.262 +    T("%s", pgp_tag_to_string(tag));
  13.263 +
  13.264 +    if (tag == PGP_TAG_LITERAL) {
  13.265 +        pgp_literal_t literal = pgp_packet_ref_literal(packet);
  13.266 +        cookie->filename = pgp_literal_filename(literal);
  13.267 +        pgp_literal_free(literal);
  13.268 +    }
  13.269 +
  13.270 +    pgp_packet_free(packet);
  13.271 +
  13.272 +    return 0;
  13.273 +}
  13.274 +
  13.275  PEP_STATUS pgp_decrypt_and_verify(
  13.276      PEP_SESSION session, const char *ctext, size_t csize,
  13.277      const char *dsigtext, size_t dsigsize,
  13.278 @@ -1176,7 +1359,7 @@
  13.279      char** filename_ptr)
  13.280  {
  13.281      PEP_STATUS status = PEP_STATUS_OK;
  13.282 -    struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, };
  13.283 +    struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL };
  13.284      pgp_reader_t reader = NULL;
  13.285      pgp_writer_t writer = NULL;
  13.286      pgp_reader_t decryptor = NULL;
  13.287 @@ -1206,7 +1389,8 @@
  13.288      pgp_error_t err = NULL;
  13.289      decryptor = pgp_decryptor_new(&err, reader,
  13.290                                    get_public_keys_cb, decrypt_cb,
  13.291 -                                  check_signatures_cb, &cookie, 0);
  13.292 +                                  check_signatures_cb, inspect_cb,
  13.293 +                                  &cookie, 0);
  13.294      if (! decryptor)
  13.295          ERROR_OUT(err, PEP_DECRYPT_NO_KEY, "pgp_decryptor_new");
  13.296  
  13.297 @@ -1235,15 +1419,28 @@
  13.298      *keylist = cookie.signer_keylist;
  13.299      stringlist_append(*keylist, cookie.recipient_keylist);
  13.300  
  13.301 +    if (filename_ptr)
  13.302 +        *filename_ptr = cookie.filename;
  13.303 +
  13.304   out:
  13.305      if (status == PEP_STATUS_OK) {
  13.306 -        if (cookie.bad_checksums) {
  13.307 -            // If there are any bad signatures, fail.
  13.308 -            status = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  13.309 -        } else if (cookie.good_checksums) {
  13.310 +        // **********************************
  13.311 +        // Sync changes with pgp_verify_text.
  13.312 +        // **********************************
  13.313 +
  13.314 +        if (cookie.good_checksums) {
  13.315              // If there is at least one signature that we can verify,
  13.316              // succeed.
  13.317              status = PEP_DECRYPTED_AND_VERIFIED;
  13.318 +        } else if (cookie.good_but_revoked) {
  13.319 +            // If there are any signatures from revoked keys, fail.
  13.320 +            status = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  13.321 +        } else if (cookie.bad_checksums) {
  13.322 +            // If there are any bad signatures, fail.
  13.323 +            status = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  13.324 +        } else if (cookie.good_but_expired) {
  13.325 +            // If there are any signatures from expired keys, fail.
  13.326 +            status = PEP_DECRYPTED;
  13.327          } else {
  13.328              // We couldn't verify any signatures (possibly because we
  13.329              // don't have the keys).
  13.330 @@ -1252,6 +1449,7 @@
  13.331      } else {
  13.332          free_stringlist(cookie.recipient_keylist);
  13.333          free_stringlist(cookie.signer_keylist);
  13.334 +        free(cookie.filename);
  13.335          free(*ptext);
  13.336      }
  13.337  
  13.338 @@ -1327,7 +1525,17 @@
  13.339  
  13.340   out:
  13.341      if (status == PEP_STATUS_OK) {
  13.342 -        if (cookie.bad_checksums) {
  13.343 +        // *****************************************
  13.344 +        // Sync changes with pgp_decrypt_and_verify.
  13.345 +        // *****************************************
  13.346 +
  13.347 +        if (cookie.good_but_expired) {
  13.348 +            // If there are any signatures from expired keys, fail.
  13.349 +            status = PEP_UNENCRYPTED;
  13.350 +        } else if (cookie.good_but_revoked) {
  13.351 +            // If there are any signatures from revoked keys, fail.
  13.352 +            status = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  13.353 +        } else if (cookie.bad_checksums) {
  13.354              // If there are any bad signatures, fail.
  13.355              status = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
  13.356          } else if (cookie.good_checksums) {
  13.357 @@ -1616,8 +1824,8 @@
  13.358      T("(%s)", userid);
  13.359  
  13.360      // Generate a key.
  13.361 -    pgp_tpk_builder_t tpkb = pgp_tpk_builder_general_purpose
  13.362 -        (PGP_TPK_CIPHER_SUITE_RSA3K, userid);
  13.363 +    pgp_tpk_builder_t tpkb = pgp_tpk_builder_general_purpose(
  13.364 +        cipher_suite(session->cipher_suite), userid);
  13.365      pgp_signature_t rev;
  13.366      if (pgp_tpk_builder_generate(&err, tpkb, &tpk, &rev))
  13.367          ERROR_OUT(err, PEP_CANNOT_CREATE_KEY, "Generating a key pair");
  13.368 @@ -1686,7 +1894,6 @@
  13.369      return PEP_STATUS_OK;
  13.370  }
  13.371  
  13.372 -// XXX: This also needs to handle revocation certificates.
  13.373  PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data,
  13.374                                size_t size, identity_list **private_idents)
  13.375  {
  13.376 @@ -2431,3 +2638,4 @@
  13.377        fpr, *has_private ? "priv" : "pub", pEp_status_to_string(status));
  13.378      return status;
  13.379  }
  13.380 +
    14.1 --- a/src/pgp_sequoia.h	Thu May 16 14:15:12 2019 +0200
    14.2 +++ b/src/pgp_sequoia.h	Mon May 20 12:26:41 2019 +0200
    14.3 @@ -112,4 +112,7 @@
    14.4  
    14.5  PEP_STATUS pgp_binary(const char **path);
    14.6  
    14.7 +PEP_STATUS pgp_config_cipher_suite(PEP_SESSION session,
    14.8 +        PEP_CIPHER_SUITE suite);
    14.9 +
   14.10  #define PGP_BINARY_PATH pgp_binary
    15.1 --- a/sync/cond_act_sync.yml2	Thu May 16 14:15:12 2019 +0200
    15.2 +++ b/sync/cond_act_sync.yml2	Mon May 20 12:26:41 2019 +0200
    15.3 @@ -273,6 +273,15 @@
    15.4              }
    15.5          }
    15.6  
    15.7 +        free(partner->user_id);
    15.8 +        partner->user_id = strdup("#NV");
    15.9 +        assert(partner->user_id);
   15.10 +        if (!partner->user_id) {
   15.11 +            free_identity(me);
   15.12 +            free_identity(partner);
   15.13 +            return PEP_OUT_OF_MEMORY;
   15.14 +        }
   15.15 +
   15.16          status = session->notifyHandshake(me, partner, «$type»);
   15.17          if (status)
   15.18              return status;
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/test/include/LiteralFilenameTests.h	Mon May 20 12:26:41 2019 +0200
    16.3 @@ -0,0 +1,19 @@
    16.4 +// This file is under GNU General Public License 3.0
    16.5 +// see LICENSE.txt
    16.6 +
    16.7 +#ifndef LITERAL_FILENAME_H
    16.8 +#define LITERAL_FILENAME_H
    16.9 +
   16.10 +#include <string>
   16.11 +#include "EngineTestIndividualSuite.h"
   16.12 +
   16.13 +using namespace std;
   16.14 +
   16.15 +class LiteralFilenameTests : public EngineTestIndividualSuite {
   16.16 +    public:
   16.17 +        LiteralFilenameTests(string test_suite, string test_home_dir);
   16.18 +    private:
   16.19 +        void check();
   16.20 +};
   16.21 +
   16.22 +#endif
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/test/include/URIAddressTests.h	Mon May 20 12:26:41 2019 +0200
    17.3 @@ -0,0 +1,20 @@
    17.4 +// This file is under GNU General Public License 3.0
    17.5 +// see LICENSE.txt
    17.6 +
    17.7 +#ifndef U_R_I_ADDRESS_H
    17.8 +#define U_R_I_ADDRESS_H
    17.9 +
   17.10 +#include <string>
   17.11 +#include "EngineTestIndividualSuite.h"
   17.12 +
   17.13 +using namespace std;
   17.14 +
   17.15 +class URIAddressTests : public EngineTestIndividualSuite {
   17.16 +    public:
   17.17 +        URIAddressTests(string test_suite, string test_home_dir);
   17.18 +    private:
   17.19 +        void check_uri_address_genkey();
   17.20 +        void check_uri_address_encrypt();        
   17.21 +};
   17.22 +
   17.23 +#endif
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/test/include/VerifyTests.h	Mon May 20 12:26:41 2019 +0200
    18.3 @@ -0,0 +1,23 @@
    18.4 +// This file is under GNU General Public License 3.0
    18.5 +// see LICENSE.txt
    18.6 +
    18.7 +#ifndef VERIFY_H
    18.8 +#define VERIFY_H
    18.9 +
   18.10 +#include <string>
   18.11 +#include "EngineTestIndividualSuite.h"
   18.12 +
   18.13 +using namespace std;
   18.14 +
   18.15 +class VerifyTests : public EngineTestIndividualSuite {
   18.16 +    public:
   18.17 +        VerifyTests(string test_suite, string test_home_dir);
   18.18 +    private:
   18.19 +        static constexpr const char *mary_fpr = "599B3D67800DB37E2DCE05C07F59F03CD04A226E";
   18.20 +        void check_revoked_tpk();
   18.21 +        void check_revoked_signing_key();
   18.22 +        void check_expired_tpk();
   18.23 +        void check_expired_signing_key();
   18.24 +};
   18.25 +
   18.26 +#endif
    19.1 --- a/test/src/SuiteMaker.cc	Thu May 16 14:15:12 2019 +0200
    19.2 +++ b/test/src/SuiteMaker.cc	Mon May 20 12:26:41 2019 +0200
    19.3 @@ -12,14 +12,17 @@
    19.4  #include "SuiteMaker.h"
    19.5  
    19.6  // Begin where we generate stuff
    19.7 +#include "URIAddressTests.h"
    19.8  #include "MimeTests.h"
    19.9  #include "OwnIdentitiesRetrieveTests.h"
   19.10  #include "ExpiredSubkeyTests.h"
   19.11 +#include "VerifyTests.h"
   19.12  #include "UserIdCollisionTests.h"
   19.13  #include "Engine463Tests.h"
   19.14  #include "BloblistTests.h"
   19.15  #include "NewUpdateIdAndMyselfTests.h"
   19.16  #include "NoOwnIdentWritesOnDecryptTests.h"
   19.17 +#include "LiteralFilenameTests.h"
   19.18  #include "I18nTests.h"
   19.19  #include "IdentityListTests.h"
   19.20  #include "PgpBinaryTests.h"
   19.21 @@ -72,14 +75,17 @@
   19.22  
   19.23  
   19.24  const char* SuiteMaker::all_suites[] = {
   19.25 +    "URIAddressTests",
   19.26      "MimeTests",
   19.27      "OwnIdentitiesRetrieveTests",
   19.28      "ExpiredSubkeyTests",
   19.29 +    "VerifyTests",
   19.30      "UserIdCollisionTests",
   19.31      "Engine463Tests",
   19.32      "BloblistTests",
   19.33      "NewUpdateIdAndMyselfTests",
   19.34      "NoOwnIdentWritesOnDecryptTests",
   19.35 +    "LiteralFilenameTests",
   19.36      "I18nTests",
   19.37      "IdentityListTests",
   19.38      "PgpBinaryTests",
   19.39 @@ -132,15 +138,19 @@
   19.40  };
   19.41  
   19.42  // This file is generated, so magic constants are ok.
   19.43 -int SuiteMaker::num_suites = 57;
   19.44 +int SuiteMaker::num_suites = 60;
   19.45  
   19.46  void SuiteMaker::suitemaker_build(const char* test_class_name, const char* test_home, Test::Suite** test_suite) {
   19.47 -    if (strcmp(test_class_name, "MimeTests") == 0)
   19.48 +    if (strcmp(test_class_name, "URIAddressTests") == 0)
   19.49 +        *test_suite = new URIAddressTests(test_class_name, test_home);
   19.50 +    else if (strcmp(test_class_name, "MimeTests") == 0)
   19.51          *test_suite = new MimeTests(test_class_name, test_home);
   19.52      else if (strcmp(test_class_name, "OwnIdentitiesRetrieveTests") == 0)
   19.53          *test_suite = new OwnIdentitiesRetrieveTests(test_class_name, test_home);
   19.54      else if (strcmp(test_class_name, "ExpiredSubkeyTests") == 0)
   19.55          *test_suite = new ExpiredSubkeyTests(test_class_name, test_home);
   19.56 +    else if (strcmp(test_class_name, "VerifyTests") == 0)
   19.57 +        *test_suite = new VerifyTests(test_class_name, test_home);
   19.58      else if (strcmp(test_class_name, "UserIdCollisionTests") == 0)
   19.59          *test_suite = new UserIdCollisionTests(test_class_name, test_home);
   19.60      else if (strcmp(test_class_name, "Engine463Tests") == 0)
   19.61 @@ -151,6 +161,8 @@
   19.62          *test_suite = new NewUpdateIdAndMyselfTests(test_class_name, test_home);
   19.63      else if (strcmp(test_class_name, "NoOwnIdentWritesOnDecryptTests") == 0)
   19.64          *test_suite = new NoOwnIdentWritesOnDecryptTests(test_class_name, test_home);
   19.65 +    else if (strcmp(test_class_name, "LiteralFilenameTests") == 0)
   19.66 +        *test_suite = new LiteralFilenameTests(test_class_name, test_home);
   19.67      else if (strcmp(test_class_name, "I18nTests") == 0)
   19.68          *test_suite = new I18nTests(test_class_name, test_home);
   19.69      else if (strcmp(test_class_name, "IdentityListTests") == 0)
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/test/src/engine_tests/LiteralFilenameTests.cc	Mon May 20 12:26:41 2019 +0200
    20.3 @@ -0,0 +1,44 @@
    20.4 +// This file is under GNU General Public License 3.0
    20.5 +// see LICENSE.txt
    20.6 +
    20.7 +#include <stdlib.h>
    20.8 +#include <string>
    20.9 +#include <cstring>
   20.10 +#include <cpptest.h>
   20.11 +#include <fstream>
   20.12 +
   20.13 +#include "pEpEngine.h"
   20.14 +
   20.15 +#include "test_util.h"
   20.16 +#include "EngineTestIndividualSuite.h"
   20.17 +#include "LiteralFilenameTests.h"
   20.18 +
   20.19 +using namespace std;
   20.20 +
   20.21 +LiteralFilenameTests::LiteralFilenameTests(string suitename, string test_home_dir) :
   20.22 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   20.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("LiteralFilenameTests::check"),
   20.24 +                                                                      static_cast<Func>(&LiteralFilenameTests::check)));
   20.25 +}
   20.26 +
   20.27 +void LiteralFilenameTests::check() {
   20.28 +    slurp_and_import_key(session, "test_keys/priv/pep-test-lisa-0xBA0997C1514E70EB_priv.asc");
   20.29 +
   20.30 +    string ciphertext = slurp("test_files/literal-packet-with-filename.pgp");
   20.31 +
   20.32 +    // Decrypt and verify it.
   20.33 +    char *plaintext = NULL;
   20.34 +    size_t plaintext_size = 0;
   20.35 +    stringlist_t *keylist = NULL;
   20.36 +    char *filename = NULL;
   20.37 +    PEP_STATUS status = decrypt_and_verify(session,
   20.38 +                                           ciphertext.c_str(),
   20.39 +                                           ciphertext.size(),
   20.40 +                                           NULL, 0,
   20.41 +                                           &plaintext, &plaintext_size,
   20.42 +                                           &keylist, &filename);
   20.43 +
   20.44 +    TEST_ASSERT_MSG(status == PEP_DECRYPTED_AND_VERIFIED, tl_status_string(status));
   20.45 +    TEST_ASSERT_MSG(filename, "filename");
   20.46 +    TEST_ASSERT_MSG((strcmp(filename, "filename.txt") == 0), "strcmp(filename, \"filename.txt\") == 0");
   20.47 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/test/src/engine_tests/URIAddressTests.cc	Mon May 20 12:26:41 2019 +0200
    21.3 @@ -0,0 +1,85 @@
    21.4 +// This file is under GNU General Public License 3.0
    21.5 +// see LICENSE.txt
    21.6 +
    21.7 +#include <stdlib.h>
    21.8 +#include <cstring>
    21.9 +#include <string>
   21.10 +
   21.11 +#include <cpptest.h>
   21.12 +#include "test_util.h"
   21.13 +
   21.14 +#include "pEpEngine.h"
   21.15 +
   21.16 +#include "EngineTestIndividualSuite.h"
   21.17 +#include "URIAddressTests.h"
   21.18 +
   21.19 +using namespace std;
   21.20 +
   21.21 +URIAddressTests::URIAddressTests(string suitename, string test_home_dir) :
   21.22 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   21.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("URIAddressTests::check_uri_address_genkey"),
   21.24 +                                                                      static_cast<Func>(&URIAddressTests::check_uri_address_genkey)));
   21.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("URIAddressTests::check_uri_address_encrypt"),
   21.26 +                                                                      static_cast<Func>(&URIAddressTests::check_uri_address_encrypt)));
   21.27 +}
   21.28 +
   21.29 +// FIXME: URL, URN
   21.30 +void URIAddressTests::check_uri_address_genkey() {
   21.31 +    const char* uri_addr = "shark://grrrr/39874293847092837443987492834";
   21.32 +    const char* uname = "GRRRR, the angry shark";
   21.33 +    
   21.34 +    pEp_identity* me = new_identity(uri_addr, NULL, PEP_OWN_USERID, uname);
   21.35 +    
   21.36 +    PEP_STATUS status = myself(session, me);
   21.37 +    
   21.38 +    TEST_ASSERT(status == PEP_STATUS_OK);
   21.39 +    TEST_ASSERT(me->fpr && me->fpr[0] != '\0');
   21.40 +    
   21.41 +    char* keydata = NULL;
   21.42 +    size_t keysize = 0;
   21.43 +    status = export_key(session, me->fpr, 
   21.44 +                        &keydata, &keysize);
   21.45 +
   21.46 +    cout << keydata << endl;
   21.47 +
   21.48 +    free(keydata);
   21.49 +    free_identity(me);
   21.50 +}
   21.51 +
   21.52 +// FIXME: URL, URN
   21.53 +void URIAddressTests::check_uri_address_encrypt() {
   21.54 +    const char* uri_addr = "shark://grrrr/39874293847092837443987492834";
   21.55 +    const char* uname = "GRRRR, the angry shark";
   21.56 +    
   21.57 +    pEp_identity* me = new_identity(uri_addr, NULL, PEP_OWN_USERID, uname);
   21.58 +    
   21.59 +    PEP_STATUS status = myself(session, me);
   21.60 +    
   21.61 +    TEST_ASSERT(status == PEP_STATUS_OK);
   21.62 +    TEST_ASSERT(me->fpr && me->fpr[0] != '\0');
   21.63 +    
   21.64 +    const char* you_uri_addr = "shark://bait/8uyoi3lu4hl2..dfoif983j4b@%";
   21.65 +    const char* youname = "Nemo, the delicious fish";
   21.66 +    pEp_identity* you = new_identity(you_uri_addr, NULL, "Food for Shark", youname);
   21.67 +    status = generate_keypair(session, you);
   21.68 +    TEST_ASSERT(status == PEP_STATUS_OK);
   21.69 +
   21.70 +    stringlist_t* keylist = NULL;
   21.71 +    status = find_keys(session, you_uri_addr, &keylist);
   21.72 +    TEST_ASSERT(status == PEP_STATUS_OK);    
   21.73 +    TEST_ASSERT(keylist && keylist->value);
   21.74 +
   21.75 +    status = update_identity(session, you);
   21.76 +    TEST_ASSERT(status == PEP_STATUS_OK);
   21.77 +    TEST_ASSERT(you->fpr && you->fpr[0] != '\0');
   21.78 +    
   21.79 +    message* msg = new_message(PEP_dir_outgoing);
   21.80 +    
   21.81 +    msg->from = me;
   21.82 +    msg->to = new_identity_list(you);
   21.83 +    msg->shortmsg = strdup("Invitation");
   21.84 +    msg->longmsg = strdup("Yo Neems, wanna come over for dinner?");
   21.85 +
   21.86 +    message* enc_msg = NULL;
   21.87 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   21.88 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/test/src/engine_tests/VerifyTests.cc	Mon May 20 12:26:41 2019 +0200
    22.3 @@ -0,0 +1,248 @@
    22.4 +// This file is under GNU General Public License 3.0
    22.5 +// see LICENSE.txt
    22.6 +
    22.7 +#include <stdlib.h>
    22.8 +#include <string>
    22.9 +#include <cstring>
   22.10 +#include <cpptest.h>
   22.11 +#include <fstream>
   22.12 +
   22.13 +#include "pEpEngine.h"
   22.14 +
   22.15 +#include "test_util.h"
   22.16 +#include "EngineTestIndividualSuite.h"
   22.17 +#include "VerifyTests.h"
   22.18 +
   22.19 +using namespace std;
   22.20 +
   22.21 +VerifyTests::VerifyTests(string suitename, string test_home_dir) :
   22.22 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   22.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("VerifyTests::check_revoked_tpk"),
   22.24 +                                                                      static_cast<Func>(&VerifyTests::check_revoked_tpk)));
   22.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("VerifyTests::check_revoked_signing_key"),
   22.26 +                                                                      static_cast<Func>(&VerifyTests::check_revoked_signing_key)));
   22.27 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("VerifyTests::check_expired_tpk"),
   22.28 +                                                                      static_cast<Func>(&VerifyTests::check_expired_tpk)));
   22.29 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("VerifyTests::check_expired_signing_key"),
   22.30 +                                                                      static_cast<Func>(&VerifyTests::check_expired_signing_key)));
   22.31 +}
   22.32 +
   22.33 +void VerifyTests::check_revoked_tpk() {
   22.34 +    slurp_and_import_key(session, "test_keys/priv/pep-test-mary-0x7F59F03CD04A226E_priv.asc");
   22.35 +
   22.36 +    string ciphertext = slurp("test_files/pep-test-mary-signed-encrypted-to-self.asc");
   22.37 +
   22.38 +    // Decrypt and verify it.
   22.39 +    char *plaintext = NULL;
   22.40 +    size_t plaintext_size = 0;
   22.41 +    stringlist_t *keylist = NULL;
   22.42 +    PEP_STATUS status = decrypt_and_verify(session,
   22.43 +                                           ciphertext.c_str(),
   22.44 +                                           ciphertext.size(),
   22.45 +                                           NULL, 0,
   22.46 +                                           &plaintext, &plaintext_size,
   22.47 +                                           &keylist, NULL);
   22.48 +
   22.49 +    TEST_ASSERT_MSG(status == PEP_DECRYPTED_AND_VERIFIED, tl_status_string(status));
   22.50 +    TEST_ASSERT(keylist);
   22.51 +    // Signer is mary.
   22.52 +    TEST_ASSERT(keylist->value);
   22.53 +    cout << "fpr: " << mary_fpr << "; got: " << keylist->value << endl;
   22.54 +    TEST_ASSERT(strcmp(mary_fpr, keylist->value) == 0);
   22.55 +    // Recipient is mary.
   22.56 +    TEST_ASSERT(keylist->next);
   22.57 +    TEST_ASSERT(keylist->next->value);
   22.58 +    TEST_ASSERT(strcmp(mary_fpr, keylist->next->value) == 0);
   22.59 +    // Content is returned.
   22.60 +    TEST_ASSERT(strcmp(plaintext, "tu was!\n") == 0);
   22.61 +
   22.62 +    // Import the revocation certificate.
   22.63 +    slurp_and_import_key(session, "test_keys/priv/pep-test-mary-0x7F59F03CD04A226E.rev");
   22.64 +
   22.65 +    plaintext = NULL;
   22.66 +    plaintext_size = 0;
   22.67 +    keylist = NULL;
   22.68 +    status = decrypt_and_verify(session,
   22.69 +                                ciphertext.c_str(), ciphertext.size(),
   22.70 +                                NULL, 0,
   22.71 +                                &plaintext, &plaintext_size,
   22.72 +                                &keylist, NULL);
   22.73 +
   22.74 +    // Now it should fail.
   22.75 +    TEST_ASSERT_MSG(status == PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH, tl_status_string(status));
   22.76 +    TEST_ASSERT(keylist);
   22.77 +    // No signer.
   22.78 +    TEST_ASSERT(strcmp(keylist->value, "") == 0);
   22.79 +    // Recipient is mary.
   22.80 +    TEST_ASSERT(keylist->next);
   22.81 +    TEST_ASSERT(keylist->next->value);
   22.82 +    TEST_ASSERT(strcmp(mary_fpr, keylist->next->value) == 0);
   22.83 +    // Content is returned.
   22.84 +    TEST_ASSERT(strcmp(plaintext, "tu was!\n") == 0);
   22.85 +
   22.86 +
   22.87 +    string text = slurp("test_files/pep-test-mary-signed.txt");
   22.88 +    string sig = slurp("test_files/pep-test-mary-signed.txt.sig");
   22.89 +
   22.90 +    plaintext = NULL;
   22.91 +    plaintext_size = 0;
   22.92 +    keylist = NULL;
   22.93 +    status = verify_text(session,
   22.94 +                         text.c_str(), text.size(),
   22.95 +                         sig.c_str(), sig.size(),
   22.96 +                         &keylist);
   22.97 +
   22.98 +    // Now it should fail.
   22.99 +    TEST_ASSERT_MSG(status == PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH, tl_status_string(status));
  22.100 +    TEST_ASSERT(keylist);
  22.101 +    // No signer.
  22.102 +    TEST_ASSERT(strcmp(keylist->value, "") == 0);
  22.103 +    TEST_ASSERT(! keylist->next);
  22.104 +}
  22.105 +
  22.106 +void VerifyTests::check_revoked_signing_key() {
  22.107 +    slurp_and_import_key(session, "test_keys/priv/pep-test-mary-0x7F59F03CD04A226E_priv.asc");
  22.108 +    slurp_and_import_key(session, "test_keys/pub/pep-test-mary-0x7F59F03CD04A226E_revoked_sig_key.asc");
  22.109 +
  22.110 +    string ciphertext = slurp("test_files/pep-test-mary-signed-encrypted-to-self.asc");
  22.111 +
  22.112 +    // Decrypt and verify it.
  22.113 +    char *plaintext = NULL;
  22.114 +    size_t plaintext_size = 0;
  22.115 +    stringlist_t *keylist = NULL;
  22.116 +    PEP_STATUS status = decrypt_and_verify(session,
  22.117 +                                           ciphertext.c_str(),
  22.118 +                                           ciphertext.size(),
  22.119 +                                           NULL, 0,
  22.120 +                                           &plaintext, &plaintext_size,
  22.121 +                                           &keylist, NULL);
  22.122 +
  22.123 +    // It should fail.
  22.124 +    TEST_ASSERT_MSG(status == PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH, tl_status_string(status));
  22.125 +    TEST_ASSERT(keylist);
  22.126 +    // No signer.
  22.127 +    TEST_ASSERT(strcmp(keylist->value, "") == 0);
  22.128 +    // Recipient is mary.
  22.129 +    TEST_ASSERT(keylist->next);
  22.130 +    TEST_ASSERT(keylist->next->value);
  22.131 +    TEST_ASSERT(strcmp(mary_fpr, keylist->next->value) == 0);
  22.132 +    // Content is returned.
  22.133 +    TEST_ASSERT(strcmp(plaintext, "tu was!\n") == 0);
  22.134 +
  22.135 +
  22.136 +    string text = slurp("test_files/pep-test-mary-signed.txt");
  22.137 +    string sig = slurp("test_files/pep-test-mary-signed.txt.sig");
  22.138 +
  22.139 +    plaintext = NULL;
  22.140 +    plaintext_size = 0;
  22.141 +    keylist = NULL;
  22.142 +    status = verify_text(session,
  22.143 +                         text.c_str(), text.size(),
  22.144 +                         sig.c_str(), sig.size(),
  22.145 +                         &keylist);
  22.146 +
  22.147 +    // Now it should fail.
  22.148 +    TEST_ASSERT_MSG(status == PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH, tl_status_string(status));
  22.149 +    TEST_ASSERT(keylist);
  22.150 +    // No signer.
  22.151 +    TEST_ASSERT(strcmp(keylist->value, "") == 0);
  22.152 +    TEST_ASSERT(! keylist->next);
  22.153 +}
  22.154 +
  22.155 +void VerifyTests::check_expired_tpk() {
  22.156 +    slurp_and_import_key(session, "test_keys/priv/pep-test-mary-0x7F59F03CD04A226E_priv.asc");
  22.157 +    slurp_and_import_key(session, "test_keys/pub/pep-test-mary-0x7F59F03CD04A226E_expired_pub.asc");
  22.158 +
  22.159 +    string ciphertext = slurp("test_files/pep-test-mary-signed-encrypted-to-self.asc");
  22.160 +
  22.161 +    // Decrypt and verify it.
  22.162 +    char *plaintext = NULL;
  22.163 +    size_t plaintext_size = 0;
  22.164 +    stringlist_t *keylist = NULL;
  22.165 +    PEP_STATUS status = decrypt_and_verify(session,
  22.166 +                                           ciphertext.c_str(),
  22.167 +                                           ciphertext.size(),
  22.168 +                                           NULL, 0,
  22.169 +                                           &plaintext, &plaintext_size,
  22.170 +                                           &keylist, NULL);
  22.171 +
  22.172 +    // It should fail.
  22.173 +    TEST_ASSERT_MSG(status == PEP_DECRYPTED, tl_status_string(status));
  22.174 +    TEST_ASSERT(keylist);
  22.175 +    // No signer.
  22.176 +    TEST_ASSERT(strcmp(keylist->value, "") == 0);
  22.177 +    // Recipient is mary.
  22.178 +    TEST_ASSERT(keylist->next);
  22.179 +    TEST_ASSERT(keylist->next->value);
  22.180 +    TEST_ASSERT(strcmp(mary_fpr, keylist->next->value) == 0);
  22.181 +    // Content is returned.
  22.182 +    TEST_ASSERT(strcmp(plaintext, "tu was!\n") == 0);
  22.183 +
  22.184 +
  22.185 +    string text = slurp("test_files/pep-test-mary-signed.txt");
  22.186 +    string sig = slurp("test_files/pep-test-mary-signed.txt.sig");
  22.187 +
  22.188 +    plaintext = NULL;
  22.189 +    plaintext_size = 0;
  22.190 +    keylist = NULL;
  22.191 +    status = verify_text(session,
  22.192 +                         text.c_str(), text.size(),
  22.193 +                         sig.c_str(), sig.size(),
  22.194 +                         &keylist);
  22.195 +
  22.196 +    // Now it should fail.
  22.197 +    TEST_ASSERT_MSG(status == PEP_UNENCRYPTED, tl_status_string(status));
  22.198 +    TEST_ASSERT(keylist);
  22.199 +    // No signer.
  22.200 +    TEST_ASSERT(strcmp(keylist->value, "") == 0);
  22.201 +    TEST_ASSERT(! keylist->next);
  22.202 +}
  22.203 +
  22.204 +void VerifyTests::check_expired_signing_key() {
  22.205 +    slurp_and_import_key(session, "test_keys/priv/pep-test-mary-0x7F59F03CD04A226E_priv.asc");
  22.206 +    slurp_and_import_key(session, "test_keys/pub/pep-test-mary-0x7F59F03CD04A226E_expired_sig_key.asc");
  22.207 +
  22.208 +    string ciphertext = slurp("test_files/pep-test-mary-signed-encrypted-to-self.asc");
  22.209 +
  22.210 +    // Decrypt and verify it.
  22.211 +    char *plaintext = NULL;
  22.212 +    size_t plaintext_size = 0;
  22.213 +    stringlist_t *keylist = NULL;
  22.214 +    PEP_STATUS status = decrypt_and_verify(session,
  22.215 +                                           ciphertext.c_str(),
  22.216 +                                           ciphertext.size(),
  22.217 +                                           NULL, 0,
  22.218 +                                           &plaintext, &plaintext_size,
  22.219 +                                           &keylist, NULL);
  22.220 +
  22.221 +    // It should fail.
  22.222 +    TEST_ASSERT_MSG(status == PEP_DECRYPTED, tl_status_string(status));
  22.223 +    TEST_ASSERT(keylist);
  22.224 +    // No signer.
  22.225 +    TEST_ASSERT(strcmp(keylist->value, "") == 0);
  22.226 +    // Recipient is mary.
  22.227 +    TEST_ASSERT(keylist->next);
  22.228 +    TEST_ASSERT(keylist->next->value);
  22.229 +    TEST_ASSERT(strcmp(mary_fpr, keylist->next->value) == 0);
  22.230 +    // Content is returned.
  22.231 +    TEST_ASSERT(strcmp(plaintext, "tu was!\n") == 0);
  22.232 +
  22.233 +
  22.234 +    string text = slurp("test_files/pep-test-mary-signed.txt");
  22.235 +    string sig = slurp("test_files/pep-test-mary-signed.txt.sig");
  22.236 +
  22.237 +    plaintext = NULL;
  22.238 +    plaintext_size = 0;
  22.239 +    keylist = NULL;
  22.240 +    status = verify_text(session,
  22.241 +                         text.c_str(), text.size(),
  22.242 +                         sig.c_str(), sig.size(),
  22.243 +                         &keylist);
  22.244 +
  22.245 +    // Now it should fail.
  22.246 +    TEST_ASSERT_MSG(status == PEP_UNENCRYPTED, tl_status_string(status));
  22.247 +    TEST_ASSERT(keylist);
  22.248 +    // No signer.
  22.249 +    TEST_ASSERT(strcmp(keylist->value, "") == 0);
  22.250 +    TEST_ASSERT(! keylist->next);
  22.251 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/test/test_files/literal-packet-with-filename.pgp	Mon May 20 12:26:41 2019 +0200
    23.3 @@ -0,0 +1,25 @@
    23.4 +-----BEGIN PGP MESSAGE-----
    23.5 +
    23.6 +wcDMA9wGqgE3hB2PAQv/Z9pFeIVERgTJJqSY0pWiGdbknsSjkTrkhJVPkMZ0LEJ7
    23.7 +A+sj0tXxRtFpEk2U4TLpoN3zlYsD0+ATTqVMGP7WKRm/EyuP40j6jWoGtxU4E3Vh
    23.8 +BL2+fLkqx5i+MV3JDNwILPb+ZQU1qRWn2Ocvu3akTiC7AwApX5GW2x1WmUbhkHjI
    23.9 +Ynwp+VDkdteL/kMP5UFiN3V+WicXBOhST/X0tz7mzq/UHpPN2e4T8Sb48ImKTlop
   23.10 +wBO3lqC23YHTVl87bGm4yeM5XrzK/0yO+pAUQ53G2aFkjNHfcqtkAGcazmOqXhXF
   23.11 +EhT1Qo6Pfu7ZXBPsBLHj8eRjBqf0HXVxv35//BSjAhUOmzMa81OQHHfD2wpuiwLB
   23.12 +yKgjvjphUQydgzTjHAI9/dkcDMM4MQkp6rbJU10dwhGqcx1rD1tmznMMdHup7lfA
   23.13 +Np6UAhvxJPAxjGtGiWfj7xi9D63TgFOoh4fboBgSd1s9X5rH6u9+9dNOPLEOPHMP
   23.14 +hgRTxqJxie3PDALN6kdL1MFyAQkBBoNRgvuptD0v1VFYsy6+w+tG3LFw/NoKC8pv
   23.15 +dcSBormmdWLNF3SLDm0ECp27x8U9tYxqjqX4J7XCv7ipcqa3cifPIafMpxCCicMP
   23.16 +hHcl5zgyMrVtlqUbgrrmlQF4+lVL64+mqo0jDJqU3C9TWUZmNJJ3B/f12ZrpbV+3
   23.17 +h8UBRUQyq85shpoCEdBCYLULvH2K7BA28RDj2kCr6RM+jOJO3UYthwJv7ebqXL/Q
   23.18 +oqmgdiZxFEl8WjQPxFL7S1fSoqkFRklSr5zaD8JNdzw8NYlgroulRVQgLKFHRjZb
   23.19 +mGvMywHSQfylbBVhx3k5JiGkPUE8jRMvibty5we/4ENAxNY4ihDlZ4LUtU/aPkND
   23.20 +QMul8MUjIWVF+ZpTF3Z6zz6cbXB8FJWiDw3+Ak0Z+sHR8TfVIhtJWQkaKO3WUJ/1
   23.21 +zaHUpfssL+n55as7H59YURYyMQFAgWcuOtqqt+pulWuv64GXWBjpYeOwds4rBb5i
   23.22 +erJ6GUZW0Or+yA+XPC15uRcJh23oef7zQoRaIyJVv9Dr4NinsMUfi3Rp8x2w53Gr
   23.23 +9K/HCZh7OPs4Ym+sKXi+lBOUhkmtc5ZRqh6SbAm/2MC5bvSPh+tswN/8mP/ejhuH
   23.24 +OVf/lXdPzmQl1vt9kuDVsj1iy20MjL9F2TXNkdkPOAOCBblUCo2GqrfImzVdL+wO
   23.25 +CrqnO063T9LexQ3Un7w8XnUnd+zvr1qck50KQ/8tDtIaNnK7u05oxw7Z9aG5fqlD
   23.26 +pCoGqA==
   23.27 +=P6SJ
   23.28 +-----END PGP MESSAGE-----
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/test/test_files/pep-test-mary-signed-encrypted-to-self.asc	Mon May 20 12:26:41 2019 +0200
    24.3 @@ -0,0 +1,24 @@
    24.4 +-----BEGIN PGP MESSAGE-----
    24.5 +
    24.6 +hQGMA6aSYtgJ++dOAQv/f5Q5icNJ2cXMe9HJgWeTiBDDBflPwuIUEVyeCGa82kyl
    24.7 +DwwWG/vS/KMwkJOzzttdT4PDlUKotRy1ujYtxYGByM8QLDEgWwGSGkS+XN0iG4Uz
    24.8 +p8SHzJbGgDbvsZCbEXrcSeR8XBLCGHRzvu1l2Dg43Co8QO250BV8PvhFAJrjEOUT
    24.9 +BhiR++biD64OuEA///zp+7lhqN6ejZw9P8lhqcl8e8wpirUTmZjrpWhNK/nSkWs1
   24.10 +ghBcteVBVdDFQX/UYKgluGldyGNy/CmYGhOuUfx3cmPGxO9qef+p3OjMVNlyYViM
   24.11 +xoawV+fn8c5hv9IK/jkCYyQmzJflzO1boQLMTCGL7DyyL9B7x58ib2lbHqIqWVTC
   24.12 +0Lq/IxKDhOf/E/qMT88g+uRRD6AUV5/CtxnHXPsomOhRINnuq8FNQjSBqws3jeXd
   24.13 +6zzI24ys0bpKk1VX3SAxIyPOcyHbSQQ4xRUGdo0dWdcm6XanC0oeri2ZaMJzfDnv
   24.14 +dUgQ8pr1AGfiih7l2MjP0ukB9SIGGjlqf7P+KQiU6TgCd5ZOPrp0hDp4vsP0wVNK
   24.15 +2S5kfK6sv+coGpEUEnUoBO827JW19MU0vLLwWkXZFoCB3DmI2KDvSBett9t2bSbT
   24.16 +N2Djvi9dLDCt05oNdmfR1e1HVIwZQm5qetHHycxQy8OscTUp9ZYlGkyrQ6jlMMeE
   24.17 +40OxcxSCmuk2ln5N5EZqUImAFv6ynuWNiN1vmKVI1ozTrDvb7QVn72QWN1slS0z6
   24.18 +b5WVunNYso58fFOjnJ4CFVCuWt5XhEhn5ArQoZrzWeDdWwV2l+vfwXlu2SXZdg6l
   24.19 +jW6tIJaUtEjPLg6PeTG0coLGE6JrUDcWCiqGEBdrV/9txssKG/efVdPn+Q1JXqom
   24.20 +//jAWwjFcDkRkrMbWVgEbtaUFHt67mTRQTQojfueqh8JbkmEVcxDzyAVtPiAnl9G
   24.21 +EZmWUD/OGePlJJjbf/B8ddRmUWzSjgtLfEQLekj9ubjq0e6+095bYHv14BOGbpdo
   24.22 +sqlxEevCwtx1F8+NoRFZq3qi1y+5BZacfoUZip3M7BVDpvAXX2t+6lKVQiMUsnSZ
   24.23 +SmupON6y8n/m6WaxnPqZkGbL07+umdPYUh68UO51A/UrCUujfFweaL2rXOK8pNkB
   24.24 +179q9WmLOWhBRNghDJlEZHbw/+OsJDiss96oGrxVBYq8T2iBM7MpFj3gW3ZDoIOr
   24.25 +Qws8uwuXIkEkwe8t+Q==
   24.26 +=BXG/
   24.27 +-----END PGP MESSAGE-----
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/test/test_files/pep-test-mary-signed.txt	Mon May 20 12:26:41 2019 +0200
    25.3 @@ -0,0 +1,1 @@
    25.4 +was soll ich machen?
    26.1 Binary file test/test_files/pep-test-mary-signed.txt.sig has changed
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/test/test_keys/priv/pep-test-lisa-0xBA0997C1514E70EB_priv.asc	Mon May 20 12:26:41 2019 +0200
    27.3 @@ -0,0 +1,139 @@
    27.4 +-----BEGIN PGP PRIVATE KEY BLOCK-----
    27.5 +
    27.6 +xcSYBFzcgtABDACkdvhKd5Kj/9qF81vu83NfXp+1+RMyhzShP7xPA1cwTmYaORUw
    27.7 +/gaPBaCc5eNW9F5NHsWOkgHRTBIC2VFXrHmxHx4PNsaDvO1C2nkVbiTggf1f299P
    27.8 +QXornJrQwAXAW8hA4ahDGznhSqI5rGNn2/vGnPhN/YmN5AxRPfIg0nteCxkz8X6u
    27.9 +Dlt8AzNnGOehEizm0nxVAEqWt1XYavASb8sFIpXAOOFw9crASw0tLzXBrdx1kFep
   27.10 +APo7RS6EBBG4nJYOicTwT6q1htpLHaicJnpuU6fNZEBtheGwyevXsh6vGC9C/0bq
   27.11 +5aSs0JtqSduzbdqnZOItaNGqxvo2Wxg8IppnYB2WuE8pwuNcxop1tfPasnW63ScX
   27.12 +64i4fqndG3BpNHMaA9ROld87SSCYjKut646sq9JOa6fqnJiDHN4R+qRAoPe1vnra
   27.13 ++ct5RenE95gcNDX4S/RZx3XpIF/SPtbUgVqsw1dkOns0Rz/C6dIhMhM9Q2btT9sg
   27.14 +6TP1Xh8m5ihgaykAEQEAAQAL/jk02LCuXueEu3IUcEnxjJQDyfH2LWNJ/FiKXuns
   27.15 +84rt+j3s1R4xff6JqpBotmcsoRCaP4WT6+XtW+Z5yP2CFOIzPLV2DB8OvEigzbVS
   27.16 +lqkxDf0l8csTr3c0BfXOlTGPu1w2Id0Vv1BKMZt2By29Kxquxv/5zLr6M/6eWXZp
   27.17 +QFg57A5RVgsdG11Lj7mwxAEW3V98n5rBezBpnQamS9Nd53Rlz0kJgAFWvaudb3vk
   27.18 +DALOgvyxtIwotuGe8ssgzzkz3b9PooDHODA0hHIdXEKWKIr80AjXM55Cbx4TkB0D
   27.19 +NQMw5yqoEHkL4s+iFYR34HXJwtGOxSwqzocUVgnoceZ0+CDN7WlgMu8v3oKnoIGv
   27.20 +VHho08gJPCadHpeCPLAGslkuo5nEVggxFuMptmILHS+W6GImO00olywUGRw0wvH8
   27.21 +D7GF0wn1ElJxIx5lmBD34AUOcLXqizXtazX4eoOasr8lXtigko1GiLC9lYLWSI6l
   27.22 +6RqO0HXtnMwYP8AG5vI+NxCD8QYAw5JOBZjr4A/uuJLCjCFt+ItKjcdukdsy68Dq
   27.23 +ZCoi5EPjJzmXrt4JsO3d4evQQbPZ/AINf+5Jr8hMw0HywEU4JjSg5g+dn0uNPu7A
   27.24 +8tyxpkrNW4JqQ3UdcOEzGv7xeALhEOeNeRYDbB6N7ADhNskWF7lInQhrP8ZqvIDM
   27.25 +JZQ9Q72PtyyJzKGPv+iP1nSY8lTjCTRnt7SXASNeHRpeWvmxUQVQHR2PxedyUU5l
   27.26 +mwpsS/kcghYPC0uA4Nrh2oMDEZlfBgDXSB7p4s0f+qnqHdnMysCIOslxTYfQMGUB
   27.27 +SbYGHQGD4Pu00uaby6N6r225zw2r6wxyOtI4DrzJDm6Uwq1hMeT/SziCVAP57TAV
   27.28 +9TgifytjYHfk2IMQdi5Q5314ifwL0fi38MBWS6B3hTRYK0+fj86XkX54QBsPPcvY
   27.29 +sQMopiuKaikQT/NluG9MM15CmlgYU2w4UfpSpdYy1Cs2f7jTGXM1BxPsrS5ezmpj
   27.30 +3SYfqg7h7a0lIIV+5anSz0GCDchh4HcGAIlR8tGkBmF4XV2yC+2jQWUxDOsNx5UK
   27.31 +irZOogvmZa7I5cqaRDcXRGpRxgQ6h1bU8CF9C30CGExQtoa6DK5TZd+oRH1gFujW
   27.32 +CUvu56w/ud3bxM9rmpNFN1vqHDMHSZJgAxotEWDQBYYYjIEELqmadDb/H3tLRoZR
   27.33 +SA7HbaUTaeVe5YpQQoeCRHdxME+eWWQiXTIbiBbT/DOh2hauAxYzZVREuAivohXn
   27.34 +c9Ref+jhMAdAfAPaLe+63re7uXa7PYmuEdGywsD8BB8BCgAwAh4DApsBBYJc3ILQ
   27.35 +FiEEEBKCMYcIEkqSW9rougmXwVFOcOsJELoJl8FRTnDrAhUKAAAdZAv+KzUDchOn
   27.36 +JRQbNn3HS4GoI5GiwxHEBAp0khU7jAiBhWUHBiYNsw76DsGy1C3udLUFrquHJaRX
   27.37 +2KLHLjpcGq+Qd++jKzXAJpnWN6x5GWMQCKJqt2++ABeCwPWZW2gZOMs+T8z6Zim9
   27.38 +mZ1lwgPk/zhIq5EfP7/kfTjr/NG6+9ucmRYalpYShfoZMgGEYX/oau4FlTR5l8Ga
   27.39 +9hAYhknwEqrK1XjfWH/G8/uuX+RHgIP+0R5tO9POs8KxbrX6Lnt1pXwPDNeBEgpg
   27.40 +Yr14zsni0askfqS4bv/eoWJbmQ2p5eZMBaCMoLof0kBAA3RTQ2l6Ks5G0XEHfCuA
   27.41 +GYPzvy2xwZhw7JrB2Jj+h5F28ZRwBEbqODPwE59UBE3Mz6ocSXSNVT8ZXNRir5xl
   27.42 +H7GMTXGryyZSvedXh4IrFPbglXd1+7DGIOrlBqr4iBxAxPXmjcbZK3bqm+WuIo+2
   27.43 +sgo1DU8aqISNNSfjEHf5J+EXBNQfVCKYJokyiqVIpY6ZcsmKO2WrqarMzV9MaXNh
   27.44 +IE1hcnkgU3VzYW4gS2FyZW4gS2ltYmVybHkgUGF0cmljaWEgTGluZGEgRG9ubmEg
   27.45 +TWljaGVsbGUgQ3ludGhpYSBKb2huc29uIDwxOTYwQGV4YW1wbGUub3JnPsLA/AQT
   27.46 +AQoAMAIeAwKbAQIVCgWCXNyC0BYhBBASgjGHCBJKklva6LoJl8FRTnDrCRC6CZfB
   27.47 +UU5w6wAAWsUL/3EkmeLQk6j34YhyHXr3bUJvLrhTDfk+W2k91p9VUmrhRleLFJpS
   27.48 +PJVPFFm9APvtZmQrrKt+YKTZEu09Oh2DbowRULisOj8EOrTOiiheBJ8YTnBxGyiI
   27.49 +Kb7ZRmVPIuYnnQSn+i5I1Ca4Wij5NvBQ8kf23C7xPzPeE/uy6m19L0nw0gtl47xQ
   27.50 +rfjVtfTqWYCrS7FQSNS5opiaJ/8Pq7x1BagMv/vrvAN7qulmWyyj3fLzM9tyVoil
   27.51 +Al6WV85qcNU7cG13gasaEPaG93dvbw/0HnQYvxf6LUxaguFUuixD6R3wnAGTYQpd
   27.52 +htbqn2HjNdXAaVu+nNc77fLqZQRK48Mpeo1m4A5+2ymcMpWgeqTG/Bz3dedH3D/g
   27.53 +Fmkc/AF3hM9K3nzSdO7jmoVWQl8OM7gs39+6swWQ1s/qHncr/R56J50VyBOomm0m
   27.54 +nK0GObGCOlCetrrobMutAWHoWUx5Hk/Mvgwy0D4gAMBG9mZ495iEotc8tYCvs+xg
   27.55 +Y33FwKdv+9RFGcfEmARc3ILQAQwAoe7NBS5Gd+rlRl+GeMLxL8AyWYe0dbznaPSM
   27.56 +S1k+hgFbU4a1pgHem5cxtzKg+9CAIcUePd9wgQDzGHboRR+dp3ImhMmwbD6ynY5i
   27.57 +TnTKxDJZ3D1CE0VqGzpgvrGFODhfu5z3GzpUEF3WGX6GPqnOfk5zH+PO01lksPyf
   27.58 +S6A6P5in/oaVnzUxxg82fDyyHq5ME0wOTrjwD4woa+ODO6We7F6+uJs+mpmL5vCS
   27.59 +nYWcn8DVLZsXj60lSNjbf+9fcVAgNMbljk/wFUdXrjADdV7TIXMgM3qJPjp8QY16
   27.60 +CJv2R9eDOEFndllPaKPsZnjqmwbBka71WSmo0aTADODo+M46kAJPZk1I9PvCAGMn
   27.61 +O78tEc2Js7j/+6ujYXUKp52jjUtqoyPX7WrqlzKFMGF129HwIyYELYel8SB6tq3V
   27.62 +knh5ARP4a1W+G+bhcOo97RA12WP+3Jnfz5sd6P/yMmM3MO+eD4xmLEs03Tvwv3eB
   27.63 +8rgltx1CVj/9+OxH4DTWs4/2j1ZNABEBAAEADACOVDmpuxG/JxwcbavhCt847EKV
   27.64 +BL0t2zq+umtxcuCMojamRLn2TqBdu1e8QOjUTF/CzuIU2galrLL+pszirLZCTgfj
   27.65 +IO9LRRRzfYmUkf0C04q+FK22CIYJppcQJTIFxy8F1SIwsWTf+cpMIDRYcaIIzGVN
   27.66 ++0p345OoKHLO4ucvrLrD8YEjLXsxLX/jVOnuI57EO048DTsbP0LsCU34qEr2URRr
   27.67 +aDBvbFRWSM9lWuHeXHxDGJVt+G7UB59uZHRMQXKXZWD1mlS3NRL1YfkXDs+TOKlq
   27.68 +VKulz6NB7Y+OLywfXcMyR4NN7mhRxX6+c/jt6qagb+vJezEzK/mgRc+jrUkNGLWG
   27.69 +Rqc6DtWSv5VPU5PopJr0rSZGjTZxXyUXKQh/mMR29XQt/3qDNQC/mN6NxhrQvY3t
   27.70 +xo2cDohhSPs5U+EOsVSvpQ/MUzJBikl6HWrTA2AzWDLNEdvKRjGrWx80BTY86kHI
   27.71 +pWNM0lMz9W4W6vf9HTxXgeCD/dj61NCVT0UgKuEGAMrWQcuA5Y5Ou4q+hBfDcMbe
   27.72 +q3212N+nLwj7QJ0E2/GeAlZJlnDbvTLH9SCjyhmEtHU/gaSfkokkufcIXlxyHvyx
   27.73 +cZuq8vPXK4dX4IUusZ/EF1UHHhdDCJL12a6JyMmEfoO6kcXILFOcXm6HEEQcoArZ
   27.74 +qHmEI7+OZo+6YP7pgFYFG3ZFiPWXogKEaBTEkIYvr1Lj+iaG3Z06cNxh4UO+IXDf
   27.75 +n6+Yx+Gipp7sdtqzU7uJ3wkvROzvw/wQVofwhSToRQYAzGAATq4gOLNZvovzqoch
   27.76 +DOhHoeXaDLCDXePae+/w+yQX2jf3Uvsotn5NRL61ays3v5tNUZtb0fe75sQxGQQP
   27.77 +Z87f9LhUAFxHpKrxddANGoKiIpK02fivpbteSy8QRA26Ly39+Ewng2TtcAO+wQXu
   27.78 +xrbWrXKMylXabnhZMbkeWkKy4AjPe2uzlPidQUStc5oNFblD4q6bsfCIynif7lH+
   27.79 +vKdC68nHwULik2D4QfjRHH0Tb2sJvI2orEQzC4OX+eppBgC/98U0K4GxSZKgT3Oe
   27.80 +59rfANg81hYkFIUR1MGD4PWE9BI0h/MULkvOX9ATRV1cQ53BylwP5EYb4Fjc5iMA
   27.81 +TBPBnHSYQFqRPNMpTTJzIPi3D2gdFdz7/jKAbUF3ASIeE1A9ACKlBn4nzh7MGJLr
   27.82 +NQSbQbBqLzMMaVsA8yV0Qt7Iee9wtf2R6utHYrHMG6C9r6OmIMwM1gMBjEXqxQ5c
   27.83 +7C5t9gPhGVtUpCmK2QPXF1v1Y03BV4/rhp99tAJGjkkG4NriFsLA/AQYAQoAMAIe
   27.84 +AwKbDAILCQWCXNyC0BYhBBASgjGHCBJKklva6LoJl8FRTnDrCRC6CZfBUU5w6wAA
   27.85 +ElYL/RZwStIiGdLdI8fDVofuUTLaBZeenzTuKmFuwhldo7ECZYB0ZrmdXkFTj6RC
   27.86 +WOUyh29OwvW7h82EMUJIx/UYMs85oQaQtVLo0DMAfoxp9rt9UAVXh022zQBjwb8b
   27.87 +axN+Bo1xncNr50xigk6UUsk5QOP6kDqd+AYUyUTTK5ZJnS10RIgrOzddVfmlplTR
   27.88 +Su3P5VyqxcbY6LDTFSrLXmQDxkTgQJYmVV4t/doKyHlnNOLC3CA6n7FxgjhocqLi
   27.89 +zOsrg5KbDmtxeA0mcOfVam7TrrwrLtUYVWUhj/xkUXpWi7U4t1aSF1aQQBZG/KZy
   27.90 +WL9pI7ClJBiXBIGDXvBFke/iMmaRjVnVnDsu9ITYAYd3unV/rb7A+KWe/59rq4xP
   27.91 +Aup0EghWZoEtOE12yVvz17gzYvWOWF+phltYobTRrvwYUA1P3MBpNtl5L7XcCOg5
   27.92 +Dm6DnJOPvt+Ds4FNyFYVUOJZ294Xv1sgesuQWRf3CTRuHGQzrukuXPLeRuNKzJmU
   27.93 +QHY7xcfEmARc3ILQAQwAusNsIouqhxHJCDDRkHFVzoPA+Pk7Wj1kfWm7e2lHvXy2
   27.94 +DKKGHkoGjz2kITeK+I8KoyTU4EXihGtOuHwHXbLzzsxk8Ae4FzBo2+UQUYEzYBaV
   27.95 +vLYuDQ8LFNHYAocLKgfI71vyCTXFvuw4vpS3ueKO4Iqw9PdCmcOuiYOO4yGsqKlL
   27.96 +5EiKRcyO4K9JFJmAUVMQ4TIdfRtevDhKAKGQts5x5emr+ty9GL6Yv6SNXQhRo4Eo
   27.97 +jmVokdylJVadO5IfETSk7kTRQbGrExh198mKTjH/1gOf9sdFtTAU+eOYSkGlB82t
   27.98 +leLPFP8zXtJ/RvNv+xE/j00vE7s4rBvLNf+eLWpjjkYU7mjqduSUx4TCwtze321k
   27.99 +fzl+fQjTRJAMJmrSn9RrFIg3OjTzKM6iZnkIL0Yi+I7Tu00ouz4knYIOBxrTwLTj
  27.100 +PcqIGl25DvaO2+eKrG/LQKmoW7/xZ3LuFYfikqK9rFHrZ0esO6lzLGXxTBGuBzGI
  27.101 +RgrPWtCWb4rApw8zFuvNABEBAAEADACk+5l88vBTnWx/pdCazuPEKTPBPTonP3CU
  27.102 +MWEDZj+PrqmLg88C1tXwl71z8oL7jDETaaf77wBphfnmkvpW1Yz3NCw+tjLzmToo
  27.103 +drPxrDbcPVdNe4o20wExBSbTJMTB/lqMyCaJ6EylmjuOcAXVWcRpq1sjK4JUHz8C
  27.104 +D4ucLdU+sT9vjH1Jp6jX50Chx/BI5x5UMVdHe3Q2xWrqH8+dDcYkGkZot7L8NvLs
  27.105 +6MpQUtb7n09aa07y+32P/HGtfCmho2RDjU96S8evtzb2cf7qRHpltDZdjnanFh65
  27.106 +Hnnkz7hddisyajfPbVNjnnQUCGcw6yeyCLsv3xVsiRhpGrjYe0Q469A78h5WweZq
  27.107 +ME4ym8kgV9IHCUGJwmlMthBxVHm5GFT3cKXdRVC2IMmpCVuHsGAh+MfEIz1+zVL0
  27.108 +oF1pLE/wGLGNqWcQUEjLyEdw5MGltsnRVjJ4SGw5zSjKSa9V8XebX+R2QdCrIFzq
  27.109 +qraC3P5RxXgYPpjIbYHkFD5tKmFoeGkGAMfarnMcyc0E1lXUcYKmN9yHyIpuo6NH
  27.110 +r3NlstH5QO17Sw6DhG33zBOpAOvCHd6wbyEl8DJENc0TyA1sWWUVqxKzEVanne9a
  27.111 +lNt5V/3hAX1q+aPR24b//ZNtPoFERfmrc/U1EsOICU1fiuI4/NyFk+JORYuYGqc/
  27.112 +8bwhQ9Fwcb6dUTpk+iFIQD8oGkK/P4cSjId1BNb5LWRf81WxEbfX+jUyH/mP7Qi9
  27.113 +CcswSws1dVLGYU1AhjXY3oqpKH+QCrq1NwYA7ztCcVqil2rffGuY2fbJnmGwso2W
  27.114 +qduQrWhmzdI7vBbdELET3fPR39E+PuiBNzVlwrTdMKRLWPCpINT8nv6otGLoY/bq
  27.115 +1mgUJ/m6VSebbPQtZeau7lc2UpcaMwSX9k1ExYAiN7YqBWHPOoPtJMzsXEObkBmD
  27.116 +RDSZBF3xKNfljqATPtKM8sf6Y9rbmuYT97zG+oH+8XZP1Kfw5Brw3uRZucpkKxZ1
  27.117 +lpaFXZpbWUMoUqAVKWs8xrx4/8iHaCZYoCkbBgCME81XiNkdKZ+PeoX3u4jxC/Aj
  27.118 +6srcR6ZavvvmrzzV8AclVn2PVpf0SGVG0D/IMvPb62hxf0geCoF3SJPiW5Iena21
  27.119 +zRSDW0KBeAc32+YwWNmNRm0CCwpBb3vA+0v0uVw71CG24IeX4ZjTnXpn1ywd177M
  27.120 +Y4e8Ebc/bQETaQy+kPja5ieGbI2pyUkVGJ3zxev64VM1f+znItOHYWrX9J4wngr0
  27.121 +rCpQ4zYrfBjBSy762kcSZ8WQrahMYJ9HFei9NeTrScLCsgQYAQoAMAIeAwKbAgIV
  27.122 +CgWCXNyC0BYhBBASgjGHCBJKklva6LoJl8FRTnDrCRC6CZfBUU5w6wG2wPSgBBkB
  27.123 +CgAnBYJc3ILQFiEEdxDh/7TuDwfji0GMwvGfZi2wcf8JEMLxn2YtsHH/AADrkwv/
  27.124 +dRccKQN7JOWanhIkYZYk/wuc1vrvg6a+VPPiMMCiqR8DFjGUXAIq0VcCseR2tiZV
  27.125 +zG9AwgZOZTU8ENHVGiaHi2PMiEK+JZabIubQtKgSW5StuLGKnVjFIU0pSOsWeYdU
  27.126 +2kBZ9muLilZ942tTRC4oNrWKOP22TQ5iVcl476MeJw/YVpqzvMBpmGWF5CAJlYHJ
  27.127 +H1gjChX70DRsfGZdpxFgjgSlf6L15xQhOoHEGYHeop4PZrH73Fx8KRsFh6BG720z
  27.128 +JOViDWZ1d3/w8Rp8bZ7n7X30aQNQq0vVIP1I7Hg5OHDqN0AZZ0Ugp8HEHMwlBQf7
  27.129 +qpMIf0qTznTYr1eUjsGHx/Ys0mPtB5OWMheOF9+0Pyrl5vI/KJg6GgR/v+vGQDMb
  27.130 +eDVLZeCdoqfD5l2CxkCyPPDiieQHuYU6PSo/tc64oRsqjHcfmsT7icX2K0DdgFfc
  27.131 +33jZIZtV5vp2xU+AQUOKe8B+mnb0crAq6FruZv6+gBUTKGjn+346xwg2zBiMaiCL
  27.132 +AXkMAIygwJlq+Eb3KOBqrRoxS2fDBQCMOn6pbrls9LdwoZyq8g6iId2KcRX6snvr
  27.133 +/TX5yM0Gbo3+s0tHXI+US5JnP6Gx0CKtXrKYt6TG86UvmyxP50Yb3i7plgwniRpx
  27.134 +HUtYb0Bf+4uzEAMn4BCHxZvD4bZ6FHr5OPFol5At8Zxv8juCLQbmbVxUhX0qbqEl
  27.135 +ipLbGn9PsGoarAUX669//kYmOfO6cNwE5BtSponN3w7dSjsFsyJqdAHqHzMonRRv
  27.136 +PuSwUxZlQmyuTCqxflkf8otWAf6p4Cps2ZRrxJja7A7LynrX5H4NmQWsB5EAR0Gt
  27.137 +YHgpjWwBMF62/34vlEwVktJS7hMvoqgDx6hnymo4gYS7V6U0h3EhQUpSdAuT0NtT
  27.138 +dRFJ6M2QAwrTDLTjZFuQz8Yxqn5dwcUv24hPiwdrWb80Slv7SD0JeHcyW3XHqLek
  27.139 +nj3vs3qQ36S0d8+yi+PmoexhJmcn70PvtxIjW6t07z33FplTAZ/VRfFpzNWmqPWr
  27.140 +b4PD8Q==
  27.141 +=1d3v
  27.142 +-----END PGP PRIVATE KEY BLOCK-----
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/test/test_keys/priv/pep-test-mary-0x7F59F03CD04A226E.rev	Mon May 20 12:26:41 2019 +0200
    28.3 @@ -0,0 +1,15 @@
    28.4 +-----BEGIN PGP PUBLIC KEY BLOCK-----
    28.5 +Comment: This is a revocation certificate
    28.6 +
    28.7 +iQG2BCABCAAgFiEEWZs9Z4ANs34tzgXAf1nwPNBKIm4FAlzakXgCHQAACgkQf1nw
    28.8 +PNBKIm6RXgv/X4oQggntl/bpPA31RJCrfND2bQUekpH8rG0BsoY5VdXww2JuGdS5
    28.9 +q7CluWviPshEYLOe1xcb9wPM1Yo2c1OQfXapDhnLXR69q32vA7yxdkcdVcvJRD5I
   28.10 +Lotm2bwe5DURW256G8dLcL4pmCweCt8UKJNppyXUk7FB4U7wQcYHdR6dAVIebovh
   28.11 +aCopH/gXEsIxKXl5/P3E+1cb4jJlsmGrP2SBymx8etvGmT48F/PG1L2lWnZrkUfc
   28.12 +Ldj/W2ds/ukhizswpL/RI7fT+nmRmDCY11tWRzMxGOBYb2/fZmeqOtaFZe/PnVC7
   28.13 +Zv3XyK/WA0wLnpHCBtM9TmWwHOwyVwI4/o2cGtZMAtVlIcWNgYYnpf5BZY7vJjM0
   28.14 +eaUjNbuCUCuiOFeW35qHNZAq1VJj5QrfwBvvLWQrEpVPzCSMNSe9YuFEhKH4z5b7
   28.15 +YHX0Na3sSEBuvtnSkPKtixkd8H6lMhJ8eEpIyKJTjDgNVFSkMsLmiK+jikuJgIpw
   28.16 ++IM1ZSCnyfCF
   28.17 +=kqka
   28.18 +-----END PGP PUBLIC KEY BLOCK-----
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/test/test_keys/priv/pep-test-mary-0x7F59F03CD04A226E_priv.asc	Mon May 20 12:26:41 2019 +0200
    29.3 @@ -0,0 +1,129 @@
    29.4 +-----BEGIN PGP PRIVATE KEY BLOCK-----
    29.5 +
    29.6 +lQVYBFzakXIBDADFQ/yauFR/q9HPFfszr8Cd2t4tZA9xBC46CtTnvetfL40EnCPV
    29.7 +umzsKCt0ZICiqMS538yMzgE5V7cUGCJJxabTt9Xnm/mqD6JJFiNxx49+BxapiJgN
    29.8 +VE7Uo5s2tXzy/BUGP3B5OeW2frFbse0zRWkgN/jvbkNr43LsHVYkBUQKSiqm3Ud7
    29.9 +1NZRaapAbkxisCOHNTZ2uyayX2WZlxKgufp/61wL75XRoPoQdnajaQvro1rr35sC
   29.10 +teG9k425WS60j80ie+AmGEIguPPc4Go5rhwf3SCqU7BfiYCxVAvX5ESr+HpyicEF
   29.11 +5iL+4wm/VMxj4zzFMQKQvQ0lHmw4I1SreS250sVfkXWdYtjiq+2XWGoQUWOnU/j4
   29.12 +nBol10pwOQVI0jL+ok8OlXfFZm6LIYY7Pmd9O4e5WbCid/UU+uc0UW1qDtkHie8t
   29.13 +25epIQGqmLOHgQJDWxdSnmNRcM7A9ckktGNMG3n53qJ8bvdfqlioRNJwm0IUF1cz
   29.14 +dHZuhDzoSFpPTbMAEQEAAQAL/ijRhZ6aT9nPOu3n9X/feTLwzBKGZu+S1uHpxd5i
   29.15 +HScoFr0CdiPOnKVNNpiyBzAhTfvMRG5KXlR4QwjkaYvsWzXqD1gKnWHENGd9Lj5n
   29.16 +9dg1LUpNWnE/pcQ4SnDKox1AbjVJwUNEaLUXiCmaKqP2U+d3zYn1vfvAJ9KVy3JO
   29.17 +qKKccDDxDs6f3u0fuTv11taA7gkXSLrOxRYZyVM7wH4DncMEd5p8q/qhnbz0Vl4/
   29.18 +6ViMB89RCKlJ63kn5CabPp/cNU+5X8bC700tgg30EcUfwE6a+GSnfLVwAquZAfPI
   29.19 ++6ikSjaA+4Ha0LiDYTqtVzW1LohKHbU9ZQgwuCngIVUn3LmFGk7NFN4QHIw4MmnA
   29.20 +un5bfoIELxBPbpGFPguZ1b+UwUjabrfXyoC6xEydIGNqV7vTYo8BW5JZqaMvMWQY
   29.21 +7RXGJpTZdxRV8FBA2PsnhmD1aGI0DR1/xjiTdiZLl+wvRj3b4s/0dvisYDAx6fbL
   29.22 +AWFqH+FxAlxdHE2qtvaHcNmK0QYAyKpbX7tb8rRpdM67yiYCT33jall0wewZn4pb
   29.23 +bJr54eoSCcpIS17AP+A3pk67ppvWJTQGGx6lMNYpy8kfgF1EsL4JD70lrAHMrXke
   29.24 +o6DbDxzG1tl+FBAvCtvVcC/wICiX97XTvsk85X/SsfGGYi4ZdrVMiLwLY0A++uHl
   29.25 +khe11Odope8ZLuGo43xi9Ug3G+1g5FsLmn2IyTuELOgyV8NBRTiewBTQcr1ON4HZ
   29.26 +rVCjWx3svk3c2kEOUWtGP/uE9hdJBgD7qZ7mI7LZaWF4la3icvMge80a1BfYC+kR
   29.27 +h5aKrlrS0QU61XHqt6n3IeXv5brm1xMBwyUiVB4JgWU9xo/BxJp1nKh0UAFG5TLc
   29.28 +7mvrtdE1AY0PjfXVaouCgsyYb+cW6HOsrMvqBMfrLz/ehZc3uKv+zRc4eHITOm4R
   29.29 +UqEH/SxKPje15IkhQf7QfqI4LwZU0HKeU5ehTqzNwm0I33eBbXQClGNbBtWfPH1e
   29.30 +aSFQmjWu5hlLH4uATnIffqBwQ3tXERsF/1rBF+nFczeJduKgzjQpNV5TBzKQrgWX
   29.31 ++12LSjcBYPsBPct9k9H36JoO8zPZ2N0Xa+YBn+dgp9g3g2mN4/D3Q0lKrEReRfnN
   29.32 +nN8/54LlbEIRTgkFlt+evH46t5lVNui4pegyBQMMUAGew4TATkf6wTcrG4644Z9C
   29.33 +wpGi2Lxe0xsM8DxngRAMtT7u87vuKTgwPZWPIlUNmyCepISHnTOxdqgRx4Dujvsb
   29.34 +h6f6XkSd8QJpnRBrZ5HGsgfSN/Qt/NNcrt+StElNYXJ5IFN1c2FuIE1hcmlhIEth
   29.35 +cmVuIExpc2EgTGluZGEgRG9ubmEgUGF0cmljaWEgU21pdGggPDE5NjBAZXhhbXBs
   29.36 +ZS5vcmc+iQHOBBMBCAA4FiEEWZs9Z4ANs34tzgXAf1nwPNBKIm4FAlzakXICGwEF
   29.37 +CwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQf1nwPNBKIm4ebgv/ax2NjqFViCSY
   29.38 +wpH0O2Mre+sdy+Qlk+IZlVs33WgLTF3+6UEtO2mSWriwTw0FJVKkKmFcC2JDnDCY
   29.39 +eR13FZVB1W7RPHHkpJzheqRTommYXvYLQN1squUVD1d1rrxsWCwMDB3j+nfmixds
   29.40 +T3GZYBdmaZbvSXnwyhm5XTUqzs9tYgftHOGwpE20ySSOSNDpJ0t6wOlp7CuuZlTp
   29.41 +BBfZl1PmiALKwbPSKhXOJyuEI/W7cJ2/LyKfGPW7lkGAbek9JowK6Y9DGos6kOf8
   29.42 +W8Api3ZBXJJeBaSPqCZ0Nk/LP93JFv8yAdgKZiLKrr7YWylSEGLD/PVwOcTW/mUR
   29.43 +vnecah3WAbBVSN6fRYzjV8sDzNCPRTmObXsLmxC7uM6F8sMlzFCUPhZTY3ghjmU6
   29.44 +jDQlXEJn/6I2Q38lsjOX6dPnvFy7221LwHz9KYBIB8GgVT9rxJ0pNlZwChUmAOTn
   29.45 +rRUFjx+zMh1G0uKk6cDsqaVBjwncOu/aQJ+nVaCp6uxDXrnuhUienQVYBFzakZYB
   29.46 +DAC2Goe/yDgr+5Nj+XwMEENhIgo0FnUJMcYXSZhb1Cp8I5k2j7ge8yet6BVVYlEj
   29.47 +VKZ7C2UWqh7h5WlaVBn/ICqoDUqkJl9LktXNVbeTswoTVJTyKagJ/FaUb7Ysb51+
   29.48 +iWsC7LZNKUY8h7CLHsaF442iHHks97iSwl5EMTv/0q1AeBa/c1wmJh3w1c0fEYjy
   29.49 +TRe/VREhYBsnHkcRns8qZKX+FyJxtgKlGh7LFxqOUEA8rKzS8157qaS+GG8HvN3X
   29.50 +r1d8cwf/XnADAwsfQahxEMeFZoUUWtclfgcBDAEJTU9davTZJrvd43IR3rqYHBCc
   29.51 +Kic0Do+Qvt43DM/Y2are2NuIo7uliEY380gSHZAI9EmVRuOe/TrwmIPyxHTocxUx
   29.52 +5oNLXN3b0G3gnzaCLv2bMGeFszIcOtmuev1zHiRRcMbIuQQbRaVsGG6Rsy7S3hmw
   29.53 +G427bbI4k+Kqmteuy0WGEgUdMZEr629focujrS0Qh2E30KM6H2P8pKFjK20QSQZ0
   29.54 +gNkAEQEAAQAL/0E4X0Ygv32BLNixkewAJyGyv1TIdkJEwV21zguVgWHUnhscfiUX
   29.55 +kS6H4JwkCktNFhMbkaj8ZPMi5wii9myZaK2nlQQVeivm+wv/lzAe/4zMzkus/7IT
   29.56 +3i5rlCN2FkIrlVgGz4PzNGSZdHFfJFrvlNpquDuSvVhSpNBnkcWd/s8IM51+A5Lm
   29.57 +M/L9n+lwrkuZsNel7+y0LwVjorB84FWelpTaVEvFlEztffne3HP76gXRElS7NSu1
   29.58 +Jnuu5JUw34NQGLnB4T77upRHa4ngZeK3+VV5UYX9vHWEiz+TrvGkHA4fFbik04jF
   29.59 +rBwxcc0lHFC2O+lxiEzWGAgxDbqHifE9TzWrpPxAUZSo4On1XnKzu9EHAZVpexHJ
   29.60 +9l8jH1H7XvxBQGbG42e/aRAL3rlbP6iZqXhJ6pUeF4KlsVRbFo1XqwKUYhcryKCp
   29.61 +6bEip5R8W4S8/3EfrSpmRymsei7cV8e572ROPYlx6tDwOUJMRNDBarvT75Z3vZ2Y
   29.62 +xfP1/4Uy7uwfwQYAwjFRDnNYC+ChfP5cdWDpfBGoulCKQ107+2TzKwnDqCi+a901
   29.63 +KxnK1iE7PVNEVL/SkF1RKJPgU2yAXJacd9AlrPRaXV8ftTaL8F8wZkSrybCodpcO
   29.64 +avOuMSztqvnldJjZk0ZJrKa+kgyKRESMDmPSe6WV7zl9S/qFox1vzncYfnCYD90X
   29.65 +DABxeqBukUEk+hWBSyZY+t0qnOcW2XP0LxFZHOix+ZWwIlRj50AS2s6uIlGKv99Z
   29.66 +fotRuwxRaxAFysiXBgDwEDWfdQX9vmw8vqzMxK0z4cj9NhMWHrDNH9QMeX4/K9V9
   29.67 +7LsTibsbTw6jpwPh/+s9zxC0RR1Ro+kZQnvleLz6+k0gqiJErHHvl4qmgFdq4T13
   29.68 +J7ISEPCH5sVO+1t1Di3oLBtEP1COY2UpNyC2Otjml3A1/CmYdGI9G6JyEVKQF4Ju
   29.69 +BwJ14RSz0b1i5pjotkD8PfGmNIVF2nOUATbFRYYnDP8MH8c8TzasIwjKrnPxY2Yx
   29.70 +k2kEOWGqm9d3TQabQA8F/2PKyMSbIjBwiGpi9PMC0MZCDjc+j2H4J/C06ycaMWiK
   29.71 +1ZPKE3yGv8bhA6zhQAAYuH02BUZBrRY2uTXHcgnyULcg0/+AWvJklaw4dbRy3iLT
   29.72 +O45J1N392Q5JFO9bOaIpemamEP+/MoD+VV8+U/Al9RSBMmxgq8BmRt0+F881d5n5
   29.73 +71g9dOjrdd1zX4Xl7eASS00kbAcGoZCb34oW0uRi9nYunzltXzM+s5INXvycoTjo
   29.74 +jEpb4FyLMeS6CPJwphAGvdy7iQNsBBgBCAAgFiEEWZs9Z4ANs34tzgXAf1nwPNBK
   29.75 +Im4FAlzakZYCGwIBwAkQf1nwPNBKIm7A9CAEGQEIAB0WIQQ0rQXUJuRMayXQhG++
   29.76 +0LH0HLDcUQUCXNqRlgAKCRC+0LH0HLDcUavFC/48V+NZzS3NlSa/R2mcBwAZyEZi
   29.77 +CGstMeualsNtpxeAI3dJD2YOptqF0EwCardYBrRYH4lvbPNCUC0/pPVBdlZGi+nX
   29.78 +7LqOffSlmYRyz9K6idLOWqLQcab7NZG8fgyygtx/zVyLvRtCcqsGuCj98vIZXgyA
   29.79 +QZnaDDaUXRPwlXlCUXXAYmEMr2zTVZzxmz18Kzr1bK7w0f6wxDHiN7gGpSX7ASp4
   29.80 +fh3glAIW7V6o03eUfzcIizXqVP+jNVrR2XbdFP6b3eW2UAXf1nAmUX7JKS1fGhk6
   29.81 +f+3Cdzmy1tGsCfB6bUQhxkzYhuWvzuLXwG5BVpKzjwMqGqwy2UnaIuq0Q8sU8N1u
   29.82 +AmphZm7+1x/4jVdQLm9if6okY51du/zPdoHucRo/sT+Sr+xAXn6QkB6SdzkwUXAC
   29.83 +/uRF3Zg2RBVyhcrrIG+mrIAW5FO12njOgrJAWP09zKilYnOGoDnbnexrqTUjpcZu
   29.84 +oaW/Yn2DobIJFAl/d6mTx2nlNfU0Ol1gwmWOA1YN4gwAhsnkzW5K5HEUPuYBxE2G
   29.85 +UAZgclQdh0/TWdUrxcooRShwZ3p0cVqmmz3xZlUUy8atx6w/hUnh173df82D/XfI
   29.86 +7HnaN27p6hA61GBhkGXXR5IYInesB+eKPgp2jzHtbxzhb4cuT+CNsyCYtlkmN278
   29.87 +9cxadYpskwhMDFWCPgGD3W16hFa7pCmgR4J8UYmZZP5LcOAgmRO3SzIroPnVj3TM
   29.88 +ftelH1Auq8GR6qysVtAlb1ckmS3m1l8jrCu53CS+UkG7HEK1LCb5L2e5DnzDLIkj
   29.89 +Z4IcByQVFvAkN/V0kx4/JWN9iZVFnhlJXkC/qgA26nM5VvCX5MoMLs9ksxdyJ4tm
   29.90 +BZCDjgefymve1y3dhNcmY8Gt0PxNYTrg22m0L7aNSz8RwShlrmlDOMn+r/x9Gt1/
   29.91 +664f6MlSmE8HXO6Ucos4z0gD9N3WCclVGJ1AXE8Q7fd/v5xiw0lARnH4++cQ0AMT
   29.92 +Ay8qn5qdai0FBVeEtrAbxdguCkcVbdbsxFOjldhDGbcdnQVYBFzakaUBDAC2L+tD
   29.93 +AJvji5xqrfPunpCa0/C+Q5zax4ypDYlNj+7KU2edPNd3Y7ZOXXU58nv2BbeKVqoZ
   29.94 +VUs5jbAe40a7XYUSoqTeechk9JxLIwsvpLh5E1bGD67U7FnXfZqvm9b7mKWeDriP
   29.95 +mPfJceWQy4b6s968BOeo0L1iR0tDu04u5mAgZDXTHmLr5oxhHixtMxOJkQUIlEaJ
   29.96 +P/NGS4R9rq1fgkS3kv+kNveiZRlxq2vGE2/g+uU4Cscq+j+19DdzTZgOu6JY02uX
   29.97 +tbPv0Z9Gaj9SUgTnUbFF/9qlV/FkAAHK1Q/j8XPoPFkeC+akeEAP3GyhLmnEgY+d
   29.98 +3MA5xWRDgsOe+0+xP3YhABIOMk0LTNb5NSXeIS+2t+9NzAA1BT9E1CTthDHC3waL
   29.99 +5Fk9w1MNwoyaAo96qEqLbFbpO1HB2k8ak3uCvdysWWkV2/zPRph3R1zcXWEm/vAD
  29.100 +Ja9sztx7dZDTy9AjDmquBWSk2/Fhs9noQsXI2xOPZd4rBwimTSNHX2xDEC8AEQEA
  29.101 +AQAL/RFyuGjT05owwjuzSjPVqsqxNpK6Pfjz+IQuQDKV8MwevcMg0w/jlE+gAryY
  29.102 +fQe8V24fy62ebhRmffIPWTRTig2VVw3ZgvgsNxW5Fvaqo2IxGHPih59rvVT2egyM
  29.103 +c8PnxCDFjyZtg3me91ntLBGxjUjbfWY9C44wfsRPWXcDaDxh7Ie6FsY578LTVXTl
  29.104 +2d6obV97d9/oKH/Ydqlkw8TsYHFmWiZbf07luNCalrlDHklhLfe2jImQqu5do7ve
  29.105 +uAvdK087vvm4G6THAEdOjLx+bs46QbeVDuCKQcI4CQbYtik4BtXlY6BNkORJczxd
  29.106 +8S9V2n61fp4TEFdzDQw/udDPXUkue6RW8as0EOT7VFiTlTvsCoK0d4L3bkYKJ2w5
  29.107 +cjt014i2959NFR4qOO+M36/mcEc2l12tA3dzZWnj/h8L9gZOcDwlgldCGY+FdIEe
  29.108 +pgwZ8hjMfNC94qhGyn/+RAbjUCgYthZx5RH6zf1WNSBMEkFRR+WJcFENCuPuXl4H
  29.109 +w536BQYAyn30zNYJlm2XsYgrM9B27ZavUNNehHu8K9yeD3oASa5E0gGk4Oj9JQm6
  29.110 +vDIbpP1ImbbiI1hUHkL+XK8tdvjxu8cKISi3KfUZvSxs12G2ax7tmUyWtnql4CHx
  29.111 +PJJOIagFlPY0f1LEuAXVGPd68hSZ5mzn3zuUbt/pLdbZ7YNTJ1aIawOZqWOBYltr
  29.112 +znrAKcjVs6OFzKeujNa+K2JYyawEU/eG4322OBVSDspEV0Z2X/z8sGgDhfAlyZmq
  29.113 +HdebYdSDBgDmVGUiErIVQAMp/LsuYr+GdrZDdAwkusAUcAS5JLt2MvLOhDjJ910t
  29.114 +ByUjU0uHWxYCZH4kcv0/aAeCF3lWuTYmGRbdFk89p7Y6zggf6W1jqWLQ7JIvZQsQ
  29.115 +KidKHP1dTb6aQp6v7tKcUoYaPlgLE+eFjdAX6f0CQ+FBYfszYbqWkRfoREW3NyDV
  29.116 +G8qlH0fZrMjYdvt3dTKRO11wh958O4eOM9yLiPxk/ZrFNcvfxzQLyjzZ65ub4JSi
  29.117 +M6zdK/pUfeUF/20iloJMsXlYTqXI1taYtKAmA1iwJ5kvpz3uPGOtNRSrISkLoSab
  29.118 +ocfojHAsOhRwZMvhrh7mXfycWZGFm58ZP6C3r0nYNeHsjDwI8UOvKUiD1w9xVSJl
  29.119 +kFR5gH3cqawPA0M8O6Ya8nnO4GayQgKwFMzB0Z6j87G0SViT3fS89DwcRjTC5QeY
  29.120 +Tj0fEeFz7/CX0buEsnsd0FM1w2We/DAK/kAQXMDirmabIOasYPDk3+BS3fWGaJf7
  29.121 +xICz4DJE99QSfd5GiQG2BBgBCAAgFiEEWZs9Z4ANs34tzgXAf1nwPNBKIm4FAlza
  29.122 +kaUCGwwACgkQf1nwPNBKIm6jJwwAhjrzhMBozPqmmprEolo2iPZFLBwVqXueIPjQ
  29.123 +S6YOVaitJxQePNOHpkWJqGaVRpmVlUg7z0oCsmfLjfQSV6FygdjjFRjbhm14ny1v
  29.124 +ZeSbYNROSwWVDWB/KoLnC3YFQh4BjhxqORsGvZ6BnWWKEtXyBN2vTCZC8+hGfo6p
  29.125 ++WbTbwCnzPWTvuhxqxFC/P9esgBfYzUDa/qRKggZvecQL+k0ebWeQzUwvTTWgfDa
  29.126 +Vh+Fl2OB3tt9kI9th46mfw1a6MXQssyH0Shd1J/cQtAZiZCCnKS41aLUKnMNjrGt
  29.127 +MdYjCq6f9WGTqB5tXhYYkMZBCiJBmXaXR1Vli8ERoZm5GXki9d54Gu1lAZ6QDM6O
  29.128 +iKngsknRFAyvQz4zDAHm0olGA4+SIdRT9iQ6I2NDR/R9kZzuQ/42CiUf8XX/4Tzb
  29.129 +vU/DhExIEyxN6S8khYaDfsDVoBrKOn4qF7Lj1PNN1xt0qNxYPy3tbQVnCOD6a0po
  29.130 +mCsddt0ANDA4BDMM32UW0FU2Ahu0
  29.131 +=EuxL
  29.132 +-----END PGP PRIVATE KEY BLOCK-----
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/test/test_keys/pub/pep-test-mary-0x7F59F03CD04A226E_expired_pub.asc	Mon May 20 12:26:41 2019 +0200
    30.3 @@ -0,0 +1,68 @@
    30.4 +-----BEGIN PGP PUBLIC KEY BLOCK-----
    30.5 +
    30.6 +mQGNBFzakXIBDADFQ/yauFR/q9HPFfszr8Cd2t4tZA9xBC46CtTnvetfL40EnCPV
    30.7 +umzsKCt0ZICiqMS538yMzgE5V7cUGCJJxabTt9Xnm/mqD6JJFiNxx49+BxapiJgN
    30.8 +VE7Uo5s2tXzy/BUGP3B5OeW2frFbse0zRWkgN/jvbkNr43LsHVYkBUQKSiqm3Ud7
    30.9 +1NZRaapAbkxisCOHNTZ2uyayX2WZlxKgufp/61wL75XRoPoQdnajaQvro1rr35sC
   30.10 +teG9k425WS60j80ie+AmGEIguPPc4Go5rhwf3SCqU7BfiYCxVAvX5ESr+HpyicEF
   30.11 +5iL+4wm/VMxj4zzFMQKQvQ0lHmw4I1SreS250sVfkXWdYtjiq+2XWGoQUWOnU/j4
   30.12 +nBol10pwOQVI0jL+ok8OlXfFZm6LIYY7Pmd9O4e5WbCid/UU+uc0UW1qDtkHie8t
   30.13 +25epIQGqmLOHgQJDWxdSnmNRcM7A9ckktGNMG3n53qJ8bvdfqlioRNJwm0IUF1cz
   30.14 +dHZuhDzoSFpPTbMAEQEAAbRJTWFyeSBTdXNhbiBNYXJpYSBLYXJlbiBMaXNhIExp
   30.15 +bmRhIERvbm5hIFBhdHJpY2lhIFNtaXRoIDwxOTYwQGV4YW1wbGUub3JnPokB1AQT
   30.16 +AQgAPgIbAQULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgBYhBFmbPWeADbN+Lc4FwH9Z
   30.17 +8DzQSiJuBQJc2pITBQkAAVIhAAoJEH9Z8DzQSiJuT9oMAMDohz5ee4mz8d1GZxgn
   30.18 +IVmktrUxhr7PoJoLjyQF5VHCifYC1fdH3ax8EblRfnjI9G+JlGXcS+Vyae0UXlTe
   30.19 +zfVHBSyDM1VWZ4X+mSs4mXgU6IQOn/zGIFfEU1TgEl7FjK70zhjJNfr1LruVA/I/
   30.20 ++oLD2oH8AObOTrYF6ZsKqqnLyAC3H0NI+FoczkXJom7h27RoRXJsCO2FGElLGhak
   30.21 +zSJwSYTbGLBT9ELqpboCop5AIiL9daPqkcHktbONNKyC5sBbXn+nRU6cWirbLrsF
   30.22 +t9epabSVpI0QlnvWsTcr0jv6yCXx5vyS8kBqmXt3hi9UbC3nsg4+7V+8iBlOTjUL
   30.23 +R3CTZepj1b4mE0vRr+JBKHXfakwdAJYvQRuPYPC6w2Hmwk7MIio+ROVdD9yb/yOA
   30.24 +LoVNzLllGM9wmpX6921suFh7romAZXD1V4AH8UzBgcRSDZfcW0oxjcYfdlQpO5QW
   30.25 +eujvNxeUXqXui7ia5f6EjGT0wAgknZd3IY/M/DsR6jHqu7kBjQRc2pGWAQwAthqH
   30.26 +v8g4K/uTY/l8DBBDYSIKNBZ1CTHGF0mYW9QqfCOZNo+4HvMnregVVWJRI1Smewtl
   30.27 +Fqoe4eVpWlQZ/yAqqA1KpCZfS5LVzVW3k7MKE1SU8imoCfxWlG+2LG+dfolrAuy2
   30.28 +TSlGPIewix7GheONohx5LPe4ksJeRDE7/9KtQHgWv3NcJiYd8NXNHxGI8k0Xv1UR
   30.29 +IWAbJx5HEZ7PKmSl/hcicbYCpRoeyxcajlBAPKys0vNee6mkvhhvB7zd169XfHMH
   30.30 +/15wAwMLH0GocRDHhWaFFFrXJX4HAQwBCU1PXWr02Sa73eNyEd66mBwQnConNA6P
   30.31 +kL7eNwzP2Nmq3tjbiKO7pYhGN/NIEh2QCPRJlUbjnv068JiD8sR06HMVMeaDS1zd
   30.32 +29Bt4J82gi79mzBnhbMyHDrZrnr9cx4kUXDGyLkEG0WlbBhukbMu0t4ZsBuNu22y
   30.33 +OJPiqprXrstFhhIFHTGRK+tvX6HLo60tEIdhN9CjOh9j/KShYyttEEkGdIDZABEB
   30.34 +AAGJA2wEGAEIACAWIQRZmz1ngA2zfi3OBcB/WfA80EoibgUCXNqRlgIbAgHACRB/
   30.35 +WfA80EoibsD0IAQZAQgAHRYhBDStBdQm5ExrJdCEb77QsfQcsNxRBQJc2pGWAAoJ
   30.36 +EL7QsfQcsNxRq8UL/jxX41nNLc2VJr9HaZwHABnIRmIIay0x65qWw22nF4Ajd0kP
   30.37 +Zg6m2oXQTAJqt1gGtFgfiW9s80JQLT+k9UF2VkaL6dfsuo599KWZhHLP0rqJ0s5a
   30.38 +otBxpvs1kbx+DLKC3H/NXIu9G0Jyqwa4KP3y8hleDIBBmdoMNpRdE/CVeUJRdcBi
   30.39 +YQyvbNNVnPGbPXwrOvVsrvDR/rDEMeI3uAalJfsBKnh+HeCUAhbtXqjTd5R/NwiL
   30.40 +NepU/6M1WtHZdt0U/pvd5bZQBd/WcCZRfskpLV8aGTp/7cJ3ObLW0awJ8HptRCHG
   30.41 +TNiG5a/O4tfAbkFWkrOPAyoarDLZSdoi6rRDyxTw3W4CamFmbv7XH/iNV1Aub2J/
   30.42 +qiRjnV27/M92ge5xGj+xP5Kv7EBefpCQHpJ3OTBRcAL+5EXdmDZEFXKFyusgb6as
   30.43 +gBbkU7XaeM6CskBY/T3MqKVic4agOdud7GupNSOlxm6hpb9ifYOhsgkUCX93qZPH
   30.44 +aeU19TQ6XWDCZY4DVg3iDACGyeTNbkrkcRQ+5gHETYZQBmByVB2HT9NZ1SvFyihF
   30.45 +KHBnenRxWqabPfFmVRTLxq3HrD+FSeHXvd1/zYP9d8jsedo3bunqEDrUYGGQZddH
   30.46 +khgid6wH54o+CnaPMe1vHOFvhy5P4I2zIJi2WSY3bvz1zFp1imyTCEwMVYI+AYPd
   30.47 +bXqEVrukKaBHgnxRiZlk/ktw4CCZE7dLMiug+dWPdMx+16UfUC6rwZHqrKxW0CVv
   30.48 +VySZLebWXyOsK7ncJL5SQbscQrUsJvkvZ7kOfMMsiSNnghwHJBUW8CQ39XSTHj8l
   30.49 +Y32JlUWeGUleQL+qADbqczlW8Jfkygwuz2SzF3Ini2YFkIOOB5/Ka97XLd2E1yZj
   30.50 +wa3Q/E1hOuDbabQvto1LPxHBKGWuaUM4yf6v/H0a3X/rrh/oyVKYTwdc7pRyizjP
   30.51 +SAP03dYJyVUYnUBcTxDt93+/nGLDSUBGcfj75xDQAxMDLyqfmp1qLQUFV4S2sBvF
   30.52 +2C4KRxVt1uzEU6OV2EMZtx25AY0EXNqRpQEMALYv60MAm+OLnGqt8+6ekJrT8L5D
   30.53 +nNrHjKkNiU2P7spTZ50813djtk5ddTnye/YFt4pWqhlVSzmNsB7jRrtdhRKipN55
   30.54 +yGT0nEsjCy+kuHkTVsYPrtTsWdd9mq+b1vuYpZ4OuI+Y98lx5ZDLhvqz3rwE56jQ
   30.55 +vWJHS0O7Ti7mYCBkNdMeYuvmjGEeLG0zE4mRBQiURok/80ZLhH2urV+CRLeS/6Q2
   30.56 +96JlGXGra8YTb+D65TgKxyr6P7X0N3NNmA67oljTa5e1s+/Rn0ZqP1JSBOdRsUX/
   30.57 +2qVX8WQAAcrVD+Pxc+g8WR4L5qR4QA/cbKEuacSBj53cwDnFZEOCw577T7E/diEA
   30.58 +Eg4yTQtM1vk1Jd4hL7a3703MADUFP0TUJO2EMcLfBovkWT3DUw3CjJoCj3qoSots
   30.59 +Vuk7UcHaTxqTe4K93KxZaRXb/M9GmHdHXNxdYSb+8AMlr2zO3Ht1kNPL0CMOaq4F
   30.60 +ZKTb8WGz2ehCxcjbE49l3isHCKZNI0dfbEMQLwARAQABiQG2BBgBCAAgFiEEWZs9
   30.61 +Z4ANs34tzgXAf1nwPNBKIm4FAlzakaUCGwwACgkQf1nwPNBKIm6jJwwAhjrzhMBo
   30.62 +zPqmmprEolo2iPZFLBwVqXueIPjQS6YOVaitJxQePNOHpkWJqGaVRpmVlUg7z0oC
   30.63 +smfLjfQSV6FygdjjFRjbhm14ny1vZeSbYNROSwWVDWB/KoLnC3YFQh4BjhxqORsG
   30.64 +vZ6BnWWKEtXyBN2vTCZC8+hGfo6p+WbTbwCnzPWTvuhxqxFC/P9esgBfYzUDa/qR
   30.65 +KggZvecQL+k0ebWeQzUwvTTWgfDaVh+Fl2OB3tt9kI9th46mfw1a6MXQssyH0Shd
   30.66 +1J/cQtAZiZCCnKS41aLUKnMNjrGtMdYjCq6f9WGTqB5tXhYYkMZBCiJBmXaXR1Vl
   30.67 +i8ERoZm5GXki9d54Gu1lAZ6QDM6OiKngsknRFAyvQz4zDAHm0olGA4+SIdRT9iQ6
   30.68 +I2NDR/R9kZzuQ/42CiUf8XX/4TzbvU/DhExIEyxN6S8khYaDfsDVoBrKOn4qF7Lj
   30.69 +1PNN1xt0qNxYPy3tbQVnCOD6a0pomCsddt0ANDA4BDMM32UW0FU2Ahu0
   30.70 +=Lvco
   30.71 +-----END PGP PUBLIC KEY BLOCK-----
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/test/test_keys/pub/pep-test-mary-0x7F59F03CD04A226E_expired_sig_key.asc	Mon May 20 12:26:41 2019 +0200
    31.3 @@ -0,0 +1,68 @@
    31.4 +-----BEGIN PGP PUBLIC KEY BLOCK-----
    31.5 +
    31.6 +mQGNBFzakXIBDADFQ/yauFR/q9HPFfszr8Cd2t4tZA9xBC46CtTnvetfL40EnCPV
    31.7 +umzsKCt0ZICiqMS538yMzgE5V7cUGCJJxabTt9Xnm/mqD6JJFiNxx49+BxapiJgN
    31.8 +VE7Uo5s2tXzy/BUGP3B5OeW2frFbse0zRWkgN/jvbkNr43LsHVYkBUQKSiqm3Ud7
    31.9 +1NZRaapAbkxisCOHNTZ2uyayX2WZlxKgufp/61wL75XRoPoQdnajaQvro1rr35sC
   31.10 +teG9k425WS60j80ie+AmGEIguPPc4Go5rhwf3SCqU7BfiYCxVAvX5ESr+HpyicEF
   31.11 +5iL+4wm/VMxj4zzFMQKQvQ0lHmw4I1SreS250sVfkXWdYtjiq+2XWGoQUWOnU/j4
   31.12 +nBol10pwOQVI0jL+ok8OlXfFZm6LIYY7Pmd9O4e5WbCid/UU+uc0UW1qDtkHie8t
   31.13 +25epIQGqmLOHgQJDWxdSnmNRcM7A9ckktGNMG3n53qJ8bvdfqlioRNJwm0IUF1cz
   31.14 +dHZuhDzoSFpPTbMAEQEAAbRJTWFyeSBTdXNhbiBNYXJpYSBLYXJlbiBMaXNhIExp
   31.15 +bmRhIERvbm5hIFBhdHJpY2lhIFNtaXRoIDwxOTYwQGV4YW1wbGUub3JnPokBzgQT
   31.16 +AQgAOBYhBFmbPWeADbN+Lc4FwH9Z8DzQSiJuBQJc2pFyAhsBBQsJCAcCBhUICQoL
   31.17 +AgQWAgMBAh4BAheAAAoJEH9Z8DzQSiJuHm4L/2sdjY6hVYgkmMKR9DtjK3vrHcvk
   31.18 +JZPiGZVbN91oC0xd/ulBLTtpklq4sE8NBSVSpCphXAtiQ5wwmHkddxWVQdVu0Txx
   31.19 +5KSc4XqkU6JpmF72C0DdbKrlFQ9Xda68bFgsDAwd4/p35osXbE9xmWAXZmmW70l5
   31.20 +8MoZuV01Ks7PbWIH7RzhsKRNtMkkjkjQ6SdLesDpaewrrmZU6QQX2ZdT5ogCysGz
   31.21 +0ioVzicrhCP1u3Cdvy8inxj1u5ZBgG3pPSaMCumPQxqLOpDn/FvAKYt2QVySXgWk
   31.22 +j6gmdDZPyz/dyRb/MgHYCmYiyq6+2FspUhBiw/z1cDnE1v5lEb53nGod1gGwVUje
   31.23 +n0WM41fLA8zQj0U5jm17C5sQu7jOhfLDJcxQlD4WU2N4IY5lOow0JVxCZ/+iNkN/
   31.24 +JbIzl+nT57xcu9ttS8B8/SmASAfBoFU/a8SdKTZWcAoVJgDk560VBY8fszIdRtLi
   31.25 +pOnA7KmlQY8J3Drv2kCfp1WgqersQ1657oVInrkBjQRc2pGWAQwAthqHv8g4K/uT
   31.26 +Y/l8DBBDYSIKNBZ1CTHGF0mYW9QqfCOZNo+4HvMnregVVWJRI1SmewtlFqoe4eVp
   31.27 +WlQZ/yAqqA1KpCZfS5LVzVW3k7MKE1SU8imoCfxWlG+2LG+dfolrAuy2TSlGPIew
   31.28 +ix7GheONohx5LPe4ksJeRDE7/9KtQHgWv3NcJiYd8NXNHxGI8k0Xv1URIWAbJx5H
   31.29 +EZ7PKmSl/hcicbYCpRoeyxcajlBAPKys0vNee6mkvhhvB7zd169XfHMH/15wAwML
   31.30 +H0GocRDHhWaFFFrXJX4HAQwBCU1PXWr02Sa73eNyEd66mBwQnConNA6PkL7eNwzP
   31.31 +2Nmq3tjbiKO7pYhGN/NIEh2QCPRJlUbjnv068JiD8sR06HMVMeaDS1zd29Bt4J82
   31.32 +gi79mzBnhbMyHDrZrnr9cx4kUXDGyLkEG0WlbBhukbMu0t4ZsBuNu22yOJPiqprX
   31.33 +rstFhhIFHTGRK+tvX6HLo60tEIdhN9CjOh9j/KShYyttEEkGdIDZABEBAAGJA3IE
   31.34 +GAEIACYCGwIWIQRZmz1ngA2zfi3OBcB/WfA80EoibgUCXNqSVQUJAAFSPwHAwPQg
   31.35 +BBkBCAAdFiEENK0F1CbkTGsl0IRvvtCx9Byw3FEFAlzakZYACgkQvtCx9Byw3FGr
   31.36 +xQv+PFfjWc0tzZUmv0dpnAcAGchGYghrLTHrmpbDbacXgCN3SQ9mDqbahdBMAmq3
   31.37 +WAa0WB+Jb2zzQlAtP6T1QXZWRovp1+y6jn30pZmEcs/SuonSzlqi0HGm+zWRvH4M
   31.38 +soLcf81ci70bQnKrBrgo/fLyGV4MgEGZ2gw2lF0T8JV5QlF1wGJhDK9s01Wc8Zs9
   31.39 +fCs69Wyu8NH+sMQx4je4BqUl+wEqeH4d4JQCFu1eqNN3lH83CIs16lT/ozVa0dl2
   31.40 +3RT+m93ltlAF39ZwJlF+ySktXxoZOn/twnc5stbRrAnwem1EIcZM2Iblr87i18Bu
   31.41 +QVaSs48DKhqsMtlJ2iLqtEPLFPDdbgJqYWZu/tcf+I1XUC5vYn+qJGOdXbv8z3aB
   31.42 +7nEaP7E/kq/sQF5+kJAeknc5MFFwAv7kRd2YNkQVcoXK6yBvpqyAFuRTtdp4zoKy
   31.43 +QFj9PcyopWJzhqA5253sa6k1I6XGbqGlv2J9g6GyCRQJf3epk8dp5TX1NDpdYMJl
   31.44 +jgNWCRB/WfA80EoibqLdC/4ssznHmOhxlEmPHZOgOsJQgtQGt3Zz4EDqOY5ejxaj
   31.45 +B9Nl5zJdypDhx1Dfb6gCR9ZOsKelpZJeees2HjKA0mqwFkQ30s/HN1ocVCKaq3md
   31.46 +ozGQv0z5Cihw1Buj+CZwHztPRbtDPNAyrLUjgJN0Lg/jfU4G90aS1aQEGnnlksE3
   31.47 +qkBw+86RV2gHoVfWOGQGFCajlJgnz6X93YL1A7IJv19rP+4fHJKubq98gnXvo60Z
   31.48 +OBiUKmIkgja2lDlZo26qz/yHiS/WBo/ZWMBiH7brM7TikIAC3JgXrc+98m8vJqAQ
   31.49 ++Ak6yndQDaMmnfaj53E4YaZ937xGiNRZq5lEnPZqII5Ki+gvscpBOrVo/N1hVsAB
   31.50 +Zqiy29r67lcrZjYAWpYVtTWtQP1el6WyhClZnZiRJJ0blnhSWF+W6G9anjPerqnw
   31.51 ++hC1oVehym7tCm/NoIMwxaUHa90T8637jYh/pEutQD3xWFRUcEMa+l9rvW9yuIYW
   31.52 +kXTPWsuZllyaw37qSGCMUA+5AY0EXNqRpQEMALYv60MAm+OLnGqt8+6ekJrT8L5D
   31.53 +nNrHjKkNiU2P7spTZ50813djtk5ddTnye/YFt4pWqhlVSzmNsB7jRrtdhRKipN55
   31.54 +yGT0nEsjCy+kuHkTVsYPrtTsWdd9mq+b1vuYpZ4OuI+Y98lx5ZDLhvqz3rwE56jQ
   31.55 +vWJHS0O7Ti7mYCBkNdMeYuvmjGEeLG0zE4mRBQiURok/80ZLhH2urV+CRLeS/6Q2
   31.56 +96JlGXGra8YTb+D65TgKxyr6P7X0N3NNmA67oljTa5e1s+/Rn0ZqP1JSBOdRsUX/
   31.57 +2qVX8WQAAcrVD+Pxc+g8WR4L5qR4QA/cbKEuacSBj53cwDnFZEOCw577T7E/diEA
   31.58 +Eg4yTQtM1vk1Jd4hL7a3703MADUFP0TUJO2EMcLfBovkWT3DUw3CjJoCj3qoSots
   31.59 +Vuk7UcHaTxqTe4K93KxZaRXb/M9GmHdHXNxdYSb+8AMlr2zO3Ht1kNPL0CMOaq4F
   31.60 +ZKTb8WGz2ehCxcjbE49l3isHCKZNI0dfbEMQLwARAQABiQG2BBgBCAAgFiEEWZs9
   31.61 +Z4ANs34tzgXAf1nwPNBKIm4FAlzakaUCGwwACgkQf1nwPNBKIm6jJwwAhjrzhMBo
   31.62 +zPqmmprEolo2iPZFLBwVqXueIPjQS6YOVaitJxQePNOHpkWJqGaVRpmVlUg7z0oC
   31.63 +smfLjfQSV6FygdjjFRjbhm14ny1vZeSbYNROSwWVDWB/KoLnC3YFQh4BjhxqORsG
   31.64 +vZ6BnWWKEtXyBN2vTCZC8+hGfo6p+WbTbwCnzPWTvuhxqxFC/P9esgBfYzUDa/qR
   31.65 +KggZvecQL+k0ebWeQzUwvTTWgfDaVh+Fl2OB3tt9kI9th46mfw1a6MXQssyH0Shd
   31.66 +1J/cQtAZiZCCnKS41aLUKnMNjrGtMdYjCq6f9WGTqB5tXhYYkMZBCiJBmXaXR1Vl
   31.67 +i8ERoZm5GXki9d54Gu1lAZ6QDM6OiKngsknRFAyvQz4zDAHm0olGA4+SIdRT9iQ6
   31.68 +I2NDR/R9kZzuQ/42CiUf8XX/4TzbvU/DhExIEyxN6S8khYaDfsDVoBrKOn4qF7Lj
   31.69 +1PNN1xt0qNxYPy3tbQVnCOD6a0pomCsddt0ANDA4BDMM32UW0FU2Ahu0
   31.70 +=INdi
   31.71 +-----END PGP PUBLIC KEY BLOCK-----
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/test/test_keys/pub/pep-test-mary-0x7F59F03CD04A226E_revoked_sig_key.asc	Mon May 20 12:26:41 2019 +0200
    32.3 @@ -0,0 +1,77 @@
    32.4 +-----BEGIN PGP PUBLIC KEY BLOCK-----
    32.5 +
    32.6 +mQGNBFzakXIBDADFQ/yauFR/q9HPFfszr8Cd2t4tZA9xBC46CtTnvetfL40EnCPV
    32.7 +umzsKCt0ZICiqMS538yMzgE5V7cUGCJJxabTt9Xnm/mqD6JJFiNxx49+BxapiJgN
    32.8 +VE7Uo5s2tXzy/BUGP3B5OeW2frFbse0zRWkgN/jvbkNr43LsHVYkBUQKSiqm3Ud7
    32.9 +1NZRaapAbkxisCOHNTZ2uyayX2WZlxKgufp/61wL75XRoPoQdnajaQvro1rr35sC
   32.10 +teG9k425WS60j80ie+AmGEIguPPc4Go5rhwf3SCqU7BfiYCxVAvX5ESr+HpyicEF
   32.11 +5iL+4wm/VMxj4zzFMQKQvQ0lHmw4I1SreS250sVfkXWdYtjiq+2XWGoQUWOnU/j4
   32.12 +nBol10pwOQVI0jL+ok8OlXfFZm6LIYY7Pmd9O4e5WbCid/UU+uc0UW1qDtkHie8t
   32.13 +25epIQGqmLOHgQJDWxdSnmNRcM7A9ckktGNMG3n53qJ8bvdfqlioRNJwm0IUF1cz
   32.14 +dHZuhDzoSFpPTbMAEQEAAbRJTWFyeSBTdXNhbiBNYXJpYSBLYXJlbiBMaXNhIExp
   32.15 +bmRhIERvbm5hIFBhdHJpY2lhIFNtaXRoIDwxOTYwQGV4YW1wbGUub3JnPokBzgQT
   32.16 +AQgAOBYhBFmbPWeADbN+Lc4FwH9Z8DzQSiJuBQJc2pFyAhsBBQsJCAcCBhUICQoL
   32.17 +AgQWAgMBAh4BAheAAAoJEH9Z8DzQSiJuHm4L/2sdjY6hVYgkmMKR9DtjK3vrHcvk
   32.18 +JZPiGZVbN91oC0xd/ulBLTtpklq4sE8NBSVSpCphXAtiQ5wwmHkddxWVQdVu0Txx
   32.19 +5KSc4XqkU6JpmF72C0DdbKrlFQ9Xda68bFgsDAwd4/p35osXbE9xmWAXZmmW70l5
   32.20 +8MoZuV01Ks7PbWIH7RzhsKRNtMkkjkjQ6SdLesDpaewrrmZU6QQX2ZdT5ogCysGz
   32.21 +0ioVzicrhCP1u3Cdvy8inxj1u5ZBgG3pPSaMCumPQxqLOpDn/FvAKYt2QVySXgWk
   32.22 +j6gmdDZPyz/dyRb/MgHYCmYiyq6+2FspUhBiw/z1cDnE1v5lEb53nGod1gGwVUje
   32.23 +n0WM41fLA8zQj0U5jm17C5sQu7jOhfLDJcxQlD4WU2N4IY5lOow0JVxCZ/+iNkN/
   32.24 +JbIzl+nT57xcu9ttS8B8/SmASAfBoFU/a8SdKTZWcAoVJgDk560VBY8fszIdRtLi
   32.25 +pOnA7KmlQY8J3Drv2kCfp1WgqersQ1657oVInrkBjQRc2pGWAQwAthqHv8g4K/uT
   32.26 +Y/l8DBBDYSIKNBZ1CTHGF0mYW9QqfCOZNo+4HvMnregVVWJRI1SmewtlFqoe4eVp
   32.27 +WlQZ/yAqqA1KpCZfS5LVzVW3k7MKE1SU8imoCfxWlG+2LG+dfolrAuy2TSlGPIew
   32.28 +ix7GheONohx5LPe4ksJeRDE7/9KtQHgWv3NcJiYd8NXNHxGI8k0Xv1URIWAbJx5H
   32.29 +EZ7PKmSl/hcicbYCpRoeyxcajlBAPKys0vNee6mkvhhvB7zd169XfHMH/15wAwML
   32.30 +H0GocRDHhWaFFFrXJX4HAQwBCU1PXWr02Sa73eNyEd66mBwQnConNA6PkL7eNwzP
   32.31 +2Nmq3tjbiKO7pYhGN/NIEh2QCPRJlUbjnv068JiD8sR06HMVMeaDS1zd29Bt4J82
   32.32 +gi79mzBnhbMyHDrZrnr9cx4kUXDGyLkEG0WlbBhukbMu0t4ZsBuNu22yOJPiqprX
   32.33 +rstFhhIFHTGRK+tvX6HLo60tEIdhN9CjOh9j/KShYyttEEkGdIDZABEBAAGJAbYE
   32.34 +KAEIACAWIQRZmz1ngA2zfi3OBcB/WfA80EoibgUCXNqSlwIdAAAKCRB/WfA80Eoi
   32.35 +bh1TC/96wk38W5QoHEff/k09349xQv1+JwvSiQSyPwaOfFM03tymNhzA/hVTsm5t
   32.36 +qihmSNRRPAyeyIcoBxkDGdr6Kr2cfeOwCroKKGzLuwh4RVc8nnzIIG4NEox+pUUa
   32.37 +V8UvQRBOgsmzedfFHmfAn48VET1hShy8a25XvFS/foRrUO4zPZatLuFbfZFGDWEt
   32.38 +mQeXvxv3w34LTcMwLo6PGLZlj0qX0qkUBP5DM37iG+eVOh5GFmg24NDKFYdoNmyf
   32.39 +w32ThCbE6hsyo18k8jdbJ3mi2Llyl0pU7MTO9VPO1N16aj9dv2G2hg3tvFIXV1r0
   32.40 +t1P2iJ3697is4fmUpt7zNTvuzbt0h4ZSSXXm9mRY0zh6DaBjIvj+k98i3Yo0czY9
   32.41 +uZDsjE3eHD6fZG0Yzg92ifDXlXSkunEBp43ofBDUcZ1Zr4AcioxGd+KUwUt6CLn7
   32.42 +0deDKETnzokYeNt0jgePrz6QvevQnfDlEEXqEo/Hevp5UeGekI18ecN6Pi226NuH
   32.43 +mNc//saJA2wEGAEIACAWIQRZmz1ngA2zfi3OBcB/WfA80EoibgUCXNqRlgIbAgHA
   32.44 +CRB/WfA80EoibsD0IAQZAQgAHRYhBDStBdQm5ExrJdCEb77QsfQcsNxRBQJc2pGW
   32.45 +AAoJEL7QsfQcsNxRq8UL/jxX41nNLc2VJr9HaZwHABnIRmIIay0x65qWw22nF4Aj
   32.46 +d0kPZg6m2oXQTAJqt1gGtFgfiW9s80JQLT+k9UF2VkaL6dfsuo599KWZhHLP0rqJ
   32.47 +0s5aotBxpvs1kbx+DLKC3H/NXIu9G0Jyqwa4KP3y8hleDIBBmdoMNpRdE/CVeUJR
   32.48 +dcBiYQyvbNNVnPGbPXwrOvVsrvDR/rDEMeI3uAalJfsBKnh+HeCUAhbtXqjTd5R/
   32.49 +NwiLNepU/6M1WtHZdt0U/pvd5bZQBd/WcCZRfskpLV8aGTp/7cJ3ObLW0awJ8Hpt
   32.50 +RCHGTNiG5a/O4tfAbkFWkrOPAyoarDLZSdoi6rRDyxTw3W4CamFmbv7XH/iNV1Au
   32.51 +b2J/qiRjnV27/M92ge5xGj+xP5Kv7EBefpCQHpJ3OTBRcAL+5EXdmDZEFXKFyusg
   32.52 +b6asgBbkU7XaeM6CskBY/T3MqKVic4agOdud7GupNSOlxm6hpb9ifYOhsgkUCX93
   32.53 +qZPHaeU19TQ6XWDCZY4DVg3iDACGyeTNbkrkcRQ+5gHETYZQBmByVB2HT9NZ1SvF
   32.54 +yihFKHBnenRxWqabPfFmVRTLxq3HrD+FSeHXvd1/zYP9d8jsedo3bunqEDrUYGGQ
   32.55 +ZddHkhgid6wH54o+CnaPMe1vHOFvhy5P4I2zIJi2WSY3bvz1zFp1imyTCEwMVYI+
   32.56 +AYPdbXqEVrukKaBHgnxRiZlk/ktw4CCZE7dLMiug+dWPdMx+16UfUC6rwZHqrKxW
   32.57 +0CVvVySZLebWXyOsK7ncJL5SQbscQrUsJvkvZ7kOfMMsiSNnghwHJBUW8CQ39XST
   32.58 +Hj8lY32JlUWeGUleQL+qADbqczlW8Jfkygwuz2SzF3Ini2YFkIOOB5/Ka97XLd2E
   32.59 +1yZjwa3Q/E1hOuDbabQvto1LPxHBKGWuaUM4yf6v/H0a3X/rrh/oyVKYTwdc7pRy
   32.60 +izjPSAP03dYJyVUYnUBcTxDt93+/nGLDSUBGcfj75xDQAxMDLyqfmp1qLQUFV4S2
   32.61 +sBvF2C4KRxVt1uzEU6OV2EMZtx25AY0EXNqRpQEMALYv60MAm+OLnGqt8+6ekJrT
   32.62 +8L5DnNrHjKkNiU2P7spTZ50813djtk5ddTnye/YFt4pWqhlVSzmNsB7jRrtdhRKi
   32.63 +pN55yGT0nEsjCy+kuHkTVsYPrtTsWdd9mq+b1vuYpZ4OuI+Y98lx5ZDLhvqz3rwE
   32.64 +56jQvWJHS0O7Ti7mYCBkNdMeYuvmjGEeLG0zE4mRBQiURok/80ZLhH2urV+CRLeS
   32.65 +/6Q296JlGXGra8YTb+D65TgKxyr6P7X0N3NNmA67oljTa5e1s+/Rn0ZqP1JSBOdR
   32.66 +sUX/2qVX8WQAAcrVD+Pxc+g8WR4L5qR4QA/cbKEuacSBj53cwDnFZEOCw577T7E/
   32.67 +diEAEg4yTQtM1vk1Jd4hL7a3703MADUFP0TUJO2EMcLfBovkWT3DUw3CjJoCj3qo
   32.68 +SotsVuk7UcHaTxqTe4K93KxZaRXb/M9GmHdHXNxdYSb+8AMlr2zO3Ht1kNPL0CMO
   32.69 +aq4FZKTb8WGz2ehCxcjbE49l3isHCKZNI0dfbEMQLwARAQABiQG2BBgBCAAgFiEE
   32.70 +WZs9Z4ANs34tzgXAf1nwPNBKIm4FAlzakaUCGwwACgkQf1nwPNBKIm6jJwwAhjrz
   32.71 +hMBozPqmmprEolo2iPZFLBwVqXueIPjQS6YOVaitJxQePNOHpkWJqGaVRpmVlUg7
   32.72 +z0oCsmfLjfQSV6FygdjjFRjbhm14ny1vZeSbYNROSwWVDWB/KoLnC3YFQh4Bjhxq
   32.73 +ORsGvZ6BnWWKEtXyBN2vTCZC8+hGfo6p+WbTbwCnzPWTvuhxqxFC/P9esgBfYzUD
   32.74 +a/qRKggZvecQL+k0ebWeQzUwvTTWgfDaVh+Fl2OB3tt9kI9th46mfw1a6MXQssyH
   32.75 +0Shd1J/cQtAZiZCCnKS41aLUKnMNjrGtMdYjCq6f9WGTqB5tXhYYkMZBCiJBmXaX
   32.76 +R1Vli8ERoZm5GXki9d54Gu1lAZ6QDM6OiKngsknRFAyvQz4zDAHm0olGA4+SIdRT
   32.77 +9iQ6I2NDR/R9kZzuQ/42CiUf8XX/4TzbvU/DhExIEyxN6S8khYaDfsDVoBrKOn4q
   32.78 +F7Lj1PNN1xt0qNxYPy3tbQVnCOD6a0pomCsddt0ANDA4BDMM32UW0FU2Ahu0
   32.79 +=CDai
   32.80 +-----END PGP PUBLIC KEY BLOCK-----