/* Copyright (c) 2018, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <openssl/pem.h>

#include <functional>

#include <gtest/gtest.h>

#include <openssl/bio.h>
#include <openssl/cipher.h>
#include <openssl/err.h>
#include <openssl/rsa.h>

#include "../test/test_util.h"


// Test that implausible ciphers, notably an IV-less RC4, aren't allowed in PEM.
// This is a regression test for https://github.com/openssl/openssl/issues/6347,
// though our fix differs from upstream.
TEST(PEMTest, NoRC4) {
  static const char kPEM[] =
      "-----BEGIN RSA PUBLIC KEY-----\n"
      "Proc-Type: 4,ENCRYPTED\n"
      "DEK-Info: RC4 -\n"
      "extra-info\n"
      "router-signature\n"
      "\n"
      "Z1w=\n"
      "-----END RSA PUBLIC KEY-----\n";
  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kPEM, sizeof(kPEM) - 1));
  ASSERT_TRUE(bio);
  bssl::UniquePtr<RSA> rsa(PEM_read_bio_RSAPublicKey(
      bio.get(), nullptr, nullptr, const_cast<char *>("password")));
  EXPECT_FALSE(rsa);
  EXPECT_TRUE(
      ErrorEquals(ERR_get_error(), ERR_LIB_PEM, PEM_R_UNSUPPORTED_ENCRYPTION));
}

static std::vector<uint8_t> DecodePEMBytes(const char *pem) {
  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, -1));
  char *name, *header;
  uint8_t *data;
  long len;
  if (bio == nullptr ||
      !PEM_read_bio(bio.get(), &name, &header, &data, &len)) {
    return {};
  }
  bssl::UniquePtr<char> free_name(name), free_header(header);
  bssl::UniquePtr<uint8_t> free_data(data);
  return std::vector<uint8_t>(data, data + len);
}

TEST(PEMTest, DecryptPassword) {
  // A private key encrypted with the password "password", encrypted at the
  // PKCS#8 level.
  static const char kEncryptedPEM[] = R"(
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIHeMEkGCSqGSIb3DQEFDTA8MBsGCSqGSIb3DQEFDDAOBAjnhMUlb9deeQICCAAw
HQYJYIZIAWUDBAECBBAO8j5GA5VK8wjvNrzp/iVhBIGQyQKFfFKlFhxiDkFfyhUc
nPLr0eboQOz8eIaTW1Rblo/qDkQwNtONyfYn909SoIP7iU8UehcBG1UQe41WvQpu
yRKYQteoWSzFl+yzktL2Y/25K7Uc+f2NScjdonYMZ+9/m1HGmEzKO+Hz28cAsJL7
rH2gQ0lkxr1GtW77m2rfMKKuGYhpkgjWUbzJwP9v3iq+
-----END ENCRYPTED PRIVATE KEY-----
)";
  // The same key and password, but encrypted at the PEM level.
  static const char kEncryptedPEM2[] = R"(
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,B3B2988AECAE6EAB0D043105994C1123

RK7DUIGDHWTFh2rpTX+dR88hUyC1PyDlIULiNCkuWFwHrJbc1gM6hMVOKmU196XC
iITrIKmilFm9CPD6Tpfk/NhI/QPxyJlk1geIkxpvUZ2FCeMuYI1To14oYOUKv14q
wr6JtaX2G+pOmwcSPymZC4u2TncAP7KHgS8UGcMw8CE=
-----END EC PRIVATE KEY-----
)";

  for (const char *pem : {kEncryptedPEM, kEncryptedPEM2}) {
    SCOPED_TRACE(pem);
    // Decrypt with the correct password.
    {
      bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, -1));
      ASSERT_TRUE(bio);
      bssl::UniquePtr<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(
          bio.get(), nullptr, nullptr, const_cast<char *>("password")));
      EXPECT_TRUE(pkey);
    }

    // Decrypt with the wrong password.
    {
      bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, -1));
      ASSERT_TRUE(bio);
      bssl::UniquePtr<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(
          bio.get(), nullptr, nullptr, const_cast<char *>("wrong")));
      EXPECT_FALSE(pkey);
      EXPECT_TRUE(
          ErrorEquals(ERR_peek_error(), ERR_LIB_CIPHER, CIPHER_R_BAD_DECRYPT));
      ERR_clear_error();
    }

    // If the caller did not pass in a password, we should not proceed to try to
    // decrypt.
    {
      bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, -1));
      ASSERT_TRUE(bio);
      bssl::UniquePtr<EVP_PKEY> pkey(
          PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
      EXPECT_FALSE(pkey);
      EXPECT_TRUE(
          ErrorEquals(ERR_peek_error(), ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ));
      ERR_clear_error();
    }

    // If the password, with a NUL terminator, does not fit in the internal
    // buffer used by the PEM library, the PEM library should notice.
    {
      std::string too_long(PEM_BUFSIZE, 'a');
      bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, -1));
      ASSERT_TRUE(bio);
      bssl::UniquePtr<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(
          bio.get(), nullptr, nullptr, const_cast<char *>(too_long.c_str())));
      EXPECT_FALSE(pkey);
      EXPECT_TRUE(
          ErrorEquals(ERR_peek_error(), ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ));
      ERR_clear_error();
    }
  }

  // |d2i_PKCS8PrivateKey_bio| should also be able to manage the password
  // callback correctly.
  std::vector<uint8_t> bytes = DecodePEMBytes(kEncryptedPEM);
  ASSERT_FALSE(bytes.empty());
  {
    bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(bytes.data(), bytes.size()));
    ASSERT_TRUE(bio);
    bssl::UniquePtr<EVP_PKEY> pkey(d2i_PKCS8PrivateKey_bio(
        bio.get(), nullptr, nullptr, const_cast<char *>("password")));
    EXPECT_TRUE(pkey);
  }

  {
    bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(bytes.data(), bytes.size()));
    ASSERT_TRUE(bio);
    bssl::UniquePtr<EVP_PKEY> pkey(
        d2i_PKCS8PrivateKey_bio(bio.get(), nullptr, nullptr, nullptr));
    EXPECT_FALSE(pkey);
    EXPECT_TRUE(
        ErrorEquals(ERR_peek_error(), ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ));
    ERR_clear_error();
  }

  {
    std::string too_long(PEM_BUFSIZE, 'a');
    bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(bytes.data(), bytes.size()));
    ASSERT_TRUE(bio);
    bssl::UniquePtr<EVP_PKEY> pkey(d2i_PKCS8PrivateKey_bio(
        bio.get(), nullptr, nullptr, const_cast<char *>(too_long.c_str())));
    EXPECT_FALSE(pkey);
    EXPECT_TRUE(
        ErrorEquals(ERR_peek_error(), ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ));
    ERR_clear_error();
  }

  // A private key encrypted with the empty password, encrypted at the PKCS#8
  // level.
  static const char kEncryptedPEMEmpty[] = R"(
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIH0MF8GCSqGSIb3DQEFDTBSMDEGCSqGSIb3DQEFDDAkBBAXiHC8iDcjzF0I+D2g
zJOcAgIIADAMBggqhkiG9w0CCQUAMB0GCWCGSAFlAwQBAgQQwupOMi8DtEWiuXt5
Odla9QSBkC37uJuG7HSCOyTVCEW76Kmf7GoH+Ou17bDAp6NGwm3KLxRfFoExki9g
hyLzdarBnhRbPqwMixhaQ2AtkpoSmjristGzZ9U7Y+TM3NnCA4+bu1TckdBn0g+Q
fvZI9eydS9buA0deGxCUytrMWrR3PxS1yoXBywMDJTom8u5hvvvkJ9WcNzUVRf0D
6z5NHHiXsQ==
-----END ENCRYPTED PRIVATE KEY-----
)";
  // THe same key and password, but encrypted at the PEM level.
  static const char kEncryptedPEMEmpty2[] = R"(
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,A9505A7DD5C3B51D8AACED18F5758256

yfJKjep7Koj8hU/PtGC+NNXSNbItQ2zyeXDMVoazffraoDGMg6g1hFPPjg9reC+J
iQQIf9uACF27zi9fpWwbszszimrxl0u6n0ddBXizcK6xzkTvk3PZ67Vz1KYmotwC
XjgdgSEeixwKhDOuHKFdlFGP/7sw5GHlK3jPSpqi2gI=
-----END EC PRIVATE KEY-----
)";

  for (const char *pem : {kEncryptedPEMEmpty, kEncryptedPEMEmpty2}) {
    SCOPED_TRACE(pem);

    // The empty password should be correctly interpreted as a password.
    {
      bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, -1));
      ASSERT_TRUE(bio);
      bssl::UniquePtr<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(
          bio.get(), nullptr, nullptr, const_cast<char *>("")));
      EXPECT_TRUE(pkey);
    }
  }

  // |d2i_PKCS8PrivateKey_bio| should also be able to manage the password
  // callback correctly.
  bytes = DecodePEMBytes(kEncryptedPEMEmpty);
  {
    ASSERT_FALSE(bytes.empty());
    bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(bytes.data(), bytes.size()));
    ASSERT_TRUE(bio);
    bssl::UniquePtr<EVP_PKEY> pkey(d2i_PKCS8PrivateKey_bio(
        bio.get(), nullptr, nullptr, const_cast<char *>("")));
    EXPECT_TRUE(pkey);
  }
}

TEST(PEMTest, EncryptPassword) {
  static const char kKey[] = R"(
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ
TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N
Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB
-----END PRIVATE KEY-----
)";
  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKey, -1));
  ASSERT_TRUE(bio);
  bssl::UniquePtr<EVP_PKEY> pkey(
      PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
  EXPECT_TRUE(pkey);

  // There are many ways to encrypt a PEM blob with a password.
  struct PasswordMethod {
    const char *name;
    std::function<bool(BIO *, const char *)> func;
    bool is_callback;
  };
  const PasswordMethod kPasswordMethods[] = {
      {"PKCS#8 encryption, password from param",
       [&](BIO *out, const char *pass) -> bool {
         return PEM_write_bio_PrivateKey(
             out, pkey.get(), EVP_aes_128_cbc(),
             reinterpret_cast<const unsigned char *>(pass),
             pass == nullptr ? 0 : strlen(pass), nullptr, nullptr);
       },
       /*is_callback=*/false},
      {"PKCS#8 encryption, password from callback",
       [&](BIO *out, const char *pass) -> bool {
         return PEM_write_bio_PrivateKey(out, pkey.get(), EVP_aes_128_cbc(),
                                         nullptr, 0, nullptr,
                                         const_cast<char *>(pass));
       },
       /*is_callback=*/true},
      {"PEM-level encryption, password from param",
       [&](BIO *out, const char *pass) -> bool {
         return PEM_write_bio_ECPrivateKey(
             out, EVP_PKEY_get0_EC_KEY(pkey.get()), EVP_aes_128_cbc(), nullptr,
             0, nullptr, const_cast<char *>(pass));
       },
       /*is_callback=*/false},
      {"PKCS#8 encryption, password from callback",
       [&](BIO *out, const char *pass) -> bool {
         return PEM_write_bio_ECPrivateKey(
             out, EVP_PKEY_get0_EC_KEY(pkey.get()), EVP_aes_128_cbc(), nullptr,
             0, nullptr, const_cast<char *>(pass));
       },
       /*is_callback=*/true},
  };
  for (const auto &p : kPasswordMethods) {
    SCOPED_TRACE(p.name);

    // Encrypting the private key with a password should work.
    bio.reset(BIO_new(BIO_s_mem()));
    ASSERT_TRUE(bio);
    ASSERT_TRUE(p.func(bio.get(), "password"));

    // Check we can decrypt it.
    bssl::UniquePtr<EVP_PKEY> pkey2(PEM_read_bio_PrivateKey(
        bio.get(), nullptr, nullptr, const_cast<char *>("password")));
    ASSERT_TRUE(pkey2);

    // The empty string is a valid password.
    bio.reset(BIO_new(BIO_s_mem()));
    ASSERT_TRUE(bio);
    ASSERT_TRUE(p.func(bio.get(), ""));

    // Check we can decrypt it.
    pkey2.reset(PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr,
                                        const_cast<char *>("")));
    ASSERT_TRUE(pkey2);

    // Check error-handling when the password is specified via the callback.
    if (p.is_callback) {
      bio.reset(BIO_new(BIO_s_mem()));
      ASSERT_TRUE(bio);
      EXPECT_FALSE(p.func(bio.get(), nullptr));
      EXPECT_TRUE(ErrorEquals(ERR_peek_error(), ERR_LIB_PEM, PEM_R_READ_KEY));
      ERR_clear_error();

      std::string too_long(PEM_BUFSIZE, 'a');
      bio.reset(BIO_new(BIO_s_mem()));
      ASSERT_TRUE(bio);
      EXPECT_FALSE(p.func(bio.get(), too_long.c_str()));
      EXPECT_TRUE(ErrorEquals(ERR_peek_error(), ERR_LIB_PEM, PEM_R_READ_KEY));
      ERR_clear_error();
    }
  }
}
