diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2013-04-12 15:24:51 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2013-04-12 15:24:51 +0200 |
commit | 97cbbdac13c0e2a08a8f0cb716b0cdce9a2bb3cf (patch) | |
tree | f7c5bf01b4443675bb9de675149886aa8ca4384b /tools/rscryutil.c | |
parent | 7a62ef673f3aea7b0ad34e27a4cfaa5ba6e9efd1 (diff) | |
download | rsyslog-97cbbdac13c0e2a08a8f0cb716b0cdce9a2bb3cf.tar.gz rsyslog-97cbbdac13c0e2a08a8f0cb716b0cdce9a2bb3cf.tar.bz2 rsyslog-97cbbdac13c0e2a08a8f0cb716b0cdce9a2bb3cf.zip |
logenc: full support for keyfiles
including their generation via rscrytool
Diffstat (limited to 'tools/rscryutil.c')
-rw-r--r-- | tools/rscryutil.c | 114 |
1 files changed, 81 insertions, 33 deletions
diff --git a/tools/rscryutil.c b/tools/rscryutil.c index 9290db4d..be14cde9 100644 --- a/tools/rscryutil.c +++ b/tools/rscryutil.c @@ -28,6 +28,9 @@ #include <unistd.h> #include <stdio.h> #include <getopt.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> #include <gcrypt.h> #include "rsyslog.h" @@ -40,10 +43,13 @@ static int verbose = 0; static gcry_cipher_hd_t gcry_chd; static size_t blkLength; +static char *keyfile = NULL; +static int randomKeyLen = -1; 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; +static int optionForce = 0; /* rectype/value must be EIF_MAX_*_LEN+1 long! * returns 0 on success or something else on error/EOF @@ -321,27 +327,70 @@ err: } static void -write_keyfile(char *keyfile) +write_keyfile(char *fn) { - FILE *fp; - - if(cry_key == NULL) { - fprintf(stderr, "ERROR: key must be set via some method\n"); + int fd; + int r; + mode_t fmode; + + fmode = O_WRONLY|O_CREAT; + if(!optionForce) + fmode |= O_EXCL; + if((fd = open(fn, fmode, S_IRUSR)) == -1) { + fprintf(stderr, "error opening keyfile "); + perror(fn); exit(1); } - if(keyfile == NULL) { - fprintf(stderr, "ERROR: keyfile must be set\n"); + if((r = write(fd, cry_key, cry_keylen)) != (ssize_t)cry_keylen) { + fprintf(stderr, "error writing keyfile (ret=%d) ", r); + perror(fn); exit(1); } - if((fp = fopen(keyfile, "w")) == NULL) { - perror(keyfile); + close(fd); +} + +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); } - if(fwrite(cry_key, cry_keylen, 1, fp) != 1) { - perror(keyfile); +} + +static void +getRandomKey(void) +{ + int fd; + cry_keylen = randomKeyLen; + cry_key = malloc(randomKeyLen); /* do NOT zero-out! */ + /* if we cannot obtain data from /dev/urandom, we use whatever + * is present at the current memory location as random data. Of + * course, this is very weak and we should consider a different + * option, especially when not running under Linux (for Linux, + * unavailability of /dev/urandom is just a theoretic thing, it + * will always work...). -- TODO -- rgerhards, 2013-03-06 + */ + if((fd = open("/dev/urandom", O_RDONLY)) > 0) { + if(read(fd, cry_key, randomKeyLen)) {}; /* keep compiler happy */ + close(fd); + } +} + + +static void +setKey() +{ + if(randomKeyLen != -1) + getRandomKey(); + else if(keyfile != NULL) + getKeyFromFile(keyfile); + if(cry_key == NULL) { + fprintf(stderr, "ERROR: key must be set via some method\n"); exit(1); } - fclose(fp); } static struct option long_options[] = @@ -349,35 +398,26 @@ static struct option long_options[] = {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'V'}, {"decrypt", no_argument, NULL, 'd'}, - {"write-keyfile", no_argument, NULL, 'W'}, + {"force", no_argument, NULL, 'f'}, + {"write-keyfile", required_argument, NULL, 'W'}, {"key", required_argument, NULL, 'K'}, + {"generate-random-key", required_argument, NULL, 'r'}, {"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; + char *newKeyFile = NULL; while(1) { - opt = getopt_long(argc, argv, "a:dk:K:m:vVW", long_options, NULL); + opt = getopt_long(argc, argv, "a:dfk:K:m:r:vVW:", long_options, NULL); if(opt == -1) break; switch(opt) { @@ -386,10 +426,22 @@ main(int argc, char *argv[]) break; case 'W': mode = MD_WRITE_KEYFILE; + newKeyFile = optarg; break; case 'k': keyfile = optarg; break; + case 'f': + optionForce = 1; + break; + case 'r': + randomKeyLen = atoi(optarg); + if(randomKeyLen > 64*1024) { + fprintf(stderr, "ERROR: keys larger than 64KiB are " + "not supported\n"); + exit(1); + } + break; case 'K': fprintf(stderr, "WARNING: specifying the actual key " "via the command line is highly insecure\n" @@ -429,20 +481,16 @@ main(int argc, char *argv[]) } } + setKey(); + 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); + write_keyfile(newKeyFile); } 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 { |