// Copyright (c) 2013, 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.

part of dart.io;

/**
 * A high-level class for communicating securely over a TCP socket, using
 * TLS and SSL. The [SecureSocket] exposes both a [Stream] and an
 * [IOSink] interface, making it ideal for using together with
 * other [Stream]s.
 */
abstract class SecureSocket implements Socket {
  external factory SecureSocket._(RawSecureSocket rawSocket);

  /**
   * Constructs a new secure client socket and connect it to the given
   * [host] on port [port]. The returned Future will complete with a
   * [SecureSocket] that is connected and ready for subscription.
   *
   * If [sendClientCertificate] is set to true, the socket will send a client
   * certificate if one is requested by the server.
   *
   * If [certificateName] is the nickname of a certificate in the certificate
   * database, that certificate will be sent.
   *
   * If [certificateName] is null, which is the usual use case, an
   * appropriate certificate will be searched for in the database and
   * sent automatically, based on what the server says it will accept.
   *
   * [onBadCertificate] is an optional handler for unverifiable certificates.
   * The handler receives the [X509Certificate], and can inspect it and
   * decide (or let the user decide) whether to accept
   * the connection or not.  The handler should return true
   * to continue the [SecureSocket] connection.
   */
  static Future<SecureSocket> connect(
      String host,
      int port,
      {bool sendClientCertificate: false,
       String certificateName,
       bool onBadCertificate(X509Certificate certificate)}) {
    return RawSecureSocket.connect(host,
                                   port,
                                   sendClientCertificate: sendClientCertificate,
                                   certificateName: certificateName,
                                   onBadCertificate: onBadCertificate)
        .then((rawSocket) => new SecureSocket._(rawSocket));
  }

  /**
   * Get the peer certificate for a connected SecureSocket.  If this
   * SecureSocket is the server end of a secure socket connection,
   * [peerCertificate] will return the client certificate, or null, if no
   * client certificate was received.  If it is the client end,
   * [peerCertificate] will return the server's certificate.
   */
  X509Certificate get peerCertificate;

  /**
   * Initializes the NSS library.  If [initialize] is not called, the library
   * is automatically initialized as if [initialize] were called with no
   * arguments.
   *
   * The optional argument [database] is the path to a certificate database
   * containing root certificates for verifying certificate paths on
   * client connections, and server certificates to provide on server
   * connections.  The argument [password] should be used when creating
   * secure server sockets, to allow the private key of the server
   * certificate to be fetched.  If [useBuiltinRoots] is true (the default),
   * then a built-in set of root certificates for trusted certificate
   * authorities is merged with the certificates in the database.
   *
   * Examples:
   *   1) Use only the builtin root certificates:
   *     SecureSocket.initialize(); or
   *
   *   2) Use a specified database and the builtin roots:
   *     SecureSocket.initialize(database: 'path/to/my/database',
   *                             password: 'my_password');
   *
   *   3) Use a specified database, without builtin roots:
   *     SecureSocket.initialize(database: 'path/to/my/database',
   *                             password: 'my_password'.
   *                             useBuiltinRoots: false);
   *
   * The database should be an NSS certificate database directory
   * containing a cert9.db file, not a cert8.db file.  This version of
   * the database can be created using the NSS certutil tool with "sql:" in
   * front of the absolute path of the database directory, or setting the
   * environment variable [[NSS_DEFAULT_DB_TYPE]] to "sql".
   */
  external static void initialize({String database,
                                   String password,
                                   bool useBuiltinRoots: true});
}


/**
 * RawSecureSocket provides a secure (SSL or TLS) network connection.
 * Client connections to a server are provided by calling
 * RawSecureSocket.connect.  A secure server, created with
 * RawSecureServerSocket, also returns RawSecureSocket objects representing
 * the server end of a secure connection.
 * The certificate provided by the server is checked
 * using the certificate database provided in SecureSocket.initialize, and/or
 * the default built-in root certificates.
 */
