]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm: add doveadm-dump-dcrypt-key
authorMartti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
Sat, 23 Jul 2016 20:40:15 +0000 (23:40 +0300)
committerGitLab <gitlab@git.dovecot.net>
Thu, 11 Aug 2016 09:35:58 +0000 (12:35 +0300)
doc/man/doveadm-dump.1.in
src/doveadm/Makefile.am
src/doveadm/doveadm-dump-dcrypt-key.c [new file with mode: 0644]
src/doveadm/doveadm-dump.c
src/doveadm/doveadm-dump.h

index a6b7b2d5116672061a0dd529888a94dd4bfcec77..7dba01e8c6a9849e647e7aaa3672e8670d332e15 100644 (file)
@@ -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
index 80ddebf20cd8cb105500e8c817f2bce2e90cf647..bf4de6138f47d8cac67992addaac89e11b186b25 100644 (file)
@@ -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 (file)
index 0000000..6242451
--- /dev/null
@@ -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 <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
+};
index a90b20340ee228da44b47891b54978270ecc42bd..34e22dfb1a6035aec806e5df6a6deb8d250889c5 100644 (file)
@@ -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)
index cff366ec71fd3768a88891ea674d1b5512301dd4..c6cbc431ae7651cb2de61982bb2d8018990759bc 100644 (file)
@@ -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);