15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/authentication_method.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base64.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/hmac.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/auth_util.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protocol { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AuthenticationMethod AuthenticationMethod::Invalid() { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AuthenticationMethod(); 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AuthenticationMethod AuthenticationMethod::Spake2(HashFunction hash_function) { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AuthenticationMethod(SPAKE2, hash_function); 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)AuthenticationMethod AuthenticationMethod::Spake2Pair() { 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return AuthenticationMethod(SPAKE2_PAIR, HMAC_SHA256); 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AuthenticationMethod AuthenticationMethod::ThirdParty() { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AuthenticationMethod(THIRD_PARTY, NONE); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AuthenticationMethod AuthenticationMethod::FromString( 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value) { 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value == "spake2_pair") { 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Spake2Pair(); 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (value == "spake2_plain") { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Spake2(NONE); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (value == "spake2_hmac") { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Spake2(HMAC_SHA256); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (value == "third_party") { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ThirdParty(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AuthenticationMethod::Invalid(); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string AuthenticationMethod::ApplyHashFunction( 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HashFunction hash_function, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& tag, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& shared_secret) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (hash_function) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NONE: 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return shared_secret; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HMAC_SHA256: { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crypto::HMAC response(crypto::HMAC::SHA256); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response.Init(tag)) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "HMAC::Init failed"; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char out_bytes[kSharedSecretHashLength]; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response.Sign(shared_secret, out_bytes, sizeof(out_bytes))) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "HMAC::Sign failed"; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(out_bytes, out_bytes + sizeof(out_bytes)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return shared_secret; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AuthenticationMethod::AuthenticationMethod() 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : type_(INVALID), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash_function_(NONE) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AuthenticationMethod::AuthenticationMethod(MethodType type, 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HashFunction hash_function) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : type_(type), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash_function_(hash_function) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(type_, INVALID); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AuthenticationMethod::HashFunction AuthenticationMethod::hash_function() const { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_valid()); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hash_function_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string AuthenticationMethod::ToString() const { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_valid()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch (type_) { 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case INVALID: 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED(); 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case SPAKE2_PAIR: 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return "spake2_pair"; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case SPAKE2: 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch (hash_function_) { 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case NONE: 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return "spake2_plain"; 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case HMAC_SHA256: 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return "spake2_hmac"; 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case THIRD_PARTY: 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return "third_party"; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "invalid"; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AuthenticationMethod::operator ==( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AuthenticationMethod& other) const { 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return type_ == other.type_ && 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hash_function_ == other.hash_function_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SharedSecretHash::Parse(const std::string& as_string) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t separator = as_string.find(':'); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (separator == std::string::npos) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string function_name = as_string.substr(0, separator); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (function_name == "plain") { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash_function = AuthenticationMethod::NONE; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (function_name == "hmac") { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash_function = AuthenticationMethod::HMAC_SHA256; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::Base64Decode(as_string.substr(separator + 1), &value)) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protocol 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 153