From 4d34512a35d8aca1ba728eef9963dca219f3f240 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Mon, 1 Aug 2022 23:12:31 -0700 Subject: [PATCH 01/12] Draft: Add Java callbacks for NOC Generation --- src/controller/CHIPDeviceController.cpp | 15 +-- src/controller/CHIPDeviceController.h | 8 +- .../ExampleOperationalCredentialsIssuer.cpp | 3 +- .../ExampleOperationalCredentialsIssuer.h | 4 +- .../OperationalCredentialsDelegate.h | 3 +- .../java/AndroidDeviceControllerWrapper.cpp | 9 +- .../java/AndroidDeviceControllerWrapper.h | 15 ++- .../AndroidOperationalCredentialsIssuer.cpp | 93 ++++++++++++++++++- .../AndroidOperationalCredentialsIssuer.h | 25 ++++- .../java/CHIPDeviceController-JNI.cpp | 85 ++++++++++++++++- .../ChipDeviceController.java | 52 ++++++++++- .../devicecontroller/ControllerParams.java | 47 ++++++---- src/controller/python/OpCredsBinding.cpp | 8 +- .../CHIP/MTROperationalCredentialsDelegate.h | 5 +- .../CHIP/MTROperationalCredentialsDelegate.mm | 5 +- 15 files changed, 328 insertions(+), 49 deletions(-) diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 11ea5dca6b5e55..730f60fde76d26 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1246,12 +1246,12 @@ CHIP_ERROR DeviceCommissioner::IssueNOCChain(const ByteSpan & NOCSRElements, Nod // Note: we don't have attestationSignature, attestationChallenge, DAC, PAI so we are just providing an empty ByteSpan // for those arguments. return mOperationalCredentialsDelegate->GenerateNOCChain(NOCSRElements, ByteSpan(), ByteSpan(), ByteSpan(), ByteSpan(), - ByteSpan(), callback); + ByteSpan(), ByteSpan(), callback); } CHIP_ERROR DeviceCommissioner::ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, - const ByteSpan & AttestationSignature, const ByteSpan & dac, const ByteSpan & pai, - const ByteSpan & csrNonce) + const ByteSpan & AttestationSignature, const ByteSpan & attestationElements, + const ByteSpan & dac, const ByteSpan & pai, const ByteSpan & csrNonce) { MATTER_TRACE_EVENT_SCOPE("ProcessOpCSR", "DeviceCommissioner"); VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE); @@ -1273,7 +1273,7 @@ CHIP_ERROR DeviceCommissioner::ProcessCSR(DeviceProxy * proxy, const ByteSpan & } return mOperationalCredentialsDelegate->GenerateNOCChain(NOCSRElements, csrNonce, AttestationSignature, attestationChallenge, - dac, pai, &mDeviceNOCChainCallback); + attestationElements, dac, pai, &mDeviceNOCChainCallback); } CHIP_ERROR DeviceCommissioner::SendOperationalCertificate(DeviceProxy * device, const ByteSpan & nocCertBuf, @@ -2173,9 +2173,10 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio ChipLogError(Controller, "Unable to generate NOC chain parameters"); return CommissioningStageComplete(CHIP_ERROR_INVALID_ARGUMENT); } - CHIP_ERROR err = ProcessCSR(proxy, params.GetNOCChainGenerationParameters().Value().nocsrElements, - params.GetNOCChainGenerationParameters().Value().signature, params.GetDAC().Value(), - params.GetPAI().Value(), params.GetCSRNonce().Value()); + CHIP_ERROR err = + ProcessCSR(proxy, params.GetNOCChainGenerationParameters().Value().nocsrElements, + params.GetNOCChainGenerationParameters().Value().signature, params.GetAttestationElements().Value(), + params.GetDAC().Value(), params.GetPAI().Value(), params.GetCSRNonce().Value()); if (err != CHIP_NO_ERROR) { ChipLogError(Controller, "Unable to process Op CSR"); diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 8f04fe771ae5f0..aeaa5b588a5e70 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -799,13 +799,15 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, * * @param[in] proxy device proxy * @param[in] NOCSRElements CSR elements as per specifications section 11.22.5.6. NOCSR Elements. - * @param[in] AttestationSignature Cryptographic signature generated for all the above fields. + * @param[in] attestationSignature Cryptographic signature generated for all the above fields. + * @param[in] attestationElements   attestation elements portion of Attestation Response (raw TLV) * @param[in] dac device attestation certificate * @param[in] pai Product Attestation Intermediate certificate * @param[in] csrNonce certificate signing request nonce */ - CHIP_ERROR ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature, - const ByteSpan & dac, const ByteSpan & pai, const ByteSpan & csrNonce); + CHIP_ERROR ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & attestationSignature, + const ByteSpan & attestationElements, const ByteSpan & dac, const ByteSpan & pai, + const ByteSpan & csrNonce); /** * @brief diff --git a/src/controller/ExampleOperationalCredentialsIssuer.cpp b/src/controller/ExampleOperationalCredentialsIssuer.cpp index 14ad78463ce225..bcb70a147d22f1 100644 --- a/src/controller/ExampleOperationalCredentialsIssuer.cpp +++ b/src/controller/ExampleOperationalCredentialsIssuer.cpp @@ -184,7 +184,8 @@ CHIP_ERROR ExampleOperationalCredentialsIssuer::GenerateNOCChainAfterValidation( CHIP_ERROR ExampleOperationalCredentialsIssuer::GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, const ByteSpan & DAC, + const ByteSpan & attestationChallenge, + const ByteSpan & attestationElements, const ByteSpan & DAC, const ByteSpan & PAI, Callback::Callback * onCompletion) { diff --git a/src/controller/ExampleOperationalCredentialsIssuer.h b/src/controller/ExampleOperationalCredentialsIssuer.h index a85684cf6957e2..d3948ef0591b8f 100644 --- a/src/controller/ExampleOperationalCredentialsIssuer.h +++ b/src/controller/ExampleOperationalCredentialsIssuer.h @@ -56,8 +56,8 @@ class DLL_EXPORT ExampleOperationalCredentialsIssuer : public OperationalCredent ~ExampleOperationalCredentialsIssuer() override {} CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, - Callback::Callback * onCompletion) override; + const ByteSpan & attestationChallenge, const ByteSpan & attestationElements, const ByteSpan & DAC, + const ByteSpan & PAI, Callback::Callback * onCompletion) override; void SetNodeIdForNextNOCRequest(NodeId nodeId) override { diff --git a/src/controller/OperationalCredentialsDelegate.h b/src/controller/OperationalCredentialsDelegate.h index e34b728b1ee9da..9c14847ba142ac 100644 --- a/src/controller/OperationalCredentialsDelegate.h +++ b/src/controller/OperationalCredentialsDelegate.h @@ -55,6 +55,7 @@ class DLL_EXPORT OperationalCredentialsDelegate * @param[in] csrNonce CSR nonce as described in 6.4.6.1 * @param[in] attestationSignature Attestation signature as per specifications section 11.22.7.6. CSRResponse Command. * @param[in] attestationChallenge Attestation challenge as per 11.18.5.7 + * @param[in] attestationElements Attestation elements portion of Attestation Response (raw TLV) * @param[in] DAC Device attestation certificate received from the device being commissioned * @param[in] PAI Product Attestation Intermediate certificate * @param[in] onCompletion Callback handler to provide generated NOC chain to the caller of GenerateNOCChain() @@ -63,7 +64,7 @@ class DLL_EXPORT OperationalCredentialsDelegate */ virtual CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, const ByteSpan & attestationChallenge, - const ByteSpan & DAC, const ByteSpan & PAI, + const ByteSpan & attestationElements, const ByteSpan & DAC, const ByteSpan & PAI, Callback::Callback * onCompletion) = 0; /** diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index 6ccdb94fc2abfe..d4fd785cec1859 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -74,7 +74,7 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew( chip::Inet::EndPointManager * tcpEndPointManager, chip::Inet::EndPointManager * udpEndPointManager, AndroidOperationalCredentialsIssuerPtr opCredsIssuerPtr, jobject keypairDelegate, jbyteArray rootCertificate, jbyteArray intermediateCertificate, jbyteArray nodeOperationalCertificate, - jbyteArray ipkEpochKey, uint16_t listenPort, uint16_t controllerVendorId, uint16_t failsafeTimerSeconds, + jbyteArray ipkEpochKey, uint64_t adminSubject, uint16_t listenPort, uint16_t controllerVendorId, uint16_t failsafeTimerSeconds, bool attemptNetworkScanWiFi, bool attemptNetworkScanThread, CHIP_ERROR * errInfoOnFailure) { if (errInfoOnFailure == nullptr) @@ -156,6 +156,10 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew( params.SetFailsafeTimerSeconds(failsafeTimerSeconds); params.SetAttemptWiFiNetworkScan(attemptNetworkScanWiFi); params.SetAttemptThreadNetworkScan(attemptNetworkScanThread); + if (adminSubject != kUndefinedNodeId) + { + params.SetAdminSubject(adminSubject); + } wrapper->UpdateCommissioningParameters(params); CHIP_ERROR err = wrapper->mGroupDataProvider.Init(); @@ -237,6 +241,9 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew( setupParams.operationalKeypair = &ephemeralKey; setupParams.hasExternallyOwnedOperationalKeypair = false; + // TODO: make this conditional based upon state passed from java + opCredsIssuer->SetUseJavaCallbackForNOCRequest(true); + *errInfoOnFailure = opCredsIssuer->GenerateNOCChainAfterValidation(nodeId, /* fabricId = */ 1, cats, ephemeralKey.Pubkey(), rcacSpan, icacSpan, nocSpan); diff --git a/src/controller/java/AndroidDeviceControllerWrapper.h b/src/controller/java/AndroidDeviceControllerWrapper.h index e5809340fea39c..8616084a8dd1ad 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.h +++ b/src/controller/java/AndroidDeviceControllerWrapper.h @@ -75,6 +75,11 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel */ CHIP_ERROR UpdateCommissioningParameters(const chip::Controller::CommissioningParameters & params); + /** + * Update the CommissioningParameters used by the active device commissioner and set the NOC Chain + */ + CHIP_ERROR SetNOCChain(const chip::Controller::CommissioningParameters & params); + // DevicePairingDelegate implementation void OnStatusUpdate(chip::Controller::DevicePairingDelegate::Status status) override; void OnPairingComplete(CHIP_ERROR error) override; @@ -130,6 +135,7 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel * @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] adminSubject the adminSubject to use for AddNOC command * @param[in] listenPort the UDP port to listen on * @param[in] controllerVendorId the vendor ID identifying the controller * @param[in] failsafeTimerSeconds the failsafe timer in seconds @@ -143,8 +149,13 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel chip::Inet::EndPointManager * 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, CHIP_ERROR * errInfoOnFailure); + uint64_t adminSubject, uint16_t listenPort, uint16_t controllerVendorId, uint16_t failsafeTimerSeconds, + bool attemptNetworkScanWiFi, bool attemptNetworkScanThread, CHIP_ERROR * errInfoOnFailure); + + chip::Controller::AndroidOperationalCredentialsIssuer * GetAndroidOperationalCredentialsIssuer() + { + return mOpCredsIssuer.get(); + } private: using ChipDeviceControllerPtr = std::unique_ptr; diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp index 619fc4cb5b8d7b..ab75f11a981ff1 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp @@ -125,14 +125,103 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::GenerateNOCChainAfterValidation( CHIP_ERROR AndroidOperationalCredentialsIssuer::GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, const ByteSpan & DAC, + const ByteSpan & attestationChallenge, + const ByteSpan & attestationElements, const ByteSpan & DAC, const ByteSpan & PAI, Callback::Callback * onCompletion) +{ + if (mUseJavaCallbackForNOCRequest) + { + return CallbackGenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, attestationElements, DAC, + PAI, onCompletion); + } + else + { + return LocalGenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, attestationElements, DAC, + PAI, onCompletion); + } +} + +CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, + const ByteSpan & attestationSignature, + const ByteSpan & attestationChallenge, + const ByteSpan & attestationElements, const ByteSpan & DAC, + const ByteSpan & PAI, + Callback::Callback * onCompletion) +{ + jmethodID method; + CHIP_ERROR err = CHIP_NO_ERROR; + err = JniReferences::GetInstance().FindMethod(JniReferences::GetInstance().GetEnvForCurrentThread(), mJavaObjectRef, + "onNOCChainGenerationNeeded", "([B[B[B[B[B[B[B)V", &method); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Error invoking onNOCChainGenerationNeeded: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + mOnNOCCompletionCallback = onCompletion; + + JniReferences::GetInstance().GetEnvForCurrentThread()->ExceptionClear(); + + jbyteArray javaCsr; + JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), csrElements.data(), + csrElements.size(), javaCsr); + + jbyteArray javaCsrNonce; + JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), csrNonce.data(), + csrNonce.size(), javaCsrNonce); + + jbyteArray javaAttestationSignature; + JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationSignature.data(), + attestationSignature.size(), javaAttestationSignature); + + jbyteArray javaAttestationChallenge; + JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationChallenge.data(), + attestationChallenge.size(), javaAttestationChallenge); + + jbyteArray javaAttestationElements; + JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationElements.data(), + attestationElements.size(), javaAttestationElements); + + jbyteArray javaDAC; + JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), DAC.data(), DAC.size(), + javaDAC); + + jbyteArray javaPAI; + JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), PAI.data(), PAI.size(), + javaPAI); + + JniReferences::GetInstance().GetEnvForCurrentThread()->CallVoidMethod(mJavaObjectRef, method, javaCsr, javaCsrNonce, + javaAttestationSignature, javaAttestationChallenge, + javaAttestationElements, javaDAC, javaPAI); + return CHIP_NO_ERROR; +} + +CHIP_ERROR AndroidOperationalCredentialsIssuer::NOCChainGenerated(CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac, + const ByteSpan & rcac, Optional ipk, + Optional adminSubject) +{ + ReturnErrorCodeIf(mOnNOCCompletionCallback == nullptr, CHIP_ERROR_INCORRECT_STATE); + + Callback::Callback * onCompletion = mOnNOCCompletionCallback; + mOnNOCCompletionCallback = nullptr; + + // Call-back into commissioner with the generated data. + onCompletion->mCall(onCompletion->mContext, status, noc, icac, rcac, ipk, adminSubject); + return CHIP_NO_ERROR; +} + +CHIP_ERROR AndroidOperationalCredentialsIssuer::LocalGenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, + const ByteSpan & attestationSignature, + const ByteSpan & attestationChallenge, + const ByteSpan & attestationElements, const ByteSpan & DAC, + const ByteSpan & PAI, + Callback::Callback * onCompletion) { jmethodID method; CHIP_ERROR err = CHIP_NO_ERROR; err = JniReferences::GetInstance().FindMethod(JniReferences::GetInstance().GetEnvForCurrentThread(), mJavaObjectRef, - "onOpCSRGenerationComplete", "([B)V", &method); + "onOpCSRGenerationComplete", "([B)V", &method); if (err != CHIP_NO_ERROR) { ChipLogError(Controller, "Error invoking onOpCSRGenerationComplete: %" CHIP_ERROR_FORMAT, err.Format()); diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.h b/src/controller/java/AndroidOperationalCredentialsIssuer.h index 1fa5f6a6b16c24..84b5e7b1eb531f 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.h +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.h @@ -48,8 +48,16 @@ class DLL_EXPORT AndroidOperationalCredentialsIssuer : public OperationalCredent virtual ~AndroidOperationalCredentialsIssuer() {} CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, - Callback::Callback * onCompletion) override; + const ByteSpan & attestationChallenge, const ByteSpan & attestationElements, const ByteSpan & DAC, + const ByteSpan & PAI, Callback::Callback * onCompletion) override; + + CHIP_ERROR NOCChainGenerated(CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac, const ByteSpan & rcac, + Optional ipk, Optional adminSubject); + + void SetUseJavaCallbackForNOCRequest(bool useJavaCallbackForNOCRequest) + { + mUseJavaCallbackForNOCRequest = useJavaCallbackForNOCRequest; + } void SetNodeIdForNextNOCRequest(NodeId nodeId) override { @@ -87,6 +95,16 @@ class DLL_EXPORT AndroidOperationalCredentialsIssuer : public OperationalCredent MutableByteSpan & noc); private: + CHIP_ERROR CallbackGenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, + const ByteSpan & attestationSignature, const ByteSpan & attestationChallenge, + const ByteSpan & attestationElements, const ByteSpan & DAC, const ByteSpan & PAI, + Callback::Callback * onCompletion); + + CHIP_ERROR LocalGenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, + const ByteSpan & attestationChallenge, const ByteSpan & attestationElements, + const ByteSpan & DAC, const ByteSpan & PAI, + Callback::Callback * onCompletion); + Crypto::P256Keypair mIssuer; bool mInitialized = false; uint32_t mIssuerId = 0; @@ -103,6 +121,9 @@ class DLL_EXPORT AndroidOperationalCredentialsIssuer : public OperationalCredent bool mNodeIdRequested = false; jobject mJavaObjectRef = nullptr; + + bool mUseJavaCallbackForNOCRequest = false; + Callback::Callback * mOnNOCCompletionCallback = nullptr; }; } // namespace Controller diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 3e8db12d8f0794..a6d38a0c825599 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -155,6 +155,80 @@ void JNI_OnUnload(JavaVM * jvm, void * reserved) chip::Platform::MemoryShutdown(); } +JNI_METHOD(jint, setNOCChain) +(JNIEnv * env, jobject self, jlong handle, jobject controllerParams) +{ + chip::DeviceLayer::StackLock lock; + CHIP_ERROR err = CHIP_NO_ERROR; + AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle); + + ChipLogProgress(Controller, "setNOCChain() called"); + + jmethodID getRootCertificate; + err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getRootCertificate", "()[B", &getRootCertificate); + VerifyOrReturnValue(err == CHIP_NO_ERROR, err.AsInteger()); + + jmethodID getIntermediateCertificate; + err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getIntermediateCertificate", "()[B", + &getIntermediateCertificate); + VerifyOrReturnValue(err == CHIP_NO_ERROR, err.AsInteger()); + + jmethodID getOperationalCertificate; + err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getOperationalCertificate", "()[B", + &getOperationalCertificate); + VerifyOrReturnValue(err == CHIP_NO_ERROR, err.AsInteger()); + + jmethodID getIpk; + err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getIpk", "()[B", &getIpk); + VerifyOrReturnValue(err == CHIP_NO_ERROR, err.AsInteger()); + + jmethodID getAdminSubject; + err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getAdminSubject", "()J", &getAdminSubject); + VerifyOrReturnValue(err == CHIP_NO_ERROR, err.AsInteger()); + + jbyteArray rootCertificate = (jbyteArray) env->CallObjectMethod(controllerParams, getRootCertificate); + VerifyOrReturnValue(rootCertificate != nullptr, CHIP_ERROR_BAD_REQUEST.AsInteger()); + + jbyteArray intermediateCertificate = (jbyteArray) env->CallObjectMethod(controllerParams, getIntermediateCertificate); + VerifyOrReturnValue(intermediateCertificate != nullptr, CHIP_ERROR_BAD_REQUEST.AsInteger()); + + jbyteArray operationalCertificate = (jbyteArray) env->CallObjectMethod(controllerParams, getOperationalCertificate); + VerifyOrReturnValue(operationalCertificate != nullptr, CHIP_ERROR_BAD_REQUEST.AsInteger()); + + jbyteArray ipk = (jbyteArray) env->CallObjectMethod(controllerParams, getIpk); + VerifyOrReturnValue(ipk != nullptr, CHIP_ERROR_BAD_REQUEST.AsInteger()); + + Optional adminSubjectOptional; + uint64_t adminSubject = env->CallLongMethod(controllerParams, getAdminSubject); + if (adminSubject != kUndefinedNodeId) + { + adminSubjectOptional.SetValue(adminSubject); + } + + JniByteArray jByteArrayRcac(env, rootCertificate); + JniByteArray jByteArrayIcac(env, intermediateCertificate); + JniByteArray jByteArrayNoc(env, operationalCertificate); + JniByteArray jByteArrayIpk(env, ipk); + + // Prepare IPK to be sent back. A more fully-fledged operational credentials delegate + // would obtain a suitable key per fabric. + uint8_t ipkValue[CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES]; + Crypto::AesCcm128KeySpan ipkSpan(ipkValue); + + VerifyOrReturnValue(jByteArrayIpk.byteSpan().size() == sizeof(ipkValue), CHIP_ERROR_INTERNAL.AsInteger()); + memcpy(&ipkValue[0], jByteArrayIpk.byteSpan().data(), jByteArrayIpk.byteSpan().size()); + + err = wrapper->GetAndroidOperationalCredentialsIssuer()->NOCChainGenerated(CHIP_NO_ERROR, jByteArrayNoc.byteSpan(), + jByteArrayIcac.byteSpan(), jByteArrayRcac.byteSpan(), + MakeOptional(ipkSpan), adminSubjectOptional); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Failed to SetNocChain for the device: %" CHIP_ERROR_FORMAT, err.Format()); + } + return err.AsInteger(); +} + JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self, jobject controllerParams) { chip::DeviceLayer::StackLock lock; @@ -211,6 +285,10 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self, jobject contr err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getIpk", "()[B", &getIpk); SuccessOrExit(err); + jmethodID getAdminSubject; + err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getAdminSubject", "()J", &getAdminSubject); + SuccessOrExit(err); + { uint16_t listenPort = env->CallIntMethod(controllerParams, getUdpListenPort); uint16_t controllerVendorId = env->CallIntMethod(controllerParams, getControllerVendorId); @@ -220,15 +298,16 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self, jobject contr jbyteArray operationalCertificate = (jbyteArray) env->CallObjectMethod(controllerParams, getOperationalCertificate); jbyteArray ipk = (jbyteArray) env->CallObjectMethod(controllerParams, getIpk); uint16_t failsafeTimerSeconds = env->CallIntMethod(controllerParams, getFailsafeTimerSeconds); - bool attemptNetworkScanWiFi = env->CallIntMethod(controllerParams, getAttemptNetworkScanWiFi); - bool attemptNetworkScanThread = env->CallIntMethod(controllerParams, getAttemptNetworkScanThread); + bool attemptNetworkScanWiFi = env->CallBooleanMethod(controllerParams, getAttemptNetworkScanWiFi); + bool attemptNetworkScanThread = env->CallBooleanMethod(controllerParams, getAttemptNetworkScanThread); + uint64_t adminSubject = env->CallLongMethod(controllerParams, getAdminSubject); std::unique_ptr opCredsIssuer( new chip::Controller::AndroidOperationalCredentialsIssuer()); wrapper = AndroidDeviceControllerWrapper::AllocateNew( sJVM, self, kLocalDeviceId, chip::kUndefinedCATs, &DeviceLayer::SystemLayer(), DeviceLayer::TCPEndPointManager(), DeviceLayer::UDPEndPointManager(), std::move(opCredsIssuer), keypairDelegate, rootCertificate, intermediateCertificate, - operationalCertificate, ipk, listenPort, controllerVendorId, failsafeTimerSeconds, attemptNetworkScanWiFi, + operationalCertificate, ipk, adminSubject, listenPort, controllerVendorId, failsafeTimerSeconds, attemptNetworkScanWiFi, attemptNetworkScanThread, &err); SuccessOrExit(err); } diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 6b1197ae28cdc5..17e663b96d634f 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -34,6 +34,7 @@ public class ChipDeviceController { private int connectionId; private CompletionListener completionListener; private ScanNetworksListener scanNetworksListener; + private NOCChainIssuer nocChainIssuer; /** * To load class and jni, we need to new AndroidChipPlatform after jni load but before new @@ -61,6 +62,10 @@ public void setScanNetworksListener(ScanNetworksListener listener) { scanNetworksListener = listener; } + public void setNOCChainIssuer(NOCChainIssuer issuer) { + nocChainIssuer = issuer; + } + public void pairDevice( BluetoothGatt bleServer, int connId, @@ -183,6 +188,11 @@ public void resumeCommissioning() { resumeCommissioning(deviceControllerPtr); } + public int setNOCChain(ControllerParams params) { + return setNOCChain(deviceControllerPtr, params); + } + + /** * Update the network credentials held by the commissioner for the current commissioning session. * The updated values will be used by the commissioner if the network credentials haven't already @@ -314,6 +324,21 @@ public void onError(Throwable error) { completionListener.onError(error); } + public void onNOCChainGenerationNeeded( + byte[] csrElements, + byte[] csrNonce, + byte[] attestationSignature, + byte[] attestationChallenge, + byte[] attestationElements, + byte[] dac, + byte[] pai) { + if (nocChainIssuer != null) { + nocChainIssuer.onNOCChainGenerationNeeded( + csrElements, csrNonce, attestationSignature, attestationChallenge, + attestationElements, dac, pai); + } + } + public void close() { releaseBluetoothGatt(connectionId); } @@ -636,6 +661,8 @@ private native boolean openPairingWindowWithPINCallback( private native void updateCommissioningNetworkCredentials( long deviceControllerPtr, NetworkCredentials networkCredentials); + private native int setNOCChain(long deviceControllerPtr, ControllerParams params); + private native void shutdownSubscriptions(long deviceControllerPtr, long devicePtr); private native void shutdownCommissioning(long deviceControllerPtr); @@ -654,7 +681,30 @@ protected void finalize() throws Throwable { } } - /** Interface to listen for callbacks from CHIPDeviceController. */ + /** Interface to implement custom operational credentials issuer (NOC chain generation). */ + public interface NOCChainIssuer { + /** + * Notifies when operational cert generation is needed. + * + * Once generated, implementor should populate the following fields on the ControllerParams object + * and call setNOCChain(): + * - ipk + * - rootCertificate + * - intermediateCertificate + * - operationalCertificate + * - adminSubject + */ + void onNOCChainGenerationNeeded( + byte[] csrElements, + byte[] csrNonce, + byte[] attestationSignature, + byte[] attestationChallenge, + byte[] attestationElements, + byte[] dac, + byte[] pai); + } + + /** Interface to listen for scn networks callbacks from CHIPDeviceController. */ public interface ScanNetworksListener { /** Notifies when scan networks call fails. */ void onScanNetworksFailure(int errorCode); diff --git a/src/controller/java/src/chip/devicecontroller/ControllerParams.java b/src/controller/java/src/chip/devicecontroller/ControllerParams.java index 87fb85a375adf1..77a076b5ab52d5 100644 --- a/src/controller/java/src/chip/devicecontroller/ControllerParams.java +++ b/src/controller/java/src/chip/devicecontroller/ControllerParams.java @@ -7,14 +7,15 @@ public final class ControllerParams { private final int udpListenPort; private final int controllerVendorId; + private final int failsafeTimerSeconds; + private final boolean attemptNetworkScanWiFi; + private final boolean attemptNetworkScanThread; @Nullable private final KeypairDelegate keypairDelegate; @Nullable private final byte[] rootCertificate; @Nullable private final byte[] intermediateCertificate; @Nullable private final byte[] operationalCertificate; @Nullable private final byte[] ipk; - private final int failsafeTimerSeconds = 30; - private final boolean attemptNetworkScanWiFi = false; - private final boolean attemptNetworkScanThread = true; + private final long adminSubject; private static final int LEGACY_GLOBAL_CHIP_PORT = 5540; @@ -22,11 +23,15 @@ public final class ControllerParams { private ControllerParams(Builder builder) { this.udpListenPort = builder.udpListenPort; this.controllerVendorId = builder.controllerVendorId; + this.failsafeTimerSeconds = builder.failsafeTimerSeconds; + this.attemptNetworkScanWiFi = builder.attemptNetworkScanWiFi; + this.attemptNetworkScanThread = builder.attemptNetworkScanThread; this.keypairDelegate = builder.keypairDelegate; this.rootCertificate = builder.rootCertificate; this.intermediateCertificate = builder.intermediateCertificate; this.operationalCertificate = builder.operationalCertificate; this.ipk = builder.ipk; + this.adminSubject = builder.adminSubject; } /** Gets the UDP listening port; 0 indicates "any available port" */ @@ -38,6 +43,18 @@ public int getControllerVendorId() { return controllerVendorId; } + public int getFailsafeTimerSeconds() { + return failsafeTimerSeconds; + } + + public boolean getAttemptNetworkScanWiFi() { + return attemptNetworkScanWiFi; + } + + public boolean getAttemptNetworkScanThread() { + return attemptNetworkScanThread; + } + public KeypairDelegate getKeypairDelegate() { return keypairDelegate; } @@ -58,16 +75,8 @@ public byte[] getIpk() { return ipk; } - public int getFailsafeTimerSeconds() { - return failsafeTimerSeconds; - } - - public boolean getAttemptNetworkScanWiFi() { - return attemptNetworkScanWiFi; - } - - public boolean getAttemptNetworkScanThread() { - return attemptNetworkScanThread; + public long getAdminSubject() { + return adminSubject; } /** Returns parameters with ephemerally generated operational credentials */ @@ -92,14 +101,15 @@ public static Builder newBuilder(OperationalKeyConfig operationalKeyConfig) { public static class Builder { private int udpListenPort = LEGACY_GLOBAL_CHIP_PORT + 1; private int controllerVendorId = 0xFFFF; + private int failsafeTimerSeconds = 30; + private boolean attemptNetworkScanWiFi = false; + private boolean attemptNetworkScanThread = true; @Nullable private KeypairDelegate keypairDelegate = null; @Nullable private byte[] rootCertificate = null; @Nullable private byte[] intermediateCertificate = null; @Nullable private byte[] operationalCertificate = null; @Nullable private byte[] ipk = null; - private int failsafeTimerSeconds = 30; - private boolean attemptNetworkScanWiFi = false; - private boolean attemptNetworkScanThread = true; + private long adminSubject = 0; private Builder() {} @@ -159,6 +169,11 @@ public Builder setIpk(byte[] ipk) { return this; } + public Builder setAdminSubject(long adminSubject) { + this.adminSubject = adminSubject; + return this; + } + public ControllerParams build() { return new ControllerParams(this); } diff --git a/src/controller/python/OpCredsBinding.cpp b/src/controller/python/OpCredsBinding.cpp index a17f726a314bc4..7a093184e7d36f 100644 --- a/src/controller/python/OpCredsBinding.cpp +++ b/src/controller/python/OpCredsBinding.cpp @@ -79,11 +79,11 @@ class OperationalCredentialsAdapter : public OperationalCredentialsDelegate private: CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, - Callback::Callback * onCompletion) override + const ByteSpan & attestationChallenge, const ByteSpan & attestationElements, const ByteSpan & DAC, + const ByteSpan & PAI, Callback::Callback * onCompletion) override { - return mExampleOpCredsIssuer.GenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, DAC, PAI, - onCompletion); + return mExampleOpCredsIssuer.GenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, + attestationElements, DAC, PAI, onCompletion); } void SetNodeIdForNextNOCRequest(NodeId nodeId) override { mExampleOpCredsIssuer.SetNodeIdForNextNOCRequest(nodeId); } diff --git a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h index d7580bce7e9e87..fabcab0c95f1c1 100644 --- a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h +++ b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h @@ -41,8 +41,9 @@ class MTROperationalCredentialsDelegate : public chip::Controller::OperationalCr NSData * _Nullable icaCert); CHIP_ERROR GenerateNOCChain(const chip::ByteSpan & csrElements, const chip::ByteSpan & csrNonce, - const chip::ByteSpan & attestationSignature, const chip::ByteSpan & attestationChallenge, const chip::ByteSpan & DAC, - const chip::ByteSpan & PAI, chip::Callback::Callback * onCompletion) override; + const chip::ByteSpan & attestationSignature, const chip::ByteSpan & attestationChallenge, + const ByteSpan & attestationElements, const chip::ByteSpan & DAC, const chip::ByteSpan & PAI, + chip::Callback::Callback * onCompletion) override; void SetNodeIdForNextNOCRequest(chip::NodeId nodeId) override { diff --git a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm index 3688c9a08f7433..858577444ffac8 100644 --- a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm +++ b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm @@ -113,8 +113,9 @@ } CHIP_ERROR MTROperationalCredentialsDelegate::GenerateNOCChain(const chip::ByteSpan & csrElements, const chip::ByteSpan & csrNonce, - const chip::ByteSpan & attestationSignature, const chip::ByteSpan & attestationChallenge, const chip::ByteSpan & DAC, - const chip::ByteSpan & PAI, chip::Callback::Callback * onCompletion) + const chip::ByteSpan & attestationSignature, const chip::ByteSpan & attestationChallenge, const ByteSpan & attestationElements, + const chip::ByteSpan & DAC, const chip::ByteSpan & PAI, + chip::Callback::Callback * onCompletion) { chip::NodeId assignedId; if (mNodeIdRequested) { From efa15c8ef6c5ea06af16e69338381f5db160ee58 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Tue, 2 Aug 2022 18:08:06 -0700 Subject: [PATCH 02/12] address feedback --- src/controller/CHIPDeviceController.cpp | 15 ++++++------- src/controller/CHIPDeviceController.h | 4 +--- .../ExampleOperationalCredentialsIssuer.cpp | 3 +-- .../ExampleOperationalCredentialsIssuer.h | 4 ++-- .../OperationalCredentialsDelegate.h | 3 +-- .../java/AndroidDeviceControllerWrapper.cpp | 5 +---- .../java/AndroidDeviceControllerWrapper.h | 5 ----- .../AndroidOperationalCredentialsIssuer.cpp | 20 ++++++++--------- .../AndroidOperationalCredentialsIssuer.h | 13 ++++++----- .../java/CHIPDeviceController-JNI.cpp | 10 +++++++++ .../ChipDeviceController.java | 22 +++++++++++++++++++ src/controller/python/OpCredsBinding.cpp | 8 +++---- .../CHIP/MTROperationalCredentialsDelegate.h | 5 ++--- .../CHIP/MTROperationalCredentialsDelegate.mm | 5 ++--- 14 files changed, 69 insertions(+), 53 deletions(-) diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 730f60fde76d26..11ea5dca6b5e55 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1246,12 +1246,12 @@ CHIP_ERROR DeviceCommissioner::IssueNOCChain(const ByteSpan & NOCSRElements, Nod // Note: we don't have attestationSignature, attestationChallenge, DAC, PAI so we are just providing an empty ByteSpan // for those arguments. return mOperationalCredentialsDelegate->GenerateNOCChain(NOCSRElements, ByteSpan(), ByteSpan(), ByteSpan(), ByteSpan(), - ByteSpan(), ByteSpan(), callback); + ByteSpan(), callback); } CHIP_ERROR DeviceCommissioner::ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, - const ByteSpan & AttestationSignature, const ByteSpan & attestationElements, - const ByteSpan & dac, const ByteSpan & pai, const ByteSpan & csrNonce) + const ByteSpan & AttestationSignature, const ByteSpan & dac, const ByteSpan & pai, + const ByteSpan & csrNonce) { MATTER_TRACE_EVENT_SCOPE("ProcessOpCSR", "DeviceCommissioner"); VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE); @@ -1273,7 +1273,7 @@ CHIP_ERROR DeviceCommissioner::ProcessCSR(DeviceProxy * proxy, const ByteSpan & } return mOperationalCredentialsDelegate->GenerateNOCChain(NOCSRElements, csrNonce, AttestationSignature, attestationChallenge, - attestationElements, dac, pai, &mDeviceNOCChainCallback); + dac, pai, &mDeviceNOCChainCallback); } CHIP_ERROR DeviceCommissioner::SendOperationalCertificate(DeviceProxy * device, const ByteSpan & nocCertBuf, @@ -2173,10 +2173,9 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio ChipLogError(Controller, "Unable to generate NOC chain parameters"); return CommissioningStageComplete(CHIP_ERROR_INVALID_ARGUMENT); } - CHIP_ERROR err = - ProcessCSR(proxy, params.GetNOCChainGenerationParameters().Value().nocsrElements, - params.GetNOCChainGenerationParameters().Value().signature, params.GetAttestationElements().Value(), - params.GetDAC().Value(), params.GetPAI().Value(), params.GetCSRNonce().Value()); + CHIP_ERROR err = ProcessCSR(proxy, params.GetNOCChainGenerationParameters().Value().nocsrElements, + params.GetNOCChainGenerationParameters().Value().signature, params.GetDAC().Value(), + params.GetPAI().Value(), params.GetCSRNonce().Value()); if (err != CHIP_NO_ERROR) { ChipLogError(Controller, "Unable to process Op CSR"); diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index aeaa5b588a5e70..8230a9e4a5f15f 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -800,14 +800,12 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, * @param[in] proxy device proxy * @param[in] NOCSRElements CSR elements as per specifications section 11.22.5.6. NOCSR Elements. * @param[in] attestationSignature Cryptographic signature generated for all the above fields. - * @param[in] attestationElements   attestation elements portion of Attestation Response (raw TLV) * @param[in] dac device attestation certificate * @param[in] pai Product Attestation Intermediate certificate * @param[in] csrNonce certificate signing request nonce */ CHIP_ERROR ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & attestationSignature, - const ByteSpan & attestationElements, const ByteSpan & dac, const ByteSpan & pai, - const ByteSpan & csrNonce); + const ByteSpan & dac, const ByteSpan & pai, const ByteSpan & csrNonce); /** * @brief diff --git a/src/controller/ExampleOperationalCredentialsIssuer.cpp b/src/controller/ExampleOperationalCredentialsIssuer.cpp index bcb70a147d22f1..14ad78463ce225 100644 --- a/src/controller/ExampleOperationalCredentialsIssuer.cpp +++ b/src/controller/ExampleOperationalCredentialsIssuer.cpp @@ -184,8 +184,7 @@ CHIP_ERROR ExampleOperationalCredentialsIssuer::GenerateNOCChainAfterValidation( CHIP_ERROR ExampleOperationalCredentialsIssuer::GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, - const ByteSpan & attestationElements, const ByteSpan & DAC, + const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, Callback::Callback * onCompletion) { diff --git a/src/controller/ExampleOperationalCredentialsIssuer.h b/src/controller/ExampleOperationalCredentialsIssuer.h index d3948ef0591b8f..a85684cf6957e2 100644 --- a/src/controller/ExampleOperationalCredentialsIssuer.h +++ b/src/controller/ExampleOperationalCredentialsIssuer.h @@ -56,8 +56,8 @@ class DLL_EXPORT ExampleOperationalCredentialsIssuer : public OperationalCredent ~ExampleOperationalCredentialsIssuer() override {} CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, const ByteSpan & attestationElements, const ByteSpan & DAC, - const ByteSpan & PAI, Callback::Callback * onCompletion) override; + const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, + Callback::Callback * onCompletion) override; void SetNodeIdForNextNOCRequest(NodeId nodeId) override { diff --git a/src/controller/OperationalCredentialsDelegate.h b/src/controller/OperationalCredentialsDelegate.h index 9c14847ba142ac..e34b728b1ee9da 100644 --- a/src/controller/OperationalCredentialsDelegate.h +++ b/src/controller/OperationalCredentialsDelegate.h @@ -55,7 +55,6 @@ class DLL_EXPORT OperationalCredentialsDelegate * @param[in] csrNonce CSR nonce as described in 6.4.6.1 * @param[in] attestationSignature Attestation signature as per specifications section 11.22.7.6. CSRResponse Command. * @param[in] attestationChallenge Attestation challenge as per 11.18.5.7 - * @param[in] attestationElements Attestation elements portion of Attestation Response (raw TLV) * @param[in] DAC Device attestation certificate received from the device being commissioned * @param[in] PAI Product Attestation Intermediate certificate * @param[in] onCompletion Callback handler to provide generated NOC chain to the caller of GenerateNOCChain() @@ -64,7 +63,7 @@ class DLL_EXPORT OperationalCredentialsDelegate */ virtual CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, const ByteSpan & attestationChallenge, - const ByteSpan & attestationElements, const ByteSpan & DAC, const ByteSpan & PAI, + const ByteSpan & DAC, const ByteSpan & PAI, Callback::Callback * onCompletion) = 0; /** diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index d4fd785cec1859..c427087462df4a 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -179,7 +179,7 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew( initParams.opCertStore = &wrapper->mOpCertStore; // TODO: Init IPK Epoch Key in opcreds issuer, so that commissionees get the right IPK - opCredsIssuer->Initialize(*wrapper.get(), wrapper.get()->mJavaObjectRef); + opCredsIssuer->Initialize(*wrapper.get(), &wrapper->mAutoCommissioner, wrapper.get()->mJavaObjectRef); Platform::ScopedMemoryBuffer noc; if (!noc.Alloc(kMaxCHIPDERCertLength)) @@ -241,9 +241,6 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew( setupParams.operationalKeypair = &ephemeralKey; setupParams.hasExternallyOwnedOperationalKeypair = false; - // TODO: make this conditional based upon state passed from java - opCredsIssuer->SetUseJavaCallbackForNOCRequest(true); - *errInfoOnFailure = opCredsIssuer->GenerateNOCChainAfterValidation(nodeId, /* fabricId = */ 1, cats, ephemeralKey.Pubkey(), rcacSpan, icacSpan, nocSpan); diff --git a/src/controller/java/AndroidDeviceControllerWrapper.h b/src/controller/java/AndroidDeviceControllerWrapper.h index 8616084a8dd1ad..2b53e002e07702 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.h +++ b/src/controller/java/AndroidDeviceControllerWrapper.h @@ -75,11 +75,6 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel */ CHIP_ERROR UpdateCommissioningParameters(const chip::Controller::CommissioningParameters & params); - /** - * Update the CommissioningParameters used by the active device commissioner and set the NOC Chain - */ - CHIP_ERROR SetNOCChain(const chip::Controller::CommissioningParameters & params); - // DevicePairingDelegate implementation void OnStatusUpdate(chip::Controller::DevicePairingDelegate::Status status) override; void OnPairingComplete(CHIP_ERROR error) override; diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp index ab75f11a981ff1..951e52136fe187 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp @@ -40,7 +40,8 @@ using namespace Credentials; using namespace Crypto; using namespace TLV; -CHIP_ERROR AndroidOperationalCredentialsIssuer::Initialize(PersistentStorageDelegate & storage, jobject javaObjectRef) +CHIP_ERROR AndroidOperationalCredentialsIssuer::Initialize(PersistentStorageDelegate & storage, AutoCommissioner * autoCommissioner, + jobject javaObjectRef) { using namespace ASN1; ASN1UniversalTime effectiveTime; @@ -71,6 +72,7 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::Initialize(PersistentStorageDele } mStorage = &storage; + mAutoCommissioner = autoCommissioner; mJavaObjectRef = javaObjectRef; mInitialized = true; @@ -125,28 +127,24 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::GenerateNOCChainAfterValidation( CHIP_ERROR AndroidOperationalCredentialsIssuer::GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, - const ByteSpan & attestationElements, const ByteSpan & DAC, + const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, Callback::Callback * onCompletion) { if (mUseJavaCallbackForNOCRequest) { - return CallbackGenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, attestationElements, DAC, - PAI, onCompletion); + return CallbackGenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, DAC, PAI, onCompletion); } else { - return LocalGenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, attestationElements, DAC, - PAI, onCompletion); + return LocalGenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, DAC, PAI, onCompletion); } } CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, const ByteSpan & attestationChallenge, - const ByteSpan & attestationElements, const ByteSpan & DAC, - const ByteSpan & PAI, + const ByteSpan & DAC, const ByteSpan & PAI, Callback::Callback * onCompletion) { jmethodID method; @@ -179,6 +177,7 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationChallenge.data(), attestationChallenge.size(), javaAttestationChallenge); + const ByteSpan & attestationElements = mAutoCommissioner->GetCommissioningParameters().GetAttestationElements().Value(); jbyteArray javaAttestationElements; JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationElements.data(), attestationElements.size(), javaAttestationElements); @@ -213,8 +212,7 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::NOCChainGenerated(CHIP_ERROR sta CHIP_ERROR AndroidOperationalCredentialsIssuer::LocalGenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, - const ByteSpan & attestationElements, const ByteSpan & DAC, + const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, Callback::Callback * onCompletion) { diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.h b/src/controller/java/AndroidOperationalCredentialsIssuer.h index 84b5e7b1eb531f..49a845710b3e4b 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.h +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.h @@ -29,6 +29,7 @@ #pragma once +#include #include #include #include @@ -48,8 +49,8 @@ class DLL_EXPORT AndroidOperationalCredentialsIssuer : public OperationalCredent virtual ~AndroidOperationalCredentialsIssuer() {} CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, const ByteSpan & attestationElements, const ByteSpan & DAC, - const ByteSpan & PAI, Callback::Callback * onCompletion) override; + const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, + Callback::Callback * onCompletion) override; CHIP_ERROR NOCChainGenerated(CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac, const ByteSpan & rcac, Optional ipk, Optional adminSubject); @@ -77,7 +78,7 @@ class DLL_EXPORT AndroidOperationalCredentialsIssuer : public OperationalCredent * * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise **/ - CHIP_ERROR Initialize(PersistentStorageDelegate & storage, jobject javaObjectRef); + CHIP_ERROR Initialize(PersistentStorageDelegate & storage, AutoCommissioner * autoCommissioner, jobject javaObjectRef); void SetIssuerId(uint32_t id) { mIssuerId = id; } @@ -97,12 +98,11 @@ class DLL_EXPORT AndroidOperationalCredentialsIssuer : public OperationalCredent private: CHIP_ERROR CallbackGenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, const ByteSpan & attestationChallenge, - const ByteSpan & attestationElements, const ByteSpan & DAC, const ByteSpan & PAI, + const ByteSpan & DAC, const ByteSpan & PAI, Callback::Callback * onCompletion); CHIP_ERROR LocalGenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, const ByteSpan & attestationElements, - const ByteSpan & DAC, const ByteSpan & PAI, + const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, Callback::Callback * onCompletion); Crypto::P256Keypair mIssuer; @@ -115,6 +115,7 @@ class DLL_EXPORT AndroidOperationalCredentialsIssuer : public OperationalCredent NodeId mNextAvailableNodeId = 1; PersistentStorageDelegate * mStorage = nullptr; + AutoCommissioner * mAutoCommissioner = nullptr; NodeId mNextRequestedNodeId = 1; FabricId mNextFabricId = 1; diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index a6d38a0c825599..06d141b3eac134 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -501,6 +501,16 @@ JNI_METHOD(void, resumeCommissioning) wrapper->GetAutoCommissioner()->ResumeCommissioning(); } +JNI_METHOD(void, setUseJavaCallbackForNOCRequest) +(JNIEnv * env, jobject self, jlong handle, jboolean useCallback) +{ + ChipLogProgress(Controller, "setUseJavaCallbackForNOCRequest() called"); + chip::DeviceLayer::StackLock lock; + AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle); + + wrapper->GetAndroidOperationalCredentialsIssuer()->SetUseJavaCallbackForNOCRequest(useCallback); +} + JNI_METHOD(void, updateCommissioningNetworkCredentials) (JNIEnv * env, jobject self, jlong handle, jobject networkCredentials) { diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 17e663b96d634f..778cb3484bf8c9 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -62,7 +62,15 @@ public void setScanNetworksListener(ScanNetworksListener listener) { scanNetworksListener = listener; } + /** + * Sets this DeviceController to use the given issuer for issuing operational certs. + * By default, the DeviceController uses an internal, OperationalCredentialsDelegate + * (see AndroidOperationalCredentialsIssuer) + * + * @param issuer + */ public void setNOCChainIssuer(NOCChainIssuer issuer) { + setUseJavaCallbackForNOCRequest(deviceControllerPtr, issuer != null); nocChainIssuer = issuer; } @@ -188,6 +196,18 @@ public void resumeCommissioning() { resumeCommissioning(deviceControllerPtr); } + /** + * + * The following fields on the ControllerParams object must be populated: + * - ipk + * - rootCertificate + * - intermediateCertificate + * - operationalCertificate + * - adminSubject + * + * @param params + * @return + */ public int setNOCChain(ControllerParams params) { return setNOCChain(deviceControllerPtr, params); } @@ -658,6 +678,8 @@ private native boolean openPairingWindowWithPINCallback( private native void resumeCommissioning(long deviceControllerPtr); + private native void setUseJavaCallbackForNOCRequest(long deviceControllerPtr, boolean useCallback); + private native void updateCommissioningNetworkCredentials( long deviceControllerPtr, NetworkCredentials networkCredentials); diff --git a/src/controller/python/OpCredsBinding.cpp b/src/controller/python/OpCredsBinding.cpp index 7a093184e7d36f..a17f726a314bc4 100644 --- a/src/controller/python/OpCredsBinding.cpp +++ b/src/controller/python/OpCredsBinding.cpp @@ -79,11 +79,11 @@ class OperationalCredentialsAdapter : public OperationalCredentialsDelegate private: CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, - const ByteSpan & attestationChallenge, const ByteSpan & attestationElements, const ByteSpan & DAC, - const ByteSpan & PAI, Callback::Callback * onCompletion) override + const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, + Callback::Callback * onCompletion) override { - return mExampleOpCredsIssuer.GenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, - attestationElements, DAC, PAI, onCompletion); + return mExampleOpCredsIssuer.GenerateNOCChain(csrElements, csrNonce, attestationSignature, attestationChallenge, DAC, PAI, + onCompletion); } void SetNodeIdForNextNOCRequest(NodeId nodeId) override { mExampleOpCredsIssuer.SetNodeIdForNextNOCRequest(nodeId); } diff --git a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h index fabcab0c95f1c1..d7580bce7e9e87 100644 --- a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h +++ b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.h @@ -41,9 +41,8 @@ class MTROperationalCredentialsDelegate : public chip::Controller::OperationalCr NSData * _Nullable icaCert); CHIP_ERROR GenerateNOCChain(const chip::ByteSpan & csrElements, const chip::ByteSpan & csrNonce, - const chip::ByteSpan & attestationSignature, const chip::ByteSpan & attestationChallenge, - const ByteSpan & attestationElements, const chip::ByteSpan & DAC, const chip::ByteSpan & PAI, - chip::Callback::Callback * onCompletion) override; + const chip::ByteSpan & attestationSignature, const chip::ByteSpan & attestationChallenge, const chip::ByteSpan & DAC, + const chip::ByteSpan & PAI, chip::Callback::Callback * onCompletion) override; void SetNodeIdForNextNOCRequest(chip::NodeId nodeId) override { diff --git a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm index 858577444ffac8..3688c9a08f7433 100644 --- a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm +++ b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm @@ -113,9 +113,8 @@ } CHIP_ERROR MTROperationalCredentialsDelegate::GenerateNOCChain(const chip::ByteSpan & csrElements, const chip::ByteSpan & csrNonce, - const chip::ByteSpan & attestationSignature, const chip::ByteSpan & attestationChallenge, const ByteSpan & attestationElements, - const chip::ByteSpan & DAC, const chip::ByteSpan & PAI, - chip::Callback::Callback * onCompletion) + const chip::ByteSpan & attestationSignature, const chip::ByteSpan & attestationChallenge, const chip::ByteSpan & DAC, + const chip::ByteSpan & PAI, chip::Callback::Callback * onCompletion) { chip::NodeId assignedId; if (mNodeIdRequested) { From 44a7cbad480921e1f1a28f1441a87af7def763e8 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Tue, 2 Aug 2022 18:09:52 -0700 Subject: [PATCH 03/12] address feedback --- src/controller/CHIPDeviceController.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 8230a9e4a5f15f..8f04fe771ae5f0 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -799,12 +799,12 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, * * @param[in] proxy device proxy * @param[in] NOCSRElements CSR elements as per specifications section 11.22.5.6. NOCSR Elements. - * @param[in] attestationSignature Cryptographic signature generated for all the above fields. + * @param[in] AttestationSignature Cryptographic signature generated for all the above fields. * @param[in] dac device attestation certificate * @param[in] pai Product Attestation Intermediate certificate * @param[in] csrNonce certificate signing request nonce */ - CHIP_ERROR ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & attestationSignature, + CHIP_ERROR ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature, const ByteSpan & dac, const ByteSpan & pai, const ByteSpan & csrNonce); /** From b75ecbe7dd9d1c0abd62fa84b516e3b0e91bca1c Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Wed, 3 Aug 2022 07:01:15 -0700 Subject: [PATCH 04/12] add missing fields for complete attestation validation --- .../AndroidOperationalCredentialsIssuer.cpp | 28 +++++++++++++------ .../ChipDeviceController.java | 12 +++++--- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp index 951e52136fe187..63a6f298561b72 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp @@ -142,7 +142,7 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::GenerateNOCChain(const ByteSpan } CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, - const ByteSpan & attestationSignature, + const ByteSpan & csrSignature, const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, Callback::Callback * onCompletion) @@ -150,7 +150,7 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B jmethodID method; CHIP_ERROR err = CHIP_NO_ERROR; err = JniReferences::GetInstance().FindMethod(JniReferences::GetInstance().GetEnvForCurrentThread(), mJavaObjectRef, - "onNOCChainGenerationNeeded", "([B[B[B[B[B[B[B)V", &method); + "onNOCChainGenerationNeeded", "([B[B[B[B[B[B[B[B[B)V", &method); if (err != CHIP_NO_ERROR) { ChipLogError(Controller, "Error invoking onNOCChainGenerationNeeded: %" CHIP_ERROR_FORMAT, err.Format()); @@ -169,9 +169,9 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), csrNonce.data(), csrNonce.size(), javaCsrNonce); - jbyteArray javaAttestationSignature; - JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationSignature.data(), - attestationSignature.size(), javaAttestationSignature); + jbyteArray javaCsrSignature; + JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), csrSignature.data(), + csrSignature.size(), javaCsrSignature); jbyteArray javaAttestationChallenge; JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationChallenge.data(), @@ -182,6 +182,18 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationElements.data(), attestationElements.size(), javaAttestationElements); + const ByteSpan & attestationNonce = mAutoCommissioner->GetCommissioningParameters().GetAttestationNonce().Value(); + jbyteArray javaAttestationNonce; + JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), attestationNonce.data(), + attestationNonce.size(), javaAttestationNonce); + + const ByteSpan & attestationElementsSignature = + mAutoCommissioner->GetCommissioningParameters().GetAttestationSignature().Value(); + jbyteArray javaAttestationElementsSignature; + JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), + attestationElementsSignature.data(), attestationElementsSignature.size(), + javaAttestationElementsSignature); + jbyteArray javaDAC; JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), DAC.data(), DAC.size(), javaDAC); @@ -190,9 +202,9 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B JniReferences::GetInstance().N2J_ByteArray(JniReferences::GetInstance().GetEnvForCurrentThread(), PAI.data(), PAI.size(), javaPAI); - JniReferences::GetInstance().GetEnvForCurrentThread()->CallVoidMethod(mJavaObjectRef, method, javaCsr, javaCsrNonce, - javaAttestationSignature, javaAttestationChallenge, - javaAttestationElements, javaDAC, javaPAI); + JniReferences::GetInstance().GetEnvForCurrentThread()->CallVoidMethod( + mJavaObjectRef, method, javaCsr, javaCsrNonce, javaCsrSignature, javaAttestationChallenge, javaAttestationElements, + javaAttestationNonce, javaAttestationElementsSignature, javaDAC, javaPAI); return CHIP_NO_ERROR; } diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 778cb3484bf8c9..94a03b328780f5 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -347,15 +347,17 @@ public void onError(Throwable error) { public void onNOCChainGenerationNeeded( byte[] csrElements, byte[] csrNonce, - byte[] attestationSignature, + byte[] csrElementsSignature, byte[] attestationChallenge, byte[] attestationElements, + byte[] attestationNonce, + byte[] attestationElementsSignature, byte[] dac, byte[] pai) { if (nocChainIssuer != null) { nocChainIssuer.onNOCChainGenerationNeeded( - csrElements, csrNonce, attestationSignature, attestationChallenge, - attestationElements, dac, pai); + csrElements, csrNonce, csrElementsSignature, attestationChallenge, + attestationElements, attestationNonce, attestationElementsSignature, dac, pai); } } @@ -719,9 +721,11 @@ public interface NOCChainIssuer { void onNOCChainGenerationNeeded( byte[] csrElements, byte[] csrNonce, - byte[] attestationSignature, + byte[] csrElementsSignature, byte[] attestationChallenge, byte[] attestationElements, + byte[] attestationNonce, + byte[] attestationElementsSignature, byte[] dac, byte[] pai); } From 915ce315f801a5d10154aa6c0c351d5e43851395 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Wed, 3 Aug 2022 08:29:39 -0700 Subject: [PATCH 05/12] address comments, use adminSubject and ipk from earlier setup if not provided in setNOCChain --- src/controller/AutoCommissioner.cpp | 6 ++ .../java/AndroidDeviceControllerWrapper.cpp | 6 +- .../java/AndroidDeviceControllerWrapper.h | 5 +- .../java/CHIPDeviceController-JNI.cpp | 55 +++++++++++++++---- 4 files changed, 52 insertions(+), 20 deletions(-) diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index 0feec835699252..6a3b064feaac83 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -51,6 +51,12 @@ CHIP_ERROR AutoCommissioner::SetCommissioningParameters(const CommissioningParam mParams.SetFailsafeTimerSeconds(params.GetFailsafeTimerSeconds().Value()); } + if (params.GetAdminSubject().HasValue()) + { + ChipLogProgress(Controller, "Setting adminSubject from parameters"); + mParams.SetAdminSubject(params.GetAdminSubject().Value()); + } + if (params.GetThreadOperationalDataset().HasValue()) { ByteSpan dataset = params.GetThreadOperationalDataset().Value(); diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index c427087462df4a..2f08bd5a211b92 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -74,7 +74,7 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew( chip::Inet::EndPointManager * tcpEndPointManager, chip::Inet::EndPointManager * udpEndPointManager, AndroidOperationalCredentialsIssuerPtr opCredsIssuerPtr, jobject keypairDelegate, jbyteArray rootCertificate, jbyteArray intermediateCertificate, jbyteArray nodeOperationalCertificate, - jbyteArray ipkEpochKey, uint64_t adminSubject, uint16_t listenPort, uint16_t controllerVendorId, uint16_t failsafeTimerSeconds, + jbyteArray ipkEpochKey, uint16_t listenPort, uint16_t controllerVendorId, uint16_t failsafeTimerSeconds, bool attemptNetworkScanWiFi, bool attemptNetworkScanThread, CHIP_ERROR * errInfoOnFailure) { if (errInfoOnFailure == nullptr) @@ -156,10 +156,6 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew( params.SetFailsafeTimerSeconds(failsafeTimerSeconds); params.SetAttemptWiFiNetworkScan(attemptNetworkScanWiFi); params.SetAttemptThreadNetworkScan(attemptNetworkScanThread); - if (adminSubject != kUndefinedNodeId) - { - params.SetAdminSubject(adminSubject); - } wrapper->UpdateCommissioningParameters(params); CHIP_ERROR err = wrapper->mGroupDataProvider.Init(); diff --git a/src/controller/java/AndroidDeviceControllerWrapper.h b/src/controller/java/AndroidDeviceControllerWrapper.h index 2b53e002e07702..77f9a6d735cc25 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.h +++ b/src/controller/java/AndroidDeviceControllerWrapper.h @@ -130,7 +130,6 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel * @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] adminSubject the adminSubject to use for AddNOC command * @param[in] listenPort the UDP port to listen on * @param[in] controllerVendorId the vendor ID identifying the controller * @param[in] failsafeTimerSeconds the failsafe timer in seconds @@ -144,8 +143,8 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel chip::Inet::EndPointManager * udpEndPointManager, AndroidOperationalCredentialsIssuerPtr opCredsIssuer, jobject keypairDelegate, jbyteArray rootCertificate, jbyteArray intermediateCertificate, jbyteArray nodeOperationalCertificate, jbyteArray ipkEpochKey, - uint64_t adminSubject, uint16_t listenPort, uint16_t controllerVendorId, uint16_t failsafeTimerSeconds, - bool attemptNetworkScanWiFi, bool attemptNetworkScanThread, CHIP_ERROR * errInfoOnFailure); + uint16_t listenPort, uint16_t controllerVendorId, uint16_t failsafeTimerSeconds, bool attemptNetworkScanWiFi, + bool attemptNetworkScanThread, CHIP_ERROR * errInfoOnFailure); chip::Controller::AndroidOperationalCredentialsIssuer * GetAndroidOperationalCredentialsIssuer() { diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 06d141b3eac134..1b86bd100db800 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -195,11 +195,36 @@ JNI_METHOD(jint, setNOCChain) jbyteArray operationalCertificate = (jbyteArray) env->CallObjectMethod(controllerParams, getOperationalCertificate); VerifyOrReturnValue(operationalCertificate != nullptr, CHIP_ERROR_BAD_REQUEST.AsInteger()); + // use ipk and adminSubject from CommissioningParameters if not set in ControllerParams + CommissioningParameters commissioningParams = wrapper->GetCommissioningParameters(); + + Optional ipkOptional; + uint8_t ipkValue[CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES]; + Crypto::AesCcm128KeySpan ipkTempSpan(ipkValue); + jbyteArray ipk = (jbyteArray) env->CallObjectMethod(controllerParams, getIpk); - VerifyOrReturnValue(ipk != nullptr, CHIP_ERROR_BAD_REQUEST.AsInteger()); + if (ipk != nullptr) + { + JniByteArray jByteArrayIpk(env, ipk); + + VerifyOrReturnValue(jByteArrayIpk.byteSpan().size() == sizeof(ipkValue), CHIP_ERROR_INTERNAL.AsInteger()); + memcpy(&ipkValue[0], jByteArrayIpk.byteSpan().data(), jByteArrayIpk.byteSpan().size()); + + ipkOptional.SetValue(ipkTempSpan); + } + else if (commissioningParams.GetIpk().HasValue()) + { + // if no value pass in ControllerParams, use value from CommissioningParameters + ipkOptional.SetValue(commissioningParams.GetIpk().Value()); + } Optional adminSubjectOptional; uint64_t adminSubject = env->CallLongMethod(controllerParams, getAdminSubject); + if (adminSubject == kUndefinedNodeId) + { + // if no value pass in ControllerParams, use value from CommissioningParameters + adminSubject = commissioningParams.GetAdminSubject().ValueOr(kUndefinedNodeId); + } if (adminSubject != kUndefinedNodeId) { adminSubjectOptional.SetValue(adminSubject); @@ -208,19 +233,10 @@ JNI_METHOD(jint, setNOCChain) JniByteArray jByteArrayRcac(env, rootCertificate); JniByteArray jByteArrayIcac(env, intermediateCertificate); JniByteArray jByteArrayNoc(env, operationalCertificate); - JniByteArray jByteArrayIpk(env, ipk); - - // Prepare IPK to be sent back. A more fully-fledged operational credentials delegate - // would obtain a suitable key per fabric. - uint8_t ipkValue[CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES]; - Crypto::AesCcm128KeySpan ipkSpan(ipkValue); - - VerifyOrReturnValue(jByteArrayIpk.byteSpan().size() == sizeof(ipkValue), CHIP_ERROR_INTERNAL.AsInteger()); - memcpy(&ipkValue[0], jByteArrayIpk.byteSpan().data(), jByteArrayIpk.byteSpan().size()); err = wrapper->GetAndroidOperationalCredentialsIssuer()->NOCChainGenerated(CHIP_NO_ERROR, jByteArrayNoc.byteSpan(), jByteArrayIcac.byteSpan(), jByteArrayRcac.byteSpan(), - MakeOptional(ipkSpan), adminSubjectOptional); + ipkOptional, adminSubjectOptional); if (err != CHIP_NO_ERROR) { @@ -285,6 +301,7 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self, jobject contr err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getIpk", "()[B", &getIpk); SuccessOrExit(err); + // TODO: remove adminSubject? jmethodID getAdminSubject; err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getAdminSubject", "()J", &getAdminSubject); SuccessOrExit(err); @@ -307,9 +324,23 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self, jobject contr wrapper = AndroidDeviceControllerWrapper::AllocateNew( sJVM, self, kLocalDeviceId, chip::kUndefinedCATs, &DeviceLayer::SystemLayer(), DeviceLayer::TCPEndPointManager(), DeviceLayer::UDPEndPointManager(), std::move(opCredsIssuer), keypairDelegate, rootCertificate, intermediateCertificate, - operationalCertificate, ipk, adminSubject, listenPort, controllerVendorId, failsafeTimerSeconds, attemptNetworkScanWiFi, + operationalCertificate, ipk, listenPort, controllerVendorId, failsafeTimerSeconds, attemptNetworkScanWiFi, attemptNetworkScanThread, &err); SuccessOrExit(err); + + if (adminSubject != kUndefinedNodeId) + { + // if there is a valid adminSubject in the ControllerParams, then remember it + + CommissioningParameters commissioningParams = wrapper->GetCommissioningParameters(); + commissioningParams.SetAdminSubject(adminSubject); + err = wrapper->UpdateCommissioningParameters(commissioningParams); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "UpdateCommissioningParameters failed. Err = %" CHIP_ERROR_FORMAT, err.Format()); + SuccessOrExit(err); + } + } } // Create and start the IO thread. Must be called after Controller()->Init From 7f052acff1039a49287651f21896bf4fa43975b7 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Wed, 3 Aug 2022 08:32:21 -0700 Subject: [PATCH 06/12] address comments --- src/controller/java/CHIPDeviceController-JNI.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 1b86bd100db800..940fc9f7d5b383 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -301,7 +301,6 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self, jobject contr err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getIpk", "()[B", &getIpk); SuccessOrExit(err); - // TODO: remove adminSubject? jmethodID getAdminSubject; err = chip::JniReferences::GetInstance().FindMethod(env, controllerParams, "getAdminSubject", "()J", &getAdminSubject); SuccessOrExit(err); @@ -331,7 +330,6 @@ JNI_METHOD(jlong, newDeviceController)(JNIEnv * env, jobject self, jobject contr if (adminSubject != kUndefinedNodeId) { // if there is a valid adminSubject in the ControllerParams, then remember it - CommissioningParameters commissioningParams = wrapper->GetCommissioningParameters(); commissioningParams.SetAdminSubject(adminSubject); err = wrapper->UpdateCommissioningParameters(commissioningParams); From dda1ad3f124905e7774e1214c9acf1354b1f9a71 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Wed, 3 Aug 2022 12:04:18 -0700 Subject: [PATCH 07/12] address comments --- .../ChipDeviceController.java | 50 ++++++++++++------- .../DefaultDeviceAttestationVerifier.cpp | 3 ++ 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 94a03b328780f5..2e469957036877 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -197,19 +197,26 @@ public void resumeCommissioning() { } /** + * When a NOCChainIssuer is set for this controller, then onNOCChainGenerationNeeded + * will be called when the NOC CSR needs to be signed. This allows for custom credentials + * issuer implementations, for example, when a proprietary cloud API will perform the + * CSR signing. * - * The following fields on the ControllerParams object must be populated: - * - ipk - * - rootCertificate - * - intermediateCertificate - * - operationalCertificate - * - adminSubject + * The commissioning workflow will stop upon the onNOCChainGenerationNeeded callback + * and resume once onNOCChainGeneration is called. + * + * The following fields on the ControllerParams object MUST be populated: + * rootCertificate, intermediateCertificate, operationalCertificate + * + * If ipk and adminSubject are set on the ControllerParams object, then they will be used + * in the AddNOC command set to the commissionee. If they are not populated, then the values + * provided in the ChipDeviceController initialization will be used. * * @param params - * @return + * @return CHIP_ERROR error code (0 is no error) */ - public int setNOCChain(ControllerParams params) { - return setNOCChain(deviceControllerPtr, params); + public int onNOCChainGeneration(ControllerParams params) { + return onNOCChainGeneration(deviceControllerPtr, params); } @@ -685,7 +692,7 @@ private native boolean openPairingWindowWithPINCallback( private native void updateCommissioningNetworkCredentials( long deviceControllerPtr, NetworkCredentials networkCredentials); - private native int setNOCChain(long deviceControllerPtr, ControllerParams params); + private native int onNOCChainGeneration(long deviceControllerPtr, ControllerParams params); private native void shutdownSubscriptions(long deviceControllerPtr, long devicePtr); @@ -708,15 +715,22 @@ protected void finalize() throws Throwable { /** Interface to implement custom operational credentials issuer (NOC chain generation). */ public interface NOCChainIssuer { /** - * Notifies when operational cert generation is needed. + * When a NOCChainIssuer is set for this controller, then onNOCChainGenerationNeeded + * will be called when the NOC CSR needs to be signed. This allows for custom credentials + * issuer implementations, for example, when a proprietary cloud API will perform the + * CSR signing. + * + * The commissioning workflow will stop upon the onNOCChainGenerationNeeded callback + * and resume once onNOCChainGeneration is called. + * + * The following fields on the ControllerParams object passed to onNOCChainGeneration + * MUST be populated: rootCertificate, intermediateCertificate, operationalCertificate + * + * If ipk and adminSubject are set on the ControllerParams object, then they will be used + * in the AddNOC command set to the commissionee. If they are not populated, then the values + * provided in the ChipDeviceController initialization will be used. * - * Once generated, implementor should populate the following fields on the ControllerParams object - * and call setNOCChain(): - * - ipk - * - rootCertificate - * - intermediateCertificate - * - operationalCertificate - * - adminSubject + * All csr and attestation fields are provided to allow for custom attestestation checks. */ void onNOCChainGenerationNeeded( byte[] csrElements, diff --git a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp index 518ebc2eb8f6f8..dc00eabb30e3d5 100644 --- a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp +++ b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp @@ -250,6 +250,9 @@ void DefaultDACVerifier::VerifyAttestationInformation(const DeviceAttestationVer DeviceAttestationVendorReservedDeconstructor vendorReserved; ByteSpan certificationDeclarationPayload; + ChipLogProgress(Support, " ----- DefaultDACVerifier::VerifyAttestationInformation vendorId=0x%04X productId=0x%04X", + info.vendorId, info.productId); + DeviceInfoForAttestation deviceInfo{ .vendorId = info.vendorId, .productId = info.productId, From 60248f3bad041ea8f15f0cf8de15d2891a712a06 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Wed, 3 Aug 2022 13:04:45 -0700 Subject: [PATCH 08/12] address comments --- src/controller/java/CHIPDeviceController-JNI.cpp | 5 ++++- .../DefaultDeviceAttestationVerifier.cpp | 3 --- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 940fc9f7d5b383..070c993a3ab674 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -155,7 +155,7 @@ void JNI_OnUnload(JavaVM * jvm, void * reserved) chip::Platform::MemoryShutdown(); } -JNI_METHOD(jint, setNOCChain) +JNI_METHOD(jint, onNOCChainGeneration) (JNIEnv * env, jobject self, jlong handle, jobject controllerParams) { chip::DeviceLayer::StackLock lock; @@ -229,6 +229,9 @@ JNI_METHOD(jint, setNOCChain) { adminSubjectOptional.SetValue(adminSubject); } + // NOTE: we are allowing adminSubject to not be set since the OnNOCChainGeneration callback makes this field + // optional and includes logic to handle the case where it is not set. It would also make sense to return + // an error here since that use case may not be realistic. JniByteArray jByteArrayRcac(env, rootCertificate); JniByteArray jByteArrayIcac(env, intermediateCertificate); diff --git a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp index dc00eabb30e3d5..518ebc2eb8f6f8 100644 --- a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp +++ b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp @@ -250,9 +250,6 @@ void DefaultDACVerifier::VerifyAttestationInformation(const DeviceAttestationVer DeviceAttestationVendorReservedDeconstructor vendorReserved; ByteSpan certificationDeclarationPayload; - ChipLogProgress(Support, " ----- DefaultDACVerifier::VerifyAttestationInformation vendorId=0x%04X productId=0x%04X", - info.vendorId, info.productId); - DeviceInfoForAttestation deviceInfo{ .vendorId = info.vendorId, .productId = info.productId, From ef83d86a5a70a24596db6745e5c916039ba8680f Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Wed, 3 Aug 2022 13:24:20 -0700 Subject: [PATCH 09/12] address comments --- .../devicecontroller/ControllerParams.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/controller/java/src/chip/devicecontroller/ControllerParams.java b/src/controller/java/src/chip/devicecontroller/ControllerParams.java index 77a076b5ab52d5..35c05f494c0816 100644 --- a/src/controller/java/src/chip/devicecontroller/ControllerParams.java +++ b/src/controller/java/src/chip/devicecontroller/ControllerParams.java @@ -103,7 +103,7 @@ public static class Builder { private int controllerVendorId = 0xFFFF; private int failsafeTimerSeconds = 30; private boolean attemptNetworkScanWiFi = false; - private boolean attemptNetworkScanThread = true; + private boolean attemptNetworkScanThread = false; @Nullable private KeypairDelegate keypairDelegate = null; @Nullable private byte[] rootCertificate = null; @Nullable private byte[] intermediateCertificate = null; @@ -126,6 +126,14 @@ public Builder setControllerVendorId(int controllerVendorId) { return this; } + /** + * Sets the FailsafeTimer duration passed to ChipDeviceCommissioner's + * CommissioningParameters. Increasing this value from its default will allow more time + * for network scans, cloud op cert signing calls, and user interaction. + * + * @param failsafeTimerSeconds + * @return + */ public Builder setFailsafeTimerSeconds(int failsafeTimerSeconds) { if (failsafeTimerSeconds < 1 || failsafeTimerSeconds > 900) { throw new IllegalArgumentException("failsafeTimerSeconds must be between 0 and 900"); @@ -134,11 +142,31 @@ public Builder setFailsafeTimerSeconds(int failsafeTimerSeconds) { return this; } + /** + * Enable/disable wifi network scan during commissioning in the the default CommissioningDelegate + * used by the ChipDeviceCommissioner. + * + * Specifically, this sets AttemptWiFiNetworkScan in the CommissioningParameters passed to the + * CommissioningDelegate. + * + * @param attemptNetworkScanWiFi + * @return + */ public Builder setAttemptNetworkScanWiFi(boolean attemptNetworkScanWiFi) { this.attemptNetworkScanWiFi = attemptNetworkScanWiFi; return this; } + /** + * Enable/disable Thread network scan during commissioning in the the default CommissioningDelegate + * used by the ChipDeviceCommissioner. + * + * Specifically, this sets AttemptThreadNetworkScan in the CommissioningParameters passed to the + * CommissioningDelegate. + * + * @param attemptNetworkScanWiFi + * @return + */ public Builder setAttemptNetworkScanThread(boolean attemptNetworkScanThread) { this.attemptNetworkScanThread = attemptNetworkScanThread; return this; @@ -169,6 +197,14 @@ public Builder setIpk(byte[] ipk) { return this; } + /** + * Sets the AdminSubject value passed to ChipDeviceCommissioner's + * CommissioningParameters. This value is passed in the AddNoc command sent to the + * commissionee and represents the subject of the default ACL created by that call. + * + * @param adminSubject + * @return + */ public Builder setAdminSubject(long adminSubject) { this.adminSubject = adminSubject; return this; From 61c820f149e850c623ac238e6645042d160be7f2 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Wed, 3 Aug 2022 13:40:02 -0700 Subject: [PATCH 10/12] address comments --- src/controller/java/AndroidDeviceControllerWrapper.cpp | 2 +- .../java/src/chip/devicecontroller/ControllerParams.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index 2f08bd5a211b92..8b28896a701d44 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -425,7 +425,7 @@ void AndroidDeviceControllerWrapper::OnCommissioningStatusUpdate(PeerId peerId, JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); jmethodID onCommissioningStatusUpdateMethod; CHIP_ERROR err = JniReferences::GetInstance().FindMethod(env, mJavaObjectRef, "onCommissioningStatusUpdate", - "(JLJAVA/LANG/STRING;I)V", &onCommissioningStatusUpdateMethod); + "(JLjava/lang/string;I)V", &onCommissioningStatusUpdateMethod); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Error finding Java method: %" CHIP_ERROR_FORMAT, err.Format())); UtfString jStageCompleted(env, StageToString(stageCompleted)); diff --git a/src/controller/java/src/chip/devicecontroller/ControllerParams.java b/src/controller/java/src/chip/devicecontroller/ControllerParams.java index 35c05f494c0816..ab30202876fb01 100644 --- a/src/controller/java/src/chip/devicecontroller/ControllerParams.java +++ b/src/controller/java/src/chip/devicecontroller/ControllerParams.java @@ -131,6 +131,9 @@ public Builder setControllerVendorId(int controllerVendorId) { * CommissioningParameters. Increasing this value from its default will allow more time * for network scans, cloud op cert signing calls, and user interaction. * + * Note: It is also possible for internal logic (within Autocommissioner, etc) to re-call + * ArmFailSafe to account for network config delays. + * * @param failsafeTimerSeconds * @return */ From 681c686355bf9726aeba2ab79dd8ebf437e1cb05 Mon Sep 17 00:00:00 2001 From: chrisdecenzo Date: Wed, 3 Aug 2022 13:47:40 -0700 Subject: [PATCH 11/12] address comments --- .../src/chip/devicecontroller/ChipDeviceController.java | 8 +++++++- .../java/src/chip/devicecontroller/ControllerParams.java | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 2e469957036877..1347957dcd34fc 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -744,7 +744,13 @@ void onNOCChainGenerationNeeded( byte[] pai); } - /** Interface to listen for scn networks callbacks from CHIPDeviceController. */ + /** + * Interface to listen for scan networks callbacks from CHIPDeviceController. + * + * Set the AttemptNetworkScanWiFi or AttemptNetworkScanThread to configure the + * enable/disable WiFi or Thread network scan during commissioning in the the default CommissioningDelegate + * used by the ChipDeviceCommissioner. + */ public interface ScanNetworksListener { /** Notifies when scan networks call fails. */ void onScanNetworksFailure(int errorCode); diff --git a/src/controller/java/src/chip/devicecontroller/ControllerParams.java b/src/controller/java/src/chip/devicecontroller/ControllerParams.java index ab30202876fb01..06052433955918 100644 --- a/src/controller/java/src/chip/devicecontroller/ControllerParams.java +++ b/src/controller/java/src/chip/devicecontroller/ControllerParams.java @@ -152,6 +152,9 @@ public Builder setFailsafeTimerSeconds(int failsafeTimerSeconds) { * Specifically, this sets AttemptWiFiNetworkScan in the CommissioningParameters passed to the * CommissioningDelegate. * + * When a WiFi scan is attempted, the result will be propagated to the ScanNetworksListener assigned + * to the ChipDeviceController. + * * @param attemptNetworkScanWiFi * @return */ @@ -167,6 +170,9 @@ public Builder setAttemptNetworkScanWiFi(boolean attemptNetworkScanWiFi) { * Specifically, this sets AttemptThreadNetworkScan in the CommissioningParameters passed to the * CommissioningDelegate. * + * When a Thread scan is attempted, the result will be propagated to the ScanNetworksListener assigned + * to the ChipDeviceController. + * * @param attemptNetworkScanWiFi * @return */ From 19f47833ed93c26100421cb0dbe650a304640439 Mon Sep 17 00:00:00 2001 From: "restyled-io[bot]" <32688539+restyled-io[bot]@users.noreply.github.com> Date: Wed, 3 Aug 2022 13:49:11 -0700 Subject: [PATCH 12/12] Restyle Draft: Add Java callbacks for NOC Generation (#21523) * Restyled by whitespace * Restyled by google-java-format * Restyled by clang-format Co-authored-by: Restyled.io --- .../AndroidOperationalCredentialsIssuer.cpp | 8 +- .../ChipDeviceController.java | 127 +++++++++--------- .../devicecontroller/ControllerParams.java | 56 ++++---- 3 files changed, 98 insertions(+), 93 deletions(-) diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp index 63a6f298561b72..b82eea4d8b21c9 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp @@ -71,9 +71,9 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::Initialize(PersistentStorageDele ReturnErrorOnFailure(mIssuer.Deserialize(serializedKey)); } - mStorage = &storage; + mStorage = &storage; mAutoCommissioner = autoCommissioner; - mJavaObjectRef = javaObjectRef; + mJavaObjectRef = javaObjectRef; mInitialized = true; return CHIP_NO_ERROR; @@ -150,7 +150,7 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B jmethodID method; CHIP_ERROR err = CHIP_NO_ERROR; err = JniReferences::GetInstance().FindMethod(JniReferences::GetInstance().GetEnvForCurrentThread(), mJavaObjectRef, - "onNOCChainGenerationNeeded", "([B[B[B[B[B[B[B[B[B)V", &method); + "onNOCChainGenerationNeeded", "([B[B[B[B[B[B[B[B[B)V", &method); if (err != CHIP_NO_ERROR) { ChipLogError(Controller, "Error invoking onNOCChainGenerationNeeded: %" CHIP_ERROR_FORMAT, err.Format()); @@ -231,7 +231,7 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::LocalGenerateNOCChain(const Byte jmethodID method; CHIP_ERROR err = CHIP_NO_ERROR; err = JniReferences::GetInstance().FindMethod(JniReferences::GetInstance().GetEnvForCurrentThread(), mJavaObjectRef, - "onOpCSRGenerationComplete", "([B)V", &method); + "onOpCSRGenerationComplete", "([B)V", &method); if (err != CHIP_NO_ERROR) { ChipLogError(Controller, "Error invoking onOpCSRGenerationComplete: %" CHIP_ERROR_FORMAT, err.Format()); diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 1347957dcd34fc..e617cb39281a49 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -63,10 +63,10 @@ public void setScanNetworksListener(ScanNetworksListener listener) { } /** - * Sets this DeviceController to use the given issuer for issuing operational certs. - * By default, the DeviceController uses an internal, OperationalCredentialsDelegate - * (see AndroidOperationalCredentialsIssuer) - * + * Sets this DeviceController to use the given issuer for issuing operational certs. By default, + * the DeviceController uses an internal, OperationalCredentialsDelegate (see + * AndroidOperationalCredentialsIssuer) + * * @param issuer */ public void setNOCChainIssuer(NOCChainIssuer issuer) { @@ -197,21 +197,20 @@ public void resumeCommissioning() { } /** - * When a NOCChainIssuer is set for this controller, then onNOCChainGenerationNeeded - * will be called when the NOC CSR needs to be signed. This allows for custom credentials - * issuer implementations, for example, when a proprietary cloud API will perform the - * CSR signing. - * - * The commissioning workflow will stop upon the onNOCChainGenerationNeeded callback - * and resume once onNOCChainGeneration is called. - * - * The following fields on the ControllerParams object MUST be populated: - * rootCertificate, intermediateCertificate, operationalCertificate - * - * If ipk and adminSubject are set on the ControllerParams object, then they will be used - * in the AddNOC command set to the commissionee. If they are not populated, then the values - * provided in the ChipDeviceController initialization will be used. - * + * When a NOCChainIssuer is set for this controller, then onNOCChainGenerationNeeded will be + * called when the NOC CSR needs to be signed. This allows for custom credentials issuer + * implementations, for example, when a proprietary cloud API will perform the CSR signing. + * + *

The commissioning workflow will stop upon the onNOCChainGenerationNeeded callback and resume + * once onNOCChainGeneration is called. + * + *

The following fields on the ControllerParams object MUST be populated: rootCertificate, + * intermediateCertificate, operationalCertificate + * + *

If ipk and adminSubject are set on the ControllerParams object, then they will be used in + * the AddNOC command set to the commissionee. If they are not populated, then the values provided + * in the ChipDeviceController initialization will be used. + * * @param params * @return CHIP_ERROR error code (0 is no error) */ @@ -219,7 +218,6 @@ public int onNOCChainGeneration(ControllerParams params) { return onNOCChainGeneration(deviceControllerPtr, params); } - /** * Update the network credentials held by the commissioner for the current commissioning session. * The updated values will be used by the commissioner if the network credentials haven't already @@ -352,19 +350,26 @@ public void onError(Throwable error) { } public void onNOCChainGenerationNeeded( - byte[] csrElements, - byte[] csrNonce, - byte[] csrElementsSignature, - byte[] attestationChallenge, - byte[] attestationElements, - byte[] attestationNonce, - byte[] attestationElementsSignature, - byte[] dac, + byte[] csrElements, + byte[] csrNonce, + byte[] csrElementsSignature, + byte[] attestationChallenge, + byte[] attestationElements, + byte[] attestationNonce, + byte[] attestationElementsSignature, + byte[] dac, byte[] pai) { if (nocChainIssuer != null) { nocChainIssuer.onNOCChainGenerationNeeded( - csrElements, csrNonce, csrElementsSignature, attestationChallenge, - attestationElements, attestationNonce, attestationElementsSignature, dac, pai); + csrElements, + csrNonce, + csrElementsSignature, + attestationChallenge, + attestationElements, + attestationNonce, + attestationElementsSignature, + dac, + pai); } } @@ -687,7 +692,8 @@ private native boolean openPairingWindowWithPINCallback( private native void resumeCommissioning(long deviceControllerPtr); - private native void setUseJavaCallbackForNOCRequest(long deviceControllerPtr, boolean useCallback); + private native void setUseJavaCallbackForNOCRequest( + long deviceControllerPtr, boolean useCallback); private native void updateCommissioningNetworkCredentials( long deviceControllerPtr, NetworkCredentials networkCredentials); @@ -714,42 +720,41 @@ protected void finalize() throws Throwable { /** Interface to implement custom operational credentials issuer (NOC chain generation). */ public interface NOCChainIssuer { - /** - * When a NOCChainIssuer is set for this controller, then onNOCChainGenerationNeeded - * will be called when the NOC CSR needs to be signed. This allows for custom credentials - * issuer implementations, for example, when a proprietary cloud API will perform the - * CSR signing. - * - * The commissioning workflow will stop upon the onNOCChainGenerationNeeded callback - * and resume once onNOCChainGeneration is called. - * - * The following fields on the ControllerParams object passed to onNOCChainGeneration - * MUST be populated: rootCertificate, intermediateCertificate, operationalCertificate - * - * If ipk and adminSubject are set on the ControllerParams object, then they will be used - * in the AddNOC command set to the commissionee. If they are not populated, then the values + /** + * When a NOCChainIssuer is set for this controller, then onNOCChainGenerationNeeded will be + * called when the NOC CSR needs to be signed. This allows for custom credentials issuer + * implementations, for example, when a proprietary cloud API will perform the CSR signing. + * + *

The commissioning workflow will stop upon the onNOCChainGenerationNeeded callback and + * resume once onNOCChainGeneration is called. + * + *

The following fields on the ControllerParams object passed to onNOCChainGeneration MUST be + * populated: rootCertificate, intermediateCertificate, operationalCertificate + * + *

If ipk and adminSubject are set on the ControllerParams object, then they will be used in + * the AddNOC command set to the commissionee. If they are not populated, then the values * provided in the ChipDeviceController initialization will be used. - * - * All csr and attestation fields are provided to allow for custom attestestation checks. + * + *

All csr and attestation fields are provided to allow for custom attestestation checks. */ void onNOCChainGenerationNeeded( - byte[] csrElements, - byte[] csrNonce, - byte[] csrElementsSignature, - byte[] attestationChallenge, - byte[] attestationElements, - byte[] attestationNonce, - byte[] attestationElementsSignature, - byte[] dac, + byte[] csrElements, + byte[] csrNonce, + byte[] csrElementsSignature, + byte[] attestationChallenge, + byte[] attestationElements, + byte[] attestationNonce, + byte[] attestationElementsSignature, + byte[] dac, byte[] pai); } - /** - * Interface to listen for scan networks callbacks from CHIPDeviceController. - * - * Set the AttemptNetworkScanWiFi or AttemptNetworkScanThread to configure the - * enable/disable WiFi or Thread network scan during commissioning in the the default CommissioningDelegate - * used by the ChipDeviceCommissioner. + /** + * Interface to listen for scan networks callbacks from CHIPDeviceController. + * + *

Set the AttemptNetworkScanWiFi or AttemptNetworkScanThread to configure the enable/disable + * WiFi or Thread network scan during commissioning in the the default CommissioningDelegate used + * by the ChipDeviceCommissioner. */ public interface ScanNetworksListener { /** Notifies when scan networks call fails. */ diff --git a/src/controller/java/src/chip/devicecontroller/ControllerParams.java b/src/controller/java/src/chip/devicecontroller/ControllerParams.java index 06052433955918..42fd04f42907de 100644 --- a/src/controller/java/src/chip/devicecontroller/ControllerParams.java +++ b/src/controller/java/src/chip/devicecontroller/ControllerParams.java @@ -127,13 +127,13 @@ public Builder setControllerVendorId(int controllerVendorId) { } /** - * Sets the FailsafeTimer duration passed to ChipDeviceCommissioner's - * CommissioningParameters. Increasing this value from its default will allow more time - * for network scans, cloud op cert signing calls, and user interaction. - * - * Note: It is also possible for internal logic (within Autocommissioner, etc) to re-call + * Sets the FailsafeTimer duration passed to ChipDeviceCommissioner's CommissioningParameters. + * Increasing this value from its default will allow more time for network scans, cloud op cert + * signing calls, and user interaction. + * + *

Note: It is also possible for internal logic (within Autocommissioner, etc) to re-call * ArmFailSafe to account for network config delays. - * + * * @param failsafeTimerSeconds * @return */ @@ -146,15 +146,15 @@ public Builder setFailsafeTimerSeconds(int failsafeTimerSeconds) { } /** - * Enable/disable wifi network scan during commissioning in the the default CommissioningDelegate - * used by the ChipDeviceCommissioner. - * - * Specifically, this sets AttemptWiFiNetworkScan in the CommissioningParameters passed to the - * CommissioningDelegate. - * - * When a WiFi scan is attempted, the result will be propagated to the ScanNetworksListener assigned - * to the ChipDeviceController. - * + * Enable/disable wifi network scan during commissioning in the the default + * CommissioningDelegate used by the ChipDeviceCommissioner. + * + *

Specifically, this sets AttemptWiFiNetworkScan in the CommissioningParameters passed to + * the CommissioningDelegate. + * + *

When a WiFi scan is attempted, the result will be propagated to the ScanNetworksListener + * assigned to the ChipDeviceController. + * * @param attemptNetworkScanWiFi * @return */ @@ -164,15 +164,15 @@ public Builder setAttemptNetworkScanWiFi(boolean attemptNetworkScanWiFi) { } /** - * Enable/disable Thread network scan during commissioning in the the default CommissioningDelegate - * used by the ChipDeviceCommissioner. - * - * Specifically, this sets AttemptThreadNetworkScan in the CommissioningParameters passed to the - * CommissioningDelegate. - * - * When a Thread scan is attempted, the result will be propagated to the ScanNetworksListener assigned - * to the ChipDeviceController. - * + * Enable/disable Thread network scan during commissioning in the the default + * CommissioningDelegate used by the ChipDeviceCommissioner. + * + *

Specifically, this sets AttemptThreadNetworkScan in the CommissioningParameters passed to + * the CommissioningDelegate. + * + *

When a Thread scan is attempted, the result will be propagated to the ScanNetworksListener + * assigned to the ChipDeviceController. + * * @param attemptNetworkScanWiFi * @return */ @@ -207,10 +207,10 @@ public Builder setIpk(byte[] ipk) { } /** - * Sets the AdminSubject value passed to ChipDeviceCommissioner's - * CommissioningParameters. This value is passed in the AddNoc command sent to the - * commissionee and represents the subject of the default ACL created by that call. - * + * Sets the AdminSubject value passed to ChipDeviceCommissioner's CommissioningParameters. This + * value is passed in the AddNoc command sent to the commissionee and represents the subject of + * the default ACL created by that call. + * * @param adminSubject * @return */