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

Side by Side Diff: components/webauth/authenticator_impl.cc

Issue 2788823002: Add the Mojo implementation of authenticator.mojom's MakeCredential. (Closed)
Patch Set: Removed dispose method Created 3 years, 8 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 2017 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 "components/webauth/authenticator_impl.h"
6
7 #include <memory>
8
9 #include "base/json/json_writer.h"
10 #include "base/memory/ptr_util.h"
11 #include "content/public/browser/render_frame_host.h"
12 #include "content/public/browser/web_contents.h"
13 #include "crypto/sha2.h"
14 #include "mojo/public/cpp/bindings/strong_binding.h"
15
16 using content::RenderFrameHost;
17 using content::WebContents;
18
19 namespace webauth {
20
21 const char kGetAssertionType[] = "navigator.id.getAssertion";
22
23 // JSON key values
24 const char kTypeKey[] = "type";
25 const char kChallengeKey[] = "challenge";
26 const char kOriginKey[] = "origin";
27 const char kCidPubkeyKey[] = "cid_pubkey";
28
29 // Serializes the |value| to a JSON string and returns the result.
30 std::string SerializeValueToJson(const base::Value& value) {
31 std::string json;
32 base::JSONWriter::Write(value, &json);
33 return json;
34 }
35
36 // static
37 void AuthenticatorImpl::Create(
38 RenderFrameHost* render_frame_host,
39 mojo::InterfaceRequest<mojom::Authenticator> request) {
40 mojo::MakeStrongBinding(
41 base::MakeUnique<AuthenticatorImpl>(render_frame_host),
42 std::move(request));
43 }
44
45 AuthenticatorImpl::AuthenticatorImpl(RenderFrameHost* render_frame_host) {
46 DCHECK(render_frame_host);
47 set_connection_error_handler(base::Bind(
48 &AuthenticatorImpl::OnConnectionTerminated, base::Unretained(this)));
49 callerOrigin_ = render_frame_host->GetLastCommittedOrigin();
50 }
51
52 AuthenticatorImpl::~AuthenticatorImpl() {
53 if (!connection_error_handler_.is_null())
54 connection_error_handler_.Run();
55 }
56
57 // mojom:Authenticator
58 void AuthenticatorImpl::MakeCredential(
59 mojom::RelyingPartyAccountPtr account,
60 std::vector<mojom::ScopedCredentialParametersPtr> parameters,
61 const std::vector<uint8_t>& challenge,
62 mojom::ScopedCredentialOptionsPtr options,
63 const MakeCredentialCallback& callback) {
64 std::string effectiveDomain;
65 std::string relyingPartyId;
66 std::string clientDataJSON;
67 base::DictionaryValue clientData;
68
69 // Steps 3 & 4 of https://w3c.github.io/webauthn/#makeCredential
70 // opaque origin
71 if (callerOrigin_.Serialize() == "") {
72 callback.Run(mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, NULL);
73 return;
74 }
75
76 if (!options->rp_id) {
77 relyingPartyId = callerOrigin_.Serialize();
78 } else {
79 effectiveDomain = callerOrigin_.host();
80
81 if (effectiveDomain.empty()) {
82 callback.Run(mojom::AuthenticatorStatus::SECURITY_ERROR, NULL);
83 return;
84 }
85 // TODO(kpaulhamus): Check if relyingPartyId is a registrable domain
86 // suffix of and equal to effectiveDomain and set relyingPartyId
87 // appropriately.
88 relyingPartyId = options->rp_id.value_or(std::string());
89 }
90
91 // TODO(kpaulhamus): Check ScopedCredentialParameter's type and
92 // algorithmIdentifier after algorithmIdentifier is added to mojom to
93 // make sure it is U2F_V2.
94
95 clientData.SetString(kTypeKey, kGetAssertionType);
96 clientData.SetString(
97 kChallengeKey,
98 base::StringPiece(reinterpret_cast<const char*>(challenge.data()),
99 challenge.size()));
100 clientData.SetString(kOriginKey, relyingPartyId);
101 // Channel ID is optional, and missing if the browser doesn't support it.
102 // It is present and set to the constant "unused" if the browser
103 // supports Channel ID but is not using it to talk to the origin.
104 // TODO(kpaulhamus): Fetch and add the Channel ID public key used to
105 // communicate with the origin.
106 clientData.SetString(kCidPubkeyKey, "unused");
107
108 // SHA-256 hash the JSON data structure
109 clientDataJSON = SerializeValueToJson(clientData);
110 std::string clientDataHash = crypto::SHA256HashString(clientDataJSON);
111
112 // Step 16 of https://w3c.github.io/webauthn/#makeCredential
113 timeout_callback_.Reset(base::Bind(&AuthenticatorImpl::onTimeout,
114 base::Unretained(this), callback));
115 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
116 FROM_HERE, timeout_callback_.callback(),
117 base::TimeDelta::FromSecondsD(options->adjusted_timeout));
118
119 // Per fido-u2f-raw-message-formats:
120 // The challenge parameter is the SHA-256 hash of the Client Data,
121 // a stringified JSON data structure that the FIDO Client prepares.
122 // Among other things, the Client Data contains the challenge from the
123 // relying party (hence the name of the parameter).
124 // The application parameter is the SHA-256 hash of the UTF-8 encoding of
125 // the application identity of the application requesting the registration
126 /*
127 U2fRegister(clientDataHash, app_param, base::Bind(
128 &AuthenticatorImpl::onRegister, weak_factory_.GetWeakPtr(),
129 std::move(clientDataJSON), callback));
130 */
131
132 timeout_callback_.Cancel();
133 callback.Run(mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, NULL);
134 }
135
136 // Callback to handle the async response from a U2fDevice.
137 void AuthenticatorImpl::OnRegister(const MakeCredentialCallback& callback,
138 std::string& clientDataJSON,
139 uint8_t status_code,
140 std::vector<uint8_t> data) {
141 timeout_callback_.Cancel();
142 callback.Run(mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, NULL);
143 }
144
145 // Runs when timer expires and cancels all issued requests to a U2fDevice.
146 void AuthenticatorImpl::onTimeout(const MakeCredentialCallback& callback) {
147 callback.Run(mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, NULL);
148 }
149
150 void AuthenticatorImpl::OnConnectionTerminated() {
151 // Closures and cleanup due to either a browser-side error or
152 // as a result of the connection_error_handler, which can mean
153 // that the renderer has decided to close the pipe for various
154 // reasons.
155 }
156 } // namespace webauth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698