17c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// Copyright 2012 Google Inc. All Rights Reserved. 27c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// 37c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// Licensed under the Apache License, Version 2.0 (the "License"); 47c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// you may not use this file except in compliance with the License. 57c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// You may obtain a copy of the License at 67c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// 77c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// http://www.apache.org/licenses/LICENSE-2.0 87c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// 97c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// Unless required by applicable law or agreed to in writing, software 107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// distributed under the License is distributed on an "AS IS" BASIS, 117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// See the License for the specific language governing permissions and 137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// limitations under the License. 147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet#include "polo/pairing/pairingsession.h" 167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet#include <glog/logging.h> 187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet#include "polo/encoding/hexadecimalencoder.h" 197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet#include "polo/util/poloutil.h" 207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetnamespace polo { 227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetnamespace pairing { 237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 247c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetPairingSession::PairingSession(wire::PoloWireAdapter* wire, 257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet PairingContext* context, 267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet PoloChallengeResponse* challenge) 277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet : state_(kUninitialized), 287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet wire_(wire), 297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet context_(context), 307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet challenge_(challenge), 317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet configuration_(NULL), 327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet encoder_(NULL), 337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet nonce_(NULL), 347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet secret_(NULL) { 357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet wire_->set_listener(this); 367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet local_options_.set_protocol_role_preference(context->is_server() ? 387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet message::OptionsMessage::kDisplayDevice 397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet : message::OptionsMessage::kInputDevice); 407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 427c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetPairingSession::~PairingSession() { 437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (configuration_) { 447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete configuration_; 457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (encoder_) { 487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete encoder_; 497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (nonce_) { 527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete nonce_; 537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (secret_) { 567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete secret_; 577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetvoid PairingSession::AddInputEncoding( 617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet const encoding::EncodingOption& encoding) { 627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (state_ != kUninitialized) { 637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Attempt to add input encoding to active session"; 647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return; 657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!IsValidEncodingOption(encoding)) { 687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Invalid input encoding: " << encoding.ToString(); 697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return; 707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet local_options_.AddInputEncoding(encoding); 737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetvoid PairingSession::AddOutputEncoding( 767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet const encoding::EncodingOption& encoding) { 777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (state_ != kUninitialized) { 787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Attempt to add output encoding to active session"; 797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return; 807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!IsValidEncodingOption(encoding)) { 837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Invalid output encoding: " << encoding.ToString(); 847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return; 857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet local_options_.AddOutputEncoding(encoding); 887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetbool PairingSession::SetSecret(const Gamma& secret) { 917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet secret_ = new Gamma(secret); 927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!IsInputDevice() || state_ != kWaitingForSecret) { 947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Invalid state: unexpected secret"; 957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return false; 967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!challenge().CheckGamma(secret)) { 997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Secret failed local check"; 1007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return false; 1017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet nonce_ = challenge().ExtractNonce(secret); 1047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!nonce_) { 1057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Failed to extract nonce"; 1067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return false; 1077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet const Alpha* gen_alpha = challenge().GetAlpha(*nonce_); 1107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!gen_alpha) { 1117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Failed to get alpha"; 1127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return false; 1137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet message::SecretMessage secret_message(*gen_alpha); 1167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete gen_alpha; 1177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet wire_->SendSecretMessage(secret_message); 1197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(INFO) << "Waiting for SecretAck..."; 1217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet wire_->GetNextMessage(); 1227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return true; 1247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 1257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetvoid PairingSession::DoPair(PairingListener *listener) { 1277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener_ = listener; 1287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener_->OnSessionCreated(); 1297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (context_->is_server()) { 1317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(INFO) << "Pairing started (SERVER mode)"; 1327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else { 1337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(INFO) << "Pairing started (CLIENT mode)"; 1347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(INFO) << "Local options: " << local_options_.ToString(); 1367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet set_state(kInitializing); 1387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet DoInitializationPhase(); 1397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 1407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetvoid PairingSession::DoPairingPhase() { 1427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (IsInputDevice()) { 1437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet DoInputPairing(); 1447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else { 1457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet DoOutputPairing(); 1467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 1487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetvoid PairingSession::DoInputPairing() { 1507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet set_state(kWaitingForSecret); 1517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener_->OnPerformInputDeviceRole(); 1527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 1537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetvoid PairingSession::DoOutputPairing() { 1557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet size_t nonce_length = configuration_->encoding().symbol_length() / 2; 1567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet size_t bytes_needed = nonce_length / encoder_->symbols_per_byte(); 1577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet uint8_t* random = util::PoloUtil::GenerateRandomBytes(bytes_needed); 1597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet nonce_ = new Nonce(random, random + bytes_needed); 1607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete[] random; 1617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet const Gamma* gamma = challenge().GetGamma(*nonce_); 1637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!gamma) { 1647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Failed to get gamma"; 1657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet wire()->SendErrorMessage(kErrorProtocol); 1667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener()->OnError(kErrorProtocol); 1677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return; 1687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener_->OnPerformOutputDeviceRole(*gamma); 1717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete gamma; 1727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet set_state(kWaitingForSecret); 1747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(INFO) << "Waiting for Secret..."; 1767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet wire_->GetNextMessage(); 1777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 1787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetvoid PairingSession::set_state(ProtocolState state) { 1807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(INFO) << "New state: " << state; 1817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet state_ = state; 1827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 1837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetbool PairingSession::SetConfiguration( 1857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet const message::ConfigurationMessage& message) { 1867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet const encoding::EncodingOption& encoding = message.encoding(); 1877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!IsValidEncodingOption(encoding)) { 1897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Invalid configuration: " << encoding.ToString(); 1907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return false; 1917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (encoder_) { 1947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete encoder_; 1957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet encoder_ = NULL; 1967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet switch (encoding.encoding_type()) { 1997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case encoding::EncodingOption::kHexadecimal: 2007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet encoder_ = new encoding::HexadecimalEncoder(); 2017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 2027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet default: 2037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Unsupported encoding type: " 2047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet << encoding.encoding_type(); 2057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return false; 2067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (configuration_) { 2097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete configuration_; 2107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet configuration_ = new message::ConfigurationMessage(message.encoding(), 2127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet message.client_role()); 2137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return true; 2147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 2157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetvoid PairingSession::OnSecretMessage(const message::SecretMessage& message) { 2177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (state() != kWaitingForSecret) { 2187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Invalid state: unexpected secret message"; 2197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet wire()->SendErrorMessage(kErrorProtocol); 2207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener()->OnError(kErrorProtocol); 2217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return; 2227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!VerifySecret(message.secret())) { 2257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet wire()->SendErrorMessage(kErrorInvalidChallengeResponse); 2267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener_->OnError(kErrorInvalidChallengeResponse); 2277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return; 2287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet const Alpha* alpha = challenge().GetAlpha(*nonce_); 2317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!alpha) { 2327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Failed to get alpha"; 2337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet wire()->SendErrorMessage(kErrorProtocol); 2347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener()->OnError(kErrorProtocol); 2357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return; 2367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet message::SecretAckMessage ack(*alpha); 2397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete alpha; 2407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet wire_->SendSecretAckMessage(ack); 2427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener_->OnPairingSuccess(); 2447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 2457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetvoid PairingSession::OnSecretAckMessage( 2477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet const message::SecretAckMessage& message) { 2487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (kVerifySecretAck && !VerifySecret(message.secret())) { 2497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet wire()->SendErrorMessage(kErrorInvalidChallengeResponse); 2507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener_->OnError(kErrorInvalidChallengeResponse); 2517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return; 2527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener_->OnPairingSuccess(); 2557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 2567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetvoid PairingSession::OnError(pairing::PoloError error) { 2587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet listener_->OnError(error); 2597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 2607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetbool PairingSession::VerifySecret(const Alpha& secret) const { 2627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!nonce_) { 2637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Nonce not set"; 2647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return false; 2657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet const Alpha* gen_alpha = challenge().GetAlpha(*nonce_); 2687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!gen_alpha) { 2697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Failed to get alpha"; 2707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return false; 2717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet bool valid = (secret == *gen_alpha); 2747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!valid) { 2767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet LOG(ERROR) << "Inband secret did not match. Expected [" 2777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet << util::PoloUtil::BytesToHexString(&(*gen_alpha)[0], gen_alpha->size()) 2787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet << "], got [" 2797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet << util::PoloUtil::BytesToHexString(&secret[0], secret.size()) 2807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet << "]"; 2817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete gen_alpha; 2847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return valid; 2857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 2867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetmessage::OptionsMessage::ProtocolRole PairingSession::GetLocalRole() const { 2887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (!configuration_) { 2897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return message::OptionsMessage::kUnknown; 2907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (context_->is_client()) { 2937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return configuration_->client_role(); 2947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else { 2957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return configuration_->client_role() == 2967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet message::OptionsMessage::kDisplayDevice ? 2977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet message::OptionsMessage::kInputDevice 2987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet : message::OptionsMessage::kDisplayDevice; 2997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 3017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetbool PairingSession::IsInputDevice() const { 3037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return GetLocalRole() == message::OptionsMessage::kInputDevice; 3047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 3057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetbool PairingSession::IsValidEncodingOption( 3077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet const encoding::EncodingOption& option) const { 3087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // Legal values of GAMMALEN must be an even number of at least 2 bytes. 3097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return option.encoding_type() != encoding::EncodingOption::kUnknown 3107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet && (option.symbol_length() % 2 == 0) 3117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet && (option.symbol_length() >= 2); 3127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 3137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} // namespace pairing 3157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} // namespace polo 316