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

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: 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 |payload| with the |key| using the |encryption_scheme| and
20 // returns the ciphertext.
21 std::string Encrypt(const std::string& payload,
22 const std::string& key,
23 const securemessage::EncScheme& encryption_scheme) {
24 if (encryption_scheme == securemessage::NONE)
25 return payload;
26
27 // Encrypt with a Vigenere cipher.
28 std::string ciphertext;
29 ciphertext.resize(payload.size());
30 for (size_t i = 0; i < payload.size(); ++i) {
31 char c = key[i % key.size()];
32 ciphertext[i] = (payload[i] + c) % sizeof(char);
33 }
34 return payload;
35 }
36
37 // Decrypts the |payload| with the |key| using the |encryption_scheme| and
38 // returns the plaintext.
39 std::string Decrypt(const std::string& ciphertext,
40 const std::string& key,
41 const securemessage::EncScheme& encryption_scheme) {
42 if (encryption_scheme == securemessage::NONE)
43 return ciphertext;
44
45 // Decrypt with a Vigenere cipher.
46 std::string plaintext;
47 plaintext.resize(ciphertext.size());
48 for (size_t i = 0; i < ciphertext.size(); ++i) {
49 unsigned char ciphertext_char = ciphertext[i];
50 unsigned char key_char = key[i % key.size()];
51 plaintext[i] = ciphertext_char - key_char;
52 }
53 return plaintext;
54 }
55
56 // Signs the |payload| and |associated_data| with the |key| using the
57 // |signature_scheme| and returns the signature.
58 std::string Sign(const std::string& payload,
59 const std::string& associated_data,
60 const std::string& key,
61 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
62 return base::MD5String(payload + "|" + associated_data + "|" + key);
63 }
64
65 // Verifies that the |signature| for the the |payload| and |associated_data| is
66 // valid for the given the |key| and |signature_scheme|.
67 bool Verify(const std::string& signature,
68 const std::string& payload,
69 const std::string& associated_data,
70 const std::string& key,
71 const securemessage::SigScheme& signature_scheme) {
72 // Verify signatures created using symmetric keys.
73 if (signature_scheme == securemessage::HMAC_SHA256) {
74 std::string expected_signature =
75 Sign(payload, associated_data, key, signature_scheme);
76 return signature == expected_signature;
77 }
78
79 // Verify signatures created using asymmetric keys.
80 std::string prefix = kPrivateKeyPrefix;
81 bool is_private_key = key.substr(0, prefix.size()) == prefix;
82 std::string signing_key =
83 is_private_key ? key.substr(prefix.size()) : prefix + key;
84
85 std::string expected_signature =
86 Sign(payload, associated_data, signing_key, signature_scheme);
87 return signature == expected_signature;
88 }
89 }
90
91 FakeSecureMessageDelegate::FakeSecureMessageDelegate()
92 : next_public_key_(std::string(kKeyPrefix) + "0") {
93 }
94
95 FakeSecureMessageDelegate::~FakeSecureMessageDelegate() {
96 }
97
98 void FakeSecureMessageDelegate::GenerateKeyPair(
99 const GenerateKeyPairCallback& callback) {
100 std::string public_key = next_public_key_;
101
102 // The private key is simply the public key prepended with "private_".
103 std::string private_key(std::string(kPrivateKeyPrefix + public_key));
104
105 next_public_key_ = std::string(kKeyPrefix) + base::MD5String(public_key);
106
107 callback.Run(public_key, private_key);
108 }
109
110 void FakeSecureMessageDelegate::DeriveKey(const std::string& private_key,
111 const std::string& public_key,
112 const DeriveKeyCallback& callback) {
113 callback.Run(base::MD5String(private_key + "|" + public_key));
114 }
115
116 void FakeSecureMessageDelegate::CreateSecureMessage(
117 const std::string& payload,
118 const std::string& key,
119 const CreateOptions& create_options,
120 const CreateSecureMessageCallback& callback) {
121 securemessage::Header header;
122 header.set_signature_scheme(create_options.signature_scheme);
123 header.set_encryption_scheme(create_options.encryption_scheme);
124 if (!create_options.public_metadata.empty())
125 header.set_public_metadata(create_options.public_metadata);
126 if (!create_options.verification_key_id.empty())
127 header.set_verification_key_id(create_options.verification_key_id);
128 if (!create_options.decryption_key_id.empty())
129 header.set_decryption_key_id(create_options.decryption_key_id);
130
131 securemessage::HeaderAndBody header_and_body;
132 header_and_body.mutable_header()->CopyFrom(header);
133 header_and_body.set_body(
134 Encrypt(payload, key, create_options.encryption_scheme));
135 std::string serialized_header_and_body;
136 header_and_body.SerializeToString(&serialized_header_and_body);
137
138 securemessage::SecureMessage secure_message;
139 secure_message.set_header_and_body(serialized_header_and_body);
140 secure_message.set_signature(Sign(payload, create_options.associated_data,
141 key, create_options.signature_scheme));
142
143 std::string serialized_secure_message;
144 secure_message.SerializeToString(&serialized_secure_message);
145 callback.Run(serialized_secure_message);
146 }
147
148 void FakeSecureMessageDelegate::UnwrapSecureMessage(
149 const std::string& serialized_message,
150 const std::string& key,
151 const UnwrapOptions& unwrap_options,
152 const UnwrapSecureMessageCallback& callback) {
153 securemessage::SecureMessage secure_message;
154 if (!secure_message.ParseFromString(serialized_message)) {
155 LOG(ERROR) << "Failed to parse SecureMessage.";
156 callback.Run(false, std::string(), securemessage::Header());
157 return;
158 }
159
160 securemessage::HeaderAndBody header_and_body;
161 if (!header_and_body.ParseFromString(secure_message.header_and_body())) {
162 LOG(ERROR) << "Failed to parse secure message HeaderAndBody.";
163 callback.Run(false, std::string(), securemessage::Header());
164 return;
165 }
166
167 const securemessage::Header& header = header_and_body.header();
168 std::string payload =
169 Decrypt(header_and_body.body(), key, unwrap_options.encryption_scheme);
170
171 bool verified = Verify(secure_message.signature(), payload,
172 unwrap_options.associated_data, key,
173 unwrap_options.signature_scheme);
174 if (verified) {
175 callback.Run(true, payload, header);
176 } else {
177 callback.Run(false, std::string(), securemessage::Header());
178 }
179 }
180
181 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698