thekuwayama/tttls1.3

View on GitHub
Rakefile

Summary

Maintainability
Test Coverage
# frozen_string_literal: true

require 'bundler/gem_tasks'
require 'rubocop/rake_task'
require 'rspec/core/rake_task'
require 'openssl'
require 'fileutils'

TMP_DIR    = __dir__ + '/tmp'
CA_KEY     = TMP_DIR + '/ca.key'
CA_CRT     = TMP_DIR + '/ca.crt'
INTER_KEY  = TMP_DIR + '/intermediate.key'
INTER_CRT  = TMP_DIR + '/intermediate.crt'
SERVER_KEY = TMP_DIR + '/server.key'
SERVER_CRT = TMP_DIR + '/server.crt'
certs = [CA_KEY, CA_CRT, INTER_KEY, INTER_CRT, SERVER_KEY, SERVER_CRT]

directory TMP_DIR

file CA_KEY => TMP_DIR do
  puts "generate #{CA_KEY}..."
  ca_key = OpenSSL::PKey::RSA.generate(2048)
  File.write(CA_KEY, ca_key.to_pem)
end

file CA_CRT => [TMP_DIR, CA_KEY] do
  ca_key = OpenSSL::PKey::RSA.new(File.read(CA_KEY))

  puts "generate #{CA_CRT}..."
  issu = sub = OpenSSL::X509::Name.new
  sub.add_entry('CN', 'test-ca')

  ca_crt = OpenSSL::X509::Certificate.new
  ca_crt.not_before = Time.now
  ca_crt.not_after = Time.now + (60 * 60 * 24 * 365 * 10)
  ca_crt.public_key = ca_key.public_key
  ca_crt.serial = OpenSSL::BN.rand(64)
  ca_crt.version = 2
  ca_crt.issuer = issu
  ca_crt.subject = sub

  factory = OpenSSL::X509::ExtensionFactory.new
  factory.subject_certificate = ca_crt
  factory.issuer_certificate = ca_crt
  ca_crt.add_extension(
    factory.create_extension(
      'keyUsage',
      'critical, cRLSign, keyCertSign'
    )
  )
  ca_crt.add_extension(
    factory.create_extension(
      'basicConstraints',
      'critical, CA:true'
    )
  )
  ca_crt.add_extension(
    factory.create_extension(
      'subjectKeyIdentifier',
      'hash'
    )
  )

  digest = OpenSSL::Digest::SHA256.new
  ca_crt.sign(ca_key, digest)
  File.write(CA_CRT, ca_crt.to_pem)
end

file INTER_KEY => TMP_DIR do
  puts "generate #{INTER_KEY}..."
  inter_key = OpenSSL::PKey::RSA.generate(2048)
  File.write(INTER_KEY, inter_key.to_pem)
end

file INTER_CRT => [TMP_DIR, INTER_KEY] do
  ca_key = OpenSSL::PKey::RSA.new(File.read(CA_KEY))
  ca_crt = OpenSSL::X509::Certificate.new(File.read(CA_CRT))
  inter_key = OpenSSL::PKey::RSA.new(File.read(INTER_KEY))

  puts "generate #{INTER_CRT}..."
  sub = OpenSSL::X509::Name.new
  sub.add_entry('CN', 'test-intermediate')

  inter_crt = OpenSSL::X509::Certificate.new
  inter_crt.not_before = Time.now
  inter_crt.not_after = Time.now + (60 * 60 * 24 * 365 * 10)
  inter_crt.public_key = inter_key.public_key
  inter_crt.serial = OpenSSL::BN.rand(64)
  inter_crt.version = 2
  inter_crt.issuer = ca_crt.subject
  inter_crt.subject = sub

  factory = OpenSSL::X509::ExtensionFactory.new
  factory.subject_certificate = inter_crt
  factory.issuer_certificate = ca_crt
  inter_crt.add_extension(
    factory.create_extension(
      'keyUsage',
      'critical, cRLSign, keyCertSign'
    )
  )
  inter_crt.add_extension(
    factory.create_extension(
      'basicConstraints',
      'critical, CA:true'
    )
  )
  inter_crt.add_extension(
    factory.create_extension(
      'subjectKeyIdentifier',
      'hash'
    )
  )

  digest = OpenSSL::Digest::SHA256.new
  inter_crt.sign(ca_key, digest)
  File.write(INTER_CRT, inter_crt.to_pem)
end

file SERVER_KEY => TMP_DIR do
  puts "generate #{SERVER_KEY}..."
  server_key = OpenSSL::PKey::RSA.generate(2048)
  File.write(SERVER_KEY, server_key.to_pem)
end

file SERVER_CRT => [TMP_DIR, INTER_CRT, SERVER_KEY] do
  inter_key = OpenSSL::PKey::RSA.new(File.read(INTER_KEY))
  inter_crt = OpenSSL::X509::Certificate.new(File.read(INTER_CRT))
  server_key = OpenSSL::PKey::RSA.new(File.read(SERVER_KEY))

  puts "generate #{SERVER_CRT}..."
  sub = OpenSSL::X509::Name.new
  sub.add_entry('CN', 'localhost')

  server_crt = OpenSSL::X509::Certificate.new
  server_crt.not_before = Time.now
  server_crt.not_after = Time.now + (60 * 60 * 24 * 365)
  server_crt.public_key = server_key.public_key
  server_crt.serial = OpenSSL::BN.rand(64)
  server_crt.version = 2
  server_crt.issuer = inter_crt.subject
  server_crt.subject = sub

  factory = OpenSSL::X509::ExtensionFactory.new
  factory.subject_certificate = server_crt
  factory.issuer_certificate = inter_crt
  server_crt.add_extension(
    factory.create_extension(
      'basicConstraints',
      'CA:FALSE'
    )
  )
  server_crt.add_extension(
    factory.create_extension(
      'keyUsage',
      'digitalSignature, keyEncipherment'
    )
  )
  server_crt.add_extension(
    factory.create_extension(
      'subjectAltName',
      'DNS:localhost'
    )
  )
  server_crt.add_extension(
    factory.create_extension(
      'authorityInfoAccess',
      'caIssuers;URI:http://localhost:8080,OCSP;URI:http://localhost:8080'
    )
  )

  digest = OpenSSL::Digest::SHA256.new
  server_crt.sign(inter_key, digest)
  File.write(SERVER_CRT, server_crt.to_pem)
end

desc 'generate ' + certs.map { |path| File.basename(path) }.join(', ')
task gen_certs: certs

desc 'delete ' + certs.map { |path| File.basename(path) }.join(', ')
task :del_certs do
  certs.each do |path|
    puts "delete #{path}..."
    FileUtils.rm(path, force: true)
  end
end

RuboCop::RakeTask.new
RSpec::Core::RakeTask.new(:spec)

desc 'interoperability test between openssl'
task interop: %i[interop:client interop:server]

namespace :interop do
  desc 'interoperability test: TTTLS13::Client'
  RSpec::Core::RakeTask.new(:client) do |t|
    t.pattern = Dir.glob('interop/client_spec.rb')
  end

  desc 'interoperability test: TTTLS13::Server'
  RSpec::Core::RakeTask.new(:server) do |t|
    t.pattern = Dir.glob('interop/server_spec.rb')
  end
end

task default: %i[rubocop spec]