Skip to content

Commit

Permalink
Manual conflict resolution for merge branch 'master' of https://githu…
Browse files Browse the repository at this point in the history
  • Loading branch information
gmarcosb committed Jun 22, 2022
2 parents 6bbaa11 + 5809552 commit 4fb736a
Show file tree
Hide file tree
Showing 6 changed files with 312 additions and 63 deletions.
90 changes: 72 additions & 18 deletions src/controller/java/AndroidDeviceControllerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <lib/support/CodeUtils.h>
#include <lib/support/JniReferences.h>
#include <lib/support/JniTypeWrappers.h>

#include <controller/CHIPDeviceControllerFactory.h>
#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
Expand All @@ -34,6 +35,7 @@
#include <lib/support/TestGroupData.h>
#include <lib/support/ThreadOperationalDataset.h>
#include <platform/KeyValueStoreManager.h>
#include <platform/android/CHIPP256KeypairBridge.h>

using namespace chip;
using namespace chip::Controller;
Expand All @@ -47,6 +49,12 @@ AndroidDeviceControllerWrapper::~AndroidDeviceControllerWrapper()
JniReferences::GetInstance().GetEnvForCurrentThread()->DeleteGlobalRef(mJavaObjectRef);
}
mController->Shutdown();

if (mKeypairBridge != nullptr)
{
chip::Platform::Delete(mKeypairBridge);
mKeypairBridge = nullptr;
}
}

