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

Side by Side Diff: components/proximity_auth/cryptauth/cryptauth_enroller_impl.cc

Issue 2502343003: Moved //components/proximity_auth/cryptauth to //components/cryptauth. (Closed)
Patch Set: Prefixed two test names with "CryptAuth" so that they do not collide with other test names. Created 4 years, 1 month 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 2015 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/proximity_auth/cryptauth/cryptauth_enroller_impl.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "components/proximity_auth/cryptauth/cryptauth_client_impl.h"
11 #include "components/proximity_auth/cryptauth/cryptauth_enrollment_utils.h"
12 #include "components/proximity_auth/cryptauth/secure_message_delegate.h"
13 #include "components/proximity_auth/logging/logging.h"
14 #include "crypto/sha2.h"
15
16 namespace proximity_auth {
17
18 namespace {
19
20 // A successful SetupEnrollment or FinishEnrollment response should contain this
21 // status string.
22 const char kResponseStatusOk[] = "ok";
23
24 // The name of the "gcmV1" protocol that the enrolling device supports.
25 const char kSupportedEnrollmentTypeGcmV1[] = "gcmV1";
26
27 // The version field of the GcmMetadata message.
28 const int kGCMMetadataVersion = 1;
29
30 // Returns true if |device_info| contains the required fields for enrollment.
31 bool ValidateDeviceInfo(const cryptauth::GcmDeviceInfo& device_info) {
32 if (!device_info.has_long_device_id()) {
33 PA_LOG(ERROR) << "Expected long_device_id field in GcmDeviceInfo.";
34 return false;
35 }
36
37 if (!device_info.has_device_type()) {
38 PA_LOG(ERROR) << "Expected device_type field in GcmDeviceInfo.";
39 return false;
40 }
41
42 return true;
43 }
44
45 // Creates the public metadata to put in the SecureMessage that is sent to the
46 // server with the FinishEnrollment request.
47 std::string CreateEnrollmentPublicMetadata() {
48 cryptauth::GcmMetadata metadata;
49 metadata.set_version(kGCMMetadataVersion);
50 metadata.set_type(cryptauth::MessageType::ENROLLMENT);
51 return metadata.SerializeAsString();
52 }
53
54 } // namespace
55
56 CryptAuthEnrollerImpl::CryptAuthEnrollerImpl(
57 std::unique_ptr<CryptAuthClientFactory> client_factory,
58 std::unique_ptr<SecureMessageDelegate> secure_message_delegate)
59 : client_factory_(std::move(client_factory)),
60 secure_message_delegate_(std::move(secure_message_delegate)),
61 weak_ptr_factory_(this) {}
62
63 CryptAuthEnrollerImpl::~CryptAuthEnrollerImpl() {
64 }
65
66 void CryptAuthEnrollerImpl::Enroll(
67 const std::string& user_public_key,
68 const std::string& user_private_key,
69 const cryptauth::GcmDeviceInfo& device_info,
70 cryptauth::InvocationReason invocation_reason,
71 const EnrollmentFinishedCallback& callback) {
72 if (!callback_.is_null()) {
73 PA_LOG(ERROR) << "Enroll() already called. Do not reuse.";
74 callback.Run(false);
75 return;
76 }
77
78 user_public_key_ = user_public_key;
79 user_private_key_ = user_private_key;
80 device_info_ = device_info;
81 invocation_reason_ = invocation_reason;
82 callback_ = callback;
83
84 if (!ValidateDeviceInfo(device_info)) {
85 callback.Run(false);
86 return;
87 }
88
89 secure_message_delegate_->GenerateKeyPair(
90 base::Bind(&CryptAuthEnrollerImpl::OnKeyPairGenerated,
91 weak_ptr_factory_.GetWeakPtr()));
92 }
93
94 void CryptAuthEnrollerImpl::OnKeyPairGenerated(const std::string& public_key,
95 const std::string& private_key) {
96 PA_LOG(INFO) << "Ephemeral key pair generated, calling SetupEnrollment API.";
97 session_public_key_ = public_key;
98 session_private_key_ = private_key;
99
100 cryptauth_client_ = client_factory_->CreateInstance();
101 cryptauth::SetupEnrollmentRequest request;
102 request.add_types(kSupportedEnrollmentTypeGcmV1);
103 request.set_invocation_reason(invocation_reason_);
104 cryptauth_client_->SetupEnrollment(
105 request, base::Bind(&CryptAuthEnrollerImpl::OnSetupEnrollmentSuccess,
106 weak_ptr_factory_.GetWeakPtr()),
107 base::Bind(&CryptAuthEnrollerImpl::OnSetupEnrollmentFailure,
108 weak_ptr_factory_.GetWeakPtr()));
109 }
110
111 void CryptAuthEnrollerImpl::OnSetupEnrollmentSuccess(
112 const cryptauth::SetupEnrollmentResponse& response) {
113 if (response.status() != kResponseStatusOk) {
114 PA_LOG(WARNING) << "Unexpected status for SetupEnrollment: "
115 << response.status();
116 callback_.Run(false);
117 return;
118 }
119
120 if (response.infos_size() == 0) {
121 PA_LOG(ERROR) << "No response info returned by server for SetupEnrollment";
122 callback_.Run(false);
123 return;
124 }
125
126 PA_LOG(INFO) << "SetupEnrollment request succeeded: deriving symmetric key.";
127 setup_info_ = response.infos(0);
128 device_info_.set_enrollment_session_id(setup_info_.enrollment_session_id());
129
130 secure_message_delegate_->DeriveKey(
131 session_private_key_, setup_info_.server_ephemeral_key(),
132 base::Bind(&CryptAuthEnrollerImpl::OnKeyDerived,
133 weak_ptr_factory_.GetWeakPtr()));
134 }
135
136 void CryptAuthEnrollerImpl::OnSetupEnrollmentFailure(const std::string& error) {
137 PA_LOG(WARNING) << "SetupEnrollment API failed with error: " << error;
138 callback_.Run(false);
139 }
140
141 void CryptAuthEnrollerImpl::OnKeyDerived(const std::string& symmetric_key) {
142 PA_LOG(INFO) << "Derived symmetric key, "
143 << "encrypting enrollment data for upload.";
144
145 // Make sure we're enrolling the same public key used below to sign the
146 // secure message.
147 device_info_.set_user_public_key(user_public_key_);
148 device_info_.set_key_handle(user_public_key_);
149
150 // Hash the symmetric key and add it to the |device_info_| to be uploaded.
151 device_info_.set_device_master_key_hash(
152 crypto::SHA256HashString(symmetric_key));
153
154 // The server verifies that the access token set here and in the header
155 // of the FinishEnrollment() request are the same.
156 device_info_.set_oauth_token(cryptauth_client_->GetAccessTokenUsed());
157 PA_LOG(INFO) << "Using access token: " << device_info_.oauth_token();
158
159 symmetric_key_ = symmetric_key;
160 SecureMessageDelegate::CreateOptions options;
161 options.encryption_scheme = securemessage::NONE;
162 options.signature_scheme = securemessage::ECDSA_P256_SHA256;
163 options.verification_key_id = user_public_key_;
164
165 // The inner message contains the signed device information that will be
166 // sent to CryptAuth.
167 secure_message_delegate_->CreateSecureMessage(
168 device_info_.SerializeAsString(), user_private_key_, options,
169 base::Bind(&CryptAuthEnrollerImpl::OnInnerSecureMessageCreated,
170 weak_ptr_factory_.GetWeakPtr()));
171 }
172
173 void CryptAuthEnrollerImpl::OnInnerSecureMessageCreated(
174 const std::string& inner_message) {
175 if (inner_message.empty()) {
176 PA_LOG(ERROR) << "Error creating inner message";
177 callback_.Run(false);
178 return;
179 }
180
181 SecureMessageDelegate::CreateOptions options;
182 options.encryption_scheme = securemessage::AES_256_CBC;
183 options.signature_scheme = securemessage::HMAC_SHA256;
184 options.public_metadata = CreateEnrollmentPublicMetadata();
185
186 // The outer message encrypts and signs the inner message with the derived
187 // symmetric session key.
188 secure_message_delegate_->CreateSecureMessage(
189 inner_message, symmetric_key_, options,
190 base::Bind(&CryptAuthEnrollerImpl::OnOuterSecureMessageCreated,
191 weak_ptr_factory_.GetWeakPtr()));
192 }
193
194 void CryptAuthEnrollerImpl::OnOuterSecureMessageCreated(
195 const std::string& outer_message) {
196 PA_LOG(INFO) << "SecureMessage created, calling FinishEnrollment API.";
197
198 cryptauth::FinishEnrollmentRequest request;
199 request.set_enrollment_session_id(setup_info_.enrollment_session_id());
200 request.set_enrollment_message(outer_message);
201 request.set_device_ephemeral_key(session_public_key_);
202 request.set_invocation_reason(invocation_reason_);
203
204 cryptauth_client_ = client_factory_->CreateInstance();
205 cryptauth_client_->FinishEnrollment(
206 request, base::Bind(&CryptAuthEnrollerImpl::OnFinishEnrollmentSuccess,
207 weak_ptr_factory_.GetWeakPtr()),
208 base::Bind(&CryptAuthEnrollerImpl::OnFinishEnrollmentFailure,
209 weak_ptr_factory_.GetWeakPtr()));
210 }
211
212 void CryptAuthEnrollerImpl::OnFinishEnrollmentSuccess(
213 const cryptauth::FinishEnrollmentResponse& response) {
214 if (response.status() != kResponseStatusOk) {
215 PA_LOG(WARNING) << "Unexpected status for FinishEnrollment: "
216 << response.status();
217 callback_.Run(false);
218 } else {
219 callback_.Run(true);
220 }
221 }
222
223 void CryptAuthEnrollerImpl::OnFinishEnrollmentFailure(
224 const std::string& error) {
225 PA_LOG(WARNING) << "FinishEnrollment API failed with error: " << error;
226 callback_.Run(false);
227 }
228
229 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698