Class: JOSE::JWS

Inherits:
Struct
  • Object
show all
Defined in:
lib/jose/jws.rb

Defined Under Namespace

Modules: ALG Classes: ALG_ECDSA, ALG_EDDSA, ALG_HMAC, ALG_RSA_PKCS1_V1_5, ALG_RSA_PSS, ALG_none

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#algObject

Returns the value of attribute alg



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

def alg
  @alg
end

#b64Object

Returns the value of attribute b64



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

def b64
  @b64
end

#fieldsObject

Returns the value of attribute fields



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

def fields
  @fields
end

Class Method Details

.compact(map) ⇒ Object

API



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/jose/jws.rb', line 82

def self.compact(map)
  if map.is_a?(Hash) or map.is_a?(JOSE::Map)
    return JOSE::SignedBinary.new([
      map['protected'] || '',
      '.',
      map['payload'] || '',
      '.',
      map['signature'] || ''
    ].join)
  else
    raise ArgumentError, "'map' must be a Hash or a JOSE::Map"
  end
end

.expand(binary) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/jose/jws.rb', line 96

def self.expand(binary)
  if binary.is_a?(String)
    if binary.count('.') == 2 and (parts = binary.split('.', 3)).length == 3
      protected_binary, payload, signature = parts
      return JOSE::SignedMap[
        'payload'   => payload,
        'protected' => protected_binary,
        'signature' => signature
      ]
    else
      raise ArgumentError, "'binary' is not a valid signed String"
    end
  else
    raise ArgumentError, "'binary' must be a String"
  end
end

.from(object, modules = {}) ⇒ Object

Decode API



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

def self.from(object, modules = {})
  case object
  when JOSE::Map, Hash
    return from_map(object, modules)
  when String
    return from_binary(object, modules)
  when JOSE::JWS
    return object
  else
    raise ArgumentError, "'object' must be a Hash, String, or JOSE::JWS"
  end
end

.from_binary(object, modules = {}) ⇒ Object



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

def self.from_binary(object, modules = {})
  case object
  when String
    return from_map(JOSE.decode(object), modules)
  else
    raise ArgumentError, "'object' must be a String"
  end
end

.from_file(file, modules = {}) ⇒ Object



41
42
43
# File 'lib/jose/jws.rb', line 41

def self.from_file(file, modules = {})
  return from_binary(File.binread(file), modules)
end

.from_map(object, modules = {}) ⇒ Object



45
46
47
48
49
50
51
52
# File 'lib/jose/jws.rb', line 45

def self.from_map(object, modules = {})
  case object
  when JOSE::Map, Hash
    return from_fields(JOSE::JWS.new(nil, nil, JOSE::Map.new(object)), modules)
  else
    raise ArgumentError, "'object' must be a Hash"
  end
end

.generate_key(object, modules = {}) ⇒ Object



113
114
115
# File 'lib/jose/jws.rb', line 113

def self.generate_key(object, modules = {})
  return from(object, modules).generate_key
end

.merge(left, right) ⇒ Object



121
122
123
# File 'lib/jose/jws.rb', line 121

def self.merge(left, right)
  return from(left).merge(right)
end

.peek_payload(signed) ⇒ Object



139
140
141
142
143
144
# File 'lib/jose/jws.rb', line 139

def self.peek_payload(signed)
  if signed.is_a?(String)
    signed = expand(signed)
  end
  return JOSE.urlsafe_decode64(signed['payload'])
end

.peek_protected(signed) ⇒ Object



146
147
148
149
150
151
# File 'lib/jose/jws.rb', line 146

def self.peek_protected(signed)
  if signed.is_a?(String)
    signed = expand(signed)
  end
  return JOSE::Map.new(JOSE.decode(JOSE.urlsafe_decode64(signed['protected'])))
end

.sign(key, plain_text, jws, header = nil) ⇒ Object



153
154
155
# File 'lib/jose/jws.rb', line 153

def self.sign(key, plain_text, jws, header = nil)
  return from(jws).sign(key, plain_text, header)
end

.to_binary(jws) ⇒ Object

Encode API



56
57
58
# File 'lib/jose/jws.rb', line 56

def self.to_binary(jws)
  return from(jws).to_binary
end

.to_file(jws, file) ⇒ Object



64
65
66
# File 'lib/jose/jws.rb', line 64

def self.to_file(jws, file)
  return from(jws).to_file(file)
end

