Skip to content

Commit

Permalink
dangeroud lints
Browse files Browse the repository at this point in the history
  • Loading branch information
Eoin Power-Moran committed May 8, 2024
1 parent 4edd589 commit 844bc08
Show file tree
Hide file tree
Showing 30 changed files with 153 additions and 94 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

source 'https://rubygems.org'

# Specify your gem's dependencies in evervault.gemspec
Expand Down
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'bundler/gem_tasks'
require 'rspec/core/rake_task'

Expand Down
2 changes: 1 addition & 1 deletion bin/console
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require 'dotenv'
Dotenv.load
Expand All @@ -14,5 +15,4 @@ require 'pry'
# require "pry"
# Pry.start

require 'pry'
Pry.start
2 changes: 2 additions & 0 deletions evervault.gemspec
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require_relative 'lib/evervault/version'

Gem::Specification.new do |spec|
Expand Down
78 changes: 38 additions & 40 deletions lib/evervault/crypto/client.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require_relative '../errors/errors'
require_relative 'curves/p256'
require_relative 'curves/koblitz'
Expand Down Expand Up @@ -25,43 +27,16 @@ def initialize(request_handler:, config: ::Evervault::Config.new)

def encrypt(data, role = nil)
if data.nil? || (data.instance_of?(String) && data.empty?)
raise Evervault::Errors::EvervaultError.new(
'Data is required for encryption'
)
raise Evervault::Errors::EvervaultError, 'Data is required for encryption'
end

unless encryptable_data?(data) || data.instance_of?(Hash) || data.instance_of?(Array)
raise Evervault::Errors::EvervaultError.new(
"Encryption is not supported for #{data.class}"
)
raise Evervault::Errors::EvervaultError, "Encryption is not supported for #{data.class}"
end

traverse_and_encrypt(data, role)
end

private def encrypt_string(data_to_encrypt, role)
cipher = OpenSSL::Cipher.new('aes-256-gcm').encrypt

shared_key = generate_shared_key
cipher.key = shared_key

iv = cipher.random_iv
cipher.iv = iv

cipher.auth_data = Base64.strict_decode64(@team_key)

metadata = generate_metadata(role)
metadata_offset = [metadata.length].pack('v') # 'v' specifies 16-bit unsigned little-endian
payload = metadata_offset + metadata + data_to_encrypt.to_s

encrypted_data = cipher.update(payload.to_s) + cipher.final + cipher.auth_tag

ephemeral_key_compressed_string = @ephemeral_public_key.to_octet_string(:compressed)

format(header_type(data_to_encrypt), Base64.strict_encode64(iv),
Base64.strict_encode64(ephemeral_key_compressed_string), Base64.strict_encode64(encrypted_data))
end

def generate_metadata(role)
buffer = []

Expand Down Expand Up @@ -93,7 +68,32 @@ def generate_metadata(role)
buffer.pack('C*')
end

private def traverse_and_encrypt(data, role)
private

def encrypt_string(data_to_encrypt, role)
cipher = OpenSSL::Cipher.new('aes-256-gcm').encrypt

shared_key = generate_shared_key
cipher.key = shared_key

iv = cipher.random_iv
cipher.iv = iv

cipher.auth_data = Base64.strict_decode64(@team_key)

metadata = generate_metadata(role)
metadata_offset = [metadata.length].pack('v') # 'v' specifies 16-bit unsigned little-endian
payload = metadata_offset + metadata + data_to_encrypt.to_s

encrypted_data = cipher.update(payload.to_s) + cipher.final + cipher.auth_tag

ephemeral_key_compressed_string = @ephemeral_public_key.to_octet_string(:compressed)

format(header_type(data_to_encrypt), Base64.strict_encode64(iv),
Base64.strict_encode64(ephemeral_key_compressed_string), Base64.strict_encode64(encrypted_data))
end

def traverse_and_encrypt(data, role)
if encryptable_data?(data)
return encrypt_string(data, role)
elsif data.instance_of?(Hash)
Expand All @@ -104,20 +104,18 @@ def generate_metadata(role)
encrypted_data = data.map { |value| traverse_and_encrypt(value, role) }
return encrypted_data
else
raise Evervault::Errors::EvervaultError.new(
"Encryption is not supported for #{data.class}"
)
raise Evervault::Errors::EvervaultError, "Encryption is not supported for #{data.class}"
end

data
end

private def encryptable_data?(data)
def encryptable_data?(data)
data.instance_of?(String) || [true, false].include?(data) ||
data.instance_of?(Integer) || data.instance_of?(Float)
data.instance_of?(Integer) || data.instance_of?(Float)
end

private def generate_shared_key
def generate_shared_key
ec = OpenSSL::PKey::EC.generate(config.curve)
@ephemeral_public_key = ec.public_key

Expand All @@ -138,19 +136,19 @@ def generate_metadata(role)
hash.digest(hash_input)
end

private def format(datatype, iv, team_key, encrypted_data)
def format(datatype, iv, team_key, encrypted_data)
"ev:#{@ev_version}#{
datatype != 'string' ? ':' + datatype : ''
datatype != 'string' ? ":#{datatype}" : ''
}:#{base_64_remove_padding(iv)}:#{base_64_remove_padding(
team_key
)}:#{base_64_remove_padding(encrypted_data)}:$"
end

private def base_64_remove_padding(str)
def base_64_remove_padding(str)
str.gsub(/={1,2}$/, '')
end

private def header_type(data)
def header_type(data)
if data.instance_of?(Array)
'Array'
elsif [true, false].include?(data)
Expand Down
6 changes: 5 additions & 1 deletion lib/evervault/crypto/curves/base.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'openssl'

module Evervault
Expand All @@ -11,7 +13,9 @@ def encode(decompressed_key:)
@asn1Encoder.call(decompressed_key)
end

private def buildEncoder(curve_values:)
private

def buildEncoder(curve_values:)
a = OpenSSL::ASN1::OctetString.new([curve_values::A].pack('H*'))
b = OpenSSL::ASN1::OctetString.new([curve_values::B].pack('H*'))
if !curve_values::SEED.nil?
Expand Down
2 changes: 2 additions & 0 deletions lib/evervault/crypto/curves/koblitz.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require_relative 'base'

module KOBLITZ_CONSTANTS
Expand Down
2 changes: 2 additions & 0 deletions lib/evervault/crypto/curves/p256.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require_relative 'base'

# https://neuromancer.sk/std/x962/prime256v1
Expand Down
19 changes: 11 additions & 8 deletions lib/evervault/errors/error_map.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require_relative 'errors'

module Evervault
Expand All @@ -8,20 +10,21 @@ def self.raise_errors_on_failure(_status_code, body, _headers)
code = parsed_body['code']
detail = parsed_body['detail']

if code == 'functions/request-timeout'
raise FunctionTimeoutError.new(detail)
elsif code == 'functions/function-not-ready'
raise FunctionNotReadyError.new(detail)
elsif code == 'functions/forbidden-ip'
raise ForbiddenIPError.new(detail)
case code
when 'functions/request-timeout'
raise FunctionTimeoutError, detail
when 'functions/function-not-ready'
raise FunctionNotReadyError, detail
when 'functions/forbidden-ip'
raise ForbiddenIPError, detail
else
raise EvervaultError.new(detail)
raise EvervaultError, detail
end
end

def self.raise_function_error_on_failure(body)
error = body['error']
raise EvervaultError.new('An unexpected error occurred. Please contact Evervault support') unless error
raise EvervaultError, 'An unexpected error occurred. Please contact Evervault support' unless error

message = error['message']
stack = error['stack']
Expand Down
4 changes: 3 additions & 1 deletion lib/evervault/errors/errors.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Evervault
module Errors
class EvervaultError < StandardError; end
Expand All @@ -17,7 +19,7 @@ def initialize(message, stack, id)
@message = message
@stack = stack
@id = id
super("#{message}")
super(message.to_s)
end
end
end
Expand Down
26 changes: 14 additions & 12 deletions lib/evervault/errors/legacy_error_map.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require_relative 'errors'

module Evervault
Expand All @@ -8,32 +10,32 @@ def self.raise_errors_on_failure(status_code, body, headers)

