ENGINE-466 merged in - header key import moves version to 1.1.0 Release 1.1.0
authorKrista Bennett <krista@pep-project.org>
Tue, 09 Oct 2018 19:56:07 +0200
changeset 303643ab5608555e
parent 3031 c7427b0aeb90
parent 3035 ff76c2a76da1
child 3038 155938bd68a1
ENGINE-466 merged in - header key import moves version to 1.1.0
src/message_api.c
src/pEp_internal.h
     1.1 --- a/src/Makefile	Mon Oct 08 13:19:57 2018 +0200
     1.2 +++ b/src/Makefile	Tue Oct 09 19:56:07 2018 +0200
     1.3 @@ -90,7 +90,7 @@
     1.4  	cp -v pEpEngine.h keymanagement.h message_api.h dynamic_api.h stringlist.h \
     1.5  	      timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h \
     1.6  	      cryptotech.h sync.h sync_fsm.h sync_app.h blacklist.h pEp_string.h \
     1.7 -	      labeled_int_list.h openpgp_compat.h $(PREFIX)/include/pEp/
     1.8 +	      labeled_int_list.h openpgp_compat.h base64.h $(PREFIX)/include/pEp/
     1.9  
    1.10  .PHONY: uninstall
    1.11  uninstall:
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/base64.c	Tue Oct 09 19:56:07 2018 +0200
     2.3 @@ -0,0 +1,219 @@
     2.4 +// This file is under GNU General Public License 3.0
     2.5 +// see LICENSE.txt
     2.6 +
     2.7 +#include <stdbool.h>
     2.8 +#include <stdlib.h>
     2.9 +#include <assert.h>
    2.10 +#include <string.h>
    2.11 +
    2.12 +#include "platform.h"
    2.13 +#include "base64.h"
    2.14 +
    2.15 +static char translate_char_to_bits(char input) {
    2.16 +    if (input >= 65 && input <= 90)
    2.17 +        return input - 65;
    2.18 +    if (input >= 97 && input <= 122)
    2.19 +        return input - 71; // 97 - 26
    2.20 +    if (input >= 48 && input <= 57)
    2.21 +        return input + 4; // 52 - 48
    2.22 +    if (input == '+')
    2.23 +        return 62;
    2.24 +    if (input == '/')
    2.25 +        return 63;
    2.26 +    if (input == ' ' || input == '\r' || input == '\n')
    2.27 +        return 127;
    2.28 +    return -1;    
    2.29 +}
    2.30 +
    2.31 +static bool _is_whitespace(const char in) {
    2.32 +    switch (in) {
    2.33 +        case ' ':
    2.34 +        case '\r':
    2.35 +        case '\t':
    2.36 +        case '\n':
    2.37 +            return true;
    2.38 +        default:
    2.39 +            return false;
    2.40 +    }        
    2.41 +}
    2.42 +
    2.43 +static size_t subtract_whitespace(const char* input, int length) {
    2.44 +    size_t actual_size = length;
    2.45 +    int i;
    2.46 +    const char* curr = input;
    2.47 +    for (i = 0; i < length; i++, curr++) {
    2.48 +        if (_is_whitespace(*curr))
    2.49 +            actual_size--;
    2.50 +    }
    2.51 +    return actual_size;
    2.52 +}
    2.53 +    
    2.54 +static void trim_end(const char* input, int* length) {
    2.55 +    const char* end = input + *length;
    2.56 +    
    2.57 +    int start_length = *length;
    2.58 +    
    2.59 +    int i;
    2.60 +    
    2.61 +    for (i = 0; i < start_length; i++) {
    2.62 +        if (!_is_whitespace(*(--end)))
    2.63 +            break;
    2.64 +        (*length) = (*length) - 1;        
    2.65 +    }
    2.66 +}    
    2.67 +    
    2.68 +char next_char(const char** input_ptr, const char* end) {
    2.69 +    const char* input = *input_ptr;
    2.70 +    char this_ch = 0;
    2.71 +    
    2.72 +    while (input < end) {
    2.73 +        this_ch = *input++;
    2.74 +        if (!this_ch)
    2.75 +            return 0;
    2.76 +        if (_is_whitespace(this_ch))
    2.77 +            continue;
    2.78 +        break;    
    2.79 +    }
    2.80 +    
    2.81 +    *input_ptr = input;
    2.82 +    return this_ch;
    2.83 +}
    2.84 +
    2.85 +// 4 chars = 3 output bytes
    2.86 +bloblist_t* base64_str_to_binary_blob(const char* input, int length) {
    2.87 +    if (length == 0)
    2.88 +        return NULL;
    2.89 +    
    2.90 +    trim_end(input, &length);
    2.91 +        
    2.92 +    const char* input_curr;
    2.93 +    input_curr = input;
    2.94 +    const char* input_end = input_curr + length;
    2.95 +    length = subtract_whitespace(input, length);
    2.96 +    size_t final_length = (length / 4) * 3;
    2.97 +
    2.98 +    // padded -- FIXME: whitespace in between ==!!!! 
    2.99 +    if (*(input_end - 1) == '=') {
   2.100 +        final_length -= 1;
   2.101 +        
   2.102 +        if (*(input_end - 2) == '=')
   2.103 +            final_length -=1;
   2.104 +    }
   2.105 +    else {
   2.106 +        // not padded
   2.107 +        int leftover = length % 4;
   2.108 +        switch (leftover) {
   2.109 +            case 0:
   2.110 +                break;
   2.111 +            case 2:
   2.112 +                final_length++;
   2.113 +                break;
   2.114 +            case 3:
   2.115 +                final_length+=2;
   2.116 +                break;
   2.117 +            default:
   2.118 +                return NULL;
   2.119 +        }
   2.120 +    }
   2.121 +    void* blobby = calloc(final_length, 1);
   2.122 +    char* blobby_curr = (char*)blobby;
   2.123 +
   2.124 +    // if the last 1 or 2 bytes are padded, we do those after
   2.125 +    size_t number_of_rounds = final_length / 3;
   2.126 +    
   2.127 +    unsigned int cycle;
   2.128 +    
   2.129 +    // full 3-byte rounds
   2.130 +    for (cycle = 0; cycle < number_of_rounds; cycle++) {
   2.131 +        char byte_array[] = {0,0,0};
   2.132 +        char in_val = next_char(&input_curr, input_end);
   2.133 +        if (in_val == 0)
   2.134 +            goto pEp_error; // can ALSO happen when input_curr == input_end,
   2.135 +                            // which simply shouldn't happen, since we're
   2.136 +                            // interating based on expected OUTPUT, not
   2.137 +                            // input.
   2.138 +                            
   2.139 +        char out_val = translate_char_to_bits(in_val);
   2.140 +        if (out_val > 63)
   2.141 +            goto pEp_error;
   2.142 +        
   2.143 +        byte_array[0] |= out_val << 2;
   2.144 +
   2.145 +        in_val = next_char(&input_curr, input_end);
   2.146 +        if (in_val == 0)
   2.147 +            goto pEp_error;         
   2.148 +        out_val = translate_char_to_bits(in_val);
   2.149 +        if (out_val > 63)
   2.150 +            goto pEp_error;
   2.151 +
   2.152 +        byte_array[0] |= out_val >> 4;
   2.153 +        byte_array[1] = out_val << 4;
   2.154 +        
   2.155 +        in_val = next_char(&input_curr, input_end);
   2.156 +        if (in_val == 0)
   2.157 +            goto pEp_error;         
   2.158 +        out_val = translate_char_to_bits(in_val);
   2.159 +        if (out_val > 63)
   2.160 +            goto pEp_error;
   2.161 +    
   2.162 +        byte_array[1] |= out_val >> 2;
   2.163 +        byte_array[2] = out_val << 6;
   2.164 +
   2.165 +        in_val = next_char(&input_curr, input_end);
   2.166 +        if (in_val == 0)
   2.167 +            goto pEp_error;         
   2.168 +        out_val = translate_char_to_bits(in_val);
   2.169 +        if (out_val > 63)
   2.170 +            goto pEp_error;
   2.171 +        
   2.172 +        byte_array[2] |= out_val;
   2.173 +        
   2.174 +        // Now write everything to the blob
   2.175 +        *blobby_curr++ = byte_array[0];
   2.176 +        *blobby_curr++ = byte_array[1];
   2.177 +        *blobby_curr++ = byte_array[2];        
   2.178 +    }
   2.179 +
   2.180 +    int last_bytes = final_length % 3;
   2.181 +
   2.182 +    if (last_bytes != 0) {
   2.183 +        char byte_1 = 0;
   2.184 +        char byte_2 = 0;
   2.185 +
   2.186 +        char in_val = next_char(&input_curr, input_end);
   2.187 +        if (in_val == 0)
   2.188 +            goto pEp_error;         
   2.189 +        char out_val = translate_char_to_bits(in_val);
   2.190 +        if (out_val > 63)
   2.191 +            goto pEp_error;
   2.192 +        byte_1 = out_val << 2;
   2.193 +        in_val = next_char(&input_curr, input_end);
   2.194 +        if (in_val == 0)
   2.195 +            goto pEp_error;         
   2.196 +        out_val = translate_char_to_bits(in_val);
   2.197 +        if (out_val > 63)
   2.198 +            goto pEp_error;
   2.199 +        byte_1 |= out_val >> 4;
   2.200 +        *blobby_curr++ = byte_1;                   
   2.201 +            
   2.202 +        if (last_bytes == 2) {
   2.203 +            byte_2 = out_val << 4;
   2.204 +            in_val = next_char(&input_curr, input_end);
   2.205 +            if (in_val == 0)
   2.206 +                goto pEp_error;         
   2.207 +            
   2.208 +            out_val = translate_char_to_bits(in_val);
   2.209 +            if (out_val > 63)
   2.210 +                goto pEp_error;
   2.211 +        
   2.212 +            byte_2 |= out_val >> 2;
   2.213 +            *blobby_curr++ = byte_2;
   2.214 +        }
   2.215 +    }
   2.216 +    
   2.217 +    return new_bloblist((char*)blobby, final_length, NULL, NULL);
   2.218 +            
   2.219 +pEp_error:
   2.220 +    free(blobby);
   2.221 +    return NULL;
   2.222 +}    
   2.223 \ No newline at end of file
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/base64.h	Tue Oct 09 19:56:07 2018 +0200
     3.3 @@ -0,0 +1,17 @@
     3.4 +// This file is under GNU General Public License 3.0
     3.5 +// see LICENSE.txt
     3.6 +
     3.7 +#pragma once
     3.8 +
     3.9 +#include "dynamic_api.h"
    3.10 +#include "bloblist.h"
    3.11 +
    3.12 +#ifdef __cplusplus
    3.13 +extern "C" {
    3.14 +#endif
    3.15 +
    3.16 +bloblist_t* base64_str_to_binary_blob(const char* input, int length);
    3.17 +
    3.18 +#ifdef __cplusplus
    3.19 +}
    3.20 +#endif
     4.1 --- a/src/message_api.c	Mon Oct 08 13:19:57 2018 +0200
     4.2 +++ b/src/message_api.c	Tue Oct 09 19:56:07 2018 +0200
     4.3 @@ -7,6 +7,7 @@
     4.4  #include "platform.h"
     4.5  #include "mime.h"
     4.6  #include "blacklist.h"
     4.7 +#include "base64.h"
     4.8  
     4.9  #include <assert.h>
    4.10  #include <string.h>
    4.11 @@ -2767,7 +2768,7 @@
    4.12                      ptext = NULL;
    4.13                  }
    4.14                  else {
    4.15 -                    static const char * const mime_type = "application/octet-stream";
    4.16 +                    static const char * const mime_type = "application/octet-stream";                    
    4.17                      if (pgp_filename) {
    4.18                          _m = bloblist_add(_m, ptext, psize, mime_type,
    4.19                               pgp_filename);
    4.20 @@ -3076,6 +3077,28 @@
    4.21      return NULL;
    4.22  }
    4.23  
    4.24 +static bool import_header_keys(PEP_SESSION session, message* src) {
    4.25 +    stringpair_list_t* header_keys = stringpair_list_find(src->opt_fields, "Autocrypt"); 
    4.26 +    if (!header_keys || !header_keys->value)
    4.27 +        return false;
    4.28 +    const char* value = header_keys->value->value;
    4.29 +    if (!value)
    4.30 +        return false;
    4.31 +    const char* start_key = strstr(value, "keydata=");
    4.32 +    if (!start_key)
    4.33 +        return false;
    4.34 +    start_key += 8; // length of "keydata="
    4.35 +    int length = strlen(start_key);
    4.36 +    bloblist_t* the_key = base64_str_to_binary_blob(start_key, length);
    4.37 +    if (!the_key)
    4.38 +        return false;
    4.39 +    PEP_STATUS status = import_key(session, the_key->value, the_key->size, NULL);
    4.40 +    free_bloblist(the_key);
    4.41 +    if (status == PEP_STATUS_OK)
    4.42 +        return true;
    4.43 +    return false;
    4.44 +}
    4.45 +
    4.46  DYNAMIC_API PEP_STATUS _decrypt_message(
    4.47          PEP_SESSION session,
    4.48          message *src,
    4.49 @@ -3161,7 +3184,8 @@
    4.50      /*** Begin Import any attached public keys and update identities accordingly ***/
    4.51      // Private key in unencrypted mail are ignored -> NULL
    4.52      bool imported_keys = import_attached_keys(session, src, NULL);
    4.53 -
    4.54 +    import_header_keys(session, src);
    4.55 +    
    4.56      // FIXME: is this really necessary here?
    4.57      if (src->from) {
    4.58          if (!is_me(session, src->from))
     5.1 --- a/src/pEp_internal.h	Mon Oct 08 13:19:57 2018 +0200
     5.2 +++ b/src/pEp_internal.h	Tue Oct 09 19:56:07 2018 +0200
     5.3 @@ -1,7 +1,7 @@
     5.4  // This file is under GNU General Public License 3.0
     5.5  // see LICENSE.txt
     5.6  
     5.7 -#define PEP_ENGINE_VERSION "1.0.442"
     5.8 +#define PEP_ENGINE_VERSION "1.1.0"
     5.9  
    5.10  // maximum attachment size to import as key 1MB, maximum of 20 attachments
    5.11  
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/test/convenience_scripts/quickadd_testcalls.py	Tue Oct 09 19:56:07 2018 +0200
     6.3 @@ -0,0 +1,53 @@
     6.4 +# very fragile, for Krista's convenience only. DANGER, USE AT OWN RISK.
     6.5 +import sys
     6.6 +import os
     6.7 +
     6.8 +calls_added_file = sys.argv[1]
     6.9 +class_name = sys.argv[2]
    6.10 +
    6.11 +f = open(calls_added_file, "r")
    6.12 +calls = f.readlines()
    6.13 +f.close()
    6.14 +
    6.15 +class_file_path = "src/engine_tests/" + class_name + ".cc"
    6.16 +class_file = open(class_file_path, "r")
    6.17 +class_file_lines = class_file.readlines();
    6.18 +class_file.close();
    6.19 +
    6.20 +accumulator = ""
    6.21 +call_part_1 = "    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string(\""
    6.22 +call_part_3 = "                                                                      static_cast<Func>("
    6.23 +
    6.24 +counter = 0
    6.25 +index = 0
    6.26 +for l in class_file_lines:
    6.27 +    if "add_test_to_suite" in l:
    6.28 +        index = counter;
    6.29 +    counter += 1;    
    6.30 +
    6.31 +if counter == 0:
    6.32 +    for l in class_file_lines:
    6.33 +        if (l.startswith(class_name)):
    6.34 +            index = counter + 2;
    6.35 +            break;
    6.36 +        counter += 1;
    6.37 +    if (counter == 0):
    6.38 +        os.exit(-1)
    6.39 +else:
    6.40 +    index += 2
    6.41 +            
    6.42 +for c in calls:
    6.43 +    if not c:
    6.44 +        continue
    6.45 +    c = c.rstrip()
    6.46 +    call_part_2 = class_name + "::" + c + "\"),\n"
    6.47 +    call_part_4 = "&" + class_name + "::" + c + ")));\n"
    6.48 +
    6.49 +    accumulator += call_part_1 + call_part_2 + call_part_3 + call_part_4
    6.50 +    
    6.51 +class_file_lines.insert(index, accumulator);    
    6.52 +
    6.53 +class_file = open(class_file_path, "w")
    6.54 +class_file.writelines(class_file_lines)
    6.55 +class_file.close()
    6.56 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/include/HeaderKeyImportTests.h	Tue Oct 09 19:56:07 2018 +0200
     7.3 @@ -0,0 +1,61 @@
     7.4 +// This file is under GNU General Public License 3.0
     7.5 +// see LICENSE.txt
     7.6 +
     7.7 +#ifndef HEADER_KEY_IMPORT_H
     7.8 +#define HEADER_KEY_IMPORT_H
     7.9 +
    7.10 +#include <string>
    7.11 +#include "EngineTestIndividualSuite.h"
    7.12 +
    7.13 +using namespace std;
    7.14 +
    7.15 +class HeaderKeyImportTests : public EngineTestIndividualSuite {
    7.16 +    public:
    7.17 +        HeaderKeyImportTests(string test_suite, string test_home_dir);
    7.18 +    private:
    7.19 +        void base_64_minimal_round();
    7.20 +        void base_64_minimal_padded_1();
    7.21 +        void base_64_minimal_padded_2();
    7.22 +        void base_64_minimal_unpadded_1();
    7.23 +        void base_64_minimal_unpadded_2();    
    7.24 +        void base_64_minimal_leading_whitespace_round();
    7.25 +        void base_64_minimal_leading_whitespace_padded_1();
    7.26 +        void base_64_minimal_leading_whitespace_padded_2();
    7.27 +        void base_64_minimal_leading_whitespace_unpadded_1();        
    7.28 +        void base_64_minimal_leading_whitespace_unpadded_2();
    7.29 +        void base_64_minimal_trailing_whitespace_round();
    7.30 +        void base_64_minimal_trailing_whitespace_padded_1();
    7.31 +        void base_64_minimal_trailing_whitespace_padded_2();
    7.32 +        void base_64_minimal_trailing_whitespace_unpadded_1();        
    7.33 +        void base_64_minimal_trailing_whitespace_unpadded_2();
    7.34 +        void base_64_minimal_internal_whitespace_round();
    7.35 +        void base_64_minimal_internal_whitespace_padded_1();
    7.36 +        void base_64_minimal_internal_whitespace_padded_2();
    7.37 +        void base_64_minimal_internal_whitespace_unpadded_1();        
    7.38 +        void base_64_minimal_internal_whitespace_unpadded_2();
    7.39 +        void base_64_round();
    7.40 +        void base_64_padded_1();
    7.41 +        void base_64_padded_2();
    7.42 +        void base_64_unpadded_1();        
    7.43 +        void base_64_unpadded_2();
    7.44 +        void base_64_leading_whitespace_round();
    7.45 +        void base_64_leading_whitespace_padded_1();
    7.46 +        void base_64_leading_whitespace_padded_2();
    7.47 +        void base_64_leading_whitespace_unpadded_1();        
    7.48 +        void base_64_leading_whitespace_unpadded_2();
    7.49 +        void base_64_trailing_whitespace_round();
    7.50 +        void base_64_trailing_whitespace_padded_1();
    7.51 +        void base_64_trailing_whitespace_padded_2();
    7.52 +        void base_64_trailing_whitespace_unpadded_1();        
    7.53 +        void base_64_trailing_whitespace_unpadded_2();
    7.54 +        void base_64_kitchen_sink_round();
    7.55 +        void base_64_kitchen_sink_padded_1();
    7.56 +        void base_64_kitchen_sink_padded_2();
    7.57 +        void base_64_kitchen_sink_unpadded_1();        
    7.58 +        void base_64_kitchen_sink_unpadded_2();
    7.59 +        void check_header_key_import();
    7.60 +        
    7.61 +        bool verify_base_64_test(const char* input, const char* desired_output);
    7.62 +};
    7.63 +
    7.64 +#endif
     8.1 --- a/test/src/SuiteMaker.cc	Mon Oct 08 13:19:57 2018 +0200
     8.2 +++ b/test/src/SuiteMaker.cc	Tue Oct 09 19:56:07 2018 +0200
     8.3 @@ -28,6 +28,7 @@
     8.4  #include "BlacklistAcceptNewKeyTests.h"
     8.5  #include "MessageApiTests.h"
     8.6  #include "StringlistTests.h"
     8.7 +#include "HeaderKeyImportTests.h"
     8.8  #include "StringpairListTests.h"
     8.9  #include "TrustManipulationTests.h"
    8.10  #include "EncryptAttachPrivateKeyTests.h"
    8.11 @@ -70,6 +71,7 @@
    8.12      "BlacklistAcceptNewKeyTests",
    8.13      "MessageApiTests",
    8.14      "StringlistTests",
    8.15 +    "HeaderKeyImportTests",
    8.16      "StringpairListTests",
    8.17      "TrustManipulationTests",
    8.18      "EncryptAttachPrivateKeyTests",
    8.19 @@ -96,7 +98,7 @@
    8.20  };
    8.21  
    8.22  // This file is generated, so magic constants are ok.
    8.23 -int SuiteMaker::num_suites = 39;
    8.24 +int SuiteMaker::num_suites = 40;
    8.25  
    8.26  void SuiteMaker::suitemaker_build(const char* test_class_name, const char* test_home, Test::Suite** test_suite) {
    8.27      if (strcmp(test_class_name, "DecorateTests") == 0)
    8.28 @@ -131,6 +133,8 @@
    8.29          *test_suite = new MessageApiTests(test_class_name, test_home);
    8.30      else if (strcmp(test_class_name, "StringlistTests") == 0)
    8.31          *test_suite = new StringlistTests(test_class_name, test_home);
    8.32 +    else if (strcmp(test_class_name, "HeaderKeyImportTests") == 0)
    8.33 +        *test_suite = new HeaderKeyImportTests(test_class_name, test_home);
    8.34      else if (strcmp(test_class_name, "StringpairListTests") == 0)
    8.35          *test_suite = new StringpairListTests(test_class_name, test_home);
    8.36      else if (strcmp(test_class_name, "TrustManipulationTests") == 0)
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/src/engine_tests/HeaderKeyImportTests.cc	Tue Oct 09 19:56:07 2018 +0200
     9.3 @@ -0,0 +1,763 @@
     9.4 +// This file is under GNU General Public License 3.0
     9.5 +// see LICENSE.txt
     9.6 +
     9.7 +#include <stdlib.h>
     9.8 +#include <string>
     9.9 +#include <cstring>
    9.10 +
    9.11 +#include <cpptest.h>
    9.12 +
    9.13 +#include "pEpEngine.h"
    9.14 +#include "bloblist.h"
    9.15 +#include "base64.h"
    9.16 +
    9.17 +#include "test_util.h"
    9.18 +#include "EngineTestIndividualSuite.h"
    9.19 +#include "HeaderKeyImportTests.h"
    9.20 +
    9.21 +using namespace std;
    9.22 +
    9.23 +HeaderKeyImportTests::HeaderKeyImportTests(string suitename, string test_home_dir) :
    9.24 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
    9.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_round"),
    9.26 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_round)));
    9.27 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_padded_1"),
    9.28 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_padded_1)));
    9.29 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_padded_2"),
    9.30 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_padded_2)));                                                                      
    9.31 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_unpadded_1"),
    9.32 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_unpadded_1)));
    9.33 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_unpadded_2"),
    9.34 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_unpadded_2)));                                                                      
    9.35 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_leading_whitespace_round"),
    9.36 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_leading_whitespace_round)));
    9.37 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_leading_whitespace_padded_1"),
    9.38 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_leading_whitespace_padded_1)));                                                                      
    9.39 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_leading_whitespace_padded_2"),
    9.40 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_leading_whitespace_padded_2)));                                                                      
    9.41 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_leading_whitespace_unpadded_1"),    
    9.42 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_leading_whitespace_unpadded_1)));
    9.43 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_leading_whitespace_unpadded_2"),    
    9.44 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_leading_whitespace_unpadded_2)));
    9.45 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_trailing_whitespace_round"),
    9.46 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_trailing_whitespace_round)));
    9.47 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_trailing_whitespace_padded_1"),
    9.48 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_trailing_whitespace_padded_1)));
    9.49 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_trailing_whitespace_padded_2"),
    9.50 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_trailing_whitespace_padded_2)));
    9.51 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_trailing_whitespace_unpadded_1"),
    9.52 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_trailing_whitespace_unpadded_1)));
    9.53 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_trailing_whitespace_unpadded_2"),
    9.54 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_trailing_whitespace_unpadded_2)));
    9.55 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_internal_whitespace_round"),
    9.56 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_internal_whitespace_round)));
    9.57 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_internal_whitespace_padded_1"),
    9.58 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_internal_whitespace_padded_1)));
    9.59 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_internal_whitespace_padded_2"),
    9.60 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_internal_whitespace_padded_2)));
    9.61 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_internal_whitespace_unpadded_1"),
    9.62 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_internal_whitespace_unpadded_1)));
    9.63 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_minimal_internal_whitespace_unpadded_2"),
    9.64 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_minimal_internal_whitespace_unpadded_2)));
    9.65 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_round"),
    9.66 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_round)));
    9.67 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_padded_1"),
    9.68 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_padded_1)));
    9.69 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_padded_2"),
    9.70 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_padded_2)));
    9.71 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_unpadded_1"),
    9.72 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_unpadded_1)));                                                                      
    9.73 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_unpadded_2"),
    9.74 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_unpadded_2)));
    9.75 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_leading_whitespace_round"),
    9.76 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_leading_whitespace_round)));
    9.77 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_leading_whitespace_padded_1"),
    9.78 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_leading_whitespace_padded_1)));
    9.79 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_leading_whitespace_padded_2"),
    9.80 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_leading_whitespace_padded_2)));
    9.81 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_leading_whitespace_unpadded_1"),
    9.82 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_leading_whitespace_unpadded_1)));                                                                      
    9.83 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_leading_whitespace_unpadded_2"),
    9.84 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_leading_whitespace_unpadded_2)));
    9.85 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_trailing_whitespace_round"),
    9.86 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_trailing_whitespace_round)));
    9.87 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_trailing_whitespace_padded_1"),
    9.88 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_trailing_whitespace_padded_1)));
    9.89 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_trailing_whitespace_padded_2"),
    9.90 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_trailing_whitespace_padded_2)));
    9.91 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_trailing_whitespace_unpadded_1"),
    9.92 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_trailing_whitespace_unpadded_1)));
    9.93 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_trailing_whitespace_unpadded_2"),
    9.94 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_trailing_whitespace_unpadded_2)));
    9.95 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_kitchen_sink_round"),
    9.96 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_kitchen_sink_round)));
    9.97 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_kitchen_sink_padded_1"),
    9.98 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_kitchen_sink_padded_1)));
    9.99 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_kitchen_sink_padded_2"),
   9.100 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_kitchen_sink_padded_2)));
   9.101 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_kitchen_sink_unpadded_1"),
   9.102 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_kitchen_sink_unpadded_1)));
   9.103 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::base_64_kitchen_sink_unpadded_2"),
   9.104 +                                                                      static_cast<Func>(&HeaderKeyImportTests::base_64_kitchen_sink_unpadded_2)));
   9.105 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("HeaderKeyImportTests::check_header_key_import"),
   9.106 +                                                                      static_cast<Func>(&HeaderKeyImportTests::check_header_key_import)));                                                                  
   9.107 +}
   9.108 +
   9.109 +bool HeaderKeyImportTests::verify_base_64_test(const char* input, const char* desired_output) {
   9.110 +    bloblist_t* blobby = NULL;
   9.111 +    bool retval = false;
   9.112 +    size_t desired_output_length = 0;
   9.113 +    const char* blobval;
   9.114 +    
   9.115 +    blobby = base64_str_to_binary_blob(input, strlen(input));    
   9.116 +    if (!blobby)
   9.117 +        goto pEp_free;
   9.118 +
   9.119 +    blobval = blobby->value;
   9.120 +    
   9.121 +    // N.B. Actual output will NOT be null-terminated!!!!
   9.122 +    desired_output_length = strlen(desired_output);
   9.123 +    if (blobby->size != desired_output_length) 
   9.124 +        goto pEp_free;
   9.125 +        
   9.126 +    int i;
   9.127 +    for (i = 0; i < desired_output_length; i++) {
   9.128 +        if (*blobval++ != *desired_output++)
   9.129 +        goto pEp_free;
   9.130 +    }
   9.131 +    
   9.132 +    retval = true;    
   9.133 +    
   9.134 +pEp_free:
   9.135 +    free_bloblist(blobby);
   9.136 +    return retval;
   9.137 +}
   9.138 +
   9.139 +void HeaderKeyImportTests::base_64_minimal_round() {
   9.140 +    TEST_ASSERT(verify_base_64_test("TWFu", "Man"));
   9.141 +}
   9.142 +
   9.143 +void HeaderKeyImportTests::base_64_minimal_padded_1() {
   9.144 +    TEST_ASSERT(verify_base_64_test("TWE=", "Ma"));
   9.145 +}
   9.146 +
   9.147 +void HeaderKeyImportTests::base_64_minimal_padded_2() {
   9.148 +    TEST_ASSERT(verify_base_64_test("TQ==", "M"));
   9.149 +}
   9.150 +
   9.151 +void HeaderKeyImportTests::base_64_minimal_unpadded_1() {
   9.152 +    TEST_ASSERT(verify_base_64_test("TWE", "Ma"));
   9.153 +}
   9.154 +
   9.155 +void HeaderKeyImportTests::base_64_minimal_unpadded_2() {
   9.156 +    TEST_ASSERT(verify_base_64_test("TQ", "M"));
   9.157 +}
   9.158 +
   9.159 +void HeaderKeyImportTests::base_64_minimal_leading_whitespace_round() {
   9.160 +    TEST_ASSERT(verify_base_64_test(" \tTWFu", "Man"));
   9.161 +}
   9.162 +
   9.163 +void HeaderKeyImportTests::base_64_minimal_leading_whitespace_padded_1() {
   9.164 +    TEST_ASSERT(verify_base_64_test(" TWE=", "Ma"));
   9.165 +}
   9.166 +
   9.167 +void HeaderKeyImportTests::base_64_minimal_leading_whitespace_padded_2() {
   9.168 +    TEST_ASSERT(verify_base_64_test("\nTQ==", "M"));
   9.169 +}
   9.170 +
   9.171 +void HeaderKeyImportTests::base_64_minimal_leading_whitespace_unpadded_1() {
   9.172 +    TEST_ASSERT(verify_base_64_test("\n TWE", "Ma"));
   9.173 +}
   9.174 +void HeaderKeyImportTests::base_64_minimal_leading_whitespace_unpadded_2() {
   9.175 +    TEST_ASSERT(verify_base_64_test(" TQ", "M"));
   9.176 +}
   9.177 +
   9.178 +void HeaderKeyImportTests::base_64_minimal_trailing_whitespace_round() {
   9.179 +    TEST_ASSERT(verify_base_64_test("TWFu ", "Man"));
   9.180 +}
   9.181 +
   9.182 +void HeaderKeyImportTests::base_64_minimal_trailing_whitespace_padded_1() {
   9.183 +    TEST_ASSERT(verify_base_64_test("TWE=\n ", "Ma"));
   9.184 +}
   9.185 +
   9.186 +void HeaderKeyImportTests::base_64_minimal_trailing_whitespace_padded_2() {
   9.187 +    TEST_ASSERT(verify_base_64_test("TQ==                 \n \t", "M"));
   9.188 +}
   9.189 +
   9.190 +void HeaderKeyImportTests::base_64_minimal_trailing_whitespace_unpadded_1() {
   9.191 +    TEST_ASSERT(verify_base_64_test("TWE           ", "Ma"));
   9.192 +}
   9.193 +
   9.194 +void HeaderKeyImportTests::base_64_minimal_trailing_whitespace_unpadded_2() {
   9.195 +    TEST_ASSERT(verify_base_64_test("TQ\n", "M"));
   9.196 +}
   9.197 +
   9.198 +void HeaderKeyImportTests::base_64_minimal_internal_whitespace_round() {
   9.199 +    TEST_ASSERT(verify_base_64_test("T\nWF\nu", "Man"));
   9.200 +}
   9.201 +
   9.202 +void HeaderKeyImportTests::base_64_minimal_internal_whitespace_padded_1() {
   9.203 +    TEST_ASSERT(verify_base_64_test("T    W E =", "Ma"));
   9.204 +}
   9.205 +
   9.206 +void HeaderKeyImportTests::base_64_minimal_internal_whitespace_padded_2() {
   9.207 +    TEST_ASSERT(verify_base_64_test("T  Q==", "M"));
   9.208 +}
   9.209 +
   9.210 +void HeaderKeyImportTests::base_64_minimal_internal_whitespace_unpadded_1() {
   9.211 +    TEST_ASSERT(verify_base_64_test("T\nWE", "Ma"));
   9.212 +}
   9.213 +
   9.214 +void HeaderKeyImportTests::base_64_minimal_internal_whitespace_unpadded_2() {
   9.215 +    TEST_ASSERT(verify_base_64_test("T\r\nQ", "M"));
   9.216 +}
   9.217 +
   9.218 +void HeaderKeyImportTests::base_64_round() {
   9.219 +    const char* input = "V2hlbiB0aGluZ3MgZ28gd3JvbmcsIGFzIHRoZX"
   9.220 +                        "kgdXN1YWxseSB3aWxsCkFuZCB5b3VyIGRhaWx5"
   9.221 +                        "IHJvYWQgc2VlbXMgYWxsIHVwaGlsbApXaGVuIG"
   9.222 +                        "Z1bmRzIGFyZSBsb3csIGFuZCBkZWJ0cyBhcmUg"
   9.223 +                        "aGlnaApZb3UgdHJ5IHRvIHNtaWxlLCBidXQgY2"
   9.224 +                        "FuIG9ubHkgY3J5CldoZW4geW91IHJlYWxseSBm"
   9.225 +                        "ZWVsIHlvdSdkIGxpa2UgdG8gcXVpdCwKRG9uJ3"
   9.226 +                        "QgcnVuIHRvIG1lLCBJIGRvbid0IGdpdmUgYSBI"
   9.227 +                        "SSBOT1RISU5HIFRPIFNFRSBIRVJFISEh";
   9.228 +    
   9.229 +    const char* output = "When things go wrong, as they usually will\n"
   9.230 +                         "And your daily road seems all uphill\n"
   9.231 +                         "When funds are low, and debts are high\n"
   9.232 +                         "You try to smile, but can only cry\n"
   9.233 +                         "When you really feel you'd like to quit,\n"
   9.234 +                         "Don't run to me, I don't give a HI NOTHING TO SEE HERE!!!";
   9.235 +    
   9.236 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.237 +}
   9.238 +
   9.239 +void HeaderKeyImportTests::base_64_padded_1() {
   9.240 +    const char* input =
   9.241 +        "U2ludGVya2xhYXMgS2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kg"
   9.242 +        "d2F0IGluIG3igJluIGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4KU2ludGVya2xhYXMg"
   9.243 +        "S2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kgd2F0IGluIG3igJlu"
   9.244 +        "IGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4=";
   9.245 +    
   9.246 +    const char* output =
   9.247 +        "Sinterklaas Kapoentje,\n"
   9.248 +        "Gooi wat in m’n schoentje,\n"
   9.249 +        "Gooi wat in m’n laarsje.\n"
   9.250 +        "Dank u, Sinterklaasje.\n"
   9.251 +        "Sinterklaas Kapoentje,\n"
   9.252 +        "Gooi wat in m’n schoentje,\n"
   9.253 +        "Gooi wat in m’n laarsje.\n"
   9.254 +        "Dank u, Sinterklaasje.";
   9.255 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.256 +}
   9.257 +
   9.258 +void HeaderKeyImportTests::base_64_padded_2() {
   9.259 +    const char* input = 
   9.260 +        "V2VsbCwgdGhhdCB3YXMgYSBtZXNzLiBCZXR0ZXIgZ2V0IHRoaW5ncyBpbiBvcmRlciBiZWZvcmUg"
   9.261 +        "dGhlIEFyaXNob2sgcmVzcG9uZHMuIENhbid0IGJlIGdvb2QuIFRoZSB2aXNjb3VudCdzIHNvbiwg"
   9.262 +        "UXVuYXJpIGluIHRoZSBDaGFudHJ5LiBCZXQgaXQncyBnb2luZyB0byByYWluLCB0b28uIEhhcmQg"
   9.263 +        "ZW5vdWdoIGRvaW5nIHRoaXMgd2l0aG91dCBzb2FraW5nIG15IGhpZGVzLiBUaGlydHkgcG91bmRz"
   9.264 +        "IG9mIHdhdGVyIGFuZCBpdCdzIGEgbWFyY2ggd2l0aCBubyByYXRpb25zLiBXaGVuIHdhcyB0aGUg"
   9.265 +        "bGFzdCB0aW1lIEkgYXRlPyBXaG8ncyBjb29raW5nIHRvbmlnaHQ/IFNhbmRhbD8gTWFrZXIuIEVu"
   9.266 +        "Y2hhbnRtZW50IHNvdXAgYWdhaW4uIFRodW1iIHJpZ2h0IGluIHRoZSBib3dsIGxhc3QgdGltZS4g"
   9.267 +        "SGlzIGVuY2hhbnRpbmcgaGFuZCwgdG9vLiBZZWFoLCBJIHNhdyB5b3UsIHlvdSBzcXVpcnJlbHkg"
   9.268 +        "bGl0dGxlIGtub3QtaGVhZC4gRGlkIEkgbG9jayBteSBjaGFtYmVycz8gSSdsbCBiZXQgaGUncyBp"
   9.269 +        "biB0aGVyZSBub3cuIFVnaC4gVGhhdCBndXkgbG9va2luZyBhdCBtZT8gVGhlcmUncyBhIGxvdCBv"
   9.270 +        "ZiBpbGxuZXNzIGluIHRoaXMgY2l0eS4gV2hhdCdzIGhlIGxvb2tpbmcgYXQ/IExvb255LiBZZWFo"
   9.271 +        "LCB0aGF0J3MgaXQsIGtlZXAgd2Fsa2luZy4gQ2FuJ3QgdHJ1c3QgYW55b25lLiBDb3VsZCBiZSBs"
   9.272 +        "eXJpdW0tYWRkbGVkLiBGYWRlLWNyYXplZC4gU3RpbGwsIGdvdCB0byBoYXZlIHNvbWUgY29udHJv"
   9.273 +        "bC4gV2hhdCBraW5kIG9mIGRhbWFnZSBzZW5kcyB0aGVzZSBkYWZ0IGZyZWFrcyBvdXQgaW4gdGhl"
   9.274 +        "IHN0cmVldHMgdGFsa2luZyB0byB0aGVtLi4uc2VsdmVzPyBBaGVtLg==";
   9.275 +
   9.276 +    const char* output = 
   9.277 +        "Well, that was a mess. Better get things in order before the Arishok responds. "
   9.278 +        "Can't be good. The viscount's son, Qunari in the Chantry. Bet it's going to rain, too. "
   9.279 +        "Hard enough doing this without soaking my hides. Thirty pounds of water and it's a march with no rations. "
   9.280 +        "When was the last time I ate? Who's cooking tonight? Sandal? Maker. Enchantment soup again. "
   9.281 +        "Thumb right in the bowl last time. His enchanting hand, too. Yeah, I saw you, you squirrely little knot-head. "
   9.282 +        "Did I lock my chambers? I'll bet he's in there now. Ugh. "
   9.283 +        "That guy looking at me? There's a lot of illness in this city. What's he looking at? Loony. "
   9.284 +        "Yeah, that's it, keep walking. Can't trust anyone. Could be lyrium-addled. Fade-crazed. "
   9.285 +        "Still, got to have some control. What kind of damage sends these daft freaks out in the streets talking to them...selves? "
   9.286 +        "Ahem.";
   9.287 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.288 +    
   9.289 +}
   9.290 +
   9.291 +void HeaderKeyImportTests::base_64_unpadded_1() {
   9.292 +    const char* input =
   9.293 +        "U2ludGVya2xhYXMgS2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kg"
   9.294 +        "d2F0IGluIG3igJluIGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4KU2ludGVya2xhYXMg"
   9.295 +        "S2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kgd2F0IGluIG3igJlu"
   9.296 +        "IGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4=";
   9.297 +    
   9.298 +    const char* output =
   9.299 +        "Sinterklaas Kapoentje,\n"
   9.300 +        "Gooi wat in m’n schoentje,\n"
   9.301 +        "Gooi wat in m’n laarsje.\n"
   9.302 +        "Dank u, Sinterklaasje.\n"
   9.303 +        "Sinterklaas Kapoentje,\n"
   9.304 +        "Gooi wat in m’n schoentje,\n"
   9.305 +        "Gooi wat in m’n laarsje.\n"
   9.306 +        "Dank u, Sinterklaasje.";
   9.307 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.308 +
   9.309 +}
   9.310 +
   9.311 +void HeaderKeyImportTests::base_64_unpadded_2() {
   9.312 +    const char* input =
   9.313 +        "V2VsbCwgdGhhdCB3YXMgYSBtZXNzLiBCZXR0ZXIgZ2V0IHRoaW5ncyBpbiBvcmRlciBiZWZvcmUg"
   9.314 +        "dGhlIEFyaXNob2sgcmVzcG9uZHMuIENhbid0IGJlIGdvb2QuIFRoZSB2aXNjb3VudCdzIHNvbiwg"
   9.315 +        "UXVuYXJpIGluIHRoZSBDaGFudHJ5LiBCZXQgaXQncyBnb2luZyB0byByYWluLCB0b28uIEhhcmQg"
   9.316 +        "ZW5vdWdoIGRvaW5nIHRoaXMgd2l0aG91dCBzb2FraW5nIG15IGhpZGVzLiBUaGlydHkgcG91bmRz"
   9.317 +        "IG9mIHdhdGVyIGFuZCBpdCdzIGEgbWFyY2ggd2l0aCBubyByYXRpb25zLiBXaGVuIHdhcyB0aGUg"
   9.318 +        "bGFzdCB0aW1lIEkgYXRlPyBXaG8ncyBjb29raW5nIHRvbmlnaHQ/IFNhbmRhbD8gTWFrZXIuIEVu"
   9.319 +        "Y2hhbnRtZW50IHNvdXAgYWdhaW4uIFRodW1iIHJpZ2h0IGluIHRoZSBib3dsIGxhc3QgdGltZS4g"
   9.320 +        "SGlzIGVuY2hhbnRpbmcgaGFuZCwgdG9vLiBZZWFoLCBJIHNhdyB5b3UsIHlvdSBzcXVpcnJlbHkg"
   9.321 +        "bGl0dGxlIGtub3QtaGVhZC4gRGlkIEkgbG9jayBteSBjaGFtYmVycz8gSSdsbCBiZXQgaGUncyBp"
   9.322 +        "biB0aGVyZSBub3cuIFVnaC4gVGhhdCBndXkgbG9va2luZyBhdCBtZT8gVGhlcmUncyBhIGxvdCBv"
   9.323 +        "ZiBpbGxuZXNzIGluIHRoaXMgY2l0eS4gV2hhdCdzIGhlIGxvb2tpbmcgYXQ/IExvb255LiBZZWFo"
   9.324 +        "LCB0aGF0J3MgaXQsIGtlZXAgd2Fsa2luZy4gQ2FuJ3QgdHJ1c3QgYW55b25lLiBDb3VsZCBiZSBs"
   9.325 +        "eXJpdW0tYWRkbGVkLiBGYWRlLWNyYXplZC4gU3RpbGwsIGdvdCB0byBoYXZlIHNvbWUgY29udHJv"
   9.326 +        "bC4gV2hhdCBraW5kIG9mIGRhbWFnZSBzZW5kcyB0aGVzZSBkYWZ0IGZyZWFrcyBvdXQgaW4gdGhl"
   9.327 +        "IHN0cmVldHMgdGFsa2luZyB0byB0aGVtLi4uc2VsdmVzPyBBaGVtLg";
   9.328 +
   9.329 +    const char* output = 
   9.330 +        "Well, that was a mess. Better get things in order before the Arishok responds. "
   9.331 +        "Can't be good. The viscount's son, Qunari in the Chantry. Bet it's going to rain, too. "
   9.332 +        "Hard enough doing this without soaking my hides. Thirty pounds of water and it's a march with no rations. "
   9.333 +        "When was the last time I ate? Who's cooking tonight? Sandal? Maker. Enchantment soup again. "
   9.334 +        "Thumb right in the bowl last time. His enchanting hand, too. Yeah, I saw you, you squirrely little knot-head. "
   9.335 +        "Did I lock my chambers? I'll bet he's in there now. Ugh. "
   9.336 +        "That guy looking at me? There's a lot of illness in this city. What's he looking at? Loony. "
   9.337 +        "Yeah, that's it, keep walking. Can't trust anyone. Could be lyrium-addled. Fade-crazed. "
   9.338 +        "Still, got to have some control. What kind of damage sends these daft freaks out in the streets talking to them...selves? "
   9.339 +        "Ahem.";
   9.340 +
   9.341 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.342 +
   9.343 +}
   9.344 +
   9.345 +void HeaderKeyImportTests::base_64_leading_whitespace_round() {
   9.346 +    const char* input = "\r\nV2hlbiB0aGluZ3MgZ28gd3JvbmcsIGFzIHRoZX"
   9.347 +                        "kgdXN1YWxseSB3aWxsCkFuZCB5b3VyIGRhaWx5"
   9.348 +                        "IHJvYWQgc2VlbXMgYWxsIHVwaGlsbApXaGVuIG"
   9.349 +                        "Z1bmRzIGFyZSBsb3csIGFuZCBkZWJ0cyBhcmUg"
   9.350 +                        "aGlnaApZb3UgdHJ5IHRvIHNtaWxlLCBidXQgY2"
   9.351 +                        "FuIG9ubHkgY3J5CldoZW4geW91IHJlYWxseSBm"
   9.352 +                        "ZWVsIHlvdSdkIGxpa2UgdG8gcXVpdCwKRG9uJ3"
   9.353 +                        "QgcnVuIHRvIG1lLCBJIGRvbid0IGdpdmUgYSBI"
   9.354 +                        "SSBOT1RISU5HIFRPIFNFRSBIRVJFISEh";
   9.355 +    
   9.356 +    const char* output = "When things go wrong, as they usually will\n"
   9.357 +                         "And your daily road seems all uphill\n"
   9.358 +                         "When funds are low, and debts are high\n"
   9.359 +                         "You try to smile, but can only cry\n"
   9.360 +                         "When you really feel you'd like to quit,\n"
   9.361 +                         "Don't run to me, I don't give a HI NOTHING TO SEE HERE!!!";
   9.362 +    
   9.363 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.364 +}
   9.365 +
   9.366 +void HeaderKeyImportTests::base_64_leading_whitespace_padded_1() {
   9.367 +    const char* input =
   9.368 +        "\tU2ludGVya2xhYXMgS2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kg"
   9.369 +        "d2F0IGluIG3igJluIGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4KU2ludGVya2xhYXMg"
   9.370 +        "S2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kgd2F0IGluIG3igJlu"
   9.371 +        "IGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4=";
   9.372 +    
   9.373 +    const char* output =
   9.374 +        "Sinterklaas Kapoentje,\n"
   9.375 +        "Gooi wat in m’n schoentje,\n"
   9.376 +        "Gooi wat in m’n laarsje.\n"
   9.377 +        "Dank u, Sinterklaasje.\n"
   9.378 +        "Sinterklaas Kapoentje,\n"
   9.379 +        "Gooi wat in m’n schoentje,\n"
   9.380 +        "Gooi wat in m’n laarsje.\n"
   9.381 +        "Dank u, Sinterklaasje.";
   9.382 +        
   9.383 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.384 +        
   9.385 +}
   9.386 +
   9.387 +void HeaderKeyImportTests::base_64_leading_whitespace_padded_2() {
   9.388 +    const char* input = 
   9.389 +        " V2VsbCwgdGhhdCB3YXMgYSBtZXNzLiBCZXR0ZXIgZ2V0IHRoaW5ncyBpbiBvcmRlciBiZWZvcmUg"
   9.390 +        "dGhlIEFyaXNob2sgcmVzcG9uZHMuIENhbid0IGJlIGdvb2QuIFRoZSB2aXNjb3VudCdzIHNvbiwg"
   9.391 +        "UXVuYXJpIGluIHRoZSBDaGFudHJ5LiBCZXQgaXQncyBnb2luZyB0byByYWluLCB0b28uIEhhcmQg"
   9.392 +        "ZW5vdWdoIGRvaW5nIHRoaXMgd2l0aG91dCBzb2FraW5nIG15IGhpZGVzLiBUaGlydHkgcG91bmRz"
   9.393 +        "IG9mIHdhdGVyIGFuZCBpdCdzIGEgbWFyY2ggd2l0aCBubyByYXRpb25zLiBXaGVuIHdhcyB0aGUg"
   9.394 +        "bGFzdCB0aW1lIEkgYXRlPyBXaG8ncyBjb29raW5nIHRvbmlnaHQ/IFNhbmRhbD8gTWFrZXIuIEVu"
   9.395 +        "Y2hhbnRtZW50IHNvdXAgYWdhaW4uIFRodW1iIHJpZ2h0IGluIHRoZSBib3dsIGxhc3QgdGltZS4g"
   9.396 +        "SGlzIGVuY2hhbnRpbmcgaGFuZCwgdG9vLiBZZWFoLCBJIHNhdyB5b3UsIHlvdSBzcXVpcnJlbHkg"
   9.397 +        "bGl0dGxlIGtub3QtaGVhZC4gRGlkIEkgbG9jayBteSBjaGFtYmVycz8gSSdsbCBiZXQgaGUncyBp"
   9.398 +        "biB0aGVyZSBub3cuIFVnaC4gVGhhdCBndXkgbG9va2luZyBhdCBtZT8gVGhlcmUncyBhIGxvdCBv"
   9.399 +        "ZiBpbGxuZXNzIGluIHRoaXMgY2l0eS4gV2hhdCdzIGhlIGxvb2tpbmcgYXQ/IExvb255LiBZZWFo"
   9.400 +        "LCB0aGF0J3MgaXQsIGtlZXAgd2Fsa2luZy4gQ2FuJ3QgdHJ1c3QgYW55b25lLiBDb3VsZCBiZSBs"
   9.401 +        "eXJpdW0tYWRkbGVkLiBGYWRlLWNyYXplZC4gU3RpbGwsIGdvdCB0byBoYXZlIHNvbWUgY29udHJv"
   9.402 +        "bC4gV2hhdCBraW5kIG9mIGRhbWFnZSBzZW5kcyB0aGVzZSBkYWZ0IGZyZWFrcyBvdXQgaW4gdGhl"
   9.403 +        "IHN0cmVldHMgdGFsa2luZyB0byB0aGVtLi4uc2VsdmVzPyBBaGVtLg==";
   9.404 +
   9.405 +    const char* output = 
   9.406 +        "Well, that was a mess. Better get things in order before the Arishok responds. "
   9.407 +        "Can't be good. The viscount's son, Qunari in the Chantry. Bet it's going to rain, too. "
   9.408 +        "Hard enough doing this without soaking my hides. Thirty pounds of water and it's a march with no rations. "
   9.409 +        "When was the last time I ate? Who's cooking tonight? Sandal? Maker. Enchantment soup again. "
   9.410 +        "Thumb right in the bowl last time. His enchanting hand, too. Yeah, I saw you, you squirrely little knot-head. "
   9.411 +        "Did I lock my chambers? I'll bet he's in there now. Ugh. "
   9.412 +        "That guy looking at me? There's a lot of illness in this city. What's he looking at? Loony. "
   9.413 +        "Yeah, that's it, keep walking. Can't trust anyone. Could be lyrium-addled. Fade-crazed. "
   9.414 +        "Still, got to have some control. What kind of damage sends these daft freaks out in the streets talking to them...selves? "
   9.415 +        "Ahem.";
   9.416 +        
   9.417 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.418 +        
   9.419 +}
   9.420 +
   9.421 +void HeaderKeyImportTests::base_64_leading_whitespace_unpadded_1() {
   9.422 +    const char* input =
   9.423 +        "\n\nU2ludGVya2xhYXMgS2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kg"
   9.424 +        "d2F0IGluIG3igJluIGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4KU2ludGVya2xhYXMg"
   9.425 +        "S2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kgd2F0IGluIG3igJlu"
   9.426 +        "IGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4";
   9.427 +    
   9.428 +    const char* output =
   9.429 +        "Sinterklaas Kapoentje,\n"
   9.430 +        "Gooi wat in m’n schoentje,\n"
   9.431 +        "Gooi wat in m’n laarsje.\n"
   9.432 +        "Dank u, Sinterklaasje.\n"
   9.433 +        "Sinterklaas Kapoentje,\n"
   9.434 +        "Gooi wat in m’n schoentje,\n"
   9.435 +        "Gooi wat in m’n laarsje.\n"
   9.436 +        "Dank u, Sinterklaasje.";
   9.437 +
   9.438 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.439 +
   9.440 +}
   9.441 +
   9.442 +void HeaderKeyImportTests::base_64_leading_whitespace_unpadded_2() {
   9.443 +    const char* input = 
   9.444 +        "   V2VsbCwgdGhhdCB3YXMgYSBtZXNzLiBCZXR0ZXIgZ2V0IHRoaW5ncyBpbiBvcmRlciBiZWZvcmUg"
   9.445 +        "dGhlIEFyaXNob2sgcmVzcG9uZHMuIENhbid0IGJlIGdvb2QuIFRoZSB2aXNjb3VudCdzIHNvbiwg"
   9.446 +        "UXVuYXJpIGluIHRoZSBDaGFudHJ5LiBCZXQgaXQncyBnb2luZyB0byByYWluLCB0b28uIEhhcmQg"
   9.447 +        "ZW5vdWdoIGRvaW5nIHRoaXMgd2l0aG91dCBzb2FraW5nIG15IGhpZGVzLiBUaGlydHkgcG91bmRz"
   9.448 +        "IG9mIHdhdGVyIGFuZCBpdCdzIGEgbWFyY2ggd2l0aCBubyByYXRpb25zLiBXaGVuIHdhcyB0aGUg"
   9.449 +        "bGFzdCB0aW1lIEkgYXRlPyBXaG8ncyBjb29raW5nIHRvbmlnaHQ/IFNhbmRhbD8gTWFrZXIuIEVu"
   9.450 +        "Y2hhbnRtZW50IHNvdXAgYWdhaW4uIFRodW1iIHJpZ2h0IGluIHRoZSBib3dsIGxhc3QgdGltZS4g"
   9.451 +        "SGlzIGVuY2hhbnRpbmcgaGFuZCwgdG9vLiBZZWFoLCBJIHNhdyB5b3UsIHlvdSBzcXVpcnJlbHkg"
   9.452 +        "bGl0dGxlIGtub3QtaGVhZC4gRGlkIEkgbG9jayBteSBjaGFtYmVycz8gSSdsbCBiZXQgaGUncyBp"
   9.453 +        "biB0aGVyZSBub3cuIFVnaC4gVGhhdCBndXkgbG9va2luZyBhdCBtZT8gVGhlcmUncyBhIGxvdCBv"
   9.454 +        "ZiBpbGxuZXNzIGluIHRoaXMgY2l0eS4gV2hhdCdzIGhlIGxvb2tpbmcgYXQ/IExvb255LiBZZWFo"
   9.455 +        "LCB0aGF0J3MgaXQsIGtlZXAgd2Fsa2luZy4gQ2FuJ3QgdHJ1c3QgYW55b25lLiBDb3VsZCBiZSBs"
   9.456 +        "eXJpdW0tYWRkbGVkLiBGYWRlLWNyYXplZC4gU3RpbGwsIGdvdCB0byBoYXZlIHNvbWUgY29udHJv"
   9.457 +        "bC4gV2hhdCBraW5kIG9mIGRhbWFnZSBzZW5kcyB0aGVzZSBkYWZ0IGZyZWFrcyBvdXQgaW4gdGhl"
   9.458 +        "IHN0cmVldHMgdGFsa2luZyB0byB0aGVtLi4uc2VsdmVzPyBBaGVtLg";
   9.459 +
   9.460 +    const char* output = 
   9.461 +        "Well, that was a mess. Better get things in order before the Arishok responds. "
   9.462 +        "Can't be good. The viscount's son, Qunari in the Chantry. Bet it's going to rain, too. "
   9.463 +        "Hard enough doing this without soaking my hides. Thirty pounds of water and it's a march with no rations. "
   9.464 +        "When was the last time I ate? Who's cooking tonight? Sandal? Maker. Enchantment soup again. "
   9.465 +        "Thumb right in the bowl last time. His enchanting hand, too. Yeah, I saw you, you squirrely little knot-head. "
   9.466 +        "Did I lock my chambers? I'll bet he's in there now. Ugh. "
   9.467 +        "That guy looking at me? There's a lot of illness in this city. What's he looking at? Loony. "
   9.468 +        "Yeah, that's it, keep walking. Can't trust anyone. Could be lyrium-addled. Fade-crazed. "
   9.469 +        "Still, got to have some control. What kind of damage sends these daft freaks out in the streets talking to them...selves? "
   9.470 +        "Ahem.";
   9.471 +
   9.472 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.473 +
   9.474 +}
   9.475 +
   9.476 +void HeaderKeyImportTests::base_64_trailing_whitespace_round() {
   9.477 +    const char* input = "V2hlbiB0aGluZ3MgZ28gd3JvbmcsIGFzIHRoZX"
   9.478 +                        "kgdXN1YWxseSB3aWxsCkFuZCB5b3VyIGRhaWx5"
   9.479 +                        "IHJvYWQgc2VlbXMgYWxsIHVwaGlsbApXaGVuIG"
   9.480 +                        "Z1bmRzIGFyZSBsb3csIGFuZCBkZWJ0cyBhcmUg"
   9.481 +                        "aGlnaApZb3UgdHJ5IHRvIHNtaWxlLCBidXQgY2"
   9.482 +                        "FuIG9ubHkgY3J5CldoZW4geW91IHJlYWxseSBm"
   9.483 +                        "ZWVsIHlvdSdkIGxpa2UgdG8gcXVpdCwKRG9uJ3"
   9.484 +                        "QgcnVuIHRvIG1lLCBJIGRvbid0IGdpdmUgYSBI"
   9.485 +                        "SSBOT1RISU5HIFRPIFNFRSBIRVJFISEh\n";
   9.486 +    
   9.487 +    const char* output = "When things go wrong, as they usually will\n"
   9.488 +                         "And your daily road seems all uphill\n"
   9.489 +                         "When funds are low, and debts are high\n"
   9.490 +                         "You try to smile, but can only cry\n"
   9.491 +                         "When you really feel you'd like to quit,\n"
   9.492 +                         "Don't run to me, I don't give a HI NOTHING TO SEE HERE!!!";
   9.493 +    
   9.494 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.495 +}
   9.496 +
   9.497 +void HeaderKeyImportTests::base_64_trailing_whitespace_padded_1() {
   9.498 +    const char* input =
   9.499 +        "U2ludGVya2xhYXMgS2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kg"
   9.500 +        "d2F0IGluIG3igJluIGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4KU2ludGVya2xhYXMg"
   9.501 +        "S2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kgd2F0IGluIG3igJlu"
   9.502 +        "IGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4=   \n";
   9.503 +    
   9.504 +    const char* output =
   9.505 +        "Sinterklaas Kapoentje,\n"
   9.506 +        "Gooi wat in m’n schoentje,\n"
   9.507 +        "Gooi wat in m’n laarsje.\n"
   9.508 +        "Dank u, Sinterklaasje.\n"
   9.509 +        "Sinterklaas Kapoentje,\n"
   9.510 +        "Gooi wat in m’n schoentje,\n"
   9.511 +        "Gooi wat in m’n laarsje.\n"
   9.512 +        "Dank u, Sinterklaasje.";
   9.513 +
   9.514 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.515 +
   9.516 +}
   9.517 +
   9.518 +void HeaderKeyImportTests::base_64_trailing_whitespace_padded_2() {
   9.519 +    const char* input = 
   9.520 +        "V2VsbCwgdGhhdCB3YXMgYSBtZXNzLiBCZXR0ZXIgZ2V0IHRoaW5ncyBpbiBvcmRlciBiZWZvcmUg"
   9.521 +        "dGhlIEFyaXNob2sgcmVzcG9uZHMuIENhbid0IGJlIGdvb2QuIFRoZSB2aXNjb3VudCdzIHNvbiwg"
   9.522 +        "UXVuYXJpIGluIHRoZSBDaGFudHJ5LiBCZXQgaXQncyBnb2luZyB0byByYWluLCB0b28uIEhhcmQg"
   9.523 +        "ZW5vdWdoIGRvaW5nIHRoaXMgd2l0aG91dCBzb2FraW5nIG15IGhpZGVzLiBUaGlydHkgcG91bmRz"
   9.524 +        "IG9mIHdhdGVyIGFuZCBpdCdzIGEgbWFyY2ggd2l0aCBubyByYXRpb25zLiBXaGVuIHdhcyB0aGUg"
   9.525 +        "bGFzdCB0aW1lIEkgYXRlPyBXaG8ncyBjb29raW5nIHRvbmlnaHQ/IFNhbmRhbD8gTWFrZXIuIEVu"
   9.526 +        "Y2hhbnRtZW50IHNvdXAgYWdhaW4uIFRodW1iIHJpZ2h0IGluIHRoZSBib3dsIGxhc3QgdGltZS4g"
   9.527 +        "SGlzIGVuY2hhbnRpbmcgaGFuZCwgdG9vLiBZZWFoLCBJIHNhdyB5b3UsIHlvdSBzcXVpcnJlbHkg"
   9.528 +        "bGl0dGxlIGtub3QtaGVhZC4gRGlkIEkgbG9jayBteSBjaGFtYmVycz8gSSdsbCBiZXQgaGUncyBp"
   9.529 +        "biB0aGVyZSBub3cuIFVnaC4gVGhhdCBndXkgbG9va2luZyBhdCBtZT8gVGhlcmUncyBhIGxvdCBv"
   9.530 +        "ZiBpbGxuZXNzIGluIHRoaXMgY2l0eS4gV2hhdCdzIGhlIGxvb2tpbmcgYXQ/IExvb255LiBZZWFo"
   9.531 +        "LCB0aGF0J3MgaXQsIGtlZXAgd2Fsa2luZy4gQ2FuJ3QgdHJ1c3QgYW55b25lLiBDb3VsZCBiZSBs"
   9.532 +        "eXJpdW0tYWRkbGVkLiBGYWRlLWNyYXplZC4gU3RpbGwsIGdvdCB0byBoYXZlIHNvbWUgY29udHJv"
   9.533 +        "bC4gV2hhdCBraW5kIG9mIGRhbWFnZSBzZW5kcyB0aGVzZSBkYWZ0IGZyZWFrcyBvdXQgaW4gdGhl"
   9.534 +        "IHN0cmVldHMgdGFsa2luZyB0byB0aGVtLi4uc2VsdmVzPyBBaGVtLg==         \n";
   9.535 +
   9.536 +    const char* output = 
   9.537 +        "Well, that was a mess. Better get things in order before the Arishok responds. "
   9.538 +        "Can't be good. The viscount's son, Qunari in the Chantry. Bet it's going to rain, too. "
   9.539 +        "Hard enough doing this without soaking my hides. Thirty pounds of water and it's a march with no rations. "
   9.540 +        "When was the last time I ate? Who's cooking tonight? Sandal? Maker. Enchantment soup again. "
   9.541 +        "Thumb right in the bowl last time. His enchanting hand, too. Yeah, I saw you, you squirrely little knot-head. "
   9.542 +        "Did I lock my chambers? I'll bet he's in there now. Ugh. "
   9.543 +        "That guy looking at me? There's a lot of illness in this city. What's he looking at? Loony. "
   9.544 +        "Yeah, that's it, keep walking. Can't trust anyone. Could be lyrium-addled. Fade-crazed. "
   9.545 +        "Still, got to have some control. What kind of damage sends these daft freaks out in the streets talking to them...selves? "
   9.546 +        "Ahem.";
   9.547 +
   9.548 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.549 +
   9.550 +}
   9.551 +
   9.552 +void HeaderKeyImportTests::base_64_trailing_whitespace_unpadded_1() {
   9.553 +    const char* input =
   9.554 +        "U2ludGVya2xhYXMgS2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kg"
   9.555 +        "d2F0IGluIG3igJluIGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4KU2ludGVya2xhYXMg"
   9.556 +        "S2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kgd2F0IGluIG3igJlu"
   9.557 +        "IGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4   \n";
   9.558 +    
   9.559 +    const char* output =
   9.560 +        "Sinterklaas Kapoentje,\n"
   9.561 +        "Gooi wat in m’n schoentje,\n"
   9.562 +        "Gooi wat in m’n laarsje.\n"
   9.563 +        "Dank u, Sinterklaasje.\n"
   9.564 +        "Sinterklaas Kapoentje,\n"
   9.565 +        "Gooi wat in m’n schoentje,\n"
   9.566 +        "Gooi wat in m’n laarsje.\n"
   9.567 +        "Dank u, Sinterklaasje.";
   9.568 +
   9.569 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.570 +
   9.571 +}
   9.572 +
   9.573 +void HeaderKeyImportTests::base_64_trailing_whitespace_unpadded_2() {
   9.574 +    const char* input = 
   9.575 +        "V2VsbCwgdGhhdCB3YXMgYSBtZXNzLiBCZXR0ZXIgZ2V0IHRoaW5ncyBpbiBvcmRlciBiZWZvcmUg"
   9.576 +        "dGhlIEFyaXNob2sgcmVzcG9uZHMuIENhbid0IGJlIGdvb2QuIFRoZSB2aXNjb3VudCdzIHNvbiwg"
   9.577 +        "UXVuYXJpIGluIHRoZSBDaGFudHJ5LiBCZXQgaXQncyBnb2luZyB0byByYWluLCB0b28uIEhhcmQg"
   9.578 +        "ZW5vdWdoIGRvaW5nIHRoaXMgd2l0aG91dCBzb2FraW5nIG15IGhpZGVzLiBUaGlydHkgcG91bmRz"
   9.579 +        "IG9mIHdhdGVyIGFuZCBpdCdzIGEgbWFyY2ggd2l0aCBubyByYXRpb25zLiBXaGVuIHdhcyB0aGUg"
   9.580 +        "bGFzdCB0aW1lIEkgYXRlPyBXaG8ncyBjb29raW5nIHRvbmlnaHQ/IFNhbmRhbD8gTWFrZXIuIEVu"
   9.581 +        "Y2hhbnRtZW50IHNvdXAgYWdhaW4uIFRodW1iIHJpZ2h0IGluIHRoZSBib3dsIGxhc3QgdGltZS4g"
   9.582 +        "SGlzIGVuY2hhbnRpbmcgaGFuZCwgdG9vLiBZZWFoLCBJIHNhdyB5b3UsIHlvdSBzcXVpcnJlbHkg"
   9.583 +        "bGl0dGxlIGtub3QtaGVhZC4gRGlkIEkgbG9jayBteSBjaGFtYmVycz8gSSdsbCBiZXQgaGUncyBp"
   9.584 +        "biB0aGVyZSBub3cuIFVnaC4gVGhhdCBndXkgbG9va2luZyBhdCBtZT8gVGhlcmUncyBhIGxvdCBv"
   9.585 +        "ZiBpbGxuZXNzIGluIHRoaXMgY2l0eS4gV2hhdCdzIGhlIGxvb2tpbmcgYXQ/IExvb255LiBZZWFo"
   9.586 +        "LCB0aGF0J3MgaXQsIGtlZXAgd2Fsa2luZy4gQ2FuJ3QgdHJ1c3QgYW55b25lLiBDb3VsZCBiZSBs"
   9.587 +        "eXJpdW0tYWRkbGVkLiBGYWRlLWNyYXplZC4gU3RpbGwsIGdvdCB0byBoYXZlIHNvbWUgY29udHJv"
   9.588 +        "bC4gV2hhdCBraW5kIG9mIGRhbWFnZSBzZW5kcyB0aGVzZSBkYWZ0IGZyZWFrcyBvdXQgaW4gdGhl"
   9.589 +        "IHN0cmVldHMgdGFsa2luZyB0byB0aGVtLi4uc2VsdmVzPyBBaGVtLg\r\n";
   9.590 +
   9.591 +    const char* output = 
   9.592 +        "Well, that was a mess. Better get things in order before the Arishok responds. "
   9.593 +        "Can't be good. The viscount's son, Qunari in the Chantry. Bet it's going to rain, too. "
   9.594 +        "Hard enough doing this without soaking my hides. Thirty pounds of water and it's a march with no rations. "
   9.595 +        "When was the last time I ate? Who's cooking tonight? Sandal? Maker. Enchantment soup again. "
   9.596 +        "Thumb right in the bowl last time. His enchanting hand, too. Yeah, I saw you, you squirrely little knot-head. "
   9.597 +        "Did I lock my chambers? I'll bet he's in there now. Ugh. "
   9.598 +        "That guy looking at me? There's a lot of illness in this city. What's he looking at? Loony. "
   9.599 +        "Yeah, that's it, keep walking. Can't trust anyone. Could be lyrium-addled. Fade-crazed. "
   9.600 +        "Still, got to have some control. What kind of damage sends these daft freaks out in the streets talking to them...selves? "
   9.601 +        "Ahem.";
   9.602 +
   9.603 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.604 +
   9.605 +}
   9.606 +
   9.607 +void HeaderKeyImportTests::base_64_kitchen_sink_round() {
   9.608 +    const char* input = "\r\nV2hlbiB0aGluZ3MgZ28gd3JvbmcsIGFzIHRoZX\n"
   9.609 +                        "kgdXN1YWxseSB3aWxsCkFuZCB5b3VyIGRhaWx5\n"
   9.610 +                        "IHJvYWQgc2VlbXMgYWxsIHVwaGlsbApXaGVuIG\n"
   9.611 +                        "Z1bmRzIGFyZSBsb3csIGFuZCBkZWJ0cyBhcmUg\n"
   9.612 +                        "aGlnaApZb3UgdHJ5IHRvIHNtaWxlLCBidXQgY2\n"
   9.613 +                        "FuIG9ubHkgY3J5CldoZW4geW91IHJlYWxseSBm\n"
   9.614 +                        "ZWVsIHlvdSdkIGxpa2UgdG8gcXVpdCwKRG9uJ3\n"
   9.615 +                        "QgcnVuIHRvIG1lLCBJIGRvbid0IGdpdmUgYSBI\n"
   9.616 +                        "SSBOT1RISU5HIFRPIFNFRSBIRVJFISEh\r\n";
   9.617 +    
   9.618 +    const char* output = "When things go wrong, as they usually will\n"
   9.619 +                         "And your daily road seems all uphill\n"
   9.620 +                         "When funds are low, and debts are high\n"
   9.621 +                         "You try to smile, but can only cry\n"
   9.622 +                         "When you really feel you'd like to quit,\n"
   9.623 +                         "Don't run to me, I don't give a HI NOTHING TO SEE HERE!!!";
   9.624 +    
   9.625 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.626 +}
   9.627 +
   9.628 +void HeaderKeyImportTests::base_64_kitchen_sink_padded_1() {
   9.629 +    const char* input =
   9.630 +        "\r\nU2ludGVya2xhYXMgS2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kg\n"
   9.631 +        "d2F0IGluIG3igJluIGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4KU2ludGVya2xhYXMg\n"
   9.632 +        "S2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kgd2F0IGluIG3igJlu\n"
   9.633 +        "IGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4=   \n";
   9.634 +    
   9.635 +    const char* output =
   9.636 +        "Sinterklaas Kapoentje,\n"
   9.637 +        "Gooi wat in m’n schoentje,\n"
   9.638 +        "Gooi wat in m’n laarsje.\n"
   9.639 +        "Dank u, Sinterklaasje.\n"
   9.640 +        "Sinterklaas Kapoentje,\n"
   9.641 +        "Gooi wat in m’n schoentje,\n"
   9.642 +        "Gooi wat in m’n laarsje.\n"
   9.643 +        "Dank u, Sinterklaasje.";
   9.644 +
   9.645 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.646 +
   9.647 +}
   9.648 +
   9.649 +void HeaderKeyImportTests::base_64_kitchen_sink_padded_2() {
   9.650 +    const char* input = 
   9.651 +        "                                                                                                 V2VsbCwgdGhhdCB3YXMgYSBtZXNzLiBCZXR0ZXIgZ2V0IHRoaW5ncyBpbiBvcmRlciBiZWZvcmUg\n"
   9.652 +        "dGhlIEFyaXNob2s gcmVzcG9uZHMuIENhbid0IGJlIGdvb2QuIFRoZSB2aXNjb3VudCdzIHNvbiwg\n"
   9.653 +        "UXVuYXJpIGluIHRoZSBDaGFudHJ5LiBCZXQgaXQncyBnb2luZyB0byByYWluLCB0b28uIEhhcmQg\n"
   9.654 +        "ZW5vdWdoIGRvaW5n IHRoaXMgd2l0aG91dCBzb2FraW5nIG15IGhpZGVzLiBUaGlydHkgcG91bmRz\n"
   9.655 +        "IG9mIHdhdGVyIGFuZCBpdCdzIGEgbWFyY2ggd2l0aCBubyByYXRpb25zLiBXaGVuIHdhcyB0aGUg\n"
   9.656 +        "bGFzdCB0aW1lIEkgYXRlPyBXaG8ncyB\tjb29raW5nIHRvbmlnaHQ/IFNhbmRhbD8gTWFrZXIuIEVu\r\n"
   9.657 +        "Y2hhbnRtZW50IHNvdXAgYWdhaW4uIFRodW1iIHJpZ2h0IGluIHRoZSBib3dsIGxhc3QgdGltZS4g\n"
   9.658 +        "SGlzIGVuY2hhbnRpbmcgaGFuZCwgdG9vLiBZZWFoLCBJIHNhdyB5b3UsIHlvdSBzcXVpcnJlbHkg\n"
   9.659 +        "bGl0dGxlIGtub3QtaGVhZC4gRGlkIEkgbG9jayBteSBjaGFtYmVycz8gSSdsbCBiZXQgaGUncyBp\n"
   9.660 +        "biB0aGVyZSBub3cuIFVnaC4gVGhhdCBndXkgbG9va2luZyBhdCBtZT8gVGhlcmUncyBhIGxvdCBv\n"
   9.661 +        "ZiBpbGxuZXNzIGluIHRoaXMgY2l0eS4gV2hhdCdzIGhlIGxvb2tpbm cgYXQ/IExvb255LiBZZWFo\n"
   9.662 +        "LCB0aGF0J3MgaXQsIGtlZXAgd2Fsa2luZy4\n\n\ngQ2FuJ3QgdHJ1c3QgYW55b25lLiBDb3VsZCBiZSBs\n"
   9.663 +        "eXJpdW0tYWRkbGVkLiBGYWRlLWNyYXplZC4gU3RpbGwsIGdvdCB0byBoYXZlIHNvbWUgY29udHJv\n"
   9.664 +        "bC4gV2hhdCBraW5kIG9mIGRhbWFnZSBzZW5kcyB0aGVzZSBkYWZ0IGZyZWFrcyBvdXQgaW4gdGhl\n"
   9.665 +        "IHN0cmVldHMgdGFsa2luZyB0byB0aGVtLi4uc2VsdmVzPyBBaGVtLg==\n\n\n\n  \t";
   9.666 +
   9.667 +    const char* output = 
   9.668 +        "Well, that was a mess. Better get things in order before the Arishok responds. "
   9.669 +        "Can't be good. The viscount's son, Qunari in the Chantry. Bet it's going to rain, too. "
   9.670 +        "Hard enough doing this without soaking my hides. Thirty pounds of water and it's a march with no rations. "
   9.671 +        "When was the last time I ate? Who's cooking tonight? Sandal? Maker. Enchantment soup again. "
   9.672 +        "Thumb right in the bowl last time. His enchanting hand, too. Yeah, I saw you, you squirrely little knot-head. "
   9.673 +        "Did I lock my chambers? I'll bet he's in there now. Ugh. "
   9.674 +        "That guy looking at me? There's a lot of illness in this city. What's he looking at? Loony. "
   9.675 +        "Yeah, that's it, keep walking. Can't trust anyone. Could be lyrium-addled. Fade-crazed. "
   9.676 +        "Still, got to have some control. What kind of damage sends these daft freaks out in the streets talking to them...selves? "
   9.677 +        "Ahem.";
   9.678 +
   9.679 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.680 +
   9.681 +}
   9.682 +
   9.683 +void HeaderKeyImportTests::base_64_kitchen_sink_unpadded_1() {
   9.684 +    const char* input =
   9.685 +        "\r\nU2ludGVya2xhYXMgS2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kg\n"
   9.686 +        "d2F0IGluIG3igJluIGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4KU2ludGVya2xhYXMg\n"
   9.687 +        "S2Fwb2VudGplLApHb29pIHdhdCBpbiBt4oCZbiBzY2hvZW50amUsCkdvb2kgd2F0IGluIG3igJlu\n"
   9.688 +        "IGxhYXJzamUuCkRhbmsgdSwgU2ludGVya2xhYXNqZS4   \n";
   9.689 +    
   9.690 +    const char* output =
   9.691 +        "Sinterklaas Kapoentje,\n"
   9.692 +        "Gooi wat in m’n schoentje,\n"
   9.693 +        "Gooi wat in m’n laarsje.\n"
   9.694 +        "Dank u, Sinterklaasje.\n"
   9.695 +        "Sinterklaas Kapoentje,\n"
   9.696 +        "Gooi wat in m’n schoentje,\n"
   9.697 +        "Gooi wat in m’n laarsje.\n"
   9.698 +        "Dank u, Sinterklaasje.";
   9.699 +
   9.700 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.701 +
   9.702 +}
   9.703 +
   9.704 +void HeaderKeyImportTests::base_64_kitchen_sink_unpadded_2() {
   9.705 +    const char* input = 
   9.706 +        "\r\n\r\n\r\nV2VsbCwgdGhhdCB3YXMgYSBtZXNzLiBCZXR0ZXIgZ2V0IHRoaW5ncyBpbiBvcmRlciBiZWZvcmUg\r\n"
   9.707 +        "dGhlIEFyaXNob2sgcmVzcG9uZHMuIENhbid0IGJlIGdvb2QuIFRoZSB2aXNjb3VudCdzIHNvbiwg\r\n"
   9.708 +        "UXVuYXJpIGluIHRoZSBDaGFudHJ5LiBCZXQgaXQncyBnb2luZyB0byByYWluLCB0b28uIEhhcmQg\r\n"
   9.709 +        "ZW5vdWdoIGRvaW5nIHRoaXMgd2l0aG91dCBzb2FraW5nIG15IGhpZGVzLiBUaGlydHkgcG91bmRz\r\n"
   9.710 +        "IG9mIHdhdGVyIGFuZCBpdCdzIGEgbWFyY2ggd2l0aCBubyByYXRpb25zLiBXaGVuIHdhcyB0aGUg\r\n"
   9.711 +        "bGFzdCB0aW1lIEkgYXRlPyBXaG8ncyBjb29raW5nIHRvbmlnaHQ/IFNhbmRhbD8gTWFrZXIuIEVu\r\n"
   9.712 +        "Y2hhbnRtZW50IHNvdXAgYWdhaW4uIFRodW1iIHJpZ2h0IGluIHRoZSBib3dsIGxhc3QgdGltZS4g\r\n"
   9.713 +        "SGlzIGVuY2hhbnRpbmcgaGFuZCwgdG9vLiBZZWFoLCBJIHNhdyB5b3UsIHlvdSBzcXVpcnJlbHkg\r\n"
   9.714 +        "bGl0dGxlIGtub3QtaGVhZC4gRGlkIEkgbG9jayBteSBjaGFtYmVycz8gSSdsbCBiZXQgaGUncyBp\r\n"
   9.715 +        "biB0aGVyZSBub3cuIFVnaC4gVGhhdCBndXkgbG9va2luZyBhdCBtZT8gVGhlcmUncyBhIGxvdCBv\r\n"
   9.716 +        "ZiBpbGxuZXNzIGluIHRoaXMgY2l0eS4gV2hhdCdzIGhlIGxvb2tpbmcgYXQ/IExvb255LiBZZWFo\r\n"
   9.717 +        "LCB0aGF0J3MgaXQsIGtlZXAgd2Fsa2luZy4gQ2FuJ3QgdHJ1c3QgYW55b25lLiBDb3VsZCBiZSBs\r\n"
   9.718 +        "eXJpdW0tYWRkbGVkLiBGYWRlLWNyYXplZC4gU3RpbGwsIGdvdCB0byBoYXZlIHNvbWUgY29udHJv\r\n"
   9.719 +        "bC4gV2hhdCBraW5kIG9mIGRhbWFnZSBzZW5kcyB0aGVzZSBkYWZ0IGZyZWFrcyBvdXQgaW4gdGhl\r\n"
   9.720 +        "IHN0cmVldHMgdGFsa2luZyB0byB0aGVtLi4uc2VsdmVzPyBBaGVtLg\r\n";
   9.721 +
   9.722 +    const char* output = 
   9.723 +        "Well, that was a mess. Better get things in order before the Arishok responds. "
   9.724 +        "Can't be good. The viscount's son, Qunari in the Chantry. Bet it's going to rain, too. "
   9.725 +        "Hard enough doing this without soaking my hides. Thirty pounds of water and it's a march with no rations. "
   9.726 +        "When was the last time I ate? Who's cooking tonight? Sandal? Maker. Enchantment soup again. "
   9.727 +        "Thumb right in the bowl last time. His enchanting hand, too. Yeah, I saw you, you squirrely little knot-head. "
   9.728 +        "Did I lock my chambers? I'll bet he's in there now. Ugh. "
   9.729 +        "That guy looking at me? There's a lot of illness in this city. What's he looking at? Loony. "
   9.730 +        "Yeah, that's it, keep walking. Can't trust anyone. Could be lyrium-addled. Fade-crazed. "
   9.731 +        "Still, got to have some control. What kind of damage sends these daft freaks out in the streets talking to them...selves? "
   9.732 +        "Ahem.";
   9.733 +
   9.734 +    TEST_ASSERT(verify_base_64_test(input, output));
   9.735 +
   9.736 +}
   9.737 +
   9.738 +void HeaderKeyImportTests::check_header_key_import() {
   9.739 +    const char* alice_fpr = "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97";
   9.740 +    slurp_and_import_key(session, "test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc");
   9.741 +    slurp_and_import_key(session, "test_keys/priv/pep-test-bob-0xC9C2EE39_priv.asc");
   9.742 +    
   9.743 +    string message = slurp("test_mails/Header_key_import.eml");
   9.744 +    
   9.745 +    char* dec_msg = NULL;
   9.746 +
   9.747 +    stringlist_t* keylist = NULL;
   9.748 +
   9.749 +    PEP_rating rating;
   9.750 +    PEP_decrypt_flags_t flags;
   9.751 +
   9.752 +    flags = 0;
   9.753 +    char* modified_src = NULL;
   9.754 +    PEP_STATUS status = MIME_decrypt_message(session, message.c_str(), message.size(), &dec_msg, &keylist, &rating, &flags, &modified_src);
   9.755 +    TEST_ASSERT_MSG(rating == PEP_rating_reliable, tl_rating_string(rating));
   9.756 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   9.757 +
   9.758 +    pEp_identity* alice_check = new_identity("pep.test.alice@pep-project.org", NULL, NULL, "pEp Test Alice");
   9.759 +    status = update_identity(session, alice_check);
   9.760 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   9.761 +    TEST_ASSERT(alice_check->fpr);
   9.762 +    TEST_ASSERT_MSG(strcmp(alice_check->fpr, alice_fpr) == 0, alice_check->fpr);
   9.763 +    free(dec_msg);
   9.764 +    free(modified_src);
   9.765 +    free_identity(alice_check);
   9.766 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/test/test_mails/Header_key_import.eml	Tue Oct 09 19:56:07 2018 +0200
    10.3 @@ -0,0 +1,87 @@
    10.4 +Reply-To: krista@pep-project.org
    10.5 +To: pEp Test Bob <pep.test.bob@pep-project.org>
    10.6 +From: pEp Test Alice <pep.test.alice@pep-project.org>
    10.7 +Subject: Header key import
    10.8 +Openpgp: preference=signencrypt
    10.9 +Autocrypt: addr=pep.test.alice@pep-project.org; prefer-encrypt=mutual;
   10.10 + keydata=
   10.11 + xsBNBFV4PbEBCADTmjGDsoti/VPoZ3w2oCjLBNq1jWIGMkbiUgCGUQjVsNrSZ80U7RmA3Pcu
   10.12 + 3hhiVQNBGA32vL6NPhSJPanVd77s6XVZg+Gq7llbGGkuIxSkJvVrWzYckjMsAInlJ8Ll0kHH
   10.13 + bgATOlO5OtQ21bLCfWZPSq74HEVzQAPtCGYFvOgpCktKTjmsGXe9ysiYN8CEWMVNbDqXmvFh
   10.14 + i4UifpITeQBVM7dtlBw5SoeLZpsHIlKF5i5WPkNw7nuMag/+lRpOqvPumhOmqybWHuAR/Dq0
   10.15 + pOOPh6BzZ4OzOBL96aWUe1dcnIZeBEm8oRxYC3nN95YsjtrLK4BQZTYDTzeh8FIccsLdABEB
   10.16 + AAHNRHBFcCBUZXN0IEFsaWNlICh0ZXN0IGtleSBkb24ndCB1c2UpIDxwZXAudGVzdC5hbGlj
   10.17 + ZUBwZXAtcHJvamVjdC5vcmc+wsB4BBMBAgAiBQJVeD2xAhsDBgsJCAcDAgYVCAIJCgsEFgID
   10.18 + AQIeAQIXgAAKCRCpQR0Xb/AOl5JjCADEBoordVBCmphG6EY+u5yjj/xeQN4Kc1Rl06Ii6m18
   10.19 + 4hnF/osxnTicr+A6Hpwf8whXULuSwXvfuOsVOQdIc2e+1zrecTqyNUWuRs3T7uZ25dvROg1X
   10.20 + ZuajMPf3wh5lX2rPRhOt3UNXJjQfc1MSYXpmT+PoqFXBzMqJUo2DYcw6MSZekoWkIzFXG2s2
   10.21 + YNwILwPnLnMesFtzU6mn9qhfoFsQA6aku8AbG+SNehNZvGuuUiBmu+4UYNoc/RJa7vNWECv9
   10.22 + qZQsT820CuoOZS9MFV7nQlgkGoPerlGXil0vkOG1gsuQD8QkuaTQpn1vYvRcC0P27qLfrqlP
   10.23 + v2Ih2hoIV9tJzsBNBFV4PbEBCADQwKB97t2B2nweprfpbH8QgLCzJYaAMrpcaUaJqm+J3C9e
   10.24 + aepRXTXGtst1zaLbooG2b3QHfDzI2CEYMxO5ynmmSBOe06VKw/PagBzK5ur/eOycl0ZPFSXd
   10.25 + lDj30BQPvRdJvLS4OTMdoKoGpsZDY4hOYj67oHo3TFtrLJCvZruPARkI/pXiOX9FqH4wquNN
   10.26 + aYW1qwk/Wq3k/gOMwp0xjvc01MbadaiiVquJk6jjPrd2wP4FYxIADAllzMpwFAJSWvgCfmqV
   10.27 + bukYOnaCp3QRQXQkc78TdqGXbD5uwJzkxxiEsMmiGT+7RDLIKwXheKmmGXSwgi8m+EndUiqM
   10.28 + TvOdjyUBABEBAAHCwF8EGAECAAkFAlV4PbECGwwACgkQqUEdF2/wDpeQVQgArnfQ7uvG0po/
   10.29 + CPepbrdytI2n63U5dm/MFMsvXpZYVYLO/mROc+akZCPwS0yxtSMKK+tYM9leQx58r89c+K1G
   10.30 + eZoko7xziwmZbt5zEITiJp5L6gg7k6CczskPMx07gY8ooscBC3cFJhz1A0o73BKPR7J0iupa
   10.31 + NmI3sTd1/RNQm6573kGGwc4m2bcQttvN5ox8yimn2QnK3D+6A+Mmzi3Rd11tF+tAWJIsfaEg
   10.32 + DJZn9mOdUkV2ckoSk1K5PptpXSsKLOL+e2WuxSMIr8AVeRqkbYYK6UzX6qIgQIrMOuaXqtRa
   10.33 + NxNccnzIS1YtdtYERSnTaBotNp/FF2wfI7BNFP6r0A==
   10.34 +Organization: pEp
   10.35 +Message-ID: <667f579e-a40b-97b8-9945-5340a2397905@pep-project.org>
   10.36 +Date: Tue, 9 Oct 2018 19:25:17 +0200
   10.37 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101
   10.38 + Thunderbird/52.9.1
   10.39 +MIME-Version: 1.0
   10.40 +Content-Type: multipart/encrypted;
   10.41 + protocol="application/pgp-encrypted";
   10.42 + boundary="iXQBGwY84uThCa5ZQvmN35nTAV4s6BbcY"
   10.43 +
   10.44 +This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)
   10.45 +--iXQBGwY84uThCa5ZQvmN35nTAV4s6BbcY
   10.46 +Content-Type: application/pgp-encrypted
   10.47 +Content-Description: PGP/MIME version identification
   10.48 +
   10.49 +Version: 1
   10.50 +
   10.51 +--iXQBGwY84uThCa5ZQvmN35nTAV4s6BbcY
   10.52 +Content-Type: application/octet-stream; name="encrypted.asc"
   10.53 +Content-Description: OpenPGP encrypted message
   10.54 +Content-Disposition: inline; filename="encrypted.asc"
   10.55 +
   10.56 +-----BEGIN PGP MESSAGE-----
   10.57 +
   10.58 +hQEMA4rbkTfsG51OAQf+OXDq3ikDsOxoE5bZTooXGXEQDyocK5fhl9YioLZk33J4
   10.59 +p6aVjSqdw0bKSgr+Og48wD91OqbuqBC8EzSUSJPD3zHaXdZsp9CNnH1lNgZe2kV1
   10.60 +Nak/e8RNASZttI4UjcPfgfDa9QnQObWA+4xW/+f5VEHlbfK+Wp4NwwHCRn/XxHPA
   10.61 +5dchhaffx8smMYtAM2DVwkGvzj0GUQRx07Q1oVoGc2OZzesn9PFozk5vJ6HXN/tW
   10.62 +nJKo3URs+RLZd9LwXj//WwZ33p9sLO2fQVgz4cZdKlne0owMF5ZgcByg5yCAtx5W
   10.63 +eM9FSuyTzIdmEcMewJb7Qqt4SgQdQqoX18mEw8qiAIUBDANaAgXZcwg/TQEIAIy+
   10.64 +kbwGBZ2Uluzfd8YICOtar8JEdPJvaVzm4eCx0USeYudMy0ZAcxakm4RcEr0maKNE
   10.65 +cXmfYg+wgPbPNvlShU/o0p4swg3zgqgv/z78ULgk/AJ4ZoZPv3plr5VS0W6LV8Wl
   10.66 +Tshh3r5dZqhvm7luqKSKVGI7OnNego1gQus/OD0mnF+xX9kcpSLmZwNibEnQIK8R
   10.67 +9/f/E/EXJKpB5JWH9NSMzcWbqoSZB+PsEb3K/TGIzbnLoA7NMH5B1W7QXZiy6ROW
   10.68 +h7OrRhCQbQ7wCshl9pTjpfVQuD23e/vQo4g4r9KXkpS19H3WoN6pmgavQjvinC+L
   10.69 +dFoG5v/x8ERJrgTqcKnS6QFpPWlAGnv/kpE2SLRlOZppZOXwaMvBsDmtBI91iXf/
   10.70 +7z4gmdhkdsKcsxhxvMxW6SLP0e55+7VsC99pPwjy44siP4QJhyUwhXCcH/nD8Vgi
   10.71 +0dgt4H6jilBqDTlcdrIIPe0iJgrgv+yRedqQgwPgsf7SOjYz0rT8H0uq35r1Qz7e
   10.72 +xiyqSHz3UJdjGJTZhd3kAimNTAT0mF663VOHXo6WqBR47VCxOb7ov+Qcs+P098Cw
   10.73 +VgRgbm/hgI1xgCXyX6hTjR1nfIscVxMNdB90ICPvkSaimCZIahGS8O7b0LA3pixj
   10.74 +oX9fUNXPLT/uYSb67BLQvGuNfTlP15AOy1Fxw445MgSOdNeaTYNKLA2bw6V413eo
   10.75 +r/Xp9QhYsr4rOImH1DOB67GbDGk8pwXHXarTtqCedFLVS0WFWV0W7wWCZwOrn8p8
   10.76 +48Wua/DiJ83LMpEcmwrCprirV8i5ZXixBp0SOqTBXfWuTubWgBTv3jonTNetSj/h
   10.77 +vGtfUZe6olQgbGPDxCJn9LLk4LsZLRXvM1ig0X4uOwn27F9cfe9aGefAujPMxl4A
   10.78 +WL+2iFtyHMsECxJUK4g8WQKXPh3PjAp/pmZxXsKbJFT1i7UUffDVMOqqQ2QCNeWx
   10.79 +bqpmFL5hNvzc0DzeQpeS50712e+p3U+uTitolPC98mnkcH54C+4jSgbg2yrYFA78
   10.80 +wF/9GMkL/hLhtmCGBXT3WicMxFyDIsXy5tVEzbGxHJQtoGoRkoSCi6La6Pvfc0il
   10.81 +p8c9OuHQwGVTThY2pbnFKbruJga+NyWnzkqtxk+BAFcRVm09SW1u01yTK1F7B6tu
   10.82 +4c4xXIBtBhHG2zg8f4y9Ilnwbddpf4yFlv2nWHEX/nTYYgqswZzOBV6NdWW3WwYz
   10.83 +9JggZCeWYKwq4S7ID6dKxRM/DlXJ8tDRQdUk4/ly2O06QVqwCSozRQEiDzKadk8M
   10.84 +D1ZE1FScZcIBADKpAOGGIqi3pXZ9Ec8yP6gnP4WJ1N8a0NL+1Dd77IuCKLmrrc/2
   10.85 +gqCCXLe6OOuMIUeeq56KahrXOc0ez2q0cfZILx5pp8cPA8Jzu0vvPSZA+IEBIH4n
   10.86 +BQ==
   10.87 +=x4dq
   10.88 +-----END PGP MESSAGE-----
   10.89 +
   10.90 +--iXQBGwY84uThCa5ZQvmN35nTAV4s6BbcY--