-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API SecureManager::SendMessage, use SecureSessoinHandle instead NodeId #3728
Conversation
e6e55e3
to
04dadc4
Compare
Before I resolve all CI failures, I want to collect opinions first. |
I have conmcerns about the approach: I agree with the intent that there may be more communication paths than 1 to a node, which we plan to call 'exchanges'. The PeerConnectionState however was meant to encapsulate things like encryption keys and counters, which applications should not see. I would rather imagine we would like something like a 'connectionID' exposed that could be something like a pair<nodeid, exchangeid>. This sounds like a minimal information required rather than an entire large structure pointer. |
Marked as 'changes requested' since I believe the PeerConnectionState to be too large of an object to pass around and ideally API boundaries should be with smaller pieces of data. |
I would also like to understand the scenario where the user of the secure session manager is aware of SPAKE based connection vs Sigma based connection. Currently, SPAKE based secure session is only used by Rendezvous state machine. It's not exposed to the controller or the ZCL layer. The multiple peer connections between two nodes are supported, but mainly for
The first could be disambiguated by adding a multicast API to the secure session manager. |
I agree with this part, an
Problem 1 and 2 may not be a real problem, but 3 is. Lets focus on the changes., How to implement |
What value (besides peer node ID) would be needed to look up the peer certificates? Is it peer's encryption key ID. |
Yes, using |
@pan-apple, still looking at this? |
I'm looking for suggestions to move forward. Both |
I don't have a strong opinion on either approach. Exposing the |
b735d46
to
e577fe1
Compare
|
||
VerifyOrExit(state->GetPeerNodeId() != kUndefinedNodeId, ChipLogProgress(AppServer, "Unknown source for received message")); | ||
|
||
state->GetPeerAddress().ToString(src_addr, sizeof(src_addr)); | ||
|
||
ChipLogProgress(AppServer, "Packet received from %s: %zu bytes", src_addr, static_cast<size_t>(data_len)); | ||
|
||
HandleDataModelMessage(header, std::move(buffer), mgr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe switch this code to reporting the node id instead of the source address (which it can get from the SecureSessionHandle
, presumably, at least for a CASE session)? Either way, keeping the "we got N bytes logging" would be useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The member of the SecureSessionHandle
is not decided yet. I don't want to expose the internal detail of SecureSessionHandle
class.
I'm still considering how do we get information from session handle interface. Maybe:
auto session = mSecureSessionManager->GetSession(handle /* an secure session handle */);
bool isPaseSession = session->IsPaseSession(); // or session->IsCaseSession() for case check.
auto nodeid = session->GetPeerNodeId();
auto localKey = session->GetLocalKeyId();
auto peerKey = session->GetPeerKeyId();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fair, but we really will need a way to get the peer node ID for CASE sessions. And we really should keep the length logging here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good, I'll make it so.
void Device::OnNewConnection(SecureSessionHandle session, SecureSessionMgr * mgr) | ||
{ | ||
mState = ConnectionState::SecureConnected; | ||
mSecureSession = session; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we expect SecureSessionHandle
to always be copyable? Or are we likely to switch to move semantics on it at some point? Put another way, should there be an std::move()
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'll expect that the handle is POD, and always be copyable. In the future, only messaging layer will use the handle, the handle class won't be exposed to applications or controller API.
src/controller/CHIPDevice.cpp
Outdated
|
||
void Device::OnConnectionExpired(SecureSessionHandle session, SecureSessionMgr * mgr) | ||
{ | ||
mState = ConnectionState::NotConnected; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should mSecureSession
be reset in some way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/controller/CHIPDevice.h
Outdated
* @brief | ||
* Called when a new pairing is being established | ||
* | ||
* @param state connection state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no such param
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/controller/CHIPDevice.h
Outdated
* | ||
* The receiver should release all resources associated with the connection. | ||
* | ||
* @param state connection state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No such param...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/controller/CHIPDevice.h
Outdated
@@ -191,6 +213,8 @@ class DLL_EXPORT Device | |||
|
|||
NodeId GetDeviceId() const { return mDeviceId; } | |||
|
|||
SecureSessionHandle GetSecureSession() const { return mSecureSession; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What will this return if OnNewConnection
has not happened yet? Will it even be initialized memory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll remove GetSecureSession
. The session should not be exposed.
@@ -395,6 +429,21 @@ void DeviceController::ReleaseAllDevices() | |||
} | |||
} | |||
|
|||
uint16_t DeviceController::FindDeviceIndex(SecureSessionHandle session) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is what the code used to look like with node id, but is there a reason this is not FindDevice
returning Device *
, with nullptr
returned if not found? Then we could use a ranged for loop instead of the indexing we are doing now, and callers wouldn't need to index back into the array; they would just use the pointer they got, if not null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While audit the usage of FindDeviceIndex
, I don't think there is any reason preventing it from returning a Device *
.
We can refactor it in another PR. but here I want to keep it consistent with FindDeviceIndex(NodeId id)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, followup is fine. Just file an issue, please.
{ | ||
public: | ||
SecureSessionHandle() : mPeerNodeId(kAnyNodeId), mPeerKeyId(0) {} | ||
SecureSessionHandle(NodeId peerNodeId, uint16_t peerKeyId) : mPeerNodeId(peerNodeId), mPeerKeyId(peerKeyId) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this constructor be protected, so only SecureSessionMgr
can use it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the future, it is. But for now, InteractionModel need to create it using this one.
7ced116
to
ac4f84e
Compare
@pan-apple @andy31415 this one is ready for merge, please do a final check. In the future, I may need to change the member if |
This one is ready for merge |
@kghost conflict |
Size increase report for "esp32-example-build" from 4bb0e53
Full report output
|
Size increase report for "nrfconnect-example-build" from 4bb0e53
Full report output
|
This change seems break the end-to-end messaging testing which is temporarily disabled in CI. With this change, the app does not specify the target NodeID, but relay on the following callback to update the SecureSessionHandle.
We can only specify one delegate of SecureSessionMgr at a time, but there are multiple connections managed by the SecureSessionMgr, how we make sure the SecureSessionMgr can pass the generated SecureSessionHandle to the corresponding target of its connection? For example, there are multiple objects are set as the delegate of SecureSessionMgr, including DeviceController, ExchangeManager and application itself. The later SetDelegate() will overwrite the previous one. Echo Application: The echo application won't received the generated SecureSessionHandle and it will sendMessage to garbage target. |
Register #4451 to track this issue. |
Problem
Currently
SecureSessionMgrBase::SendMessage
takes aPeerNodeId
as key to find properPeerConnectionState
, but is way may causing unexpected behavior. For example.Summary of Changes
SecureSessionMgrBase::SendMessage
take aTransport::PeerConnectionState *
instead ofPeerNodeId
SecureSessionMgrDelegate::OnNewConnection
so that upper components can receive aPeerConnectionState
objectSecureSessionMgrDelegate::OnConnectionExpired
callback, so upper components can acknowledge that the connection has been released.