"Fossies" - the Fresh Open Source Software Archive

Member "dovecot-2.3.8/src/lib-dcrypt/test-crypto.c" (8 Oct 2019, 41488 Bytes) of package /linux/misc/dovecot-2.3.8.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "test-crypto.c": 2.3.7.2_vs_2.3.8.

    1 /* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
    2 
    3 #include "lib.h"
    4 #include "array.h"
    5 #include "buffer.h"
    6 #include "str.h"
    7 #include "dcrypt.h"
    8 #include "dcrypt-iostream.h"
    9 #include "ostream.h"
   10 #include "ostream-encrypt.h"
   11 #include "istream.h"
   12 #include "iostream-temp.h"
   13 #include "randgen.h"
   14 #include "test-common.h"
   15 #include "hex-binary.h"
   16 #include "json-parser.h"
   17 #include <fcntl.h>
   18 #include <sys/stat.h>
   19 #include <stdio.h>
   20 
   21 static void test_cipher_test_vectors(void)
   22 {
   23     static const struct {
   24         const char *key;
   25         const char *iv;
   26         const char *pt;
   27         const char *ct;
   28     } vectors[] = {
   29         { 
   30             "2b7e151628aed2a6abf7158809cf4f3c",
   31             "000102030405060708090a0b0c0d0e0f",
   32             "6bc1bee22e409f96e93d7e117393172a",
   33             "7649abac8119b246cee98e9b12e9197d"
   34         }, { 
   35             "2b7e151628aed2a6abf7158809cf4f3c",
   36             "7649ABAC8119B246CEE98E9B12E9197D",
   37             "ae2d8a571e03ac9c9eb76fac45af8e51",
   38             "5086cb9b507219ee95db113a917678b2"
   39         }
   40     };
   41 
   42 
   43     test_begin("test_cipher_test_vectors");
   44 
   45     buffer_t *key,*iv,*pt,*ct,*res_enc,*res_dec;
   46 
   47     key = t_buffer_create(16);
   48     iv = t_buffer_create(16);
   49     pt = t_buffer_create(16);
   50     ct = t_buffer_create(16);
   51 
   52     res_enc = t_buffer_create(32);
   53     res_dec = t_buffer_create(32);
   54 
   55     for(size_t i = 0; i < N_ELEMENTS(vectors); i++) {
   56         struct dcrypt_context_symmetric *ctx;
   57 
   58         buffer_set_used_size(key, 0);
   59         buffer_set_used_size(iv, 0);
   60         buffer_set_used_size(pt, 0);
   61         buffer_set_used_size(ct, 0);
   62         buffer_set_used_size(res_enc, 0);
   63         buffer_set_used_size(res_dec, 0);
   64 
   65         hex_to_binary(vectors[i].key, key);
   66         hex_to_binary(vectors[i].iv, iv);
   67         hex_to_binary(vectors[i].pt, pt);
   68         hex_to_binary(vectors[i].ct, ct);
   69 
   70         if (!dcrypt_ctx_sym_create("AES-128-CBC", DCRYPT_MODE_ENCRYPT,
   71                        &ctx, NULL)) {
   72             test_assert_failed("dcrypt_ctx_sym_create", 
   73                        __FILE__, __LINE__-1);
   74             continue;
   75         }
   76 
   77         dcrypt_ctx_sym_set_padding(ctx, FALSE);
   78 
   79         dcrypt_ctx_sym_set_key(ctx, key->data, key->used);
   80         dcrypt_ctx_sym_set_iv(ctx, iv->data, iv->used);
   81 
   82         test_assert_idx(dcrypt_ctx_sym_init(ctx, NULL), i);
   83 
   84         test_assert_idx(dcrypt_ctx_sym_update(ctx,
   85             pt->data, pt->used, res_enc, NULL), i);
   86         test_assert_idx(dcrypt_ctx_sym_final(ctx, res_enc, NULL), i);
   87 
   88         test_assert_idx(buffer_cmp(ct, res_enc), i);
   89 
   90         dcrypt_ctx_sym_destroy(&ctx);
   91 
   92         if (!dcrypt_ctx_sym_create("AES-128-CBC", DCRYPT_MODE_DECRYPT,
   93                        &ctx, NULL)) {
   94             test_assert_failed("dcrypt_ctx_sym_create",
   95                        __FILE__, __LINE__-1);
   96             continue;
   97         }
   98 
   99         dcrypt_ctx_sym_set_padding(ctx, FALSE);
  100 
  101         dcrypt_ctx_sym_set_key(ctx, key->data, key->used);
  102         dcrypt_ctx_sym_set_iv(ctx, iv->data, iv->used);
  103 
  104         test_assert_idx(dcrypt_ctx_sym_init(ctx, NULL), i);
  105         test_assert_idx(dcrypt_ctx_sym_update(ctx,
  106             res_enc->data, res_enc->used, res_dec, NULL), i);
  107         test_assert_idx(dcrypt_ctx_sym_final(ctx, res_dec, NULL), i);
  108 
  109         test_assert_idx(buffer_cmp(pt, res_dec), i);
  110 
  111         dcrypt_ctx_sym_destroy(&ctx);
  112     }
  113 
  114     test_end();
  115 }
  116 
  117 static void test_cipher_aead_test_vectors(void)
  118 {
  119     struct dcrypt_context_symmetric *ctx;
  120     const char *error = NULL;
  121 
  122     test_begin("test_cipher_aead_test_vectors");
  123 
  124     if (!dcrypt_ctx_sym_create("aes-128-gcm", DCRYPT_MODE_ENCRYPT,
  125                    &ctx, &error)) {
  126         test_assert_failed("dcrypt_ctx_sym_create",
  127                    __FILE__, __LINE__-1);
  128         return;
  129     }
  130 
  131     buffer_t *key, *iv, *aad, *pt, *ct, *tag, *tag_res, *res;
  132 
  133     key = t_buffer_create(16);
  134     iv = t_buffer_create(16);
  135     aad = t_buffer_create(16);
  136     pt = t_buffer_create(16);
  137     ct = t_buffer_create(16);
  138     tag = t_buffer_create(16);
  139     res = t_buffer_create(16);
  140     tag_res = t_buffer_create(16);
  141 
  142     hex_to_binary("feffe9928665731c6d6a8f9467308308", key);
  143     hex_to_binary("cafebabefacedbaddecaf888", iv);
  144     hex_to_binary("d9313225f88406e5a55909c5aff5269a"
  145               "86a7a9531534f7da2e4c303d8a318a72"
  146               "1c3c0c95956809532fcf0e2449a6b525"
  147               "b16aedf5aa0de657ba637b391aafd255", pt);
  148     hex_to_binary("42831ec2217774244b7221b784d0d49c"
  149               "e3aa212f2c02a4e035c17e2329aca12e"
  150               "21d514b25466931c7d8f6a5aac84aa05"
  151               "1ba30b396a0aac973d58e091473f5985", ct);
  152     hex_to_binary("4d5c2af327cd64a62cf35abd2ba6fab4", tag);
  153 
  154     dcrypt_ctx_sym_set_key(ctx, key->data, key->used);
  155     dcrypt_ctx_sym_set_iv(ctx, iv->data, iv->used);
  156     dcrypt_ctx_sym_set_aad(ctx, aad->data, aad->used);
  157     test_assert(dcrypt_ctx_sym_init(ctx, &error));
  158     test_assert(dcrypt_ctx_sym_update(ctx, pt->data, pt->used, res, &error));
  159     test_assert(dcrypt_ctx_sym_final(ctx, res, &error));
  160     test_assert(dcrypt_ctx_sym_get_tag(ctx, tag_res));
  161 
  162     test_assert(buffer_cmp(ct, res) == TRUE);
  163     test_assert(buffer_cmp(tag, tag_res) == TRUE);
  164 
  165     dcrypt_ctx_sym_destroy(&ctx);
  166 
  167     if (!dcrypt_ctx_sym_create("aes-128-gcm", DCRYPT_MODE_DECRYPT,
  168                    &ctx, &error)) {
  169         test_assert_failed("dcrypt_ctx_sym_create",
  170                    __FILE__, __LINE__-1);
  171     } else {
  172 
  173         buffer_set_used_size(res, 0);
  174 
  175         dcrypt_ctx_sym_set_key(ctx, key->data, key->used);
  176         dcrypt_ctx_sym_set_iv(ctx, iv->data, iv->used);
  177         dcrypt_ctx_sym_set_aad(ctx, aad->data, aad->used);
  178         dcrypt_ctx_sym_set_tag(ctx, tag->data, tag->used);
  179         test_assert(dcrypt_ctx_sym_init(ctx, &error));
  180         test_assert(dcrypt_ctx_sym_update(ctx,
  181             ct->data, ct->used, res, &error));
  182         test_assert(dcrypt_ctx_sym_final(ctx, res, &error));
  183 
  184         test_assert(buffer_cmp(pt, res) == TRUE);
  185 
  186         dcrypt_ctx_sym_destroy(&ctx);
  187     }
  188 
  189     test_end();
  190 }
  191 
  192 static void test_hmac_test_vectors(void)
  193 {
  194     test_begin("test_hmac_test_vectors");
  195 
  196     buffer_t *pt, *ct, *key, *res;
  197     pt = t_buffer_create(50);
  198     key = t_buffer_create(20);
  199     ct = t_buffer_create(32);
  200     res = t_buffer_create(32);
  201 
  202     hex_to_binary("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", key);
  203     hex_to_binary("dddddddddddddddddddddddddddddddddddddddddddddddddd"
  204               "dddddddddddddddddddddddddddddddddddddddddddddddddd", pt);
  205     hex_to_binary("773ea91e36800e46854db8ebd09181a7"
  206               "2959098b3ef8c122d9635514ced565fe", res);
  207 
  208     struct dcrypt_context_hmac *hctx;
  209     if (!dcrypt_ctx_hmac_create("sha256", &hctx, NULL)) {
  210         test_assert_failed("dcrypt_ctx_hmac_create",
  211                    __FILE__, __LINE__-1);
  212     } else {
  213         dcrypt_ctx_hmac_set_key(hctx, key->data, key->used);
  214         test_assert(dcrypt_ctx_hmac_init(hctx, NULL));
  215         test_assert(dcrypt_ctx_hmac_update(hctx,
  216             pt->data, pt->used, NULL));
  217         test_assert(dcrypt_ctx_hmac_final(hctx, ct, NULL));
  218         test_assert(buffer_cmp(ct, res));
  219         dcrypt_ctx_hmac_destroy(&hctx);
  220     }
  221 
  222     test_end();
  223 }
  224 
  225 static void test_load_v1_keys(void)
  226 {
  227     test_begin("test_load_v1_keys");
  228 
  229     const char *error = NULL;
  230     const char *data1 = 
  231         "1\t716\t1\t0567e6bf9579813ae967314423b0fceb14bda24"
  232         "749303923de9a9bb9370e0026f995901a57e63113eeb2baf0c"
  233         "940e978d00686cbb52bd5014bc318563375876255\t0300E46"
  234         "DA2125427BE968EB3B649910CDC4C405E5FFDE18D433A97CAB"
  235         "FEE28CEEFAE9EE356C792004FFB80981D67E741B8CC036A342"
  236         "35A8D2E1F98D1658CFC963D07EB\td0cfaca5d335f9edc41c8"
  237         "4bb47465184cb0e2ec3931bebfcea4dd433615e77a0\t7c9a1"
  238         "039ea2e4fed73e81dd3ffc3fa22ea4a28352939adde7bf8ea8"
  239         "58b00fa4f";
  240 
  241     enum dcrypt_key_format format;
  242     enum dcrypt_key_version version;
  243     enum dcrypt_key_kind kind;
  244     enum dcrypt_key_encryption_type encryption_type;
  245     const char *encryption_key_hash = NULL;
  246     const char *key_hash = NULL;
  247 
  248     bool ret = dcrypt_key_string_get_info(data1, &format, &version,
  249             &kind, &encryption_type, &encryption_key_hash,
  250             &key_hash, &error);
  251 
  252     test_assert(ret == TRUE);
  253     test_assert(error == NULL);
  254     test_assert(format == DCRYPT_FORMAT_DOVECOT);
  255     test_assert(version == DCRYPT_KEY_VERSION_1);
  256     test_assert(kind == DCRYPT_KEY_KIND_PRIVATE);
  257     test_assert(encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_KEY);
  258     test_assert(strcmp(encryption_key_hash,
  259         "d0cfaca5d335f9edc41c84bb47465184"
  260         "cb0e2ec3931bebfcea4dd433615e77a0") == 0);
  261     test_assert(strcmp(key_hash,
  262         "7c9a1039ea2e4fed73e81dd3ffc3fa22"
  263         "ea4a28352939adde7bf8ea858b00fa4f") == 0);
  264 
  265     const char* data2 = 
  266         "1\t716\t0301EB00973C4EFC8FCECA4EA33E941F50B561199A"
  267         "5159BCB6C2EED9DD1D62D65E38A254979D89E28F0C28883E71"
  268         "EE2AD264CD16B863FA094A8F6F69A56B62E8918040\t7c9a10"
  269         "39ea2e4fed73e81dd3ffc3fa22ea4a28352939adde7bf8ea85"
  270         "8b00fa4f";
  271 
  272     error = NULL;
  273     encryption_key_hash = NULL;
  274     key_hash = NULL;
  275 
  276     ret = dcrypt_key_string_get_info(data2, &format, &version,
  277             &kind, &encryption_type, &encryption_key_hash,
  278             &key_hash, &error);
  279 
  280     test_assert(ret == TRUE);
  281     test_assert(error == NULL);
  282     test_assert(format == DCRYPT_FORMAT_DOVECOT);
  283     test_assert(version == DCRYPT_KEY_VERSION_1);
  284     test_assert(kind == DCRYPT_KEY_KIND_PUBLIC);
  285     test_assert(encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_NONE);
  286     test_assert(encryption_key_hash == NULL);
  287     test_assert(strcmp(key_hash,
  288         "7c9a1039ea2e4fed73e81dd3ffc3fa22"
  289         "ea4a28352939adde7bf8ea858b00fa4f") == 0);
  290 
  291     /* This is the key that should be able to decrypt key1 */
  292     const char *data3 =
  293         "1\t716\t0\t048FD04FD3612B22D32790C592CF21CEF417EFD"
  294         "2EA34AE5F688FA5B51BED29E05A308B68DA78E16E90B47A11E"
  295         "133BD9A208A2894FD01B0BEE865CE339EA3FB17AC\td0cfaca"
  296         "5d335f9edc41c84bb47465184cb0e2ec3931bebfcea4dd4336"
  297         "15e77a0";
  298 
  299     error = NULL;
  300     encryption_key_hash = NULL;
  301     key_hash = NULL;
  302 
  303     ret = dcrypt_key_string_get_info(data3, &format, &version,
  304             &kind, &encryption_type, &encryption_key_hash,
  305             &key_hash, &error);
  306     test_assert(ret == TRUE);
  307     test_assert(error == NULL);
  308     test_assert(format == DCRYPT_FORMAT_DOVECOT);
  309     test_assert(version == DCRYPT_KEY_VERSION_1);
  310     test_assert(kind == DCRYPT_KEY_KIND_PRIVATE);
  311     test_assert(encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_NONE);
  312     test_assert(encryption_key_hash == NULL);
  313     test_assert(strcmp(key_hash,
  314         "d0cfaca5d335f9edc41c84bb47465184"
  315         "cb0e2ec3931bebfcea4dd433615e77a0") == 0);
  316 
  317     /* key3's key_hash should and does match key1's encryption_key_hash */
  318     struct dcrypt_private_key *pkey = NULL;
  319     struct dcrypt_private_key *pkey2 = NULL;
  320     pkey = NULL;
  321     error = NULL;
  322 
  323     ret = dcrypt_key_load_private(&pkey2, data3, NULL, NULL, &error);
  324     test_assert(ret == TRUE);
  325     test_assert(error == NULL);
  326 
  327     ret = dcrypt_key_load_private(&pkey, data1, NULL, pkey2, &error);
  328     test_assert(ret == TRUE);
  329     test_assert(error == NULL);
  330 
  331     dcrypt_key_unref_private(&pkey2);
  332     dcrypt_key_unref_private(&pkey);
  333 
  334     test_end();
  335 }
  336 
  337 static void test_load_v1_key(void)
  338 {
  339     test_begin("test_load_v1_key");
  340 
  341     buffer_t *key_1 = t_buffer_create(128);
  342 
  343     struct dcrypt_private_key *pkey = NULL, *pkey2 = NULL;
  344     const char *error = NULL;
  345 
  346     test_assert(dcrypt_key_load_private(&pkey, 
  347         "1\t716\t0\t048FD04FD3612B22D32790C592CF21CEF417EFD"
  348         "2EA34AE5F688FA5B51BED29E05A308B68DA78E16E90B47A11E"
  349         "133BD9A208A2894FD01B0BEE865CE339EA3FB17AC\td0cfaca"
  350         "5d335f9edc41c84bb47465184cb0e2ec3931bebfcea4dd4336"
  351         "15e77a0", NULL, NULL, &error));
  352     if (pkey != NULL) {
  353         buffer_set_used_size(key_1, 0);
  354         /* check that key_id matches */
  355         struct dcrypt_public_key *pubkey = NULL;
  356         dcrypt_key_convert_private_to_public(pkey, &pubkey);
  357         test_assert(dcrypt_key_store_public(pubkey,
  358                 DCRYPT_FORMAT_DOVECOT, key_1, NULL));
  359         buffer_set_used_size(key_1, 0);
  360         dcrypt_key_id_public(pubkey, "sha256", key_1, &error);
  361         test_assert(strcmp("792caad4d38c9eb2134a0cbc844eae38"
  362                    "6116de096a0ccafc98479825fc99b6a1",
  363                    binary_to_hex(key_1->data, key_1->used))
  364                 == 0);
  365 
  366         dcrypt_key_unref_public(&pubkey);
  367         pkey2 = NULL;
  368 
  369         test_assert(dcrypt_key_load_private(&pkey2,
  370             "1\t716\t1\t0567e6bf9579813ae967314423b0fceb14"
  371             "bda24749303923de9a9bb9370e0026f995901a57e6311"
  372             "3eeb2baf0c940e978d00686cbb52bd5014bc318563375"
  373             "876255\t0300E46DA2125427BE968EB3B649910CDC4C4"
  374             "05E5FFDE18D433A97CABFEE28CEEFAE9EE356C792004F"
  375             "FB80981D67E741B8CC036A34235A8D2E1F98D1658CFC9"
  376             "63D07EB\td0cfaca5d335f9edc41c84bb47465184cb0e"
  377             "2ec3931bebfcea4dd433615e77a0\t7c9a1039ea2e4fe"
  378             "d73e81dd3ffc3fa22ea4a28352939adde7bf8ea858b00"
  379             "fa4f", NULL, pkey, &error));
  380         if (pkey2 != NULL) {
  381             buffer_set_used_size(key_1, 0);
  382             /* check that key_id matches */
  383             struct dcrypt_public_key *pubkey = NULL;
  384             dcrypt_key_convert_private_to_public(pkey2, &pubkey);
  385             test_assert(dcrypt_key_store_public(pubkey,
  386                 DCRYPT_FORMAT_DOVECOT, key_1, NULL));
  387             buffer_set_used_size(key_1, 0);
  388             test_assert(dcrypt_key_id_public_old(pubkey,
  389                 key_1, &error));
  390             test_assert(strcmp(
  391                 "7c9a1039ea2e4fed73e81dd3ffc3fa22"
  392                 "ea4a28352939adde7bf8ea858b00fa4f",
  393                 binary_to_hex(key_1->data, key_1->used)) == 0);
  394 
  395             dcrypt_key_unref_public(&pubkey);
  396             dcrypt_key_unref_private(&pkey2);
  397         }
  398         dcrypt_key_unref_private(&pkey);
  399     }
  400 
  401     test_end();
  402 }
  403 
  404 static void test_load_v1_public_key(void)
  405 {
  406     test_begin("test_load_v1_public_key");
  407 
  408     const char* data1 =
  409         "1\t716\t030131D8A5FD5167947A0AE9CB112ADED652665463"
  410         "5AA5887051EE2364414B60FF32EBA8FA0BBE9485DBDE8794BB"
  411         "BCB44BBFC0D662A4287A848BA570D4E5E45A11FE0F\td0cfac"
  412         "a5d335f9edc41c84bb47465184cb0e2ec3931bebfcea4dd433"
  413         "615e77a0";
  414 
  415     const char* error = NULL;
  416     const char* key_hash = NULL;
  417     const char* encryption_key_hash = NULL;
  418 
  419     enum dcrypt_key_format format;
  420     enum dcrypt_key_version version;
  421     enum dcrypt_key_kind kind;
  422     enum dcrypt_key_encryption_type encryption_type;
  423 
  424     bool ret = dcrypt_key_string_get_info(data1, &format, &version,
  425             &kind, &encryption_type, &encryption_key_hash,
  426             &key_hash, &error);
  427 
  428     test_assert(ret == TRUE);
  429     test_assert(error == NULL);
  430     test_assert(format == DCRYPT_FORMAT_DOVECOT);
  431     test_assert(version == DCRYPT_KEY_VERSION_1);
  432     test_assert(kind == DCRYPT_KEY_KIND_PUBLIC);
  433     test_assert(encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_NONE);
  434     test_assert(key_hash != NULL &&
  435         strcmp(key_hash, "d0cfaca5d335f9edc41c84bb47465184"
  436                  "cb0e2ec3931bebfcea4dd433615e77a0") == 0);
  437     test_assert(encryption_key_hash == NULL);
  438 
  439     struct dcrypt_public_key *pub_key = NULL;
  440     ret = dcrypt_key_load_public(&pub_key, data1, &error);
  441     test_assert(ret == TRUE);
  442     test_assert(error == NULL);
  443 
  444     test_assert(dcrypt_key_type_public(pub_key) == DCRYPT_KEY_EC);
  445 
  446     dcrypt_key_unref_public(&pub_key);
  447     test_assert(pub_key == NULL);
  448 
  449     test_end();
  450 }
  451 
  452 static void test_load_v2_key(void)
  453 {
  454     const char *keys[] = {
  455         "-----BEGIN PRIVATE KEY-----\n"
  456         "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgtu"
  457         "QJA+uboZWVwgHc\n"
  458         "DciyVdrovAPwlMqshDK3s78IDDuhRANCAAQm0VEdzLB9PtD0HA"
  459         "8JK1zifWnj8M00\n"
  460         "FQzedfp9SQsWyA8dzs5/NFR5MTe6Xbh/ndKEs1zZH3vZ4FlNri"
  461         "lZc0st\n"
  462         "-----END PRIVATE KEY-----\n",
  463         "2:1.2.840.10045.3.1.7:0:0000002100b6e40903eb9ba195"
  464         "95c201dc0dc8b255dae8bc03f094caac8432b7b3bf080c3b:a"
  465         "b13d251976dedab546b67354e7678821740dd534b749c2857f"
  466         "66bf62bbaddfd",
  467         "2:1.2.840.10045.3.1.7:2:aes-256-ctr:483bd74fd3d917"
  468         "63:sha256:2048:d44ae35d3af7a2febcb15cde0c3693e7ed9"
  469         "8595665ed655a97fa918d346d5c661a6e2339f4:ab13d25197"
  470         "6dedab546b67354e7678821740dd534b749c2857f66bf62bba"
  471         "ddfd",
  472         "2:1.2.840.10045.3.1.7:1:aes-256-ctr:2574c10be28a4c"
  473         "09:sha256:2048:a750ec9dea91999f108f943485a20f273f4"
  474         "0f75c37fc9bcccdedda514c8243e550d69ce1bd:02237a199d"
  475         "7d945aa6492275a02881071eceec5749caf2485da8c64fb601"
  476         "229098:ab13d251976dedab546b67354e7678821740dd534b7"
  477         "49c2857f66bf62bbaddfd:ab13d251976dedab546b67354e76"
  478         "78821740dd534b749c2857f66bf62bbaddfd"
  479     };
  480 
  481     test_begin("test_load_v2_key");
  482     const char *error = NULL;
  483     buffer_t *tmp = buffer_create_dynamic(default_pool, 256);
  484 
  485     struct dcrypt_private_key *priv,*priv2;
  486 
  487     test_assert_idx(dcrypt_key_load_private(&priv2,
  488         keys[0], NULL, NULL, &error), 0);
  489     test_assert_idx(dcrypt_key_store_private(priv2,
  490         DCRYPT_FORMAT_PEM, NULL, tmp, NULL, NULL, &error), 0);
  491     test_assert_idx(strcmp(str_c(tmp), keys[0])==0, 0);
  492     buffer_set_used_size(tmp, 0);
  493 
  494     test_assert_idx(dcrypt_key_load_private(&priv,
  495         keys[1], NULL, NULL, &error), 1);
  496     test_assert_idx(dcrypt_key_store_private(priv,
  497         DCRYPT_FORMAT_DOVECOT, NULL, tmp, NULL, NULL, &error), 1);
  498     test_assert_idx(strcmp(str_c(tmp), keys[1])==0, 1);
  499     buffer_set_used_size(tmp, 0);
  500     dcrypt_key_unref_private(&priv);
  501 
  502     test_assert_idx(dcrypt_key_load_private(&priv,
  503         keys[2], "This Is Sparta", NULL, &error), 2);
  504     test_assert_idx(dcrypt_key_store_private(priv,
  505         DCRYPT_FORMAT_DOVECOT, "aes-256-ctr", tmp,
  506         "This Is Sparta", NULL, &error), 2);
  507     buffer_set_used_size(tmp, 0);
  508     dcrypt_key_unref_private(&priv);
  509 
  510     struct dcrypt_public_key *pub = NULL;
  511     dcrypt_key_convert_private_to_public(priv2, &pub);
  512     test_assert_idx(dcrypt_key_load_private(&priv,
  513         keys[3], NULL, priv2, &error), 3);
  514     test_assert_idx(dcrypt_key_store_private(priv,
  515         DCRYPT_FORMAT_DOVECOT, "ecdh-aes-256-ctr", tmp,
  516         NULL, pub, &error), 3);
  517     buffer_set_used_size(tmp, 0);
  518     dcrypt_key_unref_private(&priv2);
  519     dcrypt_key_unref_private(&priv);
  520     dcrypt_key_unref_public(&pub);
  521 
  522     buffer_free(&tmp);
  523 
  524     if (error != NULL) error = NULL;
  525 
  526     test_end();
  527 }
  528 
  529 static void test_load_v2_public_key(void)
  530 {
  531     struct dcrypt_public_key *pub = NULL;
  532     const char *error;
  533 
  534     test_begin("test_load_v2_public_key");
  535     const char *key =
  536         "2:3058301006072a8648ce3d020106052b810400230344000"
  537         "301c50954e734dd8b410a607764a7057065a45510da52f2c6"
  538         "e28e0cb353b9c389fa8cb786943ae991fce9befed78fb162f"
  539         "bbc615415f06af06c8cc80c37f4e94ff6c7:185a721254278"
  540         "2e239111f9c19d126ad55b18ddaf4883d66afe8d9627c3607"
  541         "d8";
  542 
  543     test_assert(dcrypt_key_load_public(&pub, key, &error));
  544 
  545     buffer_t *tmp = buffer_create_dynamic(default_pool, 256);
  546 
  547     if (pub != NULL) {
  548         test_assert(dcrypt_key_store_public(pub,
  549             DCRYPT_FORMAT_DOVECOT, tmp, &error));
  550         test_assert(strcmp(key, str_c(tmp))==0);
  551         buffer_free(&tmp);
  552         dcrypt_key_unref_public(&pub);
  553     }
  554 
  555     test_end();
  556 }
  557 
  558 static void test_get_info_v2_key(void)
  559 {
  560     test_begin("test_get_info_v2_key");
  561 
  562     const char *key =
  563         "2:305e301006072a8648ce3d020106052b81040026034a0002"
  564         "03fcc90034fa03d6fb79a0fc8b3b43c3398f68e76029307360"
  565         "cdcb9e27bb7e84b3c19dfb7244763bc4d442d216f09b7b7945"
  566         "ed9d182f3156550e9ee30b237a0217dbf79d28975f31:86706"
  567         "b69d1f640011a65d26a42f2ba20a619173644e1cc7475eb1d9"
  568         "0966e84dc";
  569     enum dcrypt_key_format format;
  570     enum dcrypt_key_version version = DCRYPT_KEY_VERSION_NA;
  571     enum dcrypt_key_kind kind;
  572     enum dcrypt_key_encryption_type encryption_type;
  573     const char *encryption_key_hash = NULL;
  574     const char *key_hash = NULL;
  575     const char *error = NULL;
  576 
  577     test_assert(dcrypt_key_string_get_info(key, &format, &version,
  578             &kind, &encryption_type, &encryption_key_hash,
  579             &key_hash, &error));
  580     test_assert(error == NULL);
  581     test_assert(format == DCRYPT_FORMAT_DOVECOT);
  582     test_assert(version == DCRYPT_KEY_VERSION_2);
  583 
  584     test_assert(kind == DCRYPT_KEY_KIND_PUBLIC);
  585     test_assert(encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_NONE);
  586     test_assert(encryption_key_hash == NULL);
  587     test_assert(key_hash != NULL && strcmp(key_hash,
  588         "86706b69d1f640011a65d26a42f2ba20"
  589         "a619173644e1cc7475eb1d90966e84dc") == 0);
  590 
  591     test_end();
  592 }
  593 
  594 static void test_gen_and_get_info_rsa_pem(void)
  595 {
  596     test_begin("test_gen_and_get_info_rsa_pem");
  597 
  598     const char *error = NULL;
  599     bool ret = FALSE;
  600     struct dcrypt_keypair pair;
  601     string_t* buf = str_new(default_pool, 4096);
  602 
  603     ret = dcrypt_keypair_generate(&pair, DCRYPT_KEY_RSA, 1024, NULL, NULL);
  604     test_assert(ret == TRUE);
  605 
  606     /* test public key */
  607     enum dcrypt_key_format format;
  608     enum dcrypt_key_version version;
  609     enum dcrypt_key_kind kind;
  610     enum dcrypt_key_encryption_type encryption_type;
  611     const char *encryption_key_hash;
  612     const char *key_hash;
  613 
  614     ret = dcrypt_key_store_public(pair.pub, DCRYPT_FORMAT_PEM, buf,
  615             &error);
  616     test_assert(ret == TRUE);
  617 
  618     ret = dcrypt_key_string_get_info(str_c(buf), &format, &version,
  619             &kind, &encryption_type, &encryption_key_hash,
  620             &key_hash, &error);
  621     test_assert(ret == TRUE);
  622     test_assert(format == DCRYPT_FORMAT_PEM);
  623     test_assert(version == DCRYPT_KEY_VERSION_NA);
  624 
  625     test_assert(kind == DCRYPT_KEY_KIND_PUBLIC);
  626     test_assert(encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_NONE);
  627     test_assert(encryption_key_hash == NULL);
  628     test_assert(key_hash == NULL);
  629 
  630     /* test private key */
  631     buffer_set_used_size(buf, 0);
  632     ret = dcrypt_key_store_private(pair.priv, DCRYPT_FORMAT_PEM, NULL,
  633             buf, NULL, NULL, &error);
  634 
  635     test_assert(ret == TRUE);
  636 
  637     ret = dcrypt_key_string_get_info(str_c(buf), &format, &version,
  638             &kind, &encryption_type, &encryption_key_hash,
  639             &key_hash, &error);
  640 
  641     test_assert(ret == TRUE);
  642     test_assert(format == DCRYPT_FORMAT_PEM);
  643     test_assert(version == DCRYPT_KEY_VERSION_NA);
  644 
  645     test_assert(kind == DCRYPT_KEY_KIND_PRIVATE);
  646 
  647     test_assert(encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_NONE);
  648     test_assert(encryption_key_hash == NULL);
  649     test_assert(key_hash == NULL);
  650 
  651     dcrypt_keypair_unref(&pair);
  652     buffer_free(&buf);
  653 
  654     test_end();
  655 }
  656 
  657 static void test_get_info_rsa_private_key(void)
  658 {
  659     test_begin("test_get_info_rsa_private_key");
  660 
  661     const char *key = "-----BEGIN RSA PRIVATE KEY-----\n"
  662 "MIICXQIBAAKBgQC89q02I9NezBLQ+otn5XLYE7S+GsKUz59ogr45DA/6MI9jey0W\n"
  663 "56SeWQ1FJD1vDhAx/TRBMfOmhcIPsBjc5sakYOawPdoiqLjOIlO+iHwnbbmLuMsq\n"
  664 "ue09vgvZsKjuTr2F5DOFQY43Bq/Nd+4bjHJItdOM58+xwA2I/8vDbtI8jwIDAQAB\n"
  665 "AoGBAJCUrTMfdjqyKjN7f+6ewKBTc5eBIiB6O53ba3B6qj7jqNKVDIrZ8jq2KFEe\n"
  666 "yWKPgBS/h5vafHKNJU6bjmp2qMUJPB7PTA876eDo0cq9PplUqihiTlXJFwNQYtF+\n"
  667 "o27To5t25+5qdSAj657+lQfFT9Xn9fzYHDmotURxH10FgFkBAkEA+7Ny6lBTeb3W\n"
  668 "LnP0UPfPzQLilEr8u81PLWe69RGtsEaMQHGpHOl4e+bvvVYbG1cgxwxI1m01uR9r\n"
  669 "qpD3qLUdrQJBAMAw6UvN8R+opYTZzwqK7Nliil2QZMPmXM04SV1iFq26NM60w2Fm\n"
  670 "HqOOh0EbpSWsFtIgxJFWoZOtrguxqCJuUqsCQF3EoXf3StHczhDqM8eCOpD2lTCH\n"
  671 "qxXPy8JvlW+9EUbNUWykq0rRE4idJQ0VKe4KjHR6+Buh/dSkhvi5Hvpj1tUCQHRv\n"
  672 "LWeXZLVhXqWVrzEb6VHpuRnmGKX2MdLCfu/sNQEbBlMUgCnJzFYaSybOsMaZ81lq\n"
  673 "MKw8Z7coSYEcKFhzrfECQQD7l+4Bhy8Zuz6VoGGIZwIhxkJrImBFmaUwx8N6jg20\n"
  674 "sgDRYwCoGkGd7B8uIHZLJoWzSSutHiu5i5PYUy5VT1yT\n"
  675 "-----END RSA PRIVATE KEY-----\n";
  676 
  677     const char *error = NULL;
  678 
  679     test_assert(!dcrypt_key_string_get_info(key, NULL, NULL,
  680             NULL, NULL, NULL, NULL, &error));
  681     test_assert(error != NULL && strstr(error, "pkey") != NULL);
  682 
  683     test_end();
  684 }
  685 
  686 static void test_get_info_invalid_keys(void)
  687 {
  688     test_begin("test_get_info_invalid_keys");
  689 
  690     const char *key =
  691         "1:716:030131D8A5FD5167947A0AE9CB112ADED6526654635A"
  692         "A5887051EE2364414B60FF32EBA8FA0BBE9485DBDE8794BBBC"
  693         "B44BBFC0D662A4287A848BA570D4E5E45A11FE0F:d0cfaca5d"
  694         "335f9edc41c84bb47465184cb0e2ec3931bebfcea4dd433615"
  695         "e77a0";
  696     const char *error = NULL;
  697 
  698     test_assert(dcrypt_key_string_get_info(key, NULL, NULL,
  699             NULL, NULL, NULL, NULL, &error) == FALSE);
  700     test_assert(error != NULL && strstr(error, "tab") != NULL);
  701 
  702     key =
  703         "2\t305e301006072a8648ce3d020106052b81040026034a000"
  704         "203fcc90034fa03d6fb79a0fc8b3b43c3398f68e7602930736"
  705         "0cdcb9e27bb7e84b3c19dfb7244763bc4d442d216f09b7b794"
  706         "5ed9d182f3156550e9ee30b237a0217dbf79d28975f31\t867"
  707         "06b69d1f640011a65d26a42f2ba20a619173644e1cc7475eb1"
  708         "d90966e84dc";
  709     error = NULL;
  710 
  711     test_assert(dcrypt_key_string_get_info(key, NULL, NULL,
  712             NULL, NULL, NULL, NULL, &error) == FALSE);
  713     test_assert(error != NULL && strstr(error, "colon") != NULL);
  714 
  715     key = "2";
  716     error = NULL;
  717 
  718     test_assert(dcrypt_key_string_get_info(key, NULL, NULL,
  719             NULL, NULL, NULL, NULL, &error) == FALSE);
  720     test_assert(error != NULL && strstr(error, "Unknown") != NULL);
  721 
  722     test_end();
  723 }
  724 
  725 static void test_get_info_key_encrypted(void)
  726 {
  727     test_begin("test_get_info_key_encrypted");
  728 
  729     struct dcrypt_keypair p1, p2;
  730     const char *error = NULL;
  731     bool ret = dcrypt_keypair_generate(&p1,
  732         DCRYPT_KEY_EC, 0, "secp521r1", &error);
  733     test_assert(ret == TRUE);
  734     ret = dcrypt_keypair_generate(&p2,
  735         DCRYPT_KEY_EC, 0, "secp521r1", &error);
  736     test_assert(ret == TRUE);
  737 
  738     string_t* buf = t_str_new(4096);
  739 
  740     buffer_set_used_size(buf, 0);
  741     ret = dcrypt_key_store_private(p1.priv,
  742         DCRYPT_FORMAT_DOVECOT, "ecdh-aes-256-ctr", buf,
  743         NULL, p2.pub, &error);
  744     test_assert(ret == TRUE);
  745 
  746     enum dcrypt_key_format format;
  747     enum dcrypt_key_version version;
  748     enum dcrypt_key_kind kind;
  749     enum dcrypt_key_encryption_type enc_type;
  750     const char *enc_hash;
  751     const char *key_hash;
  752 
  753     ret = dcrypt_key_string_get_info(str_c(buf), &format, &version,
  754             &kind, &enc_type, &enc_hash, &key_hash, &error);
  755     test_assert(ret == TRUE);
  756     test_assert(format == DCRYPT_FORMAT_DOVECOT);
  757     test_assert(version == DCRYPT_KEY_VERSION_2);
  758     test_assert(kind == DCRYPT_KEY_KIND_PRIVATE);
  759     test_assert(enc_type == DCRYPT_KEY_ENCRYPTION_TYPE_KEY);
  760     test_assert(enc_hash != NULL);
  761     test_assert(key_hash != NULL);
  762 
  763     dcrypt_keypair_unref(&p1);
  764     dcrypt_keypair_unref(&p2);
  765 
  766     test_end();
  767 }
  768 
  769 static void test_get_info_pw_encrypted(void)
  770 {
  771     test_begin("test_get_info_pw_encrypted");
  772 
  773     struct dcrypt_keypair p1;
  774     i_zero(&p1);
  775     const char *error;
  776     bool ret = dcrypt_keypair_generate(&p1,
  777         DCRYPT_KEY_EC, 0, "secp521r1", &error);
  778     test_assert(ret == TRUE);
  779 
  780     string_t* buf = t_str_new(4096);
  781     ret = dcrypt_key_store_private(p1.priv,
  782         DCRYPT_FORMAT_DOVECOT, "aes-256-ctr", buf, "pw", NULL, &error);
  783     test_assert(ret == TRUE);
  784 
  785     enum dcrypt_key_format format;
  786     enum dcrypt_key_version version;
  787     enum dcrypt_key_kind kind;
  788     enum dcrypt_key_encryption_type enc_type;
  789     const char *enc_hash;
  790     const char *key_hash;
  791 
  792     ret = dcrypt_key_string_get_info(str_c(buf), &format, &version,
  793             &kind, &enc_type, &enc_hash, &key_hash, &error);
  794     test_assert(ret == TRUE);
  795     test_assert(format == DCRYPT_FORMAT_DOVECOT);
  796     test_assert(version == DCRYPT_KEY_VERSION_2);
  797     test_assert(kind == DCRYPT_KEY_KIND_PRIVATE);
  798     test_assert(enc_type == DCRYPT_KEY_ENCRYPTION_TYPE_PASSWORD);
  799     test_assert(enc_hash == NULL);
  800     test_assert(key_hash != NULL);
  801 
  802     dcrypt_keypair_unref(&p1);
  803 
  804     test_end();
  805 }
  806 
  807 static void test_password_change(void)
  808 {
  809     test_begin("test_password_change");
  810 
  811     const char *pw1 = "first password";
  812     struct dcrypt_keypair orig;
  813     const char *error = NULL;
  814 
  815     bool ret = dcrypt_keypair_generate(&orig,
  816         DCRYPT_KEY_EC, 0, "secp521r1", &error);
  817     test_assert(ret == TRUE);
  818 
  819     string_t *buf = t_str_new(4096);
  820     ret = dcrypt_key_store_private(orig.priv,
  821         DCRYPT_FORMAT_DOVECOT, "aes-256-ctr", buf, pw1, NULL, &error);
  822     test_assert(ret == TRUE);
  823 
  824     /* load the pw-encrypted key */
  825     struct dcrypt_private_key *k1_priv = NULL;
  826     ret = dcrypt_key_load_private(&k1_priv, str_c(buf), pw1, NULL, &error);
  827     test_assert(ret == TRUE);
  828 
  829     /* encrypt a key with the pw-encrypted key k1 */
  830     struct dcrypt_keypair k2;
  831     ret = dcrypt_keypair_generate(&k2,
  832         DCRYPT_KEY_EC, 0, "secp521r1", &error);
  833     test_assert(ret == TRUE);
  834 
  835     string_t *buf2 = t_str_new(4096);
  836     struct dcrypt_public_key *k1_pub = NULL;
  837     dcrypt_key_convert_private_to_public(k1_priv, &k1_pub);
  838     ret = dcrypt_key_store_private(k2.priv,
  839         DCRYPT_FORMAT_DOVECOT, "ecdh-aes-256-ctr", buf2,
  840         NULL, k1_pub, &error);
  841     test_assert(ret == TRUE);
  842 
  843     /* change the password */
  844     const char *pw2 = "second password";
  845     string_t *buf3 = t_str_new(4096);
  846 
  847     /* encrypt k1 with pw2 */
  848     ret = dcrypt_key_store_private(k1_priv,
  849         DCRYPT_FORMAT_DOVECOT, "aes-256-ctr", buf3, pw2, NULL, &error);
  850     test_assert(ret == TRUE);
  851 
  852     /* load the pw2 encrypted key */
  853     struct dcrypt_private_key *k2_priv = NULL;
  854     ret = dcrypt_key_load_private(&k2_priv, str_c(buf3), pw2, NULL, &error);
  855     test_assert(ret == TRUE);
  856 
  857     /* load the key that was encrypted with pw1 using the pw2 encrypted key */
  858     struct dcrypt_private_key *k3_priv = NULL;
  859     ret = dcrypt_key_load_private(&k3_priv,
  860         str_c(buf2), NULL, k2_priv, &error);
  861     test_assert(ret == TRUE);
  862 
  863     dcrypt_key_unref_private(&k1_priv);
  864     dcrypt_key_unref_public(&k1_pub);
  865     dcrypt_key_unref_private(&k2_priv);
  866     dcrypt_key_unref_private(&k3_priv);
  867     dcrypt_keypair_unref(&orig);
  868     dcrypt_keypair_unref(&k2);
  869 
  870     test_end();
  871 }
  872 
  873 static void test_load_invalid_keys(void)
  874 {
  875     test_begin("test_load_invalid_keys");
  876 
  877     const char *error = NULL;
  878     const char *key =
  879         "1:716:0301EB00973C4EFC8FCECA4EA33E941F50B561199A51"
  880         "59BCB6C2EED9DD1D62D65E38A254979D89E28F0C28883E71EE"
  881         "2AD264CD16B863FA094A8F6F69A56B62E8918040:7c9a1039e"
  882         "a2e4fed73e81dd3ffc3fa22ea4a28352939adde7bf8ea858b0"
  883         "0fa4f";
  884     struct dcrypt_public_key *pub_key = NULL;
  885 
  886     bool ret = dcrypt_key_load_public(&pub_key, key, &error);
  887     test_assert(ret == FALSE);
  888     test_assert(error != NULL);
  889 
  890     error = NULL;
  891     key =
  892         "2:305e301006072a8648ce3d020106052b81040026034a0002"
  893         "03fcc90034fa03d6fb79a0fc8b3b43c3398f68e76029307360"
  894         "cdcb9e27bb7e84b3c19dfb7244763bc4d442d216f09b7b7945"
  895         "ed9d182f3156550e9ee30b237a0217dbf79d28975f31:86706"
  896         "b69d1f640011a65d26a42f2ba20a619173644e1cc7475eb1d9"
  897         "0966e84dc";
  898     struct dcrypt_private_key *priv_key = NULL;
  899 
  900     ret = dcrypt_key_load_private(&priv_key, key, NULL, NULL, &error);
  901     test_assert(ret == FALSE);
  902     test_assert(error != NULL);
  903 
  904     test_end();
  905 }
  906 
  907 static void test_raw_keys(void)
  908 {
  909 
  910     test_begin("test_raw_keys");
  911 
  912     ARRAY_TYPE(dcrypt_raw_key) priv_key;
  913     ARRAY_TYPE(dcrypt_raw_key) pub_key;
  914     pool_t pool = pool_datastack_create();
  915 
  916     enum dcrypt_key_type t;
  917 
  918     p_array_init(&priv_key, pool, 2);
  919     p_array_init(&pub_key, pool, 2);
  920 
  921     /* generate ECC key */
  922     struct dcrypt_keypair pair;
  923     i_assert(dcrypt_keypair_generate(&pair, DCRYPT_KEY_EC, 0, "prime256v1", NULL));
  924 
  925     /* store it */
  926     test_assert(dcrypt_key_store_private_raw(pair.priv, pool, &t, &priv_key,
  927             NULL));
  928     test_assert(dcrypt_key_store_public_raw(pair.pub, pool, &t, &pub_key,
  929             NULL));
  930     dcrypt_keypair_unref(&pair);
  931 
  932     /* load it */
  933     test_assert(dcrypt_key_load_private_raw(&pair.priv, t, &priv_key,
  934             NULL));
  935     test_assert(dcrypt_key_load_public_raw(&pair.pub, t, &pub_key,
  936             NULL));
  937 
  938     dcrypt_keypair_unref(&pair);
  939 
  940     /* test load known raw private key */
  941     const char *curve = "prime256v1";
  942     const unsigned char priv_key_data[] = {
  943         0x16, 0x9e, 0x62, 0x36, 0xaf, 0x9c, 0xae, 0x0e, 0x71, 0xda,
  944         0xf2, 0x63, 0xe2, 0xe0, 0x5d, 0xf1, 0xd5, 0x35, 0x8c, 0x2b,
  945         0x68, 0xf0, 0x2a, 0x69, 0xc4, 0x5d, 0x3d, 0x1c, 0xde, 0xa1,
  946         0x9b, 0xd3
  947     };
  948 
  949     /* create buffers */
  950     struct dcrypt_raw_key *item;
  951     ARRAY_TYPE(dcrypt_raw_key) static_key;
  952     t_array_init(&static_key, 2);
  953 
  954     /* Add OID */
  955     buffer_t *buf = t_buffer_create(32);
  956     test_assert(dcrypt_name2oid(curve, buf, NULL));
  957     item = array_append_space(&static_key);
  958     item->parameter = buf->data;
  959     item->len = buf->used;
  960 
  961     /* Add key data */
  962     item = array_append_space(&static_key);
  963     item->parameter = priv_key_data;
  964     item->len = sizeof(priv_key_data);
  965 
  966     /* Try load it */
  967     test_assert(dcrypt_key_load_private_raw(&pair.priv, t,
  968                         &static_key, NULL));
  969 
  970     /* See what we got */
  971     buf = t_buffer_create(128);
  972     test_assert(dcrypt_key_store_private(pair.priv, DCRYPT_FORMAT_DOVECOT,
  973                          NULL, buf, NULL, NULL, NULL));
  974     test_assert_strcmp(str_c(buf),
  975                "2:1.2.840.10045.3.1.7:0:00000020169e6236af9cae0e71d"
  976                "af263e2e05df1d5358c2b68f02a69c45d3d1cdea19bd3:21d11"
  977                "6b7b3e5c52e81f0437a10b0116cfafc467fb1b96e48926d0216"
  978                "68fc1bea");
  979 
  980     /* try to load public key, too */
  981     const unsigned char pub_key_data[] = {
  982         0x04, 0xe8, 0x7c, 0x6d, 0xa0, 0x29, 0xfe, 0x5d, 0x16, 0x1a,
  983         0xd6, 0x6a, 0xc6, 0x1c, 0x78, 0x8a, 0x36, 0x0f, 0xfb, 0x64,
  984         0xe7, 0x7f, 0x58, 0x13, 0xb3, 0x80, 0x1f, 0x99, 0x45, 0xee,
  985         0xa9, 0x4a, 0xe2, 0xde, 0xf3, 0x88, 0xc6, 0x37, 0x72, 0x7f,
  986         0xbe, 0x97, 0x02, 0x94, 0xb2, 0x21, 0x60, 0xa4, 0x98, 0x4e,
  987         0xfb, 0x46, 0x19, 0x61, 0x4c, 0xc5, 0xe1, 0x9f, 0xe9, 0xb2,
  988         0xd2, 0x4d, 0xae, 0x83, 0x4b
  989     };
  990 
  991     array_clear(&static_key);
  992 
  993     /* Add OID */
  994     buf = t_buffer_create(32);
  995     test_assert(dcrypt_name2oid(curve, buf, NULL));
  996     item = array_append_space(&static_key);
  997     item->parameter = buf->data;
  998     item->len = buf->used;
  999 
 1000     /* Add key data */
 1001     item = array_append_space(&static_key);
 1002     item->parameter = pub_key_data;
 1003     item->len = sizeof(pub_key_data);
 1004 
 1005     /* See what we got */
 1006     test_assert(dcrypt_key_load_public_raw(&pair.pub, t,
 1007                            &static_key, NULL));
 1008     buf = t_buffer_create(128);
 1009     test_assert(dcrypt_key_store_public(pair.pub, DCRYPT_FORMAT_DOVECOT,
 1010                         buf, NULL));
 1011     test_assert_strcmp(str_c(buf),
 1012         "2:3039301306072a8648ce3d020106082a8648ce3d03010703220003e87c6d"
 1013         "a029fe5d161ad66ac61c788a360ffb64e77f5813b3801f9945eea94ae2:21d"
 1014         "116b7b3e5c52e81f0437a10b0116cfafc467fb1b96e48926d021668fc1bea");
 1015     dcrypt_keypair_unref(&pair);
 1016 
 1017     test_end();
 1018 }
 1019 
 1020 static void test_sign_verify_rsa(void)
 1021 {
 1022     const char *error = NULL;
 1023     bool valid;
 1024     struct dcrypt_private_key *priv_key = NULL;
 1025     struct dcrypt_public_key *pub_key = NULL;
 1026 
 1027     buffer_t *signature =
 1028         buffer_create_dynamic(pool_datastack_create(), 128);
 1029     const char *data = "signed data";
 1030 
 1031     test_begin("sign and verify (rsa)");
 1032     const char *key = "-----BEGIN PRIVATE KEY-----\n"
 1033 "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALz2rTYj017MEtD6\n"
 1034 "i2flctgTtL4awpTPn2iCvjkMD/owj2N7LRbnpJ5ZDUUkPW8OEDH9NEEx86aFwg+w\n"
 1035 "GNzmxqRg5rA92iKouM4iU76IfCdtuYu4yyq57T2+C9mwqO5OvYXkM4VBjjcGr813\n"
 1036 "7huMcki104znz7HADYj/y8Nu0jyPAgMBAAECgYEAkJStMx92OrIqM3t/7p7AoFNz\n"
 1037 "l4EiIHo7ndtrcHqqPuOo0pUMitnyOrYoUR7JYo+AFL+Hm9p8co0lTpuOanaoxQk8\n"
 1038 "Hs9MDzvp4OjRyr0+mVSqKGJOVckXA1Bi0X6jbtOjm3bn7mp1ICPrnv6VB8VP1ef1\n"
 1039 "/NgcOai1RHEfXQWAWQECQQD7s3LqUFN5vdYuc/RQ98/NAuKUSvy7zU8tZ7r1Ea2w\n"
 1040 "RoxAcakc6Xh75u+9VhsbVyDHDEjWbTW5H2uqkPeotR2tAkEAwDDpS83xH6ilhNnP\n"
 1041 "Cors2WKKXZBkw+ZczThJXWIWrbo0zrTDYWYeo46HQRulJawW0iDEkVahk62uC7Go\n"
 1042 "Im5SqwJAXcShd/dK0dzOEOozx4I6kPaVMIerFc/Lwm+Vb70RRs1RbKSrStETiJ0l\n"
 1043 "DRUp7gqMdHr4G6H91KSG+Lke+mPW1QJAdG8tZ5dktWFepZWvMRvpUem5GeYYpfYx\n"
 1044 "0sJ+7+w1ARsGUxSAKcnMVhpLJs6wxpnzWWowrDxntyhJgRwoWHOt8QJBAPuX7gGH\n"
 1045 "Lxm7PpWgYYhnAiHGQmsiYEWZpTDHw3qODbSyANFjAKgaQZ3sHy4gdksmhbNJK60e\n"
 1046 "K7mLk9hTLlVPXJM=\n"
 1047 "-----END PRIVATE KEY-----";
 1048 
 1049     test_assert(dcrypt_key_load_private(&priv_key,
 1050         key, NULL, NULL, &error));
 1051     if (priv_key == NULL)
 1052         i_fatal("%s", error);
 1053     dcrypt_key_convert_private_to_public(priv_key, &pub_key);
 1054     test_assert(dcrypt_sign(priv_key, "sha256", DCRYPT_SIGNATURE_FORMAT_DSS,
 1055          data, strlen(data), signature, 0, &error));
 1056     /* verify signature */
 1057     test_assert(dcrypt_verify(pub_key, "sha256", DCRYPT_SIGNATURE_FORMAT_DSS,
 1058          data, strlen(data),
 1059          signature->data, signature->used, &valid, 0, &error) && valid);
 1060 
 1061     dcrypt_key_unref_public(&pub_key);
 1062     dcrypt_key_unref_private(&priv_key);
 1063 
 1064     test_end();
 1065 }
 1066 
 1067 static void test_sign_verify_ecdsa(void)
 1068 {
 1069     const char *error = NULL;
 1070     bool valid;
 1071     struct dcrypt_private_key *priv_key = NULL;
 1072     struct dcrypt_public_key *pub_key = NULL;
 1073 
 1074     buffer_t *signature =
 1075         buffer_create_dynamic(pool_datastack_create(), 128);
 1076     const char *data = "signed data";
 1077 
 1078     test_begin("sign and verify (ecdsa)");
 1079     const char *key = "-----BEGIN PRIVATE KEY-----\n"
 1080 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgZ4AMMyJ9XDl5lKM2\n"
 1081 "vusbT1OQ6VzBWBkB3/4syovaKtyhRANCAAQHTR+6L2qMh5fdcMZF+Y1rctBsq8Oy\n"
 1082 "7jZ4uV+MiuaoGNQ5sTxlcv6ETX/XrEDq4S/DUhFKzQ6u9VXYZImvRCT1\n"
 1083 "-----END PRIVATE KEY-----";
 1084 
 1085     test_assert(dcrypt_key_load_private(&priv_key,
 1086         key, NULL, NULL, &error));
 1087     if (priv_key == NULL)
 1088         i_fatal("%s", error);
 1089     dcrypt_key_convert_private_to_public(priv_key, &pub_key);
 1090     test_assert(dcrypt_sign(priv_key, "sha256", DCRYPT_SIGNATURE_FORMAT_DSS,
 1091         data, strlen(data), signature, 0, &error));
 1092     /* verify signature */
 1093     test_assert(dcrypt_verify(pub_key, "sha256", DCRYPT_SIGNATURE_FORMAT_DSS,
 1094         data, strlen(data), signature->data,
 1095         signature->used, &valid, 0, &error) && valid);
 1096 
 1097     dcrypt_key_unref_public(&pub_key);
 1098     dcrypt_key_unref_private(&priv_key);
 1099 
 1100     test_end();
 1101 }
 1102 
 1103 static void test_static_verify_ecdsa(void)
 1104 {
 1105     test_begin("static verify (ecdsa)");
 1106     const char *input = "hello, world";
 1107     const char *priv_key_pem =
 1108        "-----BEGIN PRIVATE KEY-----\n"
 1109        "MGcCAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcETTBLAgEBBCC25AkD65uhlZXCAdwN\n"
 1110        "yLJV2ui8A/CUyqyEMrezvwgMO6EkAyIAAybRUR3MsH0+0PQcDwkrXOJ9aePwzTQV\n"
 1111        "DN51+n1JCxbI\n"
 1112        "-----END PRIVATE KEY-----";
 1113     const char *pub_key_pem =
 1114        "-----BEGIN PUBLIC KEY-----\n"
 1115        "MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADJtFRHcywfT7Q9BwPCStc4n1p4/DN\n"
 1116        "NBUM3nX6fUkLFsg=\n"
 1117        "-----END PUBLIC KEY-----";
 1118 
 1119     const unsigned char sig[] = {
 1120         0x30,0x45,0x02,0x20,0x2c,0x76,0x20,0x5e,0xfc,0xa6,0x9e,0x16,
 1121         0x44,0xb3,0xbc,0xbf,0xcc,0x43,0xc1,0x08,0x76,0x4a,0xe8,0x60,
 1122         0xc5,0x9b,0x99,0x20,0x5b,0x44,0x33,0x5c,0x38,0x84,0x63,0xcb,
 1123         0x02,0x21,0x00,0xa3,0x67,0xed,0x57,0xbf,0x59,0x46,0xb7,0x0c,
 1124         0x7b,0xec,0x4f,0x78,0x14,0xec,0xfa,0x8d,0xa2,0x85,0x48,0xea,
 1125         0xe1,0xaf,0x9e,0xbf,0x04,0xac,0x0e,0x41,0xfe,0x84,0x0e
 1126     };
 1127 
 1128     struct dcrypt_keypair pair;
 1129     bool valid;
 1130     const char *error;
 1131 
 1132     i_zero(&pair);
 1133     /* static key test */
 1134     test_assert(dcrypt_key_load_public(&pair.pub, pub_key_pem, NULL));
 1135     test_assert(dcrypt_key_load_private(&pair.priv, priv_key_pem, NULL, NULL, NULL));
 1136     /* validate signature */
 1137     test_assert(dcrypt_verify(pair.pub, "sha256", DCRYPT_SIGNATURE_FORMAT_DSS,
 1138                   input, strlen(input),
 1139                   sig, sizeof(sig), &valid, 0, &error) &&
 1140             valid == TRUE);
 1141 
 1142     dcrypt_keypair_unref(&pair);
 1143 
 1144     test_end();
 1145 }
 1146 
 1147 static void test_jwk_keys(void)
 1148 {
 1149     /* Make sure this matches what comes out from store private */
 1150     const char *jwk_key_json = "{\"kty\":\"EC\","
 1151       "\"crv\":\"P-256\","
 1152       "\"x\":\"Kp0Y4-Wpt-D9t_2XenFIj0LmvaZByLG69yOisek4aMI\","
 1153       "\"y\":\"wjEPB5BhH5SRPw1cCN5grWrLCphrW19fCFR8p7c9O5o\","
 1154       "\"use\":\"sig\","
 1155       "\"kid\":\"123\","
 1156       "\"d\":\"Po2z9rs86J2Qb_xWprr4idsWNPlgKf3G8-mftnE2ync\"}";
 1157     /* Acquired using another tool */
 1158     const char *pem_key =
 1159       "-----BEGIN PUBLIC KEY-----\n"
 1160       "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKp0Y4+Wpt+D9t/2XenFIj0LmvaZB\n"
 1161       "yLG69yOisek4aMLCMQ8HkGEflJE/DVwI3mCtassKmGtbX18IVHyntz07mg==\n"
 1162       "-----END PUBLIC KEY-----";
 1163     test_begin("test_jwk_keys");
 1164     struct dcrypt_keypair pair;
 1165     buffer_t *pem = t_buffer_create(256);
 1166     i_zero(&pair);
 1167 
 1168     test_assert(dcrypt_key_load_public(&pair.pub, jwk_key_json, NULL));
 1169     test_assert(dcrypt_key_load_private(&pair.priv, jwk_key_json, NULL, NULL, NULL));
 1170 
 1171     /* test accessors */
 1172     test_assert_strcmp(dcrypt_key_get_id_public(pair.pub), "123");
 1173     test_assert(dcrypt_key_get_usage_public(pair.pub) == DCRYPT_KEY_USAGE_SIGN);
 1174 
 1175     /* make sure we got the right key */
 1176     test_assert(dcrypt_key_store_public(pair.pub, DCRYPT_FORMAT_PEM, pem, NULL));
 1177     test_assert_strcmp(str_c(pem), pem_key);
 1178 
 1179     str_truncate(pem, 0);
 1180     test_assert(dcrypt_key_store_private(pair.priv, DCRYPT_FORMAT_JWK, NULL, pem, NULL, NULL, NULL));
 1181     test_assert_strcmp(str_c(pem), jwk_key_json);
 1182 
 1183     dcrypt_keypair_unref(&pair);
 1184 
 1185     test_end();
 1186 }
 1187 
 1188 static void test_static_verify_rsa(void)
 1189 {
 1190     const char *error = NULL;
 1191     bool valid;
 1192     struct dcrypt_public_key *pub_key = NULL;
 1193 
 1194     test_begin("static verify (rsa)");
 1195     const char *data = "test signature input\n";
 1196     const unsigned char sig[] = {
 1197         0x6f,0x1b,0xfb,0xdd,0xdb,0xb1,0xcd,0x6f,0xf1,0x1b,
 1198         0xb8,0xad,0x71,0x75,0x6c,0x87,0x22,0x11,0xe4,0xc3,
 1199         0xe7,0xca,0x15,0x04,0xda,0x98,0xab,0x07,0x27,0xcc,
 1200         0x5a,0x4d,0xab,0xac,0x37,0x7a,0xff,0xd2,0xdf,0x37,
 1201         0x58,0x37,0x53,0x46,0xd5,0x6d,0x9d,0x73,0x83,0x90,
 1202         0xea,0x5e,0x2c,0xc7,0x51,0x9e,0xc4,0xda,0xc5,0x7d,
 1203         0xa5,0xcd,0xb7,0xd7,0x41,0x23,0x6d,0xb9,0x6d,0xe0,
 1204         0x99,0xa1,0x63,0x6b,0x60,0x5f,0x15,0x5b,0xda,0x21,
 1205         0x17,0x4c,0x37,0x68,0x67,0x7f,0x8e,0x02,0x93,0xd2,
 1206         0x86,0xdd,0xe5,0xa7,0xc3,0xd9,0x93,0x8b,0x0c,0x56,
 1207         0x1d,0x5c,0x60,0x63,0x3e,0x8b,0xbe,0x1f,0xb2,0xe7,
 1208         0x7f,0xe5,0x66,0x6f,0xcd,0x2b,0x0c,0x02,0x2a,0x12,
 1209         0x96,0x86,0x66,0x00,0xff,0x12,0x8a,0x79
 1210     };
 1211     const char *key = "-----BEGIN PUBLIC KEY-----\n"
 1212 "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC89q02I9NezBLQ+otn5XLYE7S+\n"
 1213 "GsKUz59ogr45DA/6MI9jey0W56SeWQ1FJD1vDhAx/TRBMfOmhcIPsBjc5sakYOaw\n"
 1214 "PdoiqLjOIlO+iHwnbbmLuMsque09vgvZsKjuTr2F5DOFQY43Bq/Nd+4bjHJItdOM\n"
 1215 "58+xwA2I/8vDbtI8jwIDAQAB\n"
 1216 "-----END PUBLIC KEY-----";
 1217 
 1218     test_assert(dcrypt_key_load_public(&pub_key, key, &error));
 1219     if (pub_key == NULL)
 1220         i_fatal("%s", error);
 1221     test_assert(dcrypt_verify(pub_key, "sha256", DCRYPT_SIGNATURE_FORMAT_DSS,
 1222         data, strlen(data),
 1223         sig, sizeof(sig), &valid, DCRYPT_PADDING_RSA_PKCS1, &error) &&
 1224         valid);
 1225     dcrypt_key_unref_public(&pub_key);
 1226 
 1227     test_end();
 1228 }
 1229 
 1230 /* Sample values from RFC8292 */
 1231 static void test_static_verify_ecdsa_x962(void)
 1232 {
 1233     const char *error = NULL;
 1234     bool valid;
 1235     struct dcrypt_public_key *pub_key = NULL;
 1236 
 1237     test_begin("static verify (ecdsa x9.62)");
 1238     const char *data =
 1239         "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJodHRwczovL3B1c"
 1240         "2guZXhhbXBsZS5uZXQiLCJleHAiOjE0NTM1MjM3NjgsInN1YiI6Im1haWx0bzp"
 1241         "wdXNoQGV4YW1wbGUuY29tIn0";
 1242     const unsigned char sig[] = {
 1243         0x8b,0x70,0x98,0x6f,0xbb,0x78,0xc5,0xfc,0x42,0x0e,0xab,
 1244         0xa9,0xb4,0x53,0x9e,0xa4,0x2f,0x46,0x02,0xef,0xc7,0x2c,
 1245         0x69,0x0c,0x94,0xcb,0x82,0x19,0x22,0xb6,0xae,0x98,0x94,
 1246         0x7e,0x72,0xbd,0xa2,0x31,0x70,0x0d,0x76,0xf5,0x26,0xb1,
 1247         0x2b,0xb6,0x6c,0xac,0x6b,0x33,0x63,0x8e,0xf5,0xb6,0x2f,
 1248         0xd3,0xa4,0x49,0x21,0xf3,0xbe,0x80,0xf5,0xa0
 1249     };
 1250     const char *key =
 1251 "-----BEGIN PUBLIC KEY-----\n"
 1252 "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDUfHPKLVFQzVvnCPGyfucbECzPDa\n"
 1253 "7rWbXriLcysAjEcXpgrmHhINiJz51G5T9EI8J8Dlqr2iNLCTljYSYKUE+w==\n"
 1254 "-----END PUBLIC KEY-----";
 1255 
 1256     test_assert(dcrypt_key_load_public(&pub_key, key, &error));
 1257     if (pub_key == NULL)
 1258         i_fatal("%s", error);
 1259     test_assert(dcrypt_verify(pub_key, "sha256", DCRYPT_SIGNATURE_FORMAT_X962,
 1260         data, strlen(data),
 1261         sig, sizeof(sig), &valid, DCRYPT_PADDING_RSA_PKCS1, &error) &&
 1262         valid);
 1263     dcrypt_key_unref_public(&pub_key);
 1264 
 1265     test_end();
 1266 }
 1267 
 1268 
 1269 int main(void)
 1270 {
 1271     struct dcrypt_settings set = {
 1272         .module_dir = ".libs"
 1273     };
 1274     const char *error;
 1275 
 1276     if (!dcrypt_initialize(NULL, &set, &error)) {
 1277         i_error("No functional dcrypt backend found - "
 1278             "skipping tests: %s", error);
 1279         return 0;
 1280     }
 1281 
 1282     static void (*const test_functions[])(void) = {
 1283         test_cipher_test_vectors,
 1284         test_cipher_aead_test_vectors,
 1285         test_hmac_test_vectors,
 1286         test_load_v1_keys,
 1287         test_load_v1_key,
 1288         test_load_v1_public_key,
 1289         test_load_v2_key,
 1290         test_load_v2_public_key,
 1291         test_get_info_v2_key,
 1292         test_gen_and_get_info_rsa_pem,
 1293         test_get_info_rsa_private_key,
 1294         test_get_info_invalid_keys,
 1295         test_get_info_key_encrypted,
 1296         test_get_info_pw_encrypted,
 1297         test_password_change,
 1298         test_load_invalid_keys,
 1299         test_raw_keys,
 1300         test_jwk_keys,
 1301         test_sign_verify_rsa,
 1302         test_sign_verify_ecdsa,
 1303         test_static_verify_ecdsa,
 1304         test_static_verify_rsa,
 1305         test_static_verify_ecdsa_x962,
 1306         NULL
 1307     };
 1308 
 1309     int ret = test_run(test_functions);
 1310 
 1311     dcrypt_deinitialize();
 1312 
 1313     return ret;
 1314 }