net-http-message_signatures 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 64f8815cbd95fadf8a82cb6ac9393e0e392a6a41151dd823fa80b5bf286c6113
4
+ data.tar.gz: af25488fb64fcb1e4093b7b0d6a4c6ada4c5dc911f1a28a2d767b61bad41ae3e
5
+ SHA512:
6
+ metadata.gz: 6382ae374a287d538133c13dffedde52bfdecfb8cbe9522b56517364c0f1968f293b8d6263efc6b4598f98682c3a036efd014f126e82fa4ef28af1b4e0bafd4a
7
+ data.tar.gz: e21f3d71b8255ada68c63f13d6762490d79c0274d555705af38900f03d5b6570524ae55b52c10bd3e2504bbafc73e45e92d0170507dc8d681ec40fcf961ed846
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,36 @@
1
+ require:
2
+ - rubocop-performance
3
+ - rubocop-rake
4
+ - rubocop-rspec
5
+
6
+ AllCops:
7
+ NewCops: enable
8
+
9
+ RSpec/ExampleLength:
10
+ Enabled: false
11
+
12
+ RSpec/FilePath:
13
+ Enabled: false
14
+
15
+ RSpec/NestedGroups:
16
+ Enabled: false
17
+
18
+ RSpec/SpecFilePathFormat:
19
+ Enabled: true
20
+ CustomTransform:
21
+ RSAPSSSHA512: rsa_pss_sha512
22
+
23
+ RSpec/SpecFilePathSuffix:
24
+ Enabled: true
25
+
26
+ Style/NumericLiterals:
27
+ Enabled: false
28
+
29
+ Style/TrailingCommaInArguments:
30
+ EnforcedStyleForMultiline: consistent_comma
31
+
32
+ Style/TrailingCommaInArrayLiteral:
33
+ EnforcedStyleForMultiline: consistent_comma
34
+
35
+ Style/TrailingCommaInHashLiteral:
36
+ EnforcedStyleForMultiline: consistent_comma
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.2.2
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in net-http-message_signatures.gemspec
6
+ gemspec
7
+
8
+ gem 'rake', '~> 13.0'
9
+ gem 'rspec', '~> 3.0'
10
+ gem 'rubocop', '~> 1.56'
11
+ gem 'rubocop-performance', '~> 1.19'
12
+ gem 'rubocop-rake', '~> 0.4'
13
+ gem 'rubocop-rspec', '~> 2.1'
14
+ gem 'simplecov', '~> 0.22'
15
+ gem 'simplecov-cobertura', '~> 2.1'
data/Gemfile.lock ADDED
@@ -0,0 +1,93 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ net-http-message_signatures (0.0.1)
5
+ net-http-structured_field_values (~> 0.3.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.4.2)
11
+ base64 (0.1.1)
12
+ diff-lcs (1.5.0)
13
+ docile (1.4.0)
14
+ json (2.6.3)
15
+ language_server-protocol (3.17.0.3)
16
+ net-http-structured_field_values (0.3.0)
17
+ parallel (1.23.0)
18
+ parser (3.2.2.4)
19
+ ast (~> 2.4.1)
20
+ racc
21
+ racc (1.7.1)
22
+ rainbow (3.1.1)
23
+ rake (13.0.6)
24
+ regexp_parser (2.8.2)
25
+ rexml (3.2.6)
26
+ rspec (3.12.0)
27
+ rspec-core (~> 3.12.0)
28
+ rspec-expectations (~> 3.12.0)
29
+ rspec-mocks (~> 3.12.0)
30
+ rspec-core (3.12.2)
31
+ rspec-support (~> 3.12.0)
32
+ rspec-expectations (3.12.3)
33
+ diff-lcs (>= 1.2.0, < 2.0)
34
+ rspec-support (~> 3.12.0)
35
+ rspec-mocks (3.12.6)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.12.0)
38
+ rspec-support (3.12.1)
39
+ rubocop (1.57.1)
40
+ base64 (~> 0.1.1)
41
+ json (~> 2.3)
42
+ language_server-protocol (>= 3.17.0)
43
+ parallel (~> 1.10)
44
+ parser (>= 3.2.2.4)
45
+ rainbow (>= 2.2.2, < 4.0)
46
+ regexp_parser (>= 1.8, < 3.0)
47
+ rexml (>= 3.2.5, < 4.0)
48
+ rubocop-ast (>= 1.28.1, < 2.0)
49
+ ruby-progressbar (~> 1.7)
50
+ unicode-display_width (>= 2.4.0, < 3.0)
51
+ rubocop-ast (1.29.0)
52
+ parser (>= 3.2.1.0)
53
+ rubocop-capybara (2.19.0)
54
+ rubocop (~> 1.41)
55
+ rubocop-factory_bot (2.24.0)
56
+ rubocop (~> 1.33)
57
+ rubocop-performance (1.19.1)
58
+ rubocop (>= 1.7.0, < 2.0)
59
+ rubocop-ast (>= 0.4.0)
60
+ rubocop-rake (0.6.0)
61
+ rubocop (~> 1.0)
62
+ rubocop-rspec (2.24.1)
63
+ rubocop (~> 1.33)
64
+ rubocop-capybara (~> 2.17)
65
+ rubocop-factory_bot (~> 2.22)
66
+ ruby-progressbar (1.13.0)
67
+ simplecov (0.22.0)
68
+ docile (~> 1.1)
69
+ simplecov-html (~> 0.11)
70
+ simplecov_json_formatter (~> 0.1)
71
+ simplecov-cobertura (2.1.0)
72
+ rexml
73
+ simplecov (~> 0.19)
74
+ simplecov-html (0.12.3)
75
+ simplecov_json_formatter (0.1.4)
76
+ unicode-display_width (2.5.0)
77
+
78
+ PLATFORMS
79
+ ruby
80
+
81
+ DEPENDENCIES
82
+ net-http-message_signatures!
83
+ rake (~> 13.0)
84
+ rspec (~> 3.0)
85
+ rubocop (~> 1.56)
86
+ rubocop-performance (~> 1.19)
87
+ rubocop-rake (~> 0.4)
88
+ rubocop-rspec (~> 2.1)
89
+ simplecov (~> 0.22)
90
+ simplecov-cobertura (~> 2.1)
91
+
92
+ BUNDLED WITH
93
+ 2.4.10
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 kyori19
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Net::HTTP::MessageSignatures
2
+
3
+ A Ruby implementation of [HTTP Message Signatures](https://httpwg.org/http-extensions/draft-ietf-httpbis-message-signatures.html).
4
+
5
+ ## Installation
6
+
7
+ Install the gem and add to the application's Gemfile by executing:
8
+
9
+ $ bundle add net-http-message_signatures
10
+
11
+ If bundler is not being used to manage dependencies, install the gem by executing:
12
+
13
+ $ gem install net-http-message_signatures
14
+
15
+ ## Usage
16
+
17
+ TODO: Write usage instructions here
18
+
19
+ ## Development
20
+
21
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
22
+
23
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
24
+
25
+ ## Contributing
26
+
27
+ Bug reports and pull requests are welcome on GitHub at https://github.com/kyori19/net-http-message_signatures.
28
+
29
+ ## License
30
+
31
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'openssl'
5
+
6
+ require 'net/http/message_signatures/signature_algorithm'
7
+
8
+ module Net
9
+ class HTTP
10
+ module MessageSignatures
11
+ # Implementation of the signature algorithm, RSASSA-PSS using SHA-512.
12
+ #
13
+ # @see {https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures-19#section-3.3.1}
14
+ class RSAPSSSHA512 < SignatureAlgorithm
15
+ # @return [OpenSSL::PKey::RSA] key material
16
+ attr_writer :key
17
+
18
+ # @param [OpenSSL::PKey::RSA] key key material
19
+ def initialize(key: nil)
20
+ super()
21
+ @key = key
22
+ end
23
+
24
+ def sign(message)
25
+ ensure_key!
26
+ key.sign_pss('SHA512', message, salt_length: 64, mgf1_hash: 'SHA512')
27
+ end
28
+
29
+ def verify(message, signature)
30
+ ensure_key!
31
+ key.verify_pss('SHA512', signature, message, salt_length: 64, mgf1_hash: 'SHA512')
32
+ end
33
+
34
+ private
35
+
36
+ # @return [OpenSSL::PKey::RSA, nil] key material
37
+ attr_reader :key
38
+
39
+ def ensure_key!
40
+ return if key.is_a? OpenSSL::PKey::RSA
41
+
42
+ raise InvalidAlgorithm, 'signature algorithm and key does not match'
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+
5
+ require 'net/http/structured_field_values'
6
+
7
+ module Net
8
+ class HTTP
9
+ module MessageSignatures
10
+ # An HTTP Message Signature with its covered components and parameters.
11
+ #
12
+ # @see {https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures-19#section-3}
13
+ class Signature
14
+ include StructuredFieldValues
15
+
16
+ # @return [String, nil] signature value in binary
17
+ attr_accessor :signature
18
+ # @return [Hash{String, ParameterizedValue => String}] map of covered components' name (and optional params) and
19
+ # value
20
+ attr_reader :covered_components
21
+ # @return [Hash{String => Object}] map of signature parameters' name and value
22
+ attr_reader :params
23
+ # @return [SignatureAlgorithm] signature algorithm which can be used without key material
24
+ attr_writer :algorithm
25
+
26
+ # @param [String] signature signature value in binary
27
+ # @param [Hash{String, ParameterizedValue => String}] covered_components map of covered components' name (and
28
+ # optional params) and value
29
+ # @param [Hash{String => Object}] params map of signature parameters' name and value
30
+ # @param [SignatureAlgorithm] algorithm signature algorithm which can be used without key material
31
+ def initialize(signature: nil, covered_components: {}, params: {}, algorithm: nil)
32
+ @signature = signature
33
+ @covered_components = covered_components
34
+ @params = params
35
+ @algorithm = algorithm
36
+ end
37
+
38
+ # Verifies the signature.
39
+ # Will raise error if it is invalid.
40
+ #
41
+ # @see {https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures-19#section-3.2}
42
+ def verify!
43
+ return if algorithm.verify(signature_base, signature)
44
+
45
+ raise VerificationError, 'signature verification failed'
46
+ end
47
+
48
+ private
49
+
50
+ # @return [SignatureAlgorithm, nil] signature algorithm which can be used without key material
51
+ attr_reader :algorithm
52
+
53
+ # Creates the signature parameters component value.
54
+ #
55
+ # @see {https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures-19#section-2.3}
56
+ #
57
+ # @return [ParameterizedValue] the signature parameters component value
58
+ def signature_params
59
+ ParameterizedValue.new(covered_components.keys, params)
60
+ end
61
+
62
+ # Creates the signature base from HTTP message components covered by the signature.
63
+ #
64
+ # @see {https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures-19#section-2.5}
65
+ #
66
+ # @return [String] the signature base
67
+ def signature_base
68
+ components = covered_components
69
+ .merge({ '@signature-params' => Serializer.serialize_as_inner_list(signature_params) })
70
+ components.map do |name, value|
71
+ serialized_name = Serializer.serialize(name)
72
+ "#{serialized_name}: #{value}"
73
+ end.join("\n").encode(Encoding::ASCII)
74
+ end
75
+
76
+ class VerificationError < StandardError; end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+
5
+ module Net
6
+ class HTTP
7
+ module MessageSignatures
8
+ # Abstract representation of HTTP Signature Algorithms.
9
+ #
10
+ # To instantiate this class, you must pass the key material.
11
+ # With that instance, both of HTTP_SIGN and HTTP_VERIFY method can be used without passing key material.
12
+ #
13
+ # @see {https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures-19#section-3.3}
14
+ class SignatureAlgorithm
15
+ # HTTP_SIGN method which can be used without signing key material
16
+ #
17
+ # @param [String] message the signature base in binary
18
+ # @return [String] the signature in binary
19
+ def sign(message)
20
+ # :nocov:
21
+ raise NotImplementedError, 'signature algorithm must implement #sign'
22
+ # :nocov:
23
+ end
24
+
25
+ # HTTP_VERIFY method which can be used without verification key material
26
+ #
27
+ # @param [String] message the signature base in binary
28
+ # @param [String] signature the signature in binary
29
+ # @return [Boolean] whether signature is valid or not
30
+ def verify(message, signature)
31
+ # :nocov:
32
+ raise NotImplementedError, 'signature algorithm must implement #verify'
33
+ # :nocov:
34
+ end
35
+
36
+ class InvalidAlgorithm < StandardError; end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+
5
+ module Net
6
+ class HTTP
7
+ module MessageSignatures
8
+ VERSION = '0.0.1'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+
5
+ require_relative 'message_signatures/version'
6
+
7
+ module Net
8
+ class HTTP
9
+ # A Ruby implementation of HTTP Message Signatures.
10
+ #
11
+ # @see {https://httpwg.org/http-extensions/draft-ietf-httpbis-message-signatures.html}
12
+ module MessageSignatures
13
+ end
14
+ end
15
+ end
data/renovate.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "config:base"
5
+ ]
6
+ }
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: net-http-message_signatures
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - kyori19
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-10-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: net-http-structured_field_values
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.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.3.0
27
+ description:
28
+ email:
29
+ - kyori@accelf.net
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".rspec"
35
+ - ".rubocop.yml"
36
+ - ".ruby-version"
37
+ - Gemfile
38
+ - Gemfile.lock
39
+ - LICENSE.txt
40
+ - README.md
41
+ - Rakefile
42
+ - lib/net/http/message_signatures.rb
43
+ - lib/net/http/message_signatures/rsa_pss_sha512.rb
44
+ - lib/net/http/message_signatures/signature.rb
45
+ - lib/net/http/message_signatures/signature_algorithm.rb
46
+ - lib/net/http/message_signatures/version.rb
47
+ - renovate.json
48
+ homepage: https://github.com/kyori19/net-http-message_signatures
49
+ licenses:
50
+ - MIT
51
+ metadata:
52
+ allowed_push_host: https://rubygems.org
53
+ rubygems_mfa_required: 'true'
54
+ homepage_uri: https://github.com/kyori19/net-http-message_signatures
55
+ source_code_uri: https://github.com/kyori19/net-http-message_signatures
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '3.2'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubygems_version: 3.4.10
72
+ signing_key:
73
+ specification_version: 4
74
+ summary: A Ruby implementation of HTTP Message Signatures
75
+ test_files: []