| Index: crypto/encryptor_openssl.cc
|
| diff --git a/crypto/encryptor_openssl.cc b/crypto/encryptor_openssl.cc
|
| index cb26e221a029cd11b98c6b3bf70cc1ab42734648..08c67c9c01489907e0e70e4d86094d83599101a0 100644
|
| --- a/crypto/encryptor_openssl.cc
|
| +++ b/crypto/encryptor_openssl.cc
|
| @@ -55,8 +55,9 @@ Encryptor::~Encryptor() {
|
| bool Encryptor::Init(SymmetricKey* key,
|
| Mode mode,
|
| const base::StringPiece& iv) {
|
| - DCHECK(key);
|
| DCHECK_EQ(CBC, mode);
|
| + if (!key)
|
| + return false;
|
|
|
| EnsureOpenSSLInit();
|
| if (iv.size() != AES_BLOCK_SIZE)
|
| @@ -73,50 +74,54 @@ bool Encryptor::Init(SymmetricKey* key,
|
|
|
| bool Encryptor::Encrypt(const base::StringPiece& plaintext,
|
| std::string* ciphertext) {
|
| - CHECK(!plaintext.empty() || (mode_ == CBC));
|
| + if (plaintext.empty() && mode_ != CBC)
|
| + return false;
|
| return Crypt(true, plaintext, ciphertext);
|
| }
|
|
|
| bool Encryptor::Decrypt(const base::StringPiece& ciphertext,
|
| std::string* plaintext) {
|
| - CHECK(!ciphertext.empty());
|
| + if (ciphertext.empty())
|
| + return false;
|
| return Crypt(false, ciphertext, plaintext);
|
| }
|
|
|
| bool Encryptor::Crypt(bool do_encrypt,
|
| const base::StringPiece& input,
|
| std::string* output) {
|
| - DCHECK(key_); // Must call Init() before En/De-crypt.
|
| - // Work on the result in a local variable, and then only transfer it to
|
| - // |output| on success to ensure no partial data is returned.
|
| - std::string result;
|
| - output->clear();
|
| + if (!key_)
|
| + return false; // Must call Init() first.
|
|
|
| const EVP_CIPHER* cipher = GetCipherForKey(key_);
|
| DCHECK(cipher); // Already handled in Init();
|
|
|
| const std::string& key = key_->key();
|
| - DCHECK_EQ(EVP_CIPHER_iv_length(cipher), static_cast<int>(iv_.length()));
|
| - DCHECK_EQ(EVP_CIPHER_key_length(cipher), static_cast<int>(key.length()));
|
| + if (EVP_CIPHER_iv_length(cipher) != static_cast<int>(iv_.length()) ||
|
| + EVP_CIPHER_key_length(cipher) != static_cast<int>(key.length())) {
|
| + return false;
|
| + }
|
|
|
| ScopedCipherCTX ctx;
|
| if (!EVP_CipherInit_ex(ctx.get(), cipher, NULL,
|
| reinterpret_cast<const uint8*>(key.data()),
|
| reinterpret_cast<const uint8*>(iv_.data()),
|
| - do_encrypt))
|
| + do_encrypt)) {
|
| return false;
|
| + }
|
|
|
| // When encrypting, add another block size of space to allow for any padding.
|
| const size_t output_size = input.size() + (do_encrypt ? iv_.size() : 0);
|
| - CHECK_GT(output_size, 0u);
|
| - CHECK_GT(output_size + 1, input.size());
|
| - uint8* out_ptr = reinterpret_cast<uint8*>(WriteInto(&result,
|
| + if (output_size == 0)
|
| + return false;
|
| +
|
| + uint8* out_ptr = reinterpret_cast<uint8*>(WriteInto(output,
|
| output_size + 1));
|
| int out_len;
|
| if (!EVP_CipherUpdate(ctx.get(), out_ptr, &out_len,
|
| reinterpret_cast<const uint8*>(input.data()),
|
| - input.length()))
|
| + input.length())) {
|
| return false;
|
| + }
|
|
|
| // Write out the final block plus padding (if any) to the end of the data
|
| // just written.
|
| @@ -125,10 +130,9 @@ bool Encryptor::Crypt(bool do_encrypt,
|
| return false;
|
|
|
| out_len += tail_len;
|
| - DCHECK_LE(out_len, static_cast<int>(output_size));
|
| - result.resize(out_len);
|
| + CHECK_LE(out_len, static_cast<int>(output_size));
|
|
|
| - output->swap(result);
|
| + output->resize(out_len);
|
| return true;
|
| }
|
|
|
|
|