linzer 0.7.7 → 0.7.8
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 +5 -0
- data/LICENSE.txt +1 -1
- data/README.md +3 -1
- data/flake.lock +109 -0
- data/flake.nix +73 -0
- data/lib/linzer/common.rb +51 -0
- data/lib/linzer/ecdsa.rb +51 -0
- data/lib/linzer/ed25519.rb +35 -0
- data/lib/linzer/helper.rb +79 -0
- data/lib/linzer/hmac.rb +47 -1
- data/lib/linzer/http/bootstrap.rb +11 -0
- data/lib/linzer/http/signature_feature.rb +53 -1
- data/lib/linzer/http.rb +54 -0
- data/lib/linzer/jws.rb +74 -0
- data/lib/linzer/key/helper.rb +186 -10
- data/lib/linzer/key.rb +73 -0
- data/lib/linzer/message/adapter/abstract.rb +75 -10
- data/lib/linzer/message/adapter/generic/request.rb +27 -0
- data/lib/linzer/message/adapter/generic/response.rb +17 -0
- data/lib/linzer/message/adapter/http_gem/request.rb +11 -0
- data/lib/linzer/message/adapter/http_gem/response.rb +8 -5
- data/lib/linzer/message/adapter/net_http/request.rb +7 -0
- data/lib/linzer/message/adapter/net_http/response.rb +4 -0
- data/lib/linzer/message/adapter/rack/common.rb +14 -6
- data/lib/linzer/message/adapter/rack/request.rb +13 -0
- data/lib/linzer/message/adapter/rack/response.rb +11 -0
- data/lib/linzer/message/adapter.rb +17 -0
- data/lib/linzer/message/field/parser.rb +14 -0
- data/lib/linzer/message/field.rb +32 -2
- data/lib/linzer/message/wrapper.rb +20 -0
- data/lib/linzer/message.rb +113 -3
- data/lib/linzer/options.rb +13 -0
- data/lib/linzer/rsa.rb +34 -0
- data/lib/linzer/rsa_pss.rb +44 -0
- data/lib/linzer/signature.rb +113 -1
- data/lib/linzer/signer.rb +69 -0
- data/lib/linzer/verifier.rb +52 -0
- data/lib/linzer/version.rb +3 -1
- data/lib/linzer.rb +104 -0
- data/lib/rack/auth/signature.rb +90 -6
- metadata +30 -16
data/lib/linzer/verifier.rb
CHANGED
|
@@ -1,10 +1,57 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Linzer
|
|
4
|
+
# Handles HTTP message signature verification according to RFC 9421.
|
|
5
|
+
#
|
|
6
|
+
# This module verifies that a signature on an HTTP message is valid by:
|
|
7
|
+
# 1. Reconstructing the signature base from the message and signature parameters
|
|
8
|
+
# 2. Verifying the signature using the provided public key
|
|
9
|
+
#
|
|
10
|
+
# @example Direct usage (prefer Linzer.verify for convenience)
|
|
11
|
+
# signature = Linzer::Signature.build(signature_headers)
|
|
12
|
+
# message = Linzer::Message.new(request)
|
|
13
|
+
# Linzer::Verifier.verify(pubkey, message, signature)
|
|
14
|
+
#
|
|
15
|
+
# @see https://www.rfc-editor.org/rfc/rfc9421.html#section-3.2 RFC 9421 Section 3.2
|
|
4
16
|
module Verifier
|
|
5
17
|
class << self
|
|
6
18
|
include Common
|
|
7
19
|
|
|
20
|
+
# Verifies an HTTP message signature.
|
|
21
|
+
#
|
|
22
|
+
# Verification succeeds if:
|
|
23
|
+
# - All covered components exist in the message
|
|
24
|
+
# - The signature base matches what was signed
|
|
25
|
+
# - The cryptographic signature is valid for the public key
|
|
26
|
+
# - The signature is not older than `no_older_than` (if specified)
|
|
27
|
+
#
|
|
28
|
+
# @param key [Linzer::Key] The public key to verify with. Must respond to
|
|
29
|
+
# `#verify` and should contain public key material.
|
|
30
|
+
# @param message [Linzer::Message] The HTTP message to verify
|
|
31
|
+
# @param signature [Linzer::Signature] The signature to verify. Typically
|
|
32
|
+
# built from the `signature` and `signature-input` headers using
|
|
33
|
+
# {Signature.build}.
|
|
34
|
+
# @param no_older_than [Integer, nil] Maximum age in seconds. If the
|
|
35
|
+
# signature's `created` parameter is older than this, verification fails.
|
|
36
|
+
# This helps mitigate replay attacks. See RFC 9421 Section 7.2.2.
|
|
37
|
+
#
|
|
38
|
+
# @return [true] Returns true if verification succeeds
|
|
39
|
+
#
|
|
40
|
+
# @raise [VerifyError] If the message is nil
|
|
41
|
+
# @raise [VerifyError] If the key is nil
|
|
42
|
+
# @raise [VerifyError] If the signature is nil or invalid
|
|
43
|
+
# @raise [VerifyError] If required components are missing from the message
|
|
44
|
+
# @raise [VerifyError] If the signature is too old (when no_older_than is set)
|
|
45
|
+
# @raise [VerifyError] If the cryptographic verification fails
|
|
46
|
+
#
|
|
47
|
+
# @example Basic verification
|
|
48
|
+
# Linzer::Verifier.verify(pubkey, message, signature)
|
|
49
|
+
# # => true (or raises VerifyError)
|
|
50
|
+
#
|
|
51
|
+
# @example With age validation (5 minute window)
|
|
52
|
+
# Linzer::Verifier.verify(pubkey, message, signature, no_older_than: 300)
|
|
53
|
+
#
|
|
54
|
+
# @see https://www.rfc-editor.org/rfc/rfc9421.html#section-7.2.2 Signature Replay
|
|
8
55
|
def verify(key, message, signature, no_older_than: nil)
|
|
9
56
|
validate message, key, signature, no_older_than: no_older_than
|
|
10
57
|
|
|
@@ -18,6 +65,8 @@ module Linzer
|
|
|
18
65
|
|
|
19
66
|
private
|
|
20
67
|
|
|
68
|
+
# Validates all verification inputs before attempting verification.
|
|
69
|
+
# @raise [VerifyError] If any input is invalid or signature is too old
|
|
21
70
|
def validate(message, key, signature, no_older_than: nil)
|
|
22
71
|
raise VerifyError, "Message to verify cannot be null" if message.nil?
|
|
23
72
|
raise VerifyError, "Key to verify signature cannot be null" if key.nil?
|
|
@@ -45,6 +94,9 @@ module Linzer
|
|
|
45
94
|
end
|
|
46
95
|
end
|
|
47
96
|
|
|
97
|
+
# Performs cryptographic verification and raises on failure.
|
|
98
|
+
# @return [true] If verification succeeds
|
|
99
|
+
# @raise [VerifyError] If verification fails
|
|
48
100
|
def verify_or_fail(key, signature, data)
|
|
49
101
|
return true if key.verify(signature, data)
|
|
50
102
|
raise VerifyError, "Failed to verify message: Invalid signature."
|
data/lib/linzer/version.rb
CHANGED
data/lib/linzer.rb
CHANGED
|
@@ -28,30 +28,134 @@ require_relative "linzer/signer"
|
|
|
28
28
|
require_relative "linzer/verifier"
|
|
29
29
|
require_relative "linzer/http"
|
|
30
30
|
|
|
31
|
+
# Linzer is a Ruby library for HTTP Message Signatures as defined in RFC 9421.
|
|
32
|
+
#
|
|
33
|
+
# It provides functionality to sign and verify HTTP messages using various
|
|
34
|
+
# cryptographic algorithms including RSA-PSS, HMAC-SHA256, ECDSA, and Ed25519.
|
|
35
|
+
#
|
|
36
|
+
# @example Signing a request with Ed25519
|
|
37
|
+
# key = Linzer.generate_ed25519_key("my-key-id")
|
|
38
|
+
# request = Net::HTTP::Post.new(URI("https://example.com/api"))
|
|
39
|
+
# request["date"] = Time.now.httpdate
|
|
40
|
+
#
|
|
41
|
+
# Linzer.sign!(request,
|
|
42
|
+
# key: key,
|
|
43
|
+
# components: %w[@method @request-target date]
|
|
44
|
+
# )
|
|
45
|
+
#
|
|
46
|
+
# @example Verifying a signed request
|
|
47
|
+
# pubkey = Linzer.new_ed25519_public_key(public_key_pem, "my-key-id")
|
|
48
|
+
# Linzer.verify!(request, key: pubkey)
|
|
49
|
+
#
|
|
50
|
+
# @see https://www.rfc-editor.org/rfc/rfc9421.html RFC 9421 - HTTP Message Signatures
|
|
51
|
+
# @see https://github.com/nomadium Author on GitHub
|
|
52
|
+
# @author Miguel Landaeta
|
|
31
53
|
module Linzer
|
|
54
|
+
# Base error class for all Linzer errors.
|
|
55
|
+
# @see VerifyError
|
|
56
|
+
# @see SigningError
|
|
32
57
|
class Error < StandardError; end
|
|
33
58
|
|
|
59
|
+
# Raised when signature verification fails.
|
|
60
|
+
#
|
|
61
|
+
# @example Handling verification errors
|
|
62
|
+
# begin
|
|
63
|
+
# Linzer.verify(pubkey, message, signature)
|
|
64
|
+
# rescue Linzer::VerifyError => e
|
|
65
|
+
# puts "Verification failed: #{e.message}"
|
|
66
|
+
# end
|
|
34
67
|
class VerifyError < Error; end
|
|
35
68
|
|
|
69
|
+
# Raised when message signing fails.
|
|
70
|
+
#
|
|
71
|
+
# @example Handling signing errors
|
|
72
|
+
# begin
|
|
73
|
+
# Linzer.sign(key, message, components)
|
|
74
|
+
# rescue Linzer::SigningError => e
|
|
75
|
+
# puts "Signing failed: #{e.message}"
|
|
76
|
+
# end
|
|
36
77
|
class SigningError < Error; end
|
|
37
78
|
|
|
38
79
|
class << self
|
|
39
80
|
include Key::Helper
|
|
40
81
|
include Helper
|
|
41
82
|
|
|
83
|
+
# Verifies an HTTP message signature.
|
|
84
|
+
#
|
|
85
|
+
# @param pubkey [Linzer::Key] The public key to verify the signature with
|
|
86
|
+
# @param message [Linzer::Message] The HTTP message to verify
|
|
87
|
+
# @param signature [Linzer::Signature] The signature to verify
|
|
88
|
+
# @param no_older_than [Integer, nil] Maximum age of signature in seconds.
|
|
89
|
+
# If provided, signatures with a `created` timestamp older than this
|
|
90
|
+
# value will be rejected to mitigate replay attacks.
|
|
91
|
+
#
|
|
92
|
+
# @return [true] Returns true if verification succeeds
|
|
93
|
+
# @raise [VerifyError] If verification fails for any reason
|
|
94
|
+
#
|
|
95
|
+
# @example Basic verification
|
|
96
|
+
# Linzer.verify(pubkey, message, signature)
|
|
97
|
+
#
|
|
98
|
+
# @example Verification with age limit (reject signatures older than 5 minutes)
|
|
99
|
+
# Linzer.verify(pubkey, message, signature, no_older_than: 300)
|
|
100
|
+
#
|
|
101
|
+
# @see Linzer::Verifier.verify
|
|
42
102
|
def verify(pubkey, message, signature, no_older_than: nil)
|
|
43
103
|
Linzer::Verifier.verify(pubkey, message, signature, no_older_than: no_older_than)
|
|
44
104
|
end
|
|
45
105
|
|
|
106
|
+
# Signs an HTTP message.
|
|
107
|
+
#
|
|
108
|
+
# @param key [Linzer::Key] The private key to sign with
|
|
109
|
+
# @param message [Linzer::Message] The HTTP message to sign
|
|
110
|
+
# @param components [Array<String>] The message components to include in
|
|
111
|
+
# the signature (e.g., `["@method", "@path", "content-type"]`)
|
|
112
|
+
# @param options [Hash] Additional signature parameters
|
|
113
|
+
# @option options [Integer] :created Unix timestamp for signature creation
|
|
114
|
+
# (defaults to current time)
|
|
115
|
+
# @option options [String] :keyid Key identifier to include in signature
|
|
116
|
+
# @option options [String] :label Signature label (defaults to "sig1")
|
|
117
|
+
# @option options [String] :nonce A unique nonce value
|
|
118
|
+
# @option options [String] :tag Application-specific tag
|
|
119
|
+
# @option options [Integer] :expires Unix timestamp for signature expiration
|
|
120
|
+
#
|
|
121
|
+
# @return [Linzer::Signature] The generated signature
|
|
122
|
+
# @raise [SigningError] If signing fails
|
|
123
|
+
#
|
|
124
|
+
# @example Sign with default options
|
|
125
|
+
# signature = Linzer.sign(key, message, %w[@method @path date])
|
|
126
|
+
#
|
|
127
|
+
# @example Sign with custom parameters
|
|
128
|
+
# signature = Linzer.sign(key, message, %w[@method @path],
|
|
129
|
+
# keyid: "my-key",
|
|
130
|
+
# created: Time.now.to_i,
|
|
131
|
+
# nonce: SecureRandom.hex(16)
|
|
132
|
+
# )
|
|
133
|
+
#
|
|
134
|
+
# @see Linzer::Signer.sign
|
|
46
135
|
def sign(key, message, components, options = {})
|
|
47
136
|
Linzer::Signer.sign(key, message, components, options)
|
|
48
137
|
end
|
|
49
138
|
|
|
139
|
+
# Computes the signature base string for an HTTP message.
|
|
140
|
+
#
|
|
141
|
+
# The signature base is the canonical string representation that gets
|
|
142
|
+
# signed. This method is primarily useful for debugging or implementing
|
|
143
|
+
# custom signing logic.
|
|
144
|
+
#
|
|
145
|
+
# @param message [Linzer::Message] The HTTP message
|
|
146
|
+
# @param components [Array<String>] Serialized component identifiers
|
|
147
|
+
# @param parameters [Hash] Signature parameters
|
|
148
|
+
#
|
|
149
|
+
# @return [String] The signature base string
|
|
150
|
+
#
|
|
151
|
+
# @see https://www.rfc-editor.org/rfc/rfc9421.html#section-2.5 RFC 9421 Section 2.5
|
|
50
152
|
def signature_base(message, components, parameters)
|
|
51
153
|
Linzer::Common.signature_base(message, components, parameters)
|
|
52
154
|
end
|
|
53
155
|
end
|
|
54
156
|
|
|
157
|
+
# Alias for {Message::Field::Identifier} for convenient access.
|
|
158
|
+
# Used for serializing and deserializing component identifiers.
|
|
55
159
|
FieldId = Message::Field::Identifier
|
|
56
160
|
end
|
|
57
161
|
|
data/lib/rack/auth/signature.rb
CHANGED
|
@@ -4,23 +4,96 @@ require "linzer"
|
|
|
4
4
|
require "logger"
|
|
5
5
|
require_relative "signature/helpers"
|
|
6
6
|
|
|
7
|
-
# Rack::Auth::Signature implements HTTP Message Signatures, as per RFC 9421.
|
|
8
|
-
#
|
|
9
|
-
# Initialize with the Rack application that you want protecting.
|
|
10
|
-
# A hash with options and a block can be passed to customize, enhance
|
|
11
|
-
# or disable security checks applied to incoming requests.
|
|
12
|
-
#
|
|
13
7
|
module Rack
|
|
14
8
|
module Auth
|
|
9
|
+
# Rack middleware for HTTP Message Signature verification (RFC 9421).
|
|
10
|
+
#
|
|
11
|
+
# This middleware verifies that incoming requests have valid HTTP signatures.
|
|
12
|
+
# Requests without valid signatures are rejected with a 401 Unauthorized response.
|
|
13
|
+
#
|
|
14
|
+
# @example Basic usage in config.ru
|
|
15
|
+
# require "linzer"
|
|
16
|
+
#
|
|
17
|
+
# use Rack::Auth::Signature,
|
|
18
|
+
# except: "/health",
|
|
19
|
+
# default_key: {
|
|
20
|
+
# material: File.read("public_key.pem"),
|
|
21
|
+
# alg: "ed25519"
|
|
22
|
+
# }
|
|
23
|
+
#
|
|
24
|
+
# run MyApp
|
|
25
|
+
#
|
|
26
|
+
# @example With configuration file
|
|
27
|
+
# use Rack::Auth::Signature,
|
|
28
|
+
# except: ["/login", "/health"],
|
|
29
|
+
# config_path: "config/http-signatures.yml"
|
|
30
|
+
#
|
|
31
|
+
# @example In a Rails application (config/application.rb)
|
|
32
|
+
# config.middleware.use Rack::Auth::Signature,
|
|
33
|
+
# except: "/login",
|
|
34
|
+
# config_path: "config/http-signatures.yml"
|
|
35
|
+
#
|
|
36
|
+
# @example With a block for custom configuration
|
|
37
|
+
# use Rack::Auth::Signature do
|
|
38
|
+
# # Custom configuration via instance_eval
|
|
39
|
+
# end
|
|
40
|
+
#
|
|
41
|
+
# Configuration file format (YAML):
|
|
42
|
+
#
|
|
43
|
+
# signatures:
|
|
44
|
+
# reject_older_than: 900 # Reject signatures older than 15 minutes
|
|
45
|
+
# created_required: true # Require 'created' parameter
|
|
46
|
+
# keyid_required: false # Require 'keyid' parameter
|
|
47
|
+
# covered_components: # Required components in signature
|
|
48
|
+
# - "@method"
|
|
49
|
+
# - "@request-target"
|
|
50
|
+
# - "date"
|
|
51
|
+
# keys:
|
|
52
|
+
# my-key-id:
|
|
53
|
+
# alg: ed25519
|
|
54
|
+
# material: | # Inline PEM
|
|
55
|
+
# -----BEGIN PUBLIC KEY-----
|
|
56
|
+
# ...
|
|
57
|
+
# -----END PUBLIC KEY-----
|
|
58
|
+
# other-key:
|
|
59
|
+
# alg: rsa-pss-sha512
|
|
60
|
+
# path: keys/public.pem # Or path to key file
|
|
61
|
+
#
|
|
62
|
+
# @see https://www.rfc-editor.org/rfc/rfc9421.html RFC 9421
|
|
63
|
+
# @see Helpers::Configuration For configuration options
|
|
64
|
+
# @see Helpers::Key For key lookup behavior
|
|
15
65
|
class Signature
|
|
16
66
|
include Helpers
|
|
17
67
|
|
|
68
|
+
# Creates a new signature verification middleware.
|
|
69
|
+
#
|
|
70
|
+
# @param app [#call] The Rack application to protect
|
|
71
|
+
# @param options [Hash] Configuration options
|
|
72
|
+
# @option options [String, Array<String>] :except Paths to exclude from
|
|
73
|
+
# signature verification (e.g., "/login", "/health")
|
|
74
|
+
# @option options [String] :config_path Path to YAML configuration file
|
|
75
|
+
# @option options [Hash] :default_key Default key configuration when
|
|
76
|
+
# keyid is not present or not found in keys hash
|
|
77
|
+
# @option options [Hash] :keys Hash of key configurations keyed by keyid
|
|
78
|
+
# @option options [Hash] :signatures Signature verification options
|
|
79
|
+
#
|
|
80
|
+
# @yield Optional block for additional configuration via instance_eval
|
|
18
81
|
def initialize(app, options = {}, &block)
|
|
19
82
|
@app = app
|
|
20
83
|
@options = load_options(Hash(options))
|
|
21
84
|
instance_eval(&block) if block
|
|
22
85
|
end
|
|
23
86
|
|
|
87
|
+
# Processes an incoming request.
|
|
88
|
+
#
|
|
89
|
+
# If the request path is excluded or the signature is valid, the request
|
|
90
|
+
# is passed to the wrapped application. Otherwise, returns a 401 response.
|
|
91
|
+
#
|
|
92
|
+
# On successful verification, the signature is stored in `env["rack.signature"]`
|
|
93
|
+
# for use by the application.
|
|
94
|
+
#
|
|
95
|
+
# @param env [Hash] The Rack environment
|
|
96
|
+
# @return [Array] Rack response tuple [status, headers, body]
|
|
24
97
|
def call(env)
|
|
25
98
|
@request = Rack::Request.new(env)
|
|
26
99
|
|
|
@@ -34,25 +107,30 @@ module Rack
|
|
|
34
107
|
|
|
35
108
|
private
|
|
36
109
|
|
|
110
|
+
# Checks if the current request path is excluded from verification.
|
|
37
111
|
def excluded?
|
|
38
112
|
return false if !request
|
|
39
113
|
Array(options[:except]).include?(request.path_info)
|
|
40
114
|
end
|
|
41
115
|
|
|
116
|
+
# Checks if the request should be allowed (has valid signature).
|
|
42
117
|
def allowed?
|
|
43
118
|
has_signature? && acceptable? && verifiable?
|
|
44
119
|
end
|
|
45
120
|
|
|
46
121
|
attr_reader :request, :options
|
|
47
122
|
|
|
123
|
+
# Returns the signature parameters.
|
|
48
124
|
def params
|
|
49
125
|
@signature.parameters || {}
|
|
50
126
|
end
|
|
51
127
|
|
|
128
|
+
# Returns the logger instance.
|
|
52
129
|
def logger
|
|
53
130
|
@logger ||= request.logger || ::Logger.new($stderr)
|
|
54
131
|
end
|
|
55
132
|
|
|
133
|
+
# Checks if the request has signature headers.
|
|
56
134
|
def has_signature?
|
|
57
135
|
@signature = build_signature
|
|
58
136
|
(@signature.to_h.keys & %w[signature signature-input]).size == 2
|
|
@@ -61,6 +139,7 @@ module Rack
|
|
|
61
139
|
false
|
|
62
140
|
end
|
|
63
141
|
|
|
142
|
+
# Builds a Signature object from request headers.
|
|
64
143
|
def build_signature
|
|
65
144
|
signature_opts = {}
|
|
66
145
|
label = options[:signatures][:default_label]
|
|
@@ -77,6 +156,7 @@ module Rack
|
|
|
77
156
|
signature
|
|
78
157
|
end
|
|
79
158
|
|
|
159
|
+
# Checks if required signature parameters are present.
|
|
80
160
|
def has_required_params?
|
|
81
161
|
created? && expires? && keyid? && nonce? && alg? && tag?
|
|
82
162
|
rescue => ex
|
|
@@ -84,6 +164,7 @@ module Rack
|
|
|
84
164
|
false
|
|
85
165
|
end
|
|
86
166
|
|
|
167
|
+
# Checks if required components are covered by the signature.
|
|
87
168
|
def has_required_components?
|
|
88
169
|
components = @signature.serialized_components || []
|
|
89
170
|
covered_components = options[:signatures][:covered_components]
|
|
@@ -92,10 +173,12 @@ module Rack
|
|
|
92
173
|
(covered_components || []).all? { |c| components.include?(c) }
|
|
93
174
|
end
|
|
94
175
|
|
|
176
|
+
# Checks if the signature meets all requirements.
|
|
95
177
|
def acceptable?
|
|
96
178
|
has_required_params? && has_required_components?
|
|
97
179
|
end
|
|
98
180
|
|
|
181
|
+
# Verifies the signature cryptographically.
|
|
99
182
|
def verifiable?
|
|
100
183
|
verify_opts = build_and_check_verify_opts || {}
|
|
101
184
|
Linzer.verify(key, @message, @signature, **verify_opts)
|
|
@@ -104,6 +187,7 @@ module Rack
|
|
|
104
187
|
false
|
|
105
188
|
end
|
|
106
189
|
|
|
190
|
+
# Builds verification options and logs warnings for security issues.
|
|
107
191
|
def build_and_check_verify_opts
|
|
108
192
|
verify_opts = {}
|
|
109
193
|
reject_older = options[:signatures][:reject_older_than]
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: linzer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.7.
|
|
4
|
+
version: 0.7.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Miguel Landaeta
|
|
@@ -13,22 +13,22 @@ dependencies:
|
|
|
13
13
|
name: openssl
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "~>"
|
|
17
|
-
- !ruby/object:Gem::Version
|
|
18
|
-
version: '3.0'
|
|
19
16
|
- - ">="
|
|
20
17
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 3
|
|
18
|
+
version: '3'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '5'
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
25
|
requirements:
|
|
26
|
-
- - "~>"
|
|
27
|
-
- !ruby/object:Gem::Version
|
|
28
|
-
version: '3.0'
|
|
29
26
|
- - ">="
|
|
30
27
|
- !ruby/object:Gem::Version
|
|
31
|
-
version: 3
|
|
28
|
+
version: '3'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '5'
|
|
32
32
|
- !ruby/object:Gem::Dependency
|
|
33
33
|
name: starry
|
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -147,30 +147,42 @@ dependencies:
|
|
|
147
147
|
name: net-http
|
|
148
148
|
requirement: !ruby/object:Gem::Requirement
|
|
149
149
|
requirements:
|
|
150
|
-
- - "
|
|
150
|
+
- - ">="
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: 0.6
|
|
152
|
+
version: '0.6'
|
|
153
|
+
- - "<"
|
|
154
|
+
- !ruby/object:Gem::Version
|
|
155
|
+
version: '0.10'
|
|
153
156
|
type: :runtime
|
|
154
157
|
prerelease: false
|
|
155
158
|
version_requirements: !ruby/object:Gem::Requirement
|
|
156
159
|
requirements:
|
|
157
|
-
- - "
|
|
160
|
+
- - ">="
|
|
158
161
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: 0.6
|
|
162
|
+
version: '0.6'
|
|
163
|
+
- - "<"
|
|
164
|
+
- !ruby/object:Gem::Version
|
|
165
|
+
version: '0.10'
|
|
160
166
|
- !ruby/object:Gem::Dependency
|
|
161
167
|
name: cgi
|
|
162
168
|
requirement: !ruby/object:Gem::Requirement
|
|
163
169
|
requirements:
|
|
164
|
-
- - "
|
|
170
|
+
- - ">="
|
|
165
171
|
- !ruby/object:Gem::Version
|
|
166
172
|
version: 0.4.2
|
|
173
|
+
- - "<"
|
|
174
|
+
- !ruby/object:Gem::Version
|
|
175
|
+
version: 0.6.0
|
|
167
176
|
type: :runtime
|
|
168
177
|
prerelease: false
|
|
169
178
|
version_requirements: !ruby/object:Gem::Requirement
|
|
170
179
|
requirements:
|
|
171
|
-
- - "
|
|
180
|
+
- - ">="
|
|
172
181
|
- !ruby/object:Gem::Version
|
|
173
182
|
version: 0.4.2
|
|
183
|
+
- - "<"
|
|
184
|
+
- !ruby/object:Gem::Version
|
|
185
|
+
version: 0.6.0
|
|
174
186
|
email:
|
|
175
187
|
- miguel@miguel.cc
|
|
176
188
|
executables: []
|
|
@@ -188,6 +200,8 @@ files:
|
|
|
188
200
|
- examples/sinatra/config.ru
|
|
189
201
|
- examples/sinatra/http-signatures.yml
|
|
190
202
|
- examples/sinatra/myapp.rb
|
|
203
|
+
- flake.lock
|
|
204
|
+
- flake.nix
|
|
191
205
|
- lib/linzer.rb
|
|
192
206
|
- lib/linzer/common.rb
|
|
193
207
|
- lib/linzer/ecdsa.rb
|
|
@@ -245,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
245
259
|
- !ruby/object:Gem::Version
|
|
246
260
|
version: '0'
|
|
247
261
|
requirements: []
|
|
248
|
-
rubygems_version: 3.6.
|
|
262
|
+
rubygems_version: 3.6.8
|
|
249
263
|
specification_version: 4
|
|
250
264
|
summary: An implementation of HTTP Messages Signatures (RFC9421)
|
|
251
265
|
test_files: []
|