Skip to content

Commit

Permalink
more verbose errors
Browse files Browse the repository at this point in the history
  • Loading branch information
mulev committed Aug 9, 2017
1 parent d4247a3 commit ab98d68
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 17 deletions.
6 changes: 5 additions & 1 deletion lib/alexa_ruby/request/base_request/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ def initialize(cert_chain_url, signature, request, timestamp_diff = nil)
#
# @return [Boolean]
def valid_request?
raise ArgumentError, 'Outdated request' unless timestamp_tolerant?
unless timestamp_tolerant?
raise ArgumentError,
'Outdated request: request timestamp is more than ' \
"#{@timestamp_diff} seconds later than current time"
end
valid_uri? && valid_certificates?
end

Expand Down
26 changes: 19 additions & 7 deletions lib/alexa_ruby/request/base_request/validator/certificates.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ def initialize(certificates_chain_url, signature, request)
#
# @return [Boolean]
def valid?
raise ArgumentError, 'Inactive Amazon SSL certificate' unless active?
raise ArgumentError, 'Inactive host in SSL certificate' unless amazon?
raise ArgumentError, 'Signature and request mismatch' unless verified?
true
active? && amazon? && verified?
end

private
Expand All @@ -42,14 +39,24 @@ def download_certificates(certificates_chain_url)
# @return [Boolean]
def active?
now = Time.now
@cert.not_before < now && @cert.not_after > now
(@cert.not_before < now && @cert.not_after > now) ||
raise(
ArgumentError,
'Amazon SSL certificate is outdated ' \
"specified dates: #{@cert.not_before} - #{@cert.not_after}"
)
end

# Check if Subject Alternative Names includes Amazon domain name
#
# @return [Boolean]
def amazon?
@cert.subject.to_a.flatten.include? 'echo-api.amazon.com'
@cert.subject.to_a.flatten.include?('echo-api.amazon.com') ||
raise(
ArgumentError,
'Certificate must be issued for "echo-api.amazon.com" ' \
"(given certificate subject: #{@cert.subject.to_a})"
)
end

# Check if given signature matches given request
Expand All @@ -58,7 +65,12 @@ def amazon?
def verified?
sign = decode_signature
pkey = public_key
pkey.verify(hash, sign, @request)
pkey.verify(hash, sign, @request) ||
raise(
ArgumentError,
'Given request signature does not match with request SHA1 hash ' \
"(signature: #{sign})"
)
end

# Decode base64-encoded signature
Expand Down
34 changes: 25 additions & 9 deletions lib/alexa_ruby/request/base_request/validator/uri.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@ def initialize(uri)
#
# @return [Boolean]
def valid?
raise ArgumentError, 'Certificates chain URL must be HTTPS' unless https?
raise ArgumentError, 'Not Amazon host in certificates URL' unless amazon?
raise ArgumentError, 'Invalid certificates chain URL' unless echo_api?
raise ArgumentError, 'Certificates chain URL must be HTTPS' unless port?
true
https? && amazon? && echo_api? && port?
end

private
Expand All @@ -27,28 +23,48 @@ def valid?
#
# @return [Boolean]
def https?
@uri.scheme == 'https'
@uri.scheme == 'https' ||
raise(
ArgumentError,
'Certificates chain URL must be an HTTPS-enabled endpoint ' \
"(current endpoint: #{@uri})"
)
end

# Check if URI host is a valid Amazon host
#
# @return [Boolean]
def amazon?
@uri.host.casecmp('s3.amazonaws.com').zero?
@uri.host.casecmp('s3.amazonaws.com').zero? ||
raise(
ArgumentError,
'Certificates chain host must be equal to "s3.amazonaws.com" ' \
"(current host: #{@uri.host})"
)
end

# Check if URI path starts with /echo.api/
#
# @return [Boolean]
def echo_api?
@uri.path[0..9] == '/echo.api/'
@uri.path[0..9] == '/echo.api/' ||
raise(
ArgumentError,
'Certificates chain URL path must start with "/echo.api/" ' \
"(current path: #{@uri.path})"
)
end

# Check if URI port is 443 if port is present
#
# @return [Boolean]
def port?
@uri.port.nil? || @uri.port == 443
@uri.port.nil? || @uri.port == 443 ||
raise(
ArgumentError,
'If certificates chain URL has a port specified, it must be 443 ' \
"(current port: #{@uri.port})"
)
end
end
end

0 comments on commit ab98d68

Please sign in to comment.