Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Commissioner attestation delegate should be able to override success and failure #23173

Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
11b5724
[Android] Added mechanism to override device attestation failure base…
panliming-tuya Oct 13, 2022
ea40f1a
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Oct 14, 2022
5ed16c0
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Oct 14, 2022
d36248a
platform jar keep name of method parameters
panliming-tuya Oct 14, 2022
1c38401
Restyled by whitespace
restyled-commits Oct 14, 2022
587ac5f
Restyled by google-java-format
restyled-commits Oct 14, 2022
66bedd6
Restyled by clang-format
restyled-commits Oct 14, 2022
d9be2ba
Restyled by gn
restyled-commits Oct 14, 2022
afdf205
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Oct 16, 2022
e8f0495
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Oct 18, 2022
640ddbd
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Oct 18, 2022
3c4f499
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Oct 20, 2022
48ce640
fix copyright
panliming-tuya Oct 20, 2022
eb95edd
Merge branch 'additional-verification-after-attestation' of https://g…
panliming-tuya Oct 20, 2022
5e8723b
fix and modify comments
panliming-tuya Oct 20, 2022
79024b4
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Oct 21, 2022
2270c9d
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Oct 28, 2022
47f079e
Use setters instead of adding parameters to methods
panliming-tuya Oct 28, 2022
27a3862
fix NetworkCredentials NPE
panliming-tuya Oct 28, 2022
beb066a
Do not expose deviceController raw pointer
panliming-tuya Oct 28, 2022
f9d3dd5
add sample
panliming-tuya Oct 28, 2022
9e6a181
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Nov 2, 2022
38b0c0c
Create AttestationTrustStoreBridge when we know we have PAA certs.
panliming-tuya Nov 3, 2022
0ee733e
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Nov 3, 2022
8481cde
fix jni method
panliming-tuya Nov 3, 2022
e6211db
fix certs loss of scope and add some comments
panliming-tuya Nov 7, 2022
3bacfe3
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Nov 7, 2022
3b40467
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Nov 8, 2022
b26afb9
implement destructor
panliming-tuya Nov 8, 2022
27584d6
fix destructor crash
panliming-tuya Nov 8, 2022
a654ede
revoke vscode setting change
panliming-tuya Nov 8, 2022
6db2e8b
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Nov 9, 2022
52c5c30
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Nov 15, 2022
4958adb
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Nov 18, 2022
213164e
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Nov 18, 2022
a610fa5
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Nov 21, 2022
59c8ca6
Restyled by whitespace
panliming-tuya Nov 21, 2022
3811015
Restyled by google-java-format
panliming-tuya Nov 21, 2022
8c01083
Restyled by clang-format
panliming-tuya Nov 21, 2022
5dcbae5
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Dec 13, 2022
8837adf
fix conflict
panliming-tuya Dec 15, 2022
212dc10
add unit of failSafeExpiryTimeout
panliming-tuya Dec 15, 2022
9d41d26
add sample code
panliming-tuya Dec 15, 2022
37f760a
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Dec 15, 2022
747645d
Restyled by whitespace
panliming-tuya Dec 15, 2022
17348b2
Restyled by google-java-format
panliming-tuya Dec 15, 2022
e5972ae
Restyled by clang-format
panliming-tuya Dec 15, 2022
9d915df
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Dec 19, 2022
993b5cf
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Jan 4, 2023
f069618
fix comments
panliming-tuya Jan 4, 2023
f485757
remove android attestation trust store
panliming-tuya Jan 4, 2023
c027231
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Jan 4, 2023
2b094c8
restyle
panliming-tuya Jan 4, 2023
9ef054d
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Jan 6, 2023
e2448ec
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Jan 7, 2023
8b14201
Merge branch 'master' into additional-verification-after-attestation
panliming-tuya Jan 10, 2023
9e6211b
Fix compile error in java-matter-controller
yufengwangca Jan 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,19 @@
package com.google.chip.chiptool.provisioning

