require 'openssl'

class SSL
  def initialize; end

  def generate_cert
    key = generate_keypair(2048)
    name = OpenSSL::X509::Name.parse('/CN=nobody/DC=example')

    cert = OpenSSL::X509::Certificate.new
    cert.version = 2
    cert.serial = 0
    cert.not_before = Time.now
    cert.not_after = Time.now + 3600
    cert.public_key = key.public_key
    cert.subject = name
    [cert, name, key]
  end

  def generate_keypair(size)
    key = generate_key(size)
    open 'private_key.pem', 'w' do |io| io.write key.to_pem end
    open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
    key
  end

  def generate_key(size)
    OpenSSL::PKey::RSA.new size
  end

  def load_key(path, passphrase = nil)
    if passphrase
      OpenSSL::PKey::RSA.new(File.read(path), passphrase)
    else
      OpenSSL::PKey::RSA.new(File.read(path))
    end
  end

  # sign cert generated from generate_cert method.
  # cert, name, key = generate_cert
  def self_sign_key(cert, name, key)
    cert.issuer = name
    cert.sign key, OpenSSL::Digest.new('SHA1')
    open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
  end

  def new_ssl_context(cert, key)
    context = OpenSSL::SSL::SSLContext.new
    context.cert = cert
    context.key = key
    context
  end

  def load_cert(path)
    OpenSSL::X509::Certificate.new File.read path
  end
end