ENGINE-434: PGP/MIME behaviour in and tested. Time to fix the rest. ENGINE-434
authorKrista Bennett <krista@pep-project.org>
Fri, 18 May 2018 10:19:50 +0200
branchENGINE-434
changeset 2677a1ade141a1d1
parent 2676 074bceee15b7
child 2678 610a608c410d
ENGINE-434: PGP/MIME behaviour in and tested. Time to fix the rest.
src/message_api.c
src/message_api.h
src/pEpEngine.h
src/pgp_gpg.c
test/convenience_scripts/README
test/convenience_scripts/keygen_for_test.py
test/include/EngineTestSuite.h
test/include/test_util.h
test/msg_2.0.asc
test/src/EngineTestIndividualSuite.cc
test/src/EngineTestSuite.cc
test/src/SuiteMaker.cc
test/src/util/test_util.cc
test/test_keys/priv/integrity_test_recip_0-0xF390A40D_priv.asc
test/test_keys/priv/integrity_test_signer_0-0xFF26631A_priv.asc
test/test_keys/pub/integrity_test_recip_0-0xF390A40D_pub.asc
test/test_keys/pub/integrity_test_signer_0-0xFF26631A_pub.asc
     1.1 --- a/src/message_api.c	Fri May 11 09:06:29 2018 +0200
     1.2 +++ b/src/message_api.c	Fri May 18 10:19:50 2018 +0200
     1.3 @@ -1162,6 +1162,8 @@
     1.4          return PEP_rating_unencrypted;
     1.5  
     1.6      case PEP_DECRYPTED:
     1.7 +    case PEP_DECRYPTED_BUT_UNSIGNED:
     1.8 +    case PEP_DECRYPT_NO_KEY_FOR_SIGNER:
     1.9      case PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH:
    1.10          return PEP_rating_unreliable;
    1.11  
    1.12 @@ -1175,6 +1177,9 @@
    1.13      case PEP_CANNOT_DECRYPT_UNKNOWN:
    1.14          return PEP_rating_cannot_decrypt;
    1.15  
    1.16 +    case PEP_DECRYPT_MODIFICATION_DETECTED:
    1.17 +        return PEP_rating_under_attack;
    1.18 +        
    1.19      default:
    1.20          return PEP_rating_undefined;
    1.21      }
    1.22 @@ -3015,6 +3020,17 @@
    1.23  
    1.24      // Grab input flags
    1.25      bool reencrypt = (((*flags & PEP_decrypt_flag_untrusted_server) > 0) && *keylist && !EMPTYSTR((*keylist)->value));
    1.26 +    bool deliver_badsig_pgpmime = ((*flags & PEP_decrypt_deliver_pgpmime_badsigned) > 0);
    1.27 +    
    1.28 +    bool inline_pgp = false;
    1.29 +    
    1.30 +    if (src->longmsg) {
    1.31 +        const char* start_inline = strstr(src->longmsg, "---- BEGIN PGP ");
    1.32 +        if (start_inline && strstr(start_inline, "---- END PGP")) {
    1.33 +            // We'll decide if this IS encrypted, it was inline.
    1.34 +            inline_pgp = true;
    1.35 +        }
    1.36 +    }
    1.37      
    1.38      // We own this pointer, and we take control of *keylist if reencrypting.
    1.39      stringlist_t* extra = NULL;
    1.40 @@ -3157,6 +3173,7 @@
    1.41                                                &decrypt_status,
    1.42                                                crypto);
    1.43                  }
    1.44 +                
    1.45                  break;
    1.46  
    1.47              case PEP_enc_pieces:
    1.48 @@ -3196,9 +3213,35 @@
    1.49              status = unencapsulate_hidden_fields(src, msg, &wrap_info);
    1.50  
    1.51  //            bool is_transport_wrapper = false;
    1.52 -            
    1.53 +
    1.54 +            if (!wrap_info) {
    1.55 +                // NOT Message 2.0.
    1.56 +                // Fail hard on 1.0 and PGP/MIME messages which don't verify. 
    1.57 +                // (We will have been failing anyway due to gpg error codes, but we make sure here.)
    1.58 +                if (decrypt_status == PEP_DECRYPTED) {
    1.59 +                    if (!inline_pgp) {
    1.60 +                        if (!_keylist || EMPTYSTR(_keylist->value))
    1.61 +                            status = decrypt_status = PEP_DECRYPTED_BUT_UNSIGNED;
    1.62 +                        else
    1.63 +                            status = decrypt_status = PEP_DECRYPT_NO_KEY_FOR_SIGNER;
    1.64 +                        
    1.65 +                        if (decrypt_status == PEP_DECRYPTED_BUT_UNSIGNED && !deliver_badsig_pgpmime) {
    1.66 +                            *rating = decrypt_rating(decrypt_status);
    1.67 +                            goto pep_error;
    1.68 +                        }
    1.69 +                    }
    1.70 +                }
    1.71 +            }            
    1.72              // FIXME: replace with enums, check status
    1.73 -            if (wrap_info) {
    1.74 +            else {
    1.75 +                if (decrypt_status == PEP_DECRYPTED || 
    1.76 +                    decrypt_status == PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH) {
    1.77 +                    // For Message 2.0, if it's not signed and verified, it's 
    1.78 +                    // been modified. So...
    1.79 +                    status = decrypt_status = PEP_DECRYPT_MODIFICATION_DETECTED;
    1.80 +                    *rating = decrypt_rating(decrypt_status);
    1.81 +                    goto pep_error;
    1.82 +                }
    1.83                  if (strcmp(wrap_info, "OUTER") == 0) {
    1.84                      // this only occurs in with a direct outer wrapper
    1.85                      // where the actual content is in the inner wrapper
     2.1 --- a/src/message_api.h	Fri May 11 09:06:29 2018 +0200
     2.2 +++ b/src/message_api.h	Fri May 18 10:19:50 2018 +0200
     2.3 @@ -257,7 +257,8 @@
     2.4      PEP_decrypt_flag_ignore = 0x4,
     2.5      PEP_decrypt_flag_src_modified = 0x8,
     2.6      // input flags    
     2.7 -    PEP_decrypt_flag_untrusted_server = 0x100
     2.8 +    PEP_decrypt_flag_untrusted_server = 0x100,
     2.9 +    PEP_decrypt_deliver_pgpmime_badsigned = 0x101  
    2.10  } PEP_decrypt_flags; 
    2.11  
    2.12  typedef unsigned int PEP_decrypt_flags_t;
     3.1 --- a/src/pEpEngine.h	Fri May 11 09:06:29 2018 +0200
     3.2 +++ b/src/pEpEngine.h	Fri May 18 10:19:50 2018 +0200
     3.3 @@ -73,6 +73,10 @@
     3.4      PEP_VERIFY_NO_KEY                               = 0x0407,
     3.5      PEP_VERIFIED_AND_TRUSTED                        = 0x0408,
     3.6      PEP_CANNOT_REENCRYPT                            = 0x0409,
     3.7 +    PEP_DECRYPTED_BUT_UNSIGNED                      = 0x040A,
     3.8 +    PEP_DECRYPT_MODIFICATION_DETECTED               = 0x040B,
     3.9 +    PEP_DECRYPT_NO_KEY_FOR_SIGNER                   = 0x040C,
    3.10 +    PEP_DECRYPT_BAD_SIGNATURE                       = 0x040D,
    3.11      PEP_CANNOT_DECRYPT_UNKNOWN                      = 0x04ff,
    3.12  
    3.13      PEP_TRUSTWORD_NOT_FOUND                         = 0x0501,
     4.1 --- a/src/pgp_gpg.c	Fri May 11 09:06:29 2018 +0200
     4.2 +++ b/src/pgp_gpg.c	Fri May 18 10:19:50 2018 +0200
     4.3 @@ -622,11 +622,14 @@
     4.4          }
     4.5          gpgme_error = _GPGERR(gpgme_error);
     4.6          assert(gpgme_error != GPG_ERR_INV_VALUE);
     4.7 -        assert(gpgme_error != GPG_ERR_NO_DATA);
     4.8 +//        assert(gpgme_error != GPG_ERR_NO_DATA);
     4.9  
    4.10          switch (gpgme_error) {
    4.11              case GPG_ERR_NO_ERROR:
    4.12              {
    4.13 +                // EFail: We should get an MDC warning if there were modifications
    4.14 +                //        and never make it here. So the decrypted text is not
    4.15 +                //        returned regardless.
    4.16                  gpgme_decrypt_result = gpg.gpgme_op_decrypt_result(session->ctx);
    4.17                  /* NOW is when we have to process the decrypt_result, period.
    4.18                     it is only valid until the next call on the context. */
    4.19 @@ -792,7 +795,7 @@
    4.20                          }
    4.21                          case GPG_ERR_CERT_REVOKED:
    4.22                          case GPG_ERR_BAD_SIGNATURE:
    4.23 -                            result = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
    4.24 +                            result = PEP_DECRYPT_BAD_SIGNATURE;
    4.25                              break;
    4.26                          case GPG_ERR_SIG_EXPIRED:
    4.27                          case GPG_ERR_KEY_EXPIRED:
    4.28 @@ -853,6 +856,7 @@
    4.29                  break;
    4.30              }
    4.31              case GPG_ERR_BAD_PASSPHRASE:
    4.32 +            case GPG_ERR_NO_DATA:
    4.33                  result = PEP_DECRYPT_NO_KEY;
    4.34                  break;
    4.35              case GPG_ERR_DECRYPT_FAILED:
     5.1 --- a/test/convenience_scripts/README	Fri May 11 09:06:29 2018 +0200
     5.2 +++ b/test/convenience_scripts/README	Fri May 18 10:19:50 2018 +0200
     5.3 @@ -1,1 +1,3 @@
     5.4  This is just a collection of scripts and source files I've used to convert things and make the test environment behave from time to time. USE AT YOUR OWN RISK.
     5.5 +
     5.6 +Note that the keygen script isn't currently deleting keys properly. We probably just have to shell out and do it.
     6.1 --- a/test/convenience_scripts/keygen_for_test.py	Fri May 11 09:06:29 2018 +0200
     6.2 +++ b/test/convenience_scripts/keygen_for_test.py	Fri May 18 10:19:50 2018 +0200
     6.3 @@ -79,7 +79,7 @@
     6.4  
     6.5      
     6.6      pubkey = gpg.export_keys(fpr)
     6.7 -    privkey = gpg.export_keys(fpr, True)
     6.8 +    privkey = gpg.export_keys(fpr, True, passphrase="")
     6.9  
    6.10      pubkey_filename = os.path.join(pub_path, key_filename_prefix + "pub.asc")
    6.11      privkey_filename = os.path.join(priv_path, key_filename_prefix + "priv.asc")    
    6.12 @@ -93,7 +93,7 @@
    6.13      privkey_file.close()
    6.14          
    6.15      # Delete keys from keyring
    6.16 -    gpg.delete_keys(fpr, True) # True => private keys
    6.17 +    gpg.delete_keys(fpr, True, passphrase="") # True => private keys
    6.18      gpg.delete_keys(fpr)
    6.19  
    6.20      if (args.hgadd):
     7.1 --- a/test/include/EngineTestSuite.h	Fri May 11 09:06:29 2018 +0200
     7.2 +++ b/test/include/EngineTestSuite.h	Fri May 18 10:19:50 2018 +0200
     7.3 @@ -23,6 +23,9 @@
     7.4          
     7.5          string current_test_name;
     7.6  
     7.7 +#define TEST_FAILED_MESSAGE_BUFSIZE 1000        
     7.8 +        char failed_msg_buf[TEST_FAILED_MESSAGE_BUFSIZE];
     7.9 +        
    7.10          std::map<std::string, void (Test::Suite::*)()> test_map;                
    7.11          
    7.12          unsigned int number_of_tests;
     8.1 --- a/test/include/test_util.h	Fri May 11 09:06:29 2018 +0200
     8.2 +++ b/test/include/test_util.h	Fri May 18 10:19:50 2018 +0200
     8.3 @@ -31,4 +31,6 @@
     8.4  // Grabs a new uuid for your randomish string needs.
     8.5  char* get_new_uuid();
     8.6  
     8.7 +bool slurp_message_and_import_key(PEP_SESSION session, const char* message_fname, std::string& message, const char* key_filename);
     8.8 +
     8.9  #endif
     9.1 --- a/test/msg_2.0.asc	Fri May 11 09:06:29 2018 +0200
     9.2 +++ b/test/msg_2.0.asc	Fri May 18 10:19:50 2018 +0200
     9.3 @@ -6,82 +6,82 @@
     9.4   <three-OMGWTFBBQ.edfddffd839274982347239847@pep-project.org>
     9.5  X-pEp-Version: 2.0
     9.6  MIME-Version: 1.0
     9.7 -Content-Type: multipart/mixed; boundary="575522c015668e2f9cbd60105375cc"
     9.8 +Content-Type: multipart/mixed; boundary="3707bbd2378d65a16829c3df64cdb9cc"
     9.9  
    9.10 ---575522c015668e2f9cbd60105375cc
    9.11 +--3707bbd2378d65a16829c3df64cdb9cc
    9.12  Content-Type: text/plain; charset="utf-8"
    9.13  Content-Transfer-Encoding: quoted-printable
    9.14  Content-Disposition: inline; filename="msg.txt"
    9.15  
    9.16  this message was encrypted with p=E2=89=A1p https://pEp-project.org
    9.17 ---575522c015668e2f9cbd60105375cc
    9.18 +--3707bbd2378d65a16829c3df64cdb9cc
    9.19  Content-Type: application/pgp-encrypted
    9.20  
    9.21  Version: 1
    9.22 ---575522c015668e2f9cbd60105375cc
    9.23 +--3707bbd2378d65a16829c3df64cdb9cc
    9.24  Content-Type: application/octet-stream
    9.25  Content-Disposition: attachment; filename="msg.asc"
    9.26  
    9.27  -----BEGIN PGP MESSAGE-----
    9.28  
    9.29 -hQEMA1oCBdlzCD9NAQf+J35kigceuUv7sH8/z+fhiFkBjrDuppkEWQRE7/XrD1Br
    9.30 -YTIjoOpg4t/NrYXNIlXplnvuv+iXCpc2pKh7IySdgkROE3tDCEDkU6eAMOywsLbI
    9.31 -2T/UZ8fwr/4UOmSyfba4QkUhKUg+Qh165pGKNzMfwdSPbLl2eWexTRwRSQGrNoq6
    9.32 -WxfqwjIknXEGzb+O1duxbTszZooJC78c1vwwiZhU9PgjDsuQi/elkB8xkeq2cNen
    9.33 -pGDvODb2rp+lWpEIKbPiS6uOQLto2hJ3j80sWdgwwrcEOrtlfqwjWFCBJXQCGNOF
    9.34 -QlJ+X5obaSz3eWfSUFI8hyOJRCOpygsiAQVJ/FgSM4UBDAOo6/9vKSPoQgEH/jON
    9.35 -1PMlicRZU1kv2M/sdhWcO/kkz+5UNmciPglGX/KbS4TvIsulRoym3Z2HoTChTeKr
    9.36 -8bnBrLQazgqUtpP58gfLksQvbRkDW/tYPntgyvoWQst9i4NJhQv9soyfuJGkewpV
    9.37 -s4uBj//kEBPOtlBRVnFTnETBkSt3VxmMIPVnSne+X4pHIPk2lDquPI268HgLWiIZ
    9.38 -XdvsbIChLlykaMUBJDu5vULaBnNre6A7gJa2cn60BDnfE+PLahiBEssWT2SCJgOk
    9.39 -1gBuiuHD5Ld0PN8ZCPXeQ7WnugNfjS3atPGzUMKGbh4Iik4qF/iO/h6MXXJbLk2t
    9.40 -jk9A43x7jQr5V2D0SvvS6wH3z465jR/j1Qysm+YP+Ji6EMlc9nWsSI5tesrMEMUn
    9.41 -TbwjjLMJsSaufKVgd139lXiyr29NDogwfZb29qLcvGOU53MQXf6TBrcrFJDfOUaz
    9.42 -gcWvBczS89G3hfBxy3yn9ID5jdd24/gndCGv0Ps2g902tdt7sN3Y/wcGHpdvgDpR
    9.43 -MO3MkFVbevjyqcslYlr7/r8bvXXdST5eFRuq96xsT2smbanLLoIrt4j57K0d0ELx
    9.44 -DYh/Iq6JmnU0SEhElqg+VPvQVsWRIpcrjkMxvjV1v5z7Gx9YbUv5G2akW2BoMNMG
    9.45 -dq4372U1QXpvw+efpr9VGGQlTJLcXy5XJdmz/n+bt3XG7M6PA45Soj83E+84cNwM
    9.46 -lHT02edZnqQC6Tw1x5yLWby1KgKtajgNYw0qL6pZWRz5sO37Kms3gFUiMST6QANA
    9.47 -7JeBulhvBZiigcOq9vQIKg98JXuSzquIQUW8pCdf3xZ/FuAz28DdIBVep+Kaaujk
    9.48 -n5DqwyxmEBrJJEv4uuZBoWngBiyU++gJX/nItzqF40bWYts4v4tzkFlRa6kuE5Pq
    9.49 -h2vO8TvMt+IuYedy7DKNzpNYfSmC+KJyk8ffCZPVQPId/beDJLU4Aq3ONi99Len2
    9.50 -DoZFPVhENXw+wl4R0jyERr/d/E18QcF/HJz/YDJR8pfb4zUJPUIkbjt5+lSo/RB7
    9.51 -6gKzKJltvz6eB5dNkZ0LZbe2fJ7YnXQxQR1nEt+FPuoPiJ7JOXYOktSSwaAZ6cXW
    9.52 -KbXRTsTQ2A7YSCeQF+WJNLDl93OAJqRaJOrvjGiJ8+WQjFZX44GYV+3NXuuK8ufZ
    9.53 -twGVLOj6cM0rHyAi7BykQ2XK5fxFhEspK4ck7Nh7h9wCAgwEWFapTe7JjSqaJaGS
    9.54 -Si+CA5tZNIp6TsfNEt68QoCqzheEP95xI873QvCt3cMK3HXC2CbDic58RghWv2bZ
    9.55 -8QraqeHntJHhvxi5jXjBEZeqjf/WgAo5Y7hufmN2FIYeQBzy6nHkl9pIhz18JFKm
    9.56 -NJDRYXvUsTPcPjY1wTWN0MXoRVBNfgiZ+rkzGKZViqTlhLXmE8MgpqFcUQKJzn0i
    9.57 -IcvAvaG3pCXgSoJRCxqEC+cyX2KDMpcanqphddFLCYhkya5+1uzcW0vrNpfH7cs1
    9.58 -4sW4iqNrc91cHSOLs59i+dzAI73pk5YLwZhRCqOVA5EwWsJoic59iOvu+el8sgOj
    9.59 -PaYdIz8pGiDquuSye3JObp4aJblDP1LqAnUFS7mL4vpj4pc5jSaHq22lYYwA4kME
    9.60 -hUn8ES4+0RrLDOzkj4VEI43jlMBG16Zr+uxbawERrIJeOXrhBiVn4UCutr8DS8wG
    9.61 -RGD6x5t25/SXvV2FYNkO7RMpFg7dIYM2cNm3W9GUVZ5bdDzKcYONuNyfkDvgx1T8
    9.62 -2Qz57aUNasRKA9c6J8s+jihz63fii9aau7Npb2JSkpmedyQV9sLll3sycxjOcnoF
    9.63 -i5zFkDCy+sgNo7wRzkOkkjuQyjn0RoMIQJv7tUVnoBJPpZYkOStteryH3NJdvXd/
    9.64 -Yl4qb6KeE6EvTyjnf5DDdOFKPzLJBPyHS+3i4MfqvPz/KHXR7wNVy5Dvemcqjadc
    9.65 -N6zGlRVIL5DpgZXhO4lCt+VeqPFKvbO+1lU3IA5SVaeUmgpGbpoyLWsrcdbEUiaZ
    9.66 -rGTycegXOCunDrRRDR6org83shONzY3N3MUvJvH1rnSm4cJCaAja91MVRer3qs4M
    9.67 -i9FlWQjGksFNt5fezxESzvMotbfGh7MOepYZOXjbGijmqA1CSsUW9abhb9r0VeXU
    9.68 -brWlCJjNsBwvvGTvlBOcoJVXliA5Hp8gixL9XmBD51SsfNUMKupSOGEObIHvVCFG
    9.69 -9blBt+HgvaGj5XIzGLHm2BHah1bnex6zzgYZEpBwe7M2Y8IF4x61kEBy0BrFw6ID
    9.70 -rn76e8av9uF3Ps8p60mP4fBmNHQXRMRfkync5S563dHiHdkKzEy0e2CGCf8jup2q
    9.71 -3Dvur75MVsBce3FjOeUmWRhIQpsWHDzC+KpHGGkOakXbu7cK44x1KktZN37XdPGd
    9.72 -3VlBV8cgAQATeoFStPZTV9OUcKPWXDa+xF2uKZbY2P/c3KLvdlE9JRXCCvjVtkil
    9.73 -z+v15GJ69rMqjjrfEfFasWpWb0kck91GctAN1RGdVRq5mPHjcauPLONC0swG+uM6
    9.74 -WzupJFdlvlxA8LgAOa3tScTJfq7iY1yyqu4brte4479eJtys4IfqFKMo9cmGRCtv
    9.75 -Wkh65Z7zuV+MqwTyffgi9POu4HAqvfI8Xpt1I3iEx6WWIYsJYZBg6o/XqlNjvtiX
    9.76 -ejfTfxy/VqCOXT2oha5zbm0Fv8K6r3nLWNW8ZXbTvQOKoRBBTzB+b9sGaN+0mhIR
    9.77 -FCBP7D9plmeIzl7HwCBzqcaa/eIEoEkpHTnw1vFESqVbvRLUmHtBK/WPhOG6+M4h
    9.78 -4S2hLmj2jI0PJEmHQk3h1ICY9CAk9UvRRwdlcNhUDNrsYnpCNN7Oojp6LaJK5t7S
    9.79 -rBQOiE8gsGTBiyk8hZPT6hUXHA1IBbsOAI27kBhvQZztSlg1Ua2GxBBv+g9VRvxg
    9.80 -//kX1TXXLAYWJkwhrX4+aFQxFzOS6lBUb3z4bFDuRWPg+EfsISCvAWjdfqcnQpfC
    9.81 -lveWi+zqdA562WiT0MypYFSbm4S4uIo1s7aHIbziY8bIKMN9cMEf2PthM9TvPeWw
    9.82 -ryxOu63gQ3lJjtyEH+aoKOXGD7BXsHYk2Vu8l23Qt/nEQmF2ly5paET97RmjXmqU
    9.83 -ckNfjhrPn9LIIgAT2c8bwlXKQRcwA2mZCs+mPI5iXdT9eD0NLu0xMpbewATQ+/X3
    9.84 -qF17ExhcUuRnAvuNKtMG4woQVtOTO5Hv7cCQQ09seYczLT/8bvS5vj8KHfuKBktI
    9.85 -YLLGlEFMAVbSvS2sge10lcXJlg==
    9.86 -=EixP
    9.87 +hQEMA1oCBdlzCD9NAQf/aP0r+AcoAtTa2PpqnfdMriHZW84LJyTJerLOYeP/XEYh
    9.88 +DsGPQZIhhViOTnXx4l6/wG1UHQjJF7F+rvKeZTRrciJnLzhRDDHsli2lGXrUmbEM
    9.89 +vmUG/gnMM3YMjq/++/kZUJ/FTr6C9/JYTofueG4hYzYJS8kMz0m33Kiep2x+Btiz
    9.90 +cjJVLEBPxt5cRLZujIfEJTenE+yle8nNFUnkKuPg5xPgmGU7ITtvj9RW7bWe8/vU
    9.91 +D05avbzmVg3YNynUdJAN4hbrO1oClQXj0T5x8H5e0X4OmwoPS9z8lnuzBWBjxXnR
    9.92 +sUtOBT92iTAuTIpRB/rNUgPWWnzumuzk5wDLvbeZy4UBDAOo6/9vKSPoQgEH/ion
    9.93 +oXxLtkz2V0HOMzyQ6sIIYjpD7GdPukjpzFfAKKwsQM2j2pb1Jg3Q1DLMmup55x6x
    9.94 +ODdhjx+1UrX2BBV2jShLzebkJ9hQ7dWzfGXlVe43YPUaHCNb5Nq6Zj31kePibDWg
    9.95 +4+ZcuZTAZzQGHW5s/pAa1wgK2PVwvMrNQ3SelMlc/jR8XtsYF/JIImnotaG9yEIa
    9.96 +sKkKvX2tlKMrbLDj2oUYKGQtaRRjOeyUIpqf9F0zvN9IusZ9unDzZGb4y9p4JEHw
    9.97 +vB1ELaj1eYEeoAS8D21z5x8vy0FFYd+2JP9SvmkUYweSvoijN1xQI+ZX8m0AaDy/
    9.98 +pUMl1ENGnIEPLgwGNBfS6wHAKDIiHE3ghX/SGHoSyfxZFmGcc1lo6pCLZlKGosJ9
    9.99 +uoGZHpQS5Lfe43p7x00N1kNbxYh1FEp5W+BB3XRL8FtFWTLNwwCSTBVD8hHnS+0H
   9.100 +WEJTVbWPWNzRzOVUJWnU2jaNnaEKmrwtW7GgwWh6xGnh/M/+TYNeIXs4xgsTaGIu
   9.101 +0++zO8tGhmo1Ut6o6rW+G1OThSoEDY5uRVepMx8TtucGbjNp87AP6nxHutJ7JSZa
   9.102 +SaYlJ/YwQee9PIEBEOuyKhuXEFbR1Zv+cB7nEYHTKKsha3kBxigxcvXkgnpokZRY
   9.103 +677dkF8HILbwKlKCzNYJpb5Xgs/cyDoQEynVrT7ylpuUiIsaZfWcfjRhbiRwrwEy
   9.104 +YL5Z4pEzDX+B0ieQCQQtsD8F5uiIqxpjdHkfTwFdeLZlyTI006YEVK9ugSa12JWK
   9.105 +PWHiCOkHyjVs50fOCWq2uH2WwcaX1+YIL5RnPthxYoljVmIfT/xCik3kgL3+X5iL
   9.106 +h94qRp9E1Es91eYCKnI+y5yNNAWQht5ze6VigZIJiNveOEOJrsyUuBLEuOlJ0WMR
   9.107 +K+Qo93GtdpXMaXimvZihcTwwPgRRRYXFXuAhJ+54E4+9L8my4tAsolw8Asxdhxtn
   9.108 +kAxsofA8kS0+WnZkZkWKkV2llrQTvM9TYikaFWXuV5joumA9eHjUoVuavDuMCZ8R
   9.109 +B4qtVJ23MZAafzWw+gITsLczuH7LnmRKflZ8eYLUHXrA2DnMN9je3qJCBYFRpYuY
   9.110 +/RMCyF2pmmVElUBCDvSfrqy/ZwZtshlU4ohD4BWdsmUhhYPgy4IUWoPGOGh1KQkl
   9.111 +IIZlo/580/cU/TlhSwLB3mDrc5LBkLNtEN5Ii21LkVk+dkZ4kJIoyuvf7TEZNuRB
   9.112 +xv1jrnQXHz7n9TeMPfY1DlQRVMLGo67TVwpu58swljW+wV/wrNuArgEQQCivdqWd
   9.113 +QUxcpJFGZ+vEXvff0diW1fEYuSTXFU6ucLsER3m+NYHNe+mk0hyIodwy3g91BA+m
   9.114 +wDzwn3VhULIVBSvvQmN0VdYXG1K5RlgjaE3Qz8OZ63AjdDodAWqPvpqDPe2eKDoz
   9.115 +8mHTP6NsXIeWJxguabwfQv3zOuFomDFjSb5t+ew3cS4gnZn12/1FKs7epZ6O9PmH
   9.116 +uqMhiqM3CQDI0PcScV/qOqqINktnVR16MArUm9dXA6TXcLLblpNzMadAaMxj1+jd
   9.117 +q4vcuPuaJ6x8vTtQbBq2W+fZ2a8o6lvueXbHCD4vPB1ViRn4g1qWZXbS21YZyd1e
   9.118 +JPQexaTiWWUgsoGmGvLifwFJCi/sjEPDmSe/06AGPlKh3q+g7oFM8cD83faClzF1
   9.119 +0pqJRMmvyKp5lPgPD+tvG/XoG9aguVFTWulX0y7gAJkxLgVkDEy44+RKiX8q/Daj
   9.120 +EeIPdo5FbHK7WbF+tXGXGIHrYcJvwd5/aK+QsQc/h1wfK3U0s0kJokGmceOPVjE4
   9.121 +EuuM1NK1TjqGTsopMDnnC5mzNvwiiz5QsxdVquXCopd1PpYm5dV4DK2hYlf9ENBA
   9.122 +ahHeFQWZRppoHKHPcdZNRM7fu9ucGVVG3MbZTM+qi4nfAATVT5BWrmJRN2t9BX2h
   9.123 +3MQWEeA+y+drFiiK0lBX3j57oJcMW1vTIAAk0EOYPVJgMyxyYhqbTaw86PcM72mR
   9.124 +czpg7bnlKElujGwaw8AKBLe/XC0sM2hAqS0f669bzCCPE14BLIhrbp3UEXgiX2vr
   9.125 +SWhH1BHZxle5SE83B+LKyMr/sM9r5SiRTyK4pNuM9yT+gl0hNKpsx5K86XKeRhuU
   9.126 +46qa26uhmR0uBwypW/YiiwSuyQ+fXpJtnqhi98y/KRtivaipSgRZVqdfXOFJiuZJ
   9.127 +CRTpcEvpErHCnWvJK3jSbclFoUZdcCr3NdWBy5VppxRUa3pzTJokCd5znjVfFffx
   9.128 +HAXqqM1pGOgV99LFN3F30GqGfihX4HzQBcE9zwTIanWBnOZlqqVC5m5ne1Ar4zGB
   9.129 +z4DgLd/i8H/cLNwHDrD/gkIZBeyQySQp8T2SXRjSLnCKqiaNpjE0W0bOhSjI+KSu
   9.130 +gY/qMl4KrkiVxVOB76onxCIQ9jhLtpL8mJQYiWM84YhuA9PpFoj/+Xj8zicwafjs
   9.131 +ri/AYnyNZhmbMhhgMLJyK5iajShPJvQqJYIGqW2VFkKfC72MGgZXaNSf9FEfR60P
   9.132 +VonbkSZ947CqQ1EmdJiYAaUJAfBmHRrfMbhuBfXAFi6drMlImOOAocoxMTVdsmsI
   9.133 +raC6HDzTnCeeceIGRdpzRErQcoN2EaEUUN3Sfzktzwk9NNNxyFCT1ElxTDfNAe3J
   9.134 +OmHFjhz4uj+zaeW+qfA4HtzkUK+3i2Ir8pbUV8GC6jZ4PNsqxoc5gGGezjnMnzq/
   9.135 +lLL+FbRYonk6qNws7saxT1EBELTEkmoNa9DTafLq6jzg/TghFX6c+tSR1VYIxikQ
   9.136 +oGB17QAb9Z8lomyHvy6rgYSgqpIDYyNSD7j/Y36m6BzOISBo6ajzfA1cxPpHGaQD
   9.137 +6+IJ2d7EWkeA+EMIZbC9UsybqOV+JP5twPhAnrN/aFuRPLOROfA3Eu0InjA+O6Eh
   9.138 +bDfD85zW5YeWCdfSKDwgr1mW04heGi378MpfyQpk8yrjuZ7mFbZ5XIsT/5mkGbtu
   9.139 +1KR34/KUVAf+gjjypfB2dFyDAhwVVvgg2bLUx2hTyQjDYQYC6x2ahBpE0bqslNvF
   9.140 +Ww7EXMZ1MbYXbeCk601QzHpBxpx4+RL+p4qpn/e7pe0W6tojaPvtmH6GfPBf1bKP
   9.141 +cry6i/eN3tJAsNPbjUo9/sWyzXDy37EUJn30lFALEXGBTpjP76d5OT3t/Uj9ioqW
   9.142 +yhet5HvkreX7KFUBCw6vS0/RPsdVO6+KWOYP+ZsTaDDnp4PwLfMqEfFHw+Iz9XfD
   9.143 +NqU94u6dsxyATiQ7B1URdM1VBw==
   9.144 +=uubX
   9.145  -----END PGP MESSAGE-----
   9.146  
   9.147 ---575522c015668e2f9cbd60105375cc--
   9.148 +--3707bbd2378d65a16829c3df64cdb9cc--
    10.1 --- a/test/src/EngineTestIndividualSuite.cc	Fri May 11 09:06:29 2018 +0200
    10.2 +++ b/test/src/EngineTestIndividualSuite.cc	Fri May 18 10:19:50 2018 +0200
    10.3 @@ -24,7 +24,6 @@
    10.4  }
    10.5  
    10.6  void EngineTestIndividualSuite::tear_down() {
    10.7 -    cout << "calling release()\n";
    10.8      release(session);
    10.9      restore_full_env();
   10.10  }
    11.1 --- a/test/src/EngineTestSuite.cc	Fri May 11 09:06:29 2018 +0200
    11.2 +++ b/test/src/EngineTestSuite.cc	Fri May 18 10:19:50 2018 +0200
    11.3 @@ -44,7 +44,7 @@
    11.4          test_home.compare(prev_gpg_home + ".gnupg") == 0)
    11.5          throw std::runtime_error("SETUP: new GNUPGHOME threatens to mess up user GNUPGHOME (and delete all their keys). NO DICE.");
    11.6      
    11.7 -    cout << "Ok - checked if new test home will be safe. We'll try and make the directory, deleting it if it has already exists." << endl;
    11.8 +//    cout << "Ok - checked if new test home will be safe. We'll try and make the directory, deleting it if it has already exists." << endl;
    11.9      
   11.10      struct stat buf;
   11.11      
   11.12 @@ -56,11 +56,11 @@
   11.13      if (success != 0)
   11.14          throw std::runtime_error("SETUP: Cannot set test_home for init.");
   11.15      
   11.16 -    cout << "calling init()\n";
   11.17 +//    cout << "calling init()\n";
   11.18      PEP_STATUS status = init(&session);
   11.19      // assert(status == PEP_STATUS_OK);
   11.20      // assert(session);
   11.21 -    cout << "init() completed.\n";
   11.22 +//    cout << "init() completed.\n";
   11.23  
   11.24      success = setenv("HOME", home.c_str(), 1);
   11.25      if (success != 0)
    12.1 --- a/test/src/SuiteMaker.cc	Fri May 11 09:06:29 2018 +0200
    12.2 +++ b/test/src/SuiteMaker.cc	Fri May 18 10:19:50 2018 +0200
    12.3 @@ -30,6 +30,7 @@
    12.4  #include "LeastCommonDenomColorTests.h"
    12.5  #include "PepSubjectReceivedTests.h"
    12.6  #include "MistrustUndoTests.h"
    12.7 +#include "IntegrityTests.h"
    12.8  #include "StringpairListTests.h"
    12.9  #include "PgpListKeysTests.h"
   12.10  #include "ReencryptPlusExtraKeysTests.h"
   12.11 @@ -68,6 +69,7 @@
   12.12      "LeastCommonDenomColorTests",
   12.13      "PepSubjectReceivedTests",
   12.14      "MistrustUndoTests",
   12.15 +    "IntegrityTests",
   12.16      "StringpairListTests",
   12.17      "PgpListKeysTests",
   12.18      "ReencryptPlusExtraKeysTests",
   12.19 @@ -88,7 +90,7 @@
   12.20  };
   12.21  
   12.22  // This file is generated, so magic constants are ok.
   12.23 -int SuiteMaker::num_suites = 35;
   12.24 +int SuiteMaker::num_suites = 36;
   12.25  
   12.26  void SuiteMaker::suitemaker_build(const char* test_class_name, const char* test_home, Test::Suite** test_suite) {
   12.27      if (strcmp(test_class_name, "MapAsn1Tests") == 0)
   12.28 @@ -127,6 +129,8 @@
   12.29          *test_suite = new PepSubjectReceivedTests(test_class_name, test_home);
   12.30      else if (strcmp(test_class_name, "MistrustUndoTests") == 0)
   12.31          *test_suite = new MistrustUndoTests(test_class_name, test_home);
   12.32 +    else if (strcmp(test_class_name, "IntegrityTests") == 0)
   12.33 +        *test_suite = new IntegrityTests(test_class_name, test_home);
   12.34      else if (strcmp(test_class_name, "StringpairListTests") == 0)
   12.35          *test_suite = new StringpairListTests(test_class_name, test_home);
   12.36      else if (strcmp(test_class_name, "PgpListKeysTests") == 0)
    13.1 --- a/test/src/util/test_util.cc	Fri May 11 09:06:29 2018 +0200
    13.2 +++ b/test/src/util/test_util.cc	Fri May 18 10:19:50 2018 +0200
    13.3 @@ -137,6 +137,12 @@
    13.4              return "PEP_DECRYPT_NO_KEY";
    13.5          case PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH:
    13.6              return "PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH";
    13.7 +        case PEP_DECRYPTED_BUT_UNSIGNED:
    13.8 +            return "PEP_DECRYPTED_BUT_UNSIGNED";
    13.9 +        case PEP_DECRYPT_MODIFICATION_DETECTED:
   13.10 +            return "PEP_DECRYPT_MODIFICATION_DETECTED";
   13.11 +        case PEP_DECRYPT_NO_KEY_FOR_SIGNER:
   13.12 +            return "PEP_DECRYPT_NO_KEY_FOR_SIGNER";
   13.13          case PEP_VERIFY_NO_KEY:
   13.14              return "PEP_VERIFY_NO_KEY";
   13.15          case PEP_VERIFIED_AND_TRUSTED:
   13.16 @@ -204,7 +210,7 @@
   13.17          case PEP_OUT_OF_MEMORY:
   13.18              return "PEP_OUT_OF_MEMORY";
   13.19          case PEP_UNKNOWN_ERROR:
   13.20 -            return "PEP_UNKNOWN_ERROR";
   13.21 +            return "PEP_UNKNOWN_ERROR";    
   13.22          default:
   13.23   
   13.24              return "PEP_STATUS_OMGWTFBBQ - This means you're using a status the test lib doesn't know about!";
   13.25 @@ -317,3 +323,13 @@
   13.26              return "PEP_ct_OMGWTFBBQ\n\nIn other words, comm type is invalid. Either something's corrupt or a new ct value has been added to the enum but not to the test function.";
   13.27      }
   13.28  }
   13.29 +
   13.30 +bool slurp_message_and_import_key(PEP_SESSION session, const char* message_fname, std::string& message, const char* key_filename) {
   13.31 +    message = slurp(message_fname);
   13.32 +    if (key_filename) {
   13.33 +        std::string keyfile = slurp(key_filename);
   13.34 +        if (import_key(session, keyfile.c_str(), keyfile.size(), NULL) != PEP_STATUS_OK)
   13.35 +            return false;
   13.36 +    }
   13.37 +    return true;
   13.38 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/test_keys/priv/integrity_test_recip_0-0xF390A40D_priv.asc	Fri May 18 10:19:50 2018 +0200
    14.3 @@ -0,0 +1,64 @@
    14.4 +-----BEGIN PGP PRIVATE KEY BLOCK-----
    14.5 +
    14.6 +lQOYBFr73usBCADhtXwG4vKooTHixzhS3EEMCdqX7DS16yF/cpZJkHfHjahe+JbC
    14.7 +hOUFWMLQI99/ZXecsKNq+Vx7g8/krIyL2qvfwGY4b9RIS84CzxPyDlJ1hgoRLkLf
    14.8 +7qekLL0y25BvP7ZmqpFbtm44MP5jlK5a3GEGlz5HjMcfWVJiFPQ0q63TG8xfP1Zp
    14.9 +RUrbVPdZePFERc3IZGnj6nxhwfJLtjQtx6CZgraDslJZqBTIdeady5yBWNYaRume
   14.10 +Ei+ZH+Whhmi0UD6ojhYUeTtnLRDR1cQwKqx1tegj1zVsXRkipVxTV1jy2qeXkDTA
   14.11 +M3JWObn+qOcFz20uvZfDAkb/01W7Dwaf/C47ABEBAAEAB/wOfgioqInMKg158jC7
   14.12 +oUjL7RYMCy6XP7G27TSZJJ2MQpw8/NkxRDcwULKxipwfIfS8KttTUw+NHrmKhUnA
   14.13 +8Rl4FHJ7zTJkMfnYVFODh0fkI+chk0bX+grpj7XWPiLYAc9EaE9NBDmvgfXTjwhi
   14.14 +7SONuMhW78MZUDLp+U5001El7NQgB/0FeHnx6HLlCkUUK8GDMpp4p7ywfWZYcFJT
   14.15 +KzJ68idR4+ZfISdgRGGHx/hkOu4DS5El8Krrv7VuO83dwSO5EdaSziwYlFbzNLVa
   14.16 +rAuTl0ZF2kqtRR+f5u0HvWcTj/5D9UWT4omlELjzA0lzEcm3pVNWVL6e2heS2zGq
   14.17 +AaCBBADoxW0CWyfWMvZuwcgXj+Bd+bwyFM3GoZq6yAIb9T7ECO2SE+zqzV/Rvya1
   14.18 +zVqjjbVe4MiPRCHZ4y0O2pi0FLYYcd2J0m/QGzj/pBKaJZai7BoSpudqVQgAbgQA
   14.19 +fcHxRLinX8ZDwPS5xTezhf0wBh8MnHnhB1PbItBi/T+mt+H8ZQQA+DujyQQL+Gf6
   14.20 +9Mp6st06QxhiRrK/6dAWQOSi5GtNJDiyNLz1kjFMu6ZIRIPweatn8+z8n16x/GCe
   14.21 +FTLmJ9/n7hwR6HJq0wm8nOMTbzB0gkJg1LB94Aup+Ec2eR3z5TAi3O+LEI/JF37b
   14.22 +NfCgP9v2qAcg+ikum1cgu3G3vQj/Rh8D/REwRAZUbvfTUaNDIayK+OzZrgGrhIQJ
   14.23 +ZR2gVp/Z997T4RsDwtyvS5WpD5zJ1iHpwZx9RBP1Gw3SuC8VWJ1sPLFf2fCLMEvc
   14.24 +ZTNVyJ3KprRygl/skdDkMNmFADeVWsUTLXRpt3dKG/XPlZagfevVIIzJktDiH6Jn
   14.25 +iee57pBs64pbSSG0OUludGVncml0eSBUZXN0IFJlY2lwIDxpbnRlZ3JpdHlfdGVz
   14.26 +dF9yZWNpcEBkYXJ0aG1hbWEub3JnPokBTgQTAQgAOBYhBJ2AR5iYQc9CB+oVKkrK
   14.27 +9zXzkKQNBQJa+97rAhsvBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEErK9zXz
   14.28 +kKQNZ4MIAKFC1nK1gRghKXILC6ZqchVjbYeSJn3nOeZC2KN+NFYTSFowSgku5BYn
   14.29 +F+R5pslk6LOKhc//zsFiyY2fzmXac2uHilZeISwmpR300ZrwWrp0VDH3XnrkH9Ep
   14.30 +wnMXlCTMH1O65J7mfAYGfp4xD5RqcTW9rD9oxjy0EJ1BGwcs2TT2bqilsYjPVsVO
   14.31 +p0bFMKpjf3qFdWDIasRfSOLNM1OeNczGNxh4u04iCrUiWR2uy6tkSIHx/BF98aOL
   14.32 +NSFbqmpHqnRyIyDz15SLbX6dsYx2b5uutDwn4f4zhrYBuHFW+8c7AhZjs22HoUsa
   14.33 +TDMjLyWHW3/qHfkiiDCRHI9+s0Q5kWGdA5gEWvve6wEIANltXi9qBuA904IR/sqz
   14.34 +Yn5lY0scJ7AlS+74DY516s1hd21dNc2BQOeHYR3VN+o1DhPq1lKgPZe+7cS7vpPo
   14.35 +UZuoNl2euMGHxQU9wbp0DL9qaUQx3jM2IEN6efZDSl97DR9PVDJfZfSwqh8zHJb3
   14.36 +viTBBrcRMjJ3XWg3DYC02y8RpzdguNiATYubm5uqUMbf1QvZ2MTWIyl1pObINBsU
   14.37 +RPhVy3NciRrPfQrTai9DqrqMOqLicz1KPkFSc+6W+gYQeYWhcXvq4ZEm5r8vt5DX
   14.38 +5rFTo2WieNoD2AP5+xZ8Cgs6JVpIUwTRy0sOGU5e828tpyXR8iF31gtpPrJhfUlV
   14.39 +VGMAEQEAAQAH/A7KO7/p7HHQgtS0OKq9LRP//ZMcZS68OsAUq4dnSgOSf7c2wfQq
   14.40 +uKmHMfn/iQArf7unG9EfCVGLMU1SoBIbmYGHHbuckmDHxYUnwEfYoQ1cRbDX24+M
   14.41 +PQGaETXJOgPosOnSUZ3jk2Hjqo7YwTcbvxls7/H//3QjXn06UXbR1p8K6kUKfiPy
   14.42 +DMp0qOTj2+3OZnJm57VFi0eLmWNe9qbHhZCj72xkPDJtflqjtvl87WsY7Kc/to+n
   14.43 +9XiCr3DaMxTJR1px9STDePiOj/6BK5ah339bOCRki+6or9JDlxV0nybX8D2nBr4S
   14.44 +mpu4QzVbkQhHpQFV3JxdOOLvSJ5/nadypUEEAOgi6X7wlwdrB8IKUFT5VvMZsdJP
   14.45 +3pnVI/tAdED07jR6cJKTcLvumQP7hr0e7OAqYZ41NgEDeZ8lx+kidKQmunJBXRP3
   14.46 +xcdKIJWqFlMimeIi7YbLw45y0/7awtKpiHNmKjpfXfUnUkupM/E2LUa+ErZbv2iI
   14.47 +8VQjkKr5RT/7qkuzBADvx1uYLB77N1ltv+/uJ6w95PxgQlx1KwmZK6XzgiIjxvfw
   14.48 +YsEojhUfH/LivpJYoX0zylYXEkbaHQZ3wkcXVmoee286VK02/PkxNTCzksueupMp
   14.49 +XyScWdQrru8vQauK9ff3hbIutrdkKiD3MLo1Xy2zv3TaF6xzbPJxoA9AsBO8kQQA
   14.50 +7JYKdeB4azXV0pu1Z9XE1tPDfqQhuH92kc7wAgi4MnIskG/rnQdJTpt4v6X7PNZ5
   14.51 +xMKF/KJgUKOhDkZqeteTBb5Ju7HmE+a0KPEbdai93rswSwD7MttuBnJ0IbQple1j
   14.52 +CKfesgZ3AUKo0+0qau8eBS3YgmJjaufO5JtElmIpC65H84kCbAQYAQgAIBYhBJ2A
   14.53 +R5iYQc9CB+oVKkrK9zXzkKQNBQJa+97rAhsuAUAJEErK9zXzkKQNwHQgBBkBCAAd
   14.54 +FiEEXK1CUUbxlJ14LBUKurkoAKRaNCUFAlr73usACgkQurkoAKRaNCUYRAf/Y1fR
   14.55 +r4wcv8p4QdWJvRc49tE3pA3FCsNOG7L7qkVpyeo0v8aLj2uYccsxQLhizK7usTQ3
   14.56 +b2jgFP+s+IUZ28Ex4gRsSGO0d1+CXQR2xHPUPhoTwY09w8USPqNoFfNs0SjLccsc
   14.57 +JDa4THqaE76svFK/5z7eDI7PPoho3No4iZvE6r2lItHjYtu7qVsC3kY94XSa06W6
   14.58 +LwCCa7ntkM6sMCC/BwoCuA8Tf2DYsUwygjOY0G/ESTRx4RrpD9ubMzT1K0OUZ+4V
   14.59 +M1D8As/uIcNxa4bzKiYyJGuiReeCqhXRrmQ8cXXGgXE2ik5kKITMtemmRft2ry48
   14.60 +U+t7Rwvy7PF9WHXrod5wB/9+2ccNnHTHHDJX+TgRHExrh16/2dDtjbZgUj3LTKoP
   14.61 +NelvNA+fzHKpxcA4Ggx9GaUbzpoo/ZKMko5doWFsTU0H2vbYg2V2YWjwEEYE7lzQ
   14.62 +jebWBqz0etkxgyQnXkB+phZeaBOcW/rzEwXHdQUF+z51QtB6Emals/ISLWxc5Mbz
   14.63 +216ym7LANJ1p658s8+ktj92j3mY4W9ERu5LoG4j+sRLtUvjZJ2+R9qrJkLtcjYF3
   14.64 +FNoqB8np+dgGaWEmvkaJw9lMj/vV2LD+tHc/pzYdwOb/cPyG7+311N5uWy9BlRxM
   14.65 +wd64q8+gdnIBAcqZ8Irt5dWCGkBlh1uIyyV1MI5EHu8L
   14.66 +=8JHC
   14.67 +-----END PGP PRIVATE KEY BLOCK-----
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/test/test_keys/priv/integrity_test_signer_0-0xFF26631A_priv.asc	Fri May 18 10:19:50 2018 +0200
    15.3 @@ -0,0 +1,64 @@
    15.4 +-----BEGIN PGP PRIVATE KEY BLOCK-----
    15.5 +
    15.6 +lQOYBFr74WABCADbzBMLyrH+kyBoQshc7aK0vOvxHvwURVNtuxBUPeqzIZ4bCvLB
    15.7 +Dqo2ti7bQ1uRsupCbwX/zx36LrCIUZ/U5huxmnfsGuFosnNVbXNNTc8IlnlR/1bq
    15.8 +ESe2xDn9iqUgzBC8Md4nSk8O6xyqpZYqN5PiL7Q80OdKak/ITd15YxwKbkHxaK8S
    15.9 +eEV3UrL51V3qzWGAQ42jujKVfG6HGGp5rJM/syW98w0FIOHavNQE0fR7utZoX30L
   15.10 +5N14soNSQ7Mg45o4sRs+3l7MNIkPGxiWbfVp/flK7XvrLd8WprvY2swTaHJ8xyQj
   15.11 +9jcvXE/tCgk3/z80g5NjwmRNjMSWfoBh8nm3ABEBAAEAB/4+UzpNXC8nwGFunw1A
   15.12 +qJO8C1weFcqmFthm46XoNVxxagVypqKaUsW6WOOlgg6bnG+n4eKCHKFj+UxOg1K+
   15.13 +pHdS37nEpgSn0v44SZ5p27fqt/xz32MuYSnxPegxuFhFmgfezYcwffY4BTwuOWEA
   15.14 +3JyfBSbnHdeP9uBjrIyyKIPhgsahO1DhcUCbnhGaT4u1pe8pWrtxDcZLSrjfdpxz
   15.15 +OqKl+PtGlg/QVuzoGSgndQugChVx05NJ3wCWLmGSnc2qZysCFr7pFkxMlDXa1X5w
   15.16 +ckJ3aZw8f/lHR/yUow+8roLF/zijPnLIQwsLt+l7Jz0FLufvUpmt7gVsnpZSlqcW
   15.17 +D5sdBADjCfrS1EMT7+AXbQuUWNnDdyIcyQ5+mXlwYZKnz87qbQ/N+llqgvikPMft
   15.18 +jOtR21Tlb0J0nqsumfd+KZ3k3fYtS9+SdyLYB9rk7mTTgLhjeRaaO5SsU/DFkBYH
   15.19 +I/WTWPecc6eSbxdv9m97DtjZbL8aBJy5bkkJgYKjJfJYRMQi+wQA99Wcby1ypyP9
   15.20 +6vfik49aWhjWGsQheSlTlcJKLMsefw2zDPDM4bLg31tSqSwHWfAoCmPzRTntegmw
   15.21 +vXFWL3WsIUzPiW4SHWtYcYzBr6WyVYE8uuvirkcYWSBMt8SzFfAQBphnHNoBQudO
   15.22 +DrC8f2CEi/NNWWPloGICFiCdU13a53UD/jZTGQZEa9cQmfpRLGJ/jBPkA152IcdJ
   15.23 +OkhHAQr311Ca7xWm06FWyEeQOrbvfmraHqhnLpdXZF/T3osw4ns8Qj4sRMczeGsZ
   15.24 +5hlr2D5nmLyTG8iefztEaNPGaPelaNkX1mMSUZcqoH3k0dP7omQ/5M1BayEza99Y
   15.25 +c3XOdtaknBSyPl20O0ludGVncml0eSBUZXN0IFNpZ25lciA8aW50ZWdyaXR5X3Rl
   15.26 +c3Rfc2lnbmVyQGRhcnRobWFtYS5vcmc+iQFOBBMBCAA4FiEErSFSbMpVZ7dh0hwM
   15.27 +1MlL6f8mYxoFAlr74WACGy8FCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ1MlL
   15.28 +6f8mYxq7/wgA0HkULYopcQoC9beigbWuZFTgZmnyOLpcFTqckmHZipVNfNtEN3mD
   15.29 +4tBvvPTD65ktvUJlk6DnhfNK3kWcIBuusbdvdlBe3RHcyJUDKlcx2t6XqoKnBAzP
   15.30 +ZlNqa+8wUAmVBmCkzhfQkhaA8fiuF8L5uatMIwMGiYePiKPGk9dFm0kVnYXGYFX4
   15.31 +kD2F2KnRCeHOwreLRzLpJjqIBm9+xERbd0L02VOoL3Sb+6dj1Swyf0v98uHjn4ul
   15.32 +tGfbBN+Ct3RNdY1S6RjKyS7xyjtEE2e2qrPtU/sxaHKz6wRqXlYnhz1I6ucCWauK
   15.33 +MOh21/zyxYXlmqChdpNQ3EYUhqLR9vvn6J0DmARa++FgAQgAuKa6XUzB4pJX0Zz2
   15.34 +glCwxKfy/zjj2UgxtQM61clZPC/NbHx1zbUciNzgnlZTTEEyNpMXsgFueOa8+Xz9
   15.35 +8dTpqBHCyU7X3YnZjYLTyJR7doQbI1lPA57RBT/8HmHlbH3gj7OeGCBRJ2vDXXf5
   15.36 +UWQiTQusCh8GqAvDXbhIUuAEU76Hf16FeBVd64x7tyYjbJRvBTdgqQRcMQWK4o4K
   15.37 +eIHf8MIktRtcK0lhGltwdA513dn7Sh9/SLGbtha0QLiusqIZNBl6nCjBr1Z9zMuU
   15.38 +JBn/M2S6L4sbEx9q19np762xh8wxSCzrZH8xAL1lIjBC+2wgHGnUb/KUzuX0/7mY
   15.39 +LCve8wARAQABAAf7BBuhdcXpYlMDJSSqz0dgR1+9JjRrzT+v62kA/BSYqaAen9U9
   15.40 +AbCPy/OuA5fEDqQ8q74l/s3NWV84wQwo0iJ8eEK85KGeZ81TS7SnZYT4IjDaMbUg
   15.41 +7uGvoMBFqZ9f7UP3pPrH/51ocMoS9JdgspDZuoER+L+r9D0ewY0B/uYA8qP2zw7z
   15.42 +c796QK+vdT7uzCRyVh1nnJlHZzkpSPiOICHJMlZqQm5b44jwyj1kpobGixNIET6n
   15.43 +hKa1KX1i1bXnaisaJ373+gycQvA0PgsULscchhwg5ba+gnFTBaBXnDK2wXv4HwAl
   15.44 +aPWJb7sFq2D3VnNBHdH7tnSlPKwOC2rwqrGSoQQA1w6CcMrRQPNnq+IquBKlrJ1q
   15.45 +NnGS0CMYcgHPFhCB5Rqh4BysIbc9VsOwf/ax4QLG5M9mI+OAI0DPGGhpXwWDdpiv
   15.46 +fGogZJpKkkbWxQzDeA7MMbIveIsl6BkEGmuDRB5f9nlJ9VK/khGD6LkDeAQmpbDq
   15.47 +0xGZuddtHsc0n9kSBJsEANvOT+A6+VCP2752GULHRytONjYn1frvRo4k5nGm38pa
   15.48 +lXPasj6vmYDTTKus3q0cxftY4qkf+VEXxfi2HfNOkLUdJfWWttaqNdpFz+WXSU5k
   15.49 +CtYgAsAr/5MVVWr86PFqWVYHYJtGQdV+a3T3SRyJ9G9YVw3u9u8aXJ4gd5xiKLiJ
   15.50 +A/9jecRDTM9hBfe+Ol7e9b8YrSSw24cj6I84YOssxVnljhHa8TAQD6YdBRVAu/U2
   15.51 +J05HVJ5Q+P8cDySWbyJY6CjRDa8VGVVs0Ue/JEmF4u11kxwZkTH5g57PFyTQHi07
   15.52 +kH1ggtRmeHsBuuJ5a3S1NYJK5bC5Z+ddC3YroI5lqfQqZj5viQJsBBgBCAAgFiEE
   15.53 +rSFSbMpVZ7dh0hwM1MlL6f8mYxoFAlr74WACGy4BQAkQ1MlL6f8mYxrAdCAEGQEI
   15.54 +AB0WIQSDGHPI6DWvbXR93BWoEzPD1TjKdAUCWvvhYAAKCRCoEzPD1TjKdJwkB/0e
   15.55 +UwtplsBrb+CJE+mPEMxy3NT/7v8OYYVaeLsD02u0vkk3u6xFJmA7TXI4f/+6Tac+
   15.56 +h7SWZPycx8DZ7qQjfWEOgatD5YtGnqRc8L0eOYtnC6KdGLdDKHEkTA1vzywhhdTg
   15.57 +isgigPsOmSFjegpEwN4oQOcNMErh6Vn1mWW7eNaeBo0bh2r8dzXTokQs8Q/X0lnu
   15.58 +0bhYgBJK6JVsznKocPazIKOoJiRtWL4AeKB/92uP7fh7vYiFcIZ8knwKDDNODlaM
   15.59 +ugp8ij1aRaqBIVMspnM+/mYWq5Ev5CbfO1DTXS7JDfeoJTDL6yBQaBVRGw3RP3j4
   15.60 +dyZDtgyJ4cGrAorpn7KqToAIANl7hKZIITp7KiWluSkY/9dPSPmfESVjaS5McA96
   15.61 +UMRCxjKmne9/UZm2swjFAFkC5a81hi/c0f551uU8FadZ/CCYtWn80dchGsOYCB94
   15.62 +PUnShkdqTf6bZ+w1nMg+kqoxB2a2K2gasyjiixR5QFylir5FdTJlG2aDabZRmjlW
   15.63 +GzCDB5N/KmnqC2QCxwEi9spvXYMt4U/hBss2vcUx/0fBglyDvlBYba03AP6ovlUX
   15.64 +1sobJdzhaqcnTPLeI9wOc80IKzWJZBT04sbP0TlJTQFGOlwYjD7yJ/YrJXtzpKUj
   15.65 +lBGgYaf3pW0nAsU82a2udbq0avpVk1NZ0Baa4dAB76l5JqQ=
   15.66 +=B/PM
   15.67 +-----END PGP PRIVATE KEY BLOCK-----
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/test/test_keys/pub/integrity_test_recip_0-0xF390A40D_pub.asc	Fri May 18 10:19:50 2018 +0200
    16.3 @@ -0,0 +1,37 @@
    16.4 +-----BEGIN PGP PUBLIC KEY BLOCK-----
    16.5 +
    16.6 +mQENBFr73usBCADhtXwG4vKooTHixzhS3EEMCdqX7DS16yF/cpZJkHfHjahe+JbC
    16.7 +hOUFWMLQI99/ZXecsKNq+Vx7g8/krIyL2qvfwGY4b9RIS84CzxPyDlJ1hgoRLkLf
    16.8 +7qekLL0y25BvP7ZmqpFbtm44MP5jlK5a3GEGlz5HjMcfWVJiFPQ0q63TG8xfP1Zp
    16.9 +RUrbVPdZePFERc3IZGnj6nxhwfJLtjQtx6CZgraDslJZqBTIdeady5yBWNYaRume
   16.10 +Ei+ZH+Whhmi0UD6ojhYUeTtnLRDR1cQwKqx1tegj1zVsXRkipVxTV1jy2qeXkDTA
   16.11 +M3JWObn+qOcFz20uvZfDAkb/01W7Dwaf/C47ABEBAAG0OUludGVncml0eSBUZXN0
   16.12 +IFJlY2lwIDxpbnRlZ3JpdHlfdGVzdF9yZWNpcEBkYXJ0aG1hbWEub3JnPokBTgQT
   16.13 +AQgAOBYhBJ2AR5iYQc9CB+oVKkrK9zXzkKQNBQJa+97rAhsvBQsJCAcCBhUKCQgL
   16.14 +AgQWAgMBAh4BAheAAAoJEErK9zXzkKQNZ4MIAKFC1nK1gRghKXILC6ZqchVjbYeS
   16.15 +Jn3nOeZC2KN+NFYTSFowSgku5BYnF+R5pslk6LOKhc//zsFiyY2fzmXac2uHilZe
   16.16 +ISwmpR300ZrwWrp0VDH3XnrkH9EpwnMXlCTMH1O65J7mfAYGfp4xD5RqcTW9rD9o
   16.17 +xjy0EJ1BGwcs2TT2bqilsYjPVsVOp0bFMKpjf3qFdWDIasRfSOLNM1OeNczGNxh4
   16.18 +u04iCrUiWR2uy6tkSIHx/BF98aOLNSFbqmpHqnRyIyDz15SLbX6dsYx2b5uutDwn
   16.19 +4f4zhrYBuHFW+8c7AhZjs22HoUsaTDMjLyWHW3/qHfkiiDCRHI9+s0Q5kWG5AQ0E
   16.20 +Wvve6wEIANltXi9qBuA904IR/sqzYn5lY0scJ7AlS+74DY516s1hd21dNc2BQOeH
   16.21 +YR3VN+o1DhPq1lKgPZe+7cS7vpPoUZuoNl2euMGHxQU9wbp0DL9qaUQx3jM2IEN6
   16.22 +efZDSl97DR9PVDJfZfSwqh8zHJb3viTBBrcRMjJ3XWg3DYC02y8RpzdguNiATYub
   16.23 +m5uqUMbf1QvZ2MTWIyl1pObINBsURPhVy3NciRrPfQrTai9DqrqMOqLicz1KPkFS
   16.24 +c+6W+gYQeYWhcXvq4ZEm5r8vt5DX5rFTo2WieNoD2AP5+xZ8Cgs6JVpIUwTRy0sO
   16.25 +GU5e828tpyXR8iF31gtpPrJhfUlVVGMAEQEAAYkCbAQYAQgAIBYhBJ2AR5iYQc9C
   16.26 +B+oVKkrK9zXzkKQNBQJa+97rAhsuAUAJEErK9zXzkKQNwHQgBBkBCAAdFiEEXK1C
   16.27 +UUbxlJ14LBUKurkoAKRaNCUFAlr73usACgkQurkoAKRaNCUYRAf/Y1fRr4wcv8p4
   16.28 +QdWJvRc49tE3pA3FCsNOG7L7qkVpyeo0v8aLj2uYccsxQLhizK7usTQ3b2jgFP+s
   16.29 ++IUZ28Ex4gRsSGO0d1+CXQR2xHPUPhoTwY09w8USPqNoFfNs0SjLccscJDa4THqa
   16.30 +E76svFK/5z7eDI7PPoho3No4iZvE6r2lItHjYtu7qVsC3kY94XSa06W6LwCCa7nt
   16.31 +kM6sMCC/BwoCuA8Tf2DYsUwygjOY0G/ESTRx4RrpD9ubMzT1K0OUZ+4VM1D8As/u
   16.32 +IcNxa4bzKiYyJGuiReeCqhXRrmQ8cXXGgXE2ik5kKITMtemmRft2ry48U+t7Rwvy
   16.33 +7PF9WHXrod5wB/9+2ccNnHTHHDJX+TgRHExrh16/2dDtjbZgUj3LTKoPNelvNA+f
   16.34 +zHKpxcA4Ggx9GaUbzpoo/ZKMko5doWFsTU0H2vbYg2V2YWjwEEYE7lzQjebWBqz0
   16.35 +etkxgyQnXkB+phZeaBOcW/rzEwXHdQUF+z51QtB6Emals/ISLWxc5Mbz216ym7LA
   16.36 +NJ1p658s8+ktj92j3mY4W9ERu5LoG4j+sRLtUvjZJ2+R9qrJkLtcjYF3FNoqB8np
   16.37 ++dgGaWEmvkaJw9lMj/vV2LD+tHc/pzYdwOb/cPyG7+311N5uWy9BlRxMwd64q8+g
   16.38 +dnIBAcqZ8Irt5dWCGkBlh1uIyyV1MI5EHu8L
   16.39 +=yUx8
   16.40 +-----END PGP PUBLIC KEY BLOCK-----
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/test/test_keys/pub/integrity_test_signer_0-0xFF26631A_pub.asc	Fri May 18 10:19:50 2018 +0200
    17.3 @@ -0,0 +1,37 @@
    17.4 +-----BEGIN PGP PUBLIC KEY BLOCK-----
    17.5 +
    17.6 +mQENBFr74WABCADbzBMLyrH+kyBoQshc7aK0vOvxHvwURVNtuxBUPeqzIZ4bCvLB
    17.7 +Dqo2ti7bQ1uRsupCbwX/zx36LrCIUZ/U5huxmnfsGuFosnNVbXNNTc8IlnlR/1bq
    17.8 +ESe2xDn9iqUgzBC8Md4nSk8O6xyqpZYqN5PiL7Q80OdKak/ITd15YxwKbkHxaK8S
    17.9 +eEV3UrL51V3qzWGAQ42jujKVfG6HGGp5rJM/syW98w0FIOHavNQE0fR7utZoX30L
   17.10 +5N14soNSQ7Mg45o4sRs+3l7MNIkPGxiWbfVp/flK7XvrLd8WprvY2swTaHJ8xyQj
   17.11 +9jcvXE/tCgk3/z80g5NjwmRNjMSWfoBh8nm3ABEBAAG0O0ludGVncml0eSBUZXN0
   17.12 +IFNpZ25lciA8aW50ZWdyaXR5X3Rlc3Rfc2lnbmVyQGRhcnRobWFtYS5vcmc+iQFO
   17.13 +BBMBCAA4FiEErSFSbMpVZ7dh0hwM1MlL6f8mYxoFAlr74WACGy8FCwkIBwIGFQoJ
   17.14 +CAsCBBYCAwECHgECF4AACgkQ1MlL6f8mYxq7/wgA0HkULYopcQoC9beigbWuZFTg
   17.15 +ZmnyOLpcFTqckmHZipVNfNtEN3mD4tBvvPTD65ktvUJlk6DnhfNK3kWcIBuusbdv
   17.16 +dlBe3RHcyJUDKlcx2t6XqoKnBAzPZlNqa+8wUAmVBmCkzhfQkhaA8fiuF8L5uatM
   17.17 +IwMGiYePiKPGk9dFm0kVnYXGYFX4kD2F2KnRCeHOwreLRzLpJjqIBm9+xERbd0L0
   17.18 +2VOoL3Sb+6dj1Swyf0v98uHjn4ultGfbBN+Ct3RNdY1S6RjKyS7xyjtEE2e2qrPt
   17.19 +U/sxaHKz6wRqXlYnhz1I6ucCWauKMOh21/zyxYXlmqChdpNQ3EYUhqLR9vvn6LkB
   17.20 +DQRa++FgAQgAuKa6XUzB4pJX0Zz2glCwxKfy/zjj2UgxtQM61clZPC/NbHx1zbUc
   17.21 +iNzgnlZTTEEyNpMXsgFueOa8+Xz98dTpqBHCyU7X3YnZjYLTyJR7doQbI1lPA57R
   17.22 +BT/8HmHlbH3gj7OeGCBRJ2vDXXf5UWQiTQusCh8GqAvDXbhIUuAEU76Hf16FeBVd
   17.23 +64x7tyYjbJRvBTdgqQRcMQWK4o4KeIHf8MIktRtcK0lhGltwdA513dn7Sh9/SLGb
   17.24 +tha0QLiusqIZNBl6nCjBr1Z9zMuUJBn/M2S6L4sbEx9q19np762xh8wxSCzrZH8x
   17.25 +AL1lIjBC+2wgHGnUb/KUzuX0/7mYLCve8wARAQABiQJsBBgBCAAgFiEErSFSbMpV
   17.26 +Z7dh0hwM1MlL6f8mYxoFAlr74WACGy4BQAkQ1MlL6f8mYxrAdCAEGQEIAB0WIQSD
   17.27 +GHPI6DWvbXR93BWoEzPD1TjKdAUCWvvhYAAKCRCoEzPD1TjKdJwkB/0eUwtplsBr
   17.28 +b+CJE+mPEMxy3NT/7v8OYYVaeLsD02u0vkk3u6xFJmA7TXI4f/+6Tac+h7SWZPyc
   17.29 +x8DZ7qQjfWEOgatD5YtGnqRc8L0eOYtnC6KdGLdDKHEkTA1vzywhhdTgisgigPsO
   17.30 +mSFjegpEwN4oQOcNMErh6Vn1mWW7eNaeBo0bh2r8dzXTokQs8Q/X0lnu0bhYgBJK
   17.31 +6JVsznKocPazIKOoJiRtWL4AeKB/92uP7fh7vYiFcIZ8knwKDDNODlaMugp8ij1a
   17.32 +RaqBIVMspnM+/mYWq5Ev5CbfO1DTXS7JDfeoJTDL6yBQaBVRGw3RP3j4dyZDtgyJ
   17.33 +4cGrAorpn7KqToAIANl7hKZIITp7KiWluSkY/9dPSPmfESVjaS5McA96UMRCxjKm
   17.34 +ne9/UZm2swjFAFkC5a81hi/c0f551uU8FadZ/CCYtWn80dchGsOYCB94PUnShkdq
   17.35 +Tf6bZ+w1nMg+kqoxB2a2K2gasyjiixR5QFylir5FdTJlG2aDabZRmjlWGzCDB5N/
   17.36 +KmnqC2QCxwEi9spvXYMt4U/hBss2vcUx/0fBglyDvlBYba03AP6ovlUX1sobJdzh
   17.37 +aqcnTPLeI9wOc80IKzWJZBT04sbP0TlJTQFGOlwYjD7yJ/YrJXtzpKUjlBGgYaf3
   17.38 +pW0nAsU82a2udbq0avpVk1NZ0Baa4dAB76l5JqQ=
   17.39 +=u1h/
   17.40 +-----END PGP PUBLIC KEY BLOCK-----