14615e0d5aa416ab1a8596bde68f71f7ebe431b86Vitaly Buka// Copyright 2015 The Weave Authors. All rights reserved. 27ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka// Use of this source code is governed by a BSD-style license that can be 37ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka// found in the LICENSE file. 47ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 5912b6985096700c4bf7aa83fb01640309a9bb229Vitaly Buka#ifndef LIBWEAVE_SRC_PRIVET_SECURITY_MANAGER_H_ 6912b6985096700c4bf7aa83fb01640309a9bb229Vitaly Buka#define LIBWEAVE_SRC_PRIVET_SECURITY_MANAGER_H_ 77ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 87ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <map> 97ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <memory> 107ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <set> 117ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <string> 127ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <vector> 137ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 147ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <base/callback.h> 150d50107079e3b7d35b310d7e91ca491c17c8e840Vitaly Buka#include <base/gtest_prod_util.h> 167ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <base/memory/weak_ptr.h> 170801a1f20a0c8f34130d567cd3b7dcbd2be9cb3cVitaly Buka#include <weave/error.h> 187ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 1920896ab5bdbddbac8f67f12fc8198330e5dafdfcVitaly Buka#include "src/config.h" 202d16dfa768282b29f3fd5a905b52e3393a083e0dStefan Sauer#include "src/privet/security_delegate.h" 217ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 227ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Bukanamespace crypto { 237ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Bukaclass P224EncryptedKeyExchange; 247ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka} // namespace crypto 257ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 26b6f015a1ef3caffbc2af53184c0ec5342e42e048Vitaly Bukanamespace weave { 27823fdda17d72adf6722d6573151add921c996c43Vitaly Buka 281e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Bukanamespace provider { 29823fdda17d72adf6722d6573151add921c996c43Vitaly Bukaclass TaskRunner; 301e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka} 31823fdda17d72adf6722d6573151add921c996c43Vitaly Buka 32b6f015a1ef3caffbc2af53184c0ec5342e42e048Vitaly Bukanamespace privet { 337ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 34f08caeb9070257bb2ab0769f328eb8632f1778dcVitaly Bukaclass AuthManager; 35f08caeb9070257bb2ab0769f328eb8632f1778dcVitaly Buka 367ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Bukaclass SecurityManager : public SecurityDelegate { 377ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka public: 387ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka using PairingStartListener = 397ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka base::Callback<void(const std::string& session_id, 407ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka PairingType pairing_type, 417ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const std::vector<uint8_t>& code)>; 427ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka using PairingEndListener = 437ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka base::Callback<void(const std::string& session_id)>; 447ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 457ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka class KeyExchanger { 467ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka public: 473bfb13d1a7a1d1677b3b3af9264f7cbecb6b71bdVitaly Buka virtual ~KeyExchanger() {} 487ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 497ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka virtual const std::string& GetMessage() = 0; 507ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka virtual bool ProcessMessage(const std::string& message, 510801a1f20a0c8f34130d567cd3b7dcbd2be9cb3cVitaly Buka ErrorPtr* error) = 0; 527ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka virtual const std::string& GetKey() const = 0; 537ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka }; 547ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 5520896ab5bdbddbac8f67f12fc8198330e5dafdfcVitaly Buka SecurityManager(const Config* config, 5620896ab5bdbddbac8f67f12fc8198330e5dafdfcVitaly Buka AuthManager* auth_manager, 578589b05a372d1ba546f529aaed2fd6ad9ad35042Vitaly Buka // TODO(vitalybuka): Remove task_runner. 581e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka provider::TaskRunner* task_runner); 597ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka ~SecurityManager() override; 607ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 617ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // SecurityDelegate methods 62fd2ef6869df7fdd2eb32e17bd7854df478b1f031Vitaly Buka bool CreateAccessToken(AuthType auth_type, 63fd2ef6869df7fdd2eb32e17bd7854df478b1f031Vitaly Buka const std::string& auth_code, 64fd2ef6869df7fdd2eb32e17bd7854df478b1f031Vitaly Buka AuthScope desired_scope, 65fd2ef6869df7fdd2eb32e17bd7854df478b1f031Vitaly Buka std::string* access_token, 6666a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka AuthScope* access_token_scope, 6766a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka base::TimeDelta* access_token_ttl, 68fd2ef6869df7fdd2eb32e17bd7854df478b1f031Vitaly Buka ErrorPtr* error) override; 69a0a813490ff37868827b65d7f9aeb554c996c17cVitaly Buka bool ParseAccessToken(const std::string& token, 70a0a813490ff37868827b65d7f9aeb554c996c17cVitaly Buka UserInfo* user_info, 71a0a813490ff37868827b65d7f9aeb554c996c17cVitaly Buka ErrorPtr* error) const override; 727ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka std::set<PairingType> GetPairingTypes() const override; 737ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka std::set<CryptoType> GetCryptoTypes() const override; 74ee7322fc7ed7cf06635a01010d10aedd9714e0eaVitaly Buka std::set<AuthType> GetAuthTypes() const override; 754ab500249f346a9fcfe084ee1619a39259f7471cVitaly Buka std::string ClaimRootClientAuthToken(ErrorPtr* error) override; 76305ab613de85f6640f300010a17cb6ea22be2081Vitaly Buka bool ConfirmClientAuthToken(const std::string& token, 77305ab613de85f6640f300010a17cb6ea22be2081Vitaly Buka ErrorPtr* error) override; 787ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka bool StartPairing(PairingType mode, 797ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka CryptoType crypto, 807ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka std::string* session_id, 817ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka std::string* device_commitment, 820801a1f20a0c8f34130d567cd3b7dcbd2be9cb3cVitaly Buka ErrorPtr* error) override; 837ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 847ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka bool ConfirmPairing(const std::string& session_id, 857ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const std::string& client_commitment, 867ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka std::string* fingerprint, 877ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka std::string* signature, 880801a1f20a0c8f34130d567cd3b7dcbd2be9cb3cVitaly Buka ErrorPtr* error) override; 890801a1f20a0c8f34130d567cd3b7dcbd2be9cb3cVitaly Buka bool CancelPairing(const std::string& session_id, ErrorPtr* error) override; 90483d5970e88b56442f19baea841f6af75b5a0006Vitaly Buka std::string CreateSessionId() override; 917ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 927ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void RegisterPairingListeners(const PairingStartListener& on_start, 937ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const PairingEndListener& on_end); 947ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 957ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka private: 9620896ab5bdbddbac8f67f12fc8198330e5dafdfcVitaly Buka const Config::Settings& GetSettings() const; 9766a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka bool IsValidPairingCode(const std::vector<uint8_t>& auth_code) const; 987ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka FRIEND_TEST_ALL_PREFIXES(SecurityManagerTest, ThrottlePairing); 997ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // Allows limited number of new sessions without successful authorization. 1000801a1f20a0c8f34130d567cd3b7dcbd2be9cb3cVitaly Buka bool CheckIfPairingAllowed(ErrorPtr* error); 1017ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka bool ClosePendingSession(const std::string& session_id); 1027ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka bool CloseConfirmedSession(const std::string& session_id); 10366a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka bool CreateAccessTokenImpl(AuthType auth_type, 10466a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka const std::vector<uint8_t>& auth_code, 10566a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka AuthScope desired_scope, 10666a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka std::vector<uint8_t>* access_token, 10766a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka AuthScope* access_token_scope, 10866a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka base::TimeDelta* access_token_ttl, 10966a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka ErrorPtr* error); 11066a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka bool CreateAccessTokenImpl(AuthType auth_type, 11166a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka AuthScope desired_scope, 11266a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka std::vector<uint8_t>* access_token, 11366a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka AuthScope* access_token_scope, 11466a01e0cd687c1e078b9166b61bf9112c70c1615Vitaly Buka base::TimeDelta* access_token_ttl); 11520896ab5bdbddbac8f67f12fc8198330e5dafdfcVitaly Buka bool IsAnonymousAuthSupported() const; 11620896ab5bdbddbac8f67f12fc8198330e5dafdfcVitaly Buka bool IsPairingAuthSupported() const; 11720896ab5bdbddbac8f67f12fc8198330e5dafdfcVitaly Buka bool IsLocalAuthSupported() const; 1187ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 11920896ab5bdbddbac8f67f12fc8198330e5dafdfcVitaly Buka const Config* config_{nullptr}; 120f08caeb9070257bb2ab0769f328eb8632f1778dcVitaly Buka AuthManager* auth_manager_{nullptr}; 121f08caeb9070257bb2ab0769f328eb8632f1778dcVitaly Buka 122f9630fbb4aab7028af10600ef87be2e65df0ac91Vitaly Buka // TODO(vitalybuka): Session cleanup can be done without posting tasks. 1231e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka provider::TaskRunner* task_runner_{nullptr}; 1247ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka std::map<std::string, std::unique_ptr<KeyExchanger>> pending_sessions_; 1257ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka std::map<std::string, std::unique_ptr<KeyExchanger>> confirmed_sessions_; 1267ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka mutable int pairing_attemts_{0}; 1277ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka mutable base::Time block_pairing_until_; 1287ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka PairingStartListener on_start_; 1297ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka PairingEndListener on_end_; 130fd2ef6869df7fdd2eb32e17bd7854df478b1f031Vitaly Buka uint64_t last_user_id_{0}; 1317ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 1327ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka base::WeakPtrFactory<SecurityManager> weak_ptr_factory_{this}; 1337ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 1347ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka DISALLOW_COPY_AND_ASSIGN(SecurityManager); 1357ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka}; 1367ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 137b6f015a1ef3caffbc2af53184c0ec5342e42e048Vitaly Buka} // namespace privet 138b6f015a1ef3caffbc2af53184c0ec5342e42e048Vitaly Buka} // namespace weave 1397ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 140912b6985096700c4bf7aa83fb01640309a9bb229Vitaly Buka#endif // LIBWEAVE_SRC_PRIVET_SECURITY_MANAGER_H_ 141