| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/protocol/authentication_method.h" | 5 #include "remoting/protocol/authentication_method.h" |
| 6 | 6 |
| 7 #include <stddef.h> | |
| 8 | |
| 9 #include "base/base64.h" | |
| 10 #include "base/logging.h" | 7 #include "base/logging.h" |
| 11 #include "crypto/hmac.h" | 8 #include "crypto/hmac.h" |
| 12 #include "remoting/protocol/auth_util.h" | 9 #include "remoting/protocol/auth_util.h" |
| 10 #include "remoting/protocol/name_value_map.h" |
| 13 | 11 |
| 14 namespace remoting { | 12 namespace remoting { |
| 15 namespace protocol { | 13 namespace protocol { |
| 16 | 14 |
| 17 // static | 15 const NameMapElement<AuthenticationMethod> kAuthenticationMethodStrings[] = { |
| 18 AuthenticationMethod AuthenticationMethod::Invalid() { | 16 {AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN, "spake2_plain"}, |
| 19 return AuthenticationMethod(); | 17 {AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC, "spake2_hmac"}, |
| 18 {AuthenticationMethod::SPAKE2_PAIR, "spake2_pair"}, |
| 19 {AuthenticationMethod::THIRD_PARTY, "third_party"}}; |
| 20 |
| 21 AuthenticationMethod ParseAuthenticationMethodString(const std::string& value) { |
| 22 AuthenticationMethod result; |
| 23 if (!NameToValue(kAuthenticationMethodStrings, value, &result)) |
| 24 return AuthenticationMethod::INVALID; |
| 25 return result; |
| 20 } | 26 } |
| 21 | 27 |
| 22 // static | 28 const std::string AuthenticationMethodToString( |
| 23 AuthenticationMethod AuthenticationMethod::Spake2(HashFunction hash_function) { | 29 AuthenticationMethod method) { |
| 24 return AuthenticationMethod(SPAKE2, hash_function); | 30 return ValueToName(kAuthenticationMethodStrings, method); |
| 25 } | 31 } |
| 26 | 32 |
| 27 // static | 33 HashFunction GetHashFunctionForAuthenticationMethod( |
| 28 AuthenticationMethod AuthenticationMethod::Spake2Pair() { | 34 AuthenticationMethod method) { |
| 29 return AuthenticationMethod(SPAKE2_PAIR, HMAC_SHA256); | 35 switch (method) { |
| 36 case AuthenticationMethod::INVALID: |
| 37 NOTREACHED(); |
| 38 return HashFunction::NONE; |
| 39 |
| 40 case AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN: |
| 41 case AuthenticationMethod::THIRD_PARTY: |
| 42 return HashFunction::NONE; |
| 43 |
| 44 case AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC: |
| 45 case AuthenticationMethod::SPAKE2_PAIR: |
| 46 return HashFunction::HMAC_SHA256; |
| 47 } |
| 48 |
| 49 NOTREACHED(); |
| 50 return HashFunction::NONE; |
| 30 } | 51 } |
| 31 | 52 |
| 32 // static | 53 std::string ApplySharedSecretHashFunction(HashFunction hash_function, |
| 33 AuthenticationMethod AuthenticationMethod::ThirdParty() { | 54 const std::string& tag, |
| 34 return AuthenticationMethod(THIRD_PARTY, NONE); | 55 const std::string& shared_secret) { |
| 35 } | 56 switch (hash_function) { |
| 57 case HashFunction::NONE: |
| 58 return shared_secret; |
| 36 | 59 |
| 37 // static | 60 case HashFunction::HMAC_SHA256: { |
| 38 AuthenticationMethod AuthenticationMethod::FromString( | |
| 39 const std::string& value) { | |
| 40 if (value == "spake2_pair") { | |
| 41 return Spake2Pair(); | |
| 42 } else if (value == "spake2_plain") { | |
| 43 return Spake2(NONE); | |
| 44 } else if (value == "spake2_hmac") { | |
| 45 return Spake2(HMAC_SHA256); | |
| 46 } else if (value == "third_party") { | |
| 47 return ThirdParty(); | |
| 48 } else { | |
| 49 return AuthenticationMethod::Invalid(); | |
| 50 } | |
| 51 } | |
| 52 | |
| 53 // static | |
| 54 std::string AuthenticationMethod::ApplyHashFunction( | |
| 55 HashFunction hash_function, | |
| 56 const std::string& tag, | |
| 57 const std::string& shared_secret) { | |
| 58 switch (hash_function) { | |
| 59 case NONE: | |
| 60 return shared_secret; | |
| 61 break; | |
| 62 | |
| 63 case HMAC_SHA256: { | |
| 64 crypto::HMAC response(crypto::HMAC::SHA256); | 61 crypto::HMAC response(crypto::HMAC::SHA256); |
| 65 if (!response.Init(tag)) { | 62 if (!response.Init(tag)) { |
| 66 LOG(FATAL) << "HMAC::Init failed"; | 63 LOG(FATAL) << "HMAC::Init failed"; |
| 67 } | 64 } |
| 68 | 65 |
| 69 unsigned char out_bytes[kSharedSecretHashLength]; | 66 unsigned char out_bytes[kSharedSecretHashLength]; |
| 70 if (!response.Sign(shared_secret, out_bytes, sizeof(out_bytes))) { | 67 if (!response.Sign(shared_secret, out_bytes, sizeof(out_bytes))) { |
| 71 LOG(FATAL) << "HMAC::Sign failed"; | 68 LOG(FATAL) << "HMAC::Sign failed"; |
| 72 } | 69 } |
| 73 | 70 |
| 74 return std::string(out_bytes, out_bytes + sizeof(out_bytes)); | 71 return std::string(out_bytes, out_bytes + sizeof(out_bytes)); |
| 75 } | 72 } |
| 76 } | 73 } |
| 77 | 74 |
| 78 NOTREACHED(); | 75 NOTREACHED(); |
| 79 return shared_secret; | 76 return shared_secret; |
| 80 } | 77 } |
| 81 | 78 |
| 82 AuthenticationMethod::AuthenticationMethod() | |
| 83 : type_(INVALID), | |
| 84 hash_function_(NONE) { | |
| 85 } | |
| 86 | |
| 87 AuthenticationMethod::AuthenticationMethod(MethodType type, | |
| 88 HashFunction hash_function) | |
| 89 : type_(type), | |
| 90 hash_function_(hash_function) { | |
| 91 DCHECK_NE(type_, INVALID); | |
| 92 } | |
| 93 | |
| 94 AuthenticationMethod::HashFunction AuthenticationMethod::hash_function() const { | |
| 95 DCHECK(is_valid()); | |
| 96 return hash_function_; | |
| 97 } | |
| 98 | |
| 99 const std::string AuthenticationMethod::ToString() const { | |
| 100 DCHECK(is_valid()); | |
| 101 | |
| 102 switch (type_) { | |
| 103 case INVALID: | |
| 104 NOTREACHED(); | |
| 105 break; | |
| 106 | |
| 107 case SPAKE2_PAIR: | |
| 108 return "spake2_pair"; | |
| 109 | |
| 110 case SPAKE2: | |
| 111 switch (hash_function_) { | |
| 112 case NONE: | |
| 113 return "spake2_plain"; | |
| 114 case HMAC_SHA256: | |
| 115 return "spake2_hmac"; | |
| 116 } | |
| 117 break; | |
| 118 | |
| 119 case THIRD_PARTY: | |
| 120 return "third_party"; | |
| 121 } | |
| 122 | |
| 123 return "invalid"; | |
| 124 } | |
| 125 | |
| 126 bool AuthenticationMethod::operator ==( | |
| 127 const AuthenticationMethod& other) const { | |
| 128 return type_ == other.type_ && | |
| 129 hash_function_ == other.hash_function_; | |
| 130 } | |
| 131 | |
| 132 bool SharedSecretHash::Parse(const std::string& as_string) { | |
| 133 size_t separator = as_string.find(':'); | |
| 134 if (separator == std::string::npos) | |
| 135 return false; | |
| 136 | |
| 137 std::string function_name = as_string.substr(0, separator); | |
| 138 if (function_name == "plain") { | |
| 139 hash_function = AuthenticationMethod::NONE; | |
| 140 } else if (function_name == "hmac") { | |
| 141 hash_function = AuthenticationMethod::HMAC_SHA256; | |
| 142 } else { | |
| 143 return false; | |
| 144 } | |
| 145 | |
| 146 if (!base::Base64Decode(as_string.substr(separator + 1), &value)) { | |
| 147 return false; | |
| 148 } | |
| 149 | |
| 150 return true; | |
| 151 } | |
| 152 | |
| 153 } // namespace protocol | 79 } // namespace protocol |
| 154 } // namespace remoting | 80 } // namespace remoting |
| OLD | NEW |