.to_map(jws) ⇒ Object



72
73
74
# File 'lib/jose/jws.rb', line 72

def self.to_map(jws)
  return from(jws).to_map
end

.verify(key, signed) ⇒ Object



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

def self.verify(key, signed)
  if signed.is_a?(String)
    signed = JOSE::JWS.expand(signed)
  end
  if signed.is_a?(Hash)
    signed = JOSE::SignedMap.new(signed)
  end
  if signed.is_a?(JOSE::Map) and signed['payload'].is_a?(String) and signed['protected'].is_a?(String) and signed['signature'].is_a?(String)
    jws = from_binary(JOSE.urlsafe_decode64(signed['protected']))
    signature = JOSE.urlsafe_decode64(signed['signature'])
    plain_text = JOSE.urlsafe_decode64(signed['payload'])
    return jws.verify(key, plain_text, signature, signed['protected'])
  else
    raise ArgumentError, "'signed' is not a valid signed String, Hash, or JOSE::Map"
  end
end

.verify_strict(key, allow, signed) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/jose/jws.rb', line 195

def self.verify_strict(key, allow, signed)
  if signed.is_a?(String)
    signed = JOSE::JWS.expand(signed)
  end
  if signed.is_a?(Hash)
    signed = JOSE::SignedMap.new(signed)
  end
  if signed.is_a?(JOSE::Map) and signed['payload'].is_a?(String) and signed['protected'].is_a?(String) and signed['signature'].is_a?(String)
    protected_map = JOSE.decode(JOSE.urlsafe_decode64(signed['protected']))
    plain_text = JOSE.urlsafe_decode64(signed['payload'])
    if allow.member?(protected_map['alg'])
      jws = from_map(protected_map)
      signature = JOSE.urlsafe_decode64(signed['signature'])
      return jws.verify(key, plain_text, signature, signed['protected'])
    else
      return false, plain_text, protected_map
    end
  else
    raise ArgumentError, "'signed' is not a valid signed String, Hash, or JOSE::Map"
  end
end

Instance Method Details

#generate_keyObject



117
118
119
# File 'lib/jose/jws.rb', line 117

def generate_key
  return alg.generate_key(fields)
end

#merge(object) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/jose/jws.rb', line 125

def merge(object)
  object = case object
  when JOSE::Map, Hash
    object
  when String
    JOSE.decode(object)
  when JOSE::JWS
    object.to_map
  else
    raise ArgumentError, "'object' must be a Hash, String, or JOSE::JWS"
  end
  return JOSE::JWS.from_map(self.to_map.merge(object))
end

#sign(key, plain_text, header = nil) ⇒ Object



157
158
159
160
161
162
163
# File 'lib/jose/jws.rb', line 157

def sign(key, plain_text, header = nil)
  protected_binary = JOSE.urlsafe_encode64(to_binary)
  payload = JOSE.urlsafe_encode64(plain_text)
  signing_input = signing_input(plain_text, protected_binary)
  signature = JOSE.urlsafe_encode64(alg.sign(key, signing_input))
  return signature_to_map(payload, protected_binary, header, key, signature)
end

#signing_input(payload, protected_binary = JOSE.urlsafe_encode64(to_binary)) ⇒ Object



166
167
168
169
170
171
# File 'lib/jose/jws.rb', line 166

def signing_input(payload, protected_binary = JOSE.urlsafe_encode64(to_binary))
  if b64 == true or b64.nil?
    payload = JOSE.urlsafe_encode64(payload)
  end
  return [protected_binary, '.', payload].join
end

#to_binaryObject



60
61
62
# File 'lib/jose/jws.rb', line 60

def to_binary
  return JOSE.encode(to_map)
end

#to_file(file) ⇒ Object



68
69
70
# File 'lib/jose/jws.rb', line 68

def to_file(file)
  return File.binwrite(file, to_binary)
end

#to_mapObject



76
77
78
# File 'lib/jose/jws.rb', line 76

def to_map
  return alg.to_map(fields)
end

#verify(key, plain_text, signature, protected_binary = JOSE.urlsafe_encode64(to_binary)) ⇒ Object



190
191
192
193
# File 'lib/jose/jws.rb', line 190

def verify(key, plain_text, signature, protected_binary = JOSE.urlsafe_encode64(to_binary))
  signing_input = signing_input(plain_text, protected_binary)
  return alg.verify(key, signing_input, signature), plain_text, self
end