Add toggle in the settings for cert exchange medium

Summary:
This diff adds a toggle setting in wilde which will enable certificate exchange through www.
Right now it just sends the information about which medium to be used for cert exchange to Flipper JS and its client side. But its implementation is not done yet.

### Flow for Wilde

Whenever user changes the setting(or when user logs out) we set the state of exchange medium and accordingly set/reset authtoken. Note at no given point we remove already existing certificates.

### Context for OSS

With this diff we introduce another way to do certificate exchange. Before this diff, we did certificate exchange by accessing the file system of app. But it turns out it's not possible to do that in applications signed by enterprise certs. Thus with this diff one can write their FlipperKitCertificateProvider and fetch the certificate from WWW.

Reviewed By: jknoxville

Differential Revision: D22896320

fbshipit-source-id: 55aef7028a62e71ba9c02f9f79acaab41d09c0c6
This commit is contained in:
Pritesh Nandgaonkar
2020-08-12 04:42:26 -07:00
committed by Facebook GitHub Bot
parent 4bb110f319
commit 293de19c2b
16 changed files with 215 additions and 16 deletions

View File

@@ -79,7 +79,7 @@ Pod::Spec.new do |spec|
ss.dependency 'Flipper', '~>'+flipperkit_version ss.dependency 'Flipper', '~>'+flipperkit_version
ss.compiler_flags = folly_compiler_flags ss.compiler_flags = folly_compiler_flags
ss.source_files = 'iOS/FlipperKit/*.{h,m,mm}', 'iOS/FlipperKit/CppBridge/*.{h,mm}' ss.source_files = 'iOS/FlipperKit/*.{h,m,mm}', 'iOS/FlipperKit/CppBridge/*.{h,mm}'
ss.public_header_files = 'iOS/FlipperKit/**/{FlipperDiagnosticsViewController,FlipperStateUpdateListener,FlipperClient,FlipperPlugin,FlipperConnection,FlipperResponder,SKMacros}.h' ss.public_header_files = 'iOS/FlipperKit/**/{FlipperDiagnosticsViewController,FlipperStateUpdateListener,FlipperClient,FlipperPlugin,FlipperConnection,FlipperResponder,SKMacros,FlipperKitCertificateProvider}.h'
header_search_paths = "\"$(PODS_ROOT)/FlipperKit/iOS/FlipperKit/\" \"$(PODS_ROOT)/Headers/Private/FlipperKit/\" \"$(PODS_ROOT)/boost-for-react-native\" \"$(PODS_ROOT)/boost-for-react-native\"" header_search_paths = "\"$(PODS_ROOT)/FlipperKit/iOS/FlipperKit/\" \"$(PODS_ROOT)/Headers/Private/FlipperKit/\" \"$(PODS_ROOT)/boost-for-react-native\" \"$(PODS_ROOT)/boost-for-react-native\""
ss.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", ss.pod_target_xcconfig = { "USE_HEADERMAP" => "NO",
"ONLY_ACTIVE_ARCH": "YES", "ONLY_ACTIVE_ARCH": "YES",

View File

