jwt-eddsa 0.2.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 397516e999d09d5630932c9e83855bdcdca32a4ce1ea5c3727bc8a69cdf0488a
4
- data.tar.gz: 120eb2ca3c66104aa8023063c96077e7e3b158388f292b766546d58eb86c8a09
3
+ metadata.gz: 8a9054ac4598241fed14b327b76854fb9dd57034947c2dc94d7ffd70a3b9667f
4
+ data.tar.gz: 79ace7fb4cde12fa7fef53cdec3631be1b1be4c7f9e2acd40976b15228050152
5
5
  SHA512:
6
- metadata.gz: 7da8d363b401a7d741539941d99be57eca69fb1c2a09cf8d6eaa0431da4346952e8d4711df1518bee69cce5bf77d762d6ea45e0e2cbb4bd0a96e581019b164a3
7
- data.tar.gz: 5027b733b26cc75604395f972db17eadfe6757219a749ed1094e0bbcfa8a056bcc49cca060dc14ea71cb33c844485324a742acd793003b4445cac0fec8b4141f
6
+ metadata.gz: 55ffed5f3d15b636699d1eb8c20058a9d99c5f854de01efe1b06481aacee9f8e086fea6700c4ebc5e19e62139e3d4c9b31c81b160eab7e240cb2244c8a8e15da
7
+ data.tar.gz: d5f6976cba0e2eec62baae85abdad9c175937c90787a74d627b950e57a641869e2a562ef6e246b9b32e34379ab411e1e55d726d1130644eee667e637844485e1
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.5.0"
3
+ }
data/.rubocop.yml CHANGED
@@ -12,3 +12,4 @@ Style/StringLiteralsInInterpolation:
12
12
  Metrics/BlockLength:
13
13
  Exclude:
14
14
  - spec/**/*_spec.rb
