Class: TrueLayerSigning::Verifier

Inherits:
JwsBase
  • Object
show all
Defined in:
lib/truelayer-signing/verifier.rb

Constant Summary collapse

EXPECTED_EC_KEY_COORDS_LENGTH =
66.freeze

Instance Attribute Summary collapse

Attributes inherited from JwsBase

#body, #headers, #method, #path

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from JwsBase

#add_header, #set_body, #set_headers, #set_method, #set_path

Constructor Details

#initialize(args) ⇒ Verifier

Returns a new instance of Verifier.



7
8
9
10
11
12
# File 'lib/truelayer-signing/verifier.rb', line 7

def initialize(args)
  super

  @key_type = args[:key_type]
  @key_value = args[:key_value]
end

Instance Attribute Details

#key_typeObject (readonly)

Returns the value of attribute key_type.



5
6
7
# File 'lib/truelayer-signing/verifier.rb', line 5

def key_type
  @key_type
end

#key_valueObject (readonly)

Returns the value of attribute key_value.



5
6
7
# File 'lib/truelayer-signing/verifier.rb', line 5

def key_value
  @key_value
end

#required_headersObject (readonly)

Returns the value of attribute required_headers.



5
6
7
# File 'lib/truelayer-signing/verifier.rb', line 5

def required_headers
  @required_headers
end

Class Method Details

.parse_tl_signature(tl_signature) ⇒ Object

Raises:



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/truelayer-signing/verifier.rb', line 45

def self.parse_tl_signature(tl_signature)
  jws_header_b64, signature_b64 = tl_signature.split("..")

  raise(Error, "Invalid signature format") unless signature_b64

  begin
    jws_header_raw = Base64.urlsafe_decode64(jws_header_b64)
  rescue ArgumentError
    raise(Error, "Invalid base64 for header")
  else
    jws_header = JwsHeader.new(JSON.parse(jws_header_raw, symbolize_names: true))
  end

  [jws_header, jws_header_b64, signature_b64]
end

Instance Method Details

#require_header(name) ⇒ Object



32
33
34
35
36
37
# File 'lib/truelayer-signing/verifier.rb', line 32

def require_header(name)
  @required_headers ||= []
  @required_headers.push(name)

  self
end

#require_headers(names) ⇒ Object



39
40
41
42
43
# File 'lib/truelayer-signing/verifier.rb', line 39

def require_headers(names)
  @required_headers = names

  self
end

#verify(tl_signature) ⇒ Object

Raises:



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/truelayer-signing/verifier.rb', line 14

def verify(tl_signature)
  ensure_verifier_config!

  jws_header, jws_header_b64, signature_b64 = self.class.parse_tl_signature(tl_signature)

  raise(Error, "Unexpected `alg` header value") if jws_header.alg != TrueLayerSigning.algorithm

  ordered_headers = jws_header.filter_headers(headers)
  normalised_headers = {}

  ordered_headers.to_a.each { |header| normalised_headers[header.first.downcase] = header.last }

  raise(Error, "Signature missing required header(s)") if required_headers &&
    required_headers.any? { |key| !normalised_headers.has_key?(key.downcase) }

  verify_signature_flex(ordered_headers, jws_header, jws_header_b64, signature_b64)
end