• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef POLO_PAIRING_PAIRINGSESSION_H_
16 #define POLO_PAIRING_PAIRINGSESSION_H_
17 
18 #include <string>
19 
20 #include "polo/encoding/secretencoder.h"
21 #include "polo/pairing/pairingcontext.h"
22 #include "polo/pairing/pairinglistener.h"
23 #include "polo/pairing/message/messagelistener.h"
24 #include "polo/wire/polowireadapter.h"
25 
26 namespace polo {
27 namespace pairing {
28 
29 class PairingSession : public message::MessageListener {
30  public:
31   // The state of the Polo pairing session.
32   enum ProtocolState {
33     // The Polo session has not yet been initialized.
34     kUninitialized,
35 
36     // The session is initializing.
37     kInitializing,
38 
39     // The configuration options are being negotiated with the peer.
40     kConfiguring,
41 
42     // The local device is being paired with the peer.
43     kPairing,
44 
45     // Waiting for the secret challenge messsage or response from the peer.
46     kWaitingForSecret,
47 
48     // The pairing completely successfully.
49     kSuccess,
50 
51     // There was an error pairing.
52     kFailure,
53   };
54 
55   // Creates a new pairing session. The given wire adapter will be used for
56   // sending and receiving protocol messages. The given context contains the
57   // local and peer SSL certificates from the establishment of the SSL
58   // connection. No ownership is taken of the given pointers.
59   PairingSession(wire::PoloWireAdapter* wire,
60                  PairingContext* context,
61                  PoloChallengeResponse* challenge);
62 
63   virtual ~PairingSession();
64 
65   // Adds a supported input encoding. This must be called before the session is
66   // started.
67   void AddInputEncoding(const encoding::EncodingOption& encoding);
68 
69   // Adds a supported output encoding. This must be called before the session is
70   // started.
71   void AddOutputEncoding(const encoding::EncodingOption& encoding);
72 
73   // Starts the pairing session. The given listener will be invoked during the
74   // pairing session.
75   void DoPair(PairingListener* listener);
76 
77   // Sets the secret entered by the user. This must be invoked when, and only
78   // when, OnPerformInputDeviceRole has been called on the listener.
79   // @return Whether the secret was successfully set. If the given secret is
80   //         invalid or fails the local check, this will return false.
81   bool SetSecret(const Gamma& secret);
82 
83   // Gets the encoder used for encoding and decoding the secret challenge. This
84   // should only be invoked after OnPerformInputDeviceRole or
85   // OnPerformOutputDeviceRole has been called on the listener.
encoder()86   const encoding::SecretEncoder* encoder() const { return encoder_; }
87 
88  protected:
89   // Starts the pairing process.
90   void DoPairingPhase();
91 
92   // Performs the initialization phase of the pairing process.
93   virtual void DoInitializationPhase() = 0;
94 
95   // Performs the configuration phase of the pairing process.
96   virtual void DoConfigurationPhase() = 0;
97 
98   // Sets the configuration once it has been negotiated. This must be called
99   // by implementations during the configuration phase. Returns true if the
100   // configuration was valid and false otherwise. If the configuration was
101   // invalid the pairing process can not continue.
102   bool SetConfiguration(const message::ConfigurationMessage& message);
103 
configuration()104   const message::ConfigurationMessage* configuration() const {
105     return configuration_;
106   }
107 
108   // @override
109   virtual void OnSecretMessage(const message::SecretMessage& message);
110 
111   // @override
112   virtual void OnSecretAckMessage(const message::SecretAckMessage& message);
113 
114   // @override
115   virtual void OnError(pairing::PoloError error);
116 
117   // Determines whether this device is acting as the input device.
118   bool IsInputDevice() const;
119 
120   // Gets the local device role or kUnknown if the configuration has not been
121   // established yet.
122   message::OptionsMessage::ProtocolRole GetLocalRole() const;
123 
124   // Set the current protocol state.
125   void set_state(ProtocolState state);
126 
127   // Gets the current state of the pairing process.
state()128   ProtocolState state() const { return state_; }
129 
130   // Sets the service name.
set_service_name(const std::string & service_name)131   void set_service_name(const std::string& service_name) {
132     service_name_.assign(service_name);
133   }
134 
135   // Sets the peer name.
set_peer_name(const std::string & peer_name)136   void set_peer_name(const std::string& peer_name) {
137     peer_name_.assign(peer_name);
138   }
139 
140   // Gets the service name.
service_name()141   std::string service_name() const { return service_name_; }
142 
143   // Gets the peer name.
peer_name()144   std::string peer_name() const { return peer_name_; }
145 
146   // Gets the local options.
local_options()147   const message::OptionsMessage& local_options() const {
148     return local_options_;
149   }
150 
151   // Gets the wire adapter used to send and receive Polo messages.
wire()152   wire::PoloWireAdapter* wire() const { return wire_; }
153 
154   // Gets the listener that will be notified of pairing events.
listener()155   PairingListener* listener() const { return listener_; }
156 
157   // Gets the challenge response.
challenge()158   const PoloChallengeResponse& challenge() const { return *challenge_; }
159 
160   // Gets the nonce value.
nonce()161   const Nonce* nonce() const { return nonce_; }
162 
163  private:
164   // Performs pairing as the input device.
165   void DoInputPairing();
166 
167   // Performs pairing as the output device.
168   void DoOutputPairing();
169 
170   // Determines whether the given encoding option is valid.
171   bool IsValidEncodingOption(const encoding::EncodingOption& option) const;
172 
173   // Verifies that the given secret is correct.
174   bool VerifySecret(const Alpha& secret) const;
175 
176   enum {
177     // Whether to verify the secret ack. This is not currently required since
178     // the ack means the peer already verified the secret.
179     kVerifySecretAck = false,
180 
181     // The time to wait for a secret.
182     kSecretPollTimeoutMs = 500
183   };
184 
185   ProtocolState state_;
186   wire::PoloWireAdapter* wire_;
187   PairingContext* context_;
188   message::OptionsMessage local_options_;
189   PoloChallengeResponse* challenge_;
190   PairingListener* listener_;
191   message::ConfigurationMessage* configuration_;
192   encoding::SecretEncoder* encoder_;
193   Nonce* nonce_;
194   Gamma* secret_;
195   std::string service_name_;
196   std::string peer_name_;
197 };
198 
199 }  // namespace pairing
200 }  // namespace polo
201 
202 #endif  // POLO_PAIRING_PAIRINGSESSION_H_
203