| /* |
| * |
| * Copyright (c) 2013-2017 Nest Labs, Inc. |
| * All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @file |
| * This file defines data types and objects for managing the |
| * active node state necessary to participate in a Weave fabric. |
| * |
| */ |
| |
| #ifndef WEAVE_FABRIC_STATE_H |
| #define WEAVE_FABRIC_STATE_H |
| |
| #ifndef __STDC_FORMAT_MACROS |
| #define __STDC_FORMAT_MACROS |
| #endif |
| |
| #ifndef __STDC_LIMIT_MACROS |
| #define __STDC_LIMIT_MACROS |
| #endif |
| |
| #include <inttypes.h> |
| |
| #include <Weave/Support/NLDLLUtil.h> |
| #include <Weave/Support/WeaveCounter.h> |
| #include <Weave/Support/PersistedCounter.h> |
| #include <Weave/Support/FlagUtils.hpp> |
| #include <Weave/Core/WeaveCore.h> |
| #include <Weave/Core/WeaveKeyIds.h> |
| #include <Weave/Profiles/security/WeaveSecurity.h> |
| #include <Weave/Profiles/security/WeaveApplicationKeys.h> |
| |
| namespace nl { |
| namespace Weave { |
| |
| class NL_DLL_EXPORT WeaveConnection; |
| class NL_DLL_EXPORT WeaveMessageLayer; |
| class NL_DLL_EXPORT WeaveExchangeManager; |
| struct WeaveMessageInfo; |
| |
| // Special node id values. |
| enum |
| { |
| kNodeIdNotSpecified = 0ULL, |
| kAnyNodeId = 0xFFFFFFFFFFFFFFFFULL |
| }; |
| |
| // Special fabric id values. |
| enum |
| { |
| kFabricIdNotSpecified = 0ULL, |
| |
| /** Default fabric ID, which should only be used for testing purposes. */ |
| kFabricIdDefaultForTest = 1ULL, |
| |
| // Ids >= kReservedFabricIdStart and <= kMaxFabricId are reserved for special uses. The |
| // meanings of values in this range are context-specific; e.g. in the IdentifyRequest |
| // message, these value are used to match devices that are/are not members of a fabric. |
| kReservedFabricIdStart = 0xFFFFFFFFFFFFFF00ULL, |
| |
| kMaxFabricId = 0xFFFFFFFFFFFFFFFFULL |
| }; |
| |
| /** Identifies the purpose or application of certificate |
| * |
| * A certificate type is a label that describes a certificate's purpose or application. |
| * Certificate types are not carried as attributes of the corresponding certificates, but |
| * rather are derived from the certificate's structure and/or the context in which it is used. |
| * The certificate type enumeration includes a set of pre-defined values describing commonly |
| * used certificate applications. Developers can also extend the certificate type value |
| * range with application-specific types that described custom certificates or certificates |
| * with unique security properties. |
| * |
| * Certificate types are primarily used in the implementation of access control policies, |
| * where access to application features is influenced by the type of certificate presented |
| * by a requester. |
| * |
| * @note Cert type is an API data type only; it should never be sent over-the-wire. |
| */ |
| enum |
| { |
| // NOTE: When adding additional types, please update the PrintCertType() function. |
| |
| kCertType_NotSpecified = 0x00, /**< The certificate's type has not been specified. */ |
| kCertType_General = 0x01, /**< The certificate is of a general or non-specific type. */ |
| kCertType_Device = 0x02, /**< A Weave device certificate. */ |
| kCertType_ServiceEndpoint = 0x03, /**< A Weave service endpoint certificate. */ |
| kCertType_FirmwareSigning = 0x04, /**< A Weave firmware signing certificate. */ |
| kCertType_AccessToken = 0x05, /**< A Weave access token certificate. */ |
| kCertType_CA = 0x06, /**< A CA certificate. */ |
| |
| kCertType_AppDefinedBase = 0x7F, /**< Application-specific certificate types should have values >= this value. */ |
| |
| kCertType_Max = 0xFF, /**< Certificate types should not be greater than this value. */ |
| }; |
| |
| /** Identifies the source for the password used in a password-based authentication protocol (e.g. Weave PASE) |
| * |
| * @note Password Source is protocol data type; do not renumber. |
| */ |
| enum |
| { |
| kPasswordSource_NotSpecified = 0x0, |
| kPasswordSource_PairingCode = 0x1, |
| |
| kPasswordSource_Max = 0xF, |
| }; |
| |
| |
| /** Identifies how a peer node is authenticated. |
| * |
| * WeaveAuthMode describes the means by which a peer node has been, or should be, |
| * authenticated during a Weave message exchange. In an initiating context, |
| * applications use WeaveAuthMode to express a desired peer authentication mode |
| * for an exchange, thereby instructing the Weave security and messaging layers |
| * to achieve the desired mode or fail the communication. In a responding context, |
| * WeaveAuthMode identifies how the requesting node (the peer) was authenticated, |
| * allowing the responding application to enforce access controls based on this |
| * information. |
| * |
| * The WeaveAuthMode assigned to an incoming Weave message is related to the nature |
| * of the key that was used to encrypt that message. The WeaveAuthMode derives from |
| * the mechanism by which the key was established and the criteria used to verify the |
| * identities of the communicating parties at the time of key establishment. |
| * |
| * WeaveAuthMode includes a set of pre-defined values describing common |
| * authentication modes. These are broken down by the key agreement mechanism |
| * (CASE, PASE, GroupKey, etc.). Developers can extend WeaveAuthMode by defining |
| * application-specific mode, which they can attach to specific encryption keys. |
| * |
| * @note WeaveAuthMode is an API data type only; it should never be sent over-the-wire. |
| */ |
| typedef uint16_t WeaveAuthMode; |
| enum |
| { |
| kWeaveAuthMode_NotSpecified = 0x0000, /**< Authentication mode not specified. */ |
| |
| // ===== Major authentication categories ===== |
| kWeaveAuthModeCategory_General = 0x0000, /**< Peer authenticated using one of a set of general mechanisms */ |
| kWeaveAuthModeCategory_PASE = 0x1000, /**< Peer authenticated using Weave PASE protocol */ |
| kWeaveAuthModeCategory_CASE = 0x2000, /**< Peer authenticated using Weave CASE protocol */ |
| kWeaveAuthModeCategory_TAKE = 0x3000, /**< Peer authenticated using Weave TAKE protocol */ |
| kWeaveAuthModeCategory_GroupKey = 0x4000, /**< Peer authenticated using a shared group key */ |
| kWeaveAuthModeCategory_AppDefinedBase = 0xC000, /**< Base value for application-defined authentication categories */ |
| |
| // ===== General authentication modes ===== |
| kWeaveAuthMode_Unauthenticated = kWeaveAuthModeCategory_General | 0x001, |
| /**< Peer not authenticated. */ |
| |
| // ===== PASE authentication modes ===== |
| kWeaveAuthMode_PASE_PairingCode = kWeaveAuthModeCategory_PASE | kPasswordSource_PairingCode, |
| /**< Peer authenticated using PASE with device pairing code. */ |
| |
| // ===== CASE authentication modes ===== |
| kWeaveAuthMode_CASE_AnyCert = kWeaveAuthModeCategory_CASE | kCertType_NotSpecified, |
| /**< Peer authenticated using CASE with arbitrary certificate, or certificate of unknown type. */ |
| kWeaveAuthMode_CASE_GeneralCert = kWeaveAuthModeCategory_CASE | kCertType_General, |
| /**< Peer authenticated using CASE with a general, or non-specific certificate type. */ |
| kWeaveAuthMode_CASE_Device = kWeaveAuthModeCategory_CASE | kCertType_Device, |
| /**< Peer authenticated using CASE with Weave device certificate. */ |
| kWeaveAuthMode_CASE_ServiceEndPoint = kWeaveAuthModeCategory_CASE | kCertType_ServiceEndpoint, |
| /**< Peer authenticated using CASE with Weave service endpoint certificate. */ |
| kWeaveAuthMode_CASE_AccessToken = kWeaveAuthModeCategory_CASE | kCertType_AccessToken, |
| /**< Peer authenticated using CASE with Weave access token certificate. */ |
| |
| // ===== TAKE authentication modes ===== |
| kWeaveAuthMode_TAKE_IdentificationKey = kWeaveAuthModeCategory_TAKE | 0x001, |
| /**< Peer authenticated using TAKE with a token identification key. */ |
| |
| // ===== Subfield Masks ===== |
| kWeaveAuthModeCategory_Mask = 0xF000, |
| kWeaveAuthMode_PASE_PasswordSourceMask = kPasswordSource_Max, |
| kWeaveAuthMode_CASE_CertTypeMask = kCertType_Max, |
| kWeaveAuthMode_GroupKey_AppGroupLocalNumber = WeaveKeyId::kGroupLocalNumber_Max, |
| |
| // ===== DEPRECATED ALIASES ===== |
| kWeaveAuthMode_None = kWeaveAuthMode_Unauthenticated, |
| kWeaveAuthMode_Password_PairingCode = kWeaveAuthMode_PASE_PairingCode, |
| kWeaveAuthMode_Cert_Device = kWeaveAuthMode_CASE_Device, |
| kWeaveAuthMode_Cert_ServiceEndPoint = kWeaveAuthMode_CASE_ServiceEndPoint, |
| }; |
| |
| /** True if the authentication mode is based on the Weave PASE protocol. */ |
| inline bool IsPASEAuthMode(WeaveAuthMode authMode) { return (authMode & kWeaveAuthModeCategory_Mask) == kWeaveAuthModeCategory_PASE; } |
| |
| /** True if the authentication mode is based on the Weave CASE protocol. */ |
| inline bool IsCASEAuthMode(WeaveAuthMode authMode) { return (authMode & kWeaveAuthModeCategory_Mask) == kWeaveAuthModeCategory_CASE; } |
| |
| /** True if the authentication mode is based on the Weave TAKE protocol. */ |
| inline bool IsTAKEAuthMode(WeaveAuthMode authMode) { return (authMode & kWeaveAuthModeCategory_Mask) == kWeaveAuthModeCategory_TAKE; } |
| |
| /** True if the authentication mode is based possession of a shared password. */ |
| inline bool IsPasswordAuthMode(WeaveAuthMode authMode) { return IsPASEAuthMode(authMode); } |
| |
| /** True if the authentication mode is based on possession of a private key associated with a certificate. */ |
| inline bool IsCertAuthMode(WeaveAuthMode authMode) { return IsCASEAuthMode(authMode); } |
| |
| /** True if the authentication mode is based on possession of a shared group key. */ |
| inline bool IsGroupKeyAuthMode(WeaveAuthMode authMode) { return (authMode & kWeaveAuthModeCategory_Mask) == kWeaveAuthModeCategory_GroupKey; } |
| |
| /** Returns the password source for the given authentication mode. |
| * |
| * @note The result is only valid when the supplied mode is one of the password authentication modes. |
| */ |
| inline uint8_t PasswordSourceFromAuthMode(WeaveAuthMode authMode) { return (uint8_t)(authMode & kWeaveAuthMode_PASE_PasswordSourceMask); } |
| |
| /** Returns the password source for the given authentication mode. |
| * |
| * @note The result is only valid when the supplied mode is one of the certificate authentication modes. |
| */ |
| inline uint8_t CertTypeFromAuthMode(WeaveAuthMode authMode) { return (uint8_t)(authMode & kWeaveAuthMode_CASE_CertTypeMask); } |
| |
| /** Returns the application group master key ID associated with the authentication mode. |
| * |
| * @note The result is only valid when the supplied mode is one of the group key modes. |
| */ |
| inline uint8_t AppGroupMasterKeyIdFromAuthMode(WeaveAuthMode authMode) { return WeaveKeyId::MakeAppGroupMasterKeyId(authMode & kWeaveAuthMode_GroupKey_AppGroupLocalNumber); } |
| |
| /** Returns a corresponding PASE authentication mode for a given password source. */ |
| inline WeaveAuthMode PASEAuthMode(uint8_t pwSource) { return kWeaveAuthModeCategory_PASE | pwSource; } |
| |
| /** Returns a corresponding CASE authentication mode for a given certificate type. */ |
| inline WeaveAuthMode CASEAuthMode(uint8_t certType) { return kWeaveAuthModeCategory_CASE | certType; } |
| |
| /** Returns a corresponding group key authentication mode for a given key ID. |
| * |
| * @note The result is only valid when the supplied key ID is an application group key. |
| */ |
| inline WeaveAuthMode GroupKeyAuthMode(uint32_t keyId) { return kWeaveAuthModeCategory_GroupKey | WeaveKeyId::GetAppGroupLocalNumber(keyId); } |
| |
| |
| /** |
| * @typedef FabricSecretScope |
| * |
| * @brief |
| * Identifies the category of devices that can possess and use fabric secret. |
| * |
| * @note FabricSecretScope is protocol data type; do not renumber. |
| */ |
| typedef uint8_t FabricSecretScope; |
| enum |
| { |
| kFabricSecretScope_All = 0x00 /**< All devices can possess corresponding fabric secret. */ |
| }; |
| |
| // Encryption key for the AES-128-CTR-SHA-1 message encryption type |
| class WeaveEncryptionKey_AES128CTRSHA1 |
| { |
| public: |
| enum |
| { |
| DataKeySize = 16, |
| DataKeySizeInWords = DataKeySize/sizeof(uint32_t), |
| IntegrityKeySize = 20, |
| KeySize = DataKeySize + IntegrityKeySize |
| }; |
| |
| union { |
| uint8_t DataKey[DataKeySize]; |
| uint32_t DataKeyWords[DataKeySizeInWords]; |
| }; |
| uint8_t IntegrityKey[IntegrityKeySize]; |
| }; |
| |
| // Represents a key or key set used to encrypt Weave messages. |
| typedef union WeaveEncryptionKey |
| { |
| WeaveEncryptionKey_AES128CTRSHA1 AES128CTRSHA1; |
| } WeaveEncryptionKey; |
| |
| // AES128CTRSHA1 encryption and integrity test keys, which should only be used for testing purposes. |
| enum |
| { |
| kTestKey_AES128CTRSHA1_DataKeyByte = 0xAB, /**< Byte value that constructs encryption key, which is used only for testing. */ |
| kTestKey_AES128CTRSHA1_IntegrityKeyByte = 0xBA /**< Byte value that constructs integrity key, which is used only for testing. */ |
| }; |
| |
| /** |
| * @class WeaveMsgEncryptionKey |
| * |
| * @brief |
| * Contains information about Weave message encryption key. |
| * |
| */ |
| class WeaveMsgEncryptionKey |
| { |
| public: |
| uint16_t KeyId; /**< The key ID. */ |
| uint8_t EncType; /**< The encryption type supported by the key. */ |
| WeaveEncryptionKey EncKey; /**< The secret key material. */ |
| }; |
| |
| // WeaveSessionState -- Conveys the communication state needed to send/receive messages with another node. |
| class WeaveSessionState |
| { |
| public: |
| |
| typedef uint16_t ReceiveFlagsType; |
| |
| enum |
| { |
| kReceiveFlags_NumMessageIdFlags = (sizeof(ReceiveFlagsType) * 8) - 1, |
| kReceiveFlags_MessageIdSynchronized = (1 << kReceiveFlags_NumMessageIdFlags), |
| kReceiveFlags_MessageIdFlagsMask = ~kReceiveFlags_MessageIdSynchronized |
| }; |
| |
| WeaveSessionState(void); |
| WeaveSessionState(WeaveMsgEncryptionKey *msgEncKey, WeaveAuthMode authMode, |
| MonotonicallyIncreasingCounter *nextMsgId, uint32_t *maxRcvdMsgId, ReceiveFlagsType *rcvFlags); |
| |
| WeaveMsgEncryptionKey *MsgEncKey; |
| WeaveAuthMode AuthMode; |
| |
| uint32_t NewMessageId(void); |
| bool MessageIdNotSynchronized(void); |
| bool IsDuplicateMessage(uint32_t msgId); |
| |
| private: |
| MonotonicallyIncreasingCounter *NextMsgId; |
| uint32_t *MaxMsgIdRcvd; |
| ReceiveFlagsType *RcvFlags; |
| }; |
| |
| // WeaveSessionKey -- Contains information about a Weave session key. |
| class WeaveSessionKey |
| { |
| public: |
| enum FlagsEnum |
| { |
| kFlag_IsLocallyInitiated = 0x01, // The session was initiated by the local node. |
| kFlag_IsSharedSession = 0x02, // The session is a shared session. |
| kFlag_IsRemoveOnIdle = 0x04, // The session should be removed when idle (only applies to sessions |
| // that are not bound to a connection). |
| kFlag_RecentlyActive = 0x08, // The session was recently active. |
| }; |
| |
| uint64_t NodeId; // The id of the node with which the session key is shared. |
| MonotonicallyIncreasingCounter NextMsgId; // The next message id to be used under the session key. |
| uint32_t MaxRcvdMsgId; // The maximum message id received under the session key. |
| WeaveConnection *BoundCon; // The connection to which the key is bound. |
| WeaveSessionState::ReceiveFlagsType RcvFlags; // Flags tracking messages received under the key. |
| WeaveAuthMode AuthMode; // The means by which the peer node was authenticated during session establishment. |
| WeaveMsgEncryptionKey MsgEncKey; // The Weave message encryption key. |
| uint8_t ReserveCount; // Number of times the session key has been reserved. |
| uint8_t Flags; // Various flags associated with the session. |
| |
| void Init(void); |
| void Clear(void); |
| |
| bool IsAllocated() const { return MsgEncKey.KeyId != WeaveKeyId::kNone; } |
| bool IsKeySet() const { return MsgEncKey.EncType != 0; } |
| bool IsLocallyInitiated() const { return GetFlag(Flags, kFlag_IsLocallyInitiated); } |
| void SetLocallyInitiated(bool val) { SetFlag(Flags, kFlag_IsLocallyInitiated, val); } |
| bool IsSharedSession() const { return GetFlag(Flags, kFlag_IsSharedSession); } |
| void SetSharedSession(bool val) { SetFlag(Flags, kFlag_IsSharedSession, val); } |
| bool IsRemoveOnIdle() const { return GetFlag(Flags, kFlag_IsRemoveOnIdle); } |
| void SetRemoveOnIdle(bool val) { SetFlag(Flags, kFlag_IsRemoveOnIdle, val); } |
| bool IsRecentlyActive() const { return GetFlag(Flags, kFlag_RecentlyActive); } |
| void MarkRecentlyActive() { SetFlag(Flags, kFlag_RecentlyActive); } |
| void ClearRecentlyActive() { ClearFlag(Flags, kFlag_RecentlyActive); } |
| }; |
| |
| // Key cache for Weave message encryption keys. |
| class WeaveMsgEncryptionKeyCache |
| { |
| public: |
| void Init(void); |
| void Reset(void); |
| void Shutdown(void); |
| |
| WeaveMsgEncryptionKey *FindOrAllocateKeyEntry(uint16_t keyId, uint8_t encType); |
| |
| private: |
| // Array of Weave message encryption keys. |
| WeaveMsgEncryptionKey mKeyCache[WEAVE_CONFIG_MAX_CACHED_MSG_ENC_APP_KEYS]; |
| // Array of key entry indexes in sorted order from most- to least- recently used. |
| uint8_t mMostRecentlyUsedKeyEntries[WEAVE_CONFIG_MAX_CACHED_MSG_ENC_APP_KEYS]; |
| |
| void Clear(uint8_t keyEntryIndex); |
| }; |
| |
| /** |
| * @brief |
| * Key diversifier used for Weave message encryption key derivation. This value |
| * represents first 4 bytes of the SHA-1 HASH of "Nest Weave Message EK and AK" phrase. |
| */ |
| extern const uint8_t kWeaveMsgEncAppKeyDiversifier[4]; |
| |
| /** |
| * Weave message encryption application key diversifier size. |
| */ |
| enum |
| { |
| kWeaveMsgEncAppKeyDiversifierSize = sizeof(kWeaveMsgEncAppKeyDiversifier) + sizeof(uint8_t) |
| }; |
| |
| // Forward declaration of WeaveFabricState |
| class WeaveFabricState; |
| |
| /** |
| * This abstract delegate class communicates fabric state changes. |
| */ |
| class FabricStateDelegate |
| { |
| public: |
| /** |
| * This method is called when WeaveFabricState joins or creates a new fabric. |
| * |
| * @param[in] fabricState: A pointer to WeaveFabricState that was changed. |
| * @param[in] newFabricId: The new fabric ID of the WeaveFabricState. |
| * |
| * @retval None. |
| */ |
| virtual void DidJoinFabric(WeaveFabricState *fabricState, uint64_t newFabricId) = 0; |
| |
| /** |
| * This method is called when WeaveFabricState leaves a fabric (i.e., fabric state |
| * is cleared). |
| * |
| * @param[in] fabricState: A pointer to the WeaveFabricState that was changed. |
| * @param[in] oldFabricId: The old fabric ID that was cleared. |
| * |
| * @retval None. |
| */ |
| virtual void DidLeaveFabric(WeaveFabricState *fabricState, uint64_t oldFabricId) = 0; |
| }; |
| |
| class NL_DLL_EXPORT WeaveFabricState |
| { |
| public: |
| |
| #if WEAVE_CONFIG_MAX_PEER_NODES <= UINT8_MAX |
| typedef uint8_t PeerIndexType; |
| #else |
| typedef uint16_t PeerIndexType; |
| #endif |
| |
| enum State |
| { |
| kState_NotInitialized = 0, kState_Initialized = 1 |
| }; |
| |
| WeaveFabricState(void); |
| |
| WeaveMessageLayer *MessageLayer; // [READ ONLY] The associated WeaveMessageLayer object. |
| uint64_t FabricId; // [READ ONLY] Node's Fabric Id (0 means node is not a member of a fabric). |
| uint64_t LocalNodeId; |
| const char *PairingCode; |
| uint16_t DefaultSubnet; |
| uint8_t State; // [READ ONLY] State of the Weave Fabric State object |
| nl::Weave::Profiles::Security::AppKeys::GroupKeyStoreBase *GroupKeyStore; |
| |
| #if WEAVE_CONFIG_SECURITY_TEST_MODE |
| uint64_t DebugFabricId; |
| bool LogKeys; |
| bool UseTestKey; // DEPRECATED -- Temporarily retained for API compaibility |
| bool AutoCreateKeys; // DEPRECATED -- Temporarily retained for API compaibility |
| #endif |
| |
| #if WEAVE_CONFIG_ENABLE_TARGETED_LISTEN |
| IPAddress ListenIPv4Addr; |
| IPAddress ListenIPv6Addr; |
| #endif |
| |
| |
| WEAVE_ERROR Init(void); |
| WEAVE_ERROR Init(nl::Weave::Profiles::Security::AppKeys::GroupKeyStoreBase *groupKeyStore); |
| WEAVE_ERROR Shutdown(void); |
| |
| WEAVE_ERROR AllocSessionKey(uint64_t peerNodeId, uint16_t keyId, WeaveConnection *boundCon, WeaveSessionKey *& sessionKey); |
| WEAVE_ERROR SetSessionKey(uint16_t keyId, uint64_t peerNodeId, uint8_t encType, WeaveAuthMode authMode, const WeaveEncryptionKey *encKey); |
| void SetSessionKey(WeaveSessionKey *sessionKey, uint8_t encType, WeaveAuthMode authMode, const WeaveEncryptionKey *encKey); |
| WEAVE_ERROR GetSessionKey(uint16_t keyId, uint64_t peerNodeId, WeaveSessionKey *& outSessionKey); |
| WEAVE_ERROR FindSessionKey(uint16_t keyId, uint64_t peerNodeId, bool create, WeaveSessionKey *& retRec); |
| WEAVE_ERROR RemoveSessionKey(uint16_t keyId, uint64_t peerNodeId); |
| void RemoveSessionKey(WeaveSessionKey *sessionKey, bool wasIdle = false); |
| bool RemoveIdleSessionKeys(); |
| |
| WeaveSessionKey *FindSharedSession(uint64_t terminatingNodeId, WeaveAuthMode authMode, uint8_t encType); |
| bool IsSharedSession(uint16_t keyId, uint64_t peerNodeId); |
| WEAVE_ERROR AddSharedSessionEndNode(uint64_t endNodeId, uint64_t terminatingNodeId, uint16_t keyId); |
| WEAVE_ERROR AddSharedSessionEndNode(WeaveSessionKey *sessionKey, uint64_t endNodeId); |
| WEAVE_ERROR GetSharedSessionEndNodeIds(const WeaveSessionKey *sessionKey, uint64_t *endNodeIds, |
| uint8_t endNodeIdsBufSize, uint8_t& endNodeIdsCount); |
| |
| WEAVE_ERROR GetSessionState(uint64_t remoteNodeId, uint16_t keyId, uint8_t encType, WeaveConnection *con, WeaveSessionState& outSessionState); |
| |
| /** |
| * This method returns an IPAddress representing the ULA of a Thread Node. |
| * This variant allows for a subnet to be specified. |
| * |
| * @param[in] nodeId The Node ID number of the node in question. |
| * |
| * @param[in] subnet The desired subnet of the ULA. |
| * |
| * @retval IPAddress An IPAddress object. |
| */ |
| IPAddress SelectNodeAddress(uint64_t nodeId, uint16_t subnet) const; |
| |
| /** |
| * This method returns an IPAddress representing the ULA of a Thread Node. |
| * This variant uses the fabric state's default subnet. |
| * |
| * @param[in] nodeId The Node ID number of the node in question. |
| * |
| * @retval IPAddress An IPAddress object. |
| */ |
| IPAddress SelectNodeAddress(uint64_t nodeId) const; |
| |
| /** |
| * This method returns true if the given IP Address represents a node |
| * within the local fabric. |
| * |
| * @param[in] addr The IP Address being checked. |
| * |
| * @retval bool Whether or not the IP represents a |
| * node in the local fabric. |
| */ |
| bool IsFabricAddress(const IPAddress &addr) const; |
| |
| WEAVE_ERROR GetPassword(uint8_t pwSrc, const char *& ps, uint16_t& pwLen); |
| |
| WEAVE_ERROR CreateFabric(void); |
| void ClearFabricState(void); |
| WEAVE_ERROR GetFabricState(uint8_t *buf, uint32_t bufSize, uint32_t &fabricStateLen); |
| WEAVE_ERROR JoinExistingFabric(const uint8_t *fabricState, uint32_t fabricStateLen); |
| |
| void HandleConnectionClosed(WeaveConnection *con); |
| |
| /** |
| * This method sets the delegate object. |
| * The callback methods of delegate are invoked whenever the FabricId is changed, |
| * i.e., when we join/create a fabric, or when we leave a fabric (clear fabric state) |
| * |
| * If the delegate is previously set, then a second call to this method will overwrite |
| * the previous delegate. |
| * |
| * @param[in] aDelegate The delegate object. It can be NULL if no |
| * delegate is required. |
| * @retval None. |
| */ |
| void SetDelegate(FabricStateDelegate *aDelegate); |
| |
| #if WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC |
| void OnMsgCounterSyncRespRcvd(uint64_t peerNodeId, uint32_t peerMsgId, uint32_t requestorMsgCounter); |
| void OnMsgCounterSyncReqSent(uint32_t messageId); |
| |
| /** |
| * This method returns true if at least one peer's message counter |
| * synchronization request is in progress. |
| * |
| * @retval bool Whether or not peer's message counter synchronization |
| * is in progress. |
| */ |
| bool IsMsgCounterSyncReqInProgress(void) |
| { |
| return (MsgCounterSyncStatus & kFlag_ReqInProgress) != 0; |
| } |
| |
| WEAVE_ERROR GetMsgEncKeyIdForAppGroup(uint32_t appGroupGlobalId, uint32_t rootKeyId, bool useRotatingKey, uint32_t& keyId); |
| |
| WEAVE_ERROR CheckMsgEncForAppGroup(const WeaveMessageInfo *msgInfo, uint32_t appGroupGlobalId, uint32_t rootKeyId, bool requireRotatingKey); |
| |
| #endif // WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC |
| |
| private: |
| PeerIndexType PeerCount; |
| MonotonicallyIncreasingCounter NextUnencUDPMsgId; |
| MonotonicallyIncreasingCounter NextUnencTCPMsgId; |
| WeaveSessionKey SessionKeys[WEAVE_CONFIG_MAX_SESSION_KEYS]; |
| #if WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC |
| PersistedCounter NextGroupKeyMsgId; |
| |
| // The earliest message id that will be considered "fresh" in a message counter synchronization |
| // response, but only if kReqInProgressFlag is true when the response is received. |
| uint32_t GroupKeyMsgIdFreshWindowStart; |
| |
| // Status flags to control message counter synchronization protocol flow and the fresh window width. |
| uint16_t MsgCounterSyncStatus; |
| enum |
| { |
| // Flag indicates if there may be outstanding request for which we may receive a response. |
| kFlag_ReqInProgress = 0x8000, |
| |
| // Flag indicates if request has been sent in the current timeout period. |
| kFlag_ReqSentThisPeriod = 0x4000, |
| |
| // Mask for fresh group message counter window width. |
| kMask_GroupKeyMsgIdFreshWindowWidth = 0x3FFF, |
| }; |
| |
| WeaveMsgEncryptionKeyCache AppKeyCache; |
| #endif // WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC |
| struct |
| { |
| uint64_t NodeId[WEAVE_CONFIG_MAX_PEER_NODES]; |
| uint32_t MaxUnencUDPMsgIdRcvd[WEAVE_CONFIG_MAX_PEER_NODES]; |
| #if WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC |
| uint32_t MaxGroupKeyMsgIdRcvd[WEAVE_CONFIG_MAX_PEER_NODES]; |
| WeaveSessionState::ReceiveFlagsType GroupKeyRcvFlags[WEAVE_CONFIG_MAX_PEER_NODES]; |
| #endif |
| WeaveSessionState::ReceiveFlagsType UnencRcvFlags[WEAVE_CONFIG_MAX_PEER_NODES]; |
| // Array of peer indexes in sorted order from most- to least- recently used. |
| PeerIndexType MostRecentlyUsedIndexes[WEAVE_CONFIG_MAX_PEER_NODES]; |
| } PeerStates; |
| FabricStateDelegate *Delegate; |
| |
| // This structure contains information about shared session end node. |
| struct SharedSessionEndNode |
| { |
| uint64_t EndNodeId; |
| WeaveSessionKey *SessionKey; |
| }; |
| // Record of all active shared session end nodes. |
| SharedSessionEndNode SharedSessionsNodes[WEAVE_CONFIG_MAX_SHARED_SESSIONS_END_NODES]; |
| |
| bool FindSharedSessionEndNode(uint64_t endNodeId, const WeaveSessionKey *sessionKey); |
| |
| #if WEAVE_CONFIG_USE_APP_GROUP_KEYS_FOR_MSG_ENC |
| void StartMsgCounterSyncTimer(void); |
| static void OnMsgCounterSyncRespTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError); |
| #endif |
| |
| bool FindOrAllocPeerEntry(uint64_t peerNodeId, bool allocEntry, PeerIndexType& retPeerIndex); |
| WEAVE_ERROR FindMsgEncAppKey(uint16_t keyId, uint8_t encType, WeaveMsgEncryptionKey *& retRec); |
| WEAVE_ERROR DeriveMsgEncAppKey(uint32_t keyId, uint8_t encType, WeaveMsgEncryptionKey & appKey, uint32_t& appGroupGlobalId); |
| }; |
| |
| |
| #if WEAVE_CONFIG_SECURITY_TEST_MODE |
| |
| enum |
| { |
| kMaxEncKeyStringSize = WeaveEncryptionKey_AES128CTRSHA1::DataKeySize * 2 // Hex digits for data key |
| + 1 // Field separator (,) |
| + WeaveEncryptionKey_AES128CTRSHA1::IntegrityKeySize * 2 // Hex digits for integrity key |
| + 1, // Null terminator |
| }; |
| |
| extern void WeaveEncryptionKeyToString(uint8_t encType, const WeaveEncryptionKey& key, char *buf, size_t bufSize); |
| |
| #endif // WEAVE_CONFIG_SECURITY_TEST_MODE |
| |
| |
| } // namespace nl |
| } // namespace Weave |
| |
| #endif // WEAVE_FABRIC_STATE_H |