From: Martti Rannanjärvi Date: Sat, 23 Jul 2016 20:40:15 +0000 (+0300) Subject: doveadm: add doveadm-dump-dcrypt-key X-Git-Tag: 2.3.0.rc1~3184 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=35de0999ddf1b445ac56c19b72be6e0053049eaa;p=thirdparty%2Fdovecot%2Fcore.git doveadm: add doveadm-dump-dcrypt-key --- diff --git a/doc/man/doveadm-dump.1.in b/doc/man/doveadm-dump.1.in index a6b7b2d511..7dba01e8c6 100644 --- a/doc/man/doveadm-dump.1.in +++ b/doc/man/doveadm-dump.1.in @@ -58,6 +58,9 @@ IMAP COMPRESSION extension. .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 diff --git a/src/doveadm/Makefile.am b/src/doveadm/Makefile.am index 80ddebf20c..bf4de6138f 100644 --- a/src/doveadm/Makefile.am +++ b/src/doveadm/Makefile.am @@ -118,6 +118,7 @@ doveadm_common_dump_cmds = \ doveadm-dump-mailboxlog.c \ doveadm-dump-thread.c \ doveadm-dump-dcrypt-file.c \ + doveadm-dump-dcrypt-key.c \ doveadm-zlib.c common = \ diff --git a/src/doveadm/doveadm-dump-dcrypt-key.c b/src/doveadm/doveadm-dump-dcrypt-key.c new file mode 100644 index 0000000000..6242451f7f --- /dev/null +++ b/src/doveadm/doveadm-dump-dcrypt-key.c @@ -0,0 +1,213 @@ +/* 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 "str.h" +#include +#include +#include +#include +#include + +#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 +}; diff --git a/src/doveadm/doveadm-dump.c b/src/doveadm/doveadm-dump.c index a90b20340e..34e22dfb1a 100644 --- a/src/doveadm/doveadm-dump.c +++ b/src/doveadm/doveadm-dump.c @@ -88,7 +88,8 @@ static const struct doveadm_cmd_dump *dumps_builtin[] = { &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) diff --git a/src/doveadm/doveadm-dump.h b/src/doveadm/doveadm-dump.h index cff366ec71..c6cbc431ae 100644 --- a/src/doveadm/doveadm-dump.h +++ b/src/doveadm/doveadm-dump.h @@ -16,6 +16,7 @@ extern struct doveadm_cmd_dump doveadm_cmd_dump_mailboxlog; 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);