void AndroidDeviceControllerWrapper::SetJavaObjectRef(JavaVM * vm, jobject obj)
Expand All @@ -65,7 +73,8 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew(
JavaVM * vm, jobject deviceControllerObj, chip::NodeId nodeId, const chip::CATValues & cats, chip::System::Layer * systemLayer,
chip::Inet::EndPointManager<Inet::TCPEndPoint> * tcpEndPointManager,
chip::Inet::EndPointManager<Inet::UDPEndPoint> * udpEndPointManager, AndroidOperationalCredentialsIssuerPtr opCredsIssuerPtr,
uint16_t listenPort, CHIP_ERROR * errInfoOnFailure)
jobject keypairDelegate, jbyteArray rootCertificate, jbyteArray intermediateCertificate, jbyteArray nodeOperationalCertificate,
jbyteArray ipkEpochKey, uint16_t listenPort, CHIP_ERROR * errInfoOnFailure)
{
if (errInfoOnFailure == nullptr)
{
Expand Down Expand Up @@ -93,6 +102,14 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew(

*errInfoOnFailure = CHIP_NO_ERROR;

JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
if (env == nullptr)
{
ChipLogError(Controller, "Failed to retrieve JNIEnv.");
*errInfoOnFailure = CHIP_ERROR_INCORRECT_STATE;
return nullptr;
}

std::unique_ptr<DeviceCommissioner> controller(new DeviceCommissioner());

if (!controller)
Expand Down Expand Up @@ -166,25 +183,53 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew(
}
MutableByteSpan rcacSpan(rcac.Get(), kMaxCHIPDERCertLength);

Crypto::P256Keypair ephemeralKey;
*errInfoOnFailure = ephemeralKey.Initialize();
if (*errInfoOnFailure != CHIP_NO_ERROR)
if (rootCertificate != nullptr && intermediateCertificate != nullptr && nodeOperationalCertificate != nullptr &&
keypairDelegate != nullptr)
{
return nullptr;
CHIPP256KeypairBridge * nativeKeypairBridge = wrapper->GetP256KeypairBridge();
nativeKeypairBridge->SetDelegate(keypairDelegate);
*errInfoOnFailure = nativeKeypairBridge->Initialize();
if (*errInfoOnFailure != CHIP_NO_ERROR)
{
return nullptr;
}

setupParams.operationalKeypair = nativeKeypairBridge;
setupParams.hasExternallyOwnedOperationalKeypair = true;

JniByteArray jniRcac(env, rootCertificate);
JniByteArray jniIcac(env, intermediateCertificate);
JniByteArray jniNoc(env, nodeOperationalCertificate);

setupParams.controllerRCAC = jniRcac.byteSpan();
setupParams.controllerICAC = jniIcac.byteSpan();
setupParams.controllerNOC = jniNoc.byteSpan();
}

*errInfoOnFailure = opCredsIssuer->GenerateNOCChainAfterValidation(nodeId, /* fabricId = */ 1, cats, ephemeralKey.Pubkey(),
rcacSpan, icacSpan, nocSpan);
if (*errInfoOnFailure != CHIP_NO_ERROR)
else
{
return nullptr;
Crypto::P256Keypair ephemeralKey;
*errInfoOnFailure = ephemeralKey.Initialize();
if (*errInfoOnFailure != CHIP_NO_ERROR)
{
return nullptr;
}
setupParams.operationalKeypair = &ephemeralKey;
setupParams.hasExternallyOwnedOperationalKeypair = false;

*errInfoOnFailure = opCredsIssuer->GenerateNOCChainAfterValidation(nodeId,
/* fabricId = */ 1, cats, ephemeralKey.Pubkey(),
rcacSpan, icacSpan, nocSpan);

if (*errInfoOnFailure != CHIP_NO_ERROR)
{
return nullptr;
}

setupParams.controllerRCAC = rcacSpan;
setupParams.controllerICAC = icacSpan;
setupParams.controllerNOC = nocSpan;
}

setupParams.operationalKeypair = &ephemeralKey;
setupParams.controllerRCAC = rcacSpan;
setupParams.controllerICAC = icacSpan;
setupParams.controllerNOC = nocSpan;

*errInfoOnFailure = DeviceControllerFactory::GetInstance().Init(initParams);
if (*errInfoOnFailure != CHIP_NO_ERROR)
{
Expand Down Expand Up @@ -216,10 +261,19 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew(
static_cast<unsigned>(fabricInfo->GetFabricIndex()));
ChipLogByteSpan(Support, compressedFabricIdSpan);

chip::ByteSpan defaultIpk = chip::GroupTesting::DefaultIpkValue::GetDefaultIpk();
chip::ByteSpan ipkSpan;
if (ipkEpochKey != nullptr)
{
JniByteArray jniIpk(env, ipkEpochKey);
ipkSpan = jniIpk.byteSpan();
}
else
{
ipkSpan = chip::GroupTesting::DefaultIpkValue::GetDefaultIpk();
}

*errInfoOnFailure = chip::Credentials::SetSingleIpkEpochKey(&wrapper->mGroupDataProvider, fabricInfo->GetFabricIndex(),
defaultIpk, compressedFabricIdSpan);
*errInfoOnFailure = chip::Credentials::SetSingleIpkEpochKey(&wrapper->mGroupDataProvider, fabricInfo->GetFabricIndex(), ipkSpan,
compressedFabricIdSpan);
if (*errInfoOnFailure != CHIP_NO_ERROR)
{
return nullptr;
Expand Down
53 changes: 49 additions & 4 deletions src/controller/java/AndroidDeviceControllerWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <controller/CHIPDeviceController.h>
#include <credentials/GroupDataProviderImpl.h>
#include <lib/support/TimeUtils.h>
#include <platform/android/CHIPP256KeypairBridge.h>
#include <platform/internal/DeviceNetworkInfo.h>

#include "AndroidOperationalCredentialsIssuer.h"
Expand All @@ -46,6 +47,20 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel
jobject JavaObjectRef() { return mJavaObjectRef; }
jlong ToJNIHandle();

/**
* Returns a CHIPP256KeypairBridge which can be used to delegate signing operations
* to a KeypairDelegate in the Java layer. Note that this will always return a pointer
* to the same instance, once initialized.
*/
CHIPP256KeypairBridge * GetP256KeypairBridge()
{
if (mKeypairBridge == nullptr)
{
mKeypairBridge = chip::Platform::New<CHIPP256KeypairBridge>();
}
return mKeypairBridge;
}

void CallJavaMethod(const char * methodName, jint argument);
CHIP_ERROR InitializeOperationalCredentialsIssuer();

Expand All @@ -72,12 +87,41 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel

using AndroidOperationalCredentialsIssuerPtr = std::unique_ptr<chip::Controller::AndroidOperationalCredentialsIssuer>;

/**
* Initializes a new CHIPDeviceController using the given parameters, and returns a pointer to the
* AndroidDeviceControllerWrapper that holds the underlying controller.
*
* If the keypairDelegate is provided, then the rootCertificate, nodeOperationalCertificate, and
* ipkEpochKey must also be specified. If no operational credentials are specified here, then an
* ephemeral signing configuration will be generated for you.
*
* If there are any errors during the initialization of this controller, then a nullptr will be
* returned.
*
* @param[in] vm the JavaVM
* @param[in] deviceControllerObj a reference to the Java ChipDeviceController
* @param[in] nodeId the local node ID to use for this controller instance
* @param[in] cats the set of CASE authenticated tags
* @param[in] systemLayer a pointer to the System::Layer instance
* @param[in] tcpEndpointManager a pointer to a Inet::EndPointManager for TCP connections
* @param[in] udpEndpointManager a pointer to a Inet::EndPointManager for UDP connections
* @param[in] opCredsIssuer a pointer to an issuer for Android operational credentials
* @param[in] keypairDelegate a pointer to a Java KeypairDelegate implementation.
* @param[in] rootCertificate an X.509 DER-encoded trusted root certificate for this node
* @param[in] intermediateCertificate an X.509 DER-encoded intermediate certificate for this node
* @param[in] nodeOperationalCertificate an X.509 DER-encoded operational certificate for this node
* @param[in] ipkEpochKey the IPK epoch key to use for this node
* @param[in] listenPort the UDP port to listen on
* @param[out] errInfoOnFailure a pointer to a CHIP_ERROR that will be populated if this method returns nullptr
*/
static AndroidDeviceControllerWrapper * AllocateNew(JavaVM * vm, jobject deviceControllerObj, chip::NodeId nodeId,
const chip::CATValues & cats, chip::System::Layer * systemLayer,
chip::Inet::EndPointManager<chip::Inet::TCPEndPoint> * tcpEndPointManager,
chip::Inet::EndPointManager<chip::Inet::UDPEndPoint> * udpEndPointManager,
AndroidOperationalCredentialsIssuerPtr opCredsIssuer, uint16_t listenPort,
CHIP_ERROR * errInfoOnFailure);
AndroidOperationalCredentialsIssuerPtr opCredsIssuer,
jobject keypairDelegate, jbyteArray rootCertificate,
jbyteArray intermediateCertificate, jbyteArray nodeOperationalCertificate,
jbyteArray ipkEpochKey, uint16_t listenPort, CHIP_ERROR * errInfoOnFailure);

private:
using ChipDeviceControllerPtr = std::unique_ptr<chip::Controller::DeviceCommissioner>;
Expand All @@ -87,8 +131,9 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel
// TODO: This may need to be injected as a GroupDataProvider*
chip::Credentials::GroupDataProviderImpl mGroupDataProvider;

JavaVM * mJavaVM = nullptr;
jobject mJavaObjectRef = nullptr;
JavaVM * mJavaVM = nullptr;
jobject mJavaObjectRef = nullptr;
CHIPP256KeypairBridge * mKeypairBridge = nullptr;

// These fields allow us to release the string/byte array memory later.
jstring ssidStr = nullptr;
Expand Down
71 changes: 46 additions & 25 deletions src/controller/java/CHIPDeviceController-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ using namespace chip::Credentials;

static void * IOThreadMain(void * arg);
static CHIP_ERROR N2J_PaseVerifierParams(JNIEnv * env, jlong setupPincode, jbyteArray pakeVerifier, jobject & outParams);
static CHIP_ERROR N2J_NetworkLocation(JNIEnv * env, jstring ipAddress, jint port, jobject & outLocation);
static CHIP_ERROR N2J_NetworkLocation(JNIEnv * env, jstring ipAddress, jint port, jint interfaceIndex, jobject & outLocation);
static CHIP_ERROR GetChipPathIdValue(jobject chipPathId, uint32_t wildcardValue, uint32_t & outValue);
static CHIP_ERROR ParseAttributePathList(jobject attributePathList,
std::vector<app::AttributePathParams> & outAttributePathParamsList);
Expand All @@ -87,6 +87,8 @@ pthread_t sIOThread = PTHREAD_NULL;

jclass sChipDeviceControllerExceptionCls = NULL;

const char * PARAMS_CLASS = "()Lchip/devicecontroller/ControllerParams;";

} // namespace

// NOTE: Remote device ID is in sync with the echo server device id
Expand Down Expand Up @@ -164,17 +166,44 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self, jobject contr

// Retrieve initialization params.
jmethodID getUdpListenPort;
err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getUdpListenPort",
"()Lchip/devicecontroller/ControllerParams;", &getUdpListenPort);
err = chip::JniReferences::GetInstance().FindMethod(
env, controllerParams, "getUdpListenPort", PARAMS_CLASS, &getUdpListenPort);
SuccessOrExit(err);

jmethodID getKeypairDelegate;
err = chip::JniReferences::GetInstance().FindMethod(
env, controllerParams, "getKeypairDelegate", PARAMS_CLASS, &getKeypairDelegate);

jmethodID getRootCertificate;
err = chip::JniReferences::GetInstance().FindMethod(
env, controllerParams, "getRootCertificate", PARAMS_CLASS, &getRootCertificate);

jmethodID getIntermediateCertificate;
err = chip::JniReferences::GetInstance().FindMethod(
env, controllerParams, "getIntermediateCertificate", PARAMS_CLASS, &getIntermediateCertificate);

jmethodID getOperationalCertificate;
err = chip::JniReferences::GetInstance().FindMethod(
env, controllerParams, "getOperationalCertificate", PARAMS_CLASS, &getOperationalCertificate);

jmethodID getIpk;
err = chip::JniReferences::GetInstance().FindMethod(
env, controllerParams, "getIpk", PARAMS_CLASS, &getIpk);

{
uint16_t listenPort = env->CallIntMethod(controllerParams, getUdpListenPort);
jobject keypairDelegate = env->CallObjectMethod(controllerParams, getKeypairDelegate);
jbyteArray rootCertificate = (jbyteArray)env->CallObjectMethod(controllerParams, getRootCertificate);
jbyteArray intermediateCertificate = (jbyteArray)env->CallObjectMethod(controllerParams, getIntermediateCertificate);
jbyteArray operationalCertificate = (jbyteArray)env->CallObjectMethod(controllerParams, getOperationalCertificate);
jbyteArray ipk = (jbyteArray)env->CallObjectMethod(controllerParams, getIpk);

std::unique_ptr<chip::Controller::AndroidOperationalCredentialsIssuer> opCredsIssuer(
new chip::Controller::AndroidOperationalCredentialsIssuer());
wrapper = AndroidDeviceControllerWrapper::AllocateNew(
sJVM, self, kLocalDeviceId, chip::kUndefinedCATs, &DeviceLayer::SystemLayer(), DeviceLayer::TCPEndPointManager(),
DeviceLayer::UDPEndPointManager(), std::move(opCredsIssuer), listenPort, &err);
DeviceLayer::UDPEndPointManager(), std::move(opCredsIssuer), keypairDelegate, rootCertificate, intermediateCertificate,
operationalCertificate, ipk, listenPort, &err);
SuccessOrExit(err);
}

Expand Down Expand Up @@ -278,16 +307,13 @@ JNI_METHOD(void, pairDeviceWithAddress)

ChipLogProgress(Controller, "pairDeviceWithAddress() called");

Inet::IPAddress addr;
JniUtfString addrJniString(env, address);
VerifyOrReturn(Inet::IPAddress::FromString(addrJniString.c_str(), addr),
ChipLogError(Controller, "Failed to parse IP address."),
JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, CHIP_ERROR_INVALID_ARGUMENT));

