diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:51:24 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:51:24 +0000 |
commit | f7548d6d28c313cf80e6f3ef89aed16a19815df1 (patch) | |
tree | a3f6f2a3f247293bee59ecd28e8cd8ceb6ca064a /src/doveadm/doveadm-dump-dcrypt-key.c | |
parent | Initial commit. (diff) | |
download | dovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.tar.xz dovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.zip |
Adding upstream version 1:2.3.19.1+dfsg1.upstream/1%2.3.19.1+dfsg1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/doveadm/doveadm-dump-dcrypt-key.c')
-rw-r--r-- | src/doveadm/doveadm-dump-dcrypt-key.c | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/src/doveadm/doveadm-dump-dcrypt-key.c b/src/doveadm/doveadm-dump-dcrypt-key.c new file mode 100644 index 0000000..cecd27f --- /dev/null +++ b/src/doveadm/doveadm-dump-dcrypt-key.c @@ -0,0 +1,215 @@ +/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "dcrypt.h" +#include "dcrypt-iostream.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 <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 failed: %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 failed: %s", error); + } else { + 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 failed: %s", + error); + } else { + const char *v1_hash = binary_to_hex(hash->data, + hash->used); + printf("v1 hash: %s\n", v1_hash); + } + } + } + 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 failed: %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 failed: %s", error); + } else { + 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 failed: %s", error); + } else { + const char *v1_hash = binary_to_hex(hash->data, + hash->used); + printf("v1 hash: %s\n", v1_hash); + } + } + } + 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(%s) failed: %m", filename); + 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 failed: %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; + case DCRYPT_FORMAT_JWK: + printf("format: DCRYPT_FORMAT_JWK\n"); + } + + 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); + + const char *data = t_str_rtrim(buf, "\r\n\t "); + switch (kind) { + case DCRYPT_KEY_KIND_PUBLIC: + dcrypt_dump_public_key_metadata(data); + break; + case DCRYPT_KEY_KIND_PRIVATE: + if (encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_NONE) + dcrypt_dump_private_key_metadata(data); + 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); + return ret; +} + +static void +cmd_dump_dcrypt_key(const char *path, const char *const *args ATTR_UNUSED) +{ + const char *error = NULL; + if (!dcrypt_initialize("openssl", NULL, &error)) + i_fatal("dcrypt_initialize: %s", error); + (void)dcrypt_key_dump_metadata(path, TRUE); +} + +struct doveadm_cmd_dump doveadm_cmd_dump_dcrypt_key = { + "dcrypt-key", + test_dump_dcrypt_key, + cmd_dump_dcrypt_key +}; |