/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SECUREMESSAGE_CRYPTO_OPS_H_
#define SECUREMESSAGE_CRYPTO_OPS_H_

#include <cstdint>
#include <memory>
#include <string>

#include "securemessage/byte_buffer.h"
#include "securemessage/common.h"

namespace securemessage {

//
// Encapsulates the cryptographic operations used by the {@code SecureMessage*}
// classes.
//
class CryptoOps {
 public:
  //
  // Enum of supported signature schemes.
  //
  enum SigType {
    HMAC_SHA256,
    ECDSA_P256_SHA256,
    RSA2048_SHA256,
    SIG_TYPE_END  // used for testing
  };

  //
  // Enum of supported encryption types
  //
  enum EncType {
    NONE,
    AES_256_CBC,
    ENC_TYPE_END  // used for testing
  };

  //
  // Key Algorithms we support
  //
  enum KeyAlgorithm {
    AES_256_KEY,
    ECDSA_KEY,
    RSA_KEY
  };

  //
  // Key Types we believe to exist
  //
  enum KeyType {
    PUBLIC,
    PRIVATE,
    SECRET
  };

  //
  // Represents a base key class, SecretKey and PublicKey are derived from this
  // class
  //
  class Key {
   public:
    //
    // The default constructor is deleted so that class consumers cannot create
    // a generic key class.  They must use a particular key type class.
    //
    Key() = delete;

    ByteBuffer data() { return data_; }
    const ByteBuffer& data() const { return data_; }
    KeyAlgorithm algorithm() const { return algorithm_; }
    KeyType type() const { return type_; }

   protected:
    //
    // Constructor cannot be called so that consumers can't simply create a
    // generic key.  Instead, they must use a particular key type class.
    //
    Key(const ByteBuffer& data, KeyAlgorithm algorithm, KeyType type) {
      data_ = data;
      algorithm_ = algorithm;
      type_ = type;
    }

    ByteBuffer data_;
    KeyAlgorithm algorithm_;
    KeyType type_;
  };

  //
  // We have three key types: Public, Private, and Secret (symmetric)
  //
  class PublicKey : public Key {
   public:
    PublicKey(const string& data, KeyAlgorithm algorithm)
        : Key(ByteBuffer(data), algorithm, PUBLIC) {}
    PublicKey(const ByteBuffer& data, KeyAlgorithm algorithm)
        : Key(data, algorithm, PUBLIC) {}
  };

  class PrivateKey : public Key {
   public:
    PrivateKey(const string& data, KeyAlgorithm algorithm)
        : Key(ByteBuffer(data), algorithm, PRIVATE) {}
    PrivateKey(const ByteBuffer& data, KeyAlgorithm algorithm)
        : Key(data, algorithm, PRIVATE) {}
  };

  class SecretKey : public Key {
   public:
    SecretKey(const string& data, KeyAlgorithm algorithm)
        : Key(ByteBuffer(data), algorithm, SECRET) {}
    SecretKey(const ByteBuffer& data, KeyAlgorithm algorithm)
        : Key(data, algorithm, SECRET) {}
  };

  struct KeyPair {
    std::unique_ptr<PrivateKey> private_key;
    std::unique_ptr<PublicKey> public_key;

    KeyPair(std::unique_ptr<PublicKey> pub,
            std::unique_ptr<PrivateKey> priv) {
      public_key = std::move(pub);
      private_key = std::move(priv);
    }
  };

  //
  // Implements HKDF (RFC 5869) with the SHA-256 hash and a 256-bit output key
  // length.
  //
  // @param inputKeyMaterial master key from which to derive sub-keys
  // @param salt a (public) randomly generated 256-bit input that can be re-used
  // @param info arbitrary information that is bound to the derived key (i.e.,
  // used in its creation)
  // @return a std::unique_ptr<string> holding the derived key bytes =
  // HKDF-SHA256(inputKeyMaterial, salt, info) on success or nullptr on error
  //
  static std::unique_ptr<string> Hkdf(const string& inputKeyMaterial,
                                      const string& salt,
                                      const string& info);

