From 2802cad8c4a10a03e0aea5895c6e2b079ce113e7 Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Fri, 24 Apr 2020 15:50:39 -0700 Subject: [PATCH] more tls in memory certs doc + bump file format --- docs/CHANGELOG.md | 4 ++++ docs/design.md | 3 +-- docs/usage.md | 3 ++- ixwebsocket/IXSocketMbedTLS.cpp | 2 +- ixwebsocket/IXSocketOpenSSL.cpp | 2 +- ixwebsocket/IXSocketTLSOptions.cpp | 3 ++- ixwebsocket/IXWebSocketVersion.h | 2 +- 7 files changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 2f4cba98..86878157 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All changes to this project will be documented in this file. +## [9.4.0] - 2020-04-24 + +(ssl) Add support for supplying SSL CA from memory, for OpenSSL and MbedTLS backends + ## [9.3.3] - 2020-04-17 (ixbots) display sent/receive message, per seconds as accumulated diff --git a/docs/design.md b/docs/design.md index 4fc728d0..5c3dbb13 100644 --- a/docs/design.md +++ b/docs/design.md @@ -38,8 +38,7 @@ The regression test is running after each commit on github actions for multiple ## Limitations -* On Windows and Android certificate validation needs to be setup so that SocketTLSOptions.caFile point to a pem file, such as the one distributed by Firefox. Unless that setup is done connecting to a wss endpoint will display an error. On Windows with mbedtls the message will contain `error in handshake : X509 - Certificate verification failed, e.g. CRL, CA or signature check failed`. -* There is no convenient way to embed a ca cert. +* On some configuration (mostly Android) certificate validation needs to be setup so that SocketTLSOptions.caFile point to a pem file, such as the one distributed by Firefox. Unless that setup is done connecting to a wss endpoint will display an error. With mbedtls the message will contain `error in handshake : X509 - Certificate verification failed, e.g. CRL, CA or signature check failed`. * Automatic reconnection works at the TCP socket level, and will detect remote end disconnects. However, if the device/computer network become unreachable (by turning off wifi), it is quite hard to reliably and timely detect it at the socket level using `recv` and `send` error codes. [Here](https://stackoverflow.com/questions/14782143/linux-socket-how-to-detect-disconnected-network-in-a-client-program) is a good discussion on the subject. This behavior is consistent with other runtimes such as node.js. One way to detect a disconnected device with low level C code is to do a name resolution with DNS but this can be expensive. Mobile devices have good and reliable API to do that. * The server code is using select to detect incoming data, and creates one OS thread per connection. This is not as scalable as strategies using epoll or kqueue. diff --git a/docs/usage.md b/docs/usage.md index 6daa4507..99a38791 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -447,7 +447,7 @@ Additional TLS options can be configured by passing a `ix::SocketTLSOptions` ins webSocket.setTLSOptions({ .certFile = "path/to/cert/file.pem", .keyFile = "path/to/key/file.pem", - .caFile = "path/to/trust/bundle/file.pem", + .caFile = "path/to/trust/bundle/file.pem", // as a file, or in memory buffer in PEM format .tls = true // required in server mode }); ``` @@ -461,6 +461,7 @@ On a server, this is necessary for TLS support. Specifying `caFile` configures the trusted roots bundle file (in PEM format) that will be used to verify peer certificates. - The special value of `SYSTEM` (the default) indicates that the system-configured trust bundle should be used; this is generally what you want when connecting to any publicly exposed API/server. - The special value of `NONE` can be used to disable peer verification; this is only recommended to rule out certificate verification when testing connectivity. + - If the value contain the special value `-----BEGIN CERTIFICATE-----`, the value will be read from memory, and not from a file. This is convenient on platforms like Android where reading / writing to the file system can be challenging without proper permissions, or without knowing the location of a temp directory. For a client, specifying `caFile` can be used if connecting to a server that uses a self-signed cert, or when using a custom CA in an internal environment. diff --git a/ixwebsocket/IXSocketMbedTLS.cpp b/ixwebsocket/IXSocketMbedTLS.cpp index 5f738ab4..583d5e84 100644 --- a/ixwebsocket/IXSocketMbedTLS.cpp +++ b/ixwebsocket/IXSocketMbedTLS.cpp @@ -1,6 +1,6 @@ /* * IXSocketMbedTLS.cpp - * Author: Benjamin Sergeant + * Author: Benjamin Sergeant, Max Weisel * Copyright (c) 2019-2020 Machine Zone, Inc. All rights reserved. * * Some code taken from diff --git a/ixwebsocket/IXSocketOpenSSL.cpp b/ixwebsocket/IXSocketOpenSSL.cpp index 11fc39c9..74ff2e58 100644 --- a/ixwebsocket/IXSocketOpenSSL.cpp +++ b/ixwebsocket/IXSocketOpenSSL.cpp @@ -1,6 +1,6 @@ /* * IXSocketOpenSSL.cpp - * Author: Benjamin Sergeant, Matt DeBoer + * Author: Benjamin Sergeant, Matt DeBoer, Max Weisel * Copyright (c) 2017-2020 Machine Zone, Inc. All rights reserved. * * Adapted from Satori SDK OpenSSL code. diff --git a/ixwebsocket/IXSocketTLSOptions.cpp b/ixwebsocket/IXSocketTLSOptions.cpp index da04dc76..4156920a 100644 --- a/ixwebsocket/IXSocketTLSOptions.cpp +++ b/ixwebsocket/IXSocketTLSOptions.cpp @@ -15,6 +15,7 @@ namespace ix const char* kTLSCAFileUseSystemDefaults = "SYSTEM"; const char* kTLSCAFileDisableVerify = "NONE"; const char* kTLSCiphersUseDefault = "DEFAULT"; + const char* kTLSInMemoryMarker = "-----BEGIN CERTIFICATE-----"; bool SocketTLSOptions::isValid() const { @@ -60,7 +61,7 @@ namespace ix bool SocketTLSOptions::isUsingInMemoryCAs() const { - return caFile.find("-----BEGIN CERTIFICATE-----") != std::string::npos; + return caFile.find(kTLSInMemoryMarker) != std::string::npos; } bool SocketTLSOptions::isPeerVerifyDisabled() const diff --git a/ixwebsocket/IXWebSocketVersion.h b/ixwebsocket/IXWebSocketVersion.h index 9a31997f..8c4ac92f 100644 --- a/ixwebsocket/IXWebSocketVersion.h +++ b/ixwebsocket/IXWebSocketVersion.h @@ -6,4 +6,4 @@ #pragma once -#define IX_WEBSOCKET_VERSION "9.3.3" +#define IX_WEBSOCKET_VERSION "9.4.0"