// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_BIN_SECURE_SOCKET_MACOS_H_
#define RUNTIME_BIN_SECURE_SOCKET_MACOS_H_

#if !defined(RUNTIME_BIN_SECURE_SOCKET_H_)
#error Do not include secure_socket_macos.h directly. Use secure_socket.h.
#endif

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>

#include <CoreFoundation/CoreFoundation.h>
#include <Security/SecureTransport.h>
#include <Security/Security.h>

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/lockers.h"
#include "bin/reference_counting.h"
#include "bin/socket.h"
#include "bin/thread.h"
#include "bin/utils.h"

namespace dart {
namespace bin {

// SSLCertContext wraps the certificates needed for a SecureTransport
// connection. Fields are protected by the mutex_ field, and may only be set
// once. This is to allow access by both the Dart thread and the IOService
// thread. Setters return false if the field was already set.
class SSLCertContext : public ReferenceCounted<SSLCertContext> {
 public:
  SSLCertContext()
      : ReferenceCounted(),
        mutex_(new Mutex()),
        private_key_(NULL),
        keychain_(NULL),
        cert_chain_(NULL),
        trusted_certs_(NULL),
        cert_authorities_(NULL),
        trust_builtin_(false) {}

  ~SSLCertContext() {
    {
      MutexLocker m(mutex_);
      if (private_key_ != NULL) {
        CFRelease(private_key_);
      }
      if (keychain_ != NULL) {
        SecKeychainDelete(keychain_);
        CFRelease(keychain_);
      }
      if (cert_chain_ != NULL) {
        CFRelease(cert_chain_);
      }
      if (trusted_certs_ != NULL) {
        CFRelease(trusted_certs_);
      }
      if (cert_authorities_ != NULL) {
        CFRelease(cert_authorities_);
      }
    }
    delete mutex_;
  }

  SecKeyRef private_key() {
    MutexLocker m(mutex_);
    return private_key_;
  }
  bool set_private_key(SecKeyRef private_key) {
    MutexLocker m(mutex_);
    if (private_key_ != NULL) {
      return false;
    }
    private_key_ = private_key;
    return true;
  }

  SecKeychainRef keychain() {
    MutexLocker m(mutex_);
    return keychain_;
  }
  bool set_keychain(SecKeychainRef keychain) {
    MutexLocker m(mutex_);
    if (keychain_ != NULL) {
      return false;
    }
    keychain_ = keychain;
    return true;
  }

  CFArrayRef cert_chain() {
    MutexLocker m(mutex_);
    return cert_chain_;
  }
  bool set_cert_chain(CFArrayRef cert_chain) {
    MutexLocker m(mutex_);
    if (cert_chain_ != NULL) {
      return false;
    }
    cert_chain_ = cert_chain;
    return true;
  }

  CFArrayRef trusted_certs() {
    MutexLocker m(mutex_);
    return trusted_certs_;
  }
  bool set_trusted_certs(CFArrayRef trusted_certs) {
    MutexLocker m(mutex_);
    if (trusted_certs_ != NULL) {
      return false;
    }
    trusted_certs_ = trusted_certs;
    return true;
  }

  CFArrayRef cert_authorities() {
    MutexLocker m(mutex_);
    return cert_authorities_;
  }
  bool set_cert_authorities(CFArrayRef cert_authorities) {
    MutexLocker m(mutex_);
    if (cert_authorities_ != NULL) {
      return false;
    }
    cert_authorities_ = cert_authorities;
    return true;
  }

  bool trust_builtin() {
    MutexLocker m(mutex_);
    return trust_builtin_;
  }
  void set_trust_builtin(bool trust_builtin) {
    MutexLocker m(mutex_);
    trust_builtin_ = trust_builtin;
  }

 private:
  // The context is accessed both by Dart code and the IOService. This mutex
  // protects all fields.
  Mutex* mutex_;

  SecKeyRef private_key_;
  SecKeychainRef keychain_;

  // CFArrays of SecCertificateRef.
  CFArrayRef cert_chain_;
  CFArrayRef trusted_certs_;
  CFArrayRef cert_authorities_;

  bool trust_builtin_;

