ConnectionContext to expose client certificate in PKCS #12 format
Summary: RSocket plays nicely with Folly and OpenSSL. Flipper WebSocket-client uses SocketRocket which instead relies on Apple's NSInputStream and NSOutputStream types. SSL options can be set to secure the communication in both. Unfortunately, Apple APIs are a bit limited on the supported cryptographic formats it can accept as arguments. SSL options require the client certificate to be set in PKCS #12 format, contrary to the existing PEM format used by RSocket. This change adds a method to the ConnectionContext which converts and saves the client certificate in PKCS #12 format. The method is always expected to succeed as it will only be called once a valid client certificate is available. An unlikely failure will raise an exception. Reviewed By: fabiomassimo Differential Revision: D30074334 fbshipit-source-id: 91a475d080569cc339b649c7302b1f28793c7de7
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a5b83dc148
commit
43179a7ef4
@@ -8,12 +8,17 @@
|
||||
#include "ConnectionContextStore.h"
|
||||
#include <folly/json.h>
|
||||
#include <folly/portability/SysStat.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include "CertificateUtils.h"
|
||||
#include "Log.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace flipper {
|
||||
|
||||
@@ -21,6 +26,8 @@ static constexpr auto CSR_FILE_NAME = "app.csr";
|
||||
static constexpr auto FLIPPER_CA_FILE_NAME = "sonarCA.crt";
|
||||
static constexpr auto CLIENT_CERT_FILE_NAME = "device.crt";
|
||||
static constexpr auto PRIVATE_KEY_FILE = "privateKey.pem";
|
||||
static constexpr auto CERTIFICATE_FILE_NAME = "device.p12";
|
||||
static constexpr auto CERTIFICATE_PASSWORD = "fl1pp3r";
|
||||
static constexpr auto CONNECTION_CONFIG_FILE = "connection_config.json";
|
||||
|
||||
bool fileExists(std::string fileName);
|
||||
@@ -72,7 +79,7 @@ std::string ConnectionContextStore::getCertificateSigningRequest() {
|
||||
return csr;
|
||||
}
|
||||
|
||||
std::shared_ptr<SSLContext> ConnectionContextStore::getSSLContext() {
|
||||
std::shared_ptr<folly::SSLContext> ConnectionContextStore::getSSLContext() {
|
||||
std::shared_ptr<folly::SSLContext> sslContext =
|
||||
std::make_shared<folly::SSLContext>();
|
||||
sslContext->loadTrustedCertificates(
|
||||
@@ -132,7 +139,8 @@ bool ConnectionContextStore::resetState() {
|
||||
FLIPPER_CA_FILE_NAME,
|
||||
CLIENT_CERT_FILE_NAME,
|
||||
PRIVATE_KEY_FILE,
|
||||
CONNECTION_CONFIG_FILE}) {
|
||||
CONNECTION_CONFIG_FILE,
|
||||
CERTIFICATE_FILE_NAME}) {
|
||||
std::remove(absoluteFilePath(file).c_str());
|
||||
}
|
||||
return true;
|
||||
@@ -142,6 +150,30 @@ bool ConnectionContextStore::resetState() {
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> ConnectionContextStore::getCertificate() {
|
||||
auto cacertFilepath = absoluteFilePath(FLIPPER_CA_FILE_NAME);
|
||||
auto certFilepath = absoluteFilePath(CLIENT_CERT_FILE_NAME);
|
||||
auto keyFilepath = absoluteFilePath(PRIVATE_KEY_FILE);
|
||||
auto certificate_path = absoluteFilePath(CERTIFICATE_FILE_NAME);
|
||||
|
||||
if (fileExists(certificate_path.c_str())) {
|
||||
std::remove(certificate_path.c_str());
|
||||
}
|
||||
|
||||
if (!facebook::flipper::generateCertPKCS12(
|
||||
cacertFilepath.c_str(),
|
||||
certFilepath.c_str(),
|
||||
keyFilepath.c_str(),
|
||||
certificate_path.c_str(),
|
||||
CERTIFICATE_FILE_NAME,
|
||||
CERTIFICATE_PASSWORD)) {
|
||||
log("ERROR: Unable to genereate certificate pkcs#12");
|
||||
return std::make_pair("", "");
|
||||
}
|
||||
|
||||
return std::make_pair(certificate_path, std::string(CERTIFICATE_PASSWORD));
|
||||
}
|
||||
|
||||
std::string loadStringFromFile(std::string fileName) {
|
||||
if (!fileExists(fileName)) {
|
||||
return "";
|
||||
|
||||
Reference in New Issue
Block a user