summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2013-04-12 12:52:59 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2013-04-12 12:52:59 +0200
commit7a62ef673f3aea7b0ad34e27a4cfaa5ba6e9efd1 (patch)
treed92f1477b81edcadba77450e815b99240763aad2
parent815bae1f35c67ff7b8caf7b446a9e4cf1c870aa3 (diff)
downloadrsyslog-7a62ef673f3aea7b0ad34e27a4cfaa5ba6e9efd1.tar.gz
rsyslog-7a62ef673f3aea7b0ad34e27a4cfaa5ba6e9efd1.tar.bz2
rsyslog-7a62ef673f3aea7b0ad34e27a4cfaa5ba6e9efd1.zip
logenc: support keyfiles in rscryutil
-rw-r--r--runtime/Makefile.am14
-rw-r--r--runtime/libgcry.c3
-rw-r--r--runtime/libgcry.h1
-rw-r--r--runtime/libgcry_common.c77
-rw-r--r--tools/Makefile.am2
-rw-r--r--tools/rscryutil.c81
-rw-r--r--tools/rscryutil.rst4
7 files changed, 164 insertions, 18 deletions
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
index e1f0673c..ee5a3ef2 100644
--- a/runtime/Makefile.am
+++ b/runtime/Makefile.am
@@ -1,6 +1,6 @@
sbin_PROGRAMS =
man_MANS =
-noinst_LTLIBRARIES = librsyslog.la librsgt.la
+noinst_LTLIBRARIES = librsyslog.la
pkglib_LTLIBRARIES =
#pkglib_LTLIBRARIES = librsyslog.la
@@ -178,15 +178,14 @@ endif
# support library for libgcrypt
#
if ENABLE_LIBGCRYPT
-#noinst_LTLIBRARIES += libgcry.la
-#libgcry_la_SOURCES = libgcry.c libgcry.h
-#libcgry_la_CPPFLAGS = $(RSRT_CFLAGS) $(LIBGCRYPT_CFLAGS)
+ noinst_LTLIBRARIES += libgcry.la
+ libgcry_la_SOURCES = libgcry.c libgcry_common.c libgcry.h
+ libgcry_la_CPPFLAGS = $(RSRT_CFLAGS) $(LIBGCRYPT_CFLAGS)
pkglib_LTLIBRARIES += lmcry_gcry.la
- lmcry_gcry_la_SOURCES = lmcry_gcry.c lmcry_gcry.h libgcry.c libgcry.h
+ lmcry_gcry_la_SOURCES = lmcry_gcry.c lmcry_gcry.h
lmcry_gcry_la_CPPFLAGS = $(RSRT_CFLAGS) $(LIBGCRYPT_CFLAGS)
lmcry_gcry_la_LDFLAGS = -module -avoid-version `libgcrypt-config --libs`
-#lmcry_gcry_la_LIBADD = libgcry.la $(LIBGCRYPT_LIBS)
- lmcry_gcry_la_LIBADD = $(LIBGCRYPT_LIBS)
+ lmcry_gcry_la_LIBADD = libgcry.la $(LIBGCRYPT_LIBS)
endif
@@ -194,6 +193,7 @@ endif
# support library for guardtime
#
if ENABLE_GUARDTIME
+ noinst_LTLIBRARIES += librsgt.la
librsgt_la_SOURCES = librsgt.c librsgt_read.c librsgt.h
pkglib_LTLIBRARIES += lmsig_gt.la
lmsig_gt_la_SOURCES = lmsig_gt.c lmsig_gt.h
diff --git a/runtime/libgcry.c b/runtime/libgcry.c
index ef94e8ac..e57ee8bc 100644
--- a/runtime/libgcry.c
+++ b/runtime/libgcry.c
@@ -43,6 +43,8 @@
#include <gcrypt.h>
#include <sys/stat.h>
#include <sys/uio.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
@@ -199,6 +201,7 @@ finalize_it:
RETiRet;
}
+
gcryctx
gcryCtxNew(void)
{
diff --git a/runtime/libgcry.h b/runtime/libgcry.h
index d699124d..5dde1576 100644
--- a/runtime/libgcry.h
+++ b/runtime/libgcry.h
@@ -41,6 +41,7 @@ struct gcryfile_s {
gcryctx ctx;
};
+int gcryGetKeyFromFile(char *fn, char **key, unsigned *keylen);
int rsgcryInit(void);
void rsgcryExit(void);
int rsgcrySetKey(gcryctx ctx, unsigned char *key, uint16_t keyLen);
diff --git a/runtime/libgcry_common.c b/runtime/libgcry_common.c
new file mode 100644
index 00000000..49a0e669
--- /dev/null
+++ b/runtime/libgcry_common.c
@@ -0,0 +1,77 @@
+/* libgcry_common.c
+ * This file hosts functions both being used by the rsyslog runtime as
+ * well as tools who do not use the runtime (so we can maintain the
+ * code at a single place).
+ *
+ * Copyright 2013 Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * -or-
+ * see COPYING.ASL20 in the source distribution
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <gcrypt.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "rsyslog.h" /* we need data typedefs */
+#include "libgcry.h"
+
+
+/* read a key from a key file
+ * @param[out] key - key buffer, must be freed by caller
+ * @param[out] keylen - length of buffer
+ * @returns 0 if OK, something else otherwise (we do not use
+ * iRet as this is also called from non-rsyslog w/o runtime)
+ * The key length is limited to 64KiB to prevent DoS.
+ * Note well: key is a blob, not a C string (NUL may be present!)
+ */
+int
+gcryGetKeyFromFile(char *fn, char **key, unsigned *keylen)
+{
+ struct stat sb;
+ int fd;
+ int r;
+
+ if(stat(fn, &sb) == -1) {
+ r = 1; goto done;
+ }
+ if((sb.st_mode & S_IFMT) != S_IFREG) {
+ r = 2; goto done;
+ }
+ if(sb.st_size > 64*1024) {
+ r = 3; goto done;
+ }
+ if((*key = malloc(sb.st_size)) == NULL) {
+ r = -1; goto done;
+ }
+ if((fd = open(fn, O_RDONLY)) < 0) {
+ r = 4; goto done;
+ }
+ if(read(fd, *key, sb.st_size) != sb.st_size) {
+ r = 5; goto done;
+ }
+ *keylen = sb.st_size;
+ close(fd);
+ r = 0;
+done: return r;
+}
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 0f2bb57e..938782f7 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -79,7 +79,7 @@ bin_PROGRAMS += rscryutil
rscryutil = rscryutil.c
rscryutil_CPPFLAGS = -I../runtime $(RSRT_CFLAGS) $(LIBGCRYPT_CFLAGS)
rscryutil_LDFLAGS = `libgcrypt-config --libs`
-#rscryutil_LDFLAGS = $(LIBGCRYPT_LIBS)
+rscryutil_LDADD = ../runtime/libgcry.la $(LIBGCRYPT_LIBS)
rscryutil.1: rscryutil.rst
$(AM_V_GEN) $(RST2MAN) $< $@
man1_MANS = rscryutil.1
diff --git a/tools/rscryutil.c b/tools/rscryutil.c
index e1e900a7..9290db4d 100644
--- a/tools/rscryutil.c
+++ b/tools/rscryutil.c
@@ -34,13 +34,14 @@
#include "libgcry.h"
-static enum { MD_DECRYPT
+static enum { MD_DECRYPT, MD_WRITE_KEYFILE
} mode = MD_DECRYPT;
static int verbose = 0;
static gcry_cipher_hd_t gcry_chd;
static size_t blkLength;
static char *cry_key = NULL;
+static unsigned cry_keylen = 0;
static int cry_algo = GCRY_CIPHER_AES128;
static int cry_mode = GCRY_CIPHER_MODE_CBC;
@@ -171,7 +172,7 @@ initCrypt(FILE *eifp)
size_t keyLength = gcry_cipher_get_algo_keylen(cry_algo);
if(strlen(cry_key) != keyLength) {
fprintf(stderr, "invalid key length; key is %u characters, but "
- "exactly %u characters are required\n", strlen(cry_key),
+ "exactly %u characters are required\n", cry_keylen,
keyLength);
r = 1; goto done;
}
@@ -319,38 +320,82 @@ err:
fclose(logfp);
}
+static void
+write_keyfile(char *keyfile)
+{
+ FILE *fp;
+
+ if(cry_key == NULL) {
+ fprintf(stderr, "ERROR: key must be set via some method\n");
+ exit(1);
+ }
+ if(keyfile == NULL) {
+ fprintf(stderr, "ERROR: keyfile must be set\n");
+ exit(1);
+ }
+ if((fp = fopen(keyfile, "w")) == NULL) {
+ perror(keyfile);
+ exit(1);
+ }
+ if(fwrite(cry_key, cry_keylen, 1, fp) != 1) {
+ perror(keyfile);
+ exit(1);
+ }
+ fclose(fp);
+}
static struct option long_options[] =
{
{"verbose", no_argument, NULL, 'v'},
{"version", no_argument, NULL, 'V'},
{"decrypt", no_argument, NULL, 'd'},
- {"key", required_argument, NULL, 'k'},
+ {"write-keyfile", no_argument, NULL, 'W'},
+ {"key", required_argument, NULL, 'K'},
+ {"keyfile", required_argument, NULL, 'k'},
{"algo", required_argument, NULL, 'a'},
{"mode", required_argument, NULL, 'm'},
{NULL, 0, NULL, 0}
};
+static void
+getKeyFromFile(char *fn)
+{
+ int r;
+ r = gcryGetKeyFromFile(fn, &cry_key, &cry_keylen);
+ if(r != 0) {
+ fprintf(stderr, "Error %d reading key from file '%s'\n", r, fn);
+ exit(1);
+ }
+}
+
int
main(int argc, char *argv[])
{
int i;
int opt;
int temp;
+ char *keyfile = NULL;
while(1) {
- opt = getopt_long(argc, argv, "a:dk:m:vV", long_options, NULL);
+ opt = getopt_long(argc, argv, "a:dk:K:m:vVW", long_options, NULL);
if(opt == -1)
break;
switch(opt) {
case 'd':
mode = MD_DECRYPT;
break;
+ case 'W':
+ mode = MD_WRITE_KEYFILE;
+ break;
case 'k':
+ keyfile = optarg;
+ break;
+ case 'K':
fprintf(stderr, "WARNING: specifying the actual key "
"via the command line is highly insecure\n"
"Do NOT use this for PRODUCTION use.\n");
cry_key = optarg;
+ cry_keylen = strlen(cry_key);
break;
case 'a':
temp = rsgcryAlgoname2Algo(optarg);
@@ -384,13 +429,29 @@ main(int argc, char *argv[])
}
}
- if(optind == argc)
- decrypt("-");
- else {
- for(i = optind ; i < argc ; ++i)
- decrypt(argv[i]); /* currently only mode ;) */
+ if(mode == MD_WRITE_KEYFILE) {
+ if(optind != argc) {
+ fprintf(stderr, "ERROR: no file parameters permitted in "
+ "--write-keyfile mode\n");
+ exit(1);
+ }
+ write_keyfile(keyfile);
+ } else {
+ if(keyfile != NULL)
+ getKeyFromFile(keyfile);
+ if(cry_key == NULL) {
+ fprintf(stderr, "ERROR: key must be set via some method\n");
+ exit(1);
+ }
+ if(optind == argc)
+ decrypt("-");
+ else {
+ for(i = optind ; i < argc ; ++i)
+ decrypt(argv[i]);
+ }
}
- memset(cry_key, 0, strlen(cry_key)); /* zero-out key store */
+ memset(cry_key, 0, cry_keylen); /* zero-out key store */
+ cry_keylen = 0;
return 0;
}
diff --git a/tools/rscryutil.rst b/tools/rscryutil.rst
index 3cc54f57..d6381011 100644
--- a/tools/rscryutil.rst
+++ b/tools/rscryutil.rst
@@ -31,6 +31,10 @@ OPTIONS
-d, --decrypt
Select decryption mode. This is the default mode.
+-W, --write-keyfile
+ Utility function to write a key to a keyfile. The key can be obtained
+ via any method (except via a keyfile for obvious reasons).
+
-v, --verbose
Select verbose mode.