14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/api/messaging/message_property_provider.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/json/json_writer.h" 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/logging.h" 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_piece.h" 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/values.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/api/runtime.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/base/completion_callback.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/cert/asn1_util.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/cert/jwk_serializer.h" 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/ssl/channel_id_service.h" 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/url_request/url_request_context.h" 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "url/gurl.h" 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace extensions { 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)MessagePropertyProvider::MessagePropertyProvider() {} 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void MessagePropertyProvider::GetChannelID(Profile* profile, 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL& source_url, const ChannelIDCallback& reply) { 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!source_url.is_valid()) { 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This isn't a real URL, so there's no sense in looking for a channel ID 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // for it. Dispatch with an empty tls channel ID. 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) reply.Run(std::string()); 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context_getter( 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) profile->GetRequestContext()); 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&MessagePropertyProvider::GetChannelIDOnIOThread, 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::MessageLoopProxy::current(), 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) request_context_getter, 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) source_url.host(), 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) reply)); 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Helper struct to bind the memory addresses that will be written to by 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// ChannelIDService::GetChannelID to the callback provided to 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// MessagePropertyProvider::GetChannelID. 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct MessagePropertyProvider::GetChannelIDOutput { 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string domain_bound_private_key; 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string domain_bound_cert; 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net::ChannelIDService::RequestHandle request_handle; 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void MessagePropertyProvider::GetChannelIDOnIOThread( 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<base::TaskRunner> original_task_runner, 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context_getter, 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& host, 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const ChannelIDCallback& reply) { 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net::ChannelIDService* channel_id_service = 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) request_context_getter->GetURLRequestContext()-> 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel_id_service(); 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetChannelIDOutput* output = new GetChannelIDOutput(); 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) net::CompletionCallback net_completion_callback = 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&MessagePropertyProvider::GotChannelID, 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) original_task_runner, 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Owned(output), 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) reply); 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int status = channel_id_service->GetChannelID( 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) host, 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &output->domain_bound_private_key, 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &output->domain_bound_cert, 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) net_completion_callback, 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &output->request_handle); 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (status == net::ERR_IO_PENDING) 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GotChannelID(original_task_runner, output, reply, status); 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void MessagePropertyProvider::GotChannelID( 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<base::TaskRunner> original_task_runner, 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) struct GetChannelIDOutput* output, 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const ChannelIDCallback& reply, 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int status) { 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Closure no_tls_channel_id_closure = base::Bind(reply, ""); 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (status != net::OK) { 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) original_task_runner->PostTask(FROM_HERE, no_tls_channel_id_closure); 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::StringPiece spki; 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!net::asn1::ExtractSPKIFromDERCert(output->domain_bound_cert, &spki)) { 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) original_task_runner->PostTask(FROM_HERE, no_tls_channel_id_closure); 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::DictionaryValue jwk_value; 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!net::JwkSerializer::ConvertSpkiFromDerToJwk(spki, &jwk_value)) { 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) original_task_runner->PostTask(FROM_HERE, no_tls_channel_id_closure); 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string jwk_str; 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::JSONWriter::Write(&jwk_value, &jwk_str); 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) original_task_runner->PostTask(FROM_HERE, base::Bind(reply, jwk_str)); 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace extensions 108