// Copyright (c) 2012, 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 "common_patch.dart";

@patch
class SecureSocket {
  @patch
  factory SecureSocket._(RawSecureSocket rawSocket) =>
      new _SecureSocket(rawSocket);
}

@patch
class _SecureFilter {
  @patch
  factory _SecureFilter() => new _SecureFilterImpl();
}

@patch
@pragma("vm:entry-point")
class X509Certificate {
  @patch
  @pragma("vm:entry-point")
  factory X509Certificate._() => new _X509CertificateImpl();
}

class _SecureSocket extends _Socket implements SecureSocket {
  _RawSecureSocket get _raw => super._raw as _RawSecureSocket;

  _SecureSocket(RawSecureSocket raw) : super(raw);

  void renegotiate(
      {bool useSessionCache: true,
      bool requestClientCertificate: false,
      bool requireClientCertificate: false}) {
    _raw.renegotiate(
        useSessionCache: useSessionCache,
        requestClientCertificate: requestClientCertificate,
        requireClientCertificate: requireClientCertificate);
  }

  X509Certificate get peerCertificate {
    if (_raw == null) {
      throw new StateError("peerCertificate called on destroyed SecureSocket");
    }
    return _raw.peerCertificate;
  }

  String get selectedProtocol {
    if (_raw == null) {
      throw new StateError("selectedProtocol called on destroyed SecureSocket");
    }
    return _raw.selectedProtocol;
  }
}

/**
 * _SecureFilterImpl wraps a filter that encrypts and decrypts data travelling
 * over an encrypted socket.  The filter also handles the handshaking
 * and certificate verification.
 *
 * The filter exposes its input and output buffers as Dart objects that
 * are backed by an external C array of bytes, so that both Dart code and
 * native code can access the same data.
 */
class _SecureFilterImpl extends NativeFieldWrapperClass1
    implements _SecureFilter {
  // Performance is improved if a full buffer of plaintext fits
  // in the encrypted buffer, when encrypted.
  // SIZE and ENCRYPTED_SIZE are referenced from C++.
  @pragma("vm:entry-point")
  static final int SIZE = 8 * 1024;
  @pragma("vm:entry-point")
  static final int ENCRYPTED_SIZE = 10 * 1024;

  _SecureFilterImpl() {
    buffers = new List<_ExternalBuffer>(_RawSecureSocket.bufferCount);
    for (int i = 0; i < _RawSecureSocket.bufferCount; ++i) {
      buffers[i] = new _ExternalBuffer(
          _RawSecureSocket._isBufferEncrypted(i) ? ENCRYPTED_SIZE : SIZE);
    }
  }

  void connect(
      String hostName,
      SecurityContext context,
      bool is_server,
      bool requestClientCertificate,
      bool requireClientCertificate,
      Uint8List protocols) native "SecureSocket_Connect";

  void destroy() {
    buffers = null;
    _destroy();
  }

  void _destroy() native "SecureSocket_Destroy";

  void handshake() native "SecureSocket_Handshake";

  void rehandshake() => throw new UnimplementedError();

  int processBuffer(int bufferIndex) => throw new UnimplementedError();

  String selectedProtocol() native "SecureSocket_GetSelectedProtocol";

  void renegotiate(bool useSessionCache, bool requestClientCertificate,
      bool requireClientCertificate) native "SecureSocket_Renegotiate";

  void init() native "SecureSocket_Init";

  X509Certificate get peerCertificate native "SecureSocket_PeerCertificate";

  void registerBadCertificateCallback(Function callback)
      native "SecureSocket_RegisterBadCertificateCallback";

  void registerHandshakeCompleteCallback(Function handshakeCompleteHandler)
      native "SecureSocket_RegisterHandshakeCompleteCallback";

  // This is a security issue, as it exposes a raw pointer to Dart code.
  int _pointer() native "SecureSocket_FilterPointer";

  @pragma("vm:entry-point", "get")
  List<_ExternalBuffer> buffers;
}

