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

Side by Side Diff: components/cryptauth/device_to_device_initiator_operations.cc

Issue 2899863002: Updating D2D protocol to v1 to support separate sequence numbers. (Closed)
Patch Set: Addressing comments Created 3 years, 7 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/cryptauth/device_to_device_initiator_operations.h" 5 #include "components/cryptauth/device_to_device_initiator_operations.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/memory/ptr_util.h"
9 #include "components/cryptauth/proto/cryptauth_api.pb.h" 10 #include "components/cryptauth/proto/cryptauth_api.pb.h"
10 #include "components/cryptauth/proto/securemessage.pb.h" 11 #include "components/cryptauth/proto/securemessage.pb.h"
11 #include "components/cryptauth/secure_message_delegate.h" 12 #include "components/cryptauth/secure_message_delegate.h"
13 #include "components/cryptauth/session_keys.h"
12 #include "components/proximity_auth/logging/logging.h" 14 #include "components/proximity_auth/logging/logging.h"
13 15
14 namespace cryptauth { 16 namespace cryptauth {
15 17
16 namespace { 18 namespace {
17 19
18 // TODO(tengs): Due to a bug with the ChromeOS secure message daemon, we cannot 20 // TODO(tengs): Due to a bug with the ChromeOS secure message daemon, we cannot
19 // create SecureMessages with empty payloads. To workaround this bug, this value 21 // create SecureMessages with empty payloads. To workaround this bug, this value
20 // is put into the payload if it would otherwise be empty. 22 // is put into the payload if it would otherwise be empty.
21 // See crbug.com/512894. 23 // See crbug.com/512894.
22 const char kPayloadFiller[] = "\xae"; 24 const char kPayloadFiller[] = "\xae";
23 25
24 // The version to put in the GcmMetadata field. 26 // The version to put in the GcmMetadata field.
25 const int kGcmMetadataVersion = 1; 27 const int kGcmMetadataVersion = 1;
26 28
29 // The D2D protocol version.
30 const int kD2DProtocolVersion = 1;
31
27 // Callback for DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage(), 32 // Callback for DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage(),
28 // after the inner message is created. 33 // after the inner message is created.
29 void OnInnerMessageCreatedForInitiatorAuth( 34 void OnInnerMessageCreatedForInitiatorAuth(
30 const std::string& session_symmetric_key, 35 const SessionKeys& session_keys,
31 SecureMessageDelegate* secure_message_delegate, 36 SecureMessageDelegate* secure_message_delegate,
32 const DeviceToDeviceInitiatorOperations::MessageCallback& callback, 37 const DeviceToDeviceInitiatorOperations::MessageCallback& callback,
33 const std::string& inner_message) { 38 const std::string& inner_message) {
34 if (inner_message.empty()) { 39 if (inner_message.empty()) {
35 PA_LOG(INFO) << "Failed to create inner message for [Initiator Auth]."; 40 PA_LOG(INFO) << "Failed to create inner message for [Initiator Auth].";
36 callback.Run(std::string()); 41 callback.Run(std::string());
37 return; 42 return;
38 } 43 }
39 44
40 GcmMetadata gcm_metadata; 45 GcmMetadata gcm_metadata;
41 gcm_metadata.set_type(DEVICE_TO_DEVICE_MESSAGE); 46 gcm_metadata.set_type(DEVICE_TO_DEVICE_MESSAGE);
42 gcm_metadata.set_version(kGcmMetadataVersion); 47 gcm_metadata.set_version(kGcmMetadataVersion);
43 48
44 // Store the inner message inside a DeviceToDeviceMessage proto. 49 // Store the inner message inside a DeviceToDeviceMessage proto.
45 securemessage::DeviceToDeviceMessage device_to_device_message; 50 securemessage::DeviceToDeviceMessage device_to_device_message;
46 device_to_device_message.set_message(inner_message); 51 device_to_device_message.set_message(inner_message);
47 device_to_device_message.set_sequence_number(2); 52 device_to_device_message.set_sequence_number(1);
48 53
49 // Create and return the outer message, which wraps the inner message. 54 // Create and return the outer message, which wraps the inner message.
50 SecureMessageDelegate::CreateOptions create_options; 55 SecureMessageDelegate::CreateOptions create_options;
51 create_options.encryption_scheme = securemessage::AES_256_CBC; 56 create_options.encryption_scheme = securemessage::AES_256_CBC;
52 create_options.signature_scheme = securemessage::HMAC_SHA256; 57 create_options.signature_scheme = securemessage::HMAC_SHA256;
53 gcm_metadata.SerializeToString(&create_options.public_metadata); 58 gcm_metadata.SerializeToString(&create_options.public_metadata);
54 secure_message_delegate->CreateSecureMessage( 59 secure_message_delegate->CreateSecureMessage(
55 device_to_device_message.SerializeAsString(), session_symmetric_key, 60 device_to_device_message.SerializeAsString(),
56 create_options, callback); 61 session_keys.initiator_encode_key(), create_options, callback);
57 } 62 }
58 63
59 // Helper struct containing all the context needed to validate the 64 // Helper struct containing all the context needed to validate the
60 // [Responder Auth] message. 65 // [Responder Auth] message.
61 struct ValidateResponderAuthMessageContext { 66 struct ValidateResponderAuthMessageContext {
62 std::string responder_auth_message; 67 std::string responder_auth_message;
63 std::string persistent_responder_public_key; 68 std::string persistent_responder_public_key;
64 std::string persistent_symmetric_key; 69 std::string persistent_symmetric_key;
65 std::string session_private_key; 70 std::string session_private_key;
66 std::string hello_message; 71 std::string hello_message;
(...skipping 27 matching lines...) Expand all
94 99
95 // Begins the [Responder Auth] validation flow by validating the header. 100 // Begins the [Responder Auth] validation flow by validating the header.
96 void BeginResponderAuthValidation(ValidateResponderAuthMessageContext context) { 101 void BeginResponderAuthValidation(ValidateResponderAuthMessageContext context) {
97 // Parse the encrypted SecureMessage so we can get plaintext data from the 102 // Parse the encrypted SecureMessage so we can get plaintext data from the
98 // header. Note that the payload will be encrypted. 103 // header. Note that the payload will be encrypted.
99 securemessage::SecureMessage encrypted_message; 104 securemessage::SecureMessage encrypted_message;
100 securemessage::HeaderAndBody header_and_body; 105 securemessage::HeaderAndBody header_and_body;
101 if (!encrypted_message.ParseFromString(context.responder_auth_message) || 106 if (!encrypted_message.ParseFromString(context.responder_auth_message) ||
102 !header_and_body.ParseFromString(encrypted_message.header_and_body())) { 107 !header_and_body.ParseFromString(encrypted_message.header_and_body())) {
103 PA_LOG(WARNING) << "Failed to parse [Responder Hello] message"; 108 PA_LOG(WARNING) << "Failed to parse [Responder Hello] message";
104 context.callback.Run(false, std::string()); 109 context.callback.Run(false, SessionKeys());
105 return; 110 return;
106 } 111 }
107 112
108 // Check that header public_metadata contains the correct metadata fields. 113 // Check that header public_metadata contains the correct metadata fields.
109 securemessage::Header header = header_and_body.header(); 114 securemessage::Header header = header_and_body.header();
110 GcmMetadata gcm_metadata; 115 GcmMetadata gcm_metadata;
111 if (!gcm_metadata.ParseFromString(header.public_metadata()) || 116 if (!gcm_metadata.ParseFromString(header.public_metadata()) ||
112 gcm_metadata.type() != 117 gcm_metadata.type() !=
113 DEVICE_TO_DEVICE_RESPONDER_HELLO_PAYLOAD || 118 DEVICE_TO_DEVICE_RESPONDER_HELLO_PAYLOAD ||
114 gcm_metadata.version() != kGcmMetadataVersion) { 119 gcm_metadata.version() != kGcmMetadataVersion) {
115 PA_LOG(WARNING) << "Failed to validate GcmMetadata in " 120 PA_LOG(WARNING) << "Failed to validate GcmMetadata in "
116 << "[Responder Auth] header."; 121 << "[Responder Auth] header.";
117 context.callback.Run(false, std::string()); 122 context.callback.Run(false, SessionKeys());
118 return; 123 return;
119 } 124 }
120 125
121 // Extract responder session public key from |decryption_key_id| field. 126 // Extract responder session public key from |decryption_key_id| field.
122 securemessage::ResponderHello responder_hello; 127 securemessage::ResponderHello responder_hello;
123 if (!responder_hello.ParseFromString(header.decryption_key_id()) || 128 if (!responder_hello.ParseFromString(header.decryption_key_id()) ||
124 !responder_hello.public_dh_key().SerializeToString( 129 !responder_hello.public_dh_key().SerializeToString(
125 &context.responder_session_public_key)) { 130 &context.responder_session_public_key)) {
126 PA_LOG(INFO) << "Failed to extract responder session public key in " 131 PA_LOG(INFO) << "Failed to extract responder session public key in "
127 << "[Responder Auth] header."; 132 << "[Responder Auth] header.";
128 context.callback.Run(false, std::string()); 133 context.callback.Run(false, SessionKeys());
129 return; 134 return;
130 } 135 }
131 136
132 // Perform a Diffie-Helmann key exchange to get the session symmetric key. 137 // Perform a Diffie-Helmann key exchange to get the session symmetric key.
133 context.secure_message_delegate->DeriveKey( 138 context.secure_message_delegate->DeriveKey(
134 context.session_private_key, context.responder_session_public_key, 139 context.session_private_key, context.responder_session_public_key,
135 base::Bind(&OnSessionSymmetricKeyDerived, context)); 140 base::Bind(&OnSessionSymmetricKeyDerived, context));
136 } 141 }
137 142
138 // Called after the session symmetric key is derived, so now we can unwrap the 143 // Called after the session symmetric key is derived, so now we can unwrap the
139 // outer message of [Responder Auth]. 144 // outer message of [Responder Auth].
140 void OnSessionSymmetricKeyDerived(ValidateResponderAuthMessageContext context, 145 void OnSessionSymmetricKeyDerived(ValidateResponderAuthMessageContext context,
141 const std::string& session_symmetric_key) { 146 const std::string& session_symmetric_key) {
142 context.session_symmetric_key = session_symmetric_key; 147 context.session_symmetric_key = session_symmetric_key;
143 148
144 // Unwrap the outer message, using symmetric key encryption and signature. 149 // Unwrap the outer message, using symmetric key encryption and signature.
145 SecureMessageDelegate::UnwrapOptions unwrap_options; 150 SecureMessageDelegate::UnwrapOptions unwrap_options;
146 unwrap_options.encryption_scheme = securemessage::AES_256_CBC; 151 unwrap_options.encryption_scheme = securemessage::AES_256_CBC;
147 unwrap_options.signature_scheme = securemessage::HMAC_SHA256; 152 unwrap_options.signature_scheme = securemessage::HMAC_SHA256;
148 context.secure_message_delegate->UnwrapSecureMessage( 153 context.secure_message_delegate->UnwrapSecureMessage(
149 context.responder_auth_message, session_symmetric_key, unwrap_options, 154 context.responder_auth_message,
155 SessionKeys(session_symmetric_key).responder_encode_key(), unwrap_options,
150 base::Bind(&OnOuterMessageUnwrappedForResponderAuth, context)); 156 base::Bind(&OnOuterMessageUnwrappedForResponderAuth, context));
151 } 157 }
152 158
153 // Called after the outer-most layer of [Responder Auth] is unwrapped. 159 // Called after the outer-most layer of [Responder Auth] is unwrapped.
154 void OnOuterMessageUnwrappedForResponderAuth( 160 void OnOuterMessageUnwrappedForResponderAuth(
155 const ValidateResponderAuthMessageContext& context, 161 const ValidateResponderAuthMessageContext& context,
156 bool verified, 162 bool verified,
157 const std::string& payload, 163 const std::string& payload,
158 const securemessage::Header& header) { 164 const securemessage::Header& header) {
159 if (!verified) { 165 if (!verified) {
160 PA_LOG(INFO) << "Failed to unwrap outer [Responder Auth] message."; 166 PA_LOG(INFO) << "Failed to unwrap outer [Responder Auth] message.";
161 context.callback.Run(false, std::string()); 167 context.callback.Run(false, SessionKeys());
162 return; 168 return;
163 } 169 }
164 170
165 // Parse the decrypted payload. 171 // Parse the decrypted payload.
166 securemessage::DeviceToDeviceMessage device_to_device_message; 172 securemessage::DeviceToDeviceMessage device_to_device_message;
167 if (!device_to_device_message.ParseFromString(payload) || 173 if (!device_to_device_message.ParseFromString(payload) ||
168 device_to_device_message.sequence_number() != 1) { 174 device_to_device_message.sequence_number() != 1) {
169 PA_LOG(INFO) << "Failed to validate DeviceToDeviceMessage payload."; 175 PA_LOG(INFO) << "Failed to validate DeviceToDeviceMessage payload.";
170 context.callback.Run(false, std::string()); 176 context.callback.Run(false, SessionKeys());
171 return; 177 return;
172 } 178 }
173 179
174 // Unwrap the middle level SecureMessage, using symmetric key encryption and 180 // Unwrap the middle level SecureMessage, using symmetric key encryption and
175 // signature. 181 // signature.
176 SecureMessageDelegate::UnwrapOptions unwrap_options; 182 SecureMessageDelegate::UnwrapOptions unwrap_options;
177 unwrap_options.encryption_scheme = securemessage::AES_256_CBC; 183 unwrap_options.encryption_scheme = securemessage::AES_256_CBC;
178 unwrap_options.signature_scheme = securemessage::HMAC_SHA256; 184 unwrap_options.signature_scheme = securemessage::HMAC_SHA256;
179 unwrap_options.associated_data = context.hello_message; 185 unwrap_options.associated_data = context.hello_message;
180 context.secure_message_delegate->UnwrapSecureMessage( 186 context.secure_message_delegate->UnwrapSecureMessage(
181 device_to_device_message.message(), context.persistent_symmetric_key, 187 device_to_device_message.message(), context.persistent_symmetric_key,
182 unwrap_options, 188 unwrap_options,
183 base::Bind(&OnMiddleMessageUnwrappedForResponderAuth, context)); 189 base::Bind(&OnMiddleMessageUnwrappedForResponderAuth, context));
184 } 190 }
185 191
186 // Called after the middle layer of [Responder Auth] is unwrapped. 192 // Called after the middle layer of [Responder Auth] is unwrapped.
187 void OnMiddleMessageUnwrappedForResponderAuth( 193 void OnMiddleMessageUnwrappedForResponderAuth(
188 const ValidateResponderAuthMessageContext& context, 194 const ValidateResponderAuthMessageContext& context,
189 bool verified, 195 bool verified,
190 const std::string& payload, 196 const std::string& payload,
191 const securemessage::Header& header) { 197 const securemessage::Header& header) {
192 if (!verified) { 198 if (!verified) {
193 PA_LOG(INFO) << "Failed to unwrap middle [Responder Auth] message."; 199 PA_LOG(INFO) << "Failed to unwrap middle [Responder Auth] message.";
194 context.callback.Run(false, std::string()); 200 context.callback.Run(false, SessionKeys());
195 return; 201 return;
196 } 202 }
197 203
198 // Unwrap the inner-most SecureMessage, using no encryption and an asymmetric 204 // Unwrap the inner-most SecureMessage, using no encryption and an asymmetric
199 // key signature. 205 // key signature.
200 SecureMessageDelegate::UnwrapOptions unwrap_options; 206 SecureMessageDelegate::UnwrapOptions unwrap_options;
201 unwrap_options.encryption_scheme = securemessage::NONE; 207 unwrap_options.encryption_scheme = securemessage::NONE;
202 unwrap_options.signature_scheme = securemessage::ECDSA_P256_SHA256; 208 unwrap_options.signature_scheme = securemessage::ECDSA_P256_SHA256;
203 unwrap_options.associated_data = context.hello_message; 209 unwrap_options.associated_data = context.hello_message;
204 context.secure_message_delegate->UnwrapSecureMessage( 210 context.secure_message_delegate->UnwrapSecureMessage(
(...skipping 10 matching lines...) Expand all
215 if (!verified) 221 if (!verified)
216 PA_LOG(INFO) << "Failed to unwrap inner [Responder Auth] message."; 222 PA_LOG(INFO) << "Failed to unwrap inner [Responder Auth] message.";
217 223
218 // Note: The GMS Core implementation does not properly set the metadata 224 // Note: The GMS Core implementation does not properly set the metadata
219 // version, so we only check that the type is UNLOCK_KEY_SIGNED_CHALLENGE. 225 // version, so we only check that the type is UNLOCK_KEY_SIGNED_CHALLENGE.
220 GcmMetadata gcm_metadata; 226 GcmMetadata gcm_metadata;
221 if (!gcm_metadata.ParseFromString(header.public_metadata()) || 227 if (!gcm_metadata.ParseFromString(header.public_metadata()) ||
222 gcm_metadata.type() != UNLOCK_KEY_SIGNED_CHALLENGE) { 228 gcm_metadata.type() != UNLOCK_KEY_SIGNED_CHALLENGE) {
223 PA_LOG(WARNING) << "Failed to validate GcmMetadata in inner-most " 229 PA_LOG(WARNING) << "Failed to validate GcmMetadata in inner-most "
224 << "[Responder Auth] message."; 230 << "[Responder Auth] message.";
225 context.callback.Run(false, std::string()); 231 context.callback.Run(false, SessionKeys());
226 return; 232 return;
227 } 233 }
228 234
229 context.callback.Run(verified, context.session_symmetric_key); 235 context.callback.Run(verified, SessionKeys(context.session_symmetric_key));
230 } 236 }
231 237
232 } // namespace 238 } // namespace
233 239
234 // static 240 // static
235 void DeviceToDeviceInitiatorOperations::CreateHelloMessage( 241 void DeviceToDeviceInitiatorOperations::CreateHelloMessage(
236 const std::string& session_public_key, 242 const std::string& session_public_key,
237 const std::string& persistent_symmetric_key, 243 const std::string& persistent_symmetric_key,
238 SecureMessageDelegate* secure_message_delegate, 244 SecureMessageDelegate* secure_message_delegate,
239 const MessageCallback& callback) { 245 const MessageCallback& callback) {
240 // Decode public key into the |initator_hello| proto. 246 // Decode public key into the |initator_hello| proto.
241 securemessage::InitiatorHello initator_hello; 247 securemessage::InitiatorHello initiator_hello;
242 if (!initator_hello.mutable_public_dh_key()->ParseFromString( 248 if (!initiator_hello.mutable_public_dh_key()->ParseFromString(
243 session_public_key)) { 249 session_public_key)) {
244 PA_LOG(ERROR) << "Unable to parse user's public key"; 250 PA_LOG(ERROR) << "Unable to parse user's public key";
245 callback.Run(std::string()); 251 callback.Run(std::string());
246 return; 252 return;
247 } 253 }
254 initiator_hello.set_protocol_version(kD2DProtocolVersion);
248 255
249 // The [Hello] message has the structure: 256 // The [Hello] message has the structure:
250 // { 257 // {
251 // header: <session_public_key>, 258 // header: <session_public_key>,
252 // Sig(<session_public_key>, persistent_symmetric_key) 259 // Sig(<session_public_key>, persistent_symmetric_key)
253 // payload: "" 260 // payload: ""
254 // } 261 // }
255 SecureMessageDelegate::CreateOptions create_options; 262 SecureMessageDelegate::CreateOptions create_options;
256 create_options.encryption_scheme = securemessage::NONE; 263 create_options.encryption_scheme = securemessage::NONE;
257 create_options.signature_scheme = securemessage::HMAC_SHA256; 264 create_options.signature_scheme = securemessage::HMAC_SHA256;
258 initator_hello.SerializeToString(&create_options.public_metadata); 265 initiator_hello.SerializeToString(&create_options.public_metadata);
259 secure_message_delegate->CreateSecureMessage( 266 secure_message_delegate->CreateSecureMessage(
260 kPayloadFiller, persistent_symmetric_key, create_options, callback); 267 kPayloadFiller, persistent_symmetric_key, create_options, callback);
261 } 268 }
262 269
263 // static 270 // static
264 void DeviceToDeviceInitiatorOperations::ValidateResponderAuthMessage( 271 void DeviceToDeviceInitiatorOperations::ValidateResponderAuthMessage(
265 const std::string& responder_auth_message, 272 const std::string& responder_auth_message,
266 const std::string& persistent_responder_public_key, 273 const std::string& persistent_responder_public_key,
267 const std::string& persistent_symmetric_key, 274 const std::string& persistent_symmetric_key,
268 const std::string& session_private_key, 275 const std::string& session_private_key,
(...skipping 23 matching lines...) Expand all
292 persistent_symmetric_key, 299 persistent_symmetric_key,
293 session_private_key, 300 session_private_key,
294 hello_message, 301 hello_message,
295 secure_message_delegate, 302 secure_message_delegate,
296 callback}; 303 callback};
297 BeginResponderAuthValidation(context); 304 BeginResponderAuthValidation(context);
298 } 305 }
299 306
300 // static 307 // static
301 void DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage( 308 void DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage(
302 const std::string& session_symmetric_key, 309 const SessionKeys& session_keys,
303 const std::string& persistent_symmetric_key, 310 const std::string& persistent_symmetric_key,
304 const std::string& responder_auth_message, 311 const std::string& responder_auth_message,
305 SecureMessageDelegate* secure_message_delegate, 312 SecureMessageDelegate* secure_message_delegate,
306 const MessageCallback& callback) { 313 const MessageCallback& callback) {
307 // The [Initiator Auth] message has the structure: 314 // The [Initiator Auth] message has the structure:
308 // { 315 // {
309 // header: Sig(payload1, session_symmetric_key) 316 // header: Sig(payload1, session_symmetric_key)
310 // payload1: Enc({ 317 // payload1: Enc({
311 // sequence_number: 2, 318 // sequence_number: 2,
312 // body: { 319 // body: {
313 // header: Sig(payload2 + responder_auth_message, 320 // header: Sig(payload2 + responder_auth_message,
314 // persistent_symmetric_key) 321 // persistent_symmetric_key)
315 // payload2: "" 322 // payload2: ""
316 // } 323 // }
317 // }, session_symmetric_key) 324 // }, session_symmetric_key)
318 // } 325 // }
319 SecureMessageDelegate::CreateOptions create_options; 326 SecureMessageDelegate::CreateOptions create_options;
320 create_options.encryption_scheme = securemessage::AES_256_CBC; 327 create_options.encryption_scheme = securemessage::AES_256_CBC;
321 create_options.signature_scheme = securemessage::HMAC_SHA256; 328 create_options.signature_scheme = securemessage::HMAC_SHA256;
322 create_options.associated_data = responder_auth_message; 329 create_options.associated_data = responder_auth_message;
323 secure_message_delegate->CreateSecureMessage( 330 secure_message_delegate->CreateSecureMessage(
324 kPayloadFiller, persistent_symmetric_key, create_options, 331 kPayloadFiller, persistent_symmetric_key, create_options,
325 base::Bind(&OnInnerMessageCreatedForInitiatorAuth, session_symmetric_key, 332 base::Bind(&OnInnerMessageCreatedForInitiatorAuth, session_keys,
326 secure_message_delegate, callback)); 333 secure_message_delegate, callback));
327 } 334 }
328 335
329 } // cryptauth 336 } // cryptauth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698