diff --git a/utils/websocket.c b/utils/websocket.c index 4205721f..4a124f15 100644 --- a/utils/websocket.c +++ b/utils/websocket.c @@ -117,12 +117,21 @@ ws_ctx_t *ws_socket(int socket) { return ctx; } -ws_ctx_t *ws_socket_ssl(int socket, char * certfile) { +ws_ctx_t *ws_socket_ssl(int socket, char * certfile, char * keyfile) { int ret; char msg[1024]; + char * use_keyfile; ws_ctx_t *ctx; ctx = ws_socket(socket); + if (keyfile && (keyfile[0] != '\0')) { + // Separate key file + use_keyfile = keyfile; + } else { + // Combined key and cert file + use_keyfile = certfile; + } + // Initialize the library if (! ssl_initialized) { SSL_library_init(); @@ -138,9 +147,9 @@ ws_ctx_t *ws_socket_ssl(int socket, char * certfile) { fatal("Failed to configure SSL context"); } - if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, certfile, - SSL_FILETYPE_PEM) <= 0) { - sprintf(msg, "Unable to load private key file %s\n", certfile); + if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, use_keyfile, + SSL_FILETYPE_PEM) <= 0) { + sprintf(msg, "Unable to load private key file %s\n", use_keyfile); fatal(msg); } @@ -354,7 +363,7 @@ ws_ctx_t *do_handshake(int sock) { (bcmp(handshake, "\x80", 1) == 0)) { // SSL if (! settings.cert) { return NULL; } - ws_ctx = ws_socket_ssl(sock, settings.cert); + ws_ctx = ws_socket_ssl(sock, settings.cert, settings.key); if (! ws_ctx) { return NULL; } scheme = "wss"; handler_msg("using SSL socket\n"); diff --git a/utils/websocket.h b/utils/websocket.h index 28616c6a..c428fa53 100644 --- a/utils/websocket.h +++ b/utils/websocket.h @@ -12,9 +12,10 @@ typedef struct { int listen_port; void (*handler)(ws_ctx_t*); int handler_id; + char *cert; + char *key; int ssl_only; int daemon; - char *cert; } settings_t; typedef struct { diff --git a/utils/websocket.py b/utils/websocket.py index 630af9ee..b4bc01ec 100755 --- a/utils/websocket.py +++ b/utils/websocket.py @@ -28,6 +28,7 @@ settings = { 'handler' : None, 'handler_id' : 1, 'cert' : None, + 'key' : None, 'ssl_only' : False, 'daemon' : True, 'record' : None, } @@ -114,7 +115,8 @@ def do_handshake(sock): retsock = ssl.wrap_socket( sock, server_side=True, - certfile=settings['cert']) + certfile=settings['cert'], + keyfile=settings['key']) scheme = "wss" handler_msg("using SSL/TLS") elif settings['ssl_only']: diff --git a/utils/wsproxy.c b/utils/wsproxy.c index f0f452c8..dc8b5f7d 100644 --- a/utils/wsproxy.c +++ b/utils/wsproxy.c @@ -33,9 +33,11 @@ Traffic Legend:\n\ char USAGE[] = "Usage: [options] " \ "[source_addr:]source_port target_addr:target_port\n\n" \ - " --cert CERT load CERT as SSL certificate\n" \ - " --foreground|-f run in the foreground\n" \ - " --ssl-only disallow non-SSL connections"; + " --verbose|-v verbose messages and per frame traffic\n" \ + " --foreground|-f stay in foreground, do not daemonize\n" \ + " --cert CERT SSL certificate file\n" \ + " --key KEY SSL key file (if separate from cert)\n" \ + " --ssl-only disallow non-encrypted connections"; #define usage(fmt, args...) \ fprintf(stderr, "%s\n\n", USAGE); \ @@ -250,13 +252,15 @@ int main(int argc, char *argv[]) {"foreground", no_argument, &foreground, 'f'}, /* ---- */ {"cert", required_argument, 0, 'c'}, + {"key", required_argument, 0, 'k'}, {0, 0, 0, 0} }; settings.cert = realpath("self.pem", NULL); + settings.key = ""; while (1) { - c = getopt_long (argc, argv, "vfc:", + c = getopt_long (argc, argv, "vfc:k:", long_options, &option_index); /* Detect the end */ @@ -279,6 +283,12 @@ int main(int argc, char *argv[]) usage("No cert file at %s\n", optarg); } break; + case 'k': + settings.key = realpath(optarg, NULL); + if (! settings.key) { + usage("No key file at %s\n", optarg); + } + break; default: usage(""); } @@ -316,16 +326,16 @@ int main(int argc, char *argv[]) } if (ssl_only) { - printf("cert: %s\n", settings.cert); if (!settings.cert || !access(settings.cert, R_OK)) { usage("SSL only and cert file not found\n"); } } //printf(" verbose: %d\n", settings.verbose); - //printf(" ssl_only: %d\n", settings.ssl_only); - //printf(" daemon: %d\n", settings.daemon); - //printf(" cert: %s\n", settings.cert); + //printf(" ssl_only: %d\n", settings.ssl_only); + //printf(" daemon: %d\n", settings.daemon); + //printf(" cert: %s\n", settings.cert); + //printf(" key: %s\n", settings.key); settings.handler = proxy_handler; start_server(); diff --git a/utils/wsproxy.py b/utils/wsproxy.py index 71fe5774..7482abdf 100755 --- a/utils/wsproxy.py +++ b/utils/wsproxy.py @@ -137,10 +137,12 @@ if __name__ == '__main__': parser.add_option("--foreground", "-f", dest="daemon", default=True, action="store_false", help="stay in foreground, do not daemonize") + parser.add_option("--cert", default="self.pem", + help="SSL certificate file") + parser.add_option("--key", default=None, + help="SSL key file (if separate from cert)") parser.add_option("--ssl-only", action="store_true", help="disallow non-encrypted connections") - parser.add_option("--cert", default="self.pem", - help="SSL certificate") (options, args) = parser.parse_args() if len(args) > 2: parser.error("Too many arguments") @@ -166,6 +168,8 @@ if __name__ == '__main__': settings['listen_port'] = port settings['handler'] = proxy_handler settings['cert'] = os.path.abspath(options.cert) + if settings['key']: + settings['key'] = os.path.abspath(options.key) settings['ssl_only'] = options.ssl_only settings['daemon'] = options.daemon if options.record: