// 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.

// OtherResources=certificates/server_chain.pem
// OtherResources=certificates/server_key.pem
// OtherResources=certificates/trusted_certs.pem
// OtherResources=certificates/client_authority.pem
// OtherResources=certificates/client1.pem
// OtherResources=certificates/client1_key.pem
// OtherResources=certificates/server_chain.p12
// OtherResources=certificates/server_key.p12
// OtherResources=certificates/trusted_certs.p12
// OtherResources=certificates/client_authority.p12
// OtherResources=certificates/client1.p12
// OtherResources=certificates/client1_key.p12

import "dart:async";
import "dart:io";

import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";

late InternetAddress HOST;

String localFile(path) => Platform.script.resolve(path).toFilePath();

SecurityContext serverContext(String certType, String password) =>
    new SecurityContext()
      ..useCertificateChain(localFile('certificates/server_chain.$certType'),
          password: password)
      ..usePrivateKey(localFile('certificates/server_key.$certType'),
          password: password)
      ..setTrustedCertificates(
          localFile('certificates/client_authority.$certType'),
          password: password)
      ..setClientAuthorities(
          localFile('certificates/client_authority.$certType'),
          password: password);

SecurityContext clientCertContext(String certType, String password) =>
    new SecurityContext()
      ..setTrustedCertificates(
          localFile('certificates/trusted_certs.$certType'),
          password: password)
      ..useCertificateChain(localFile('certificates/client1.$certType'),
          password: password)
      ..usePrivateKey(localFile('certificates/client1_key.$certType'),
          password: password);

SecurityContext clientNoCertContext(String certType, String password) =>
    new SecurityContext()
      ..setTrustedCertificates(
          localFile('certificates/trusted_certs.$certType'),
          password: password);

Future testClientCertificate(
    {required bool required,
    required bool sendCert,
    required String certType,
    required String password}) async {
  var server = await SecureServerSocket.bind(
      HOST, 0, serverContext(certType, password),
      requestClientCertificate: true, requireClientCertificate: required);
  var clientContext = sendCert
      ? clientCertContext(certType, password)
      : clientNoCertContext(certType, password);
  var clientEndFuture =
      SecureSocket.connect(HOST, server.port, context: clientContext);
  if (required && !sendCert) {
    final serverErrorCompleter = Completer<Exception>();
    server.listen((request) {
      Expect.fail('Should not get a request through');
    }, onError: (e) => serverErrorCompleter.complete(e));

    final clientDisconnected = Completer();
    final clientEnd = await clientEndFuture;
    clientEnd.write(<int>[5, 6, 7, 8]);
    clientEnd.close();
    clientEnd.listen((data) {
      Expect.fail('Should not get data through');
    }, onError: (e) {
      Expect.isTrue(e is SocketException);
    }, onDone: () {
      clientDisconnected.complete();
    });
    Expect.isTrue(await serverErrorCompleter.future is HandshakeException);
    // Client might not report an error, might get just disconnected.
    await clientDisconnected.future;
    server.close();
    return;
  }
  var serverEnd = await server.first;
  var clientEnd = await clientEndFuture;

  X509Certificate? clientCertificate = serverEnd.peerCertificate;
  if (sendCert) {
    Expect.isNotNull(clientCertificate);
    Expect.isTrue(clientCertificate!.subject.contains("user1"));
    Expect.isTrue(clientCertificate.issuer.contains("clientauthority"));
  } else {
    Expect.isNull(clientCertificate);
  }
  X509Certificate serverCertificate = clientEnd.peerCertificate!;
  Expect.isTrue(serverCertificate.subject.contains("localhost"));
  Expect.isTrue(serverCertificate.issuer.contains("intermediateauthority"));
  clientEnd.close();
  serverEnd.close();
}

main() async {
  asyncStart();
  HOST = (await InternetAddress.lookup("localhost")).first;
  await testClientCertificate(
      required: false, sendCert: true, certType: 'pem', password: 'dartdart');
  await testClientCertificate(
      required: true, sendCert: true, certType: 'pem', password: 'dartdart');
  await testClientCertificate(
      required: false, sendCert: false, certType: 'pem', password: 'dartdart');
  await testClientCertificate(
      required: true, sendCert: false, certType: 'pem', password: 'dartdart');

  await testClientCertificate(
      required: false, sendCert: true, certType: 'p12', password: 'dartdart');
  await testClientCertificate(
      required: true, sendCert: true, certType: 'p12', password: 'dartdart');
  await testClientCertificate(
      required: false, sendCert: false, certType: 'p12', password: 'dartdart');
  await testClientCertificate(
      required: true, sendCert: false, certType: 'p12', password: 'dartdart');
  asyncEnd();
}
