| 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;
|
| }
|
|
|
|
|