| OLD | NEW |
| 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/proximity_auth/device_to_device_initiator_operations.h" | 5 #include "components/proximity_auth/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 "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h" | 9 #include "components/cryptauth/proto/cryptauth_api.pb.h" |
| 10 #include "components/proximity_auth/cryptauth/proto/securemessage.pb.h" | 10 #include "components/cryptauth/proto/securemessage.pb.h" |
| 11 #include "components/proximity_auth/cryptauth/secure_message_delegate.h" | 11 #include "components/cryptauth/secure_message_delegate.h" |
| 12 #include "components/proximity_auth/logging/logging.h" | 12 #include "components/proximity_auth/logging/logging.h" |
| 13 | 13 |
| 14 namespace proximity_auth { | 14 namespace proximity_auth { |
| 15 | 15 |
| 16 namespace { | 16 namespace { |
| 17 | 17 |
| 18 // TODO(tengs): Due to a bug with the ChromeOS secure message daemon, we cannot | 18 // 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 | 19 // create SecureMessages with empty payloads. To workaround this bug, this value |
| 20 // is put into the payload if it would otherwise be empty. | 20 // is put into the payload if it would otherwise be empty. |
| 21 // See crbug.com/512894. | 21 // See crbug.com/512894. |
| 22 const char kPayloadFiller[] = "\xae"; | 22 const char kPayloadFiller[] = "\xae"; |
| 23 | 23 |
| 24 // The version to put in the GcmMetadata field. | 24 // The version to put in the GcmMetadata field. |
| 25 const int kGcmMetadataVersion = 1; | 25 const int kGcmMetadataVersion = 1; |
| 26 | 26 |
| 27 // Callback for DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage(), | 27 // Callback for DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage(), |
| 28 // after the inner message is created. | 28 // after the inner message is created. |
| 29 void OnInnerMessageCreatedForInitiatorAuth( | 29 void OnInnerMessageCreatedForInitiatorAuth( |
| 30 const std::string& session_symmetric_key, | 30 const std::string& session_symmetric_key, |
| 31 SecureMessageDelegate* secure_message_delegate, | 31 cryptauth::SecureMessageDelegate* secure_message_delegate, |
| 32 const DeviceToDeviceInitiatorOperations::MessageCallback& callback, | 32 const DeviceToDeviceInitiatorOperations::MessageCallback& callback, |
| 33 const std::string& inner_message) { | 33 const std::string& inner_message) { |
| 34 if (inner_message.empty()) { | 34 if (inner_message.empty()) { |
| 35 PA_LOG(INFO) << "Failed to create inner message for [Initiator Auth]."; | 35 PA_LOG(INFO) << "Failed to create inner message for [Initiator Auth]."; |
| 36 callback.Run(std::string()); | 36 callback.Run(std::string()); |
| 37 return; | 37 return; |
| 38 } | 38 } |
| 39 | 39 |
| 40 cryptauth::GcmMetadata gcm_metadata; | 40 cryptauth::GcmMetadata gcm_metadata; |
| 41 gcm_metadata.set_type(cryptauth::DEVICE_TO_DEVICE_MESSAGE); | 41 gcm_metadata.set_type(cryptauth::DEVICE_TO_DEVICE_MESSAGE); |
| 42 gcm_metadata.set_version(kGcmMetadataVersion); | 42 gcm_metadata.set_version(kGcmMetadataVersion); |
| 43 | 43 |
| 44 // Store the inner message inside a DeviceToDeviceMessage proto. | 44 // Store the inner message inside a DeviceToDeviceMessage proto. |
| 45 securemessage::DeviceToDeviceMessage device_to_device_message; | 45 securemessage::DeviceToDeviceMessage device_to_device_message; |
| 46 device_to_device_message.set_message(inner_message); | 46 device_to_device_message.set_message(inner_message); |
| 47 device_to_device_message.set_sequence_number(2); | 47 device_to_device_message.set_sequence_number(2); |
| 48 | 48 |
| 49 // Create and return the outer message, which wraps the inner message. | 49 // Create and return the outer message, which wraps the inner message. |
| 50 SecureMessageDelegate::CreateOptions create_options; | 50 cryptauth::SecureMessageDelegate::CreateOptions create_options; |
| 51 create_options.encryption_scheme = securemessage::AES_256_CBC; | 51 create_options.encryption_scheme = securemessage::AES_256_CBC; |
| 52 create_options.signature_scheme = securemessage::HMAC_SHA256; | 52 create_options.signature_scheme = securemessage::HMAC_SHA256; |
| 53 gcm_metadata.SerializeToString(&create_options.public_metadata); | 53 gcm_metadata.SerializeToString(&create_options.public_metadata); |
| 54 secure_message_delegate->CreateSecureMessage( | 54 secure_message_delegate->CreateSecureMessage( |
| 55 device_to_device_message.SerializeAsString(), session_symmetric_key, | 55 device_to_device_message.SerializeAsString(), session_symmetric_key, |
| 56 create_options, callback); | 56 create_options, callback); |
| 57 } | 57 } |
| 58 | 58 |
| 59 // Helper struct containing all the context needed to validate the | 59 // Helper struct containing all the context needed to validate the |
| 60 // [Responder Auth] message. | 60 // [Responder Auth] message. |
| 61 struct ValidateResponderAuthMessageContext { | 61 struct ValidateResponderAuthMessageContext { |
| 62 std::string responder_auth_message; | 62 std::string responder_auth_message; |
| 63 std::string persistent_responder_public_key; | 63 std::string persistent_responder_public_key; |
| 64 std::string persistent_symmetric_key; | 64 std::string persistent_symmetric_key; |
| 65 std::string session_private_key; | 65 std::string session_private_key; |
| 66 std::string hello_message; | 66 std::string hello_message; |
| 67 SecureMessageDelegate* secure_message_delegate; | 67 cryptauth::SecureMessageDelegate* secure_message_delegate; |
| 68 DeviceToDeviceInitiatorOperations::ValidateResponderAuthCallback callback; | 68 DeviceToDeviceInitiatorOperations::ValidateResponderAuthCallback callback; |
| 69 std::string responder_session_public_key; | 69 std::string responder_session_public_key; |
| 70 std::string session_symmetric_key; | 70 std::string session_symmetric_key; |
| 71 }; | 71 }; |
| 72 | 72 |
| 73 // Forward declarations of functions used in the [Responder Auth] validation | 73 // Forward declarations of functions used in the [Responder Auth] validation |
| 74 // flow. These functions are declared in order in which they are called during | 74 // flow. These functions are declared in order in which they are called during |
| 75 // the flow. | 75 // the flow. |
| 76 void BeginResponderAuthValidation(ValidateResponderAuthMessageContext context); | 76 void BeginResponderAuthValidation(ValidateResponderAuthMessageContext context); |
| 77 void OnSessionSymmetricKeyDerived(ValidateResponderAuthMessageContext context, | 77 void OnSessionSymmetricKeyDerived(ValidateResponderAuthMessageContext context, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 base::Bind(&OnSessionSymmetricKeyDerived, context)); | 135 base::Bind(&OnSessionSymmetricKeyDerived, context)); |
| 136 } | 136 } |
| 137 | 137 |
| 138 // Called after the session symmetric key is derived, so now we can unwrap the | 138 // Called after the session symmetric key is derived, so now we can unwrap the |
| 139 // outer message of [Responder Auth]. | 139 // outer message of [Responder Auth]. |
| 140 void OnSessionSymmetricKeyDerived(ValidateResponderAuthMessageContext context, | 140 void OnSessionSymmetricKeyDerived(ValidateResponderAuthMessageContext context, |
| 141 const std::string& session_symmetric_key) { | 141 const std::string& session_symmetric_key) { |
| 142 context.session_symmetric_key = session_symmetric_key; | 142 context.session_symmetric_key = session_symmetric_key; |
| 143 | 143 |
| 144 // Unwrap the outer message, using symmetric key encryption and signature. | 144 // Unwrap the outer message, using symmetric key encryption and signature. |
| 145 SecureMessageDelegate::UnwrapOptions unwrap_options; | 145 cryptauth::SecureMessageDelegate::UnwrapOptions unwrap_options; |
| 146 unwrap_options.encryption_scheme = securemessage::AES_256_CBC; | 146 unwrap_options.encryption_scheme = securemessage::AES_256_CBC; |
| 147 unwrap_options.signature_scheme = securemessage::HMAC_SHA256; | 147 unwrap_options.signature_scheme = securemessage::HMAC_SHA256; |
| 148 context.secure_message_delegate->UnwrapSecureMessage( | 148 context.secure_message_delegate->UnwrapSecureMessage( |
| 149 context.responder_auth_message, session_symmetric_key, unwrap_options, | 149 context.responder_auth_message, session_symmetric_key, unwrap_options, |
| 150 base::Bind(&OnOuterMessageUnwrappedForResponderAuth, context)); | 150 base::Bind(&OnOuterMessageUnwrappedForResponderAuth, context)); |
| 151 } | 151 } |
| 152 | 152 |
| 153 // Called after the outer-most layer of [Responder Auth] is unwrapped. | 153 // Called after the outer-most layer of [Responder Auth] is unwrapped. |
| 154 void OnOuterMessageUnwrappedForResponderAuth( | 154 void OnOuterMessageUnwrappedForResponderAuth( |
| 155 const ValidateResponderAuthMessageContext& context, | 155 const ValidateResponderAuthMessageContext& context, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 166 securemessage::DeviceToDeviceMessage device_to_device_message; | 166 securemessage::DeviceToDeviceMessage device_to_device_message; |
| 167 if (!device_to_device_message.ParseFromString(payload) || | 167 if (!device_to_device_message.ParseFromString(payload) || |
| 168 device_to_device_message.sequence_number() != 1) { | 168 device_to_device_message.sequence_number() != 1) { |
| 169 PA_LOG(INFO) << "Failed to validate DeviceToDeviceMessage payload."; | 169 PA_LOG(INFO) << "Failed to validate DeviceToDeviceMessage payload."; |
| 170 context.callback.Run(false, std::string()); | 170 context.callback.Run(false, std::string()); |
| 171 return; | 171 return; |
| 172 } | 172 } |
| 173 | 173 |
| 174 // Unwrap the middle level SecureMessage, using symmetric key encryption and | 174 // Unwrap the middle level SecureMessage, using symmetric key encryption and |
| 175 // signature. | 175 // signature. |
| 176 SecureMessageDelegate::UnwrapOptions unwrap_options; | 176 cryptauth::SecureMessageDelegate::UnwrapOptions unwrap_options; |
| 177 unwrap_options.encryption_scheme = securemessage::AES_256_CBC; | 177 unwrap_options.encryption_scheme = securemessage::AES_256_CBC; |
| 178 unwrap_options.signature_scheme = securemessage::HMAC_SHA256; | 178 unwrap_options.signature_scheme = securemessage::HMAC_SHA256; |
| 179 unwrap_options.associated_data = context.hello_message; | 179 unwrap_options.associated_data = context.hello_message; |
| 180 context.secure_message_delegate->UnwrapSecureMessage( | 180 context.secure_message_delegate->UnwrapSecureMessage( |
| 181 device_to_device_message.message(), context.persistent_symmetric_key, | 181 device_to_device_message.message(), context.persistent_symmetric_key, |
| 182 unwrap_options, | 182 unwrap_options, |
| 183 base::Bind(&OnMiddleMessageUnwrappedForResponderAuth, context)); | 183 base::Bind(&OnMiddleMessageUnwrappedForResponderAuth, context)); |
| 184 } | 184 } |
| 185 | 185 |
| 186 // Called after the middle layer of [Responder Auth] is unwrapped. | 186 // Called after the middle layer of [Responder Auth] is unwrapped. |
| 187 void OnMiddleMessageUnwrappedForResponderAuth( | 187 void OnMiddleMessageUnwrappedForResponderAuth( |
| 188 const ValidateResponderAuthMessageContext& context, | 188 const ValidateResponderAuthMessageContext& context, |
| 189 bool verified, | 189 bool verified, |
| 190 const std::string& payload, | 190 const std::string& payload, |
| 191 const securemessage::Header& header) { | 191 const securemessage::Header& header) { |
| 192 if (!verified) { | 192 if (!verified) { |
| 193 PA_LOG(INFO) << "Failed to unwrap middle [Responder Auth] message."; | 193 PA_LOG(INFO) << "Failed to unwrap middle [Responder Auth] message."; |
| 194 context.callback.Run(false, std::string()); | 194 context.callback.Run(false, std::string()); |
| 195 return; | 195 return; |
| 196 } | 196 } |
| 197 | 197 |
| 198 // Unwrap the inner-most SecureMessage, using no encryption and an asymmetric | 198 // Unwrap the inner-most SecureMessage, using no encryption and an asymmetric |
| 199 // key signature. | 199 // key signature. |
| 200 SecureMessageDelegate::UnwrapOptions unwrap_options; | 200 cryptauth::SecureMessageDelegate::UnwrapOptions unwrap_options; |
| 201 unwrap_options.encryption_scheme = securemessage::NONE; | 201 unwrap_options.encryption_scheme = securemessage::NONE; |
| 202 unwrap_options.signature_scheme = securemessage::ECDSA_P256_SHA256; | 202 unwrap_options.signature_scheme = securemessage::ECDSA_P256_SHA256; |
| 203 unwrap_options.associated_data = context.hello_message; | 203 unwrap_options.associated_data = context.hello_message; |
| 204 context.secure_message_delegate->UnwrapSecureMessage( | 204 context.secure_message_delegate->UnwrapSecureMessage( |
| 205 payload, context.persistent_responder_public_key, unwrap_options, | 205 payload, context.persistent_responder_public_key, unwrap_options, |
| 206 base::Bind(&OnInnerMessageUnwrappedForResponderAuth, context)); | 206 base::Bind(&OnInnerMessageUnwrappedForResponderAuth, context)); |
| 207 } | 207 } |
| 208 | 208 |
| 209 // Called after the inner-most layer of [Responder Auth] is unwrapped. | 209 // Called after the inner-most layer of [Responder Auth] is unwrapped. |
| 210 void OnInnerMessageUnwrappedForResponderAuth( | 210 void OnInnerMessageUnwrappedForResponderAuth( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 228 | 228 |
| 229 context.callback.Run(verified, context.session_symmetric_key); | 229 context.callback.Run(verified, context.session_symmetric_key); |
| 230 } | 230 } |
| 231 | 231 |
| 232 } // namespace | 232 } // namespace |
| 233 | 233 |
| 234 // static | 234 // static |
| 235 void DeviceToDeviceInitiatorOperations::CreateHelloMessage( | 235 void DeviceToDeviceInitiatorOperations::CreateHelloMessage( |
| 236 const std::string& session_public_key, | 236 const std::string& session_public_key, |
| 237 const std::string& persistent_symmetric_key, | 237 const std::string& persistent_symmetric_key, |
| 238 SecureMessageDelegate* secure_message_delegate, | 238 cryptauth::SecureMessageDelegate* secure_message_delegate, |
| 239 const MessageCallback& callback) { | 239 const MessageCallback& callback) { |
| 240 // Decode public key into the |initator_hello| proto. | 240 // Decode public key into the |initator_hello| proto. |
| 241 securemessage::InitiatorHello initator_hello; | 241 securemessage::InitiatorHello initator_hello; |
| 242 if (!initator_hello.mutable_public_dh_key()->ParseFromString( | 242 if (!initator_hello.mutable_public_dh_key()->ParseFromString( |
| 243 session_public_key)) { | 243 session_public_key)) { |
| 244 PA_LOG(ERROR) << "Unable to parse user's public key"; | 244 PA_LOG(ERROR) << "Unable to parse user's public key"; |
| 245 callback.Run(std::string()); | 245 callback.Run(std::string()); |
| 246 return; | 246 return; |
| 247 } | 247 } |
| 248 | 248 |
| 249 // The [Hello] message has the structure: | 249 // The [Hello] message has the structure: |
| 250 // { | 250 // { |
| 251 // header: <session_public_key>, | 251 // header: <session_public_key>, |
| 252 // Sig(<session_public_key>, persistent_symmetric_key) | 252 // Sig(<session_public_key>, persistent_symmetric_key) |
| 253 // payload: "" | 253 // payload: "" |
| 254 // } | 254 // } |
| 255 SecureMessageDelegate::CreateOptions create_options; | 255 cryptauth::SecureMessageDelegate::CreateOptions create_options; |
| 256 create_options.encryption_scheme = securemessage::NONE; | 256 create_options.encryption_scheme = securemessage::NONE; |
| 257 create_options.signature_scheme = securemessage::HMAC_SHA256; | 257 create_options.signature_scheme = securemessage::HMAC_SHA256; |
| 258 initator_hello.SerializeToString(&create_options.public_metadata); | 258 initator_hello.SerializeToString(&create_options.public_metadata); |
| 259 secure_message_delegate->CreateSecureMessage( | 259 secure_message_delegate->CreateSecureMessage( |
| 260 kPayloadFiller, persistent_symmetric_key, create_options, callback); | 260 kPayloadFiller, persistent_symmetric_key, create_options, callback); |
| 261 } | 261 } |
| 262 | 262 |
| 263 // static | 263 // static |
| 264 void DeviceToDeviceInitiatorOperations::ValidateResponderAuthMessage( | 264 void DeviceToDeviceInitiatorOperations::ValidateResponderAuthMessage( |
| 265 const std::string& responder_auth_message, | 265 const std::string& responder_auth_message, |
| 266 const std::string& persistent_responder_public_key, | 266 const std::string& persistent_responder_public_key, |
| 267 const std::string& persistent_symmetric_key, | 267 const std::string& persistent_symmetric_key, |
| 268 const std::string& session_private_key, | 268 const std::string& session_private_key, |
| 269 const std::string& hello_message, | 269 const std::string& hello_message, |
| 270 SecureMessageDelegate* secure_message_delegate, | 270 cryptauth::SecureMessageDelegate* secure_message_delegate, |
| 271 const ValidateResponderAuthCallback& callback) { | 271 const ValidateResponderAuthCallback& callback) { |
| 272 // The [Responder Auth] message has the structure: | 272 // The [Responder Auth] message has the structure: |
| 273 // { | 273 // { |
| 274 // header: <responder_public_key>, | 274 // header: <responder_public_key>, |
| 275 // Sig(<responder_public_key> + payload1, | 275 // Sig(<responder_public_key> + payload1, |
| 276 // session_symmetric_key), | 276 // session_symmetric_key), |
| 277 // payload1: Enc({ | 277 // payload1: Enc({ |
| 278 // header: Sig(payload2 + <hello_message>, persistent_symmetric_key), | 278 // header: Sig(payload2 + <hello_message>, persistent_symmetric_key), |
| 279 // payload2: { | 279 // payload2: { |
| 280 // sequence_number: 1, | 280 // sequence_number: 1, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 295 secure_message_delegate, | 295 secure_message_delegate, |
| 296 callback}; | 296 callback}; |
| 297 BeginResponderAuthValidation(context); | 297 BeginResponderAuthValidation(context); |
| 298 } | 298 } |
| 299 | 299 |
| 300 // static | 300 // static |
| 301 void DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage( | 301 void DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage( |
| 302 const std::string& session_symmetric_key, | 302 const std::string& session_symmetric_key, |
| 303 const std::string& persistent_symmetric_key, | 303 const std::string& persistent_symmetric_key, |
| 304 const std::string& responder_auth_message, | 304 const std::string& responder_auth_message, |
| 305 SecureMessageDelegate* secure_message_delegate, | 305 cryptauth::SecureMessageDelegate* secure_message_delegate, |
| 306 const MessageCallback& callback) { | 306 const MessageCallback& callback) { |
| 307 // The [Initiator Auth] message has the structure: | 307 // The [Initiator Auth] message has the structure: |
| 308 // { | 308 // { |
| 309 // header: Sig(payload1, session_symmetric_key) | 309 // header: Sig(payload1, session_symmetric_key) |
| 310 // payload1: Enc({ | 310 // payload1: Enc({ |
| 311 // sequence_number: 2, | 311 // sequence_number: 2, |
| 312 // body: { | 312 // body: { |
| 313 // header: Sig(payload2 + responder_auth_message, | 313 // header: Sig(payload2 + responder_auth_message, |
| 314 // persistent_symmetric_key) | 314 // persistent_symmetric_key) |
| 315 // payload2: "" | 315 // payload2: "" |
| 316 // } | 316 // } |
| 317 // }, session_symmetric_key) | 317 // }, session_symmetric_key) |
| 318 // } | 318 // } |
| 319 SecureMessageDelegate::CreateOptions create_options; | 319 cryptauth::SecureMessageDelegate::CreateOptions create_options; |
| 320 create_options.encryption_scheme = securemessage::AES_256_CBC; | 320 create_options.encryption_scheme = securemessage::AES_256_CBC; |
| 321 create_options.signature_scheme = securemessage::HMAC_SHA256; | 321 create_options.signature_scheme = securemessage::HMAC_SHA256; |
| 322 create_options.associated_data = responder_auth_message; | 322 create_options.associated_data = responder_auth_message; |
| 323 secure_message_delegate->CreateSecureMessage( | 323 secure_message_delegate->CreateSecureMessage( |
| 324 kPayloadFiller, persistent_symmetric_key, create_options, | 324 kPayloadFiller, persistent_symmetric_key, create_options, |
| 325 base::Bind(&OnInnerMessageCreatedForInitiatorAuth, session_symmetric_key, | 325 base::Bind(&OnInnerMessageCreatedForInitiatorAuth, session_symmetric_key, |
| 326 secure_message_delegate, callback)); | 326 secure_message_delegate, callback)); |
| 327 } | 327 } |
| 328 | 328 |
| 329 } // proximity_auth | 329 } // proximity_auth |
| OLD | NEW |