Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: content/browser/media/dtls_identity_store.cc

Issue 15969025: Generates the DTLS identity in browser process and returns it to render process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 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 "content/browser/media/dtls_identity_store.h"
6
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/rand_util.h"
12 #include "base/task_runner.h"
13 #include "base/threading/worker_pool.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "crypto/rsa_private_key.h"
16 #include "googleurl/src/gurl.h"
17 #include "net/base/net_errors.h"
18 #include "net/cert/x509_certificate.h"
19
20 namespace content {
21
22 namespace {
Ryan Sleevi 2013/06/13 22:36:47 STYLE: Linebreak
jiayl 2013/06/14 00:37:01 Done.
23 struct DTLSIdentityRequestResult {
24 int error;
25 std::string certificate;
26 std::string private_key;
27 };
28
29 static void GenerateIdentityWorker(const std::string& common_name,
30 DTLSIdentityRequestResult* result) {
31 result->error = net::OK;
32 std::string certificate;
33 std::vector<uint8> private_key_info;
34
35 int serial_number = base::RandInt(0, std::numeric_limits<int>::max());
36
37 scoped_ptr<crypto::RSAPrivateKey> key(crypto::RSAPrivateKey::Create(1024));
38 if (!key.get()) {
39 DLOG(ERROR) << "Unable to create key pair for client";
40 result->error = net::ERR_KEY_GENERATION_FAILED;
41 return;
42 }
43
44 scoped_refptr<net::X509Certificate> cert =
45 net::X509Certificate::CreateSelfSigned(key.get(),
46 "CN=" + common_name,
47 serial_number,
48 base::TimeDelta::FromDays(30));
49 if (!cert) {
50 DLOG(ERROR) << "Unable to create x509 cert for client";
51 result->error = net::ERR_SELF_SIGNED_CERT_GENERATION_FAILED;
52 return;
53 }
54 if (!net::X509Certificate::GetDEREncoded(cert->os_cert_handle(),
55 &result->certificate)) {
56 DLOG(ERROR) << "Unable to get the DER decoded data from the cert.";
57 result->error = net::ERR_SELF_SIGNED_CERT_GENERATION_FAILED;
58 return;
59 }
60
61 if (!key->ExportPrivateKey(&private_key_info)) {
62 DLOG(ERROR) << "Unable to export private key";
63 result->error = net::ERR_PRIVATE_KEY_EXPORT_FAILED;
64 return;
65 }
66
67 result->private_key =
68 std::string(private_key_info.begin(), private_key_info.end());
69 }
70
71 class DTLSIdentityRequest {
72 public:
73 DTLSIdentityRequest(const DTLSIdentityStore::CompletionCallback& callback)
74 : callback_(callback) {}
75
76 void Cancel() {
77 callback_.Reset();
78 }
79
80 void Post(DTLSIdentityRequestResult* result) {
81 if (callback_.is_null())
82 return;
83 callback_.Run(result->error, result->certificate, result->private_key);
84 }
85
86 private:
87 DTLSIdentityStore::CompletionCallback callback_;
88 };
89
90 } // namespace
91
92 DTLSIdentityStore::RequestHandle::RequestHandle()
93 : store_(NULL),
94 request_(NULL) {}
95
96 DTLSIdentityStore::RequestHandle::~RequestHandle() {
97 Cancel();
98 }
99
100 void DTLSIdentityStore::RequestHandle::Cancel() {
101 if (request_) {
102 store_->CancelRequest(request_);
103 request_ = NULL;
104 callback_.Reset();
105 }
106 }
107
108 void DTLSIdentityStore::RequestHandle::RequestStarted(
109 DTLSIdentityStore* store,
110 DTLSIdentityRequest* request,
111 const CompletionCallback& callback) {
112 DCHECK(request_ == NULL);
Ryan Sleevi 2013/06/13 22:36:47 DCHECK(!request_)
jiayl 2013/06/14 00:37:01 Done.
113 store_ = store;
114 request_ = request;
115 callback_ = callback;
116 }
117
118 void DTLSIdentityStore::RequestHandle::OnRequestComplete(
119 int error,
120 const std::string& certificate,
121 const std::string& private_key) {
122 request_ = NULL;
123 base::ResetAndReturn(&callback_).Run(error, certificate, private_key);
124 }
125
126 DTLSIdentityStore::DTLSIdentityStore()
127 : task_runner_(base::WorkerPool::GetTaskRunner(true)) {
128 }
129
130 DTLSIdentityStore::DTLSIdentityStore(
131 const scoped_refptr<base::TaskRunner>& task_runner)
132 : task_runner_(task_runner) {
133 }
134
135 DTLSIdentityStore::~DTLSIdentityStore() {}
136
137 void DTLSIdentityStore::RequestIdentity(const GURL& origin,
138 const std::string& identity_name,
139 const std::string& common_name,
140 const CompletionCallback& callback,
141 RequestHandle* out_request) {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
143 // TODO(jiayl): find the cert in the persistent store and generate a new one
144 // only when not found.
145 DTLSIdentityRequest* request = new DTLSIdentityRequest(
146 base::Bind(&RequestHandle::OnRequestComplete,
147 base::Unretained(out_request)));
148 out_request->RequestStarted(this, request, callback);
149
150 DTLSIdentityRequestResult* result = new DTLSIdentityRequestResult;
151 task_runner_->PostTaskAndReply(
152 FROM_HERE,
153 base::Bind(&GenerateIdentityWorker, common_name, result),
154 base::Bind(&DTLSIdentityRequest::Post,
155 base::Owned(request), base::Owned(result)));
156 }
157
158 void DTLSIdentityStore::CancelRequest(DTLSIdentityRequest* request) {
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
160 request->Cancel();
161 }
162
163 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698