summaryrefslogtreecommitdiffstats
path: root/src/doveadm/doveadm-dump-dcrypt-key.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:51:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:51:24 +0000
commitf7548d6d28c313cf80e6f3ef89aed16a19815df1 (patch)
treea3f6f2a3f247293bee59ecd28e8cd8ceb6ca064a /src/doveadm/doveadm-dump-dcrypt-key.c
parentInitial commit. (diff)
downloaddovecot-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.c215
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
+};