@@ -7,7 +7,10 @@
* @format * @format
*/ */
import {SecureServerConfig} from './utils/CertificateProvider'; import {
SecureServerConfig,
CertificateExchangeMedium,
} from './utils/CertificateProvider';
import {Logger} from './fb-interfaces/Logger'; import {Logger} from './fb-interfaces/Logger';
import {ClientQuery} from './Client'; import {ClientQuery} from './Client';
import {Store} from './reducers/index'; import {Store} from './reducers/index';
@@ -45,6 +48,18 @@ type ClientCsrQuery = {
csr_path?: string | undefined; csr_path?: string | undefined;
}; };
function transformCertificateExchangeMediumToType(
medium: number | undefined,
): CertificateExchangeMedium {
if (medium === 1) {
return 'FS_ACCESS';
} else if (medium === 2) {
return 'WWW';
} else {
return 'FS_ACCESS';
}
}
declare interface Server { declare interface Server {
on(event: 'new-client', callback: (client: Client) => void): this; on(event: 'new-client', callback: (client: Client) => void): this;
on(event: 'error', callback: (err: Error) => void): this; on(event: 'error', callback: (err: Error) => void): this;
@@ -347,11 +362,12 @@ class Server extends EventEmitter {
method: 'signCertificate'; method: 'signCertificate';
csr: string; csr: string;
destination: string; destination: string;
medium: number | undefined; // OSS's older Client SDK might not send medium information. This is not an issue for internal FB users, as Flipper release is insync with client SDK through launcher.
} = rawData; } = rawData;
if (json.method === 'signCertificate') { if (json.method === 'signCertificate') {
console.debug('CSR received from device', 'server'); console.debug('CSR received from device', 'server');
const {csr, destination} = json; const {csr, destination, medium} = json;
return new Single((subscriber) => { return new Single((subscriber) => {
subscriber.onSubscribe(undefined); subscriber.onSubscribe(undefined);
reportPlatformFailures( reportPlatformFailures(
@@ -359,6 +375,7 @@ class Server extends EventEmitter {
csr, csr,
clientData.os, clientData.os,
destination, destination,
transformCertificateExchangeMediumToType(medium),
), ),
'processCertificateSigningRequest', 'processCertificateSigningRequest',
) )
@@ -396,6 +413,7 @@ class Server extends EventEmitter {
method: 'signCertificate'; method: 'signCertificate';
csr: string; csr: string;
destination: string; destination: string;
medium: number | undefined;
} }
| undefined; | undefined;
try { try {
@@ -407,9 +425,14 @@ class Server extends EventEmitter {
if (json && json.method === 'signCertificate') { if (json && json.method === 'signCertificate') {
console.debug('CSR received from device', 'server'); console.debug('CSR received from device', 'server');
const {csr, destination} = json; const {csr, destination, medium} = json;
this.certificateProvider this.certificateProvider
.processCertificateSigningRequest(csr, clientData.os, destination) .processCertificateSigningRequest(
csr,
clientData.os,
destination,
transformCertificateExchangeMediumToType(medium),
)
.catch((e) => { .catch((e) => {
console.error(e); console.error(e);
}); });

View File

@@ -25,6 +25,8 @@ import os from 'os';
import {Client as ADBClient} from 'adbkit'; import {Client as ADBClient} from 'adbkit';
import {Store} from '../reducers/index'; import {Store} from '../reducers/index';
export type CertificateExchangeMedium = 'FS_ACCESS' | 'WWW';
const tmpFile = promisify(tmp.file) as ( const tmpFile = promisify(tmp.file) as (
options?: FileOptions, options?: FileOptions,
) => Promise<string>; ) => Promise<string>;
@@ -96,7 +98,14 @@ export default class CertificateProvider {
unsanitizedCsr: string, unsanitizedCsr: string,
os: string, os: string,
appDirectory: string, appDirectory: string,
medium: CertificateExchangeMedium,
): Promise<{deviceId: string}> { ): Promise<{deviceId: string}> {
// TODO: Add implementations for each of these conditions
if (medium === 'FS_ACCESS') {
// Use IDB for cert exchange
} else if (medium === 'WWW') {
// Use WWWW
}
const csr = this.santitizeString(unsanitizedCsr); const csr = this.santitizeString(unsanitizedCsr);
if (csr === '') { if (csr === '') {
return Promise.reject(new Error(`Received empty CSR from ${os} device`)); return Promise.reject(new Error(`Received empty CSR from ${os} device`));

View File

@@ -25,9 +25,12 @@ This is achieved through the following steps:
* Desktop app starts an insecure server on port 8089. * Desktop app starts an insecure server on port 8089.
* Mobile app connects to localhost:8089 and sends a Certificate Signing Request to the desktop app. * Mobile app connects to localhost:8089 and sends a Certificate Signing Request to the desktop app.
* Desktop app uses it's private key (this is generated once and stored in ~/.flipper) to sign a client certificate for the mobile app. * Desktop app uses it's private key (this is generated once and stored in ~/.flipper) to sign a client certificate for the mobile app.
* The desktop uses ADB (for Android), or the mounted file system (for iOS simulators) to write the following files to the mobile app's private data partition * Along with the Certificate Signing Request, mobile app also lets the desktop app know which certificate exchange medium to use.
* If the chosen Certificate Exchange Medium is FS_ACCESS, the desktop uses ADB (for Android), or the mounted file system (for iOS simulators) to write the following files to the mobile app's private data partition
* Server certificate that the mobile app can now trust. * Server certificate that the mobile app can now trust.
* Client certificate for the mobile app to use going forward. * Client certificate for the mobile app to use going forward.
* If the chosen Certificate Exchange Medium is WWW, the desktop app will use your implementation of Certificate Uploader to upload the certificates.
* Once uploaded the desktop app will reply back with the device id, which can be used by Certificate Provider on the client side to fetch those certificates.
* Now the mobile app knows which server certificate it can trust, and can connect to the secure server. * Now the mobile app knows which server certificate it can trust, and can connect to the secure server.
This allows the mobile app to trust a certificate if and only if, it is stored inside its internal data partition. Typically it's only possible to write there with physical access to the device (i.e. through ADB or a mounted simulator). This allows the mobile app to trust a certificate if and only if, it is stored inside its internal data partition. Typically it's only possible to write there with physical access to the device (i.e. through ADB or a mounted simulator).
@@ -42,6 +45,7 @@ localhost:8089/sonar?os={OS}
&device={DEVICE} &device={DEVICE}
&app={APP} &app={APP}
&sdk_version={SDK_VERSION} &sdk_version={SDK_VERSION}
&medium={CERTIFICATE_EXCHANGE_MEDIUM}
``` ```
On that connection, send the following payload: On that connection, send the following payload:
@@ -49,7 +53,8 @@ On that connection, send the following payload:
Request = { Request = {
"method": "signCertificate", "method": "signCertificate",
"csr": string, "csr": string,
"destination": string "destination": string,
"medium": int
} }
``` ```
Where `csr` is a Certificate Signing Request the client has generated, and `destination` identifies a location accessible to both the client and Flipper desktop, where the certificate should be placed. Where `csr` is a Certificate Signing Request the client has generated, and `destination` identifies a location accessible to both the client and Flipper desktop, where the certificate should be placed.
@@ -60,4 +65,8 @@ This will ask Flipper desktop to generate a client certificate, using the CSR pr
Depending on the client, `destination` can have a different meaning. A basic example would be a file path, that both the desktop and the client have access to. With this Flipper desktop could write the certificate to that path. A more involved example is that of the Android Client, where destination specifies a relative path inside an app container. And the Subject Common Name determines which app container. Together these two pieces of information form an absolute file path inside an android device. Depending on the client, `destination` can have a different meaning. A basic example would be a file path, that both the desktop and the client have access to. With this Flipper desktop could write the certificate to that path. A more involved example is that of the Android Client, where destination specifies a relative path inside an app container. And the Subject Common Name determines which app container. Together these two pieces of information form an absolute file path inside an android device.
For Flipper desktop to work with a given Client type, it needs to be modified to know how to correctly interpret the `destination` argument, and deploy certificates to it. You can see the current implementations in [CertificateProvider.tsx](https://github.com/facebook/flipper/blob/master/desktop/app/src/utils/CertificateProvider.tsx). For Flipper desktop to work with a given Client type, it needs to be modified to know how to correctly interpret the `destination` argument, and deploy certificates to it.
`destination` field may not be relevant if your `medium` value is more than 1. `medium=1`(default) means Flipper should do certificate exchange by directly putting certificates at `destination` in the sandbox of the app. `medium=2` means Flipper will use Certificate Uploader and Provider to upload certificates and download it on the client side respectively.
You can see the current implementations in [CertificateProvider.tsx](https://github.com/facebook/flipper/blob/master/desktop/app/src/utils/CertificateProvider.tsx).

View File

@@ -8,6 +8,7 @@
#ifdef FB_SONARKIT_ENABLED #ifdef FB_SONARKIT_ENABLED
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "FlipperKitCertificateProvider.h"
#import "FlipperPlugin.h" #import "FlipperPlugin.h"
#import "FlipperStateUpdateListener.h" #import "FlipperStateUpdateListener.h"
@@ -64,6 +65,16 @@ Subscribe a ViewController to state update change notifications
*/ */
- (void)subscribeForUpdates:(id<FlipperStateUpdateListener>)controller; - (void)subscribeForUpdates:(id<FlipperStateUpdateListener>)controller;
/**
Sets the certificate provider responsible for obtaining certificates
*/
- (void)setCertificateProvider:(id<FlipperKitCertificateProvider>)provider;
/**
Get the certificate provider of Flipper Client
*/
- (id<FlipperKitCertificateProvider>)getCertificateProvider;
// initializers are disabled. You must use `+[FlipperClient sharedClient]` // initializers are disabled. You must use `+[FlipperClient sharedClient]`
// instance. // instance.
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;

View File

@@ -8,15 +8,17 @@
#if FB_SONARKIT_ENABLED #if FB_SONARKIT_ENABLED
#import "FlipperClient.h" #import "FlipperClient.h"
#import <Flipper/FlipperCertificateProvider.h>
#import <Flipper/FlipperClient.h> #import <Flipper/FlipperClient.h>
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#include <folly/io/async/EventBase.h> #include <folly/io/async/EventBase.h>
#include <folly/io/async/ScopedEventBaseThread.h> #include <folly/io/async/ScopedEventBaseThread.h>
#include <memory>
#import "FlipperClient+Testing.h" #import "FlipperClient+Testing.h"
#import "FlipperCppWrapperPlugin.h" #import "FlipperCppWrapperPlugin.h"
#import "FlipperKitCertificateProvider.h"
#import "SKEnvironmentVariables.h" #import "SKEnvironmentVariables.h"
#include "SKStateUpdateCPPWrapper.h" #include "SKStateUpdateCPPWrapper.h"
#if !TARGET_OS_SIMULATOR #if !TARGET_OS_SIMULATOR
#import <FKPortForwarding/FKPortForwardingServer.h> #import <FKPortForwarding/FKPortForwardingServer.h>
#endif #endif
@@ -27,6 +29,7 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
facebook::flipper::FlipperClient* _cppClient; facebook::flipper::FlipperClient* _cppClient;
folly::ScopedEventBaseThread sonarThread; folly::ScopedEventBaseThread sonarThread;
folly::ScopedEventBaseThread connectionThread; folly::ScopedEventBaseThread connectionThread;
id<FlipperKitCertificateProvider> _certProvider;
#if !TARGET_OS_SIMULATOR #if !TARGET_OS_SIMULATOR
FKPortForwardingServer* _secureServer; FKPortForwardingServer* _secureServer;
FKPortForwardingServer* _insecureServer; FKPortForwardingServer* _insecureServer;
@@ -46,7 +49,6 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
}); });
return sharedClient; return sharedClient;
} }
- (instancetype)init { - (instancetype)init {
if (self = [super init]) { if (self = [super init]) {
UIDevice* device = [UIDevice currentDevice]; UIDevice* device = [UIDevice currentDevice];
@@ -57,9 +59,7 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
NSString* appId = [bundle bundleIdentifier]; NSString* appId = [bundle bundleIdentifier];
NSString* privateAppDirectory = NSSearchPathForDirectoriesInDomains( NSString* privateAppDirectory = NSSearchPathForDirectoriesInDomains(
NSApplicationSupportDirectory, NSUserDomainMask, YES)[0]; NSApplicationSupportDirectory, NSUserDomainMask, YES)[0];
NSFileManager* manager = [NSFileManager defaultManager]; NSFileManager* manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:privateAppDirectory isDirectory:NULL] == NO && if ([manager fileExistsAtPath:privateAppDirectory isDirectory:NULL] == NO &&
![manager createDirectoryAtPath:privateAppDirectory ![manager createDirectoryAtPath:privateAppDirectory
withIntermediateDirectories:YES withIntermediateDirectories:YES
@@ -99,6 +99,19 @@ using WrapperPlugin = facebook::flipper::FlipperCppWrapperPlugin;
return self; return self;
} }
- (void)setCertificateProvider:(id<FlipperKitCertificateProvider>)provider {
_certProvider = provider;
std::shared_ptr<facebook::flipper::FlipperCertificateProvider>* prov =
static_cast<
std::shared_ptr<facebook::flipper::FlipperCertificateProvider>*>(
[provider getCPPCertificateProvider]);
_cppClient->setCertificateProvider(*prov);
}
- (id<FlipperKitCertificateProvider>)getCertificateProvider {
return _certProvider;
}
- (void)refreshPlugins { - (void)refreshPlugins {
_cppClient->refreshPlugins(); _cppClient->refreshPlugins();
} }

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#ifdef FB_SONARKIT_ENABLED
#import <Flipper/FlipperCertificateExchangeMedium.h>
typedef enum FlipperCertificateExchangeMedium
FlipperKitCertificateExchangeMedium;
/**
Represents a CPP Certificate Provider to be used by FlipperClient
*/
@protocol FlipperKitCertificateProvider<NSObject>
- (_Nonnull instancetype)initCPPCertificateProvider;
- (void* _Nonnull)
getCPPCertificateProvider; // Returning it as void* as the file needs to
// have no cpp for it to be compatible with
// Swift. The pointer returned should point to
// std::shared_ptr<FlipperCertificateProvider>
- (void)setCertificateExchangeMedium:
(FlipperKitCertificateExchangeMedium)medium;
@optional
- (void)setAuthToken:(nullable NSString*)authToken;
@end
#endif

View File

@@ -8,12 +8,10 @@
#include "ConnectionContextStore.h" #include "ConnectionContextStore.h"
#include <folly/json.h> #include <folly/json.h>
#include <folly/portability/SysStat.h> #include <folly/portability/SysStat.h>
#include <stdio.h>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include "CertificateUtils.h" #include "CertificateUtils.h"
#include "Log.h" #include "Log.h"
using namespace facebook::flipper; using namespace facebook::flipper;
static constexpr auto CSR_FILE_NAME = "app.csr"; static constexpr auto CSR_FILE_NAME = "app.csr";

View File

@@ -0,0 +1,8 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
enum FlipperCertificateExchangeMedium { FS_ACCESS = 1, WWW = 2 };

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <functional>
#include <string>
#include "FlipperCertificateExchangeMedium.h"
namespace facebook {
namespace flipper {
/**
* Represents a FlipperCertificateProvider which is responsible for obtaining
* Flipper TLS certificates.
*/
class FlipperCertificateProvider {
public:
virtual ~FlipperCertificateProvider() {}
/**
* Gets certificates downloaded at a path, which is passed as an argument.
*/
virtual void getCertificates(
const std::string& path,
const std::string& deviceID) = 0;
virtual void setCertificateExchangeMedium(
const FlipperCertificateExchangeMedium medium) = 0;
virtual FlipperCertificateExchangeMedium getCertificateExchangeMedium() = 0;
};
} // namespace flipper
} // namespace facebook

View File

@@ -73,6 +73,17 @@ void FlipperClient::addPlugin(std::shared_ptr<FlipperPlugin> plugin) {
}); });
} }
void FlipperClient::setCertificateProvider(
const std::shared_ptr<FlipperCertificateProvider> provider) {
socket_->setCertificateProvider(provider);
log("cpp setCertificateProvider called");
}
std::shared_ptr<FlipperCertificateProvider>
FlipperClient::getCertificateProvider() {
return socket_->getCertificateProvider();
}
void FlipperClient::removePlugin(std::shared_ptr<FlipperPlugin> plugin) { void FlipperClient::removePlugin(std::shared_ptr<FlipperPlugin> plugin) {
performAndReportError([this, plugin]() { performAndReportError([this, plugin]() {
log("FlipperClient::removePlugin " + plugin->identifier()); log("FlipperClient::removePlugin " + plugin->identifier());

View File

@@ -10,6 +10,7 @@
#include <map> #include <map>
#include <mutex> #include <mutex>
#include <vector> #include <vector>
#include "FlipperCertificateProvider.h"
#include "FlipperConnectionImpl.h" #include "FlipperConnectionImpl.h"
#include "FlipperConnectionManager.h" #include "FlipperConnectionManager.h"
#include "FlipperInitConfig.h" #include "FlipperInitConfig.h"
@@ -85,6 +86,10 @@ class FlipperClient : public FlipperConnectionManager::Callbacks {
void setStateListener( void setStateListener(
std::shared_ptr<FlipperStateUpdateListener> stateListener); std::shared_ptr<FlipperStateUpdateListener> stateListener);
void setCertificateProvider(
const std::shared_ptr<FlipperCertificateProvider> provider);
std::shared_ptr<FlipperCertificateProvider> getCertificateProvider();
std::shared_ptr<FlipperPlugin> getPlugin(const std::string& identifier); std::shared_ptr<FlipperPlugin> getPlugin(const std::string& identifier);
std::string getState(); std::string getState();

View File

@@ -8,6 +8,7 @@
#pragma once #pragma once
#include <folly/json.h> #include <folly/json.h>
#include "FlipperCertificateProvider.h"
#include "FlipperResponder.h" #include "FlipperResponder.h"
namespace facebook { namespace facebook {
@@ -30,6 +31,18 @@ class FlipperConnectionManager {
*/ */
virtual void stop() = 0; virtual void stop() = 0;
/**
Sets the Auth token to be used for hitting an Intern end point
*/
virtual void setCertificateProvider(
const std::shared_ptr<FlipperCertificateProvider> provider) = 0;
/**
Gets the certificate provider
*/
virtual std::shared_ptr<FlipperCertificateProvider>
getCertificateProvider() = 0;
/** /**
True if there's an open connection. True if there's an open connection.
This method may block if the connection is busy. This method may block if the connection is busy.

View File

@@ -90,6 +90,16 @@ FlipperConnectionManagerImpl::~FlipperConnectionManagerImpl() {
stop(); stop();
} }
void FlipperConnectionManagerImpl::setCertificateProvider(
const std::shared_ptr<FlipperCertificateProvider> provider) {
certProvider_ = provider;
};
std::shared_ptr<FlipperCertificateProvider>
FlipperConnectionManagerImpl::getCertificateProvider() {
return certProvider_;
};
void FlipperConnectionManagerImpl::start() { void FlipperConnectionManagerImpl::start() {
if (isStarted_) { if (isStarted_) {
log("Already started"); log("Already started");
@@ -169,10 +179,13 @@ void FlipperConnectionManagerImpl::startSync() {
bool FlipperConnectionManagerImpl::doCertificateExchange() { bool FlipperConnectionManagerImpl::doCertificateExchange() {
rsocket::SetupParameters parameters; rsocket::SetupParameters parameters;
folly::SocketAddress address; folly::SocketAddress address;
int medium = certProvider_ != nullptr
? certProvider_->getCertificateExchangeMedium()
: FlipperCertificateExchangeMedium::FS_ACCESS;
parameters.payload = rsocket::Payload(folly::toJson(folly::dynamic::object( parameters.payload = rsocket::Payload(folly::toJson(folly::dynamic::object(
"os", deviceData_.os)("device", deviceData_.device)( "os", deviceData_.os)("device", deviceData_.device)(
"app", deviceData_.app)("sdk_version", sdkVersion))); "app", deviceData_.app)("sdk_version", sdkVersion)("medium", medium)));
address.setFromHostPort(deviceData_.host, insecurePort); address.setFromHostPort(deviceData_.host, insecurePort);
auto connectingInsecurely = flipperState_->start("Connect insecurely"); auto connectingInsecurely = flipperState_->start("Connect insecurely");
@@ -358,6 +371,9 @@ void FlipperConnectionManagerImpl::requestSignedCertFromFlipper() {
} }
gettingCert->complete(); gettingCert->complete();
log("Certificate exchange complete."); log("Certificate exchange complete.");
// TODO: Use Certificate provider get Certificates
// `certProvider_->getCertificates("path", "device");`
// Disconnect after message sending is complete. // Disconnect after message sending is complete.
// This will trigger a reconnect which should use the secure // This will trigger a reconnect which should use the secure
// channel. // channel.

View File

@@ -50,10 +50,14 @@ class FlipperConnectionManagerImpl : public FlipperConnectionManager {
std::unique_ptr<FlipperResponder> responder) override; std::unique_ptr<FlipperResponder> responder) override;
void reconnect(); void reconnect();
void setCertificateProvider(
const std::shared_ptr<FlipperCertificateProvider> provider) override;
std::shared_ptr<FlipperCertificateProvider> getCertificateProvider() override;
private: private:
bool isOpen_ = false; bool isOpen_ = false;
bool isStarted_ = false; bool isStarted_ = false;
std::shared_ptr<FlipperCertificateProvider> certProvider_ = nullptr;
Callbacks* callbacks_; Callbacks* callbacks_;
DeviceData deviceData_; DeviceData deviceData_;
std::shared_ptr<FlipperState> flipperState_; std::shared_ptr<FlipperState> flipperState_;

View File

@@ -40,6 +40,14 @@ class FlipperConnectionManagerMock : public FlipperConnectionManager {
messages.push_back(message); messages.push_back(message);
} }
void setCertificateProvider(
const std::shared_ptr<FlipperCertificateProvider> provider) override{};
std::shared_ptr<FlipperCertificateProvider> getCertificateProvider()
override {
return nullptr;
};
void onMessageReceived( void onMessageReceived(
const folly::dynamic& message, const folly::dynamic& message,
std::unique_ptr<FlipperResponder> responder) override { std::unique_ptr<FlipperResponder> responder) override {