abstract class RawSecureSocket implements RawSocket {
  /**
   * Constructs a new secure client socket and connect it to the given
   * host on the given port. The returned Future is completed with the
   * RawSecureSocket when it is connected and ready for subscription.
   *
   * The certificate provided by the server is checked using the certificate
   * database provided in [SecureSocket.initialize], and/or the default built-in
   * root certificates. If [sendClientCertificate] is
   * set to true, the socket will send a client certificate if one is
   * requested by the server. If [certificateName] is the nickname of
   * a certificate in the certificate database, that certificate will be sent.
   * If [certificateName] is null, which is the usual use case, an
   * appropriate certificate will be searched for in the database and
   * sent automatically, based on what the server says it will accept.
   *
   * [onBadCertificate] is an optional handler for unverifiable certificates.
   * The handler receives the [X509Certificate], and can inspect it and
   * decide (or let the user decide) whether to accept
   * the connection or not.  The handler should return true
   * to continue the [RawSecureSocket] connection.
   */
  static Future<RawSecureSocket> connect(
      String host,
      int port,
      {bool sendClientCertificate: false,
       String certificateName,
       bool onBadCertificate(X509Certificate certificate)}) {
    return  _RawSecureSocket.connect(
        host,
        port,
        certificateName,
        is_server: false,
        sendClientCertificate: sendClientCertificate,
        onBadCertificate: onBadCertificate);
  }

  /**
   * Get the peer certificate for a connected RawSecureSocket.  If this
   * RawSecureSocket is the server end of a secure socket connection,
   * [peerCertificate] will return the client certificate, or null, if no
   * client certificate was received.  If it is the client end,
   * [peerCertificate] will return the server's certificate.
   */
  X509Certificate get peerCertificate;
}


/**
 * X509Certificate represents an SSL certificate, with accessors to
 * get the fields of the certificate.
 */
class X509Certificate {
  X509Certificate(this.subject,
                  this.issuer,
                  this.startValidity,
                  this.endValidity);
  final String subject;
  final String issuer;
  final DateTime startValidity;
  final DateTime endValidity;
}