  //
  // A key derivation function specific to this library, which accepts a {@code
  // masterKey} and an arbitrary {@code purpose} describing the intended
  // application of the derived sub-key, and produces a derived AES - 256 key
  // safe to use as if it were independent of any other derived key which used
  // a different {@code purpose}.
  //
  // @param masterKey any key suitable for use with HmacSHA256
  // @param purpose a UTF-8 encoded string describing the intended purpose of
  // derived key
  // @return a derived Key suitable for use with AES-256
  //
  static std::unique_ptr<SecretKey> DeriveAes256KeyFor(
      const SecretKey& masterKey, const string& purpose);

  //
  // SHA 256 length, in bytes
  //
  static const unsigned int kSha256DigestSize = 32;

  //
  // Salt length, in bytes
  //
  static const unsigned int kSaltSize = 32;

  // AES 256 key length, in bytes
  static const unsigned int kAesKeySize = 32;

  //
  // Truncated hash output length, in bytes.
  //
  static const unsigned int kDigestLength = 20;

  //
  // Computes a collision-resistant hash of {@link #kDigestLength} bytes
  // (using a truncated SHA-256 output).
  //
  // @return a std::unique_ptr holding the digest or a nullptr on error
  //
  static std::unique_ptr<string> Digest(const string& data);

  //
  // Decrypts {@code ciphertext} using the algorithm specified in {@code
  // encType}, with the specified {@code iv} and {@code decryptionKey}.
  //
  // @return a std::unique_ptr holding the decrypted data or a nullptr on error
  //
  static std::unique_ptr<string> Decrypt(const SecretKey& decryptionKey,
                                         EncType encType,
                                         const string& iv,
                                         const string& ciphertext);

  //
  // Encrypts {@code plaintext} using the algorithm specified in {@code
  // encType}, with the specified * {@code iv} and {@code encryptionKey}.
  //
  // @param rng source of randomness to be used with the specified cipher, if
  // necessary
  // @return a std::unique_ptr holding the encrypted data or nullptr on error
  static std::unique_ptr<string> Encrypt(const SecretKey& encryptionKey,
                                         EncType encType,
                                         const string& iv,
                                         const string& plaintext);

  //
  // Runs the Diffie-Hellman algorithm.
  //
  // @param private_key must have the same algorithm as the peer_key
  // @param peer_key must be the matching public key
  // @return an AES secret key created from the SHA-256 of the secret created
  // here or nullptr on error.
  //
  static std::unique_ptr<SecretKey> KeyAgreementSha256(
      const PrivateKey& private_key,
      const PublicKey& peer_key);

  //
  // Generate a random IV appropriate for use with the algorithm specified in
  // {@code encType}.
  //
  // @return a freshly generated IV (a random byte sequence of appropriate
  // length)
  //
  static std::unique_ptr<string> GenerateIv(EncType encType);

  //
  // Signs {@code data} using the algorithm specified by {@code sigType} with
  // {@code signingKey}.
  //
  // @param rng is required for public key signature schemes
  // @return a std::unique_ptr holding a string that represents the raw
  // signature or a nullptr on error
  //
  static std::unique_ptr<string> Sign(SigType sigType,
                                      const Key& signingKey,
                                      const string& data);

  //
  // Verifies the {@code signature} on {@code data} using the algorithm
  // specified by {@code sigType} with {@code verificationKey}.
  //
  // @return true iff the signature is verified
  //
  static bool Verify(SigType sigType,
                     const Key& verificationKey,
                     const string& signature,
                     const string& data);

  //
  // Imports a P256 EC Public Key using the x and y coordinates of the curve.
  //
  // @return nullptr if the point is invalid
  //
  static std::unique_ptr<PublicKey> ImportEcP256Key(const string& x,
                                                    const string& y);

