// Copyright (c) 2015, 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;

/**
 * The object containing the certificates to trust when making
 * a secure client connection, and the certificate chain and
 * private key to serve from a secure server.
 *
 * The [SecureSocket]  and [SecureServerSocket] classes take a SecurityContext
 * as an argument to their connect and bind methods.
 *
 * Certificates and keys can be added to a SecurityContext from either PEM
 * or PKCS12 containers.
 *
 * iOS note: Some methods to add, remove, and inspect certificates are not yet
 * implemented. However, the platform's built-in trusted certificates can
 * be used, by way of [SecurityContext.defaultContext].
 */
abstract class SecurityContext {
  /**
   * Creates a new [SecurityContext].
   *
   * By default, the created [SecurityContext] contains no keys or certificates.
   * These can be added by calling the methods of this class.
   *
   * If `withTrustedRoots` is passed as `true`, the [SecurityContext] will be
   * seeded by the trusted root certificates provided as explained below. To
   * obtain a [SecurityContext] containing trusted root certificates,
   * [SecurityContext.defaultContext] is usually sufficient, and should
   * be used instead. However, if the [SecurityContext] containing the trusted
   * root certificates must be modified per-connection, then `withTrustedRoots`
   * should be used.
   */
  external factory SecurityContext({bool withTrustedRoots: false});

  /**
   * Secure networking classes with an optional `context` parameter
   * use the [defaultContext] object if the parameter is omitted.
   * This object can also be accessed, and modified, directly.
   * Each isolate has a different [defaultContext] object.
   * The [defaultContext] object uses a list of well-known trusted
   * certificate authorities as its trusted roots. On Linux and Windows, this
   * list is taken from Mozilla, who maintains it as part of Firefox. On,
   * MacOS, iOS, and Android, this list comes from the trusted certificates
   * stores built in to the platforms.
   */
  external static SecurityContext get defaultContext;

  /**
   * Sets the private key for a server certificate or client certificate.
   *
   * A secure connection using this SecurityContext will use this key with
   * the server or client certificate to sign and decrypt messages.
   * [file] is the path to a PEM or PKCS12 file containing an encrypted
   * private key, encrypted with [password]. Assuming it is well-formatted, all
   * other contents of [file] are ignored. An unencrypted file can be used,
   * but this is not usual.
   *
   * NB: This function calls [File.readAsBytesSync], and will block on file IO.
   * Prefer using [usePrivateKeyBytes].
   *
   * iOS note: Only PKCS12 data is supported. It should contain both the private
   * key and the certificate chain. On iOS one call to [usePrivateKey] with this
   * data is used instead of two calls to [useCertificateChain] and
   * [usePrivateKey].
   */
  void usePrivateKey(String file, {String password});

  /**
   * Sets the private key for a server certificate or client certificate.
   *
   * Like [usePrivateKey], but takes the contents of the file as a list
   * of bytes.
   */
  void usePrivateKeyBytes(List<int> keyBytes, {String password});

  /**
   * Sets the set of trusted X509 certificates used by [SecureSocket]
   * client connections, when connecting to a secure server.
   *
   * [file] is the path to a PEM or PKCS12 file containing X509 certificates,
   * usually root certificates from certificate authorities. For PKCS12 files,
   * [password] is the password for the file. For PEM files, [password] is
   * ignored. Assuming it is well-formatted, all other contents of [file] are
   * ignored.
   *
   * NB: This function calls [File.readAsBytesSync], and will block on file IO.
   * Prefer using [setTrustedCertificatesBytes].
   *
   * iOS note: On iOS, this call takes only the bytes for a single DER
   * encoded X509 certificate. It may be called multiple times to add
   * multiple trusted certificates to the context. A DER encoded certificate
   * can be obtained from a PEM encoded certificate by using the openssl tool:
   *
   *   $ openssl x509 -outform der -in cert.pem -out cert.der
   */
  void setTrustedCertificates(String file, {String password});

  /**
   * Sets the set of trusted X509 certificates used by [SecureSocket]
   * client connections, when connecting to a secure server.
   *
   * Like [setTrustedCertificates] but takes the contents of the file.
   */
  void setTrustedCertificatesBytes(List<int> certBytes, {String password});

  /**
   * Sets the chain of X509 certificates served by [SecureServerSocket]
   * when making secure connections, including the server certificate.
   *
   * [file] is a PEM or PKCS12 file containing X509 certificates, starting with
   * the root authority and intermediate authorities forming the signed
   * chain to the server certificate, and ending with the server certificate.
   * The private key for the server certificate is set by [usePrivateKey]. For
   * PKCS12 files, [password] is the password for the file. For PEM files,
   * [password] is ignored. Assuming it is well-formatted, all
   * other contents of [file] are ignored.
   *
   * NB: This function calls [File.readAsBytesSync], and will block on file IO.
   * Prefer using [useCertificateChainBytes].
   *
   * iOS note: As noted above, [usePrivateKey] does the job of both
   * that call and this one. On iOS, this call is a no-op.
   */
  void useCertificateChain(String file, {String password});