case status_code
when 404
raise EvervaultError.new('Resource not found')
raise EvervaultError, 'Resource not found'
when 400
raise EvervaultError.new('Bad request')
raise EvervaultError, 'Bad request'
when 401
raise EvervaultError.new('Unauthorized')
raise EvervaultError, 'Unauthorized'
when 403
if (headers.include? 'x-evervault-error-code') && (headers['x-evervault-error-code'] == 'forbidden-ip-error')
raise ForbiddenIPError.new('IP is not present in Cage whitelist')
raise ForbiddenIPError, 'IP is not present in Cage whitelist'
end

raise EvervaultError.new('Forbidden')
raise EvervaultError, 'Forbidden'

when 500
raise EvervaultError.new('Server error')
raise EvervaultError, 'Server error'
when 502
raise EvervaultError.new('Bad gateway error')
raise EvervaultError, 'Bad gateway error'
when 503
raise EvervaultError.new('Service unavailable')
raise EvervaultError, 'Service unavailable'
else
raise EvervaultError.new(
message_for_unexpected_error_without_type(body)
)
raise EvervaultError, message_for_unexpected_error_without_type(body)
end
end

private def message_for_unexpected_error_without_type(error_details)
private

def message_for_unexpected_error_without_type(error_details)
if error_details.nil?
return(
'An unexpected error occurred without message or status code. Please contact Evervault support'
Expand Down
8 changes: 6 additions & 2 deletions lib/evervault/http/relay_outbound_config.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Evervault
module Http
class RelayOutboundConfig
Expand Down Expand Up @@ -32,7 +34,9 @@ def self.clear_cache
@@destination_domains_cache = nil
end

private def get_relay_outbound_config
private

def get_relay_outbound_config
resp = @request.execute(:get, "#{@base_url}#{RELAY_OUTBOUND_CONFIG_API_ENDPOINT}")
poll_interval = resp.headers['x-poll-interval']
update_poll_interval(poll_interval.to_f) unless poll_interval.nil?
Expand All @@ -42,7 +46,7 @@ def self.clear_cache
end
end

private def update_poll_interval(poll_interval)
def update_poll_interval(poll_interval)
@@poll_interval = poll_interval
return if @@timer.nil?

Expand Down
2 changes: 2 additions & 0 deletions lib/evervault/http/request.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'faraday'
require 'json'
require_relative '../version'
Expand Down
8 changes: 6 additions & 2 deletions lib/evervault/http/request_handler.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'faraday'
require 'json'
require_relative '../version'
Expand Down Expand Up @@ -38,11 +40,13 @@ def post(path, body, basic_auth = false, error_map = Evervault::Errors::LegacyEr
parse_json_body(resp.body) unless resp.body.empty?
end

private def parse_json_body(body)
private

def parse_json_body(body)
JSON.parse(body)
end

private def build_url(path)
def build_url(path)
"#{config.base_url}#{path}"
end
end
Expand Down
9 changes: 6 additions & 3 deletions lib/evervault/http/request_intercept.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'faraday'
require 'json'
require 'tempfile'
Expand Down Expand Up @@ -38,7 +40,7 @@ def self.should_decrypt(domain)
decryption_domains = @@get_decryption_domains_func.call
decryption_domains.any? do |decryption_domain|
if decryption_domain.start_with?('*')
domain.end_with?(decryption_domain[1..-1])
domain.end_with?(decryption_domain[1..])
else
domain == decryption_domain
end
Expand Down Expand Up @@ -125,7 +127,8 @@ def get_cert
end

if !ca_content || ca_content == ''
raise Evervault::Errors::EvervaultError.new("Unable to install the Evervault root certificate from #{config.ca_host}")
raise Evervault::Errors::EvervaultError,
"Unable to install the Evervault root certificate from #{config.ca_host}"
end

cert = OpenSSL::X509::Certificate.new ca_content
Expand All @@ -136,7 +139,7 @@ def get_cert
def set_cert_expire_date(cert)
@expire_date = cert.not_after
@initial_date = cert.not_before
rescue StandardError => e
rescue StandardError
@expire_date = nil
end
end
Expand Down
4 changes: 3 additions & 1 deletion lib/evervault/threading/repeated_timer.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Evervault
module Threading
class RepeatedTimer
Expand All @@ -16,7 +18,7 @@ def start
sleep @interval
begin
@func.call
rescue StandardError => e
rescue StandardError
# Silently ignore exceptions
end
end
Expand Down
Loading

0 comments on commit 844bc08

Please sign in to comment.