Index: net/quic/crypto/crypto_secret_boxer.cc |
diff --git a/net/quic/crypto/crypto_secret_boxer.cc b/net/quic/crypto/crypto_secret_boxer.cc |
index 1fbf0709715c93521bc4f4349a5cc705fc7dad9a..08a431745fd5512d94ef312406a28db9eb8c3659 100644 |
--- a/net/quic/crypto/crypto_secret_boxer.cc |
+++ b/net/quic/crypto/crypto_secret_boxer.cc |
@@ -15,6 +15,7 @@ |
using base::StringPiece; |
using std::string; |
+using std::vector; |
namespace net { |
@@ -34,21 +35,34 @@ static const size_t kKeySize = 16; |
// It's not terrible, but it's not a "forget about it" margin. |
static const size_t kBoxNonceSize = 12; |
+CryptoSecretBoxer::CryptoSecretBoxer() {} |
+ |
+CryptoSecretBoxer::~CryptoSecretBoxer() {} |
+ |
// static |
size_t CryptoSecretBoxer::GetKeySize() { |
return kKeySize; |
} |
-void CryptoSecretBoxer::SetKey(StringPiece key) { |
- DCHECK_EQ(kKeySize, key.size()); |
- key_ = key.as_string(); |
+void CryptoSecretBoxer::SetKeys(const vector<string>& keys) { |
+ DCHECK(!keys.empty()); |
+ vector<string> copy = keys; |
+ for (const string& key : keys) { |
+ DCHECK_EQ(kKeySize, key.size()); |
+ } |
+ base::AutoLock l(lock_); |
+ keys_.swap(copy); |
} |
string CryptoSecretBoxer::Box(QuicRandom* rand, StringPiece plaintext) const { |
scoped_ptr<Aes128Gcm12Encrypter> encrypter(new Aes128Gcm12Encrypter()); |
- if (!encrypter->SetKey(key_)) { |
- DLOG(DFATAL) << "CryptoSecretBoxer's encrypter->SetKey failed."; |
- return string(); |
+ { |
+ base::AutoLock l(lock_); |
+ DCHECK_EQ(kKeySize, keys_[0].size()); |
+ if (!encrypter->SetKey(keys_[0])) { |
+ DLOG(DFATAL) << "CryptoSecretBoxer's encrypter->SetKey failed."; |
+ return string(); |
+ } |
} |
size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length()); |
@@ -86,17 +100,25 @@ bool CryptoSecretBoxer::Unbox(StringPiece ciphertext, |
sizeof(packet_number)); |
scoped_ptr<Aes128Gcm12Decrypter> decrypter(new Aes128Gcm12Decrypter()); |
- if (!decrypter->SetKey(key_)) { |
- DLOG(DFATAL) << "CryptoSecretBoxer's decrypter->SetKey failed."; |
- return false; |
- } |
- decrypter->SetNoncePrefix(nonce_prefix); |
char plaintext[kMaxPacketSize]; |
size_t plaintext_length = 0; |
- const bool success = decrypter->DecryptPacket( |
- /*path_id=*/0u, packet_number, /*associated data=*/StringPiece(), |
- ciphertext, plaintext, &plaintext_length, kMaxPacketSize); |
- if (!success) { |
+ bool ok = false; |
+ { |
+ base::AutoLock l(lock_); |
+ for (const string& key : keys_) { |
+ if (decrypter->SetKey(key)) { |
+ decrypter->SetNoncePrefix(nonce_prefix); |
+ if (decrypter->DecryptPacket( |
+ /*path_id=*/0u, packet_number, |
+ /*associated data=*/StringPiece(), ciphertext, plaintext, |
+ &plaintext_length, kMaxPacketSize)) { |
+ ok = true; |
+ break; |
+ } |
+ } |
+ } |
+ } |
+ if (!ok) { |
return false; |
} |