class Aws::SNS::MessageVerifier
A utility class that can be used to verify the authenticity of messages sent by Amazon SNS
.
verifier = Aws::SNS::MessageVerifier.new # returns true/false verifier.authentic?(message_body) # raises a Aws::SNS::MessageVerifier::VerificationError on failure verifier.authenticate!(message_body)
You can re-use a single {MessageVerifier} instance to authenticate multiple SNS
messages.
Constants
- AWS_HOSTNAMES
@api private
- SIGNABLE_KEYS
@api private
Public Class Methods
new()
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 42 def initialize @cached_pems = {} end
Public Instance Methods
authentic?(message_body)
click to toggle source
@param [String<JSON>] message_body @return [Boolean] Returns `true` if the given message has been
successfully verified. Returns `false` otherwise.
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 49 def authentic?(message_body) authenticate!(message_body) rescue VerificationError false end
authenticate!(message_body)
click to toggle source
@param [String<JSON>] message_body @return [Boolean] Returns `true` when the given message has been
successfully verified.
@raise [VerificationError] Raised when the given message has failed
verification.
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 60 def authenticate!(message_body) msg = Json.load(message_body) if public_key(msg).verify(sha1, signature(msg), canonical_string(msg)) true else msg = 'the authenticity of the message cannot be verified' raise VerificationError, msg end end
Private Instance Methods
canonical_string(message)
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 80 def canonical_string(message) parts = [] SIGNABLE_KEYS.each do |key| value = message[key] unless value.nil? or value.empty? parts << "#{key}\n#{value}\n" end end parts.join end
download_pem(uri)
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 105 def download_pem(uri) verify_uri!(uri) https_get(uri) end
https_get(uri, failed_attempts = 0)
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 137 def https_get(uri, failed_attempts = 0) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.start resp = http.request(Net::HTTP::Get.new(uri.request_uri)) http.finish if resp.code == '200' resp.body else raise VerificationError, resp.body end rescue => error failed_attempts += 1 retry if failed_attempts < 3 raise VerificationError, error.message end
pem(uri)
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 97 def pem(uri) if @cached_pems[uri.to_s] @cached_pems[uri.to_s] else @cached_pems[uri.to_s] = download_pem(uri) end end
public_key(message)
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 91 def public_key(message) x509_url = URI.parse(message['SigningCertURL']) x509 = OpenSSL::X509::Certificate.new(pem(x509_url)) OpenSSL::PKey::RSA.new(x509.public_key) end
sha1()
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 72 def sha1 OpenSSL::Digest::SHA1.new end
signature(message)
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 76 def signature(message) Base64.decode64(message['Signature']) end
verify_hosted_by_aws!(uri)
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 123 def verify_hosted_by_aws!(uri) unless AWS_HOSTNAMES.any? { |pattern| pattern.match(uri.host) } msg = "signing cert is not hosted by AWS: #{uri}" raise VerificationError, msg end end
verify_https!(uri)
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 116 def verify_https!(uri) unless uri.scheme == 'https' msg = "the SigningCertURL must be https, got: #{uri}" raise VerificationError, msg end end
verify_pem!(uri)
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 130 def verify_pem!(uri) unless File.extname(uri.path) == '.pem' msg = "the SigningCertURL must link to a .pem file" raise VerificationError, msg end end
verify_uri!(uri)
click to toggle source
# File lib/aws-sdk-resources/services/sns/message_verifier.rb, line 110 def verify_uri!(uri) verify_https!(uri) verify_hosted_by_aws!(uri) verify_pem!(uri) end