  //
  // Exports the x and y coordinates of a P256 EC Public Key.
  //
  // @return false iff the key cannot be exported (for example, incorrect type)
  //
  static bool ExportEcP256Key(const PublicKey& key, string *x, string *y);

  //
  // Imports a 2048 bit RSA Public Key using the modulus {@code n} and exponent
  // {@code e}.
  //
  // @return nullptr if the parameters are invalid
  //
  static std::unique_ptr<PublicKey> ImportRsa2048Key(const string& n,
                                                     int32_t e);

  //
  // Exports the modulus and exponent of a 2048 bit RSA Public Key.
  //
  // @return false iff the key cannot be exported (for example, incorrect type)
  //
  static bool ExportRsa2048Key(const PublicKey& key, string* n, int32_t* e);

  //
  // Returns true if a sigType is a public key scheme
  //
  static bool IsPublicKeyScheme(SigType sigType);

  //
  // Indicates whether a "tag" is needed next to the plaintext body inside the
  // ciphertext, to prevent the same ciphertext from being reused with someone
  // else's signature on it.
  //
  static bool TaggedPlaintextRequired(const Key& signing_key,
                                      SigType sig_type,
                                      const Key& encryption_key);

  // Generates a 256 bit AES secret key
  static std::unique_ptr<SecretKey> GenerateAes256SecretKey();

  // Generates a P256 EC key pair
  static std::unique_ptr<KeyPair> GenerateEcP256KeyPair();

  // Generates a 2048 bit RSA key pair
  static std::unique_ptr<KeyPair> GenerateRsa2048KeyPair();

 private:
  //
  // @return SHA-256(UTF-8 encoded input)
  //
  // Will return a 32 byte ByteBuffer representing the SHA256 of the input bytes
  // Will return a nullptr if an internal error occurs
  //
  static std::unique_ptr<ByteBuffer> Sha256(const ByteBuffer& message);

  //
  // @return SHA256HMAC of specified message using provided key or nullptr on
  // error
  static std::unique_ptr<ByteBuffer> Sha256hmac(const ByteBuffer& key,
                                                const ByteBuffer& message);

  //
  // A salt value specific to this library, generated as
  // SHA-256("SecureMessage")
  //
  // We have to initialize salt in crypto_ops.cc because C++ doesn't allow
  // initialization and declaration in the same place.
  //
  static const uint8_t kSalt[kSaltSize];

  //
  // The HKDF (RFC 5869) extraction function, using the SHA-256 hash
  // function. This function is used to pre-process the inputKeyMaterial and mix
  // it with the salt, producing output suitable for use with HKDF expansion
  // function (which produces the actual derived key).
  //
  // @see #hkdfSha256Expand(ByteBuffer, ByteBuffer)
  // @return a std::unique_ptr<ByteBuffer> with HMAC-SHA256(salt,
  // inputKeyMaterial) (salt is the "key" for the HMAC) on success or a nullptr
  // on error
  //
  static std::unique_ptr<ByteBuffer> HkdfSha256Extract(
      const ByteBuffer& inputKeyMaterial, const ByteBuffer& salt);

  //
  // Special case of HKDF (RFC 5869) expansion function, using the SHA-256
  // hash function and allowing for a maximum output length of 256 bits.
  //
  // @param pseudoRandomKey should be generated by
  //        {@link #hkdfSha256Expand(ByteBuffer, ByteBuffer}
  // @param info arbitrary information the derived key should be bound to
  // @return a std::unique_ptr<ByteBuffer> holding derived key bytes =
  // HMAC-SHA256(pseudoRandomKey, info | 0x01) on success or a nullptr on
  // error
  //
  static std::unique_ptr<ByteBuffer> HkdfSha256Expand(
      const ByteBuffer& pseudoRandomKey, const ByteBuffer& info);

  //
  // Performs AES 256 CBC decryption of {@code ciphertext} with the specified
  // {@code iv} and {@code decryptionKey}.  Assumes PKCS#5 padding is used
  //
  // @return a std::unique_ptr holding the plaintext (decrypted) data or a
  // nullptr on error
  //
  static std::unique_ptr<ByteBuffer> Aes256CBCDecrypt(
      const SecretKey& decryptionKey,
      const ByteBuffer& iv,
      const ByteBuffer& ciphertext);

