bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
a81d5c3f5a4ad5d100b258d10d4c75f4a02ab1f6Stephan Bosch
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "lib.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "buffer.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "str.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "dcrypt.h"
17fbd200b78112bd0d89e89598aa01cea72a74e5Martti Rannanjärvi#include "dcrypt-iostream.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "ostream.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "ostream-encrypt.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "istream.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "istream-decrypt.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "istream-hash.h"
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi#include "istream-base64.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "randgen.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "hash-method.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "test-common.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "hex-binary.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include <fcntl.h>
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include <sys/stat.h>
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include <stdio.h>
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic const char key_v1_priv[] = "-----BEGIN PRIVATE KEY-----\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"MIGpAgEAMBAGByqGSM49AgEGBSuBBAAjBIGRMIGOAgEBBEGz2V2VMi/5s+Z+GJh7\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"4WfqZjZUpqqm+NJWojm6BbrZMY+9ZComlTGVcUZ007acFxV93oMmrfmtRUb5ynrb\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"MRFskKFGA0QAAwHrAJc8TvyPzspOoz6UH1C1YRmaUVm8tsLu2d0dYtZeOKJUl52J\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"4o8MKIg+ce4q0mTNFrhj+glKj29ppWti6JGAQA==\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"-----END PRIVATE KEY-----";
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic const char key_v1_pub[] = "-----BEGIN PUBLIC KEY-----\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"MFgwEAYHKoZIzj0CAQYFK4EEACMDRAADAesAlzxO/I/Oyk6jPpQfULVhGZpRWby2\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"wu7Z3R1i1l44olSXnYnijwwoiD5x7irSZM0WuGP6CUqPb2mla2LokYBA\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"-----END PUBLIC KEY-----";
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic const char key_v2_priv[] = "-----BEGIN PRIVATE KEY-----\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgtuQJA+uboZWVwgHc\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"DciyVdrovAPwlMqshDK3s78IDDuhRANCAAQm0VEdzLB9PtD0HA8JK1zifWnj8M00\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"FQzedfp9SQsWyA8dzs5/NFR5MTe6Xbh/ndKEs1zZH3vZ4FlNrilZc0st\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"-----END PRIVATE KEY-----";
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic const char key_v2_pub[] = "-----BEGIN PUBLIC KEY-----\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJtFRHcywfT7Q9BwPCStc4n1p4/DN\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"NBUM3nX6fUkLFsgPHc7OfzRUeTE3ul24f53ShLNc2R972eBZTa4pWXNLLQ==\n" \
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi"-----END PUBLIC KEY-----";
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic const char test_sample_v1_hash[] = "1d7cc2cc1f1983f76241cc42389911e88590ad58cf9d54cafeb5b198d3723dd1";
80449618d545154901b1fc709d23d77986ef4429Aki Tuomistatic const char test_sample_v1_short_hash[] = "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c";
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic const char test_sample_v2_hash[] = "2e31218656dd34db65b321688bf418dee4ee785e99eb9c21e0d29b4af27a863e";
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic struct dcrypt_keypair test_v1_kp;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic struct dcrypt_keypair test_v2_kp;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid test_static_v1_input(void)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi ssize_t siz;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi const struct hash_method *hash = hash_method_lookup("sha256");
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi unsigned char hash_ctx[hash->context_size];
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi unsigned char hash_dgst[hash->digest_size];
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi hash->init(hash_ctx);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_begin("test_static_v1_input");
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
b0c472c7a93dfc869e2124ca738d62f1d6794e43Timo Sirainen struct istream *is_1 = i_stream_create_file(DCRYPT_SRC_DIR"/sample-v1.asc", IO_BLOCK_SIZE);
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi struct istream *is_2 = i_stream_create_base64_decoder(is_1);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi i_stream_unref(&is_1);
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi struct istream *is_3 = i_stream_create_decrypt(is_2, test_v1_kp.priv);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi i_stream_unref(&is_2);
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi struct istream *is_4 = i_stream_create_hash(is_3, hash, hash_ctx);
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi i_stream_unref(&is_3);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi while((siz = i_stream_read(is_4))>0) { i_stream_skip(is_4, siz); }
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi if (is_4->stream_errno != 0)
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi i_debug("error: %s", i_stream_get_error(is_4));
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi test_assert(is_4->stream_errno == 0);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi i_stream_unref(&is_4);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi hash->result(hash_ctx, hash_dgst);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_assert(strcmp(test_sample_v1_hash, binary_to_hex(hash_dgst, sizeof(hash_dgst))) == 0);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_end();
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
80449618d545154901b1fc709d23d77986ef4429Aki Tuomistatic
80449618d545154901b1fc709d23d77986ef4429Aki Tuomivoid test_static_v1_input_short(void)
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi{
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi ssize_t siz;
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi const struct hash_method *hash = hash_method_lookup("sha256");
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi unsigned char hash_ctx[hash->context_size];
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi unsigned char hash_dgst[hash->digest_size];
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi hash->init(hash_ctx);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi test_begin("test_static_v1_input_short");
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi struct istream *is_1 = i_stream_create_file(DCRYPT_SRC_DIR"/sample-v1_short.asc", IO_BLOCK_SIZE);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi struct istream *is_2 = i_stream_create_base64_decoder(is_1);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi i_stream_unref(&is_1);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi struct istream *is_3 = i_stream_create_decrypt(is_2, test_v1_kp.priv);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi i_stream_unref(&is_2);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi struct istream *is_4 = i_stream_create_hash(is_3, hash, hash_ctx);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi i_stream_unref(&is_3);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi while((siz = i_stream_read(is_4))>0) { i_stream_skip(is_4, siz); }
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi if (is_4->stream_errno != 0)
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi i_debug("error: %s", i_stream_get_error(is_4));
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi test_assert(is_4->stream_errno == 0);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi i_stream_unref(&is_4);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi hash->result(hash_ctx, hash_dgst);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi test_assert(strcmp(test_sample_v1_short_hash, binary_to_hex(hash_dgst, sizeof(hash_dgst))) == 0);
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi test_end();
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi}
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid test_static_v2_input(void)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_begin("test_static_v2_input");
7d0d1c56133c82168a3cee2a7ef34dea44d0d462Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi ssize_t amt;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi const struct hash_method *hash = hash_method_lookup("sha256");
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi unsigned char hash_ctx[hash->context_size];
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi unsigned char hash_dgst[hash->digest_size];
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi hash->init(hash_ctx);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
b0c472c7a93dfc869e2124ca738d62f1d6794e43Timo Sirainen struct istream *is_1 = i_stream_create_file(DCRYPT_SRC_DIR"/sample-v2.asc", IO_BLOCK_SIZE);
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi struct istream *is_2 = i_stream_create_base64_decoder(is_1);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi i_stream_unref(&is_1);
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi struct istream *is_3 = i_stream_create_decrypt(is_2, test_v2_kp.priv);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi i_stream_unref(&is_2);
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi struct istream *is_4 = i_stream_create_hash(is_3, hash, hash_ctx);
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi i_stream_unref(&is_3);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi while((amt = i_stream_read(is_4))>0) { i_stream_skip(is_4, amt); }
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi if (is_4->stream_errno != 0)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_debug("error: %s", i_stream_get_error(is_4));
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi test_assert(is_4->stream_errno == 0);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi i_stream_unref(&is_4);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi hash->result(hash_ctx, hash_dgst);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_assert(strcmp(test_sample_v2_hash, binary_to_hex(hash_dgst, sizeof(hash_dgst))) == 0);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_end();
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi/** this code is left here to show how the sample file is created
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi struct istream *is = i_stream_create_file("../lib-fts/udhr_fra.txt", 8192);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi struct istream *is_2 = i_stream_create_hash(is, hash, hash_ctx);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi int fd = open("sample-v2.bin", O_CREAT|O_TRUNC|O_WRONLY, S_IRWXU);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi struct ostream *os = o_stream_create_fd_file(fd, 0, TRUE);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi struct ostream *os_2 = o_stream_create_encrypt(os, "aes-256-gcm-sha256", test_v2_kp.pub, IO_STREAM_ENC_INTEGRITY_AEAD);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi const unsigned char *ptr;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi size_t siz;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi while(i_stream_read_data(is_2, &ptr, &siz, 0)>0) {
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi o_stream_nsend(os_2, ptr, siz);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi i_stream_skip(is_2, siz);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi }
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
ad9afb64630511d5e25bc5bc11c5304986156928Timo Sirainen i_assert(o_stream_finish(os_2) > 0);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi o_stream_close(os_2);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi i_stream_close(is_2);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi hash->result(hash_ctx, hash_dgst);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi printf("%s\n", binary_to_hex(hash_dgst, sizeof(hash_dgst)));
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi*/
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid test_write_read_v1(void)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_begin("test_write_read_v1");
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi unsigned char payload[IO_BLOCK_SIZE];
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi const unsigned char *ptr;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi size_t pos = 0, siz;
2a628a8c90839439baff5b45116f89f2b3cd9e37Aki Tuomi random_fill(payload, IO_BLOCK_SIZE);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_t *buf = buffer_create_dynamic(default_pool, sizeof(payload));
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct ostream *os = o_stream_create_buffer(buf);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi struct ostream *os_2 = o_stream_create_encrypt(os, "<unused>", test_v2_kp.pub, IO_STREAM_ENC_VERSION_1);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi o_stream_nsend(os_2, payload, sizeof(payload));
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi if (os_2->stream_errno != 0)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_debug("error: %s", o_stream_get_error(os_2));
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_assert(os_2->stream_errno == 0);
ad9afb64630511d5e25bc5bc11c5304986156928Timo Sirainen test_assert(o_stream_finish(os_2) > 0);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_assert(os_2->stream_errno == 0);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
58764929b6656f1381253f7a60ed2629564c29b0Timo Sirainen o_stream_unref(&os);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi o_stream_unref(&os_2);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct istream *is = test_istream_create_data(buf->data, buf->used);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi struct istream *is_2 = i_stream_create_decrypt(is, test_v2_kp.priv);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen size_t offset = 0;
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_allow_eof(is, FALSE);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, 0);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) {
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen if (offset == buf->used)
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_istream_set_allow_eof(is, TRUE);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen else
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, ++offset);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_assert_idx(pos + siz <= sizeof(payload), pos);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi if (pos + siz > sizeof(payload)) break;
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen test_assert_idx(siz == 0 || memcmp(ptr, payload + pos, siz) == 0, pos);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen i_stream_skip(is_2, siz); pos += siz;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi }
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_assert(is_2->stream_errno == 0);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen i_stream_unref(&is);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi i_stream_unref(&is_2);
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_free(&buf);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_end();
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomistatic
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomivoid test_write_read_v1_short(void)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi{
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_begin("test_write_read_v1_short");
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi unsigned char payload[1];
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi const unsigned char *ptr;
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi size_t pos = 0, siz;
2a628a8c90839439baff5b45116f89f2b3cd9e37Aki Tuomi random_fill(payload, 1);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_t *buf = buffer_create_dynamic(default_pool, 64);
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct ostream *os = o_stream_create_buffer(buf);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi struct ostream *os_2 = o_stream_create_encrypt(os, "<unused>", test_v2_kp.pub, IO_STREAM_ENC_VERSION_1);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi o_stream_nsend(os_2, payload, sizeof(payload));
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi if (os_2->stream_errno != 0)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_debug("error: %s", o_stream_get_error(os_2));
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_assert(os_2->stream_errno == 0);
ad9afb64630511d5e25bc5bc11c5304986156928Timo Sirainen test_assert(o_stream_finish(os_2) > 0);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_assert(os_2->stream_errno == 0);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
58764929b6656f1381253f7a60ed2629564c29b0Timo Sirainen o_stream_unref(&os);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi o_stream_unref(&os_2);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct istream *is = test_istream_create_data(buf->data, buf->used);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi struct istream *is_2 = i_stream_create_decrypt(is, test_v2_kp.priv);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen size_t offset = 0;
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_allow_eof(is, FALSE);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, 0);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) {
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen if (offset == buf->used)
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_istream_set_allow_eof(is, TRUE);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen else
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, ++offset);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_assert_idx(pos + siz <= sizeof(payload), pos);
bcf23eed0f43d4a0bff450fddb283f4cd7e645a0Timo Sirainen if (siz > sizeof(payload) || pos + siz > sizeof(payload)) break;
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen test_assert_idx(siz == 0 || memcmp(ptr, payload + pos, siz) == 0, pos);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen i_stream_skip(is_2, siz); pos += siz;
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi }
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_assert(is_2->stream_errno == 0);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen i_stream_unref(&is);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_stream_unref(&is_2);
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_free(&buf);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_end();
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi}
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomistatic
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomivoid test_write_read_v1_empty(void)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi{
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi const unsigned char *ptr;
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi size_t siz;
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_begin("test_write_read_v1_empty");
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_t *buf = buffer_create_dynamic(default_pool, 64);
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct ostream *os = o_stream_create_buffer(buf);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi struct ostream *os_2 = o_stream_create_encrypt(os, "<unused>", test_v1_kp.pub, IO_STREAM_ENC_VERSION_1);
ad9afb64630511d5e25bc5bc11c5304986156928Timo Sirainen test_assert(o_stream_finish(os_2) > 0);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi if (os_2->stream_errno != 0)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_debug("error: %s", o_stream_get_error(os_2));
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
58764929b6656f1381253f7a60ed2629564c29b0Timo Sirainen o_stream_unref(&os);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi o_stream_unref(&os_2);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi /* this should've been enough */
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct istream *is = test_istream_create_data(buf->data, buf->used);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi /* read should not fail */
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_allow_eof(is, FALSE);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, 0);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen size_t offset = 0;
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen ssize_t ret;
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen while ((ret = i_stream_read_data(is_2, &ptr, &siz, 0)) >= 0) {
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_assert(ret == 0);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen if (offset == buf->used)
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_istream_set_allow_eof(is, TRUE);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen else
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, ++offset);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi };
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_assert(is_2->stream_errno == 0);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi if (is_2->stream_errno != 0)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_debug("error: %s", i_stream_get_error(is_2));
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen i_stream_unref(&is);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_stream_unref(&is_2);
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_free(&buf);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_end();
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi}
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid test_write_read_v2(void)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_begin("test_write_read_v2");
7d0d1c56133c82168a3cee2a7ef34dea44d0d462Aki Tuomi unsigned char payload[IO_BLOCK_SIZE*10];
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi const unsigned char *ptr;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi size_t pos = 0, siz;
2a628a8c90839439baff5b45116f89f2b3cd9e37Aki Tuomi random_fill(payload, IO_BLOCK_SIZE*10);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_t *buf = buffer_create_dynamic(default_pool, sizeof(payload));
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct ostream *os = o_stream_create_buffer(buf);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi struct ostream *os_2 = o_stream_create_encrypt(os, "aes-256-gcm-sha256", test_v1_kp.pub, IO_STREAM_ENC_INTEGRITY_AEAD);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi o_stream_nsend(os_2, payload, sizeof(payload));
ad9afb64630511d5e25bc5bc11c5304986156928Timo Sirainen test_assert(o_stream_finish(os_2) > 0);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi if (os_2->stream_errno != 0)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_debug("error: %s", o_stream_get_error(os_2));
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
58764929b6656f1381253f7a60ed2629564c29b0Timo Sirainen o_stream_unref(&os);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi o_stream_unref(&os_2);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct istream *is = test_istream_create_data(buf->data, buf->used);
7d0d1c56133c82168a3cee2a7ef34dea44d0d462Aki Tuomi /* test regression where read fails due to incorrect behaviour
7d0d1c56133c82168a3cee2a7ef34dea44d0d462Aki Tuomi when buffer is full before going to decrypt code */
7d0d1c56133c82168a3cee2a7ef34dea44d0d462Aki Tuomi i_stream_set_max_buffer_size(is, 8192);
7d0d1c56133c82168a3cee2a7ef34dea44d0d462Aki Tuomi i_stream_read(is);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen size_t offset = 0;
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, 0);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_allow_eof(is, FALSE);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) {
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen if (offset == buf->used)
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_istream_set_allow_eof(is, TRUE);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen else
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, ++offset);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_assert_idx(pos + siz <= sizeof(payload), pos);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi if (pos + siz > sizeof(payload)) break;
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen test_assert_idx(siz == 0 || memcmp(ptr, payload + pos, siz) == 0, pos);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen i_stream_skip(is_2, siz); pos += siz;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi }
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_assert(is_2->stream_errno == 0);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi if (is_2->stream_errno != 0)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_debug("error: %s", i_stream_get_error(is_2));
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen i_stream_unref(&is);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi i_stream_unref(&is_2);
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_free(&buf);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_end();
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomistatic
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomivoid test_write_read_v2_short(void)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi{
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_begin("test_write_read_v2_short");
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi unsigned char payload[1];
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi const unsigned char *ptr;
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi size_t pos = 0, siz;
2a628a8c90839439baff5b45116f89f2b3cd9e37Aki Tuomi random_fill(payload, 1);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_t *buf = buffer_create_dynamic(default_pool, 64);
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct ostream *os = o_stream_create_buffer(buf);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi struct ostream *os_2 = o_stream_create_encrypt(os, "aes-256-gcm-sha256", test_v1_kp.pub, IO_STREAM_ENC_INTEGRITY_AEAD);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi o_stream_nsend(os_2, payload, sizeof(payload));
ad9afb64630511d5e25bc5bc11c5304986156928Timo Sirainen test_assert(o_stream_finish(os_2) > 0);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi if (os_2->stream_errno != 0)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_debug("error: %s", o_stream_get_error(os_2));
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
58764929b6656f1381253f7a60ed2629564c29b0Timo Sirainen o_stream_unref(&os);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi o_stream_unref(&os_2);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct istream *is = test_istream_create_data(buf->data, buf->used);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen size_t offset = 0;
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_allow_eof(is, FALSE);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, 0);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) {
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen if (offset == buf->used)
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_istream_set_allow_eof(is, TRUE);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, ++offset);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_assert_idx(pos + siz <= sizeof(payload), pos);
bcf23eed0f43d4a0bff450fddb283f4cd7e645a0Timo Sirainen if (siz > sizeof(payload) || pos + siz > sizeof(payload)) break;
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen test_assert_idx(siz == 0 || memcmp(ptr, payload + pos, siz) == 0, pos);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen i_stream_skip(is_2, siz); pos += siz;
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi }
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_assert(is_2->stream_errno == 0);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi if (is_2->stream_errno != 0)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_debug("error: %s", i_stream_get_error(is_2));
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen i_stream_unref(&is);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_stream_unref(&is_2);
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_free(&buf);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_end();
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi}
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomistatic
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomivoid test_write_read_v2_empty(void)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi{
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi const unsigned char *ptr;
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi size_t siz;
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_begin("test_write_read_v2_empty");
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_t *buf = buffer_create_dynamic(default_pool, 64);
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct ostream *os = o_stream_create_buffer(buf);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi struct ostream *os_2 = o_stream_create_encrypt(os, "aes-256-gcm-sha256", test_v1_kp.pub, IO_STREAM_ENC_INTEGRITY_AEAD);
ad9afb64630511d5e25bc5bc11c5304986156928Timo Sirainen test_assert(o_stream_finish(os_2) > 0);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi if (os_2->stream_errno != 0)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_debug("error: %s", o_stream_get_error(os_2));
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
58764929b6656f1381253f7a60ed2629564c29b0Timo Sirainen o_stream_unref(&os);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi o_stream_unref(&os_2);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi /* this should've been enough */
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen struct istream *is = test_istream_create_data(buf->data, buf->used);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi /* read should not fail */
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen size_t offset = 0;
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_allow_eof(is, FALSE);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, 0);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen ssize_t ret;
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen while ((ret = i_stream_read_data(is_2, &ptr, &siz, 0)) >= 0) {
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_assert(ret == 0);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen if (offset == buf->used)
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_istream_set_allow_eof(is, TRUE);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, ++offset);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi };
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_assert(is_2->stream_errno == 0);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi if (is_2->stream_errno != 0)
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_debug("error: %s", i_stream_get_error(is_2));
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen i_stream_unref(&is);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi i_stream_unref(&is_2);
12fed8013469fadbc2d57ebf463b7c6ab32beb31Timo Sirainen buffer_free(&buf);
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_end();
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi}
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvistatic int no_op_cb(const char *digest ATTR_UNUSED,
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi struct dcrypt_private_key **priv_key_r ATTR_UNUSED,
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi const char **error_r ATTR_UNUSED,
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi void *context ATTR_UNUSED)
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi{
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi return 0;
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi}
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvistatic void test_read_0_to_400_byte_garbage(void)
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi{
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi test_begin("test_read_0_to_100_byte_garbage");
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi char data[512];
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi memset(data, 0, sizeof(data));
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi for (size_t s = 0; s <= 400; ++s) {
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen struct istream *is = test_istream_create_data(data, s);
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi struct istream *ds = i_stream_create_decrypt_callback(is,
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi no_op_cb, NULL);
b99357fa1952863bbea761ff7ff3b8ca0f07702fTimo Sirainen test_istream_set_size(is, 0);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_istream_set_allow_eof(is, FALSE);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen ssize_t siz = 0;
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen for (size_t offset = 0; offset <= s && siz == 0; offset++) {
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen if (offset == s)
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_istream_set_allow_eof(is, TRUE);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_istream_set_size(is, offset);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen siz = i_stream_read(ds);
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen }
b671974c5aafc99ff3dc9c6718aff4260aee4ba3Timo Sirainen test_assert_idx(siz < 0, s);
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi i_stream_unref(&ds);
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi i_stream_unref(&is);
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi }
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi test_end();
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi}
e78065a7195cbcdb8ee1967216e0881928298959Martti Rannanjärvi
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainenstatic void test_read_large_header(void)
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen{
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen test_begin("test_read_large_header");
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen struct istream *is = test_istream_create_data(IOSTREAM_CRYPT_MAGIC, sizeof(IOSTREAM_CRYPT_MAGIC));
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen struct istream *ds = i_stream_create_decrypt_callback(is, no_op_cb, NULL);
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen test_istream_set_allow_eof(is, FALSE);
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen test_istream_set_max_buffer_size(is, sizeof(IOSTREAM_CRYPT_MAGIC));
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen test_assert(i_stream_read(ds) == -1);
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen i_stream_unref(&ds);
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen i_stream_unref(&is);
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen test_end();
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen}
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen
3a2f060811827cd20809537b8364c0d8892e175cAki Tuomistatic
3a2f060811827cd20809537b8364c0d8892e175cAki Tuomivoid test_free_keys() {
cce36a2c5573e4c69b01b163b08e6c8586c56aa6Aki Tuomi dcrypt_key_unref_private(&test_v1_kp.priv);
cce36a2c5573e4c69b01b163b08e6c8586c56aa6Aki Tuomi dcrypt_key_unref_public(&test_v1_kp.pub);
cce36a2c5573e4c69b01b163b08e6c8586c56aa6Aki Tuomi dcrypt_key_unref_private(&test_v2_kp.priv);
cce36a2c5573e4c69b01b163b08e6c8586c56aa6Aki Tuomi dcrypt_key_unref_public(&test_v2_kp.pub);
3a2f060811827cd20809537b8364c0d8892e175cAki Tuomi}
3a2f060811827cd20809537b8364c0d8892e175cAki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomiint main(void) {
b3a968f434cbb9e374ea3da0a7d493e20231a4aeAki Tuomi struct dcrypt_settings set = {
b3a968f434cbb9e374ea3da0a7d493e20231a4aeAki Tuomi .module_dir = ".libs"
b3a968f434cbb9e374ea3da0a7d493e20231a4aeAki Tuomi };
5fc85eac8aa8b5663e62e3321c6617c27d670630Timo Sirainen const char *error;
b3a968f434cbb9e374ea3da0a7d493e20231a4aeAki Tuomi
5fc85eac8aa8b5663e62e3321c6617c27d670630Timo Sirainen if (!dcrypt_initialize(NULL, &set, &error)) {
5fc85eac8aa8b5663e62e3321c6617c27d670630Timo Sirainen i_error("No functional dcrypt backend found - skipping tests: %s", error);
b91d91633bf40f5fc8f962cc72faea8b867a181aAki Tuomi return 0;
b91d91633bf40f5fc8f962cc72faea8b867a181aAki Tuomi }
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
401160c5ca4c3c8f122f437d00f5e4498243d7bfMartti Rannanjärvi test_assert(dcrypt_key_load_private(&test_v1_kp.priv, key_v1_priv, NULL, NULL, NULL));
fadd4c92940c10a01556e1ebcb2f17890b35d7bcMartti Rannanjärvi test_assert(dcrypt_key_load_public(&test_v1_kp.pub, key_v1_pub, NULL));
401160c5ca4c3c8f122f437d00f5e4498243d7bfMartti Rannanjärvi test_assert(dcrypt_key_load_private(&test_v2_kp.priv, key_v2_priv, NULL, NULL, NULL));
fadd4c92940c10a01556e1ebcb2f17890b35d7bcMartti Rannanjärvi test_assert(dcrypt_key_load_public(&test_v2_kp.pub, key_v2_pub, NULL));
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
baf3e87e186453fda13bd21f7cbcb2efc8492e8bTimo Sirainen static void (*const test_functions[])(void) = {
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_static_v1_input,
80449618d545154901b1fc709d23d77986ef4429Aki Tuomi test_static_v1_input_short,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_static_v2_input,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_write_read_v1,
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_write_read_v1_short,
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_write_read_v1_empty,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi test_write_read_v2,
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_write_read_v2_short,
7de7bc1f75c8f481c03984e3aaef9a5ce060c47fAki Tuomi test_write_read_v2_empty,
3a2f060811827cd20809537b8364c0d8892e175cAki Tuomi test_free_keys,
68f961acaca2d7931dcec1fb3920acd276762546Martti Rannanjärvi test_read_0_to_400_byte_garbage,
8a2f21f2b03878918333efac486f99e4fa0ecce2Timo Sirainen test_read_large_header,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi NULL
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi };
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return test_run(test_functions);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}