ruby-paseto 0.1.2 → 0.2.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/CHANGELOG.md +7 -0
- data/README.md +55 -50
- data/lib/paseto/asn1/ecdsa_signature.rb +2 -2
- data/lib/paseto/asymmetric_key.rb +7 -4
- data/lib/paseto/configuration/decode_configuration.rb +7 -7
- data/lib/paseto/interface/key.rb +5 -2
- data/lib/paseto/interface/pbkd.rb +4 -20
- data/lib/paseto/interface/pie.rb +5 -26
- data/lib/paseto/interface/pke.rb +15 -51
- data/lib/paseto/interface/version.rb +30 -117
- data/lib/paseto/operations/id/i_dv3.rb +1 -1
- data/lib/paseto/operations/id/i_dv4.rb +1 -1
- data/lib/paseto/operations/pbkd/p_b_k_dv3.rb +4 -5
- data/lib/paseto/operations/pbkd/p_b_k_dv4.rb +3 -4
- data/lib/paseto/operations/pbkw.rb +6 -6
- data/lib/paseto/operations/pke/p_k_ev3.rb +23 -25
- data/lib/paseto/operations/pke/p_k_ev4.rb +33 -34
- data/lib/paseto/operations/pke.rb +9 -10
- data/lib/paseto/operations/wrap.rb +1 -1
- data/lib/paseto/paserk.rb +1 -1
- data/lib/paseto/paserk_types.rb +2 -2
- data/lib/paseto/protocol/version3.rb +17 -16
- data/lib/paseto/protocol/version4.rb +17 -16
- data/lib/paseto/symmetric_key.rb +16 -10
- data/lib/paseto/token.rb +17 -15
- data/lib/paseto/token_types.rb +2 -2
- data/lib/paseto/util.rb +1 -1
- data/lib/paseto/v3/local.rb +1 -1
- data/lib/paseto/v3/public.rb +5 -4
- data/lib/paseto/v4/local.rb +3 -3
- data/lib/paseto/v4/public.rb +3 -6
- data/lib/paseto/validator.rb +1 -1
- data/lib/paseto/version.rb +1 -1
- data/lib/paseto/versions.rb +2 -2
- data/lib/paseto/wrappers/pie/pie_v3.rb +18 -21
- data/lib/paseto/wrappers/pie/pie_v4.rb +17 -20
- data/lib/paseto/wrappers/pie.rb +3 -17
- data/lib/paseto.rb +2 -5
- data/paseto.gemspec +5 -5
- data/sorbet/rbi/annotations/.gitattributes +1 -0
- data/sorbet/rbi/annotations/rainbow.rbi +4 -4
- data/sorbet/rbi/gems/.gitattributes +1 -0
- data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +1 -1
- data/sorbet/rbi/gems/docile@1.4.0.rbi +1 -1
- data/sorbet/rbi/gems/{ffi@1.15.5.rbi → ffi@1.16.3.rbi} +260 -117
- data/sorbet/rbi/gems/{oj@3.14.2.rbi → oj@3.16.1.rbi} +26 -37
- data/sorbet/rbi/gems/{rake@13.0.6.rbi → rake@13.1.0.rbi} +75 -69
- data/sorbet/rbi/gems/rbnacl@7.1.1.rbi +2 -2
- data/sorbet/rbi/gems/{rspec-core@3.12.1.rbi → rspec-core@3.12.2.rbi} +1 -1
- data/sorbet/rbi/gems/{rspec-expectations@3.12.2.rbi → rspec-expectations@3.12.3.rbi} +27 -33
- data/sorbet/rbi/gems/{rspec-mocks@3.12.4.rbi → rspec-mocks@3.12.6.rbi} +60 -61
- data/sorbet/rbi/gems/{rspec-support@3.12.0.rbi → rspec-support@3.12.1.rbi} +35 -43
- data/sorbet/rbi/gems/rspec@3.12.0.rbi +22 -28
- data/sorbet/rbi/gems/simplecov-html@0.12.3.rbi +41 -44
- data/sorbet/rbi/gems/simplecov_json_formatter@0.1.4.rbi +232 -2
- data/sorbet/rbi/gems/{timecop@0.9.6.rbi → timecop@0.9.8.rbi} +13 -16
- data/sorbet/rbi/shims/multi_json.rbi +2 -0
- data/sorbet/rbi/shims/openssl.rbi +0 -8
- data/sorbet/rbi/todo.rbi +5 -1
- metadata +19 -42
- data/sorbet/rbi/gems/ast@2.4.2.rbi +0 -584
- data/sorbet/rbi/gems/io-console@0.6.0.rbi +0 -8
- data/sorbet/rbi/gems/irb@1.6.3.rbi +0 -342
- data/sorbet/rbi/gems/json@2.6.3.rbi +0 -1541
- data/sorbet/rbi/gems/multi_json@1.15.0.rbi +0 -267
- data/sorbet/rbi/gems/netrc@0.11.0.rbi +0 -158
- data/sorbet/rbi/gems/openssl@3.1.0.rbi +0 -1739
- data/sorbet/rbi/gems/parallel@1.22.1.rbi +0 -277
- data/sorbet/rbi/gems/rainbow@3.1.1.rbi +0 -407
- data/sorbet/rbi/gems/regexp_parser@2.7.0.rbi +0 -3580
- data/sorbet/rbi/gems/reline@0.3.2.rbi +0 -8
- data/sorbet/rbi/gems/rexml@3.2.5.rbi +0 -4717
- data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +0 -1317
- data/sorbet/rbi/gems/thor@1.2.1.rbi +0 -3956
- data/sorbet/rbi/gems/unicode-display_width@2.4.2.rbi +0 -65
- data/sorbet/rbi/gems/webrick@1.7.0.rbi +0 -2555
- data/sorbet/rbi/gems/yard-sorbet@0.8.0.rbi +0 -441
- data/sorbet/rbi/gems/yard@0.9.28.rbi +0 -17816
- data/sorbet/rbi/gems/zeitwerk@2.6.7.rbi +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a58c81dd9d66d7512b70184c48f9dce92e1f3a798d0a1dccc7b795e09becc048
|
4
|
+
data.tar.gz: 48064247e0d0dbaa082ca8b602f89bcf5728d923169f51c0a079bb2f1302731f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c21dedaf0227394479b5258ee07acacf2135e1e3be4c86f3e838f95cd8827713a086b575af0c93b27237c7b73492f15ac576b8828b27ba6735c8bc6fbcd16b9f
|
7
|
+
data.tar.gz: fb379b133bdcd64cd09cecefc3edd507a6627291c5b02dece8ab5ab10d64870b2dcc0c8a04a92481e11d692eee1d55af8c8d57711719a76675d010b3ef2fc5bf
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
- Minimum ruby version 3.0 -> 3.1
|
4
|
+
- Remove support for OpenSSL 1.1.1
|
5
|
+
- Remove support for ruby/openssl 3.0.x
|
6
|
+
- Refactor how version protocols are implemented to greatly improve sorbet coverage
|
7
|
+
- `Paseto.rbnacl?` is replaced by `Paseto::HAS_RBNACL`
|
8
|
+
- Fix decoding of multibyte characters in payloads, #216 thanks to @pelted @levicole
|
9
|
+
|
3
10
|
## [0.1.2]
|
4
11
|
|
5
12
|
- Fixed versioning in 0.1.1 changelog
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# Paseto
|
2
|
+
|
2
3
|
[](https://rubystyle.guide) [](https://dl.circleci.com/status-badge/redirect/gh/bannable/paseto/tree/main) [](https://codeclimate.com/github/bannable/paseto/maintainability) [](https://codeclimate.com/github/bannable/paseto/test_coverage)
|
3
4
|
|
4
5
|
This is an implementation of the [PASETO token protocol](https://github.com/paseto-standard/paseto-spec), written in Ruby, which supports versions [v3](https://github.com/paseto-standard/paseto-spec/tree/master/docs/01-Protocol-Versions#version-3-nist-modern) and [v4](https://github.com/paseto-standard/paseto-spec/tree/master/docs/01-Protocol-Versions#version-4-sodium-modern). This library passes all [official test vectors](https://github.com/paseto-standard/test-vectors) for supported versions and purposes.
|
@@ -11,14 +12,15 @@ Additionally, the library uses [Sorbet](https://sorbet.org) to enforce types at
|
|
11
12
|
|
12
13
|
**Optional for v4.local tokens support**: Handling v4.local tokens requires [`RbNaCl`](https://github.com/RubyCrypto/rbnacl) with `libsodium 1.0.0` or newer.
|
13
14
|
|
14
|
-
You can find instructions for obtaining libsodium at https://libsodium.org.
|
15
|
+
You can find instructions for obtaining libsodium at [libsodium.org](https://libsodium.org).
|
15
16
|
|
16
17
|
If you do not intend to create or parse `v4.local` tokens, feel free to skip this dependency.
|
17
18
|
|
18
|
-
### Using Bundler
|
19
|
+
### Using Bundler
|
19
20
|
|
20
21
|
Add the following to your Gemfile:
|
21
|
-
|
22
|
+
|
23
|
+
```ruby
|
22
24
|
gem 'ruby-paseto'
|
23
25
|
# and optionally:
|
24
26
|
gem 'rbnacl', '~> 7.1.1'
|
@@ -29,26 +31,26 @@ Then, run `bundle install` and `require 'paseto'`.
|
|
29
31
|
## Supported PASETO versions
|
30
32
|
|
31
33
|
`paseto` supports these PASETO versions and purposes:
|
32
|
-
| purpose |
|
33
|
-
|
|
34
|
-
| `local` |
|
35
|
-
| `public` |
|
34
|
+
| purpose | v4 | v3 |
|
35
|
+
| -------- | --- | --- |
|
36
|
+
| `local` | ✅ | ✅ |
|
37
|
+
| `public` | ✅ | ✅ |
|
36
38
|
|
37
39
|
## Support for PASERK types
|
38
40
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
| [`lid`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/lid.md)
|
42
|
-
| [`sid`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/sid.md)
|
43
|
-
| [`pid`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/pid.md)
|
44
|
-
| [`local`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/local.md)
|
45
|
-
| [`secret`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/secret.md)
|
46
|
-
| [`public`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/public.md)
|
47
|
-
| [`seal`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/seal.md)
|
48
|
-
| [`local-wrap`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/local-wrap.md)
|
49
|
-
| [`secret-wrap`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/secret-wrap.md) |
|
50
|
-
| [`local-pw`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/local-pw.md)
|
51
|
-
| [`secret-pw`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/secret-pw.md)
|
41
|
+
| | v4 | v3 |
|
42
|
+
| ----------------------------------------------------------------------------------------------------------------------------- | --- | --- |
|
43
|
+
| [`lid`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/lid.md) | ✅ | ✅ |
|
44
|
+
| [`sid`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/sid.md) | ✅ | ✅ |
|
45
|
+
| [`pid`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/pid.md) | ✅ | ✅ |
|
46
|
+
| [`local`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/local.md) | ✅ | ✅ |
|
47
|
+
| [`secret`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/secret.md) | ✅ | ✅ |
|
48
|
+
| [`public`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/public.md) | ✅ | ✅ |
|
49
|
+
| [`seal`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/seal.md) | ✅ | ✅ |
|
50
|
+
| [`local-wrap`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/local-wrap.md) | ✅ | ✅ |
|
51
|
+
| [`secret-wrap`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/secret-wrap.md) | ✅ | ✅ |
|
52
|
+
| [`local-pw`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/local-pw.md) | ✅ | ✅ |
|
53
|
+
| [`secret-pw`](https://github.com/paseto-standard/paserk/blob/8cc4934687a3c9235387d005fb79eec33f43166d/types/secret-pw.md) | ✅ | ✅ |
|
52
54
|
|
53
55
|
## Implementation Guideline compliance
|
54
56
|
|
@@ -167,6 +169,7 @@ signer.pid # => "k4.pid.5g4..." (PASERK Type pid)
|
|
167
169
|
verifier.pid # => same as above!
|
168
170
|
verifier.id # => same as above
|
169
171
|
```
|
172
|
+
|
170
173
|
## PASETO/PASERK v4, Sodium Modern
|
171
174
|
|
172
175
|
[Description](https://github.com/paseto-standard/paseto-spec/tree/master/docs/01-Protocol-Versions#version-4-nist-modern) and [Specification](https://github.com/paseto-standard/paseto-spec/blob/master/docs/01-Protocol-Versions/Version4.md).
|
@@ -310,8 +313,8 @@ key == secret_key
|
|
310
313
|
|
311
314
|
### Version 4, Argon2id Parameters
|
312
315
|
|
313
|
-
|
|
314
|
-
| :--------: |
|
316
|
+
| param | allowed values | default |
|
317
|
+
| :--------: | :---------------: | :------------: |
|
315
318
|
| `opslimit` | Symbol \| Integer | `:interactive` |
|
316
319
|
| `memlimit` | Symbol \| Integer | `:interactive` |
|
317
320
|
|
@@ -319,12 +322,11 @@ Allowed symbol values are `:interactive`, `:moderate` and `:sensitive` as descri
|
|
319
322
|
|
320
323
|
You most likely do not want to use the `:interactive` default in production. See [libsodium's documentation](https://libsodium.gitbook.io/doc/~/revisions/-LL5wcLSbESuQhMZUBZo/password_hashing/the_argon2i_function#guidelines-for-choosing-the-parameters) for parameter guidance.
|
321
324
|
|
322
|
-
|
323
325
|
### Version 3, PBKDF2 Parameters
|
324
326
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
| `iterations` |
|
327
|
+
| param | allowed values | default |
|
328
|
+
| :----------: | :------------: | :-------: |
|
329
|
+
| `iterations` | Integer | `100_000` |
|
328
330
|
|
329
331
|
As with the Version 4 parameters above, you most likely do not want to use the default value and should pick an `iterations` value with time objectives similar to the argon2 guidance.
|
330
332
|
|
@@ -332,13 +334,14 @@ As with the Version 4 parameters above, you most likely do not want to use the d
|
|
332
334
|
|
333
335
|
PASETO [reserves some claim names](https://github.com/paseto-standard/paseto-spec/blob/master/docs/02-Implementation-Guide/04-Claims.md) for particular use in the protocol, and this gem supports verification of all reserved claims.
|
334
336
|
|
335
|
-
In the default configuration, the
|
337
|
+
In the default configuration, the following claims are verified when present: `exp`, `nbf` and `iat`
|
336
338
|
|
337
339
|
Verification behavior can be controlled by passing a kwarg for the setting to `decode` calls, or through library-level configuration.
|
338
340
|
|
339
341
|
## Default Configuration
|
340
342
|
|
341
343
|
See the appropriate section below for more information on configuring each `verify_foo`.
|
344
|
+
|
342
345
|
```ruby
|
343
346
|
Paseto.configure do |config|
|
344
347
|
# Controls the behavior of footer deserialization in Result objects.
|
@@ -359,9 +362,9 @@ end
|
|
359
362
|
|
360
363
|
## Audience Claim
|
361
364
|
|
362
|
-
| claim type |
|
363
|
-
| :--------: |
|
364
|
-
|
|
365
|
+
| claim type | config type | default |
|
366
|
+
| :--------: | :------------------------------: | :-----: |
|
367
|
+
| String | False \| String \| Array[String] | `false` |
|
365
368
|
|
366
369
|
```ruby
|
367
370
|
crypt = Paseto::V4::Local.generate
|
@@ -379,7 +382,7 @@ crypt.decode(payload, verify_aud: audience) # => { 'aud' => ... }
|
|
379
382
|
|
380
383
|
| claim type | config type | default |
|
381
384
|
| :--------: | :---------: | :-----: |
|
382
|
-
|
|
385
|
+
| DateTime | Boolean | `true` |
|
383
386
|
|
384
387
|
```ruby
|
385
388
|
crypt = Paseto::V4::Local.generate
|
@@ -396,7 +399,7 @@ crypt.decode(payload, verify_exp: false) # { 'exp' => ... }
|
|
396
399
|
|
397
400
|
| claim type | config type | default |
|
398
401
|
| :--------: | :---------: | :-----: |
|
399
|
-
|
|
402
|
+
| DateTime | Boolean | `true` |
|
400
403
|
|
401
404
|
```ruby
|
402
405
|
crypt = Paseto::V4::Local.generate
|
@@ -411,9 +414,9 @@ crypt.decode(payload, verify_iat: false) # { 'iat' => ... }
|
|
411
414
|
|
412
415
|
### Issuer Claim
|
413
416
|
|
414
|
-
| claim type |
|
415
|
-
| :--------: |
|
416
|
-
|
|
417
|
+
| claim type | config type | default |
|
418
|
+
| :--------: | :---------------------------------: | :-----: |
|
419
|
+
| String | Boolean \| String \| Regexp \| Proc | `false` |
|
417
420
|
|
418
421
|
```ruby
|
419
422
|
crypt = Paseto::V4::Local.generate
|
@@ -440,7 +443,7 @@ crypt.decode(payload, verify_issuer: true) # { 'iss' => ... }
|
|
440
443
|
|
441
444
|
| claim type | config type | default |
|
442
445
|
| :--------: | :---------: | :-----: |
|
443
|
-
|
|
446
|
+
| DateTime | Boolean | `true` |
|
444
447
|
|
445
448
|
```ruby
|
446
449
|
crypt = Paseto::V4::Local.generate
|
@@ -454,9 +457,9 @@ crypt.decode(payload, verify_nbf: false) # => { 'nbf' => ... }
|
|
454
457
|
|
455
458
|
### Subject Claim
|
456
459
|
|
457
|
-
| claim type |
|
458
|
-
| :--------: |
|
459
|
-
|
|
460
|
+
| claim type | config type | default |
|
461
|
+
| :--------: | :-------------: | :-----: |
|
462
|
+
| String | False \| String | `false` |
|
460
463
|
|
461
464
|
```ruby
|
462
465
|
crypt = Paseto::V4::Local.generate
|
@@ -469,9 +472,9 @@ crypt.decode(payload, verify_sub: 'example.org') # => Paseto::InvalidSubject
|
|
469
472
|
|
470
473
|
### Token Identifier Claim
|
471
474
|
|
472
|
-
| claim type |
|
473
|
-
| :--------: |
|
474
|
-
|
|
475
|
+
| claim type | config type | default |
|
476
|
+
| :--------: | :-----------------------: | :-----: |
|
477
|
+
| String | Boolean \| String \| Proc | `false` |
|
475
478
|
|
476
479
|
```ruby
|
477
480
|
crypt = Paseto::V4::Local.generate
|
@@ -479,17 +482,17 @@ hash = { data: 'data' }
|
|
479
482
|
payload = crypt.encode(hash)
|
480
483
|
|
481
484
|
# Require presence
|
482
|
-
crypt.decode(payload, verify_jti: true)
|
485
|
+
crypt.decode(payload, verify_jti: true) # => Paseto::InvalidTokenIdentifier
|
483
486
|
|
484
487
|
# Require exact value
|
485
488
|
hash[:jti] = 'foo'
|
486
489
|
payload = crypt.encode(payload: hash)
|
487
|
-
crypt.decode(payload, verify_jti: 'foo')
|
488
|
-
crypt.decode(payload, verify_jti: 'bar')
|
490
|
+
crypt.decode(payload, verify_jti: 'foo') # { 'data' => ... }
|
491
|
+
crypt.decode(payload, verify_jti: 'bar') # Paseto::InvalidTokenIdentifier
|
489
492
|
|
490
493
|
# Or something more complex
|
491
494
|
jti_proc = ->(jti) { jti == 'bar'}
|
492
|
-
crypt.decode(payload, verify_jti: jti_proc)
|
495
|
+
crypt.decode(payload, verify_jti: jti_proc) # Paseto::InvalidTokenIdentifier
|
493
496
|
```
|
494
497
|
|
495
498
|
## Development
|
@@ -512,7 +515,7 @@ You can learn more over at the `sorbet` [documentation](https://sorbet.org/docs/
|
|
512
515
|
|
513
516
|
The tests are written with rspec. [Appraisal](https://github.com/thoughtbot/appraisal) is used to ensure compatibility with 3rd party dependencies providing cryptographic features.
|
514
517
|
|
515
|
-
```
|
518
|
+
```sh
|
516
519
|
bundle install
|
517
520
|
appraisal install
|
518
521
|
# in parallel
|
@@ -524,19 +527,21 @@ appraisal rake specs
|
|
524
527
|
### Updating RBI Files
|
525
528
|
|
526
529
|
To check that RBI files for gems are up-to-date:
|
527
|
-
|
530
|
+
|
531
|
+
```sh
|
528
532
|
appraisal rbnacl bin/tapioca gems --verify
|
529
533
|
```
|
530
534
|
|
531
535
|
To update RBI files for gems:
|
532
|
-
|
536
|
+
|
537
|
+
```sh
|
533
538
|
appraisal rbnacl bin/tapioca gems
|
534
539
|
appraisal rbnacl bin/tapioca annotations
|
535
540
|
```
|
536
541
|
|
537
542
|
## Contributing
|
538
543
|
|
539
|
-
Bug reports and pull requests are welcome on GitHub
|
544
|
+
Bug reports and pull requests are welcome on [GitHub](https://github.com/bannable/paseto).
|
540
545
|
|
541
546
|
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](CODE_OF_CONDUCT.md).
|
542
547
|
|
@@ -12,13 +12,13 @@ module Paseto
|
|
12
12
|
def self.from_rs(bytes, part_len)
|
13
13
|
r = OpenSSL::BN.new(T.must(bytes[0, part_len]), 2)
|
14
14
|
s = OpenSSL::BN.new(T.must(bytes[-part_len, part_len]), 2)
|
15
|
-
new(signature: ECDSASigValue.new(r
|
15
|
+
new(signature: ECDSASigValue.new(r:, s:))
|
16
16
|
end
|
17
17
|
|
18
18
|
sig { params(sig: String).returns(ECDSASignature) }
|
19
19
|
def self.from_asn1(sig)
|
20
20
|
r, s = OpenSSL::ASN1.decode(sig).value.map(&:value)
|
21
|
-
new(signature: ECDSASigValue.new(r
|
21
|
+
new(signature: ECDSASigValue.new(r:, s:))
|
22
22
|
end
|
23
23
|
|
24
24
|
sig { returns(OpenSSL::ASN1::Sequence) }
|
@@ -60,7 +60,7 @@ module Paseto
|
|
60
60
|
end
|
61
61
|
def encode!(payload, footer: '', implicit_assertion: '', **options)
|
62
62
|
MultiJson.dump(payload, options)
|
63
|
-
.then { |json| sign(message: json, footer
|
63
|
+
.then { |json| sign(message: json, footer:, implicit_assertion:) }
|
64
64
|
.then(&:to_s)
|
65
65
|
end
|
66
66
|
|
@@ -74,14 +74,17 @@ module Paseto
|
|
74
74
|
def decode!(payload, implicit_assertion: '', **options)
|
75
75
|
token = Token.parse(payload)
|
76
76
|
|
77
|
-
verify(token
|
77
|
+
verify(token:, implicit_assertion:)
|
78
78
|
.then { |json| MultiJson.load(json, **options) }
|
79
|
-
.then { |claims| Result.new(claims
|
79
|
+
.then { |claims| Result.new(claims:, footer: token.footer) }
|
80
80
|
end
|
81
81
|
|
82
82
|
sig(:final) { override.returns(String) }
|
83
83
|
def pbkw_header = protocol.pbkd_secret_header
|
84
84
|
|
85
|
+
sig(:final) { override.returns(String) }
|
86
|
+
def pie_header = "#{paserk_version}.secret-wrap.pie."
|
87
|
+
|
85
88
|
sig(:final) { override.returns(String) }
|
86
89
|
def purpose = 'public'
|
87
90
|
|
@@ -95,6 +98,6 @@ module Paseto
|
|
95
98
|
def seal(other) = Paserk.seal(sealing_key: self, key: other)
|
96
99
|
|
97
100
|
sig(:final) { params(paserk: String).returns(SymmetricKey) }
|
98
|
-
def unseal(paserk) = Paserk.from_paserk(paserk
|
101
|
+
def unseal(paserk) = Paserk.from_paserk(paserk:, unsealing_key: self)
|
99
102
|
end
|
100
103
|
end
|
@@ -54,13 +54,13 @@ module Paseto
|
|
54
54
|
sig { returns(T::Hash[Symbol, T.untyped]) }
|
55
55
|
def to_h
|
56
56
|
{
|
57
|
-
verify_exp
|
58
|
-
verify_nbf
|
59
|
-
verify_iss
|
60
|
-
verify_iat
|
61
|
-
verify_jti
|
62
|
-
verify_aud
|
63
|
-
verify_sub:
|
57
|
+
verify_exp:,
|
58
|
+
verify_nbf:,
|
59
|
+
verify_iss:,
|
60
|
+
verify_iat:,
|
61
|
+
verify_jti:,
|
62
|
+
verify_aud:,
|
63
|
+
verify_sub:
|
64
64
|
}
|
65
65
|
end
|
66
66
|
end
|
data/lib/paseto/interface/key.rb
CHANGED
@@ -41,6 +41,9 @@ module Paseto
|
|
41
41
|
sig { abstract.returns(String) }
|
42
42
|
def pbkw_header; end
|
43
43
|
|
44
|
+
sig { abstract.returns(String) }
|
45
|
+
def pie_header; end
|
46
|
+
|
44
47
|
sig { abstract.returns(Version) }
|
45
48
|
def protocol; end
|
46
49
|
|
@@ -58,7 +61,7 @@ module Paseto
|
|
58
61
|
).returns(Result)
|
59
62
|
end
|
60
63
|
def decode(payload, implicit_assertion: '', **options)
|
61
|
-
decode!(payload, **T.unsafe(implicit_assertion
|
64
|
+
decode!(payload, **T.unsafe(implicit_assertion:, **options))
|
62
65
|
.then { |result| Verify.verify(result, options) }
|
63
66
|
end
|
64
67
|
|
@@ -83,7 +86,7 @@ module Paseto
|
|
83
86
|
def encode(payload, footer: '', implicit_assertion: '', **options)
|
84
87
|
footer = MultiJson.dump(footer, mode: :object) if footer.is_a?(Hash)
|
85
88
|
default_claims.merge(payload)
|
86
|
-
.then { |claims| encode!(claims, footer
|
89
|
+
.then { |claims| encode!(claims, footer:, implicit_assertion:, **options) }
|
87
90
|
end
|
88
91
|
|
89
92
|
sig(:final) { params(other: T.untyped).returns(T::Boolean) }
|
@@ -7,22 +7,8 @@ module Paseto
|
|
7
7
|
extend T::Sig
|
8
8
|
extend T::Helpers
|
9
9
|
|
10
|
-
include Kernel
|
11
|
-
|
12
10
|
abstract!
|
13
11
|
|
14
|
-
module ClassMethods
|
15
|
-
extend T::Sig
|
16
|
-
extend T::Helpers
|
17
|
-
|
18
|
-
interface!
|
19
|
-
|
20
|
-
sig { abstract.returns(Interface::Version) }
|
21
|
-
def protocol; end
|
22
|
-
end
|
23
|
-
|
24
|
-
mixes_in_class_methods(ClassMethods)
|
25
|
-
|
26
12
|
sig do
|
27
13
|
abstract.params(
|
28
14
|
header: String,
|
@@ -33,13 +19,13 @@ module Paseto
|
|
33
19
|
params: T::Hash[Symbol, Integer]
|
34
20
|
).returns([String, String])
|
35
21
|
end
|
36
|
-
def authenticate(header:, pre_key:, salt:, nonce:, edk:, params:); end
|
22
|
+
def authenticate(header:, pre_key:, salt:, nonce:, edk:, params:); end # rubocop:disable Metrics/ParameterLists
|
37
23
|
|
38
24
|
sig(:final) { params(payload: String, key: String, nonce: String).returns(String) }
|
39
25
|
def crypt(payload:, key:, nonce:)
|
40
26
|
ek = protocol.digest("#{Operations::PBKW::DOMAIN_SEPARATOR_ENCRYPT}#{key}", digest_size: 32)
|
41
27
|
|
42
|
-
protocol.crypt(key: ek, nonce
|
28
|
+
protocol.crypt(key: ek, nonce:, payload:)
|
43
29
|
end
|
44
30
|
|
45
31
|
sig do
|
@@ -63,10 +49,8 @@ module Paseto
|
|
63
49
|
protocol.paserk_version
|
64
50
|
end
|
65
51
|
|
66
|
-
sig
|
67
|
-
def protocol
|
68
|
-
self.class.protocol
|
69
|
-
end
|
52
|
+
sig { abstract.returns(Interface::Version) }
|
53
|
+
def protocol; end
|
70
54
|
|
71
55
|
sig { abstract.returns(String) }
|
72
56
|
def random_nonce; end
|
data/lib/paseto/interface/pie.rb
CHANGED
@@ -8,25 +8,8 @@ module Paseto
|
|
8
8
|
extend T::Sig
|
9
9
|
extend T::Helpers
|
10
10
|
|
11
|
-
include Kernel
|
12
|
-
|
13
11
|
abstract!
|
14
12
|
|
15
|
-
module ClassMethods
|
16
|
-
extend T::Sig
|
17
|
-
extend T::Helpers
|
18
|
-
|
19
|
-
interface!
|
20
|
-
|
21
|
-
sig { abstract.params(data: String).returns({ t: String, n: String, c: String }) }
|
22
|
-
def decode_and_split(data); end
|
23
|
-
|
24
|
-
sig { abstract.returns(Interface::Version) }
|
25
|
-
def protocol; end
|
26
|
-
end
|
27
|
-
|
28
|
-
mixes_in_class_methods(ClassMethods)
|
29
|
-
|
30
13
|
sig { abstract.params(nonce: String).returns(String) }
|
31
14
|
def authentication_key(nonce:); end
|
32
15
|
|
@@ -36,24 +19,20 @@ module Paseto
|
|
36
19
|
sig { abstract.params(nonce: String, payload: String).returns(String) }
|
37
20
|
def crypt(nonce:, payload:); end
|
38
21
|
|
39
|
-
sig { params(data: String).returns({ t: String, n: String, c: String }) }
|
40
|
-
def decode_and_split(data)
|
41
|
-
self.class.decode_and_split(data)
|
42
|
-
end
|
22
|
+
sig { abstract.params(data: String).returns({ t: String, n: String, c: String }) }
|
23
|
+
def decode_and_split(data); end
|
43
24
|
|
44
25
|
sig { abstract.returns(String) }
|
45
26
|
def local_header; end
|
46
27
|
|
28
|
+
sig { abstract.returns(Interface::Version) }
|
29
|
+
def protocol; end
|
30
|
+
|
47
31
|
sig { abstract.returns(String) }
|
48
32
|
def random_nonce; end
|
49
33
|
|
50
34
|
sig { abstract.returns(String) }
|
51
35
|
def secret_header; end
|
52
|
-
|
53
|
-
sig(:final) { returns(Interface::Version) }
|
54
|
-
def protocol
|
55
|
-
self.class.protocol
|
56
|
-
end
|
57
36
|
end
|
58
37
|
end
|
59
38
|
end
|
data/lib/paseto/interface/pke.rb
CHANGED
@@ -8,40 +8,11 @@ module Paseto
|
|
8
8
|
extend T::Sig
|
9
9
|
extend T::Helpers
|
10
10
|
|
11
|
-
include Kernel
|
12
|
-
|
13
11
|
abstract!
|
14
12
|
|
15
13
|
DOMAIN_SEPARATOR_ENCRYPT = "\x01"
|
16
14
|
DOMAIN_SEPARATOR_AUTH = "\x02"
|
17
15
|
|
18
|
-
module ClassMethods
|
19
|
-
extend T::Sig
|
20
|
-
extend T::Helpers
|
21
|
-
|
22
|
-
interface!
|
23
|
-
|
24
|
-
sig { abstract.params(esk: T.untyped).returns(String) }
|
25
|
-
def epk_bytes_from_esk(esk); end
|
26
|
-
|
27
|
-
sig { abstract.returns(T.untyped) }
|
28
|
-
def generate_ephemeral_key; end
|
29
|
-
|
30
|
-
sig { abstract.returns(String) }
|
31
|
-
def header; end
|
32
|
-
|
33
|
-
sig { abstract.returns(Interface::Version) }
|
34
|
-
def protocol; end
|
35
|
-
|
36
|
-
sig { abstract.params(encoded_data: String).returns([String, T.untyped, String]) }
|
37
|
-
def split(encoded_data); end
|
38
|
-
end
|
39
|
-
|
40
|
-
mixes_in_class_methods(ClassMethods)
|
41
|
-
|
42
|
-
sig { abstract.returns(AsymmetricKey) }
|
43
|
-
def sealing_key; end
|
44
|
-
|
45
16
|
sig { abstract.params(xk: String, epk: T.untyped).returns(String) }
|
46
17
|
def derive_ak(xk:, epk:); end
|
47
18
|
|
@@ -54,33 +25,26 @@ module Paseto
|
|
54
25
|
sig { abstract.params(message: String, ek: String, n: String).returns(String) }
|
55
26
|
def encrypt(message:, ek:, n:); end
|
56
27
|
|
57
|
-
sig { abstract.params(
|
58
|
-
def
|
28
|
+
sig { abstract.params(esk: T.untyped).returns(String) }
|
29
|
+
def epk_bytes_from_esk(esk); end
|
59
30
|
|
60
|
-
sig
|
61
|
-
def
|
62
|
-
self.class.epk_bytes_from_esk(esk)
|
63
|
-
end
|
31
|
+
sig { abstract.returns(T.untyped) }
|
32
|
+
def generate_ephemeral_key; end
|
64
33
|
|
65
|
-
sig
|
66
|
-
def
|
67
|
-
self.class.generate_ephemeral_key
|
68
|
-
end
|
34
|
+
sig { abstract.returns(Interface::Version) }
|
35
|
+
def protocol; end
|
69
36
|
|
70
|
-
sig
|
71
|
-
def header
|
72
|
-
self.class.header
|
73
|
-
end
|
37
|
+
sig { abstract.returns(String) }
|
38
|
+
def header; end
|
74
39
|
|
75
|
-
sig
|
76
|
-
def
|
77
|
-
|
78
|
-
|
40
|
+
sig { abstract.returns(AsymmetricKey) }
|
41
|
+
def sealing_key; end
|
42
|
+
|
43
|
+
sig { abstract.params(encoded_data: String).returns([String, T.untyped, String]) }
|
44
|
+
def split(encoded_data); end
|
79
45
|
|
80
|
-
sig
|
81
|
-
def
|
82
|
-
self.class.split(encoded_data)
|
83
|
-
end
|
46
|
+
sig { abstract.params(ak: String, epk: T.untyped, edk: String).returns(String) }
|
47
|
+
def tag(ak:, epk:, edk:); end
|
84
48
|
end
|
85
49
|
end
|
86
50
|
end
|