import android.bluetooth.BluetoothGatt
import android.content.DialogInterface
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.AttestationInfo
import chip.devicecontroller.DeviceAttestationDelegate.DeviceAttestationCompletionCallback
import chip.devicecontroller.DeviceAttestationDelegate.DeviceAttestationFailureCallback
import chip.devicecontroller.NetworkCredentials
import com.google.chip.chiptool.NetworkCredentialsParcelable
import com.google.chip.chiptool.ChipClient
Expand All @@ -38,7 +43,9 @@ import com.google.chip.chiptool.util.DeviceIdUtil
import com.google.chip.chiptool.util.FragmentUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Runnable
import kotlinx.coroutines.launch
import java.lang.IllegalArgumentException

@ExperimentalCoroutinesApi
class DeviceProvisioningFragment : Fragment() {
Expand Down Expand Up @@ -132,7 +139,30 @@ class DeviceProvisioningFragment : Fragment() {
if (thread != null) {
network = NetworkCredentials.forThread(NetworkCredentials.ThreadCredentials(thread.operationalDataset))
}

deviceController.setDeviceAttestationFailureCallback(600
panliming-tuya marked this conversation as resolved.
Show resolved Hide resolved
) { devicePtr, errorCode ->
Log.i(TAG, "Device attestation errorCode: $errorCode")
requireActivity().runOnUiThread(Runnable {
val alertDialog: AlertDialog? = activity?.let {
val builder = AlertDialog.Builder(it)
builder.apply {
setPositiveButton("Continue",
DialogInterface.OnClickListener { dialog, id ->
deviceController.continueCommissioning(devicePtr, true)
})
setNegativeButton("No",
DialogInterface.OnClickListener { dialog, id ->
deviceController.continueCommissioning(devicePtr, false)
})
}
builder.setTitle("Device Attestation")
builder.setMessage("Device Attestation failed for device under commissioning. Do you wish to continue pairing?")
panliming-tuya marked this conversation as resolved.
Show resolved Hide resolved
// Create the AlertDialog
builder.create()
}
alertDialog?.show()
})
}
deviceController.pairDevice(gatt, connId, deviceId, deviceInfo.setupPinCode, network)
DeviceIdUtil.setNextAvailableId(requireContext(), deviceId + 1)
}
Expand Down
97 changes: 91 additions & 6 deletions src/controller/java/AndroidDeviceControllerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@ AndroidDeviceControllerWrapper::~AndroidDeviceControllerWrapper()
chip::Platform::Delete(mKeypairBridge);
mKeypairBridge = nullptr;
}
if (mDeviceAttestationDelegateBridge != nullptr)
{
delete mDeviceAttestationDelegateBridge;
mDeviceAttestationDelegateBridge = nullptr;
}
if (mDeviceAttestationVerifier != nullptr)
{
delete mDeviceAttestationVerifier;
mDeviceAttestationVerifier = nullptr;
}
if (mAttestationTrustStoreBridge != nullptr)
{
delete mAttestationTrustStoreBridge;
mAttestationTrustStoreBridge = nullptr;
}
}

