aboutsummaryrefslogtreecommitdiff
path: root/src/privet/security_manager.h
blob: bb513e6f975afbe94ccccf4253e5d31c8033b844 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright 2015 The Weave Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LIBWEAVE_SRC_PRIVET_SECURITY_MANAGER_H_
#define LIBWEAVE_SRC_PRIVET_SECURITY_MANAGER_H_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <base/callback.h>
#include <base/gtest_prod_util.h>
#include <base/memory/weak_ptr.h>
#include <weave/error.h>

#include "src/privet/security_delegate.h"

namespace crypto {
class P224EncryptedKeyExchange;
}  // namespace crypto

namespace weave {

namespace provider {
class TaskRunner;
}

namespace privet {

class SecurityManager : public SecurityDelegate {
 public:
  using PairingStartListener =
      base::Callback<void(const std::string& session_id,
                          PairingType pairing_type,
                          const std::vector<uint8_t>& code)>;
  using PairingEndListener =
      base::Callback<void(const std::string& session_id)>;

  class KeyExchanger {
   public:
    virtual ~KeyExchanger() {}

    virtual const std::string& GetMessage() = 0;
    virtual bool ProcessMessage(const std::string& message,
                                ErrorPtr* error) = 0;
    virtual const std::string& GetKey() const = 0;
  };

  SecurityManager(const std::string& secret,
                  const std::set<PairingType>& pairing_modes,
                  const std::string& embedded_code,
                  bool disable_security,
                  // TODO(vitalybuka): Remove task_runner.
                  provider::TaskRunner* task_runner);
  ~SecurityManager() override;

  // SecurityDelegate methods
  std::string CreateAccessToken(const UserInfo& user_info,
                                const base::Time& time) override;
  UserInfo ParseAccessToken(const std::string& token,
                            base::Time* time) const override;
  std::set<PairingType> GetPairingTypes() const override;
  std::set<CryptoType> GetCryptoTypes() const override;
  bool IsValidPairingCode(const std::string& auth_code) const override;

  bool StartPairing(PairingType mode,
                    CryptoType crypto,
                    std::string* session_id,
                    std::string* device_commitment,
                    ErrorPtr* error) override;

  bool ConfirmPairing(const std::string& session_id,
                      const std::string& client_commitment,
                      std::string* fingerprint,
                      std::string* signature,
                      ErrorPtr* error) override;
  bool CancelPairing(const std::string& session_id, ErrorPtr* error) override;

  void RegisterPairingListeners(const PairingStartListener& on_start,
                                const PairingEndListener& on_end);

  void SetCertificateFingerprint(const std::vector<uint8_t>& fingerprint) {
    certificate_fingerprint_ = fingerprint;
  }

  std::string GetSecret() const;

 private:
  FRIEND_TEST_ALL_PREFIXES(SecurityManagerTest, ThrottlePairing);
  // Allows limited number of new sessions without successful authorization.
  bool CheckIfPairingAllowed(ErrorPtr* error);
  bool ClosePendingSession(const std::string& session_id);
  bool CloseConfirmedSession(const std::string& session_id);

  // If true allows unencrypted pairing and accepts any access code.
  bool is_security_disabled_{false};
  std::set<PairingType> pairing_modes_;
  std::string embedded_code_;
  // TODO(vitalybuka): Session cleanup can be done without posting tasks.
  provider::TaskRunner* task_runner_{nullptr};
  std::map<std::string, std::unique_ptr<KeyExchanger>> pending_sessions_;
  std::map<std::string, std::unique_ptr<KeyExchanger>> confirmed_sessions_;
  mutable int pairing_attemts_{0};
  mutable base::Time block_pairing_until_;
  std::vector<uint8_t> secret_;
  std::vector<uint8_t> certificate_fingerprint_;
  PairingStartListener on_start_;
  PairingEndListener on_end_;

  base::WeakPtrFactory<SecurityManager> weak_ptr_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(SecurityManager);
};

}  // namespace privet
}  // namespace weave

#endif  // LIBWEAVE_SRC_PRIVET_SECURITY_MANAGER_H_