Mercurial > dovecot > core-2.2
changeset 20629:e23e2b702622
doveadm: add doveadm-dump-dcrypt-key
author | Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi> |
---|---|
date | Sat, 23 Jul 2016 23:40:15 +0300 |
parents | c5438de8fc7f |
children | b1831491a9d7 |
files | doc/man/doveadm-dump.1.in src/doveadm/Makefile.am src/doveadm/doveadm-dump-dcrypt-key.c src/doveadm/doveadm-dump.c src/doveadm/doveadm-dump.h |
diffstat | 5 files changed, 221 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/man/doveadm-dump.1.in Wed Aug 10 19:15:56 2016 +0300 +++ b/doc/man/doveadm-dump.1.in Sat Jul 23 23:40:15 2016 +0300 @@ -58,6 +58,9 @@ .B dcrypt-file Dump metadata of a dcrypt encrypted file. .TP +.B dcrypt-key +Dump metadata of a dcrypt key. +.TP .B index \(rA dovecot.index, dovecot.map.index .TP
--- a/src/doveadm/Makefile.am Wed Aug 10 19:15:56 2016 +0300 +++ b/src/doveadm/Makefile.am Sat Jul 23 23:40:15 2016 +0300 @@ -114,6 +114,7 @@ doveadm-dump-mailboxlog.c \ doveadm-dump-thread.c \ doveadm-dump-dcrypt-file.c \ + doveadm-dump-dcrypt-key.c \ doveadm-zlib.c common = \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doveadm/doveadm-dump-dcrypt-key.c Sat Jul 23 23:40:15 2016 +0300 @@ -0,0 +1,214 @@ +/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "dcrypt.h" +#include "ostream-encrypt.h" +#include "istream-private.h" +#include "istream-decrypt.h" +#include "doveadm-dump.h" +#include "hex-binary.h" +#include "buffer.h" +#include "str.h" +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> + +#define KEY_BUF_SIZE 4096 + +static void dcrypt_dump_public_key_metadata(const char *buf) +{ + const char *error = NULL; + struct dcrypt_public_key *pub_key; + + bool ret = dcrypt_key_load_public(&pub_key, buf, &error); + if (ret == FALSE) { + i_error("dcrypt_key_load_public: %s", error); + return; + } + enum dcrypt_key_type key_type = dcrypt_key_type_public(pub_key); + if (key_type == DCRYPT_KEY_RSA) + printf("key type: DCRYPT_KEY_RSA\n"); + else if (key_type == DCRYPT_KEY_EC) + printf("key type: DCRYPT_KEY_EC\n"); + + string_t *hash = t_str_new(128); + if (!dcrypt_key_id_public(pub_key, "sha256", hash, &error)) { + i_error("dcrypt_key_id_public: %s", error); + goto out; + } + const char *v2_hash = binary_to_hex(hash->data, hash->used); + printf("v2 hash: %s\n", v2_hash); + + if (key_type == DCRYPT_KEY_EC) { + buffer_set_used_size(hash, 0); + if (!dcrypt_key_id_public_old(pub_key, hash, &error)) + { + i_error("dcrypt_key_id_public_old: %s", error); + goto out; + } + const char *v1_hash = binary_to_hex(hash->data, hash->used); + printf("v1 hash: %s\n", v1_hash); + } +out: + dcrypt_key_unref_public(&pub_key); +} + +static void dcrypt_dump_private_key_metadata(const char *buf) +{ + const char *error = NULL; + struct dcrypt_private_key *priv_key; + + bool ret = dcrypt_key_load_private(&priv_key, buf, NULL, NULL, + &error); + if (ret == FALSE) { + i_error("dcrypt_key_load_private: %s", error); + return; + } + enum dcrypt_key_type key_type = dcrypt_key_type_private(priv_key); + if (key_type == DCRYPT_KEY_RSA) + printf("key type: DCRYPT_KEY_RSA\n"); + else if (key_type == DCRYPT_KEY_EC) + printf("key type: DCRYPT_KEY_EC\n"); + + string_t *hash = t_str_new(128); + if (!dcrypt_key_id_private(priv_key, "sha256", hash, &error)) { + i_error("dcrypt_key_id_private: %s", error); + goto out; + } + const char *v2_hash = binary_to_hex(hash->data, hash->used); + printf("v2 hash: %s\n", v2_hash); + + if (key_type == DCRYPT_KEY_EC) { + buffer_set_used_size(hash, 0); + if (!dcrypt_key_id_private_old(priv_key, hash, &error)) + { + i_error("dcrypt_key_id_private_old: %s", error); + goto out; + } + const char *v1_hash = binary_to_hex(hash->data, hash->used); + printf("v1 hash: %s\n", v1_hash); + } +out: + dcrypt_key_unref_private(&priv_key); +} + +static bool dcrypt_key_dump_metadata(const char *filename, bool print) +{ + bool ret = TRUE; + int fd = open(filename, O_RDONLY); + if (fd < 0) { + if (print) i_error("open(%s) failed: %m", filename); + return FALSE; + } + + char buf[KEY_BUF_SIZE+1]; + ssize_t res = read(fd, buf, KEY_BUF_SIZE); + if (res < 0) { + if (print) i_error("read(%d) failed: %m", fd); + i_close_fd(&fd); + return FALSE; + } + i_close_fd(&fd); + + buf[res] = '\0'; + enum dcrypt_key_format format; + enum dcrypt_key_version version; + enum dcrypt_key_kind kind; + enum dcrypt_key_encryption_type encryption_type; + const char *encryption_key_hash; + const char *key_hash; + const char *error; + + ret = dcrypt_key_string_get_info(buf, &format, &version, + &kind, &encryption_type, &encryption_key_hash, + &key_hash, &error); + if (ret == FALSE) { + if (print) i_error("dcrypt_key_string_get_info: %s", error); + return FALSE; + } + if (!print) return TRUE; + + switch (format) { + case DCRYPT_FORMAT_PEM: + printf("format: DCRYPT_FORMAT_PEM\n"); + break; + case DCRYPT_FORMAT_DOVECOT: + printf("format: DCRYPT_FORMAT_DOVECOT\n"); + break; + } + + switch (version) { + case DCRYPT_KEY_VERSION_1: + printf("version: DCRYPT_KEY_VERSION_1\n"); + break; + case DCRYPT_KEY_VERSION_2: + printf("version: DCRYPT_KEY_VERSION_2\n"); + break; + case DCRYPT_KEY_VERSION_NA: + printf("version: DCRYPT_KEY_VERSION_NA\n"); + break; + } + + switch (kind) { + case DCRYPT_KEY_KIND_PUBLIC: + printf("kind: DCRYPT_KEY_KIND_PUBLIC\n"); + break; + case DCRYPT_KEY_KIND_PRIVATE: + printf("kind: DCRYPT_KEY_KIND_PRIVATE\n"); + break; + } + + switch (encryption_type) { + case DCRYPT_KEY_ENCRYPTION_TYPE_NONE: + printf("encryption_type: DCRYPT_KEY_ENCRYPTION_TYPE_NONE\n"); + break; + case DCRYPT_KEY_ENCRYPTION_TYPE_KEY: + printf("encryption_type: DCRYPT_KEY_ENCRYPTION_TYPE_KEY\n"); + break; + case DCRYPT_KEY_ENCRYPTION_TYPE_PASSWORD: + printf("encryption_type: DCRYPT_KEY_ENCRYPTION_TYPE_PASSWORD\n"); + break; + } + + if (encryption_key_hash != NULL) + printf("encryption_key_hash: %s\n", encryption_key_hash); + if (key_hash != NULL) + printf("key_hash: %s\n", key_hash); + + switch (kind) { + case DCRYPT_KEY_KIND_PUBLIC: + dcrypt_dump_public_key_metadata(buf); + break; + case DCRYPT_KEY_KIND_PRIVATE: + if (encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_NONE) + dcrypt_dump_private_key_metadata(buf); + break; + } + return TRUE; +} + +static bool test_dump_dcrypt_key(const char *path) +{ + if (!dcrypt_initialize("openssl", NULL, NULL)) + return FALSE; + bool ret = dcrypt_key_dump_metadata(path, FALSE); + dcrypt_deinitialize(); + return ret; +} + +static void cmd_dump_dcrypt_key(int argc ATTR_UNUSED, char *argv[]) +{ + const char *error = NULL; + if (!dcrypt_initialize("openssl", NULL, &error)) + i_fatal("dcrypt_initialize: %s", error); + (void)dcrypt_key_dump_metadata(argv[1], TRUE); + dcrypt_deinitialize(); +} + +struct doveadm_cmd_dump doveadm_cmd_dump_dcrypt_key = { + "dcrypt-key", + test_dump_dcrypt_key, + cmd_dump_dcrypt_key +};
--- a/src/doveadm/doveadm-dump.c Wed Aug 10 19:15:56 2016 +0300 +++ b/src/doveadm/doveadm-dump.c Sat Jul 23 23:40:15 2016 +0300 @@ -88,7 +88,8 @@ &doveadm_cmd_dump_mailboxlog, &doveadm_cmd_dump_thread, &doveadm_cmd_dump_zlib, - &doveadm_cmd_dump_dcrypt_file + &doveadm_cmd_dump_dcrypt_file, + &doveadm_cmd_dump_dcrypt_key }; void print_dump_types(void)
--- a/src/doveadm/doveadm-dump.h Wed Aug 10 19:15:56 2016 +0300 +++ b/src/doveadm/doveadm-dump.h Sat Jul 23 23:40:15 2016 +0300 @@ -16,6 +16,7 @@ extern struct doveadm_cmd_dump doveadm_cmd_dump_thread; extern struct doveadm_cmd_dump doveadm_cmd_dump_zlib; extern struct doveadm_cmd_dump doveadm_cmd_dump_dcrypt_file; +extern struct doveadm_cmd_dump doveadm_cmd_dump_dcrypt_key; void doveadm_dump_register(const struct doveadm_cmd_dump *dump);