void AndroidDeviceControllerWrapper::SetJavaObjectRef(JavaVM * vm, jobject obj)
Expand All @@ -77,8 +92,9 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew(
chip::System::Layer * systemLayer, chip::Inet::EndPointManager<Inet::TCPEndPoint> * tcpEndPointManager,
chip::Inet::EndPointManager<Inet::UDPEndPoint> * udpEndPointManager, AndroidOperationalCredentialsIssuerPtr opCredsIssuerPtr,
jobject keypairDelegate, jbyteArray rootCertificate, jbyteArray intermediateCertificate, jbyteArray nodeOperationalCertificate,
jbyteArray ipkEpochKey, uint16_t listenPort, uint16_t controllerVendorId, uint16_t failsafeTimerSeconds,
bool attemptNetworkScanWiFi, bool attemptNetworkScanThread, bool skipCommissioningComplete, CHIP_ERROR * errInfoOnFailure)
jbyteArray ipkEpochKey, jobject paaCertsArrayList, jobject cdCertsArrayList, uint16_t listenPort, uint16_t controllerVendorId,
panliming-tuya marked this conversation as resolved.
Show resolved Hide resolved
uint16_t failsafeTimerSeconds, bool attemptNetworkScanWiFi, bool attemptNetworkScanThread, bool skipCommissioningComplete,
CHIP_ERROR * errInfoOnFailure)
{
if (errInfoOnFailure == nullptr)
{
Expand Down Expand Up @@ -131,9 +147,77 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew(
chip::Controller::AndroidOperationalCredentialsIssuer * opCredsIssuer = wrapper->mOpCredsIssuer.get();

// Initialize device attestation verifier
// TODO: Replace testingRootStore with a AttestationTrustStore that has the necessary official PAA roots available
const chip::Credentials::AttestationTrustStore * testingRootStore = chip::Credentials::GetTestAttestationTrustStore();
SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore));
const Credentials::AttestationTrustStore * trustStore;
CHIP_ERROR err = CHIP_NO_ERROR;
if (paaCertsArrayList)
{
jint listSize;
JniReferences::GetInstance().GetListSize(paaCertsArrayList, listSize);
std::vector<std::vector<uint8_t>> paaCerts;
for (uint8_t i = 0; i < listSize; i++)
panliming-tuya marked this conversation as resolved.
Show resolved Hide resolved
{
jobject paaCertObj = nullptr;
err = JniReferences::GetInstance().GetListItem(paaCertsArrayList, i, paaCertObj);
if (err != CHIP_NO_ERROR)
{
*errInfoOnFailure = err;
return nullptr;
}
JniByteArray paaCert(env, static_cast<jbyteArray>(paaCertObj));
// Make a copy of the cert so that it does not loss of scope.
paaCerts.push_back(std::vector<uint8_t>(paaCert.byteSpan().begin(), paaCert.byteSpan().end()));
}
wrapper->mAttestationTrustStoreBridge = new AttestationTrustStoreBridge(paaCerts);
if (wrapper->mAttestationTrustStoreBridge == nullptr)
{
ChipLogError(Controller, "Failed to create AttestationTrustStoreBridge");
*errInfoOnFailure = CHIP_ERROR_NO_MEMORY;
return nullptr;
}
trustStore = wrapper->mAttestationTrustStoreBridge;
}
else
{
trustStore = chip::Credentials::GetTestAttestationTrustStore();
}
wrapper->mDeviceAttestationVerifier = new Credentials::DefaultDACVerifier(trustStore);
if (wrapper->mDeviceAttestationVerifier == nullptr)
{
ChipLogError(Controller, "Init failure while creating the device attestation verifier");
*errInfoOnFailure = CHIP_ERROR_NO_MEMORY;
return nullptr;
}
if (cdCertsArrayList)
{
auto cdTrustStore = wrapper->mDeviceAttestationVerifier->GetCertificationDeclarationTrustStore();
if (cdTrustStore == nullptr)
{
ChipLogError(Controller, "Failed to get cd trust store");
*errInfoOnFailure = CHIP_ERROR_NO_MEMORY;
return nullptr;
}
jint listSize;
JniReferences::GetInstance().GetListSize(cdCertsArrayList, listSize);
for (uint8_t i = 0; i < listSize; i++)
panliming-tuya marked this conversation as resolved.
Show resolved Hide resolved
{
jobject cdCertObj = nullptr;
err = JniReferences::GetInstance().GetListItem(cdCertsArrayList, i, cdCertObj);
if (err != CHIP_NO_ERROR)
{
*errInfoOnFailure = err;
return nullptr;
}
JniByteArray cdCert(env, static_cast<jbyteArray>(cdCertObj));
std::vector<uint8_t> cdCertCopy(cdCert.byteSpan().begin(), cdCert.byteSpan().end());
chip::ByteSpan trustedKey = chip::ByteSpan(cdCertCopy.data(), cdCertCopy.size());
err = cdTrustStore->AddTrustedKey(trustedKey);
if (err != CHIP_NO_ERROR)
{
*errInfoOnFailure = err;
return nullptr;
}
}
}

chip::Controller::FactoryInitParams initParams;
chip::Controller::SetupParams setupParams;
Expand All @@ -152,6 +236,7 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew(
setupParams.operationalCredentialsDelegate = opCredsIssuer;
setupParams.defaultCommissioner = &wrapper->mAutoCommissioner;
initParams.fabricIndependentStorage = wrapperStorage;
setupParams.deviceAttestationVerifier = wrapper->mDeviceAttestationVerifier;

wrapper->mGroupDataProvider.SetStorageDelegate(wrapperStorage);

Expand All @@ -162,7 +247,7 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew(
params.SetSkipCommissioningComplete(skipCommissioningComplete);
wrapper->UpdateCommissioningParameters(params);

CHIP_ERROR err = wrapper->mGroupDataProvider.Init();
err = wrapper->mGroupDataProvider.Init();
if (err != CHIP_NO_ERROR)
{
*errInfoOnFailure = err;
Expand Down
27 changes: 25 additions & 2 deletions src/controller/java/AndroidDeviceControllerWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include <platform/internal/DeviceNetworkInfo.h>

#include "AndroidOperationalCredentialsIssuer.h"
#include "AttestationTrustStoreBridge.h"
#include "DeviceAttestationDelegateBridge.h"

/**
* This class contains all relevant information for the JNI view of CHIPDeviceController
Expand Down Expand Up @@ -149,14 +151,31 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel
chip::Inet::EndPointManager<chip::Inet::UDPEndPoint> * udpEndPointManager,
AndroidOperationalCredentialsIssuerPtr opCredsIssuer, jobject keypairDelegate, jbyteArray rootCertificate,
jbyteArray intermediateCertificate, jbyteArray nodeOperationalCertificate, jbyteArray ipkEpochKey,
uint16_t listenPort, uint16_t controllerVendorId, uint16_t failsafeTimerSeconds, bool attemptNetworkScanWiFi,
bool attemptNetworkScanThread, bool skipCommissioningComplete, CHIP_ERROR * errInfoOnFailure);
jobject paaCertsArrayList, jobject cdCertsArrayList, uint16_t listenPort, uint16_t controllerVendorId,
uint16_t failsafeTimerSeconds, bool attemptNetworkScanWiFi, bool attemptNetworkScanThread,
bool skipCommissioningComplete, CHIP_ERROR * errInfoOnFailure);

chip::Controller::AndroidOperationalCredentialsIssuer * GetAndroidOperationalCredentialsIssuer()
{
return mOpCredsIssuer.get();
}

void SetDeviceAttestationDelegateBridge(DeviceAttestationDelegateBridge * deviceAttestationDelegateBridge)
{
mDeviceAttestationDelegateBridge = deviceAttestationDelegateBridge;
}

DeviceAttestationDelegateBridge * GetDeviceAttestationDelegateBridge() { return mDeviceAttestationDelegateBridge; }

void ClearDeviceAttestationDelegateBridge()
{
if (mDeviceAttestationDelegateBridge != nullptr)
{
delete mDeviceAttestationDelegateBridge;
panliming-tuya marked this conversation as resolved.
Show resolved Hide resolved
mDeviceAttestationDelegateBridge = nullptr;
}
}

private:
using ChipDeviceControllerPtr = std::unique_ptr<chip::Controller::DeviceCommissioner>;

Expand Down Expand Up @@ -187,6 +206,10 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel

chip::Credentials::PartialDACVerifier mPartialDACVerifier;

DeviceAttestationDelegateBridge * mDeviceAttestationDelegateBridge = nullptr;
AttestationTrustStoreBridge * mAttestationTrustStoreBridge = nullptr;
chip::Credentials::DeviceAttestationVerifier * mDeviceAttestationVerifier = nullptr;

AndroidDeviceControllerWrapper(ChipDeviceControllerPtr controller, AndroidOperationalCredentialsIssuerPtr opCredsIssuer) :
mController(std::move(controller)), mOpCredsIssuer(std::move(opCredsIssuer))
{}
Expand Down
54 changes: 54 additions & 0 deletions src/controller/java/AttestationTrustStoreBridge.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
*
* Copyright (c) 2022 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "AttestationTrustStoreBridge.h"
#include <lib/support/CodeUtils.h>

AttestationTrustStoreBridge::~AttestationTrustStoreBridge()
{
if (!mPaaCerts.empty())
{
for (auto paaCert : mPaaCerts)
{
paaCert.clear();
paaCert.shrink_to_fit();
}
mPaaCerts.clear();
mPaaCerts.shrink_to_fit();
}
}

CHIP_ERROR AttestationTrustStoreBridge::GetProductAttestationAuthorityCert(const chip::ByteSpan & skid,
chip::MutableByteSpan & outPaaDerBuffer) const
{
VerifyOrReturnError(skid.size() == chip::Crypto::kSubjectKeyIdentifierLength, CHIP_ERROR_INVALID_ARGUMENT);

for (auto paaCert : mPaaCerts)
{
chip::ByteSpan candidate = chip::ByteSpan(paaCert.data(), paaCert.size());
uint8_t skidBuf[chip::Crypto::kSubjectKeyIdentifierLength] = { 0 };
chip::MutableByteSpan candidateSkidSpan{ skidBuf };
VerifyOrReturnError(CHIP_NO_ERROR == chip::Crypto::ExtractSKIDFromX509Cert(candidate, candidateSkidSpan),
CHIP_ERROR_INTERNAL);
if (skid.data_equal(candidateSkidSpan))
{
// Found a match
return CopySpanToMutableSpan(candidate, outPaaDerBuffer);
}
}
return CHIP_ERROR_CA_CERT_NOT_FOUND;
}
panliming-tuya marked this conversation as resolved.
Show resolved Hide resolved
32 changes: 32 additions & 0 deletions src/controller/java/AttestationTrustStoreBridge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
*
* Copyright (c) 2022 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
#include <vector>

class AttestationTrustStoreBridge : public chip::Credentials::AttestationTrustStore
{
public:
AttestationTrustStoreBridge(std::vector<std::vector<uint8_t>> paaCerts) : mPaaCerts(paaCerts) {}
~AttestationTrustStoreBridge();

CHIP_ERROR GetProductAttestationAuthorityCert(const chip::ByteSpan & skid,
chip::MutableByteSpan & outPaaDerBuffer) const override;

private:
std::vector<std::vector<uint8_t>> mPaaCerts;
};
10 changes: 9 additions & 1 deletion src/controller/java/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ shared_library("jni") {
"AndroidDeviceControllerWrapper.h",
"AndroidOperationalCredentialsIssuer.cpp",
"AndroidOperationalCredentialsIssuer.h",
"AttestationTrustStoreBridge.cpp",
"AttestationTrustStoreBridge.h",
"BaseCHIPCluster-JNI.cpp",
"CHIPAttributeTLVValueDecoder.h",
"CHIPDefaultCallbacks.cpp",
"CHIPDefaultCallbacks.h",
"CHIPDeviceController-JNI.cpp",
"DeviceAttestationDelegateBridge.cpp",
"DeviceAttestationDelegateBridge.h",
"zap-generated/CHIPAttributeTLVValueDecoder.cpp",
"zap-generated/CHIPClustersWrite-JNI.cpp",
"zap-generated/CHIPEventTLVValueDecoder.cpp",
Expand Down Expand Up @@ -101,6 +105,7 @@ android_library("java") {
"src/chip/devicecontroller/ChipDeviceController.java",
"src/chip/devicecontroller/ChipDeviceControllerException.java",
"src/chip/devicecontroller/ControllerParams.java",
"src/chip/devicecontroller/DeviceAttestationDelegate.java",
"src/chip/devicecontroller/DiscoveredDevice.java",
"src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java",
"src/chip/devicecontroller/KeypairDelegate.java",
Expand Down Expand Up @@ -143,7 +148,10 @@ android_library("java") {
data_deps += [ "${chip_root}/build/chip/java:shared_cpplib" ]
}

javac_flags = [ "-Xlint:deprecation" ]
javac_flags = [
"-Xlint:deprecation",
"-parameters", # Store infomation about method parameters
]

# TODO: add classpath support (we likely need to add something like
# ..../platforms/android-21/android.jar to access BLE items)
Expand Down
Loading