RendezvousParameters rendezvousParams = RendezvousParameters()
.SetDiscriminator(discriminator)
.SetSetupPINCode(pinCode)
.SetPeerAddress(Transport::PeerAddress::UDP(addr, port));
RendezvousParameters rendezvousParams =
RendezvousParameters()
.SetDiscriminator(discriminator)
.SetSetupPINCode(pinCode)
.SetPeerAddress(Transport::PeerAddress::UDP(const_cast<char *>(addrJniString.c_str()), port));
CommissioningParameters commissioningParams = CommissioningParameters();
if (csrNonce != nullptr)
{
Expand Down Expand Up @@ -533,26 +559,21 @@ JNI_METHOD(jobject, getNetworkLocation)(JNIEnv * env, jobject self, jlong handle
chip::DeviceLayer::StackLock lock;
AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle);

chip::Inet::IPAddress addr;
uint16_t port;
Transport::PeerAddress addr;
jobject networkLocation;
char addrStr[50];

CHIP_ERROR err =
wrapper->Controller()->GetPeerAddressAndPort(PeerId()
.SetCompressedFabricId(wrapper->Controller()->GetCompressedFabricId())
.SetNodeId(static_cast<chip::NodeId>(deviceId)),
addr, port);

CHIP_ERROR err = wrapper->Controller()->GetPeerAddress(static_cast<chip::NodeId>(deviceId), addr);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "Failed to get device address.");
JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err);
}

