1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "remoting/protocol/auth_util.h" 6 7 #include "base/base64.h" 8 #include "base/logging.h" 9 #include "base/strings/string_util.h" 10 #include "crypto/hmac.h" 11 #include "crypto/sha2.h" 12 #include "net/base/net_errors.h" 13 #include "net/socket/ssl_socket.h" 14 15 namespace remoting { 16 namespace protocol { 17 18 const char kClientAuthSslExporterLabel[] = 19 "EXPORTER-remoting-channel-auth-client"; 20 const char kHostAuthSslExporterLabel[] = 21 "EXPORTER-remoting-channel-auth-host"; 22 23 const char kSslFakeHostName[] = "chromoting"; 24 25 std::string GenerateSupportAuthToken(const std::string& jid, 26 const std::string& access_code) { 27 std::string sha256 = crypto::SHA256HashString(jid + " " + access_code); 28 std::string sha256_base64; 29 base::Base64Encode(sha256, &sha256_base64); 30 return sha256_base64; 31 } 32 33 bool VerifySupportAuthToken(const std::string& jid, 34 const std::string& access_code, 35 const std::string& auth_token) { 36 std::string expected_token = 37 GenerateSupportAuthToken(jid, access_code); 38 return expected_token == auth_token; 39 } 40 41 // static 42 std::string GetAuthBytes(net::SSLSocket* socket, 43 const base::StringPiece& label, 44 const base::StringPiece& shared_secret) { 45 // Get keying material from SSL. 46 unsigned char key_material[kAuthDigestLength]; 47 int export_result = socket->ExportKeyingMaterial( 48 label, false, "", key_material, kAuthDigestLength); 49 if (export_result != net::OK) { 50 LOG(ERROR) << "Error fetching keying material: " << export_result; 51 return std::string(); 52 } 53 54 // Generate auth digest based on the keying material and shared secret. 55 crypto::HMAC response(crypto::HMAC::SHA256); 56 if (!response.Init(key_material, kAuthDigestLength)) { 57 NOTREACHED() << "HMAC::Init failed"; 58 return std::string(); 59 } 60 unsigned char out_bytes[kAuthDigestLength]; 61 if (!response.Sign(shared_secret, out_bytes, kAuthDigestLength)) { 62 NOTREACHED() << "HMAC::Sign failed"; 63 return std::string(); 64 } 65 66 return std::string(out_bytes, out_bytes + kAuthDigestLength); 67 } 68 69 } // namespace protocol 70 } // namespace remoting 71