1 // Copyright 2013 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.
5 #include "remoting/host/token_validator_factory_impl.h"
7 #include "base/base64.h"
9 #include "base/callback.h"
10 #include "base/json/json_reader.h"
11 #include "base/logging.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/strings/string_util.h"
14 #include "base/values.h"
15 #include "crypto/random.h"
16 #include "net/base/elements_upload_data_stream.h"
17 #include "net/base/escape.h"
18 #include "net/base/io_buffer.h"
19 #include "net/base/request_priority.h"
20 #include "net/base/upload_bytes_element_reader.h"
21 #include "net/url_request/url_request.h"
22 #include "net/url_request/url_request_context.h"
23 #include "net/url_request/url_request_status.h"
24 #include "remoting/base/rsa_key_pair.h"
25 #include "remoting/host/token_validator_base.h"
30 // Length in bytes of the cryptographic nonce used to salt the token scope.
31 const size_t kNonceLength
= 16; // 128 bits.
38 class TokenValidatorImpl
: public TokenValidatorBase
{
41 const ThirdPartyAuthConfig
& third_party_auth_config
,
42 scoped_refptr
<RsaKeyPair
> key_pair
,
43 const std::string
& local_jid
,
44 const std::string
& remote_jid
,
45 scoped_refptr
<net::URLRequestContextGetter
> request_context_getter
);
48 void StartValidateRequest(const std::string
& token
) override
;
51 static std::string
CreateScope(const std::string
& local_jid
,
52 const std::string
& remote_jid
);
54 std::string post_body_
;
55 scoped_refptr
<RsaKeyPair
> key_pair_
;
57 DISALLOW_COPY_AND_ASSIGN(TokenValidatorImpl
);
60 TokenValidatorImpl::TokenValidatorImpl(
61 const ThirdPartyAuthConfig
& third_party_auth_config
,
62 scoped_refptr
<RsaKeyPair
> key_pair
,
63 const std::string
& local_jid
,
64 const std::string
& remote_jid
,
65 scoped_refptr
<net::URLRequestContextGetter
> request_context_getter
)
66 : TokenValidatorBase(third_party_auth_config
,
67 CreateScope(local_jid
, remote_jid
),
68 request_context_getter
),
70 DCHECK(key_pair_
.get());
71 token_scope_
= CreateScope(local_jid
, remote_jid
);
74 // TokenValidator interface.
75 void TokenValidatorImpl::StartValidateRequest(const std::string
& token
) {
76 post_body_
= "code=" + net::EscapeUrlEncodedData(token
, true) +
77 "&client_id=" + net::EscapeUrlEncodedData(
78 key_pair_
->GetPublicKey(), true) +
79 "&client_secret=" + net::EscapeUrlEncodedData(
80 key_pair_
->SignMessage(token
), true) +
81 "&grant_type=authorization_code";
83 request_
= request_context_getter_
->GetURLRequestContext()->CreateRequest(
84 third_party_auth_config_
.token_validation_url
, net::DEFAULT_PRIORITY
,
86 request_
->SetExtraRequestHeaderByName(
87 net::HttpRequestHeaders::kContentType
,
88 "application/x-www-form-urlencoded", true);
89 request_
->set_method("POST");
90 scoped_ptr
<net::UploadElementReader
> reader(
91 new net::UploadBytesElementReader(
92 post_body_
.data(), post_body_
.size()));
94 net::ElementsUploadDataStream::CreateWithReader(reader
.Pass(), 0));
98 std::string
TokenValidatorImpl::CreateScope(
99 const std::string
& local_jid
,
100 const std::string
& remote_jid
) {
101 std::string nonce_bytes
;
102 crypto::RandBytes(WriteInto(&nonce_bytes
, kNonceLength
+ 1), kNonceLength
);
104 base::Base64Encode(nonce_bytes
, &nonce
);
105 return "client:" + remote_jid
+ " host:" + local_jid
+ " nonce:" + nonce
;
108 TokenValidatorFactoryImpl::TokenValidatorFactoryImpl(
109 const ThirdPartyAuthConfig
& third_party_auth_config
,
110 scoped_refptr
<RsaKeyPair
> key_pair
,
111 scoped_refptr
<net::URLRequestContextGetter
> request_context_getter
)
112 : third_party_auth_config_(third_party_auth_config
),
114 request_context_getter_(request_context_getter
) {
117 TokenValidatorFactoryImpl::~TokenValidatorFactoryImpl() {
120 scoped_ptr
<protocol::TokenValidator
>
121 TokenValidatorFactoryImpl::CreateTokenValidator(
122 const std::string
& local_jid
,
123 const std::string
& remote_jid
) {
124 return make_scoped_ptr(
125 new TokenValidatorImpl(third_party_auth_config_
,
126 key_pair_
, local_jid
, remote_jid
,
127 request_context_getter_
));
130 } // namespace remoting