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