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

Side by Side 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: add unit test Created 5 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 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/fake_secure_message_delegate.h"
6
7 #include <algorithm>
8
9 #include "base/callback.h"
10 #include "base/md5.h"
11
12 namespace proximity_auth {
13
14 namespace {
15
16 const char kKeyPrefix[] = "fake_key_";
17 const char kPrivateKeyPrefix[] = "private_";
18
19 // Encrypts the |plaintext| with the |key| using the |encryption_scheme| and
20 // returns the ciphertext.
21 std::string Encrypt(const std::string& plaintext,
22 const std::string& key,
23 const securemessage::EncScheme& encryption_scheme) {
24 if (encryption_scheme == securemessage::NONE)
25 return plaintext;
26
27 // Encrypt with a Vigenere cipher.
28 std::string ciphertext;
29 ciphertext.resize(plaintext.size());
30 for (size_t i = 0; i < plaintext.size(); ++i) {
31 unsigned char plaintext_char = plaintext[i];
32 unsigned char key_char = key[i % key.size()];
33 ciphertext[i] = plaintext_char + key_char;
34 }
35 return ciphertext;
36 }
37
38 // Decrypts the |ciphertext| with the |key| using the |encryption_scheme| and
39 // returns the plaintext.
40 std::string Decrypt(const std::string& ciphertext,
41 const std::string& key,
42 const securemessage::EncScheme& encryption_scheme) {
43 if (encryption_scheme == securemessage::NONE)
44 return ciphertext;
45
46 // Decrypt with a Vigenere cipher.
47 std::string plaintext;
48 plaintext.resize(ciphertext.size());
49 for (size_t i = 0; i < ciphertext.size(); ++i) {
50 unsigned char ciphertext_char = ciphertext[i];
51 unsigned char key_char = key[i % key.size()];
52 plaintext[i] = ciphertext_char - key_char;
53 }
54 return plaintext;
55 }
56
57 // Signs the |payload| and |associated_data| with the |key| using the
58 // |signature_scheme| and returns the signature.
59 std::string Sign(const std::string& payload,
60 const std::string& associated_data,
61 const std::string& key,
62 const securemessage::SigScheme& signature_scheme) {
Ilya Sherman 2015/04/03 22:43:41 nit: The |signature_scheme| is not used, so let's
Tim Song 2015/04/04 05:06:14 Done.
63 return base::MD5String(payload + "|" + associated_data + "|" + key);
64 }
65
66 // Verifies that the |signature| for the the |payload| and |associated_data| is
67 // valid for the given the |key| and |signature_scheme|.
68 bool Verify(const std::string& signature,
69 const std::string& payload,
70 const std::string& associated_data,
71 const std::string& key,
72 const securemessage::SigScheme& signature_scheme) {
73 // Verify signatures created using symmetric keys.
74 if (signature_scheme == securemessage::HMAC_SHA256) {
75 std::string expected_signature =
76 Sign(payload, associated_data, key, signature_scheme);
77 return signature == expected_signature;
78 }
Ilya Sherman 2015/04/03 22:43:41 I think this method would be clearer if it were st
Tim Song 2015/04/04 05:06:14 Done.
79
80 // Verify signatures created using asymmetric keys.
81 std::string prefix = kPrivateKeyPrefix;
82 bool is_private_key = key.substr(0, prefix.size()) == prefix;
83 std::string signing_key =
84 is_private_key ? key.substr(prefix.size()) : prefix + key;
85
86 std::string expected_signature =
87 Sign(payload, associated_data, signing_key, signature_scheme);
88 << signature_scheme;
Ilya Sherman 2015/04/03 22:43:41 Hmm?
Tim Song 2015/04/04 05:06:14 Sorry, forgot to delete this.
89 return signature == expected_signature;
90 }
91 }
92
93 FakeSecureMessageDelegate::FakeSecureMessageDelegate()
94 : next_public_key_(std::string(kKeyPrefix) + "0") {
95 }
96
97 FakeSecureMessageDelegate::~FakeSecureMessageDelegate() {
98 }
99
100 void FakeSecureMessageDelegate::GenerateKeyPair(
101 const GenerateKeyPairCallback& callback) {
102 std::string public_key = next_public_key_;
103
104 // The private key is simply the public key prepended with "private_".
105 std::string private_key(std::string(kPrivateKeyPrefix + public_key));
Ilya Sherman 2015/04/03 22:43:41 nit: No need for the inner "std::string"
Tim Song 2015/04/04 05:06:14 Done.
106
107 next_public_key_ = std::string(kKeyPrefix) + base::MD5String(public_key);
108
109 callback.Run(public_key, private_key);
110 }
111
112 void FakeSecureMessageDelegate::DeriveKey(const std::string& private_key,
113 const std::string& public_key,
114 const DeriveKeyCallback& callback) {
115 // Ensure that the same symmetric is derived for DeriveKey(private1, public2)
Ilya Sherman 2015/04/03 22:43:41 nit: "same symmetric" -> "same symmetric key"
Tim Song 2015/04/04 05:06:14 Done.
116 // and DeriveKey(private2, public1).
Ilya Sherman 2015/04/03 22:43:41 I think it would help to explain, in the comment,
Tim Song 2015/04/04 05:06:14 Done.
117 std::string prefix(kPrivateKeyPrefix);
118 std::string normalized_private_key =
119 private_key.size() > prefix.size()
Ilya Sherman 2015/04/03 22:43:41 I'm not really following why you're just comparing
Tim Song 2015/04/04 05:06:14 I don't want to call substr with an out of bounds
Ilya Sherman 2015/04/06 18:33:51 I mean, sure, but trimming off the prefix only mak
Tim Song 2015/04/06 19:37:23 All private keys are expected to start with "priva
120 ? private_key.substr(std::string(kPrivateKeyPrefix).size())
Ilya Sherman 2015/04/03 22:43:41 nit: s/std::string(kPrivateKeyPrefix)/prefix
Tim Song 2015/04/04 05:06:14 Done.
121 : private_key;
122
123 std::vector<std::string> keys;
124 keys.push_back(normalized_private_key);
125 keys.push_back(public_key);
126 std::sort(keys.begin(), keys.end());
127 callback.Run(base::MD5String(keys[0] + "|" + keys[1]));
128 }
129
130 void FakeSecureMessageDelegate::CreateSecureMessage(
131 const std::string& payload,
132 const std::string& key,
133 const CreateOptions& create_options,
134 const CreateSecureMessageCallback& callback) {
135 securemessage::Header header;
136 header.set_signature_scheme(create_options.signature_scheme);
137 header.set_encryption_scheme(create_options.encryption_scheme);
138 if (!create_options.public_metadata.empty())
139 header.set_public_metadata(create_options.public_metadata);
140 if (!create_options.verification_key_id.empty())
141 header.set_verification_key_id(create_options.verification_key_id);
142 if (!create_options.decryption_key_id.empty())
143 header.set_decryption_key_id(create_options.decryption_key_id);
144
145 securemessage::HeaderAndBody header_and_body;
146 header_and_body.mutable_header()->CopyFrom(header);
147 header_and_body.set_body(
148 Encrypt(payload, key, create_options.encryption_scheme));
149 std::string serialized_header_and_body;
150 header_and_body.SerializeToString(&serialized_header_and_body);
151
152 securemessage::SecureMessage secure_message;
153 secure_message.set_header_and_body(serialized_header_and_body);
154 secure_message.set_signature(Sign(payload, create_options.associated_data,
155 key, create_options.signature_scheme));
156
157 std::string serialized_secure_message;
158 secure_message.SerializeToString(&serialized_secure_message);
159 callback.Run(serialized_secure_message);
160 }
Ilya Sherman 2015/04/03 22:43:41 Most of this seems appropriate to do in the base c
Tim Song 2015/04/04 05:06:14 We need to keep SecureMessageDelegate as an interf
161
162 void FakeSecureMessageDelegate::UnwrapSecureMessage(
163 const std::string& serialized_message,
164 const std::string& key,
165 const UnwrapOptions& unwrap_options,
166 const UnwrapSecureMessageCallback& callback) {
167 securemessage::SecureMessage secure_message;
168 if (!secure_message.ParseFromString(serialized_message)) {
169 LOG(ERROR) << "Failed to parse SecureMessage.";
170 callback.Run(false, std::string(), securemessage::Header());
171 return;
172 }
173
174 securemessage::HeaderAndBody header_and_body;
175 if (!header_and_body.ParseFromString(secure_message.header_and_body())) {
176 LOG(ERROR) << "Failed to parse secure message HeaderAndBody.";
177 callback.Run(false, std::string(), securemessage::Header());
178 return;
179 }
180
181 const securemessage::Header& header = header_and_body.header();
182 std::string payload =
183 Decrypt(header_and_body.body(), key, unwrap_options.encryption_scheme);
184
185 bool verified = Verify(secure_message.signature(), payload,
186 unwrap_options.associated_data, key,
187 unwrap_options.signature_scheme);
188 if (verified) {
189 callback.Run(true, payload, header);
190 } else {
191 callback.Run(false, std::string(), securemessage::Header());
192 }
193 }
Ilya Sherman 2015/04/03 22:43:41 Same applies here.
Tim Song 2015/04/04 05:06:14 Same reasoning.
194
195 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698