15
+ - '*.gemspec'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.0](https://github.com/anakinj/jwt-eddsa/compare/v0.4.0...v0.5.0) (2024-08-02)
4
+
5
+
6
+ ### Features
7
+
8
+ * Initial release ([d7ce4d3](https://github.com/anakinj/jwt-eddsa/commit/d7ce4d3885a1fbe0e268a672a52d4ed8b7c558d2))
9
+ * Release using release-please ([d450241](https://github.com/anakinj/jwt-eddsa/commit/d45024107095270ad6bafc0a638f154c0cb4d763))
10
+ * Still trying to configure release-please ([fcfe5cc](https://github.com/anakinj/jwt-eddsa/commit/fcfe5cc0c5ff18ea296a64d78db3fe073d667190))
11
+
12
+ ## [0.4.0](https://github.com/anakinj/jwt-eddsa/compare/jwt-eddsa-v0.3.0...jwt-eddsa/v0.4.0) (2024-08-02)
13
+
14
+
15
+ ### Features
16
+
17
+ * Initial release ([d7ce4d3](https://github.com/anakinj/jwt-eddsa/commit/d7ce4d3885a1fbe0e268a672a52d4ed8b7c558d2))
18
+ * Release using release-please ([d450241](https://github.com/anakinj/jwt-eddsa/commit/d45024107095270ad6bafc0a638f154c0cb4d763))
19
+ * Still trying to configure release-please ([fcfe5cc](https://github.com/anakinj/jwt-eddsa/commit/fcfe5cc0c5ff18ea296a64d78db3fe073d667190))
20
+
21
+ ## [0.3.0](https://github.com/anakinj/jwt-eddsa/compare/v0.2.0...v0.3.0) (2024-08-02)
22
+
23
+
24
+ ### Features
25
+
26
+ * Initial release ([d7ce4d3](https://github.com/anakinj/jwt-eddsa/commit/d7ce4d3885a1fbe0e268a672a52d4ed8b7c558d2))
27
+
3
28
  ## [v0.0.1](https://github.com/anakinj/jwt-eddsa/tree/v0.0.1) (NEXT)
4
29
 
5
30
  [Full Changelog](https://github.com/jwt/ruby-jwt/compare/v2.8.2...main)
@@ -11,4 +36,4 @@
11
36
 
12
37
  **Fixes and enhancements:**
13
38
 
14
- - Your contribution here
39
+ - Your contribution here
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2024 TODO: Write your name
3
+ Copyright (c) 2024 Joakim Antman
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # jwt-eddsa
2
2
 
3
- A library extending the ruby-jwt gem with EdDSA algorithms
3
+ [![Gem Version](https://badge.fury.io/rb/jwt-eddsa.svg)](https://badge.fury.io/rb/jwt-eddsa)
4
+ [![Build Status](https://github.com/anakinj/jwt-eddsa/workflows/test/badge.svg?branch=main)](https://github.com/jwt/ruby-jwt/actions)
5
+
6
+ A library extending the ruby-jwt gem with EdDSA algorithms. Based on [RFC 8037](https://datatracker.ietf.org/doc/html/rfc8037).
4
7
 
5
8
  **NOTE: This gem is still WIP**
6
9
 
@@ -13,6 +16,7 @@ Plan is to replace rbnacl with something else in the near future.
13
16
  Will only work with the WIP branch, so adding the following to your the Gemfile should do the trick:
14
17
  ```
15
18
  gem "jwt", github: "anakinj/ruby-jwt", branch: "extendable-algos"
19
+ gem "jwt-eddsa"
16
20
  ```
17
21
 
18
22
  ```
@@ -31,7 +35,7 @@ payload, header = JWT.decode(token, private_key.verify_key, true, algorithm: "Ed
31
35
 
32
36
  ```
33
37
  bundle install
34
- bundle exec rspec
38
+ bundle exec rake
35
39
  ```
36
40
 
37
41
  ## Contributing
data/Rakefile CHANGED
@@ -10,3 +10,12 @@ require "rubocop/rake_task"
10
10
  RuboCop::RakeTask.new
11
11
 
12
12
  task default: %i[spec rubocop]
13
+
14
+ task :check_version do
15
+ require_relative "lib/jwt/eddsa/version"
16
+ version = ENV.fetch("GEM_VERSION", nil)
17
+
18
+ raise "Version mismatch: #{JWT::EdDSA::VERSION} != #{version}" if version != JWT::EdDSA::VERSION
19
+ end
20
+
21
+ Rake::Task[:build].enhance([:check_version]) if ENV["CI"]
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWT
4
+ module EdDSA
5
+ # EdDSA algorithm implementation
6
+ module Algo
7
+ include JWT::JWA::Algorithm
8
+
9
+ register_algorithm("EdDSA")
10
+
11
+ class << self
12
+ def sign(_algorithm, msg, key)
13
+ unless key.is_a?(RbNaCl::Signatures::Ed25519::SigningKey)
14
+ raise_sign_error!("Key given is a #{key.class} but needs to be a " \
15
+ "RbNaCl::Signatures::Ed25519::SigningKey")
16
+ end
17
+
18
+ key.sign(msg)
19
+ end
20
+
21
+ def verify(_algorithm, public_key, signing_input, signature)
22
+ unless public_key.is_a?(RbNaCl::Signatures::Ed25519::VerifyKey)
23
+ raise_verify_error!("Key given is a #{public_key.class} but needs to be a " \
24
+ "RbNaCl::Signatures::Ed25519::VerifyKey")
25
+ end
26
+
27
+ public_key.verify(signature, signing_input)
28
+ rescue RbNaCl::CryptoError
29
+ false
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWT
4
+ module EdDSA
5
+ module JWK
6
+ # https://datatracker.ietf.org/doc/html/rfc8037
7
+ class OKP < ::JWT::JWK::KeyBase
8
+ KTY = "OKP"
9
+ KTYS = [KTY, JWT::EdDSA::JWK::OKP, RbNaCl::Signatures::Ed25519::SigningKey,
10
+ RbNaCl::Signatures::Ed25519::VerifyKey].freeze
11
+ OKP_PUBLIC_KEY_ELEMENTS = %i[kty n x].freeze
12
+ OKP_PRIVATE_KEY_ELEMENTS = %i[d].freeze
13
+
14
+ def initialize(key, params = nil, options = {})
15
+ params ||= {}
16
+ # For backwards compatibility when kid was a String
17
+ params = { kid: params } if params.is_a?(String)
18
+
19
+ key_params = extract_key_params(key)
20
+
21
+ params = params.transform_keys(&:to_sym)
22
+ check_jwk_params!(key_params, params)
23
+ super(options, key_params.merge(params))
24
+ end
25
+
26
+ def verify_key
27
+ return @verify_key if defined?(@verify_key)
28
+
29
+ @verify_key = verify_key_from_parameters
30
+ end
31
+
32
+ def signing_key
33
+ return @signing_key if defined?(@signing_key)
34
+
35
+ @signing_key = signing_key_from_parameters
36
+ end
37
+
38
+ def key_digest
39
+ ::JWT::JWK::Thumbprint.new(self).to_s
40
+ end
41
+
42
+ def private?
43
+ !signing_key.nil?
44
+ end
45
+
46
+ def members
47
+ OKP_PUBLIC_KEY_ELEMENTS.each_with_object({}) { |i, h| h[i] = self[i] }
48
+ end
49
+
50
+ def export(options = {})
51
+ exported = parameters.clone
52
+ unless private? && options[:include_private] == true
53
+ exported.reject! do |k, _|
54
+ OKP_PRIVATE_KEY_ELEMENTS.include?(k)
55
+ end
56
+ end
57
+ exported
58
+ end
59
+
60
+ private
61
+
62
+ def extract_key_params(key) # rubocop:disable Metrics/MethodLength
63
+ case key
64
+ when JWT::JWK::KeyBase
65
+ key.export(include_private: true)
66
+ when RbNaCl::Signatures::Ed25519::SigningKey
67
+ @signing_key = key
68
+ @verify_key = key.verify_key
69
+ parse_okp_key_params(@verify_key, @signing_key)
70
+ when RbNaCl::Signatures::Ed25519::VerifyKey
71
+ @signing_key = nil
72
+ @verify_key = key
73
+ parse_okp_key_params(@verify_key)
74
+ when Hash
75
+ key.transform_keys(&:to_sym)
76
+ else
77
+ raise ArgumentError,
78
+ "key must be of type RbNaCl::Signatures::Ed25519::SigningKey, " \
79
+ "RbNaCl::Signatures::Ed25519::VerifyKey " \
80
+ "or Hash with key parameters"
81
+ end
82
+ end
83
+
84
+ def check_jwk_params!(key_params, _given_params)
85
+ return if key_params[:kty] == KTY
86
+
87
+ raise JWT::JWKError,
88
+ "Incorrect 'kty' value: #{key_params[:kty]}, expected #{KTY}"
89
+ end
90
+
91
+ def parse_okp_key_params(verify_key, signing_key = nil)
92
+ params = {
93
+ kty: KTY,
94
+ crv: "Ed25519",
95
+ x: ::Base64.urlsafe_encode64(verify_key.to_bytes, padding: false)
96
+ }
97
+
98
+ params[:d] = ::Base64.urlsafe_encode64(signing_key.to_bytes, padding: false) if signing_key
99
+
100
+ params
101
+ end
102
+
103
+ def verify_key_from_parameters
104
+ RbNaCl::Signatures::Ed25519::VerifyKey.new(::Base64.urlsafe_decode64(self[:x]))
105
+ end
106
+
107
+ def signing_key_from_parameters
108
+ return nil unless self[:d]
109
+
110
+ RbNaCl::Signatures::Ed25519::SigningKey.new(::Base64.urlsafe_decode64(self[:d]))
111
+ end
112
+
113
+ class << self
114
+ def import(jwk_data)
115
+ new(jwk_data)
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JWT
4
- module Eddsa
5
- VERSION = "0.2.0"
4
+ module EdDSA
5
+ VERSION = "0.5.0"
6
6
  end
7
7
  end
data/lib/jwt/eddsa.rb CHANGED
@@ -1,33 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "jwt"
4
- require_relative "eddsa/version"
5
-
6
- module JWT
7
- # EdDSA algorithm implementation
8
- module Eddsa
9
- include JWT::JWA::Algorithm
10
-
11
- register_algorithm("EdDSA")
12
-
13
- class << self
14
- def sign(_algorithm, msg, key)
15
- unless key.is_a?(RbNaCl::Signatures::Ed25519::SigningKey)
16
- raise_sign_error!("Key given is a #{key.class} but needs to be a RbNaCl::Signatures::Ed25519::SigningKey")
17
- end
18
4
 
19
- key.sign(msg)
20
- end
21
-
22
- def verify(_algorithm, public_key, signing_input, signature)
23
- unless public_key.is_a?(RbNaCl::Signatures::Ed25519::VerifyKey)
24
- raise_verify_error!("Key given is a #{public_key.class} but needs to be a RbNaCl::Signatures::Ed25519::VerifyKey")
25
- end
26
-
27
- public_key.verify(signature, signing_input)
28
- rescue RbNaCl::CryptoError
29
- false
30
- end
31
- end
32
- end
33
- end
5
+ require_relative "eddsa/version"
6
+ require_relative "eddsa/jwk/okp"
7
+ require_relative "eddsa/algo"
@@ -0,0 +1,9 @@
1
+ {
2
+ "release-type": "ruby",
3
+ "include-v-in-tag": true,
4
+ "packages": {
5
+ ".": {
6
+ "version-file": "lib/jwt/eddsa/version.rb"
7
+ }
8
+ }
9
+ }
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwt-eddsa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joakim Antman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-01 00:00:00.000000000 Z
11
+ date: 2024-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: base64
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: jwt
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,13 +52,14 @@ dependencies:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
54
  version: '6.0'
41
- description:
55
+ description: Extends the ruby-jwt gem with EdDSA signing, verification and JWK importing/exporting
42
56
  email:
43
57
  - antmanj@gmail.com
44
58
  executables: []
45
59
  extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
62
+ - ".release-please-manifest.json"
48
63
  - ".rspec"
49
64
  - ".rubocop.yml"
50
65
  - ".ruby-version"
@@ -54,14 +69,17 @@ files:
54
69
  - README.md
55
70
  - Rakefile
56
71
  - lib/jwt/eddsa.rb
72
+ - lib/jwt/eddsa/algo.rb
73
+ - lib/jwt/eddsa/jwk/okp.rb
57
74
  - lib/jwt/eddsa/version.rb
75
+ - release-please-config.json
58
76
  homepage: https://github.com/anakinj/jwt-eddsa
59
77
  licenses:
60
78
  - MIT
61
79
  metadata:
62
80
  homepage_uri: https://github.com/anakinj/jwt-eddsa
63
81
  source_code_uri: https://github.com/anakinj/jwt-eddsa
64
- changelog_uri: https://github.com/anakinj/jwt-eddsablob/v0.2.0/CHANGELOG.md
82
+ changelog_uri: https://github.com/anakinj/jwt-eddsa/blob/v0.5.0/CHANGELOG.md
65
83
  rubygems_mfa_required: 'true'
66
84
  post_install_message:
67
85
  rdoc_options: []
@@ -81,5 +99,5 @@ requirements: []
81
99
  rubygems_version: 3.5.11
82
100
  signing_key:
83
101
  specification_version: 4
84
- summary: Extension for the jwt gem
102
+ summary: jwt EdDSA algorithm extension
85
103
  test_files: []