sealights-rspec-agent 2.0.4 → 2.0.5

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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/agent/config.rb +6 -6
  3. data/agent/dependencies/faraday-0.17.0/LICENSE.md +20 -0
  4. data/agent/dependencies/faraday-0.17.0/README.md +384 -0
  5. data/agent/dependencies/faraday-0.17.0/lib/faraday.rb +248 -0
  6. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter.rb +55 -0
  7. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/em_http.rb +243 -0
  8. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/em_synchrony.rb +106 -0
  9. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/em_synchrony/parallel_manager.rb +66 -0
  10. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/excon.rb +82 -0
  11. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/httpclient.rb +128 -0
  12. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/net_http.rb +152 -0
  13. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/net_http_persistent.rb +68 -0
  14. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/patron.rb +95 -0
  15. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/rack.rb +58 -0
  16. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/sl_em_http_ssl_patch.rb +56 -0
  17. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/test.rb +213 -0
  18. data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/typhoeus.rb +12 -0
  19. data/agent/dependencies/faraday-0.17.0/lib/faraday/autoload.rb +84 -0
  20. data/agent/dependencies/faraday-0.17.0/lib/faraday/connection.rb +484 -0
  21. data/agent/dependencies/faraday-0.17.0/lib/faraday/error.rb +66 -0
  22. data/agent/dependencies/faraday-0.17.0/lib/faraday/middleware.rb +37 -0
  23. data/agent/dependencies/faraday-0.17.0/lib/faraday/options.rb +373 -0
  24. data/agent/dependencies/faraday-0.17.0/lib/faraday/parameters.rb +198 -0
  25. data/agent/dependencies/faraday-0.17.0/lib/faraday/rack_builder.rb +237 -0
  26. data/agent/dependencies/faraday-0.17.0/lib/faraday/request.rb +114 -0
  27. data/agent/dependencies/faraday-0.17.0/lib/faraday/request/authorization.rb +41 -0
  28. data/agent/dependencies/faraday-0.17.0/lib/faraday/request/basic_authentication.rb +13 -0
  29. data/agent/dependencies/faraday-0.17.0/lib/faraday/request/instrumentation.rb +36 -0
  30. data/agent/dependencies/faraday-0.17.0/lib/faraday/request/multipart.rb +68 -0
  31. data/agent/dependencies/faraday-0.17.0/lib/faraday/request/retry.rb +212 -0
  32. data/agent/dependencies/faraday-0.17.0/lib/faraday/request/token_authentication.rb +15 -0
  33. data/agent/dependencies/faraday-0.17.0/lib/faraday/request/url_encoded.rb +36 -0
  34. data/agent/dependencies/faraday-0.17.0/lib/faraday/response.rb +97 -0
  35. data/agent/dependencies/faraday-0.17.0/lib/faraday/response/logger.rb +80 -0
  36. data/agent/dependencies/faraday-0.17.0/lib/faraday/response/raise_error.rb +21 -0
  37. data/agent/dependencies/faraday-0.17.0/lib/faraday/upload_io.rb +67 -0
  38. data/agent/dependencies/faraday-0.17.0/lib/faraday/utils.rb +326 -0
  39. data/agent/dependencies/jwt-2.2.1/AUTHORS +84 -0
  40. data/agent/dependencies/jwt-2.2.1/Appraisals +14 -0
  41. data/agent/dependencies/jwt-2.2.1/CHANGELOG.md +570 -0
  42. data/agent/dependencies/jwt-2.2.1/Gemfile +3 -0
  43. data/agent/dependencies/jwt-2.2.1/LICENSE +7 -0
  44. data/agent/dependencies/jwt-2.2.1/README.md +489 -0
  45. data/agent/dependencies/jwt-2.2.1/Rakefile +11 -0
  46. data/agent/dependencies/jwt-2.2.1/lib/jwt.rb +30 -0
  47. data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/ecdsa.rb +35 -0
  48. data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/eddsa.rb +23 -0
  49. data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/hmac.rb +33 -0
  50. data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/ps.rb +43 -0
  51. data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/rsa.rb +19 -0
  52. data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/unsupported.rb +16 -0
  53. data/agent/dependencies/jwt-2.2.1/lib/jwt/base64.rb +19 -0
  54. data/agent/dependencies/jwt-2.2.1/lib/jwt/claims_validator.rb +33 -0
  55. data/agent/dependencies/jwt-2.2.1/lib/jwt/decode.rb +100 -0
  56. data/agent/dependencies/jwt-2.2.1/lib/jwt/default_options.rb +15 -0
  57. data/agent/dependencies/jwt-2.2.1/lib/jwt/encode.rb +68 -0
  58. data/agent/dependencies/jwt-2.2.1/lib/jwt/error.rb +20 -0
  59. data/agent/dependencies/jwt-2.2.1/lib/jwt/json.rb +18 -0
  60. data/agent/dependencies/jwt-2.2.1/lib/jwt/jwk.rb +31 -0
  61. data/agent/dependencies/jwt-2.2.1/lib/jwt/jwk/key_finder.rb +57 -0
  62. data/agent/dependencies/jwt-2.2.1/lib/jwt/jwk/rsa.rb +47 -0
  63. data/agent/dependencies/jwt-2.2.1/lib/jwt/security_utils.rb +57 -0
  64. data/agent/dependencies/jwt-2.2.1/lib/jwt/signature.rb +52 -0
  65. data/agent/dependencies/jwt-2.2.1/lib/jwt/verify.rb +98 -0
  66. data/agent/dependencies/jwt-2.2.1/lib/jwt/version.rb +24 -0
  67. data/agent/dependencies/jwt-2.2.1/ruby-jwt.gemspec +34 -0
  68. data/agent/dependencies/multipart-post-2.1.1/Gemfile +6 -0
  69. data/agent/dependencies/multipart-post-2.1.1/History.txt +64 -0
  70. data/agent/dependencies/multipart-post-2.1.1/LICENSE +21 -0
  71. data/agent/dependencies/multipart-post-2.1.1/Manifest.txt +9 -0
  72. data/agent/dependencies/multipart-post-2.1.1/README.md +127 -0
  73. data/agent/dependencies/multipart-post-2.1.1/Rakefile +6 -0
  74. data/agent/dependencies/multipart-post-2.1.1/lib/composite_io.rb +108 -0
  75. data/agent/dependencies/multipart-post-2.1.1/lib/multipart_post.rb +9 -0
  76. data/agent/dependencies/multipart-post-2.1.1/lib/multipartable.rb +48 -0
  77. data/agent/dependencies/multipart-post-2.1.1/lib/net/http/post/multipart.rb +28 -0
  78. data/agent/dependencies/multipart-post-2.1.1/lib/parts.rb +126 -0
  79. data/agent/dependencies/multipart-post-2.1.1/multipart-post.gemspec +23 -0
  80. data/agent/http_client.rb +46 -0
  81. data/agent/listener.rb +1 -1
  82. data/agent/sealights-rspec-agent.rb +2 -2
  83. data/agent/tia.rb +5 -1
  84. metadata +80 -3
  85. data/agent/rest-client-wrapper.rb +0 -27
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SL_JWT
4
+ EncodeError = Class.new(StandardError)
5
+ DecodeError = Class.new(StandardError)
6
+ RequiredDependencyError = Class.new(StandardError)
7
+
8
+ VerificationError = Class.new(DecodeError)
9
+ ExpiredSignature = Class.new(DecodeError)
10
+ IncorrectAlgorithm = Class.new(DecodeError)
11
+ ImmatureSignature = Class.new(DecodeError)
12
+ InvalidIssuerError = Class.new(DecodeError)
13
+ InvalidIatError = Class.new(DecodeError)
14
+ InvalidAudError = Class.new(DecodeError)
15
+ InvalidSubError = Class.new(DecodeError)
16
+ InvalidJtiError = Class.new(DecodeError)
17
+ InvalidPayload = Class.new(DecodeError)
18
+
19
+ JWKError = Class.new(DecodeError)
20
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module SL_JWT
6
+ # JSON wrapper
7
+ class JSON
8
+ class << self
9
+ def generate(data)
10
+ ::JSON.generate(data)
11
+ end
12
+
13
+ def parse(data)
14
+ ::JSON.parse(data)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'jwk/rsa'
4
+ require_relative 'jwk/key_finder'
5
+
6
+ module SL_JWT
7
+ module JWK
8
+ MAPPINGS = {
9
+ 'RSA' => ::SL_JWT::JWK::RSA,
10
+ OpenSSL::PKey::RSA => ::SL_JWT::JWK::RSA
11
+ }.freeze
12
+
13
+ class << self
14
+ def import(jwk_data)
15
+ raise SL_JWT::JWKError, 'Key type (kty) not provided' unless jwk_data[:kty]
16
+
17
+ MAPPINGS.fetch(jwk_data[:kty].to_s) do |kty|
18
+ raise SL_JWT::JWKError, "Key type #{kty} not supported"
19
+ end.import(jwk_data)
20
+ end
21
+
22
+ def create_from(keypair)
23
+ MAPPINGS.fetch(keypair.class) do |klass|
24
+ raise SL_JWT::JWKError, "Cannot create JWK from a #{klass.name}"
25
+ end.new(keypair)
26
+ end
27
+
28
+ alias new create_from
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SL_JWT
4
+ module JWK
5
+ class KeyFinder
6
+ def initialize(options)
7
+ jwks_or_loader = options[:jwks]
8
+ @jwks = jwks_or_loader if jwks_or_loader.is_a?(Hash)
9
+ @jwk_loader = jwks_or_loader if jwks_or_loader.respond_to?(:call)
10
+ end
11
+
12
+ def key_for(kid)
13
+ raise ::SL_JWT::DecodeError, 'No key id (kid) found from token headers' unless kid
14
+
15
+ jwk = resolve_key(kid)
16
+
17
+ raise ::SL_JWT::DecodeError, "Could not find public key for kid #{kid}" unless jwk
18
+
19
+ ::SL_JWT::JWK.import(jwk).keypair
20
+ end
21
+
22
+ private
23
+
24
+ def resolve_key(kid)
25
+ jwk = find_key(kid)
26
+
27
+ return jwk if jwk
28
+
29
+ if reloadable?
30
+ load_keys(invalidate: true)
31
+ return find_key(kid)
32
+ end
33
+
34
+ nil
35
+ end
36
+
37
+ def jwks
38
+ return @jwks if @jwks
39
+
40
+ load_keys
41
+ @jwks
42
+ end
43
+
44
+ def load_keys(opts = {})
45
+ @jwks = @jwk_loader.call(opts)
46
+ end
47
+
48
+ def find_key(kid)
49
+ Array(jwks[:keys]).find { |key| key[:kid] == kid }
50
+ end
51
+
52
+ def reloadable?
53
+ @jwk_loader
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module SL_JWT
6
+ module JWK
7
+ class RSA
8
+ extend Forwardable
9
+
10
+ attr_reader :keypair
11
+
12
+ def_delegators :keypair, :private?, :public_key
13
+
14
+ BINARY = 2
15
+ KTY = 'RSA'.freeze
16
+
17
+ def initialize(keypair)
18
+ raise ArgumentError, 'keypair must be of type OpenSSL::PKey::RSA' unless keypair.is_a?(OpenSSL::PKey::RSA)
19
+
20
+ @keypair = keypair
21
+ end
22
+
23
+ def kid
24
+ sequence = OpenSSL::ASN1::Sequence([OpenSSL::ASN1::Integer.new(public_key.n),
25
+ OpenSSL::ASN1::Integer.new(public_key.e)])
26
+ OpenSSL::Digest::SHA256.hexdigest(sequence.to_der)
27
+ end
28
+
29
+ def export
30
+ {
31
+ kty: KTY,
32
+ n: ::Base64.urlsafe_encode64(public_key.n.to_s(BINARY), padding: false),
33
+ e: ::Base64.urlsafe_encode64(public_key.e.to_s(BINARY), padding: false),
34
+ kid: kid
35
+ }
36
+ end
37
+
38
+ def self.import(jwk_data)
39
+ imported_key = OpenSSL::PKey::RSA.new
40
+ imported_key.set_key(OpenSSL::BN.new(::Base64.urlsafe_decode64(jwk_data[:n]), BINARY),
41
+ OpenSSL::BN.new(::Base64.urlsafe_decode64(jwk_data[:e]), BINARY),
42
+ nil)
43
+ self.new(imported_key)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,57 @@
1
+ module SL_JWT
2
+ # Collection of security methods
3
+ #
4
+ # @see: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/security_utils.rb
5
+ module SecurityUtils
6
+ module_function
7
+
8
+ def secure_compare(left, right)
9
+ left_bytesize = left.bytesize
10
+
11
+ return false unless left_bytesize == right.bytesize
12
+
13
+ unpacked_left = left.unpack "C#{left_bytesize}"
14
+ result = 0
15
+ right.each_byte { |byte| result |= byte ^ unpacked_left.shift }
16
+ result.zero?
17
+ end
18
+
19
+ def verify_rsa(algorithm, public_key, signing_input, signature)
20
+ public_key.verify(OpenSSL::Digest.new(algorithm.sub('RS', 'sha')), signature, signing_input)
21
+ end
22
+
23
+ def verify_ps(algorithm, public_key, signing_input, signature)
24
+ formatted_algorithm = algorithm.sub('PS', 'sha')
25
+
26
+ public_key.verify_pss(formatted_algorithm, signature, signing_input, salt_length: :auto, mgf1_hash: formatted_algorithm)
27
+ end
28
+
29
+ def asn1_to_raw(signature, public_key)
30
+ byte_size = (public_key.group.degree + 7) / 8
31
+ OpenSSL::ASN1.decode(signature).value.map { |value| value.value.to_s(2).rjust(byte_size, "\x00") }.join
32
+ end
33
+
34
+ def raw_to_asn1(signature, private_key)
35
+ byte_size = (private_key.group.degree + 7) / 8
36
+ sig_bytes = signature[0..(byte_size - 1)]
37
+ sig_char = signature[byte_size..-1] || ''
38
+ OpenSSL::ASN1::Sequence.new([sig_bytes, sig_char].map { |int| OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(int, 2)) }).to_der
39
+ end
40
+
41
+ def rbnacl_fixup(algorithm, key)
42
+ algorithm = algorithm.sub('HS', 'SHA').to_sym
43
+
44
+ return [] unless defined?(RbNaCl) && RbNaCl::HMAC.constants(false).include?(algorithm)
45
+
46
+ authenticator = RbNaCl::HMAC.const_get(algorithm)
47
+
48
+ # Fall back to OpenSSL for keys larger than 32 bytes.
49
+ return [] if key.bytesize > authenticator.key_bytes
50
+
51
+ [
52
+ authenticator,
53
+ key.bytes.fill(0, key.bytesize...authenticator.key_bytes).pack('C*')
54
+ ]
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './security_utils'
4
+ require 'openssl'
5
+ require_relative './algos/hmac'
6
+ require_relative './algos/eddsa'
7
+ require_relative './algos/ecdsa'
8
+ require_relative './algos/rsa'
9
+ require_relative './algos/ps'
10
+ require_relative './algos/unsupported'
11
+ begin
12
+ require 'rbnacl'
13
+ rescue LoadError
14
+ raise if defined?(RbNaCl)
15
+ end
16
+
17
+ # JWT::Signature module
18
+ module SL_JWT
19
+ # Signature logic for JWT
20
+ module Signature
21
+ extend self
22
+ ALGOS = [
23
+ Algos::Hmac,
24
+ Algos::Ecdsa,
25
+ Algos::Rsa,
26
+ Algos::Eddsa,
27
+ Algos::Ps,
28
+ Algos::Unsupported
29
+ ].freeze
30
+ ToSign = Struct.new(:algorithm, :msg, :key)
31
+ ToVerify = Struct.new(:algorithm, :public_key, :signing_input, :signature)
32
+
33
+ def sign(algorithm, msg, key)
34
+ algo = ALGOS.find do |alg|
35
+ alg.const_get(:SUPPORTED).include? algorithm
36
+ end
37
+ algo.sign ToSign.new(algorithm, msg, key)
38
+ end
39
+
40
+ def verify(algorithm, key, signing_input, signature)
41
+ algo = ALGOS.find do |alg|
42
+ alg.const_get(:SUPPORTED).include? algorithm
43
+ end
44
+ verified = algo.verify(ToVerify.new(algorithm, key, signing_input, signature))
45
+ raise(SL_JWT::VerificationError, 'Signature verification raised') unless verified
46
+ rescue OpenSSL::PKey::PKeyError
47
+ raise SL_JWT::VerificationError, 'Signature verification raised'
48
+ ensure
49
+ OpenSSL.errors.clear
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './error'
4
+
5
+ module SL_JWT
6
+ # JWT verify methods
7
+ class Verify
8
+ DEFAULTS = {
9
+ leeway: 0
10
+ }.freeze
11
+
12
+ class << self
13
+ %w[verify_aud verify_expiration verify_iat verify_iss verify_jti verify_not_before verify_sub].each do |method_name|
14
+ define_method method_name do |payload, options|
15
+ new(payload, options).send(method_name)
16
+ end
17
+ end
18
+
19
+ def verify_claims(payload, options)
20
+ options.each do |key, val|
21
+ next unless key.to_s =~ /verify/
22
+ Verify.send(key, payload, options) if val
23
+ end
24
+ end
25
+ end
26
+
27
+ def initialize(payload, options)
28
+ @payload = payload
29
+ @options = DEFAULTS.merge(options)
30
+ end
31
+
32
+ def verify_aud
33
+ return unless (options_aud = @options[:aud])
34
+
35
+ aud = @payload['aud']
36
+ raise(SL_JWT::InvalidAudError, "Invalid audience. Expected #{options_aud}, received #{aud || '<none>'}") if ([*aud] & [*options_aud]).empty?
37
+ end
38
+
39
+ def verify_expiration
40
+ return unless @payload.include?('exp')
41
+ raise(SL_JWT::ExpiredSignature, 'Signature has expired') if @payload['exp'].to_i <= (Time.now.to_i - exp_leeway)
42
+ end
43
+
44
+ def verify_iat
45
+ return unless @payload.include?('iat')
46
+
47
+ iat = @payload['iat']
48
+ raise(SL_JWT::InvalidIatError, 'Invalid iat') if !iat.is_a?(Numeric) || iat.to_f > Time.now.to_f
49
+ end
50
+
51
+ def verify_iss
52
+ return unless (options_iss = @options[:iss])
53
+
54
+ iss = @payload['iss']
55
+
56
+ return if Array(options_iss).map(&:to_s).include?(iss.to_s)
57
+
58
+ raise(SL_JWT::InvalidIssuerError, "Invalid issuer. Expected #{options_iss}, received #{iss || '<none>'}")
59
+ end
60
+
61
+ def verify_jti
62
+ options_verify_jti = @options[:verify_jti]
63
+ jti = @payload['jti']
64
+
65
+ if options_verify_jti.respond_to?(:call)
66
+ verified = options_verify_jti.arity == 2 ? options_verify_jti.call(jti, @payload) : options_verify_jti.call(jti)
67
+ raise(SL_JWT::InvalidJtiError, 'Invalid jti') unless verified
68
+ elsif jti.to_s.strip.empty?
69
+ raise(SL_JWT::InvalidJtiError, 'Missing jti')
70
+ end
71
+ end
72
+
73
+ def verify_not_before
74
+ return unless @payload.include?('nbf')
75
+ raise(SL_JWT::ImmatureSignature, 'Signature nbf has not been reached') if @payload['nbf'].to_i > (Time.now.to_i + nbf_leeway)
76
+ end
77
+
78
+ def verify_sub
79
+ return unless (options_sub = @options[:sub])
80
+ sub = @payload['sub']
81
+ raise(SL_JWT::InvalidSubError, "Invalid subject. Expected #{options_sub}, received #{sub || '<none>'}") unless sub.to_s == options_sub.to_s
82
+ end
83
+
84
+ private
85
+
86
+ def global_leeway
87
+ @options[:leeway]
88
+ end
89
+
90
+ def exp_leeway
91
+ @options[:exp_leeway] || global_leeway
92
+ end
93
+
94
+ def nbf_leeway
95
+ @options[:nbf_leeway] || global_leeway
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ # Moments version builder module
5
+ module SL_JWT
6
+ def self.gem_version
7
+ Gem::Version.new VERSION::STRING
8
+ end
9
+
10
+ # Moments version builder module
11
+ module VERSION
12
+ # major version
13
+ MAJOR = 2
14
+ # minor version
15
+ MINOR = 2
16
+ # tiny version
17
+ TINY = 1
18
+ # alpha, beta, etc. tag
19
+ PRE = nil
20
+
21
+ # Build version string
22
+ STRING = [[MAJOR, MINOR, TINY].compact.join('.'), PRE].compact.join('-')
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ lib = File.expand_path('../lib/', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'jwt/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'jwt'
7
+ spec.version = SL_JWT.gem_version
8
+ spec.authors = [
9
+ 'Tim Rudat'
10
+ ]
11
+ spec.email = 'timrudat@gmail.com'
12
+ spec.summary = 'JSON Web Token implementation in Ruby'
13
+ spec.description = 'A pure ruby implementation of the RFC 7519 OAuth JSON Web Token (JWT) standard.'
14
+ spec.homepage = 'https://github.com/jwt/ruby-jwt'
15
+ spec.license = 'MIT'
16
+ spec.required_ruby_version = '>= 2.1'
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|gemfiles|coverage|bin)/}) }
19
+ spec.executables = []
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = %w[lib]
22
+
23
+ spec.add_development_dependency 'appraisal'
24
+ spec.add_development_dependency 'bundler'
25
+ spec.add_development_dependency 'rake'
26
+ spec.add_development_dependency 'rspec'
27
+ spec.add_development_dependency 'simplecov'
28
+ spec.add_development_dependency 'simplecov-json'
29
+ spec.add_development_dependency 'codeclimate-test-reporter'
30
+ spec.add_development_dependency 'codacy-coverage'
31
+ spec.add_development_dependency 'rbnacl'
32
+ # RSASSA-PSS support provided by OpenSSL +2.1
33
+ spec.add_development_dependency 'openssl', '~> 2.1'
34
+ end