Class: JSON::JWS

Inherits:
JWT
  • Object
show all
Defined in:
lib/json/jws.rb

Defined Under Namespace

Classes: InvalidFormat, UnexpectedAlgorithm, VerificationFailed

Constant Summary collapse

NUM_OF_SEGMENTS =
3

Instance Attribute Summary collapse

Attributes inherited from JWT

#signature

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from JWT

#as_json, #encrypt, pretty_generate, #pretty_generate, #to_s

Methods included from JOSE

#with_jwk_support

Constructor Details

#initialize(jwt) ⇒ JWS

Returns a new instance of JWS.



11
12
13
# File 'lib/json/jws.rb', line 11

def initialize(jwt)
  update jwt
end

Instance Attribute Details

#signature_base_string=(value) ⇒ Object

Sets the attribute signature_base_string

Parameters:

  • value

    the value to set the attribute signature_base_string to.



9
10
11
# File 'lib/json/jws.rb', line 9

def signature_base_string=(value)
  @signature_base_string = value
end

Class Method Details

.decode_compact_serialized(input, public_key_or_secret, algorithms = nil) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/json/jws.rb', line 155

def decode_compact_serialized(input, public_key_or_secret, algorithms = nil)
  unless input.count('.') + 1 == NUM_OF_SEGMENTS
    raise InvalidFormat.new("Invalid JWS Format. JWS should include #{NUM_OF_SEGMENTS} segments.")
  end
  header, claims, signature = input.split('.', JWS::NUM_OF_SEGMENTS).collect do |segment|
    UrlSafeBase64.decode64 segment.to_s
  end
  header, claims = [header, claims].collect do |json|
    JSON.parse(json).with_indifferent_access
  end
  jws = new claims
  jws.header = header
  jws.signature = signature
  jws.signature_base_string = input.split('.')[0, JWS::NUM_OF_SEGMENTS - 1].join('.')
  jws.verify! public_key_or_secret, algorithms unless public_key_or_secret == :skip_verification
  jws
end

.decode_json_serialized(input, public_key_or_secret, algorithms = nil) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/json/jws.rb', line 173

def decode_json_serialized(input, public_key_or_secret, algorithms = nil)
  input = input.with_indifferent_access
  header, payload, signature = if input[:signatures].present?
    [
      input[:signatures].first[:protected],
      input[:payload],
      input[:signatures].first[:signature]
    ].collect do |segment|
      segment
    end
  else
    [:protected, :payload, :signature].collect do |key|
      input[key]
    end
  end
  compact_serialized = [header, payload, signature].join('.')
  decode_compact_serialized compact_serialized, public_key_or_secret, algorithms
end

Instance Method Details

#sign!(private_key_or_secret) ⇒ Object



15
16
17
18
# File 'lib/json/jws.rb', line 15

def sign!(private_key_or_secret)
  self.signature = sign signature_base_string, private_key_or_secret
  self
end

#update(hash_or_jwt) ⇒ Object



32
33
34
35
36
37
38
39
# File 'lib/json/jws.rb', line 32

def update(hash_or_jwt)
  super
  if hash_or_jwt.is_a? JSON::JWT
    self.header.update hash_or_jwt.header
    self.signature = hash_or_jwt.signature
  end
  self
end

#verify!(public_key_or_secret, algorithms = nil) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/json/jws.rb', line 20

def verify!(public_key_or_secret, algorithms = nil)
  if alg.try(:to_sym) == :none
    raise UnexpectedAlgorithm if public_key_or_secret
    signature == '' or raise VerificationFailed
  elsif algorithms.blank? || Array(algorithms).include?(alg.try(:to_sym))
    public_key_or_secret && valid?(public_key_or_secret) or
    raise VerificationFailed
  else
    raise UnexpectedAlgorithm.new('Unexpected alg header')
  end
end