Module: JWT::Multisig
- Defined in:
- lib/jwt-multisig.rb,
lib/jwt-multisig/version.rb
Overview
The module provides tools for encoding/decoding JWT with multiple signatures.
Constant Summary collapse
- VERSION =
"1.0.6"
Class Method Summary collapse
-
.add_jws(jwt, key_id, key_value, algorithm) ⇒ Hash
Generates and adds new JWS to existing JWT.
-
.generate_jws(payload, key_id, key_value, algorithm) ⇒ Hash
Generates new JWS based on payload, key, and algorithm.
-
.generate_jwt(payload, private_keychain, algorithms) ⇒ Hash
Generates new JWT based on payload, keys, and algorithms.
-
.remove_jws(jwt, key_id) ⇒ Hash
Removes all JWS associated with given key ID.
-
.verify_jws(jws, encoded_payload, public_keychain, options = {}) ⇒ Hash
Verifies JWS.
-
.verify_jwt(jwt, public_keychain, options = {}) ⇒ Hash
Verifies JWT.
Class Method Details
.add_jws(jwt, key_id, key_value, algorithm) ⇒ Hash
Generates and adds new JWS to existing JWT.
65 66 67 68 69 70 71 72 |
# File 'lib/jwt-multisig.rb', line 65 def add_jws(jwt, key_id, key_value, algorithm) proxy_exception JWT::EncodeError do remove_jws(jwt, key_id).tap do |new_jwt| payload = JSON.parse(base64_decode(new_jwt.fetch(:payload))) new_jwt.fetch(:signatures) << generate_jws(payload, key_id, key_value, algorithm) end end end |
.generate_jws(payload, key_id, key_value, algorithm) ⇒ Hash
Generates new JWS based on payload, key, and algorithm.
167 168 169 170 171 172 173 174 |
# File 'lib/jwt-multisig.rb', line 167 def generate_jws(payload, key_id, key_value, algorithm) proxy_exception JWT::EncodeError do protected, _, signature = JWT.encode(payload, to_pem_or_key(key_value, algorithm), algorithm).split(".") { protected: protected, header: { kid: key_id }, signature: signature } end end |
.generate_jwt(payload, private_keychain, algorithms) ⇒ Hash
Generates new JWT based on payload, keys, and algorithms.
41 42 43 44 45 46 47 48 49 |
# File 'lib/jwt-multisig.rb', line 41 def generate_jwt(payload, private_keychain, algorithms) proxy_exception JWT::EncodeError do algorithms_mapping = algorithms.with_indifferent_access { payload: base64_encode(::JSON.dump(payload)), signatures: private_keychain.map do |id, value| generate_jws(payload, id, value, algorithms_mapping.fetch(id)) end } end end |
.remove_jws(jwt, key_id) ⇒ Hash
Removes all JWS associated with given key ID.
83 84 85 86 87 88 89 |
# File 'lib/jwt-multisig.rb', line 83 def remove_jws(jwt, key_id) jwt.deep_symbolize_keys.tap do |new_jwt| new_jwt[:signatures] = new_jwt.fetch(:signatures, []).reject do |jws| jws.fetch(:header).fetch(:kid) == key_id end end end |
.verify_jws(jws, encoded_payload, public_keychain, options = {}) ⇒ Hash
Verifies JWS.
197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/jwt-multisig.rb', line 197 def verify_jws(jws, encoded_payload, public_keychain, = {}) proxy_exception JWT::DecodeError do encoded_header = jws.fetch("protected") serialized_header = base64_decode(encoded_header) signature = jws.fetch("signature") public_key = public_keychain.with_indifferent_access.fetch(jws.fetch("header").fetch("kid")) jwt = [encoded_header, encoded_payload, signature].join(".") algorithm = JSON.parse(serialized_header).fetch("alg") JWT.decode(jwt, to_pem_or_key(public_key, algorithm), true, .merge(algorithms: [algorithm])).first end end |
.verify_jwt(jwt, public_keychain, options = {}) ⇒ Hash
Verifies JWT.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/jwt-multisig.rb', line 123 def verify_jwt(jwt, public_keychain, = {}) proxy_exception JWT::DecodeError do keychain = public_keychain.with_indifferent_access encoded_payload = jwt.fetch("payload") serialized_payload = base64_decode(jwt.fetch("payload")) payload = JSON.parse(serialized_payload) verified = [] unverified = [] jwt.fetch("signatures").each do |jws| key_id = jws.fetch("header").fetch("kid") if keychain.key?(key_id) verify_jws(jws, encoded_payload, public_keychain, ) verified << key_id else unverified << key_id end end { payload: payload.deep_symbolize_keys, verified: verified.uniq.map(&:to_sym), unverified: unverified.uniq.map(&:to_sym) } end end |