From 66f40d1badeb945d60b76c182e7bee4b0fc4dd7b Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 19 Apr 2014 00:37:19 +0200 Subject: Add ZMQ CURVE auth support --- src/dabplus-enc-alsa-zmq.cpp | 34 ++++++++++++++++++++++++++++++++-- src/dabplus-enc-file-zmq.c | 37 +++++++++++++++++++++++++++++++++++-- src/encryption.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/encryption.h | 27 +++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 src/encryption.c create mode 100644 src/encryption.h (limited to 'src') diff --git a/src/dabplus-enc-alsa-zmq.cpp b/src/dabplus-enc-alsa-zmq.cpp index 4739ed0..92980e2 100644 --- a/src/dabplus-enc-alsa-zmq.cpp +++ b/src/dabplus-enc-alsa-zmq.cpp @@ -21,6 +21,10 @@ #include "SampleQueue.h" #include "zmq.hpp" +extern "C" { +#include "encryption.h" +} + #include #include #include @@ -81,7 +85,7 @@ void usage(const char* name) { " -d, --device=alsa_device Set ALSA input device (default: \"default\").\n" " -c, --channels={ 1, 2 } Nb of input channels for raw input (default: 2).\n" " -r, --rate={ 32000, 48000 } Sample rate for raw input (default: 48000).\n" - //" -v, --verbose=LEVEL Set verbosity level.\n" + " -k, --secret-key=FILE Set the secret key for encryption.\n" //" -V, --version Print version and exit.\n" "\n" "Only the tcp:// zeromq transport has been tested until now.\n" @@ -231,6 +235,11 @@ int main(int argc, char *argv[]) unsigned char pad_buf[128]; int padlen; + + /* Data for ZMQ CURVE authentication */ + char* keyfile = NULL; + char secretkey[CURVE_KEYLEN+1]; + const struct option longopts[] = { {"bitrate", required_argument, 0, 'b'}, {"output", required_argument, 0, 'o'}, @@ -239,6 +248,7 @@ int main(int argc, char *argv[]) {"channels", required_argument, 0, 'c'}, {"pad", required_argument, 0, 'p'}, {"pad-fifo", required_argument, 0, 'P'}, + {"secret-key", required_argument, 0, 'k'}, {"drift-comp", no_argument, 0, 'D'}, {"afterburner", no_argument, 0, 'a'}, {"help", no_argument, 0, 'h'}, @@ -252,7 +262,7 @@ int main(int argc, char *argv[]) int index; while(ch != -1) { - ch = getopt_long(argc, argv, "hab:c:o:r:d:Dp:P:", longopts, &index); + ch = getopt_long(argc, argv, "hab:c:k:o:r:d:Dp:P:", longopts, &index); switch (ch) { case 'd': alsa_device = optarg; @@ -272,6 +282,9 @@ int main(int argc, char *argv[]) case 'o': outuri = optarg; break; + case 'k': + keyfile = optarg; + break; case 'D': drift_compensation = true; break; @@ -328,6 +341,23 @@ int main(int argc, char *argv[]) zmq::context_t zmq_ctx; zmq::socket_t zmq_sock(zmq_ctx, ZMQ_PUB); + + if (keyfile) { + fprintf(stderr, "Enabling encryption\n"); + + int rc = readkey(keyfile, secretkey); + if (rc) { + fprintf(stderr, "Error reading secret key\n"); + return 2; + } + + const int yes = 1; + zmq_sock.setsockopt(ZMQ_CURVE_SERVER, + &yes, sizeof(yes)); + + zmq_sock.setsockopt(ZMQ_CURVE_SECRETKEY, + secretkey, CURVE_KEYLEN); + } zmq_sock.connect(outuri); HANDLE_AACENCODER encoder; diff --git a/src/dabplus-enc-file-zmq.c b/src/dabplus-enc-file-zmq.c index 04c3e7e..b677d5c 100644 --- a/src/dabplus-enc-file-zmq.c +++ b/src/dabplus-enc-file-zmq.c @@ -31,6 +31,7 @@ #include #include "libAACenc/include/aacenc_lib.h" #include "wavreader.h" +#include "encryption.h" #include #include @@ -76,7 +77,7 @@ void usage(const char* name) { " -f, --format={ wav, raw } Set input file format (default: wav).\n" " -c, --channels={ 1, 2 } Nb of input channels for raw input (default: 2).\n" " -r, --rate={ 32000, 48000 } Sample rate for raw input (default: 48000).\n" - //" -t, --type=TYPE Set data type (dls|pad|packet|dg).\n" + " -k, --secret-key=FILE Set the secret key for encryption.\n" //" -v, --verbose=LEVEL Set verbosity level.\n" "\n" "Only the tcp:// zeromq transport has been tested until now.\n" @@ -116,6 +117,10 @@ int main(int argc, char *argv[]) { void *zmq_context = zmq_ctx_new(); void *zmq_sock = NULL; + /* Data for ZMQ CURVE authentication */ + char* keyfile = NULL; + char secretkey[CURVE_KEYLEN+1]; + const struct option longopts[] = { {"bitrate", required_argument, 0, 'b'}, {"input", required_argument, 0, 'i'}, @@ -125,6 +130,7 @@ int main(int argc, char *argv[]) { {"channels", required_argument, 0, 'c'}, {"pad", required_argument, 0, 'p'}, {"pad-fifo", required_argument, 0, 'P'}, + {"secret-key", required_argument, 0, 'k'}, {"afterburner", no_argument, 0, 'a'}, {"help", no_argument, 0, 'h'}, {0,0,0,0}, @@ -137,7 +143,7 @@ int main(int argc, char *argv[]) { int index; while(ch != -1) { - ch = getopt_long(argc, argv, "tlhab:c:i:o:r:f:p:P:", longopts, &index); + ch = getopt_long(argc, argv, "tlhab:c:i:k:o:r:f:p:P:", longopts, &index); switch (ch) { case 'f': if(strcmp(optarg, "raw")==0) { @@ -160,6 +166,9 @@ int main(int argc, char *argv[]) { case 'i': infile = optarg; break; + case 'k': + keyfile = optarg; + break; case 'o': outuri = optarg; break; @@ -256,6 +265,30 @@ int main(int argc, char *argv[]) { zmq_strerror(errno)); return 2; } + if (keyfile) { + fprintf(stderr, "Enabling encryption\n"); + + int rc = readkey(keyfile, secretkey); + if (rc) { + fprintf(stderr, "Error reading secret key\n"); + return 2; + } + + const int yes = 1; + rc = zmq_setsockopt(zmq_sock, ZMQ_CURVE_SERVER, + &yes, sizeof(yes)); + if (rc) { + fprintf(stderr, "Error: %s\n", zmq_strerror(errno)); + return 2; + } + + rc = zmq_setsockopt(zmq_sock, ZMQ_CURVE_SECRETKEY, + secretkey, CURVE_KEYLEN); + if (rc) { + fprintf(stderr, "Error: %s\n", zmq_strerror(errno)); + return 2; + } + } if (zmq_connect(zmq_sock, outuri) != 0) { fprintf(stderr, "Error occurred during zmq_connect: %s\n", zmq_strerror(errno)); diff --git a/src/encryption.c b/src/encryption.c new file mode 100644 index 0000000..f39fd28 --- /dev/null +++ b/src/encryption.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2014 Matthias P. Braendli + * + * 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 + * + * 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. + * ------------------------------------------------------------------- + */ + +#include "encryption.h" +#include +#include +#include +#include +#include + +int readkey(const char* keyfile, char* key) +{ + int fd = open(keyfile, O_RDONLY); + if (fd < 0) + return fd; + int ret = read(fd, key, CURVE_KEYLEN); + if (ret < 0) + return ret; + close(fd); + + /* It needs to be zero-terminated */ + key[CURVE_KEYLEN] = '\0'; + + return 0; +} + diff --git a/src/encryption.h b/src/encryption.h new file mode 100644 index 0000000..936578b --- /dev/null +++ b/src/encryption.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2014 Matthias P. Braendli + * + * 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 + * + * 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. + * ------------------------------------------------------------------- + */ + +#ifndef _ENCRYPTION_H_ +#define _ENCRYPTION_H_ + +int readkey(const char* keyfile, char* key); + +#define CURVE_KEYLEN 40 + +#endif + -- cgit v1.2.3