  //
  // Performs AES 256 CBC encryption of {@code plaintext} with the specified
  // {@code iv} and {@code encryptionKey}.  PKCS#5 is used.
  //
  // @return a std::unique_ptr holding the ciphertext (encrypted) data or a
  // nullptr on error
  //
  static std::unique_ptr<ByteBuffer> Aes256CBCEncrypt(
      const SecretKey& encryptionKey,
      const ByteBuffer& iv,
      const ByteBuffer& ciphertext);

  //
  // Get the purpose of an encryption scheme.  Basically a string representation
  // of the enum.
  //
  static string GetPurpose(EncType encType);

  //
  // Get the purpose of a signature scheme.  Basically a string representation
  // of the enum.
  //
  static string GetPurpose(SigType sigType);

  // Computes the ECDSA P256 SHA 256 MAC
  //
  // @param data the data to be signed
  // @param signingKey the ECDSA private key used for signing.
  // @return std::unique_ptr holding string that represents the MAC or nullptr
  // on error
  //
  static std::unique_ptr<ByteBuffer> EcdsaP256Sha256Sign(
      const PrivateKey& private_key,
      const ByteBuffer& data);

  // Verifies the ECDSA P256 SHA 256 signature
  //
  // @param signature to be verified
  // @param data the data over which the signature was computed
  // @param verificationKey the ECDSA public key used for verification.
  // @return bool true if signature is valid, false otherwise
  //
  static bool EcdsaP256Sha256Verify(const PublicKey& public_key,
                                    const ByteBuffer& signature,
                                    const ByteBuffer& data);

  //
  // Runs the Elliptic Curve variant of the Diffie-Hellman algorithm.
  //
  // @param private_key must have the algorithm ECDSA_KEY
  // @param peer_key must have the algorithm ECDSA_KEY
  // @return an AES secret key created from the SHA-256 of the secret created
  // by applying ECDH to the private_key and the peer_key.
  //
  static std::unique_ptr<ByteBuffer> EcdhKeyAgreement(
      const PrivateKey& private_key,
      const PublicKey& peer_key);


  // Computes the RSA 2048 SHA 256 signature
  //
  // @param data the data to be signed
  // @param signingKey the RSA Private key used to sign the data.  The key
  // should be in DER form.
  // @return std::unique_ptr holding string that represents the MAC or nullptr
  // on error
  //
  // TODO(aczeskis): refactor sign and verify to be virtual functions of key
  // objects
  //
  static std::unique_ptr<ByteBuffer> Rsa2048Sha256Sign(
      const PrivateKey& private_key, const ByteBuffer& data);

  // Verifies the RSA 2048 SHA 256 MAC
  //
  // @param signature to be verified
  // @param data the data over which the signature was computed
  // @param verificationKey the RSA public key used for verification
  // @return bool true if signature is valid, false otherwise
  //
  static bool Rsa2048Sha256Verify(const PublicKey& public_key,
                                  const ByteBuffer& signature,
                                  const ByteBuffer& data);

  static bool IsValidEcP256CoordinateEncoding(const string& bytes);

  static bool IsValidRsa2048ModulusEncoding(const string& bytes);

  //
  // Converts int32 value to an array of bytes represented as a string. The
  // bytes are in big-endian order.
  //
  static string Int32BytesToString(int32_t value);

  //
  // Converts a string of bytes to an int32 value. Fails if the bytes do not fit
  // in the int32 type. The bytes are in big-endian order.
  //
  static bool StringToInt32Bytes(const string& value, int32_t* result);

  // For testing private helper functions
  friend class CryptoOpsTest;

  virtual ~CryptoOps();
};

}  // namespace securemessage
#endif  // SECUREMESSAGE_CRYPTO_OPS_H_