  /**
   * Sets the chain of X509 certificates served by [SecureServerSocket]
   * when making secure connections, including the server certificate.
   *
   * Like [useCertificateChain] but takes the contents of the file.
   */
  void useCertificateChainBytes(List<int> chainBytes, {String password});

  /**
   * Sets the list of authority names that a [SecureServerSocket] will advertise
   * as accepted when requesting a client certificate from a connecting
   * client.
   *
   * [file] is a PEM or PKCS12 file containing the accepted signing
   * authority certificates - the authority names are extracted from the
   * certificates. For PKCS12 files, [password] is the password for the file.
   * For PEM files, [password] is ignored. Assuming it is well-formatted, all
   * other contents of [file] are ignored.
   *
   * NB: This function calls [File.readAsBytesSync], and will block on file IO.
   * Prefer using [setClientAuthoritiesBytes].
   *
   * iOS note: This call is not supported.
   */
  void setClientAuthorities(String file, {String password});

  /**
   * Sets the list of authority names that a [SecureServerSocket] will advertise
   * as accepted, when requesting a client certificate from a connecting
   * client.
   *
   * Like [setClientAuthorities] but takes the contents of the file.
   */
  void setClientAuthoritiesBytes(List<int> authCertBytes, {String password});

  /**
   * Whether the platform supports ALPN. This always returns true and will be
   * removed in a future release.
   */
  @deprecated
  external static bool get alpnSupported;

  /**
   * Sets the list of application-level protocols supported by a client
   * connection or server connection. The ALPN (application level protocol
   * negotiation) extension to TLS allows a client to send a list of
   * protocols in the TLS client hello message, and the server to pick
   * one and send the selected one back in its server hello message.
   *
   * Separate lists of protocols can be sent for client connections and
   * for server connections, using the same SecurityContext.  The [isServer]
   * boolean argument specifies whether to set the list for server connections
   * or client connections.
   */
  void setAlpnProtocols(List<String> protocols, bool isServer);

  /// Encodes a set of supported protocols for ALPN/NPN usage.
  ///
  /// The `protocols` list is expected to contain protocols in descending order
  /// of preference.
  ///
  /// See RFC 7301 (https://tools.ietf.org/html/rfc7301) for the encoding of
  /// `List<String> protocols`:
  ///     opaque ProtocolName<1..2^8-1>;
  ///
  ///     struct {
  ///         ProtocolName protocol_name_list<2..2^16-1>
  ///     } ProtocolNameList;
  ///
  /// The encoding of the opaque `ProtocolName<lower..upper>` vector is
  /// described in RFC 2246: 4.3 Vectors.
  ///
  /// Note: Even though this encoding scheme would allow a total
  /// `ProtocolNameList` length of 65535, this limit cannot be reached. Testing
  /// showed that more than ~ 2^14  bytes will fail to negotiate a protocol.
  /// We will be conservative and support only messages up to (1<<13)-1 bytes.
  static Uint8List _protocolsToLengthEncoding(List<String> protocols) {
    if (protocols == null || protocols.length == 0) {
      return new Uint8List(0);
    }
    int protocolsLength = protocols.length;

    // Calculate the number of bytes we will need if it is ASCII.
    int expectedLength = protocolsLength;
    for (int i = 0; i < protocolsLength; i++) {
      int length = protocols[i].length;
      if (length > 0 && length <= 255) {
        expectedLength += length;
      } else {
        throw new ArgumentError(
            'Length of protocol must be between 1 and 255 (was: $length).');
      }
    }

    if (expectedLength >= (1 << 13)) {
      throw new ArgumentError(
          'The maximum message length supported is 2^13-1.');
    }

    // Try encoding the `List<String> protocols` array using fast ASCII path.
    var bytes = new Uint8List(expectedLength);
    int bytesOffset = 0;
    for (int i = 0; i < protocolsLength; i++) {
      String proto = protocols[i];

      // Add length byte.
      bytes[bytesOffset++] = proto.length;
      int bits = 0;

      // Add protocol bytes.
      for (int j = 0; j < proto.length; j++) {
        var char = proto.codeUnitAt(j);
        bits |= char;
        bytes[bytesOffset++] = char & 0xff;
      }

      // Go slow case if we have encountered anything non-ascii.
      if (bits > 0x7f) {
        return _protocolsToLengthEncodingNonAsciiBailout(protocols);
      }
    }
    return bytes;
  }

  static Uint8List _protocolsToLengthEncodingNonAsciiBailout(
      List<String> protocols) {
    void addProtocol(List<int> outBytes, String protocol) {
      var protocolBytes = utf8.encode(protocol);
      var len = protocolBytes.length;

      if (len > 255) {
        throw new ArgumentError(
            'Length of protocol must be between 1 and 255 (was: $len)');
      }
      // Add length byte.
      outBytes.add(len);

      // Add protocol bytes.
      outBytes.addAll(protocolBytes);
    }

    List<int> bytes = [];
    for (var i = 0; i < protocols.length; i++) {
      addProtocol(bytes, protocols[i]);
    }

    if (bytes.length >= (1 << 13)) {
      throw new ArgumentError(
          'The maximum message length supported is 2^13-1.');
    }

    return new Uint8List.fromList(bytes);
  }
}
