thekuwayama/tttls1.3

View on GitHub
interop/client_spec.rb

Summary

Maintainability
A
0 mins
Test Coverage
# encoding: ascii-8bit
# frozen_string_literal: true

require_relative 'spec_helper'

FIXTURES_DIR = __dir__ + '/../spec/fixtures'
PORT = 14433

RSpec.describe Client do
  # normal [Boolean] Is this nominal scenarios?
  # opt [String] openssl s_server options
  # crt [String] server crt file path
  # key [String] server key file path
  # settings [Hash] TTTLS13::Server settings
  # rubocop: disable Layout/LineLength
  testcases = [
    [
      true,
      '-ciphersuites TLS_AES_256_GCM_SHA384',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      cipher_suites: [CipherSuite::TLS_AES_256_GCM_SHA384]
    ],
    [
      true,
      '-ciphersuites TLS_CHACHA20_POLY1305_SHA256',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      cipher_suites: [CipherSuite::TLS_CHACHA20_POLY1305_SHA256]
    ],
    [
      true,
      '-ciphersuites TLS_AES_128_GCM_SHA256',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      cipher_suites: [CipherSuite::TLS_AES_128_GCM_SHA256]
    ],
    [
      false,
      '-ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      cipher_suites: [CipherSuite::TLS_AES_128_GCM_SHA256]
    ],
    [
      true,
      '-groups P-256',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      supported_groups: [NamedGroup::SECP256R1]
    ],
    [
      true,
      '-groups P-384',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      supported_groups: [NamedGroup::SECP384R1]
    ],
    [
      true,
      '-groups P-521',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      supported_groups: [NamedGroup::SECP521R1]
    ],
    [
      false,
      '-groups P-256:P-384',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      supported_groups: [NamedGroup::SECP521R1]
    ],
    [
      true,
      '-sigalgs RSA-PSS+SHA256',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      signature_algorithms_cert: [SignatureScheme::RSA_PKCS1_SHA256],
      signature_algorithms: [SignatureScheme::RSA_PSS_RSAE_SHA256]
    ],
    [
      true,
      '-sigalgs RSA-PSS+SHA384',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      signature_algorithms_cert: [SignatureScheme::RSA_PKCS1_SHA256],
      signature_algorithms: [SignatureScheme::RSA_PSS_RSAE_SHA384]
    ],
    [
      true,
      '-sigalgs RSA-PSS+SHA512',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      signature_algorithms_cert: [SignatureScheme::RSA_PKCS1_SHA256],
      signature_algorithms: [SignatureScheme::RSA_PSS_RSAE_SHA512]
    ],
    [
      true,
      '-sigalgs ECDSA+SHA256',
      'rsa_secp256r1.crt',
      'rsa_secp256r1.key',
      signature_algorithms_cert: [SignatureScheme::RSA_PKCS1_SHA256],
      signature_algorithms: [SignatureScheme::ECDSA_SECP256R1_SHA256]
    ],
    [
      true,
      '-sigalgs ECDSA+SHA384',
      'rsa_secp384r1.crt',
      'rsa_secp384r1.key',
      signature_algorithms_cert: [SignatureScheme::RSA_PKCS1_SHA256],
      signature_algorithms: [SignatureScheme::ECDSA_SECP384R1_SHA384]
    ],
    [
      true,
      '-sigalgs ECDSA+SHA512',
      'rsa_secp521r1.crt',
      'rsa_secp521r1.key',
      signature_algorithms_cert: [SignatureScheme::RSA_PKCS1_SHA256],
      signature_algorithms: [SignatureScheme::ECDSA_SECP521R1_SHA512]
    ],
    [
      true,
      '-sigalgs RSA-PSS+SHA256',
      'rsa_rsassaPss.crt',
      'rsa_rsassaPss.key',
      signature_algorithms_cert: [SignatureScheme::RSA_PSS_RSAE_SHA256],
      signature_algorithms: [SignatureScheme::RSA_PSS_RSAE_SHA256]
    ],
    [
      false,
      '-sigalgs ECDSA+SHA256:ECDSA+SHA384:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256',
      'rsa_secp521r1.crt',
      'rsa_secp521r1.key',
      signature_algorithms_cert: [SignatureScheme::RSA_PKCS1_SHA256],
      signature_algorithms: [SignatureScheme::ECDSA_SECP521R1_SHA512]
    ],
    [
      true,
      '-record_padding 8446',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      {}
    ],
    [
      true,
      '',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      key_share_groups: []
    ],
    [
      true,
      '-alpn http/1.0',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      alpn: ['http/1.0']
    ],
    [
      true,
      '',
      'rsa_rsa.crt',
      'rsa_rsa.key',
      compatibility_mode: false
    ]
  ]
  # rubocop: enable Layout/LineLength
  testcases.each do |normal, opt, crt, key, settings|
    context 'client interop' do
      before do
        cmd = 'openssl s_server ' \
              + "-cert /tmp/#{crt} " \
              + "-key /tmp/#{key} " \
              + '-tls1_3 ' \
              + '-www ' \
              + '-quiet ' \
              + "-accept #{PORT} " \
              + opt
        pid = spawn('docker run ' \
                    + "--volume #{FIXTURES_DIR}:/tmp " \
                    + "--publish #{PORT}:#{PORT} " \
                    + 'thekuwayama/openssl ' + cmd)
        Process.detach(pid)

        wait_to_listen('127.0.0.1', PORT)
      end

      let(:client) do
        hostname = 'localhost'
        @socket = TCPSocket.new(hostname, PORT)
        settings[:ca_file] = FIXTURES_DIR + '/rsa_ca.crt'
        Client.new(@socket, hostname, **settings)
      end

      after do
        @socket.close
        `docker ps -ql | xargs docker stop`
      end

      if normal
        it "should connect with openssl s_server ...#{opt}" do
          expect { client.connect }.to_not raise_error
          expect { client.write("GET / HTTP/1.0\r\n\r\n") }.to_not raise_error
          expect(client.read).to include "HTTP/1.0 200 ok\r\n"
          expect { client.close }.to_not raise_error
        end
      else # exceptions scenarios
        it "should NOT connect with openssl s_server ...#{opt}" do
          expect { client.connect }.to raise_error ErrorAlerts
        end
      end
    end
  end
end