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 |