  DISALLOW_COPY_AND_ASSIGN(SSLCertContext);
};

// SSLFilter encapsulates the SecureTransport code in a filter that communicates
// with the containing _SecureFilterImpl Dart object through four shared
// ExternalByteArray buffers, for reading and writing plaintext, and
// reading and writing encrypted text.  The filter handles handshaking
// and certificate verification.
class SSLFilter : public ReferenceCounted<SSLFilter> {
 public:
  // These enums must agree with those in sdk/lib/io/secure_socket.dart.
  enum BufferIndex {
    kReadPlaintext,
    kWritePlaintext,
    kReadEncrypted,
    kWriteEncrypted,
    kNumBuffers,
    kFirstEncrypted = kReadEncrypted
  };

  SSLFilter()
      : ReferenceCounted(),
        cert_context_(NULL),
        ssl_context_(NULL),
        peer_certs_(NULL),
        string_start_(NULL),
        string_length_(NULL),
        handshake_complete_(NULL),
        bad_certificate_callback_(NULL),
        in_handshake_(false),
        connected_(false),
        bad_cert_(false),
        is_server_(false),
        hostname_(NULL) {}

  ~SSLFilter();

  // Callback called by the IOService.
  static CObject* ProcessFilterRequest(const CObjectArray& request);

  Dart_Handle Init(Dart_Handle dart_this);
  void Connect(Dart_Handle dart_this,
               const char* hostname,
               SSLCertContext* context,
               bool is_server,
               bool request_client_certificate,
               bool require_client_certificate);
  void Destroy();
  OSStatus CheckHandshake();
  void Renegotiate(bool use_session_cache,
                   bool request_client_certificate,
                   bool require_client_certificate);
  void RegisterHandshakeCompleteCallback(Dart_Handle handshake_complete);
  void RegisterBadCertificateCallback(Dart_Handle callback);
  Dart_Handle PeerCertificate();

 private:
  static OSStatus SSLReadCallback(SSLConnectionRef connection,
                                  void* data,
                                  size_t* data_length);
  static OSStatus SSLWriteCallback(SSLConnectionRef connection,
                                   const void* data,
                                   size_t* data_length);

  static bool isBufferEncrypted(intptr_t i) {
    return static_cast<BufferIndex>(i) >= kFirstEncrypted;
  }
  Dart_Handle InitializeBuffers(Dart_Handle dart_this);

  intptr_t GetBufferStart(intptr_t idx) const;
  intptr_t GetBufferEnd(intptr_t idx) const;
  void SetBufferStart(intptr_t idx, intptr_t value);
  void SetBufferEnd(intptr_t idx, intptr_t value);

  OSStatus ProcessAllBuffers(intptr_t starts[kNumBuffers],
                             intptr_t ends[kNumBuffers],
                             bool in_handshake);
  OSStatus ProcessReadPlaintextBuffer(intptr_t start,
                                      intptr_t end,
                                      intptr_t* bytes_processed);
  OSStatus ProcessWritePlaintextBuffer(intptr_t start,
                                       intptr_t end,
                                       intptr_t* bytes_processed);

  // These calls can block on IO, and should only be invoked from
  // from ProcessAllBuffers from ProcessFilterRequest.
  OSStatus EvaluatePeerTrust();
  OSStatus Handshake();
  Dart_Handle InvokeBadCertCallback(SecCertificateRef peer_cert);

  RetainedPointer<SSLCertContext> cert_context_;
  SSLContextRef ssl_context_;
  CFArrayRef peer_certs_;

  // starts and ends filled in at the start of ProcessAllBuffers.
  // If these are NULL, then try to get the pointers out of
  // dart_buffer_objects_.
  uint8_t* buffers_[kNumBuffers];
  intptr_t* buffer_starts_[kNumBuffers];
  intptr_t* buffer_ends_[kNumBuffers];
  intptr_t buffer_size_;
  intptr_t encrypted_buffer_size_;
  Dart_PersistentHandle string_start_;
  Dart_PersistentHandle string_length_;
  Dart_PersistentHandle dart_buffer_objects_[kNumBuffers];
  Dart_PersistentHandle handshake_complete_;
  Dart_PersistentHandle bad_certificate_callback_;
  bool in_handshake_;
  bool connected_;
  bool bad_cert_;
  bool is_server_;
  char* hostname_;

  DISALLOW_COPY_AND_ASSIGN(SSLFilter);
};

}  // namespace bin
}  // namespace dart

#endif  // RUNTIME_BIN_SECURE_SOCKET_MACOS_H_