@patch
class SecurityContext {
  @patch
  factory SecurityContext({bool withTrustedRoots: false}) {
    return new _SecurityContext(withTrustedRoots);
  }

  @patch
  static SecurityContext get defaultContext {
    return _SecurityContext.defaultContext;
  }

  @patch
  static bool get alpnSupported => true;
}

class _SecurityContext extends NativeFieldWrapperClass1
    implements SecurityContext {
  _SecurityContext(bool withTrustedRoots) {
    _createNativeContext();
    if (withTrustedRoots) {
      _trustBuiltinRoots();
    }
  }

  void _createNativeContext() native "SecurityContext_Allocate";

  static final SecurityContext defaultContext = new _SecurityContext(true);

  void usePrivateKey(String file, {String password}) {
    List<int> bytes = (new File(file)).readAsBytesSync();
    usePrivateKeyBytes(bytes, password: password);
  }

  void usePrivateKeyBytes(List<int> keyBytes, {String password})
      native "SecurityContext_UsePrivateKeyBytes";

  void setTrustedCertificates(String file, {String password}) {
    List<int> bytes = (new File(file)).readAsBytesSync();
    setTrustedCertificatesBytes(bytes, password: password);
  }

  void setTrustedCertificatesBytes(List<int> certBytes, {String password})
      native "SecurityContext_SetTrustedCertificatesBytes";

  void useCertificateChain(String file, {String password}) {
    List<int> bytes = (new File(file)).readAsBytesSync();
    useCertificateChainBytes(bytes, password: password);
  }

  void useCertificateChainBytes(List<int> chainBytes, {String password})
      native "SecurityContext_UseCertificateChainBytes";

  void setClientAuthorities(String file, {String password}) {
    List<int> bytes = (new File(file)).readAsBytesSync();
    setClientAuthoritiesBytes(bytes, password: password);
  }

  void setClientAuthoritiesBytes(List<int> authCertBytes, {String password})
      native "SecurityContext_SetClientAuthoritiesBytes";

  void setAlpnProtocols(List<String> protocols, bool isServer) {
    Uint8List encodedProtocols =
        SecurityContext._protocolsToLengthEncoding(protocols);
    _setAlpnProtocols(encodedProtocols, isServer);
  }

  void _setAlpnProtocols(Uint8List protocols, bool isServer)
      native "SecurityContext_SetAlpnProtocols";
  void _trustBuiltinRoots() native "SecurityContext_TrustBuiltinRoots";
}

/**
 * _X509CertificateImpl wraps an X509 certificate object held by the BoringSSL
 * library. It exposes the fields of the certificate object.
 */
class _X509CertificateImpl extends NativeFieldWrapperClass1
    implements X509Certificate {
  // The native field must be set manually on a new object, in native code.
  // This is done by WrappedX509 in secure_socket.cc.
  _X509CertificateImpl();

  Uint8List _cachedDer;
  Uint8List get _der native "X509_Der";
  Uint8List get der {
    if (_cachedDer == null) {
      _cachedDer = _der;
    }
    return _cachedDer;
  }

  String _cachedPem;
  String get _pem native "X509_Pem";
  String get pem {
    if (_cachedPem == null) {
      _cachedPem = _pem;
    }
    return _cachedPem;
  }

  Uint8List _cachedSha1;
  Uint8List get _sha1 native "X509_Sha1";
  Uint8List get sha1 {
    if (_cachedSha1 == null) {
      _cachedSha1 = _sha1;
    }
    return _cachedSha1;
  }

  String get subject native "X509_Subject";
  String get issuer native "X509_Issuer";
  DateTime get startValidity {
    return new DateTime.fromMillisecondsSinceEpoch(_startValidity(),
        isUtc: true);
  }

  DateTime get endValidity {
    return new DateTime.fromMillisecondsSinceEpoch(_endValidity(), isUtc: true);
  }

  int _startValidity() native "X509_StartValidity";
  int _endValidity() native "X509_EndValidity";
}
