sandal 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +14 -0
- data/README.md +1 -1
- data/lib/sandal.rb +77 -76
- data/lib/sandal/claims.rb +13 -13
- data/lib/sandal/enc.rb +15 -49
- data/lib/sandal/enc/acbc_hs.rb +97 -52
- data/lib/sandal/enc/agcm.rb +64 -26
- data/lib/sandal/enc/alg.rb +2 -3
- data/lib/sandal/enc/alg/direct.rb +27 -25
- data/lib/sandal/enc/alg/rsa.rb +82 -0
- data/lib/sandal/sig.rb +12 -12
- data/lib/sandal/sig/es.rb +43 -25
- data/lib/sandal/sig/hs.rb +21 -8
- data/lib/sandal/sig/rs.rb +34 -23
- data/lib/sandal/util.rb +7 -7
- data/lib/sandal/version.rb +1 -1
- data/spec/helper.rb +1 -0
- data/spec/sample_keys.rb +28 -0
- data/spec/sandal/claims_spec.rb +4 -4
- data/spec/sandal/enc/a128cbc_hs256_spec.rb +15 -39
- data/spec/sandal/enc/a128gcm_spec.rb +13 -6
- data/spec/sandal/enc/a256cbc_hs512_spec.rb +13 -4
- data/spec/sandal/enc/a256gcm_spec.rb +15 -37
- data/spec/sandal/enc/alg/direct_spec.rb +27 -33
- data/spec/sandal/enc/alg/rsa_spec.rb +100 -0
- data/spec/sandal/enc/shared_examples.rb +93 -21
- data/spec/sandal/sig/es_spec.rb +145 -188
- data/spec/sandal/sig/hs_spec.rb +73 -18
- data/spec/sandal/sig/rs_spec.rb +81 -78
- metadata +7 -6
- data/lib/sandal/enc/alg/rsa1_5.rb +0 -47
- data/lib/sandal/enc/alg/rsa_oaep.rb +0 -48
- data/spec/sandal/enc/alg/rsa1_5_spec.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ea79b1b4960ee68f883439155f86e455f840297
|
4
|
+
data.tar.gz: 88fe766c7e0dd6f42ffe8cc9e362bd4f9d4dcf1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8caf814bd10d413690942fde42d319a9b1d65afcef90c3ebf19f27f35b731e2d48c4d4225fb0700a60c9841c98ea46a6e34c610b40d93cf5584c605b6144621a
|
7
|
+
data.tar.gz: 978832491980e5e85b83bdac17e4c615cddc01594600785db0e7b7a621d459b7955003ab0352dac65ba803ded8890780cb609895528a6f35f60e107938dc8be6
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## 0.5.0 (07 June 2013)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- Updated to JWT draft-08 specification, and corresponding JWE, JWS and JWA drafts.
|
6
|
+
- Added a KeyError class for when invalid keys are given to the library.
|
7
|
+
- Added an ExpiredTokenError class to make handling the common case of expired tokens easier.
|
8
|
+
- Added a NAME constant to all classes with a JWA name to save user having to hard-code the name string.
|
9
|
+
|
10
|
+
Breaking changes:
|
11
|
+
|
12
|
+
- Tokens are not backwards compatible with previous versions of the library due to changes in the specification.
|
13
|
+
- Dropped support for Ruby 1.9.2; supported platforms are now 1.9.3, 2.0.0, JRuby (head) and Rubinius (head).
|
14
|
+
|
1
15
|
## 0.4.0 (30 April 2013)
|
2
16
|
|
3
17
|
Features:
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Sandal [](https://travis-ci.org/gregbeech/sandal) [](https://coveralls.io/r/gregbeech/sandal) [](https://codeclimate.com/github/gregbeech/sandal) [](https://gemnasium.com/gregbeech/sandal)
|
2
2
|
|
3
|
-
A Ruby library for creating and reading [JSON Web Tokens (JWT) draft-
|
3
|
+
A Ruby library for creating and reading [JSON Web Tokens (JWT) draft-08](http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-08), supporting [JSON Web Signatures (JWS) draft-11](http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-11) and [JSON Web Encryption (JWE) draft-11](http://tools.ietf.org/html/draft-ietf-jose-json-web-encryption-11). See the [CHANGELOG](CHANGELOG.md) for version history.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
data/lib/sandal.rb
CHANGED
@@ -1,48 +1,60 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
|
10
|
-
|
11
|
-
# A library for creating and reading JSON Web Tokens (JWT), supporting JSON Web
|
12
|
-
#
|
1
|
+
require "multi_json"
|
2
|
+
require "openssl"
|
3
|
+
require "zlib"
|
4
|
+
require "sandal/version"
|
5
|
+
require "sandal/claims"
|
6
|
+
require "sandal/enc"
|
7
|
+
require "sandal/sig"
|
8
|
+
require "sandal/util"
|
9
|
+
|
10
|
+
|
11
|
+
# A library for creating and reading JSON Web Tokens (JWT), supporting JSON Web Signatures (JWS) and JSON Web Encryption
|
12
|
+
# (JWE).
|
13
13
|
#
|
14
|
-
# Currently supports draft-
|
15
|
-
# specs.
|
14
|
+
# Currently supports draft-07 of the JWT spec, and draft-10 of the JWS and JWE specs.
|
16
15
|
module Sandal
|
17
16
|
extend Sandal::Util
|
18
17
|
|
18
|
+
# The base error for all errors raised by this library.
|
19
|
+
class Error < StandardError; end
|
20
|
+
|
21
|
+
# The error that is raised when a key provided for signing/encryption/etc. is invalid.
|
22
|
+
class KeyError < Error; end
|
23
|
+
|
24
|
+
# The error that is raised when there is a problem with a token.
|
25
|
+
class TokenError < Error; end
|
26
|
+
|
19
27
|
# The error that is raised when a token is invalid.
|
20
|
-
class
|
28
|
+
class InvalidTokenError < TokenError; end
|
21
29
|
|
22
30
|
# The error that is raised when a claim within a token is invalid.
|
23
|
-
class ClaimError <
|
31
|
+
class ClaimError < InvalidTokenError; end
|
32
|
+
|
33
|
+
# The error that is raised when the token has expired.
|
34
|
+
class ExpiredTokenError < ClaimError; end
|
35
|
+
|
36
|
+
# The error that is raised when a token is unsupported (e.g. the algorithm used to encrypt the token is not supported
|
37
|
+
# by this library or by the Ruby platform it is executing on).
|
38
|
+
class UnsupportedTokenError < TokenError; end
|
24
39
|
|
25
40
|
# The default options for token handling.
|
26
41
|
#
|
27
42
|
# ignore_exp::
|
28
|
-
# Whether to ignore the expiry date of the token. This setting is just to
|
29
|
-
#
|
43
|
+
# Whether to ignore the expiry date of the token. This setting is just to help get things working and should always
|
44
|
+
# be false in real apps!
|
30
45
|
# ignore_nbf::
|
31
|
-
# Whether to ignore the not-before date of the token. This setting is just
|
32
|
-
#
|
46
|
+
# Whether to ignore the not-before date of the token. This setting is just to help get things working and should
|
47
|
+
# always be false in real apps!
|
33
48
|
# ignore_signature::
|
34
|
-
# Whether to ignore the signature of signed (JWS) tokens. This setting is
|
35
|
-
#
|
49
|
+
# Whether to ignore the signature of signed (JWS) tokens. This setting is just tohelp get things working and should
|
50
|
+
# always be false in real apps!
|
36
51
|
# max_clock_skew::
|
37
|
-
# The maximum clock skew, in seconds, when validating times. If your server
|
38
|
-
#
|
39
|
-
# take that into account. It probably shouldn't be more than about 300.
|
52
|
+
# The maximum clock skew, in seconds, when validating times. If your server time is out of sync with the token
|
53
|
+
# server then this can be increased to take that into account. It probably shouldn't be more than about 300.
|
40
54
|
# valid_iss::
|
41
|
-
# A list of valid token issuers, if validation of the issuer claim is
|
42
|
-
# required.
|
55
|
+
# A list of valid token issuers, if validation of the issuer claim is required.
|
43
56
|
# valid_aud::
|
44
|
-
# A list of valid audiences, if validation of the audience claim is
|
45
|
-
# required.
|
57
|
+
# A list of valid audiences, if validation of the audience claim is required.
|
46
58
|
DEFAULT_OPTIONS = {
|
47
59
|
ignore_exp: false,
|
48
60
|
ignore_nbf: false,
|
@@ -54,8 +66,7 @@ module Sandal
|
|
54
66
|
|
55
67
|
# Overrides the default options.
|
56
68
|
#
|
57
|
-
# @param defaults [Hash] The options to override (see {DEFAULT_OPTIONS} for
|
58
|
-
# details).
|
69
|
+
# @param defaults [Hash] The options to override (see {DEFAULT_OPTIONS} for details).
|
59
70
|
# @return [Hash] The new default options.
|
60
71
|
def self.default!(defaults)
|
61
72
|
DEFAULT_OPTIONS.merge!(defaults)
|
@@ -67,7 +78,7 @@ module Sandal
|
|
67
78
|
# @return [Boolean] true if the token is encrypted; otherwise false.
|
68
79
|
def self.is_encrypted?(token)
|
69
80
|
if token.is_a?(String)
|
70
|
-
token.count(
|
81
|
+
token.count(".") == 4
|
71
82
|
else
|
72
83
|
token.count == 5
|
73
84
|
end
|
@@ -79,7 +90,7 @@ module Sandal
|
|
79
90
|
# @return [Boolean] true if the token is signed; otherwise false.
|
80
91
|
def self.is_signed?(token)
|
81
92
|
if token.is_a?(String)
|
82
|
-
!token.end_with?(
|
93
|
+
!token.end_with?(".") && token.count(".") == 2
|
83
94
|
else
|
84
95
|
token.count == 3 && !token[2].nil? && !token[2].empty?
|
85
96
|
end
|
@@ -87,75 +98,65 @@ module Sandal
|
|
87
98
|
|
88
99
|
# Creates a signed JSON Web Token.
|
89
100
|
#
|
90
|
-
# @param payload [String or Hash] The payload of the token. Hashes will be
|
91
|
-
#
|
92
|
-
# @param
|
93
|
-
# unsigned token.
|
94
|
-
# @param header_fields [Hash] Header fields for the token (note: do not
|
95
|
-
# include 'alg').
|
101
|
+
# @param payload [String or Hash] The payload of the token. Hashes will be encoded as JSON.
|
102
|
+
# @param signer [#name,#sign] The token signer, which may be nil for an unsigned token.
|
103
|
+
# @param header_fields [Hash] Header fields for the token (note: do not include "alg").
|
96
104
|
# @return [String] A signed JSON Web Token.
|
97
105
|
def self.encode_token(payload, signer, header_fields = nil)
|
98
106
|
signer ||= Sandal::Sig::NONE
|
99
107
|
|
100
108
|
header = {}
|
101
|
-
header[
|
109
|
+
header["alg"] = signer.name
|
102
110
|
header = header_fields.merge(header) if header_fields
|
103
111
|
header = MultiJson.dump(header)
|
104
112
|
|
105
113
|
payload = MultiJson.dump(payload) unless payload.is_a?(String)
|
106
114
|
|
107
|
-
sec_input = [header, payload].map { |p| jwt_base64_encode(p) }.join(
|
115
|
+
sec_input = [header, payload].map { |p| jwt_base64_encode(p) }.join(".")
|
108
116
|
signature = signer.sign(sec_input)
|
109
|
-
[sec_input, jwt_base64_encode(signature)].join(
|
117
|
+
[sec_input, jwt_base64_encode(signature)].join(".")
|
110
118
|
end
|
111
119
|
|
112
120
|
# Creates an encrypted JSON Web Token.
|
113
121
|
#
|
114
122
|
# @param payload [String] The payload of the token.
|
115
123
|
# @param encrypter [#name,#alg,#encrypt] The token encrypter.
|
116
|
-
# @param header_fields [Hash] Header fields for the token (note: do not
|
117
|
-
# include 'alg' or 'enc').
|
124
|
+
# @param header_fields [Hash] Header fields for the token (note: do not include "alg" or "enc").
|
118
125
|
# @return [String] An encrypted JSON Web Token.
|
119
126
|
def self.encrypt_token(payload, encrypter, header_fields = nil)
|
120
127
|
header = {}
|
121
|
-
header[
|
122
|
-
header[
|
128
|
+
header["enc"] = encrypter.name
|
129
|
+
header["alg"] = encrypter.alg.name
|
123
130
|
header = header_fields.merge(header) if header_fields
|
124
131
|
|
125
|
-
if header.has_key?(
|
126
|
-
unless header[
|
127
|
-
raise ArgumentError,
|
132
|
+
if header.has_key?("zip")
|
133
|
+
unless header["zip"] == "DEF"
|
134
|
+
raise ArgumentError, "Invalid zip algorithm."
|
128
135
|
end
|
129
136
|
payload = Zlib::Deflate.deflate(payload, Zlib::BEST_COMPRESSION)
|
130
137
|
end
|
131
138
|
|
132
|
-
encrypter.encrypt(header, payload)
|
139
|
+
encrypter.encrypt(MultiJson.dump(header), payload)
|
133
140
|
end
|
134
141
|
|
135
|
-
# Decodes and validates a signed and/or encrypted JSON Web Token, recursing
|
136
|
-
#
|
142
|
+
# Decodes and validates a signed and/or encrypted JSON Web Token, recursing into any nested tokens, and returns the
|
143
|
+
# payload.
|
137
144
|
#
|
138
|
-
# The block is called with the token header as the first parameter, and should
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
# options parameter which can be used to override the {DEFAULT_OPTIONS} on a
|
143
|
-
# per-token basis; options are not persisted between yields.
|
145
|
+
# The block is called with the token header as the first parameter, and should return the appropriate signature or
|
146
|
+
# decryption method to either validate the signature or decrypt the token as applicable. When the tokens are nested,
|
147
|
+
# this block will be called once per token. It can optionally have a second options parameter which can be used to
|
148
|
+
# override the {DEFAULT_OPTIONS} on a per-token basis; options are not persisted between yields.
|
144
149
|
#
|
145
150
|
# @param token [String] The encoded JSON Web Token.
|
146
151
|
# @param depth [Integer] The maximum depth of token nesting to decode to.
|
147
152
|
# @yieldparam header [Hash] The JWT header values.
|
148
|
-
# @yieldparam options [Hash] (Optional) A hash that can be used to override
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
# @
|
153
|
-
# otherwise as a String.
|
154
|
-
# @raise [Sandal::ClaimError] One or more claims in the token is invalid.
|
155
|
-
# @raise [Sandal::TokenError] The token format is invalid, or validation of
|
156
|
-
# the token failed.
|
153
|
+
# @yieldparam options [Hash] (Optional) A hash that can be used to override the default options.
|
154
|
+
# @yieldreturn [#valid? or #decrypt] The signature validator if the token is signed, or the token decrypter if the
|
155
|
+
# token is encrypted.
|
156
|
+
# @return [Hash or String] The payload of the token as a Hash if it was JSON, otherwise as a String.
|
157
|
+
# @raise [Sandal::TokenError] The token is invalid or not supported.
|
157
158
|
def self.decode_token(token, depth = 16)
|
158
|
-
parts = token.split(
|
159
|
+
parts = token.split(".")
|
159
160
|
decoded_parts = decode_token_parts(parts)
|
160
161
|
header = decoded_parts[0]
|
161
162
|
|
@@ -163,10 +164,10 @@ module Sandal
|
|
163
164
|
decoder = yield header, options if block_given?
|
164
165
|
|
165
166
|
if is_encrypted?(parts)
|
166
|
-
payload = decoder.decrypt(parts
|
167
|
-
if header.has_key?(
|
168
|
-
unless header[
|
169
|
-
raise Sandal::
|
167
|
+
payload = decoder.decrypt(parts)
|
168
|
+
if header.has_key?("zip")
|
169
|
+
unless header["zip"] == "DEF"
|
170
|
+
raise Sandal::InvalidTokenError, "Invalid zip algorithm."
|
170
171
|
end
|
171
172
|
payload = Zlib::Inflate.inflate(payload)
|
172
173
|
end
|
@@ -177,7 +178,7 @@ module Sandal
|
|
177
178
|
end
|
178
179
|
end
|
179
180
|
|
180
|
-
if header[
|
181
|
+
if header["cty"] == "JWT"
|
181
182
|
if depth > 0
|
182
183
|
if block_given?
|
183
184
|
decode_token(payload, depth - 1, &Proc.new)
|
@@ -197,9 +198,9 @@ module Sandal
|
|
197
198
|
# Decodes and validates a signed JSON Web Token.
|
198
199
|
def self.validate_signature(parts, signature, validator)
|
199
200
|
validator ||= Sandal::Sig::NONE
|
200
|
-
secured_input = parts.take(2).join(
|
201
|
+
secured_input = parts.take(2).join(".")
|
201
202
|
unless validator.valid?(signature, secured_input)
|
202
|
-
raise TokenError,
|
203
|
+
raise TokenError, "Invalid signature."
|
203
204
|
end
|
204
205
|
end
|
205
206
|
|
@@ -209,7 +210,7 @@ module Sandal
|
|
209
210
|
parts[0] = MultiJson.load(parts[0])
|
210
211
|
parts
|
211
212
|
rescue
|
212
|
-
raise TokenError,
|
213
|
+
raise TokenError, "Invalid token encoding."
|
213
214
|
end
|
214
215
|
|
215
216
|
# Parses the content of a token and validates the claims if is JSON claims.
|
data/lib/sandal/claims.rb
CHANGED
@@ -21,14 +21,14 @@ module Sandal
|
|
21
21
|
#
|
22
22
|
# @param max_clock_skew [Numeric] The maximum clock skew, in seconds.
|
23
23
|
# @return [void].
|
24
|
-
# @raise [Sandal::ClaimError] The
|
24
|
+
# @raise [Sandal::ClaimError] The "exp" claim is invalid, or the token has
|
25
25
|
# expired.
|
26
26
|
def validate_exp(max_clock_skew = 0)
|
27
27
|
max_clock_skew ||= 0
|
28
28
|
|
29
|
-
exp = time_claim(
|
29
|
+
exp = time_claim("exp")
|
30
30
|
if exp && exp <= (Time.now - max_clock_skew)
|
31
|
-
raise Sandal::
|
31
|
+
raise Sandal::ExpiredTokenError, "The token has expired."
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -36,14 +36,14 @@ module Sandal
|
|
36
36
|
#
|
37
37
|
# @param max_clock_skew [Numeric] The maximum clock skew, in seconds.
|
38
38
|
# @return [void].
|
39
|
-
# @raise [Sandal::ClaimError] The
|
39
|
+
# @raise [Sandal::ClaimError] The "nbf" claim is invalid, or the token is
|
40
40
|
# not valid yet.
|
41
41
|
def validate_nbf(max_clock_skew = 0)
|
42
42
|
max_clock_skew ||= 0
|
43
43
|
|
44
|
-
nbf = time_claim(
|
44
|
+
nbf = time_claim("nbf")
|
45
45
|
if nbf && nbf > (Time.now + max_clock_skew)
|
46
|
-
raise Sandal::ClaimError,
|
46
|
+
raise Sandal::ClaimError, "The token is not valid yet."
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -51,12 +51,12 @@ module Sandal
|
|
51
51
|
#
|
52
52
|
# @param valid_iss [Array] The valid issuers.
|
53
53
|
# @return [void].
|
54
|
-
# @raise [Sandal::ClaimError] The
|
54
|
+
# @raise [Sandal::ClaimError] The "iss" claim value is not a valid issuer.
|
55
55
|
def validate_iss(valid_iss)
|
56
56
|
return unless valid_iss && valid_iss.length > 0
|
57
57
|
|
58
|
-
unless valid_iss.include?(self[
|
59
|
-
raise Sandal::ClaimError,
|
58
|
+
unless valid_iss.include?(self["iss"])
|
59
|
+
raise Sandal::ClaimError, "The issuer is invalid."
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -64,15 +64,15 @@ module Sandal
|
|
64
64
|
#
|
65
65
|
# @param valid_aud [Array] The valid audiences.
|
66
66
|
# @return [void].
|
67
|
-
# @raise [Sandal::ClaimError] The
|
67
|
+
# @raise [Sandal::ClaimError] The "aud" claim value does not contain a valid
|
68
68
|
# audience.
|
69
69
|
def validate_aud(valid_aud)
|
70
70
|
return unless valid_aud && valid_aud.length > 0
|
71
71
|
|
72
|
-
aud = self[
|
72
|
+
aud = self["aud"]
|
73
73
|
aud = [aud] unless aud.is_a?(Array)
|
74
74
|
unless (aud & valid_aud).length > 0
|
75
|
-
raise Sandal::ClaimError,
|
75
|
+
raise Sandal::ClaimError, "The audence is invalid."
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
@@ -85,7 +85,7 @@ module Sandal
|
|
85
85
|
begin
|
86
86
|
Time.at(claim)
|
87
87
|
rescue
|
88
|
-
raise Sandal::ClaimError, "The
|
88
|
+
raise Sandal::ClaimError, "The "#{name}" claim is invalid."
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
data/lib/sandal/enc.rb
CHANGED
@@ -1,60 +1,26 @@
|
|
1
|
-
require
|
1
|
+
require "openssl"
|
2
|
+
require "sandal/util"
|
2
3
|
|
3
4
|
module Sandal
|
4
5
|
# Contains encryption (JWE) functionality.
|
5
6
|
module Enc
|
6
7
|
|
7
|
-
#
|
8
|
+
# Gets the decoded parts of a JWE token.
|
8
9
|
#
|
9
|
-
# @param
|
10
|
-
# @
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
def self.concat_kdf(digest, key, keydatalen, algorithm_id,
|
19
|
-
party_u_info, party_v_info,
|
20
|
-
supp_pub_info = nil, supp_priv_info = nil)
|
21
|
-
digest = OpenSSL::Digest.new(digest) if digest.is_a?(String)
|
22
|
-
rounds = (keydatalen / (digest.digest_length * 8.0)).ceil
|
23
|
-
|
24
|
-
round_input = concat_kdf_round_input(key, keydatalen, algorithm_id,
|
25
|
-
party_u_info, party_v_info,
|
26
|
-
supp_pub_info, supp_priv_info)
|
27
|
-
|
28
|
-
(1..rounds).reduce('') do |output, round|
|
29
|
-
hash = digest.digest([round].pack('N') + round_input)
|
30
|
-
if round == rounds
|
31
|
-
round_bits = keydatalen % (digest.digest_length * 8)
|
32
|
-
hash = hash[0...(round_bits / 8)] unless round_bits == 0
|
33
|
-
end
|
34
|
-
output << hash
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
# The round input for the Concat KDF function (excluding round number).
|
41
|
-
def self.concat_kdf_round_input(key, keydatalen, algorithm_id,
|
42
|
-
party_u_info, party_v_info,
|
43
|
-
supp_pub_info, supp_priv_info)
|
44
|
-
input = ''.force_encoding('binary')
|
45
|
-
input << key.force_encoding('binary')
|
46
|
-
input << [keydatalen].pack('N')
|
47
|
-
input << algorithm_id.force_encoding('binary')
|
48
|
-
input << (party_u_info == 0 ? [0].pack('N') : party_u_info.force_encoding('binary'))
|
49
|
-
input << (party_v_info == 0 ? [0].pack('N') : party_v_info.force_encoding('binary'))
|
50
|
-
input << supp_pub_info.force_encoding('binary') if supp_pub_info
|
51
|
-
input << supp_priv_info.force_encoding('binary') if supp_priv_info
|
52
|
-
input
|
10
|
+
# @param token [String or Array] The token, or encoded token parts.
|
11
|
+
# @return [[Array, Array]] The encoded parts and the decoded parts.
|
12
|
+
def self.token_parts(token)
|
13
|
+
parts = token.is_a?(Array) ? token : token.split(".")
|
14
|
+
raise ArgumentError unless parts.length == 5
|
15
|
+
decoded_parts = parts.map { |part| jwt_base64_decode(part) }
|
16
|
+
return parts, decoded_parts
|
17
|
+
rescue ArgumentError
|
18
|
+
raise Sandal::InvalidTokenError, "Invalid token encoding."
|
53
19
|
end
|
54
20
|
|
55
21
|
end
|
56
22
|
end
|
57
23
|
|
58
|
-
require
|
59
|
-
require
|
60
|
-
require
|
24
|
+
require "sandal/enc/acbc_hs"
|
25
|
+
require "sandal/enc/agcm" unless RUBY_VERSION < "2.0.0"
|
26
|
+
require "sandal/enc/alg"
|