openssl-signature_algorithm 0.1.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76f8dacd6dc7e43d630421e43c7e2849bb99bf857bdedd10a732b04122cf2499
4
- data.tar.gz: 8030c5dfcc2c70ae600778cebcc9bb02d7d70fb28b345b67608dc8fa14b65f81
3
+ metadata.gz: 14fbf64f6f493adb44ffe4e2f8dc537a8800a6af79c7716c85a49eaab5664ce0
4
+ data.tar.gz: 700d2d7ebfa40f05f004735eca6dc938066b69a02015c2b2cca0349db1b330ed
5
5
  SHA512:
6
- metadata.gz: 0c04ce36ef91da99f985f22154842e5cdc3440bf7c74e2e94ec819e8774f0cfc7f216e241f61d4b4ed87da48aaad288db12e2b33a3590c5aa1a31f694db6af32
7
- data.tar.gz: 7335e381e291719ef449ba8967b0a1417262ccc3f37fe139b36a757842cf8e5e5d346b605c72ef276c445c21e41415edb5ab3e02efa03dc8a6600f4c03b177e5
6
+ metadata.gz: dd9b7bd8aca161cc531427cb7b2b2e0dfcc5143b5d4443069f95bf4d135fb5d936806372de7c5ed8f91739c8ebe7b1e98f8268bd1186df4061a1a587fc722b3c
7
+ data.tar.gz: 36ceaa919dbd5dfda0dfcf90848c53d5e9eeed9be7cc1eaafdf1d15c5351b4f9782ee4c501c40cad9db147b6c1955f1c8ce3405cd4a49ccb9cf741e5878512b3
data/.gitignore CHANGED
@@ -9,3 +9,6 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ .byebug_history
13
+
14
+ /gemfiles/*.gemfile.lock
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
1
  --format documentation
2
2
  --color
3
3
  --require spec_helper
4
+ --order random
@@ -1,6 +1,8 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.5
2
+ TargetRubyVersion: 2.4
3
3
  DisabledByDefault: true
4
+ Exclude:
5
+ - "gemfiles/**/*"
4
6
 
5
7
  Bundler:
6
8
  Enabled: true
@@ -26,9 +28,6 @@ Security:
26
28
  Style/BlockComments:
27
29
  Enabled: true
28
30
 
29
- Style/BracesAroundHashParameters:
30
- Enabled: true
31
-
32
31
  Style/CaseEquality:
33
32
  Enabled: true
34
33
 
@@ -1,8 +1,24 @@
1
1
  ---
2
+ dist: bionic
2
3
  language: ruby
3
4
  cache: bundler
4
5
  rvm:
5
- - 2.7.0
6
- - 2.6.5
7
- - 2.5.7
8
- before_install: gem install bundler -v 2.1.4
6
+ - ruby-head
7
+ - 2.7.1
8
+ - 2.6.6
9
+ - 2.5.8
10
+ - 2.4.10
11
+ gemfile:
12
+ - gemfiles/openssl_head.gemfile
13
+ - gemfiles/openssl_2_2.gemfile
14
+ - gemfiles/openssl_2_1.gemfile
15
+ - gemfiles/openssl_2_0.gemfile
16
+ - gemfiles/openssl_default.gemfile
17
+ matrix:
18
+ fast_finish: true
19
+ allow_failures:
20
+ - rvm: ruby-head
21
+ - gemfile: gemfiles/openssl_head.gemfile
22
+ before_install:
23
+ - gem install bundler -v 2.1.4
24
+ - rm Gemfile.lock
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ appraise "openssl_head" do
4
+ gem "openssl", git: "https://github.com/ruby/openssl"
5
+ end
6
+
7
+ appraise "openssl_2_2" do
8
+ gem "openssl", "~> 2.2.0"
9
+ end
10
+
11
+ appraise "openssl_2_1" do
12
+ gem "openssl", "~> 2.1.0"
13
+ end
14
+
15
+ appraise "openssl_2_0" do
16
+ gem "openssl", "~> 2.0.0"
17
+ end
18
+
19
+ appraise "openssl_default" do
20
+ end
@@ -0,0 +1,80 @@
1
+ # Changelog
2
+
3
+ ## [v1.0.0] - 2020-07-08
4
+
5
+ ### Added
6
+
7
+ - ECDSA with **secp256k1** curve support added:
8
+ ```rb
9
+ OpenSSL::SignatureAlgorithm::ECDSA.new(curve: "secp256k1")
10
+ ```
11
+ - Algorithm **arguments** are now **optional**. The following works:
12
+
13
+ ```rb
14
+ OpenSSL::SignatureAlgorithm::ECDSA.new
15
+ # defaults to ECDSA with SHA-256 and NIST P256 curve
16
+ # Same as OpenSSL::SignatureAlgorithm::ECDSA.new(hash_function: "SHA256", curve: "prime256v1")
17
+
18
+ OpenSSL::SignatureAlgorithm::RSAPSS.new
19
+ # defaults to SHA-256
20
+ # Same as OpenSSL::SignatureAlgorithm::RSAPSS.new(hash_function: "SHA256")
21
+
22
+ OpenSSL::SignatureAlgorithm::RSAPKCS1.new
23
+ # defaults to SHA-256
24
+ # Same as OpenSSL::SignatureAlgorithm::RSAPSS.new(hash_function: "SHA256")
25
+ ```
26
+
27
+ ### Changed
28
+
29
+ - Algorithm **instantiation** changed. The positional argument `digest_length` is replaced with keyword arguments, `hash_function:` for RSA algorithms and `hash_function:` and `curve:` for ECDSA. None are required arguments, you get sane defaults if you don't provide any arguments. Code migration examples:
30
+ ```rb
31
+ # Change this
32
+ # OpenSSL::SignatureAlgorithm::ECDSA.new("256")
33
+ # to
34
+ OpenSSL::SignatureAlgorithm::ECDSA.new(hash_function: "SHA256")
35
+ ```
36
+ ```rb
37
+ # Change this
38
+ # OpenSSL::SignatureAlgorithm::RSAPSS.new("384")
39
+ # to
40
+ OpenSSL::SignatureAlgorithm::RSAPSS.new(hash_function: "SHA384")
41
+ ```
42
+
43
+ ## [v0.4.0] - 2020-01-31
44
+
45
+ ### Added
46
+
47
+ - `VerifyKey` serialization and deserialization for easy transmission over the network
48
+
49
+ ## [v0.3.0] - 2020-01-30
50
+
51
+ ### Added
52
+
53
+ - Support ruby v2.4 (without RSA-PSS)
54
+
55
+ ## [v0.2.0] - 2020-01-29
56
+
57
+ ### Added
58
+
59
+ - `OpenSSL::SignatureAlgorithm::ECDSA#verify` now supports raw (non DER) signatures
60
+
61
+ ## [v0.1.1] - 2020-01-29
62
+
63
+ ### Fixed
64
+
65
+ - Fixed error in `OpenSSL::SignatureAlgorithm::RSAPSS#sign`
66
+
67
+ ## [v0.1.0] - 2020-01-29
68
+
69
+ ### Added
70
+
71
+ - `OpenSSL::SignatureAlgorithm::ECDSA`
72
+ - `OpenSSL::SignatureAlgorithm::RSAPSS`
73
+ - `OpenSSL::SignatureAlgorithm::RSAPKCS1`
74
+
75
+ [v1.0.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.4.0...v1.0.0/
76
+ [v0.4.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.3.0...v0.4.0/
77
+ [v0.3.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.2.0...v0.3.0/
78
+ [v0.2.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.1.1...v0.2.0/
79
+ [v0.1.1]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.1.0...v0.1.1/
80
+ [v0.1.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/41887c277dc7fa0c884ccf8924cf990ff76784d9...v0.1.0/
data/Gemfile CHANGED
@@ -5,6 +5,8 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in openssl-signature_algorithm.gemspec
6
6
  gemspec
7
7
 
8
- gem "rake", "~> 12.0"
8
+ gem "appraisal", "~> 2.2"
9
+ gem "byebug", "~> 11.0"
10
+ gem "rake", "~> 13.0"
9
11
  gem "rspec", "~> 3.0"
10
- gem "rubocop", "~> 0.79.0"
12
+ gem "rubocop", "~> 0.80.1"
@@ -1,50 +1,60 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openssl-signature_algorithm (0.1.0)
4
+ openssl-signature_algorithm (1.0.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ appraisal (2.2.0)
10
+ bundler
11
+ rake
12
+ thor (>= 0.14.0)
9
13
  ast (2.4.0)
14
+ byebug (11.1.1)
10
15
  diff-lcs (1.3)
11
16
  jaro_winkler (1.5.4)
12
17
  parallel (1.19.1)
13
- parser (2.7.0.2)
18
+ parser (2.7.0.5)
14
19
  ast (~> 2.4.0)
15
20
  rainbow (3.0.0)
16
- rake (12.3.3)
21
+ rake (13.0.1)
22
+ rexml (3.2.4)
17
23
  rspec (3.9.0)
18
24
  rspec-core (~> 3.9.0)
19
25
  rspec-expectations (~> 3.9.0)
20
26
  rspec-mocks (~> 3.9.0)
21
27
  rspec-core (3.9.1)
22
28
  rspec-support (~> 3.9.1)
23
- rspec-expectations (3.9.0)
29
+ rspec-expectations (3.9.1)
24
30
  diff-lcs (>= 1.2.0, < 2.0)
25
31
  rspec-support (~> 3.9.0)
26
32
  rspec-mocks (3.9.1)
27
33
  diff-lcs (>= 1.2.0, < 2.0)
28
34
  rspec-support (~> 3.9.0)
29
35
  rspec-support (3.9.2)
30
- rubocop (0.79.0)
36
+ rubocop (0.80.1)
31
37
  jaro_winkler (~> 1.5.1)
32
38
  parallel (~> 1.10)
33
39
  parser (>= 2.7.0.1)
34
40
  rainbow (>= 2.2.2, < 4.0)
41
+ rexml
35
42
  ruby-progressbar (~> 1.7)
36
43
  unicode-display_width (>= 1.4.0, < 1.7)
37
44
  ruby-progressbar (1.10.1)
45
+ thor (1.0.1)
38
46
  unicode-display_width (1.6.1)
39
47
 
40
48
  PLATFORMS
41
49
  ruby
42
50
 
43
51
  DEPENDENCIES
52
+ appraisal (~> 2.2)
53
+ byebug (~> 11.0)
44
54
  openssl-signature_algorithm!
45
- rake (~> 12.0)
55
+ rake (~> 13.0)
46
56
  rspec (~> 3.0)
47
- rubocop (~> 0.79.0)
57
+ rubocop (~> 0.80.1)
48
58
 
49
59
  BUNDLED WITH
50
60
  2.1.4
data/README.md CHANGED
@@ -1,8 +1,16 @@
1
1
  # OpenSSL::SignatureAlgorithm
2
2
 
3
- This tiny library introduces `OpenSSL::SignatureAlgorithm::ECDSA`, `OpenSSL::SignatureAlgorithm::RSAPSS` and `OpenSSL::SignatureAlgorithm::RSAPKCS1`, so that you can reason in terms of signature algorithms when signing and/or verifying signatures―instead of keys.
3
+ > ECDSA, RSA-PSS and RSA-PKCS#1 signature algorithms for ruby
4
4
 
5
- This provides a higher level of abstraction, on top of `openssl`'s gem `OpenSSL::PKey::EC`, `OpenSSL::PKey::EC::Point` and `OpenSSL::PKey::RSA`.
5
+ Sign and verify using signature algorithm wrappers, instead of key objects.
6
+
7
+ Provides `OpenSSL::SignatureAlgorithm::ECDSA`, `OpenSSL::SignatureAlgorithm::RSAPSS`
8
+ and `OpenSSL::SignatureAlgorithm::RSAPKCS1` ruby object wrappers on top of `OpenSSL::PKey::EC`
9
+ and `OpenSSL::PKey::RSA`, so that you can reason in terms of the algorithms and do less when
10
+ signing or verifying signatures.
11
+
12
+ [![Gem](https://img.shields.io/gem/v/openssl-signature_algorithm.svg?style=flat-square&color=informational)](https://rubygems.org/gems/openssl-signature_algorithm)
13
+ [![Travis](https://img.shields.io/travis/cedarcode/openssl-signature_algorithm/master.svg?style=flat-square)](https://travis-ci.org/cedarcode/openssl-signature_algorithm)
6
14
 
7
15
  ## Installation
8
16
 
@@ -28,15 +36,16 @@ Or install it yourself as:
28
36
  to_be_signed = "to-be-signed"
29
37
 
30
38
  # Signer
31
- algorithm = OpenSSL::SignatureAlgorithm::ECDSA.new("256")
39
+ algorithm = OpenSSL::SignatureAlgorithm::ECDSA.new
32
40
  signing_key = algorithm.generate_signing_key
33
41
  signature = algorithm.sign(to_be_signed)
34
42
 
35
43
  # Signer sends verify key to Verifier
36
- verify_key = signing_key.verify_key
44
+ verify_key_string = signing_key.verify_key.serialize
37
45
 
38
46
  # Verifier
39
- algorithm = OpenSSL::SignatureAlgorithm::ECDSA.new("256")
47
+ verify_key = OpenSSL::SignatureAlgorithm::ECDSA::VerifyKey.deserialize(verify_key_string)
48
+ algorithm = OpenSSL::SignatureAlgorithm::ECDSA.new
40
49
  algorithm.verify_key = verify_key
41
50
  algorithm.verify(signature, to_be_signed)
42
51
  ```
@@ -47,15 +56,16 @@ algorithm.verify(signature, to_be_signed)
47
56
  to_be_signed = "to-be-signed"
48
57
 
49
58
  # Signer
50
- algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new("256")
59
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new
51
60
  signing_key = algorithm.generate_signing_key
52
61
  signature = algorithm.sign(to_be_signed)
53
62
 
54
63
  # Signer sends verify key to Verifier
55
- verify_key = signing_key.verify_key
64
+ verify_key_string = signing_key.verify_key.serialize
56
65
 
57
66
  # Verifier
58
- algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new("256")
67
+ verify_key = OpenSSL::SignatureAlgorithm::RSAPSS::VerifyKey.deserialize(verify_key_string)
68
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new
59
69
  algorithm.verify_key = verify_key
60
70
  algorithm.verify(signature, to_be_signed)
61
71
  ```
@@ -66,15 +76,16 @@ algorithm.verify(signature, to_be_signed)
66
76
  to_be_signed = "to-be-signed"
67
77
 
68
78
  # Signer
69
- algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new("256")
79
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new
70
80
  signing_key = algorithm.generate_signing_key
71
81
  signature = algorithm.sign(to_be_signed)
72
82
 
73
83
  # Signer sends verify key to Verifier
74
- verify_key = signing_key.verify_key
84
+ verify_key_string = signing_key.verify_key.serialize
75
85
 
76
86
  # Verifier
77
- algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new("256")
87
+ verify_key = OpenSSL::SignatureAlgorithm::RSAPKCS1::VerifyKey.deserialize(verify_key_string)
88
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new
78
89
  algorithm.verify_key = verify_key
79
90
  algorithm.verify(signature, to_be_signed)
80
91
  ```
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_RETRY: "1"
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal", "~> 2.2"
6
+ gem "byebug", "~> 11.0"
7
+ gem "rake", "~> 13.0"
8
+ gem "rspec", "~> 3.0"
9
+ gem "rubocop", "~> 0.80.1"
10
+ gem "openssl", "~> 2.0.0"
11
+
12
+ gemspec path: "../"
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal", "~> 2.2"
6
+ gem "byebug", "~> 11.0"
7
+ gem "rake", "~> 13.0"
8
+ gem "rspec", "~> 3.0"
9
+ gem "rubocop", "~> 0.80.1"
10
+ gem "openssl", "~> 2.1.0"
11
+
12
+ gemspec path: "../"
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal", "~> 2.2"
6
+ gem "byebug", "~> 11.0"
7
+ gem "rake", "~> 13.0"
8
+ gem "rspec", "~> 3.0"
9
+ gem "rubocop", "~> 0.80.1"
10
+ gem "openssl", "~> 2.2.0"
11
+
12
+ gemspec path: "../"
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal", "~> 2.2"
6
+ gem "byebug", "~> 11.0"
7
+ gem "rake", "~> 13.0"
8
+ gem "rspec", "~> 3.0"
9
+ gem "rubocop", "~> 0.80.1"
10
+
11
+ gemspec path: "../"
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal", "~> 2.2"
6
+ gem "byebug", "~> 11.0"
7
+ gem "rake", "~> 13.0"
8
+ gem "rspec", "~> 3.0"
9
+ gem "rubocop", "~> 0.80.1"
10
+ gem "openssl", git: "https://github.com/ruby/openssl"
11
+
12
+ gemspec path: "../"
@@ -5,25 +5,39 @@ require "openssl/signature_algorithm/error"
5
5
 
6
6
  module OpenSSL
7
7
  module SignatureAlgorithm
8
+ class SignatureVerificationError < Error; end
9
+ class UnsupportedParameterError < Error; end
10
+ class VerifyKeyError < Error; end
11
+
8
12
  class Base
9
- attr_reader :digest_length, :signing_key
10
- attr_accessor :verify_key
13
+ attr_reader :signing_key, :verify_key
11
14
 
12
- def initialize(digest_length)
13
- @digest_length = digest_length
15
+ def verify_key=(key)
16
+ if compatible_verify_key?(key)
17
+ @verify_key = key
18
+ else
19
+ raise(OpenSSL::SignatureAlgorithm::VerifyKeyError, "Incompatible verify key for algorithm")
20
+ end
14
21
  end
15
22
 
16
- def sign(data)
17
- signing_key.sign(hash_function, data)
23
+ def compatible_verify_key?(verify_key)
24
+ verify_key.respond_to?(:verify)
18
25
  end
19
26
 
20
- def hash_function
21
- OpenSSL::Digest.new("sha#{digest_length}")
27
+ def sign(data)
28
+ signing_key.sign(hash_function, data)
22
29
  end
23
30
 
24
31
  def verify(signature, verification_data)
25
- verify_key.verify(hash_function, signature, verification_data) ||
26
- raise(OpenSSL::SignatureAlgorithm::Error, "Signature verification failed")
32
+ formatted_signature =
33
+ if respond_to?(:formatted_signature, true)
34
+ formatted_signature(signature)
35
+ else
36
+ signature
37
+ end
38
+
39
+ verify_key.verify(hash_function, formatted_signature, verification_data) ||
40
+ raise(OpenSSL::SignatureAlgorithm::SignatureVerificationError, "Signature verification failed")
27
41
  end
28
42
  end
29
43
  end
@@ -6,6 +6,8 @@ require "openssl/signature_algorithm/base"
6
6
  module OpenSSL
7
7
  module SignatureAlgorithm
8
8
  class ECDSA < Base
9
+ BYTE_LENGTH = 8
10
+
9
11
  class SigningKey < OpenSSL::PKey::EC
10
12
  def initialize(*args)
11
13
  super(*args).generate_key
@@ -17,27 +19,93 @@ module OpenSSL
17
19
  end
18
20
 
19
21
  class VerifyKey < OpenSSL::PKey::EC::Point
20
- def verify(*args)
21
- ec_key = OpenSSL::PKey::EC.new(group)
22
- ec_key.public_key = self
22
+ def self.deserialize(pem_string)
23
+ new(OpenSSL::PKey::EC.new(pem_string).public_key)
24
+ end
23
25
 
26
+ def serialize
27
+ ec_key.to_pem
28
+ end
29
+
30
+ def ec_key
31
+ @ec_key ||=
32
+ begin
33
+ ec_key = OpenSSL::PKey::EC.new(group)
34
+ ec_key.public_key = self
35
+
36
+ ec_key
37
+ end
38
+ end
39
+
40
+ def verify(*args)
24
41
  ec_key.verify(*args)
25
42
  end
26
43
  end
27
44
 
28
- CURVE_BY_DIGEST_LENGTH = {
29
- "256" => "prime256v1",
30
- "384" => "secp384r1",
31
- "512" => "secp521r1"
32
- }.freeze
45
+ ACCEPTED_PARAMETERS = [
46
+ { curve: "prime256v1", hash_function: "SHA256" },
47
+ { curve: "secp384r1", hash_function: "SHA384" },
48
+ { curve: "secp521r1", hash_function: "SHA512" },
49
+ { curve: "secp256k1", hash_function: "SHA256" }
50
+ ].freeze
51
+
52
+ attr_reader :curve, :hash_function
53
+
54
+ def initialize(curve: nil, hash_function: nil)
55
+ @curve, @hash_function = pick_parameters(curve, hash_function)
56
+ end
33
57
 
34
58
  def generate_signing_key
35
- @signing_key = SigningKey.new(curve_name)
59
+ @signing_key = SigningKey.new(curve)
36
60
  end
37
61
 
38
- def curve_name
39
- CURVE_BY_DIGEST_LENGTH[digest_length] ||
40
- raise(OpenSSL::SignatureAlgorithm::Error, "Unsupported digest length #{digest_length}")
62
+ def compatible_verify_key?(key)
63
+ super && key.respond_to?(:group) && key.group.curve_name == curve
64
+ end
65
+
66
+ private
67
+
68
+ # Borrowed from jwt rubygem.
69
+ # https://github.com/jwt/ruby-jwt/blob/7a6a3f1dbaff806993156d1dff9c217bb2523ff8/lib/jwt/security_utils.rb#L34-L39
70
+ #
71
+ # Hopefully this will be provided by openssl rubygem in the future.
72
+ def formatted_signature(signature)
73
+ n = (verify_key_length.to_f / BYTE_LENGTH).ceil
74
+
75
+ if signature.size == n * 2
76
+ r = signature[0..(n - 1)]
77
+ s = signature[n..-1]
78
+
79
+ OpenSSL::ASN1::Sequence.new([r, s].map { |int| OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(int, 2)) }).to_der
80
+ else
81
+ signature
82
+ end
83
+ end
84
+
85
+ def verify_key_length
86
+ verify_key.group.degree
87
+ end
88
+
89
+ def pick_parameters(curve, hash_function)
90
+ parameters = ACCEPTED_PARAMETERS.detect do |params|
91
+ if curve
92
+ if hash_function
93
+ params[:curve] == curve && params[:hash_function] == hash_function
94
+ else
95
+ params[:curve] == curve
96
+ end
97
+ elsif hash_function
98
+ params[:hash_function] == hash_function
99
+ else
100
+ true
101
+ end
102
+ end
103
+
104
+ if parameters
105
+ [parameters[:curve], parameters[:hash_function]]
106
+ else
107
+ raise(OpenSSL::SignatureAlgorithm::UnsupportedParameterError, "Unsupported algorithm parameters")
108
+ end
41
109
  end
42
110
  end
43
111
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openssl"
4
+ require "openssl/signature_algorithm/base"
5
+
6
+ module OpenSSL
7
+ module SignatureAlgorithm
8
+ class RSA < Base
9
+ class SigningKey < OpenSSL::PKey::RSA
10
+ def verify_key
11
+ VerifyKey.new(public_key.to_pem)
12
+ end
13
+ end
14
+
15
+ class VerifyKey < OpenSSL::PKey::RSA
16
+ class << self
17
+ alias_method :deserialize, :new
18
+ end
19
+
20
+ def serialize
21
+ to_pem
22
+ end
23
+ end
24
+
25
+ ACCEPTED_HASH_FUNCTIONS = ["SHA256", "SHA384", "SHA512"].freeze
26
+ DEFAULT_KEY_SIZE = 2048
27
+
28
+ attr_reader :hash_function
29
+
30
+ def initialize(hash_function: self.class::ACCEPTED_HASH_FUNCTIONS.first)
31
+ if self.class::ACCEPTED_HASH_FUNCTIONS.include?(hash_function)
32
+ @hash_function = hash_function
33
+ else
34
+ raise(OpenSSL::SignatureAlgorithm::UnsupportedParameterError, "Unsupported hash function '#{hash_function}'")
35
+ end
36
+ end
37
+
38
+ def generate_signing_key(size: DEFAULT_KEY_SIZE)
39
+ @signing_key = SigningKey.new(size)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,22 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "openssl"
4
- require "openssl/signature_algorithm/base"
4
+ require "openssl/signature_algorithm/rsa"
5
5
 
6
6
  module OpenSSL
7
7
  module SignatureAlgorithm
8
- class RSAPKCS1 < Base
9
- class SigningKey < OpenSSL::PKey::RSA
10
- def verify_key
11
- public_key
12
- end
13
- end
14
-
15
- DEFAULT_KEY_SIZE = 2048
16
-
17
- def generate_signing_key(size: DEFAULT_KEY_SIZE)
18
- @signing_key = SigningKey.new(size)
19
- end
8
+ class RSAPKCS1 < RSA
20
9
  end
21
10
  end
22
11
  end
@@ -1,25 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "openssl"
4
- require "openssl/signature_algorithm/base"
4
+ require "openssl/signature_algorithm/rsa"
5
5
 
6
6
  module OpenSSL
7
7
  module SignatureAlgorithm
8
- class RSAPSS < Base
9
- class SigningKey < OpenSSL::PKey::RSA
10
- def verify_key
11
- public_key
12
- end
13
- end
14
-
15
- DEFAULT_KEY_SIZE = 2048
16
-
17
- def generate_signing_key(size: DEFAULT_KEY_SIZE)
18
- @signing_key = SigningKey.new(size)
19
- end
20
-
8
+ class RSAPSS < RSA
21
9
  def sign(data)
22
- signing_key.sign_pss(hash_function, data, salt_length: salt_length, mgf1_hash: mgf1_hash_function)
10
+ signing_key.sign_pss(hash_function, data, salt_length: :max, mgf1_hash: mgf1_hash_function)
23
11
  end
24
12
 
25
13
  def verify(signature, verification_data)
@@ -27,13 +15,9 @@ module OpenSSL
27
15
  hash_function,
28
16
  signature,
29
17
  verification_data,
30
- salt_length: salt_length,
18
+ salt_length: :auto,
31
19
  mgf1_hash: mgf1_hash_function
32
- ) || raise(OpenSSL::SignatureAlgorithm::Error, "Signature verification failed")
33
- end
34
-
35
- def salt_length
36
- :auto
20
+ ) || raise(OpenSSL::SignatureAlgorithm::SignatureVerificationError, "Signature verification failed")
37
21
  end
38
22
 
39
23
  def mgf1_hash_function
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OpenSSL
4
4
  module SignatureAlgorithm
5
- VERSION = "0.1.0"
5
+ VERSION = "1.0.0"
6
6
  end
7
7
  end
@@ -5,20 +5,15 @@ require_relative 'lib/openssl/signature_algorithm/version'
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "openssl-signature_algorithm"
7
7
  spec.version = OpenSSL::SignatureAlgorithm::VERSION
8
- spec.authors = ["Gonzalo"]
8
+ spec.authors = ["Gonzalo Rodriguez"]
9
9
  spec.email = ["gonzalo@cedarcode.com"]
10
10
  spec.license = "Apache-2.0"
11
11
 
12
- spec.summary = "Signature Algorithm abstraction for openssl ruby gem"
13
- spec.description = <<-DESC
14
- This tiny library introduces `OpenSSL::SignatureAlgorithm::ECDSA`,
15
- `OpenSSL::SignatureAlgorithm::RSAPSS` and `OpenSSL::SignatureAlgorithm::RSAPKCS1`,
16
- so that you can reason in terms of signature algorithms when signing and/or
17
- verifying signatures―instead of keys.
18
- DESC
12
+ spec.summary = "ECDSA, RSA-PSS and RSA-PKCS#1 algorithms for ruby"
13
+ spec.description = spec.summary
19
14
 
20
- spec.homepage = "https://github.com/cedarcode/openssl-signature_algorithm"
21
- spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
15
+ spec.homepage = "https://github.com/cedarcode/openssl-signature_algorithm"
16
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
22
17
 
23
18
  spec.metadata["homepage_uri"] = spec.homepage
24
19
  spec.metadata["source_code_uri"] = spec.homepage
metadata CHANGED
@@ -1,20 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openssl-signature_algorithm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - Gonzalo
7
+ - Gonzalo Rodriguez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-29 00:00:00.000000000 Z
11
+ date: 2020-07-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: |2
14
- This tiny library introduces `OpenSSL::SignatureAlgorithm::ECDSA`,
15
- `OpenSSL::SignatureAlgorithm::RSAPSS` and `OpenSSL::SignatureAlgorithm::RSAPKCS1`,
16
- so that you can reason in terms of signature algorithms when signing and/or
17
- verifying signatures―instead of keys.
13
+ description: ECDSA, RSA-PSS and RSA-PKCS#1 algorithms for ruby
18
14
  email:
19
15
  - gonzalo@cedarcode.com
20
16
  executables: []
@@ -25,6 +21,8 @@ files:
25
21
  - ".rspec"
26
22
  - ".rubocop.yml"
27
23
  - ".travis.yml"
24
+ - Appraisals
25
+ - CHANGELOG.md
28
26
  - Gemfile
29
27
  - Gemfile.lock
30
28
  - LICENSE
@@ -32,10 +30,17 @@ files:
32
30
  - Rakefile
33
31
  - bin/console
34
32
  - bin/setup
33
+ - gemfiles/.bundle/config
34
+ - gemfiles/openssl_2_0.gemfile
35
+ - gemfiles/openssl_2_1.gemfile
36
+ - gemfiles/openssl_2_2.gemfile
37
+ - gemfiles/openssl_default.gemfile
38
+ - gemfiles/openssl_head.gemfile
35
39
  - lib/openssl/signature_algorithm.rb
36
40
  - lib/openssl/signature_algorithm/base.rb
37
41
  - lib/openssl/signature_algorithm/ecdsa.rb
38
42
  - lib/openssl/signature_algorithm/error.rb
43
+ - lib/openssl/signature_algorithm/rsa.rb
39
44
  - lib/openssl/signature_algorithm/rsapkcs1.rb
40
45
  - lib/openssl/signature_algorithm/rsapss.rb
41
46
  - lib/openssl/signature_algorithm/version.rb
@@ -55,15 +60,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
55
60
  requirements:
56
61
  - - ">="
57
62
  - !ruby/object:Gem::Version
58
- version: 2.5.0
63
+ version: 2.4.0
59
64
  required_rubygems_version: !ruby/object:Gem::Requirement
60
65
  requirements:
61
66
  - - ">="
62
67
  - !ruby/object:Gem::Version
63
68
  version: '0'
64
69
  requirements: []
65
- rubygems_version: 3.1.2
70
+ rubygems_version: 3.1.4
66
71
  signing_key:
67
72
  specification_version: 4
68
- summary: Signature Algorithm abstraction for openssl ruby gem
73
+ summary: ECDSA, RSA-PSS and RSA-PKCS#1 algorithms for ruby
69
74
  test_files: []