Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 | |
| OLD | NEW |