# frozen_string_literal: true

# This file can be loaded by RubyGems test-unit files and Bundler rspec files.
# Don't add test-unit or rspec dependent logic in this file.

require "rubygems/openssl"

module Gem::PemUtilities
  ##
  # Loads certificate named +cert_name+ from <tt>test/rubygems/</tt>.

  def self.load_cert(cert_name)
    cert = File.read(cert_file(cert_name))
    OpenSSL::X509::Certificate.new cert
  end

  ##
  # Returns the file path to the certificate named +cert_name+ from
  # <tt>test/rubygems/</tt>.

  def self.cert_file(cert_name)
    if begin
         Time.at(2**32)
       rescue StandardError
         32
       end == 32
      cert_file = "#{__dir__}/#{cert_name}_cert_32.pem"

      return cert_file if File.exist? cert_file
    end

    "#{__dir__}/#{cert_name}_cert.pem"
  end

  ##
  # Loads a private key named +key_name+ with +passphrase+ in <tt>test/rubygems/</tt>

  def self.load_key(key_name, passphrase = nil)
    key = File.read(key_file(key_name))

    # Rescue if unsupported key algorithm's file is read with old OpenSSL versions.
    begin
      OpenSSL::PKey.read key, passphrase
    rescue OpenSSL::PKey::PKeyError
      nil
    end
  end

  ##
  # Returns the file path to the key named +key_name+ from <tt>test/rubygems</tt>

  def self.key_file(key_name)
    "#{__dir__}/#{key_name}_key.pem"
  end

  ##
  # Returns the file path to the PEM file named +pem_name+ from <tt>test/rubygems</tt>

  def self.pem_file(pem_name)
    "#{__dir__}/#{pem_name}.pem"
  end

  # :stopdoc:

  PRIVATE_KEY_PASSPHRASE = "Foo bar"

  if Gem::HAVE_OPENSSL
    # Only the key and certificate constants used in tests are managed here. Add
    # constants here when adding or using new .pem files. The constant naming
    # convention is <algorithm>_<name>.

    # Keys and certificates mostly generated by create_certs.sh
    # RSA CA
    CA_CERT                     = load_cert "ca"
    CA_CERT_FILE                = cert_file "ca"
    # RSA server
    SSL_KEY                     = load_key "ssl"
    SSL_KEY_FILE                = key_file "ssl"
    SSL_CERT                    = load_cert "ssl"
    SSL_CERT_FILE               = cert_file "ssl"
    # RSA client key/cert pair
    CLIENT_FILE                 = pem_file "client"
    # RSA invalid client manually created without script
    INVALID_CLIENT_FILE         = pem_file "invalid_client"
    # ML-DSA-65 CA
    MLDSA65_CA_CERT_FILE        = cert_file "mldsa65_ca"
    # ML-DSA-65 server
    MLDSA65_SSL_KEY             = load_key "mldsa65_ssl"
    MLDSA65_SSL_KEY_FILE        = key_file "mldsa65_ssl"
    MLDSA65_SSL_CERT            = load_cert "mldsa65_ssl"
    MLDSA65_SSL_CERT_FILE       = cert_file "mldsa65_ssl"
    # ML-DSA-65 client key/cert pair
    MLDSA65_CLIENT_FILE         = pem_file "mldsa65_client"

    # Keys and certificates generated by create_certs.rb
    PRIVATE_KEY                 = load_key "private"
    PRIVATE_KEY_FILE            = key_file "private"
    # ENCRYPTED_PRIVATE_KEY is PRIVATE_KEY encrypted with PRIVATE_KEY_PASSPHRASE
    ENCRYPTED_PRIVATE_KEY       = load_key "encrypted_private", PRIVATE_KEY_PASSPHRASE
    ENCRYPTED_PRIVATE_KEY_FILE  = key_file "encrypted_private"
    PUBLIC_KEY                  = PRIVATE_KEY.public_key
    PUBLIC_KEY_FILE             = key_file "public"
    PUBLIC_CERT                 = load_cert "public"
    PUBLIC_CERT_FILE            = cert_file "public"
    ALTERNATE_KEY               = load_key "alternate"
    ALTERNATE_KEY_FILE          = key_file "alternate"
    ALTERNATE_CERT              = load_cert "alternate"
    ALTERNATE_CERT_FILE         = cert_file "alternate"
    CHILD_KEY                   = load_key "child"
    CHILD_CERT                  = load_cert "child"
    CHILD_CERT_FILE             = cert_file "child"
    GRANDCHILD_CERT             = load_cert "grandchild"
    INVALID_ISSUER_CERT         = load_cert "invalid_issuer"
    INVALID_SIGNER_CERT         = load_cert "invalid_signer"
    INVALIDCHILD_CERT           = load_cert "invalidchild"
    EXPIRED_CERT                = load_cert "expired"
    EXPIRED_CERT_FILE           = cert_file "expired"
    FUTURE_CERT                 = load_cert "future"
    WRONG_KEY_CERT              = load_cert "wrong_key"

    # Keys and certificates manually created without script
    # RSA 3072 bits
    RSA3072_PRIVATE_KEY_FILE    = key_file "rsa3072_private"
    RSA3072_PUBLIC_CERT         = load_cert "rsa3072_public"
    RSA3072_PUBLIC_CERT_FILE    = cert_file "rsa3072_public"
    # EC
    EC_PRIVATE_KEY              = load_key "ec_private", PRIVATE_KEY_PASSPHRASE
    EC_PRIVATE_KEY_FILE         = key_file "ec_private"
  end
end