class _RawSecureSocket extends Stream<RawSocketEvent>
                       implements RawSecureSocket {
  // Status states
  static final int NOT_CONNECTED = 200;
  static final int HANDSHAKE = 201;
  static final int CONNECTED = 202;
  static final int CLOSED = 203;

  // Buffer identifiers.
  // These must agree with those in the native C++ implementation.
  static final int READ_PLAINTEXT = 0;
  static final int WRITE_PLAINTEXT = 1;
  static final int READ_ENCRYPTED = 2;
  static final int WRITE_ENCRYPTED = 3;
  static final int NUM_BUFFERS = 4;

  RawSocket _socket;
  final Completer<_RawSecureSocket> _handshakeComplete =
      new Completer<_RawSecureSocket>();
  StreamController<RawSocketEvent> _controller;
  Stream<RawSocketEvent> _stream;
  StreamSubscription<RawSocketEvent> _socketSubscription;
  final String host;
  final bool is_server;
  final String certificateName;
  final bool requestClientCertificate;
  final bool requireClientCertificate;
  final bool sendClientCertificate;
  final Function onBadCertificate;

  var _status = NOT_CONNECTED;
  bool _writeEventsEnabled = true;
  bool _readEventsEnabled = true;
  bool _socketClosedRead = false;  // The network socket is closed for reading.
  bool _socketClosedWrite = false;  // The network socket is closed for writing.
  bool _closedRead = false;  // The secure socket has fired an onClosed event.
  bool _closedWrite = false;  // The secure socket has been closed for writing.
  bool _filterReadEmpty = true;  // There is no buffered data to read.
  bool _filterWriteEmpty = true;  // There is no buffered data to be written.
  bool _connectPending = false;
  _SecureFilter _secureFilter = new _SecureFilter();

  static Future<_RawSecureSocket> connect(
      String host,
      int requestedPort,
      String certificateName,
      {bool is_server,
       RawSocket socket,
       bool requestClientCertificate: false,
       bool requireClientCertificate: false,
       bool sendClientCertificate: false,
       bool onBadCertificate(X509Certificate certificate)}){
     return new _RawSecureSocket(host,
                                 requestedPort,
                                 certificateName,
                                 is_server,
                                 socket,
                                 requestClientCertificate,
                                 requireClientCertificate,
                                 sendClientCertificate,
                                 onBadCertificate)
         ._handshakeComplete.future;
  }

  _RawSecureSocket(
      String this.host,
      int requestedPort,
      String this.certificateName,
      bool this.is_server,
      RawSocket socket,
      bool this.requestClientCertificate,
      bool this.requireClientCertificate,
      bool this.sendClientCertificate,
      bool this.onBadCertificate(X509Certificate certificate)) {
    _controller = new StreamController<RawSocketEvent>(
        onPauseStateChange: _onPauseStateChange,
        onSubscriptionStateChange: _onSubscriptionStateChange);
    _stream = _controller.stream;
    // Throw an ArgumentError if any field is invalid.  After this, all
    // errors will be reported through the future or the stream.
    _verifyFields();
    _secureFilter.init();
    _secureFilter.registerHandshakeCompleteCallback(
        _secureHandshakeCompleteHandler);
    if (onBadCertificate != null) {
      _secureFilter.registerBadCertificateCallback(onBadCertificate);
    }
    var futureSocket;
    if (socket == null) {
      futureSocket = RawSocket.connect(host, requestedPort);
    } else {
      futureSocket = new Future.immediate(socket);
    }
    futureSocket.then((rawSocket) {
      rawSocket.writeEventsEnabled = false;
      _socket = rawSocket;
      _socketSubscription = _socket.listen(_eventDispatcher,
                                           onError: _errorHandler,
                                           onDone: _doneHandler);
      _connectPending = true;
      _secureFilter.connect(host,
                            port,
                            is_server,
                            certificateName,
                            requestClientCertificate ||
                                requireClientCertificate,
                            requireClientCertificate,
                            sendClientCertificate);
      _status = HANDSHAKE;
      _secureHandshake();
    })
    .catchError((error) {
      _handshakeComplete.completeError(error);
      _close();
    });
  }

  StreamSubscription listen(void onData(RawSocketEvent data),
                            {void onError(AsyncError error),
                             void onDone(),
                             bool unsubscribeOnError}) {
    if (_writeEventsEnabled) {
      _writeEventsEnabled = false;
      _controller.add(RawSocketEvent.WRITE);
    }
    return _stream.listen(onData,
                          onError: onError,
                          onDone: onDone,
                          unsubscribeOnError: unsubscribeOnError);
  }

  void _verifyFields() {
    assert(is_server is bool);
    assert(_socket == null || _socket is RawSocket);
    if (host is! String) {
      throw new ArgumentError(
          "RawSecureSocket constructor: host is not a String");
    }
    if (certificateName != null && certificateName is! String) {
      throw new ArgumentError("certificateName is not null or a String");
    }
    if (certificateName == null && is_server) {
      throw new ArgumentError("certificateName is null on a server");
    }
    if (requestClientCertificate is! bool) {
      throw new ArgumentError("requestClientCertificate is not a bool");
    }
    if (requireClientCertificate is! bool) {
      throw new ArgumentError("requireClientCertificate is not a bool");
    }
    if (sendClientCertificate is! bool) {
      throw new ArgumentError("sendClientCertificate is not a bool");
    }
    if (onBadCertificate != null && onBadCertificate is! Function) {
      throw new ArgumentError("onBadCertificate is not null or a Function");
    }
   }

  int get port => _socket.port;

  String get remoteHost => _socket.remoteHost;

  int get remotePort => _socket.remotePort;

  int available() {
    if (_status != CONNECTED) return 0;
    _readEncryptedData();
    return _secureFilter.buffers[READ_PLAINTEXT].length;
  }

  void close() {
    shutdown(SocketDirection.BOTH);
  }

  void _close() {
    _closedWrite = true;
    _closedRead = true;
    if (_socket != null) {
      _socket.close();
    }
    _socketClosedWrite = true;
    _socketClosedRead = true;
    if (_secureFilter != null) {
      _secureFilter.destroy();
      _secureFilter = null;
    }
    if (_socketSubscription != null) {
      _socketSubscription.cancel();
    }
    _controller.close();
    _status = CLOSED;
  }

  void shutdown(SocketDirection direction) {
    if (direction == SocketDirection.SEND ||
        direction == SocketDirection.BOTH) {
      _closedWrite = true;
      _writeEncryptedData();
      if (_filterWriteEmpty) {
        _socket.shutdown(SocketDirection.SEND);
        _socketClosedWrite = true;
        if (_closedRead) {
          _close();
        }
      }
    }
    if (direction == SocketDirection.RECEIVE ||
        direction == SocketDirection.BOTH) {
      _closedRead = true;
      _socketClosedRead = true;
      _socket.shutdown(SocketDirection.RECEIVE);
      if (_socketClosedWrite) {
        _close();
      }
    }
  }

  bool get writeEventsEnabled => _writeEventsEnabled;

  void set writeEventsEnabled(bool value) {
    if (value &&
        _controller.hasSubscribers &&
        _secureFilter != null &&
        _secureFilter.buffers[WRITE_PLAINTEXT].free > 0) {
      Timer.run(() => _controller.add(RawSocketEvent.WRITE));
    } else {
      _writeEventsEnabled = value;
    }
  }

  bool get readEventsEnabled => _readEventsEnabled;

  void set readEventsEnabled(bool value) {
    _readEventsEnabled = value;
    if (value &&
        ((_secureFilter != null &&
          _secureFilter.buffers[READ_PLAINTEXT].length > 0) ||
         _socketClosedRead)) {
      // We might not have no underlying socket to set off read events.
      Timer.run(_readHandler);
    }
  }

  List<int> read([int len]) {
    if (_closedRead) {
      throw new SocketIOException("Reading from a closed socket");
    }
    if (_status != CONNECTED) {
      return null;
    }
    var buffer = _secureFilter.buffers[READ_PLAINTEXT];
    _readEncryptedData();
    int toRead = buffer.length;
    if (len != null) {
      if (len is! int || len < 0) {
        throw new ArgumentError(
            "Invalid len parameter in SecureSocket.read (len: $len)");
      }
      if (len < toRead) {
        toRead = len;
      }
    }
    List<int> result = (toRead == 0) ? null :
        buffer.data.getRange(buffer.start, toRead);
    buffer.advanceStart(toRead);

    // Set up a read event if the filter still has data.
    if (!_filterReadEmpty) {
      Timer.run(_readHandler);
    }

    if (_socketClosedRead) {  // An onClose event is pending.
      // _closedRead is false, since we are in a read  call.
      if (!_filterReadEmpty) {
        // _filterReadEmpty may be out of date since read empties
        // the plaintext buffer after calling _readEncryptedData.
        // TODO(whesse): Fix this as part of fixing read.
        _readEncryptedData();
      }
      if (_filterReadEmpty) {
        // This can't be an else clause: the value of _filterReadEmpty changes.
        // This must be asynchronous, because we are in a read call.
        Timer.run(_closeHandler);
      }
    }

    return result;
  }

  // Write the data to the socket, and flush it as much as possible
  // until it would block.  If the write would block, _writeEncryptedData sets
  // up handlers to flush the pipeline when possible.
  int write(List<int> data, [int offset, int bytes]) {
    if (_closedWrite) {
      _controller.signalError(new AsyncError(new SocketIOException(
          "Writing to a closed socket")));
      return 0;
    }
    if (_status != CONNECTED) return 0;
    var buffer = _secureFilter.buffers[WRITE_PLAINTEXT];
    if (bytes > buffer.free) {
      bytes = buffer.free;
    }
    if (bytes > 0) {
      buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset);
      buffer.length += bytes;
    }
    _writeEncryptedData();  // Tries to flush all pipeline stages.
    return bytes;
  }

  X509Certificate get peerCertificate => _secureFilter.peerCertificate;

  void _writeHandler() {
    if (_status == CLOSED) return;
    _writeEncryptedData();
    if (_filterWriteEmpty && _closedWrite && !_socketClosedWrite) {
      // Close _socket for write, by calling shutdown(), to avoid cloning the
      // socket closing code in shutdown().
      shutdown(SocketDirection.SEND);
    }
    if (_status == HANDSHAKE) {
      try {
        _secureHandshake();
      } catch (e) { _reportError(e, "RawSecureSocket error"); }
    } else if (_status == CONNECTED &&
               _controller.hasSubscribers &&
               _writeEventsEnabled &&
               _secureFilter.buffers[WRITE_PLAINTEXT].free > 0) {
      // Reset the one-shot handler.
      _writeEventsEnabled = false;
      _controller.add(RawSocketEvent.WRITE);
    }
  }

  void _eventDispatcher(RawSocketEvent event) {
    if (event == RawSocketEvent.READ) {
      _readHandler();
    } else if (event == RawSocketEvent.WRITE) {
      _writeHandler();
    } else if (event == RawSocketEvent.READ_CLOSED) {
      _closeHandler();
    }
  }

  void _readHandler() {
    if (_status == CLOSED) {
      return;
    } else if (_status == HANDSHAKE) {
      try {
        _secureHandshake();
        if (_status != HANDSHAKE) _readHandler();
      } catch (e) { _reportError(e, "RawSecureSocket error"); }
    } else {
      if (_status != CONNECTED) {
        // Cannot happen.
        throw new SocketIOException("Internal SocketIO Error");
      }
      try {
        _readEncryptedData();
      } catch (e) { _reportError(e, "RawSecureSocket error"); }
      if (!_filterReadEmpty) {
        if (_readEventsEnabled) {
          if (_secureFilter.buffers[READ_PLAINTEXT].length > 0) {
            _controller.add(RawSocketEvent.READ);
          }
          if (_socketClosedRead) {
            // Keep firing read events until we are paused or buffer is empty.
            Timer.run(_readHandler);
          }
        }
      } else if (_socketClosedRead) {
        _closeHandler();
      }
    }
  }

  void _doneHandler() {
    if (_filterReadEmpty) {
      _close();
    }
  }

  void _errorHandler(e) {
    _reportError(e, 'Error on underlying RawSocket');
  }

  void _reportError(error, String message) {
    // TODO(whesse): Call _reportError from all internal functions that throw.
    var e;
    if (error is AsyncError) {
      e = error;
    } else if (error is SocketIOException) {
      e = new SocketIOException('$message (${error.message})', error.osError);
    } else if (error is OSError) {
      e = new SocketIOException(message, error);
    } else {
      e = new SocketIOException('$message (${error.toString()})', null);
    }
    if (_connectPending) {
      _handshakeComplete.completeError(e);
    } else {
      _controller.signalError(e);
    }
    _close();
  }

  void _closeHandler() {
    if  (_status == CONNECTED) {
      if (_closedRead) return;
      _socketClosedRead = true;
      if (_filterReadEmpty) {
        _closedRead = true;
        _controller.add(RawSocketEvent.READ_CLOSED);
        if (_socketClosedWrite) {
          _close();
        }
      }
    } else if (_status == HANDSHAKE) {
      _reportError(
          new SocketIOException('Connection terminated during handshake'),
          'handshake error');
    }
  }

  void _secureHandshake() {
    _readEncryptedData();
    _secureFilter.handshake();
    _writeEncryptedData();
  }

  void _secureHandshakeCompleteHandler() {
    _status = CONNECTED;
    if (_connectPending) {
      _connectPending = false;
      // If we complete the future synchronously, user code will run here,
      // and modify the state of the RawSecureSocket.  For example, it
      // could close the socket, and set _filter to null.
      Timer.run(() => _handshakeComplete.complete(this));
    }
  }

  void _onPauseStateChange() {
    if (!_socketClosedRead || !_socketClosedWrite) {
      if (_controller.isPaused) {
        _socketSubscription.pause();
      } else {
        _socketSubscription.resume();
      }
    }
  }

  void _onSubscriptionStateChange() {
    if (_controller.hasSubscribers) {
      // TODO(ajohnsen): Do something here?
    }
  }

  void _readEncryptedData() {
    // Read from the socket, and push it through the filter as far as
    // possible.
    var encrypted = _secureFilter.buffers[READ_ENCRYPTED];
    var plaintext = _secureFilter.buffers[READ_PLAINTEXT];
    bool progress = true;
    while (progress) {
      progress = false;
      // Do not try to read plaintext from the filter while handshaking.
      if ((_status == CONNECTED) && plaintext.free > 0) {
        int bytes = _secureFilter.processBuffer(READ_PLAINTEXT);
        if (bytes > 0) {
          plaintext.length += bytes;
          progress = true;
        }
      }
      if (encrypted.length > 0) {
        int bytes = _secureFilter.processBuffer(READ_ENCRYPTED);
        if (bytes > 0) {
          encrypted.advanceStart(bytes);
          progress = true;
        }
      }
      if (!_socketClosedRead && encrypted.free > 0) {
        List<int> data = _socket.read(encrypted.free);
        if (data != null) {
          int bytes = data.length;
          encrypted.data.setRange(encrypted.start + encrypted.length,
                                  bytes,
                                  data);
          encrypted.length += bytes;
          progress = true;
        }
      }
    }
    // If there is any data in any stages of the filter, there should
    // be data in the plaintext buffer after this process.
    // TODO(whesse): Verify that this is true, and there can be no
    // partial encrypted block stuck in the secureFilter.
    _filterReadEmpty = (plaintext.length == 0);
  }

  void _writeEncryptedData() {
    if (_socketClosedWrite) return;
    var encrypted = _secureFilter.buffers[WRITE_ENCRYPTED];
    var plaintext = _secureFilter.buffers[WRITE_PLAINTEXT];
    while (true) {
      if (encrypted.length > 0) {
        // Write from the filter to the socket.
        int bytes = _socket.write(encrypted.data,
                                  encrypted.start,
                                  encrypted.length);
        encrypted.advanceStart(bytes);
        if (encrypted.length > 0) {
          // The socket has blocked while we have data to write.
          // We must be notified when it becomes unblocked.
          _socket.writeEventsEnabled = true;
          _filterWriteEmpty = false;
          break;
        }
      } else {
        var plaintext = _secureFilter.buffers[WRITE_PLAINTEXT];
        if (plaintext.length > 0) {
           int plaintext_bytes = _secureFilter.processBuffer(WRITE_PLAINTEXT);
           plaintext.advanceStart(plaintext_bytes);
        }
        int bytes = _secureFilter.processBuffer(WRITE_ENCRYPTED);
        if (bytes <= 0) {
          // We know the WRITE_ENCRYPTED buffer is empty, and the
          // filter wrote zero bytes to it, so the filter must be empty.
          // Also, the WRITE_PLAINTEXT buffer must have been empty, or
          // it would have written to the filter.
          // TODO(whesse): Verify that the filter works this way.
          _filterWriteEmpty = true;
          break;
        }
        encrypted.length += bytes;
      }
    }
  }
}


class _ExternalBuffer {
  // Performance is improved if a full buffer of plaintext fits
  // in the encrypted buffer, when encrypted.
  static final int SIZE = 8 * 1024;
  static final int ENCRYPTED_SIZE = 10 * 1024;
  _ExternalBuffer() : start = 0, length = 0;

  // TODO(whesse): Consider making this a circular buffer.  Only if it helps.
  void advanceStart(int numBytes) {
    start += numBytes;
    length -= numBytes;
    if (length == 0) {
      start = 0;
    }
  }

  int get free => data.length - (start + length);

  List data;  // This will be a ExternalByteArray, backed by C allocated data.
  int start;
  int length;
}


abstract class _SecureFilter {
  external factory _SecureFilter();

  void connect(String hostName,
               int port,
               bool is_server,
               String certificateName,
               bool requestClientCertificate,
               bool requireClientCertificate,
               bool sendClientCertificate);
  void destroy();
  void handshake();
  void init();
  X509Certificate get peerCertificate;
  int processBuffer(int bufferIndex);
  void registerBadCertificateCallback(Function callback);
  void registerHandshakeCompleteCallback(Function handshakeCompleteHandler);

  List<_ExternalBuffer> get buffers;
}
