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. 4 5 #include "remoting/host/token_validator_factory_impl.h" 6 7 #include "base/base64.h" 8 #include "base/bind.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/escape.h" 17 #include "net/base/io_buffer.h" 18 #include "net/base/request_priority.h" 19 #include "net/base/upload_bytes_element_reader.h" 20 #include "net/base/upload_data_stream.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" 26 #include "url/gurl.h" 27 28 namespace { 29 30 // Length in bytes of the cryptographic nonce used to salt the token scope. 31 const size_t kNonceLength = 16; // 128 bits. 32 33 } // namespace 34 35 namespace remoting { 36 37 38 class TokenValidatorImpl : public TokenValidatorBase { 39 public: 40 TokenValidatorImpl( 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); 46 47 protected: 48 virtual void StartValidateRequest(const std::string& token) OVERRIDE; 49 50 private: 51 static std::string CreateScope(const std::string& local_jid, 52 const std::string& remote_jid); 53 54 std::string post_body_; 55 scoped_refptr<RsaKeyPair> key_pair_; 56 57 DISALLOW_COPY_AND_ASSIGN(TokenValidatorImpl); 58 }; 59 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), 69 key_pair_(key_pair) { 70 DCHECK(key_pair_.get()); 71 token_scope_ = CreateScope(local_jid, remote_jid); 72 } 73 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"; 82 83 request_ = request_context_getter_->GetURLRequestContext()->CreateRequest( 84 third_party_auth_config_.token_validation_url, net::DEFAULT_PRIORITY, 85 this, NULL); 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())); 93 request_->set_upload(make_scoped_ptr( 94 net::UploadDataStream::CreateWithReader(reader.Pass(), 0))); 95 request_->Start(); 96 } 97 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); 103 std::string nonce; 104 base::Base64Encode(nonce_bytes, &nonce); 105 return "client:" + remote_jid + " host:" + local_jid + " nonce:" + nonce; 106 } 107 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), 113 key_pair_(key_pair), 114 request_context_getter_(request_context_getter) { 115 } 116 117 TokenValidatorFactoryImpl::~TokenValidatorFactoryImpl() { 118 } 119 120 scoped_ptr<protocol::TokenValidator> 121 TokenValidatorFactoryImpl::CreateTokenValidator( 122 const std::string& local_jid, 123 const std::string& remote_jid) { 124 return scoped_ptr<protocol::TokenValidator>( 125 new TokenValidatorImpl(third_party_auth_config_, 126 key_pair_, local_jid, remote_jid, 127 request_context_getter_)); 128 } 129 130 } // namespace remoting 131