Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / messaging / message_property_provider.cc
blobb52b02784b8bc044f2d3b6f32dcbc7b9b9acf5fe
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 "chrome/browser/extensions/api/messaging/message_property_provider.h"
7 #include "base/json/json_writer.h"
8 #include "base/logging.h"
9 #include "base/strings/string_piece.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/values.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "crypto/ec_private_key.h"
15 #include "extensions/common/api/runtime.h"
16 #include "net/base/completion_callback.h"
17 #include "net/cert/asn1_util.h"
18 #include "net/cert/jwk_serializer.h"
19 #include "net/ssl/channel_id_service.h"
20 #include "net/url_request/url_request_context.h"
21 #include "net/url_request/url_request_context_getter.h"
22 #include "url/gurl.h"
24 namespace extensions {
26 MessagePropertyProvider::MessagePropertyProvider() {}
28 void MessagePropertyProvider::GetChannelID(Profile* profile,
29 const GURL& source_url, const ChannelIDCallback& reply) {
30 if (!source_url.is_valid()) {
31 // This isn't a real URL, so there's no sense in looking for a channel ID
32 // for it. Dispatch with an empty tls channel ID.
33 reply.Run(std::string());
34 return;
36 scoped_refptr<net::URLRequestContextGetter> request_context_getter(
37 profile->GetRequestContext());
38 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
39 base::Bind(&MessagePropertyProvider::GetChannelIDOnIOThread,
40 base::ThreadTaskRunnerHandle::Get(),
41 request_context_getter,
42 source_url.host(),
43 reply));
46 // Helper struct to bind the memory addresses that will be written to by
47 // ChannelIDService::GetChannelID to the callback provided to
48 // MessagePropertyProvider::GetChannelID.
49 struct MessagePropertyProvider::GetChannelIDOutput {
50 scoped_ptr<crypto::ECPrivateKey> channel_id_key;
51 net::ChannelIDService::Request request;
54 // static
55 void MessagePropertyProvider::GetChannelIDOnIOThread(
56 scoped_refptr<base::TaskRunner> original_task_runner,
57 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
58 const std::string& host,
59 const ChannelIDCallback& reply) {
60 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
61 net::ChannelIDService* channel_id_service =
62 request_context_getter->GetURLRequestContext()->
63 channel_id_service();
64 GetChannelIDOutput* output = new GetChannelIDOutput();
65 net::CompletionCallback net_completion_callback =
66 base::Bind(&MessagePropertyProvider::GotChannelID,
67 original_task_runner,
68 base::Owned(output),
69 reply);
70 int status = channel_id_service->GetChannelID(
71 host, &output->channel_id_key, net_completion_callback, &output->request);
72 if (status == net::ERR_IO_PENDING)
73 return;
74 GotChannelID(original_task_runner, output, reply, status);
77 // static
78 void MessagePropertyProvider::GotChannelID(
79 scoped_refptr<base::TaskRunner> original_task_runner,
80 struct GetChannelIDOutput* output,
81 const ChannelIDCallback& reply,
82 int status) {
83 base::Closure no_tls_channel_id_closure = base::Bind(reply, "");
84 if (status != net::OK) {
85 original_task_runner->PostTask(FROM_HERE, no_tls_channel_id_closure);
86 return;
88 std::vector<uint8> spki_vector;
89 if (!output->channel_id_key->ExportPublicKey(&spki_vector)) {
90 original_task_runner->PostTask(FROM_HERE, no_tls_channel_id_closure);
91 return;
93 base::StringPiece spki(reinterpret_cast<char*>(vector_as_array(&spki_vector)),
94 spki_vector.size());
95 base::DictionaryValue jwk_value;
96 if (!net::JwkSerializer::ConvertSpkiFromDerToJwk(spki, &jwk_value)) {
97 original_task_runner->PostTask(FROM_HERE, no_tls_channel_id_closure);
98 return;
100 std::string jwk_str;
101 base::JSONWriter::Write(jwk_value, &jwk_str);
102 original_task_runner->PostTask(FROM_HERE, base::Bind(reply, jwk_str));
105 } // namespace extensions