Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2021 Project CHIP Authors 4 : * 5 : * Licensed under the Apache License, Version 2.0 (the "License"); 6 : * you may not use this file except in compliance with the License. 7 : * You may obtain a copy of the License at 8 : * 9 : * http://www.apache.org/licenses/LICENSE-2.0 10 : * 11 : * Unless required by applicable law or agreed to in writing, software 12 : * distributed under the License is distributed on an "AS IS" BASIS, 13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 : * See the License for the specific language governing permissions and 15 : * limitations under the License. 16 : */ 17 : 18 : #pragma once 19 : 20 : #include <credentials/CertificateValidityPolicy.h> 21 : #include <credentials/GroupDataProvider.h> 22 : #include <messaging/ExchangeDelegate.h> 23 : #include <messaging/ExchangeMgr.h> 24 : #include <protocols/secure_channel/CASESession.h> 25 : #include <system/SystemClock.h> 26 : 27 : namespace chip { 28 : 29 : class CASEServer : public SessionEstablishmentDelegate, 30 : public Messaging::UnsolicitedMessageHandler, 31 : public Messaging::ExchangeDelegate 32 : { 33 : public: 34 1 : CASEServer() {} 35 1 : ~CASEServer() override { Shutdown(); } 36 : 37 : /* 38 : * This method will shutdown this object, releasing the strong reference to the pinned SecureSession object. 39 : * It will also unregister the unsolicited handler and clear out the session object (which will release the weak 40 : * reference through the underlying SessionHolder). 41 : * 42 : */ 43 2 : void Shutdown() 44 : { 45 2 : if (mExchangeManager != nullptr) 46 : { 47 1 : mExchangeManager->UnregisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::MsgType::CASE_Sigma1); 48 1 : mExchangeManager = nullptr; 49 : } 50 : 51 2 : GetSession().Clear(); 52 2 : mPinnedSecureSession.ClearValue(); 53 2 : } 54 : 55 : CHIP_ERROR ListenForSessionEstablishment(Messaging::ExchangeManager * exchangeManager, SessionManager * sessionManager, 56 : FabricTable * fabrics, SessionResumptionStorage * sessionResumptionStorage, 57 : Credentials::CertificateValidityPolicy * policy, 58 : Credentials::GroupDataProvider * responderGroupDataProvider); 59 : 60 : //////////// SessionEstablishmentDelegate Implementation /////////////// 61 : void OnSessionEstablishmentError(CHIP_ERROR error) override; 62 : void OnSessionEstablished(const SessionHandle & session) override; 63 : 64 : //// UnsolicitedMessageHandler Implementation //// 65 : CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) override; 66 : 67 : //// ExchangeDelegate Implementation //// 68 : CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader, 69 : System::PacketBufferHandle && payload) override; 70 0 : void OnResponseTimeout(Messaging::ExchangeContext * ec) override {} 71 8 : Messaging::ExchangeMessageDispatch & GetMessageDispatch() override { return GetSession().GetMessageDispatch(); } 72 : 73 6 : CASESession & GetSession() { return mPairingSession; } 74 : 75 : private: 76 : Messaging::ExchangeManager * mExchangeManager = nullptr; 77 : SessionResumptionStorage * mSessionResumptionStorage = nullptr; 78 : Credentials::CertificateValidityPolicy * mCertificateValidityPolicy = nullptr; 79 : 80 : // 81 : // When we're in the process of establishing a session, this is used 82 : // to maintain an additional, strong reference to the underlying SecureSession. 83 : // This is because the existing reference in PairingSession is a weak one 84 : // (i.e a SessionHolder) and can lose its reference if the session is evicted 85 : // for any reason. 86 : // 87 : // This initially points to a session that is not yet active. Upon activation, it 88 : // transfers ownership of the session to the SecureSessionManager and this reference 89 : // is released before simultaneously acquiring ownership of a new SecureSession. 90 : // 91 : Optional<SessionHandle> mPinnedSecureSession; 92 : 93 : CASESession mPairingSession; 94 : SessionManager * mSessionManager = nullptr; 95 : 96 : FabricTable * mFabrics = nullptr; 97 : Credentials::GroupDataProvider * mGroupDataProvider = nullptr; 98 : 99 : CHIP_ERROR InitCASEHandshake(Messaging::ExchangeContext * ec); 100 : 101 : /* 102 : * This will clean up any state from a previous session establishment 103 : * attempt (if any) and setup the machinery to listen for and handle 104 : * any session handshakes there-after. 105 : * 106 : * If a session had previously been established successfully, previouslyEstablishedPeer 107 : * should be set to the scoped node-id of the peer associated with that session. 108 : * 109 : */ 110 : void PrepareForSessionEstablishment(const ScopedNodeId & previouslyEstablishedPeer = ScopedNodeId()); 111 : 112 : // If we are in the middle of handshake and receive a Sigma1 then respond with Busy status code. 113 : // @param[in] ec Exchange Context 114 : // @param[in] minimumWaitTime Minimum wait time reported to client before it can attempt to resend sigma1 115 : // 116 : // @return CHIP_NO_ERROR on success, error code otherwise 117 : CHIP_ERROR SendBusyStatusReport(Messaging::ExchangeContext * ec, System::Clock::Milliseconds16 minimumWaitTime); 118 : }; 119 : 120 : } // namespace chip