addr.ToString(addrStr);
addr.GetIPAddress().ToString(addrStr);

err = N2J_NetworkLocation(env, env->NewStringUTF(addrStr), static_cast<jint>(port), networkLocation);
err = N2J_NetworkLocation(env, env->NewStringUTF(addrStr), static_cast<jint>(addr.GetPort()),
static_cast<jint>(addr.GetInterface().GetPlatformInterface()), networkLocation);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "Failed to create NetworkLocation");
Expand Down Expand Up @@ -1069,7 +1090,7 @@ CHIP_ERROR N2J_PaseVerifierParams(JNIEnv * env, jlong setupPincode, jbyteArray p
return err;
}

CHIP_ERROR N2J_NetworkLocation(JNIEnv * env, jstring ipAddress, jint port, jobject & outLocation)
CHIP_ERROR N2J_NetworkLocation(JNIEnv * env, jstring ipAddress, jint port, jint interfaceIndex, jobject & outLocation)
{
CHIP_ERROR err = CHIP_NO_ERROR;
jmethodID constructor;
Expand All @@ -1080,10 +1101,10 @@ CHIP_ERROR N2J_NetworkLocation(JNIEnv * env, jstring ipAddress, jint port, jobje
SuccessOrExit(err);

env->ExceptionClear();
constructor = env->GetMethodID(locationClass, "<init>", "(Ljava/lang/String;I)V");
constructor = env->GetMethodID(locationClass, "<init>", "(Ljava/lang/String;II)V");
VerifyOrExit(constructor != nullptr, err = CHIP_JNI_ERROR_METHOD_NOT_FOUND);

outLocation = (jobject) env->NewObject(locationClass, constructor, ipAddress, port);
outLocation = (jobject) env->NewObject(locationClass, constructor, ipAddress, port, interfaceIndex);

VerifyOrExit(!env->ExceptionCheck(), err = CHIP_JNI_ERROR_EXCEPTION_THROWN);
exit:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,16 @@ public static void loadJni() {
return;
}

/**
* Returns a new {@link ChipDeviceController} with default parameters.
*/
public ChipDeviceController() {
this(new ControllerParams());
this(ControllerParams.newBuilder().build());
}

/**
* Returns a new {@link ChipDeviceController} with the specified parameters.
*/
public ChipDeviceController(ControllerParams params) {
deviceControllerPtr = newDeviceController(params);
}
Expand Down
Loading

0 comments on commit 4fb736a

Please sign in to comment.