/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_RTC_BASE_OPENSSLADAPTER_H_
#define WEBRTC_RTC_BASE_OPENSSLADAPTER_H_

#include <map>
#include <string>
#include "webrtc/rtc_base/buffer.h"
#include "webrtc/rtc_base/messagehandler.h"
#include "webrtc/rtc_base/messagequeue.h"
#include "webrtc/rtc_base/opensslidentity.h"
#include "webrtc/rtc_base/ssladapter.h"

typedef struct ssl_st SSL;
typedef struct ssl_ctx_st SSL_CTX;
typedef struct x509_store_ctx_st X509_STORE_CTX;
typedef struct ssl_session_st SSL_SESSION;

namespace rtc {

class OpenSSLAdapterFactory;

class OpenSSLAdapter : public SSLAdapter, public MessageHandler {
 public:
  static bool InitializeSSL(VerificationCallback callback);
  static bool InitializeSSLThread();
  static bool CleanupSSL();

  explicit OpenSSLAdapter(AsyncSocket* socket,
                          OpenSSLAdapterFactory* factory = nullptr);
  ~OpenSSLAdapter() override;

  void SetMode(SSLMode mode) override;
  void SetIdentity(SSLIdentity* identity) override;
  void SetRole(SSLRole role) override;
  AsyncSocket* Accept(SocketAddress* paddr) override;
  int StartSSL(const char* hostname, bool restartable) override;
  int Send(const void* pv, size_t cb) override;
  int SendTo(const void* pv, size_t cb, const SocketAddress& addr) override;
  int Recv(void* pv, size_t cb, int64_t* timestamp) override;
  int RecvFrom(void* pv,
               size_t cb,
               SocketAddress* paddr,
               int64_t* timestamp) override;
  int Close() override;

  // Note that the socket returns ST_CONNECTING while SSL is being negotiated.
  ConnState GetState() const override;
  bool IsResumedSession() override;

  // Creates a new SSL_CTX object, configured for client-to-server usage
  // with SSLMode |mode|, and if |enable_cache| is true, with support for
  // storing successful sessions so that they can be later resumed.
  // OpenSSLAdapterFactory will call this method to create its own internal
  // SSL_CTX, and OpenSSLAdapter will also call this when used without a
  // factory.
  static SSL_CTX* CreateContext(SSLMode mode, bool enable_cache);

 protected:
  void OnConnectEvent(AsyncSocket* socket) override;
  void OnReadEvent(AsyncSocket* socket) override;
  void OnWriteEvent(AsyncSocket* socket) override;
  void OnCloseEvent(AsyncSocket* socket, int err) override;

 private:
  enum SSLState {
    SSL_NONE, SSL_WAIT, SSL_CONNECTING, SSL_CONNECTED, SSL_ERROR
  };

  enum { MSG_TIMEOUT };

  int BeginSSL();
  int ContinueSSL();
  void Error(const char* context, int err, bool signal = true);
  void Cleanup();

  // Return value and arguments have the same meanings as for Send; |error| is
  // an output parameter filled with the result of SSL_get_error.
  int DoSslWrite(const void* pv, size_t cb, int* error);

  void OnMessage(Message* msg) override;

  static bool VerifyServerName(SSL* ssl, const char* host,
                               bool ignore_bad_cert);
  bool SSLPostConnectionCheck(SSL* ssl, const char* host);
#if !defined(NDEBUG)
  // In debug builds, logs info about the state of the SSL connection.
  static void SSLInfoCallback(const SSL* ssl, int where, int ret);
#endif
  static int SSLVerifyCallback(int ok, X509_STORE_CTX* store);
  static VerificationCallback custom_verify_callback_;
  friend class OpenSSLStreamAdapter;  // for custom_verify_callback_;

  // If the SSL_CTX was created with |enable_cache| set to true, this callback
  // will be called when a SSL session has been successfully established,
  // to allow its SSL_SESSION* to be cached for later resumption.
  static int NewSSLSessionCallback(SSL* ssl, SSL_SESSION* session);

  static bool ConfigureTrustedRootCertificates(SSL_CTX* ctx);

  // Parent object that maintains shared state.
  // Can be null if state sharing is not needed.
  OpenSSLAdapterFactory* factory_;

  SSLState state_;
  std::unique_ptr<OpenSSLIdentity> identity_;
  SSLRole role_;
  bool ssl_read_needs_write_;
  bool ssl_write_needs_read_;
  // If true, socket will retain SSL configuration after Close.
  // TODO(juberti): Remove this unused flag.
  bool restartable_;

  // This buffer is used if SSL_write fails with SSL_ERROR_WANT_WRITE, which
  // means we need to keep retrying with *the same exact data* until it
  // succeeds. Afterwards it will be cleared.
  Buffer pending_data_;

  SSL* ssl_;
  SSL_CTX* ssl_ctx_;
  std::string ssl_host_name_;
  // Do DTLS or not
  SSLMode ssl_mode_;

  bool custom_verification_succeeded_;
};

class OpenSSLAdapterFactory : public SSLAdapterFactory {
 public:
  OpenSSLAdapterFactory();
  ~OpenSSLAdapterFactory() override;

  void SetMode(SSLMode mode) override;
  OpenSSLAdapter* CreateAdapter(AsyncSocket* socket) override;

  static OpenSSLAdapterFactory* Create();

 private:
  SSL_CTX* ssl_ctx() { return ssl_ctx_; }
  // Looks up a session by hostname. The returned SSL_SESSION is not up_refed.
  SSL_SESSION* LookupSession(const std::string& hostname);
  // Adds a session to the cache, and up_refs it. Any existing session with the
  // same hostname is replaced.
  void AddSession(const std::string& hostname, SSL_SESSION* session);
  friend class OpenSSLAdapter;

  SSLMode ssl_mode_;
  // Holds the shared SSL_CTX for all created adapters.
  SSL_CTX* ssl_ctx_;
  // Map of hostnames to SSL_SESSIONs; holds references to the SSL_SESSIONs,
  // which are cleaned up when the factory is destroyed.
  // TODO(juberti): Add LRU eviction to keep the cache from growing forever.
  std::map<std::string, SSL_SESSION*> sessions_;
};

}  // namespace rtc

#endif  // WEBRTC_RTC_BASE_OPENSSLADAPTER_H_
