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

Unified Diff: components/proximity_auth/cryptauth/fake_secure_message_delegate.cc

Issue 1060483002: Add SecureMessage definitions to CryptAuth. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: components/proximity_auth/cryptauth/fake_secure_message_delegate.cc
diff --git a/components/proximity_auth/cryptauth/fake_secure_message_delegate.cc b/components/proximity_auth/cryptauth/fake_secure_message_delegate.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f497a58ebd359a368970b8441bec87a1401f65f3
--- /dev/null
+++ b/components/proximity_auth/cryptauth/fake_secure_message_delegate.cc
@@ -0,0 +1,181 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/proximity_auth/cryptauth/fake_secure_message_delegate.h"
+
+#include <algorithm>
+
+#include "base/callback.h"
+#include "base/md5.h"
+
+namespace proximity_auth {
+
+namespace {
+
+const char kKeyPrefix[] = "fake_key_";
+const char kPrivateKeyPrefix[] = "private_";
+
+// Encrypts the |payload| with the |key| using the |encryption_scheme| and
+// returns the ciphertext.
+std::string Encrypt(const std::string& payload,
+ const std::string& key,
+ const securemessage::EncScheme& encryption_scheme) {
+ if (encryption_scheme == securemessage::NONE)
+ return payload;
+
+ // Encrypt with a Vigenere cipher.
+ std::string ciphertext;
+ ciphertext.resize(payload.size());
+ for (size_t i = 0; i < payload.size(); ++i) {
+ char c = key[i % key.size()];
+ ciphertext[i] = (payload[i] + c) % sizeof(char);
+ }
+ return payload;
+}
+
+// Decrypts the |payload| with the |key| using the |encryption_scheme| and
+// returns the plaintext.
+std::string Decrypt(const std::string& ciphertext,
+ const std::string& key,
+ const securemessage::EncScheme& encryption_scheme) {
+ if (encryption_scheme == securemessage::NONE)
+ return ciphertext;
+
+ // Decrypt with a Vigenere cipher.
+ std::string plaintext;
+ plaintext.resize(ciphertext.size());
+ for (size_t i = 0; i < ciphertext.size(); ++i) {
+ unsigned char ciphertext_char = ciphertext[i];
+ unsigned char key_char = key[i % key.size()];
+ plaintext[i] = ciphertext_char - key_char;
+ }
+ return plaintext;
+}
+
+// Signs the |payload| and |associated_data| with the |key| using the
+// |signature_scheme| and returns the signature.
+std::string Sign(const std::string& payload,
+ const std::string& associated_data,
+ const std::string& key,
+ const securemessage::SigScheme& signature_scheme) {
Ilya Sherman 2015/04/03 02:13:05 The signature_scheme is ignored here, but used in
Tim Song 2015/04/03 02:46:34 Anything signed by the private key can be verified
+ return base::MD5String(payload + "|" + associated_data + "|" + key);
+}
+
+// Verifies that the |signature| for the the |payload| and |associated_data| is
+// valid for the given the |key| and |signature_scheme|.
+bool Verify(const std::string& signature,
+ const std::string& payload,
+ const std::string& associated_data,
+ const std::string& key,
+ const securemessage::SigScheme& signature_scheme) {
+ // Verify signatures created using symmetric keys.
+ if (signature_scheme == securemessage::HMAC_SHA256) {
+ std::string expected_signature =
+ Sign(payload, associated_data, key, signature_scheme);
+ return signature == expected_signature;
+ }
+
+ // Verify signatures created using asymmetric keys.
+ std::string prefix = kPrivateKeyPrefix;
+ bool is_private_key = key.substr(0, prefix.size()) == prefix;
+ std::string signing_key =
+ is_private_key ? key.substr(prefix.size()) : prefix + key;
+
+ std::string expected_signature =
+ Sign(payload, associated_data, signing_key, signature_scheme);
+ return signature == expected_signature;
+}
+}
+
+FakeSecureMessageDelegate::FakeSecureMessageDelegate()
+ : next_public_key_(std::string(kKeyPrefix) + "0") {
+}
+
+FakeSecureMessageDelegate::~FakeSecureMessageDelegate() {
+}
+
+void FakeSecureMessageDelegate::GenerateKeyPair(
+ const GenerateKeyPairCallback& callback) {
+ std::string public_key = next_public_key_;
+
+ // The private key is simply the public key prepended with "private_".
+ std::string private_key(std::string(kPrivateKeyPrefix + public_key));
+
+ next_public_key_ = std::string(kKeyPrefix) + base::MD5String(public_key);
+
+ callback.Run(public_key, private_key);
+}
+
+void FakeSecureMessageDelegate::DeriveKey(const std::string& private_key,
+ const std::string& public_key,
+ const DeriveKeyCallback& callback) {
+ callback.Run(base::MD5String(private_key + "|" + public_key));
+}
+
+void FakeSecureMessageDelegate::CreateSecureMessage(
+ const std::string& payload,
+ const std::string& key,
+ const CreateOptions& create_options,
+ const CreateSecureMessageCallback& callback) {
+ securemessage::Header header;
+ header.set_signature_scheme(create_options.signature_scheme);
+ header.set_encryption_scheme(create_options.encryption_scheme);
+ if (!create_options.public_metadata.empty())
+ header.set_public_metadata(create_options.public_metadata);
+ if (!create_options.verification_key_id.empty())
+ header.set_verification_key_id(create_options.verification_key_id);
+ if (!create_options.decryption_key_id.empty())
+ header.set_decryption_key_id(create_options.decryption_key_id);
+
+ securemessage::HeaderAndBody header_and_body;
+ header_and_body.mutable_header()->CopyFrom(header);
+ header_and_body.set_body(
+ Encrypt(payload, key, create_options.encryption_scheme));
+ std::string serialized_header_and_body;
+ header_and_body.SerializeToString(&serialized_header_and_body);
+
+ securemessage::SecureMessage secure_message;
+ secure_message.set_header_and_body(serialized_header_and_body);
+ secure_message.set_signature(Sign(payload, create_options.associated_data,
+ key, create_options.signature_scheme));
+
+ std::string serialized_secure_message;
+ secure_message.SerializeToString(&serialized_secure_message);
+ callback.Run(serialized_secure_message);
+}
+
+void FakeSecureMessageDelegate::UnwrapSecureMessage(
+ const std::string& serialized_message,
+ const std::string& key,
+ const UnwrapOptions& unwrap_options,
+ const UnwrapSecureMessageCallback& callback) {
+ securemessage::SecureMessage secure_message;
+ if (!secure_message.ParseFromString(serialized_message)) {
+ LOG(ERROR) << "Failed to parse SecureMessage.";
+ callback.Run(false, std::string(), securemessage::Header());
+ return;
+ }
+
+ securemessage::HeaderAndBody header_and_body;
+ if (!header_and_body.ParseFromString(secure_message.header_and_body())) {
+ LOG(ERROR) << "Failed to parse secure message HeaderAndBody.";
+ callback.Run(false, std::string(), securemessage::Header());
+ return;
+ }
+
+ const securemessage::Header& header = header_and_body.header();
+ std::string payload =
+ Decrypt(header_and_body.body(), key, unwrap_options.encryption_scheme);
+
+ bool verified = Verify(secure_message.signature(), payload,
+ unwrap_options.associated_data, key,
+ unwrap_options.signature_scheme);
+ if (verified) {
+ callback.Run(true, payload, header);
+ } else {
+ callback.Run(false, std::string(), securemessage::Header());
+ }
+}
+
+} // namespace proximity_auth

Powered by Google App Engine
This is Rietveld 408576698