module Faria::Launchpad::Packet
Constants
- VERSION
Public Class Methods
add_api_url(packet, url)
click to toggle source
# File lib/faria/launchpad/packet.rb, line 85 def self.add_api_url(packet, url) packet["api_url"] = Addressable::URI.parse(url).normalize.to_s packet end
add_expires(packet, expires_in)
click to toggle source
# File lib/faria/launchpad/packet.rb, line 95 def self.add_expires(packet, expires_in) packet[:exp] = Time.now.utc.to_i + expires_in packet end
add_issued_at(packet)
click to toggle source
# File lib/faria/launchpad/packet.rb, line 90 def self.add_issued_at(packet) packet[:iat] = Time.now.utc.to_i packet end
add_issuer(packet, issuer)
click to toggle source
# File lib/faria/launchpad/packet.rb, line 80 def self.add_issuer(packet, issuer) packet[:iss] = issuer packet end
add_source(packet, source)
click to toggle source
# File lib/faria/launchpad/packet.rb, line 75 def self.add_source(packet, source) packet[:faria_source] = source packet end
decrypt(raw_data, options = {}, local_key:, remote_key: )
click to toggle source
for cases where you known in advance the remote key to use (such as LaunchPad clients which will only be receiving messages from LaunchPad and therefore will only use it's public key for verifying signatures
# File lib/faria/launchpad/packet.rb, line 45 def self.decrypt(raw_data, options = {}, local_key:, remote_key: ) _version, jwe = raw_data.split(";", 2) jwt = JWE.decrypt(jwe, local_key) arr = JWT.decode(jwt, remote_key, true, { :algorithm => 'RS512' }) payload, _header = arr # validate_expiration will be handled by JWT decode validate_url!(payload, options[:actual_url]) payload["data"] end
decrypt_variable_key(raw_data, options = {}, local_key:, remote_key_func: )
click to toggle source
for cases where the signature key is not known in advance and must be determined by source information embedded in the JWT header
# File lib/faria/launchpad/packet.rb, line 59 def self.decrypt_variable_key(raw_data, options = {}, local_key:, remote_key_func: ) _version, jwe = raw_data.split(";", 2) jwt = JWE.decrypt(jwe, local_key) header, payload = JWT::Decode.new(jwt, nil, false, {}).decode_segments[0..1] remote_key = remote_key_func.call(header, payload) fail(MissingRemoteKey) if remote_key.nil? arr = JWT.decode(jwt, remote_key, true, { :algorithm => 'RS512' }) payload, _header = arr # validate_expiration will be handled by JWT decode validate_url!(payload, options[:actual_url]) payload["data"] end
encrypt(data, options = {}, local_key:, remote_key: )
click to toggle source
encrypting is done with LaunchPad public key signing is done with local private key
# File lib/faria/launchpad/packet.rb, line 29 def self.encrypt(data, options = {}, local_key:, remote_key: ) packet = { "data" => data} packet = add_issued_at(packet) packet = add_expires(packet, options[:expires_in]) if options[:expires_in] packet = add_api_url(packet, options[:api_url]) if options[:api_url] # packet = add_issuer(packet, options[:issuer]) packet = add_source(packet, options[:source]) if options[:source] payload = JWT.encode(packet, local_key, 'RS512') "#{VERSION};" + JWE.encrypt(payload, remote_key) # public end
validate_expiration!(payload)
click to toggle source
# File lib/faria/launchpad/packet.rb, line 109 def self.validate_expiration!(payload) return unless payload.include?('exp') leeway = 0 valid_until = (Time.now.utc.to_i - leeway) if payload['exp'].to_i < valid_until diff = valid_until - payload['exp'].to_i error = ExpiredSignature.new("Signature expired", diff) fail(error) end end
validate_url!(payload, actual_url)
click to toggle source
# File lib/faria/launchpad/packet.rb, line 100 def self.validate_url!(payload, actual_url) return unless payload.include?('api_url') normalized_url = Addressable::URI.parse(actual_url).normalize.to_s if payload['api_url'] != normalized_url fail(MismatchedRequestURL) end end