// 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.
 */
@pragma("vm:entry-point")
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 = <_ExternalBuffer>[
      for (int i = 0; i < _RawSecureSocket.bufferCount; ++i)
        new _ExternalBuffer(
            _RawSecureSocket._isBufferEncrypted(i) ? ENCRYPTED_SIZE : SIZE),
    ];
  }

  @pragma("vm:external-name", "SecureSocket_Connect")
  external void connect(
      String hostName,
      SecurityContext context,
      bool isServer,
      bool requestClientCertificate,
      bool requireClientCertificate,
      Uint8List protocols);

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

  @pragma("vm:external-name", "SecureSocket_Destroy")
  external void _destroy();

  @pragma("vm:external-name", "SecureSocket_Handshake")
  external int _handshake(SendPort replyPort);

  @pragma("vm:external-name", "SecureSocket_MarkAsTrusted")
  external void _markAsTrusted(int certificatePtr, bool isTrusted);

  @pragma("vm:external-name", "SecureSocket_NewX509CertificateWrapper")
  external static X509Certificate _newX509CertificateWrapper(
      int certificatePtr);

  Future<bool> handshake() {
    Completer<bool> evaluatorCompleter = Completer<bool>();

    ReceivePort rpEvaluateResponse = ReceivePort();
    rpEvaluateResponse.listen((data) {
      List list = data as List;
      // incoming messages (bool isTrusted, int certificatePtr) is
      // sent by TrustEvaluator native port after system evaluates
      // the certificate chain
      if (list.length != 2) {
        throw Exception("Invalid number of arguments in evaluate response");
      }
      bool isTrusted = list[0] as bool;
      int certificatePtr = list[1] as int;
      if (!isTrusted) {
        if (badCertificateCallback != null) {
          try {
            isTrusted = badCertificateCallback!(
                _newX509CertificateWrapper(certificatePtr));
          } catch (e, st) {
            evaluatorCompleter.completeError(e, st);
            rpEvaluateResponse.close();
            return;
          }
        }
      }
      _markAsTrusted(certificatePtr, isTrusted);
      evaluatorCompleter.complete(true);
      rpEvaluateResponse.close();
    });

    const int kSslErrorWantCertificateVerify = 16; // ssl.h:558
    int handshakeResult;
    try {
      handshakeResult = _handshake(rpEvaluateResponse.sendPort);
    } catch (e, st) {
      rpEvaluateResponse.close();
      rethrow;
    }
    if (handshakeResult == kSslErrorWantCertificateVerify) {
      return evaluatorCompleter.future;
    } else {
      // Response is ready, no need for evaluate response receive port
      rpEvaluateResponse.close();
      return Future<bool>.value(false);
    }
  }

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

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

  @pragma("vm:external-name", "SecureSocket_GetSelectedProtocol")
  external String? selectedProtocol();

  @pragma("vm:external-name", "SecureSocket_Renegotiate")
  external void renegotiate(bool useSessionCache, bool requestClientCertificate,
      bool requireClientCertificate);

  @pragma("vm:external-name", "SecureSocket_Init")
  external void init();

  @pragma("vm:external-name", "SecureSocket_PeerCertificate")
  external X509Certificate? get peerCertificate;

  @pragma("vm:external-name", "SecureSocket_RegisterBadCertificateCallback")
  external void _registerBadCertificateCallback(Function callback);

  Function? badCertificateCallback;

  void registerBadCertificateCallback(Function callback) {
    badCertificateCallback = callback;
    _registerBadCertificateCallback(callback);
  }

  @pragma("vm:external-name", "SecureSocket_RegisterHandshakeCompleteCallback")
  external void registerHandshakeCompleteCallback(
      Function handshakeCompleteHandler);

  @pragma("vm:external-name", "SecureSocket_RegisterKeyLogPort")
  external void registerKeyLogPort(SendPort port);

  // This is a security issue, as it exposes a raw pointer to Dart code.
  @pragma("vm:external-name", "SecureSocket_FilterPointer")
  external int _pointer();

  @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();
    }
  }

  @pragma("vm:external-name", "SecurityContext_Allocate")
  external void _createNativeContext();

  static final SecurityContext defaultContext = new _SecurityContext(true);

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

  @pragma("vm:external-name", "SecurityContext_UsePrivateKeyBytes")
  external void usePrivateKeyBytes(List<int> keyBytes, {String? password});

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

  @pragma("vm:external-name", "SecurityContext_SetTrustedCertificatesBytes")
  external void setTrustedCertificatesBytes(List<int> certBytes,
      {String? password});

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

  @pragma("vm:external-name", "SecurityContext_UseCertificateChainBytes")
  external void useCertificateChainBytes(List<int> chainBytes,
      {String? password});

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

  @pragma("vm:external-name", "SecurityContext_SetClientAuthoritiesBytes")
  external void setClientAuthoritiesBytes(List<int> authCertBytes,
      {String? password});

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

  @pragma("vm:external-name", "SecurityContext_SetAlpnProtocols")
  external void _setAlpnProtocols(Uint8List protocols, bool isServer);
  @pragma("vm:external-name", "SecurityContext_TrustBuiltinRoots")
  external void _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 WrappedX509Certificate in security_context.cc.
  _X509CertificateImpl._();

  @pragma("vm:external-name", "X509_Der")
  external Uint8List get _der;
  late final Uint8List der = _der;

  @pragma("vm:external-name", "X509_Pem")
  external String get _pem;
  late final String pem = _pem;

  @pragma("vm:external-name", "X509_Sha1")
  external Uint8List get _sha1;
  late final Uint8List sha1 = _sha1;

  @pragma("vm:external-name", "X509_Subject")
  external String get subject;
  @pragma("vm:external-name", "X509_Issuer")
  external String get issuer;
  DateTime get startValidity {
    return new DateTime.fromMillisecondsSinceEpoch(_startValidity(),
        isUtc: true);
  }

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

  @pragma("vm:external-name", "X509_StartValidity")
  external int _startValidity();
  @pragma("vm:external-name", "X509_EndValidity")
  external int _endValidity();
}
