diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2013-04-12 12:52:59 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2013-04-12 12:52:59 +0200 |
commit | 7a62ef673f3aea7b0ad34e27a4cfaa5ba6e9efd1 (patch) | |
tree | d92f1477b81edcadba77450e815b99240763aad2 | |
parent | 815bae1f35c67ff7b8caf7b446a9e4cf1c870aa3 (diff) | |
download | rsyslog-7a62ef673f3aea7b0ad34e27a4cfaa5ba6e9efd1.tar.gz rsyslog-7a62ef673f3aea7b0ad34e27a4cfaa5ba6e9efd1.tar.bz2 rsyslog-7a62ef673f3aea7b0ad34e27a4cfaa5ba6e9efd1.zip |
logenc: support keyfiles in rscryutil
-rw-r--r-- | runtime/Makefile.am | 14 | ||||
-rw-r--r-- | runtime/libgcry.c | 3 | ||||
-rw-r--r-- | runtime/libgcry.h | 1 | ||||
-rw-r--r-- | runtime/libgcry_common.c | 77 | ||||
-rw-r--r-- | tools/Makefile.am | 2 | ||||
-rw-r--r-- | tools/rscryutil.c | 81 | ||||
-rw-r--r-- | tools/rscryutil.rst | 4 |
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. |