diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-02-26 14:54:40 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-02-26 14:54:40 +0000 |
commit | 8b5cd205ada30cb3e05d154efb078fb69a53c358 (patch) | |
tree | ba4839a8698372a6ee1982f0554ff1e0aea4f90f /src/rspamadm | |
parent | 83e473fa183b66e75443591e9f897b06db549622 (diff) | |
download | rspamd-8b5cd205ada30cb3e05d154efb078fb69a53c358.tar.gz rspamd-8b5cd205ada30cb3e05d154efb078fb69a53c358.zip |
[Feature] Support ed25519 dkim keys generation
Diffstat (limited to 'src/rspamadm')
-rw-r--r-- | src/rspamadm/dkim_keygen.c | 128 |
1 files changed, 116 insertions, 12 deletions
diff --git a/src/rspamadm/dkim_keygen.c b/src/rspamadm/dkim_keygen.c index 86b228d01..86f786295 100644 --- a/src/rspamadm/dkim_keygen.c +++ b/src/rspamadm/dkim_keygen.c @@ -17,6 +17,8 @@ #include "rspamadm.h" #include "printf.h" #include "str_util.h" +#include "libcryptobox/cryptobox.h" +#include "contrib/libottery/ottery.h" #include "lua/lua_common.h" #include <openssl/rsa.h> #include <openssl/bn.h> @@ -26,6 +28,7 @@ static gchar *privkey_file = NULL; static gchar *selector = NULL; static gchar *domain = NULL; static guint bits = 1024; +static gchar *type = "rsa"; static void rspamadm_dkim_keygen (gint argc, gchar **argv, const struct rspamadm_command *cmd); @@ -50,6 +53,8 @@ static GOptionEntry entries[] = { "Save private key in the specified file", NULL}, {"bits", 'b', 0, G_OPTION_ARG_INT, &bits, "Set key length to N bits (1024 by default)", NULL}, + {"type", 't', 0, G_OPTION_ARG_STRING, &type, + "Key type: rsa or ed25519 (rsa by default)", NULL}, {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL} }; @@ -76,8 +81,9 @@ rspamadm_dkim_keygen_help (gboolean full_help, const struct rspamadm_command *cm } static void -rspamadm_dkim_generate_keypair (const gchar *domain, const gchar *selector, - const gchar *priv_fname, const gchar *pub_fname, guint keylen) +rspamd_dkim_generate_rsa_keypair (const gchar *domain, const gchar *selector, + const gchar *priv_fname, const gchar *pub_fname, + guint keylen) { BIGNUM *e; RSA *r; @@ -109,8 +115,7 @@ rspamadm_dkim_generate_keypair (const gchar *domain, const gchar *selector, priv_fname, strerror (errno)); exit (EXIT_FAILURE); } - } - else { + } else { privout = BIO_new_fp (stdout, 0); } @@ -125,7 +130,7 @@ rspamadm_dkim_generate_keypair (const gchar *domain, const gchar *selector, BIO_free (privout); fflush (stdout); - pubout = BIO_new (BIO_s_mem()); + pubout = BIO_new (BIO_s_mem ()); rc = i2d_RSA_PUBKEY_bio (pubout, r); publen = BIO_get_mem_data (pubout, &pubdata); @@ -141,18 +146,16 @@ rspamadm_dkim_generate_keypair (const gchar *domain, const gchar *selector, pub_fname, strerror (errno)); exit (EXIT_FAILURE); } - } - else { + } else { pubfile = stdout; } if (b64_len < 255 - 2) { rspamd_fprintf (pubfile, "%s._domainkey IN TXT ( \"v=DKIM1; k=rsa; \"\n" - "\t\"p=%s\" ) ;\n", + "\t\"p=%s\" ) ;\n", selector ? selector : "selector", b64_data); - } - else { + } else { guint i; gint step = 253, remain = b64_len; @@ -162,8 +165,7 @@ rspamadm_dkim_generate_keypair (const gchar *domain, const gchar *selector, for (i = 0; i < b64_len; i += step, remain -= step) { if (i == 0) { rspamd_fprintf (pubfile, "\t\"p=%*s\"\n", MIN(step, remain), &b64_data[i]); - } - else { + } else { step = 255; rspamd_fprintf (pubfile, "\t\"%*s\"\n", MIN(step, remain), &b64_data[i]); } @@ -183,6 +185,108 @@ rspamadm_dkim_generate_keypair (const gchar *domain, const gchar *selector, BN_free (e); } +static void +rspamd_dkim_generate_ed25519_keypair (const gchar *domain, const gchar *selector, + const gchar *priv_fname, const gchar *pub_fname, + guint keylen) +{ + rspamd_sig_sk_t ed_sk; + rspamd_sig_pk_t ed_pk; + gchar *base64_pk, *base64_sk; + FILE *pubfile = NULL, *privfile = NULL; + + rspamd_cryptobox_keypair_sig (ed_pk, ed_sk, RSPAMD_CRYPTOBOX_MODE_25519); + /* Just encode seed, not the full sk */ + base64_sk = rspamd_encode_base64_common (ed_sk, 32, 0, NULL, FALSE, + RSPAMD_TASK_NEWLINES_LF); + base64_pk = rspamd_encode_base64_common (ed_pk, sizeof (ed_pk), 0, NULL, FALSE, + RSPAMD_TASK_NEWLINES_LF); + + /* Cleanup sensitive data */ + rspamd_explicit_memzero (ed_sk, sizeof (ed_sk)); + + if (priv_fname) { + privfile = fopen (priv_fname, "w"); + + if (privfile == NULL) { + rspamd_fprintf (stderr, "cannot open output file %s: %s\n", + priv_fname, strerror (errno)); + rspamd_explicit_memzero (base64_sk, strlen (base64_sk)); + g_free (base64_sk); + g_free (base64_pk); + exit (EXIT_FAILURE); + } + } + else { + privfile = stdout; + } + + if (rspamd_fprintf (privfile, "%s\n", base64_sk) == -1) { + rspamd_fprintf (stderr, "cannot write to output file %s: %s\n", + priv_fname, strerror (errno)); + rspamd_explicit_memzero (base64_sk, strlen (base64_sk)); + g_free (base64_sk); + g_free (base64_pk); + + if (privfile != stdout) { + fclose (privfile); + } + + exit (EXIT_FAILURE); + } + + if (privfile != stdout) { + fclose (privfile); + } + + if (pub_fname) { + pubfile = fopen (pub_fname, "w"); + + if (pubfile == NULL) { + rspamd_fprintf (stderr, "cannot open output file %s: %s\n", + pub_fname, strerror (errno)); + rspamd_explicit_memzero (base64_sk, strlen (base64_sk)); + g_free (base64_sk); + g_free (base64_pk); + exit (EXIT_FAILURE); + } + } + else { + pubfile = stdout; + } + + rspamd_fprintf (pubfile, "%s._domainkey IN TXT ( \"v=DKIM1; k=ed25519; \"\n" + "\t\"p=%s\" ) ;\n", + selector ? selector : "selector", + base64_pk); + + if (pubfile != stdout) { + fclose (pubfile); + } + + rspamd_explicit_memzero (base64_sk, strlen (base64_sk)); + g_free (base64_sk); + g_free (base64_pk); +} + +static void +rspamadm_dkim_generate_keypair (const gchar *domain, const gchar *selector, + const gchar *priv_fname, const gchar *pub_fname, guint keylen) +{ + if (strcmp (type, "rsa") == 0) { + rspamd_dkim_generate_rsa_keypair (domain, selector, priv_fname, + pub_fname, keylen); + } + else if (strcmp (type, "ed25519") == 0) { + rspamd_dkim_generate_ed25519_keypair (domain, selector, priv_fname, + pub_fname, keylen); + } + else { + fprintf (stderr, "invalid key type: %s\n", type); + exit (EXIT_FAILURE); + } +} + static gint rspamadm_dkim_keygen_lua_generate (lua_State *L) { |