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