openssl-signature_algorithm 0.2.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 155970f6aff98c1b9f86fe354d17a70fc7b558b7c7805c1c7f6ae65e55a24d13
4
- data.tar.gz: bd248c160731f6d98d5547c4cbe2895180a3b2fdec45ab74c7bd608f02e32949
3
+ metadata.gz: c5b527f33fd6b399b9b6c6baaebc173be1a848e3de4249dfc12c2640fbecf964
4
+ data.tar.gz: ad5361e7381c7aa34f66dbe94e32c7a5e54fcedd9a536897588728fd7f8e2771
5
5
  SHA512:
6
- metadata.gz: 311d955094353e8198ce781dda61c6038c2e1b731c48f5de5f7741faeabe6d9e24464d4aa9dc1dd10b897a3beef28a6046501ee59ce771914c3a71add860ff56
7
- data.tar.gz: c02b2031484f238b3069f16b3e0f88cd1ac980d67dfdd36fc3aed6cf6fcae8a8ee87bcc0b42da474360abef72e890e4d6acd86c4459e3b27d92a670332d15209
6
+ metadata.gz: 1e532e2f5ae196cc3136f7eefaee626bfb80454cd581c80f067e6c237769a262d0188c9c82a32a40193b7218238c979231861e64445074264eebf5d03dc16f5f
7
+ data.tar.gz: 2dcfffdf4680abeb725c4f15a36ac8fa80e49061d3408fba763270701ccc70c7982c6630ac26c8dcb56cd77f0b303e0431c1f923202d8eaccb0c01ede519d14d
@@ -0,0 +1,37 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: build
9
+
10
+ on: push
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-20.04
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ ruby-version:
19
+ - 3.0.0
20
+ - 2.7.2
21
+ - 2.6.6
22
+ - 2.5.8
23
+ - 2.4.10
24
+ gemfile:
25
+ - openssl_2_2
26
+ - openssl_2_1
27
+ - openssl_2_0
28
+ env:
29
+ BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
30
+ steps:
31
+ - uses: actions/checkout@v2
32
+ - run: rm Gemfile.lock
33
+ - uses: ruby/setup-ruby@v1
34
+ with:
35
+ ruby-version: ${{ matrix.ruby-version }}
36
+ bundler-cache: true
37
+ - run: bundle exec rake
data/.gitignore CHANGED
@@ -10,3 +10,5 @@
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
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
data/.rubocop.yml CHANGED
@@ -1,6 +1,9 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.5
2
+ TargetRubyVersion: 2.4
3
3
  DisabledByDefault: true
4
+ Exclude:
5
+ - "gemfiles/**/*"
6
+ - "vendor/bundle/**/*"
4
7
 
5
8
  Bundler:
6
9
  Enabled: true
@@ -26,9 +29,6 @@ Security:
26
29
  Style/BlockComments:
27
30
  Enabled: true
28
31
 
29
- Style/BracesAroundHashParameters:
30
- Enabled: true
31
-
32
32
  Style/CaseEquality:
33
33
  Enabled: true
34
34
 
data/Appraisals ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ appraise "openssl_2_2" do
4
+ gem "openssl", "~> 2.2.0"
5
+ end
6
+
7
+ appraise "openssl_2_1" do
8
+ gem "openssl", "~> 2.1.0"
9
+ end
10
+
11
+ appraise "openssl_2_0" do
12
+ gem "openssl", "~> 2.0.0"
13
+ end
data/CHANGELOG.md CHANGED
@@ -1,5 +1,69 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.1.1] - 2021-02-11
4
+
5
+ ### Fixed
6
+
7
+ - Fix error asking for ed25519 gem when actually not using EdDSA
8
+
9
+ ## [v1.1.0] - 2021-02-11
10
+
11
+ ### Added
12
+
13
+ - EdDSA support added (requires adding the `ed25519` gem to your `Gemfile`) ([@santiagorodriguez96])
14
+
15
+ ## [v1.0.0] - 2020-07-08
16
+
17
+ ### Added
18
+
19
+ - ECDSA with **secp256k1** curve support added:
20
+ ```rb
21
+ OpenSSL::SignatureAlgorithm::ECDSA.new(curve: "secp256k1")
22
+ ```
23
+ - Algorithm **arguments** are now **optional**. The following works:
24
+
25
+ ```rb
26
+ OpenSSL::SignatureAlgorithm::ECDSA.new
27
+ # defaults to ECDSA with SHA-256 and NIST P256 curve
28
+ # Same as OpenSSL::SignatureAlgorithm::ECDSA.new(hash_function: "SHA256", curve: "prime256v1")
29
+
30
+ OpenSSL::SignatureAlgorithm::RSAPSS.new
31
+ # defaults to SHA-256
32
+ # Same as OpenSSL::SignatureAlgorithm::RSAPSS.new(hash_function: "SHA256")
33
+
34
+ OpenSSL::SignatureAlgorithm::RSAPKCS1.new
35
+ # defaults to SHA-256
36
+ # Same as OpenSSL::SignatureAlgorithm::RSAPSS.new(hash_function: "SHA256")
37
+ ```
38
+
39
+ ### Changed
40
+
41
+ - 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:
42
+ ```rb
43
+ # Change this
44
+ # OpenSSL::SignatureAlgorithm::ECDSA.new("256")
45
+ # to
46
+ OpenSSL::SignatureAlgorithm::ECDSA.new(hash_function: "SHA256")
47
+ ```
48
+ ```rb
49
+ # Change this
50
+ # OpenSSL::SignatureAlgorithm::RSAPSS.new("384")
51
+ # to
52
+ OpenSSL::SignatureAlgorithm::RSAPSS.new(hash_function: "SHA384")
53
+ ```
54
+
55
+ ## [v0.4.0] - 2020-01-31
56
+
57
+ ### Added
58
+
59
+ - `VerifyKey` serialization and deserialization for easy transmission over the network
60
+
61
+ ## [v0.3.0] - 2020-01-30
62
+
63
+ ### Added
64
+
65
+ - Support ruby v2.4 (without RSA-PSS)
66
+
3
67
  ## [v0.2.0] - 2020-01-29
4
68
 
5
69
  ### Added
@@ -20,6 +84,13 @@
20
84
  - `OpenSSL::SignatureAlgorithm::RSAPSS`
21
85
  - `OpenSSL::SignatureAlgorithm::RSAPKCS1`
22
86
 
87
+ [v1.1.1]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v1.1.0...v1.1.1/
88
+ [v1.1.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v1.0.0...v1.1.0/
89
+ [v1.0.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.4.0...v1.0.0/
90
+ [v0.4.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.3.0...v0.4.0/
91
+ [v0.3.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.2.0...v0.3.0/
23
92
  [v0.2.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.1.1...v0.2.0/
24
93
  [v0.1.1]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.1.0...v0.1.1/
25
94
  [v0.1.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/41887c277dc7fa0c884ccf8924cf990ff76784d9...v0.1.0/
95
+
96
+ [@santiagorodriguez96]: https://github.com/santiagorodriguez96
data/Gemfile CHANGED
@@ -5,7 +5,9 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in openssl-signature_algorithm.gemspec
6
6
  gemspec
7
7
 
8
+ gem "appraisal", "~> 2.2"
8
9
  gem "byebug", "~> 11.0"
9
- gem "rake", "~> 12.0"
10
+ gem "ed25519", "~> 1.2"
11
+ gem "rake", "~> 13.0"
10
12
  gem "rspec", "~> 3.0"
11
- gem "rubocop", "~> 0.79.0"
13
+ gem "rubocop", "~> 0.80.1"
data/Gemfile.lock CHANGED
@@ -1,52 +1,64 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openssl-signature_algorithm (0.2.0)
4
+ openssl-signature_algorithm (1.1.1)
5
+ openssl (~> 2.0)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
8
9
  specs:
10
+ appraisal (2.2.0)
11
+ bundler
12
+ rake
13
+ thor (>= 0.14.0)
9
14
  ast (2.4.0)
10
15
  byebug (11.1.1)
11
16
  diff-lcs (1.3)
17
+ ed25519 (1.2.4)
12
18
  jaro_winkler (1.5.4)
19
+ openssl (2.2.0)
13
20
  parallel (1.19.1)
14
- parser (2.7.0.2)
21
+ parser (2.7.0.5)
15
22
  ast (~> 2.4.0)
16
23
  rainbow (3.0.0)
17
- rake (12.3.3)
24
+ rake (13.0.1)
25
+ rexml (3.2.4)
18
26
  rspec (3.9.0)
19
27
  rspec-core (~> 3.9.0)
20
28
  rspec-expectations (~> 3.9.0)
21
29
  rspec-mocks (~> 3.9.0)
22
30
  rspec-core (3.9.1)
23
31
  rspec-support (~> 3.9.1)
24
- rspec-expectations (3.9.0)
32
+ rspec-expectations (3.9.1)
25
33
  diff-lcs (>= 1.2.0, < 2.0)
26
34
  rspec-support (~> 3.9.0)
27
35
  rspec-mocks (3.9.1)
28
36
  diff-lcs (>= 1.2.0, < 2.0)
29
37
  rspec-support (~> 3.9.0)
30
38
  rspec-support (3.9.2)
31
- rubocop (0.79.0)
39
+ rubocop (0.80.1)
32
40
  jaro_winkler (~> 1.5.1)
33
41
  parallel (~> 1.10)
34
42
  parser (>= 2.7.0.1)
35
43
  rainbow (>= 2.2.2, < 4.0)
44
+ rexml
36
45
  ruby-progressbar (~> 1.7)
37
46
  unicode-display_width (>= 1.4.0, < 1.7)
38
47
  ruby-progressbar (1.10.1)
48
+ thor (1.0.1)
39
49
  unicode-display_width (1.6.1)
40
50
 
41
51
  PLATFORMS
42
52
  ruby
43
53
 
44
54
  DEPENDENCIES
55
+ appraisal (~> 2.2)
45
56
  byebug (~> 11.0)
57
+ ed25519 (~> 1.2)
46
58
  openssl-signature_algorithm!
47
- rake (~> 12.0)
59
+ rake (~> 13.0)
48
60
  rspec (~> 3.0)
49
- rubocop (~> 0.79.0)
61
+ rubocop (~> 0.80.1)
50
62
 
51
63
  BUNDLED WITH
52
- 2.1.4
64
+ 2.2.8
data/README.md CHANGED
@@ -1,11 +1,18 @@
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, EdDSA, 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
6
 
7
- [![Gem](https://img.shields.io/gem/v/openssl-signature_algorithm.svg?style=flat-square)](https://rubygems.org/gems/openssl-signature_algorithm)
8
- [![Travis](https://img.shields.io/travis/cedarcode/openssl-signature_algorithm.svg?style=flat-square)](https://travis-ci.org/cedarcode/openssl-signature_algorithm)
7
+ Provides `OpenSSL::SignatureAlgorithm::ECDSA`, `OpenSSL::SignatureAlgorithm::EdDSA`, `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
+ Loosely inspired by [rbnacl](https://github.com/RubyCrypto/rbnacl)'s [Digital Signatures](https://github.com/RubyCrypto/rbnacl/wiki/Digital-Signatures) interface.
13
+
14
+ [![Gem](https://img.shields.io/gem/v/openssl-signature_algorithm.svg?style=flat-square&color=informational)](https://rubygems.org/gems/openssl-signature_algorithm)
15
+ [![Actions Build](https://github.com/cedarcode/openssl-signature_algorithm/workflows/build/badge.svg)](https://github.com/cedarcode/openssl-signature_algorithm/actions)
9
16
 
10
17
  ## Installation
11
18
 
@@ -31,15 +38,40 @@ Or install it yourself as:
31
38
  to_be_signed = "to-be-signed"
32
39
 
33
40
  # Signer
34
- algorithm = OpenSSL::SignatureAlgorithm::ECDSA.new("256")
41
+ algorithm = OpenSSL::SignatureAlgorithm::ECDSA.new
42
+ signing_key = algorithm.generate_signing_key
43
+ signature = algorithm.sign(to_be_signed)
44
+
45
+ # Signer sends verify key to Verifier
46
+ verify_key_string = signing_key.verify_key.serialize
47
+
48
+ # Verifier
49
+ verify_key = OpenSSL::SignatureAlgorithm::ECDSA::VerifyKey.deserialize(verify_key_string)
50
+ algorithm = OpenSSL::SignatureAlgorithm::ECDSA.new
51
+ algorithm.verify_key = verify_key
52
+ algorithm.verify(signature, to_be_signed)
53
+ ```
54
+
55
+ ### EdDSA
56
+
57
+ Requires adding the `ed25519` gem to your `Gemfile`
58
+
59
+ ```ruby
60
+ require "openssl/signature_algorithm/eddsa"
61
+
62
+ to_be_signed = "to-be-signed"
63
+
64
+ # Signer
65
+ algorithm = OpenSSL::SignatureAlgorithm::EdDSA.new
35
66
  signing_key = algorithm.generate_signing_key
36
67
  signature = algorithm.sign(to_be_signed)
37
68
 
38
69
  # Signer sends verify key to Verifier
39
- verify_key = signing_key.verify_key
70
+ verify_key_string = signing_key.verify_key.serialize
40
71
 
41
72
  # Verifier
42
- algorithm = OpenSSL::SignatureAlgorithm::ECDSA.new("256")
73
+ verify_key = OpenSSL::SignatureAlgorithm::EdDSA::VerifyKey.deserialize(verify_key_string)
74
+ algorithm = OpenSSL::SignatureAlgorithm::EdDSA.new
43
75
  algorithm.verify_key = verify_key
44
76
  algorithm.verify(signature, to_be_signed)
45
77
  ```
@@ -50,15 +82,16 @@ algorithm.verify(signature, to_be_signed)
50
82
  to_be_signed = "to-be-signed"
51
83
 
52
84
  # Signer
53
- algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new("256")
85
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new
54
86
  signing_key = algorithm.generate_signing_key
55
87
  signature = algorithm.sign(to_be_signed)
56
88
 
57
89
  # Signer sends verify key to Verifier
58
- verify_key = signing_key.verify_key
90
+ verify_key_string = signing_key.verify_key.serialize
59
91
 
60
92
  # Verifier
61
- algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new("256")
93
+ verify_key = OpenSSL::SignatureAlgorithm::RSAPSS::VerifyKey.deserialize(verify_key_string)
94
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new
62
95
  algorithm.verify_key = verify_key
63
96
  algorithm.verify(signature, to_be_signed)
64
97
  ```
@@ -69,15 +102,16 @@ algorithm.verify(signature, to_be_signed)
69
102
  to_be_signed = "to-be-signed"
70
103
 
71
104
  # Signer
72
- algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new("256")
105
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new
73
106
  signing_key = algorithm.generate_signing_key
74
107
  signature = algorithm.sign(to_be_signed)
75
108
 
76
109
  # Signer sends verify key to Verifier
77
- verify_key = signing_key.verify_key
110
+ verify_key_string = signing_key.verify_key.serialize
78
111
 
79
112
  # Verifier
80
- algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new("256")
113
+ verify_key = OpenSSL::SignatureAlgorithm::RSAPKCS1::VerifyKey.deserialize(verify_key_string)
114
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new
81
115
  algorithm.verify_key = verify_key
82
116
  algorithm.verify(signature, to_be_signed)
83
117
  ```
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_RETRY: "1"
@@ -0,0 +1,13 @@
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 "ed25519", "~> 1.2"
11
+ gem "openssl", "~> 2.0.0"
12
+
13
+ gemspec path: "../"
@@ -0,0 +1,13 @@
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 "ed25519", "~> 1.2"
11
+ gem "openssl", "~> 2.1.0"
12
+
13
+ gemspec path: "../"
@@ -0,0 +1,13 @@
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 "ed25519", "~> 1.2"
11
+ gem "openssl", "~> 2.2.0"
12
+
13
+ gemspec path: "../"
@@ -5,20 +5,27 @@ 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)
@@ -30,7 +37,7 @@ module OpenSSL
30
37
  end
31
38
 
32
39
  verify_key.verify(hash_function, formatted_signature, verification_data) ||
33
- raise(OpenSSL::SignatureAlgorithm::Error, "Signature verification failed")
40
+ raise(OpenSSL::SignatureAlgorithm::SignatureVerificationError, "Signature verification failed")
34
41
  end
35
42
  end
36
43
  end
@@ -19,27 +19,48 @@ module OpenSSL
19
19
  end
20
20
 
21
21
  class VerifyKey < OpenSSL::PKey::EC::Point
22
- def verify(*args)
23
- ec_key = OpenSSL::PKey::EC.new(group)
24
- ec_key.public_key = self
22
+ def self.deserialize(pem_string)
23
+ new(OpenSSL::PKey::EC.new(pem_string).public_key)
24
+ end
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
25
35
 
36
+ ec_key
37
+ end
38
+ end
39
+
40
+ def verify(*args)
26
41
  ec_key.verify(*args)
27
42
  end
28
43
  end
29
44
 
30
- CURVE_BY_DIGEST_LENGTH = {
31
- "256" => "prime256v1",
32
- "384" => "secp384r1",
33
- "512" => "secp521r1"
34
- }.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
35
57
 
36
58
  def generate_signing_key
37
- @signing_key = SigningKey.new(curve_name)
59
+ @signing_key = SigningKey.new(curve)
38
60
  end
39
61
 
40
- def curve_name
41
- CURVE_BY_DIGEST_LENGTH[digest_length] ||
42
- 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
43
64
  end
44
65
 
45
66
  private
@@ -64,6 +85,28 @@ module OpenSSL
64
85
  def verify_key_length
65
86
  verify_key.group.degree
66
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
109
+ end
67
110
  end
68
111
  end
69
112
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ gem "ed25519", ">= 1.0.0"
5
+ require "ed25519"
6
+ rescue LoadError
7
+ warn "OpenSSL::SignatureAlgorithm::EdDSA requires the ed25519 gem, version 1.0 or higher. "\
8
+ "Please add it to your Gemfile: `gem \"ed25519\", \"~> 1.0\"`"
9
+ raise
10
+ end
11
+
12
+ require "openssl/signature_algorithm/base"
13
+
14
+ module OpenSSL
15
+ module SignatureAlgorithm
16
+ class EdDSA < Base
17
+ class SigningKey < ::Ed25519::SigningKey
18
+ def verify_key
19
+ VerifyKey.new(keypair[32, 32])
20
+ end
21
+ end
22
+
23
+ class VerifyKey < ::Ed25519::VerifyKey
24
+ def self.deserialize(key_bytes)
25
+ new(key_bytes)
26
+ end
27
+
28
+ def serialize
29
+ to_bytes
30
+ end
31
+ end
32
+
33
+ def generate_signing_key
34
+ @signing_key = SigningKey.generate
35
+ end
36
+
37
+ def sign(data)
38
+ signing_key.sign(data)
39
+ end
40
+
41
+ def verify(signature, verification_data)
42
+ verify_key.verify(signature, verification_data)
43
+ rescue ::Ed25519::VerifyError
44
+ raise(OpenSSL::SignatureAlgorithm::SignatureVerificationError, "Signature verification failed")
45
+ end
46
+ end
47
+ end
48
+ 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,23 +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 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
10
  signing_key.sign_pss(hash_function, data, salt_length: :max, mgf1_hash: mgf1_hash_function)
23
11
  end
@@ -29,7 +17,7 @@ module OpenSSL
29
17
  verification_data,
30
18
  salt_length: :auto,
31
19
  mgf1_hash: mgf1_hash_function
32
- ) || raise(OpenSSL::SignatureAlgorithm::Error, "Signature verification failed")
20
+ ) || raise(OpenSSL::SignatureAlgorithm::SignatureVerificationError, "Signature verification failed")
33
21
  end
34
22
 
35
23
  def mgf1_hash_function
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OpenSSL
4
4
  module SignatureAlgorithm
5
- VERSION = "0.2.0"
5
+ VERSION = "1.1.1"
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, EdDSA, RSA-PSS and RSA-PKCS#1 algorithms for ruby"
13
+ spec.description = spec.summary
19
14
 
20
15
  spec.homepage = "https://github.com/cedarcode/openssl-signature_algorithm"
21
- spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
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
@@ -32,4 +27,6 @@ Gem::Specification.new do |spec|
32
27
  spec.bindir = "exe"
33
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
34
29
  spec.require_paths = ["lib"]
30
+
31
+ spec.add_runtime_dependency "openssl", "~> 2.0"
35
32
  end
metadata CHANGED
@@ -1,30 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openssl-signature_algorithm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.1.1
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
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.
11
+ date: 2021-02-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: openssl
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ description: ECDSA, EdDSA, RSA-PSS and RSA-PKCS#1 algorithms for ruby
18
28
  email:
19
29
  - gonzalo@cedarcode.com
20
30
  executables: []
21
31
  extensions: []
22
32
  extra_rdoc_files: []
23
33
  files:
34
+ - ".github/workflows/build.yml"
24
35
  - ".gitignore"
25
36
  - ".rspec"
26
37
  - ".rubocop.yml"
27
- - ".travis.yml"
38
+ - Appraisals
28
39
  - CHANGELOG.md
29
40
  - Gemfile
30
41
  - Gemfile.lock
@@ -33,10 +44,16 @@ files:
33
44
  - Rakefile
34
45
  - bin/console
35
46
  - bin/setup
47
+ - gemfiles/.bundle/config
48
+ - gemfiles/openssl_2_0.gemfile
49
+ - gemfiles/openssl_2_1.gemfile
50
+ - gemfiles/openssl_2_2.gemfile
36
51
  - lib/openssl/signature_algorithm.rb
37
52
  - lib/openssl/signature_algorithm/base.rb
38
53
  - lib/openssl/signature_algorithm/ecdsa.rb
54
+ - lib/openssl/signature_algorithm/eddsa.rb
39
55
  - lib/openssl/signature_algorithm/error.rb
56
+ - lib/openssl/signature_algorithm/rsa.rb
40
57
  - lib/openssl/signature_algorithm/rsapkcs1.rb
41
58
  - lib/openssl/signature_algorithm/rsapss.rb
42
59
  - lib/openssl/signature_algorithm/version.rb
@@ -56,15 +73,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
73
  requirements:
57
74
  - - ">="
58
75
  - !ruby/object:Gem::Version
59
- version: 2.5.0
76
+ version: 2.4.0
60
77
  required_rubygems_version: !ruby/object:Gem::Requirement
61
78
  requirements:
62
79
  - - ">="
63
80
  - !ruby/object:Gem::Version
64
81
  version: '0'
65
82
  requirements: []
66
- rubygems_version: 3.1.2
83
+ rubygems_version: 3.2.8
67
84
  signing_key:
68
85
  specification_version: 4
69
- summary: Signature Algorithm abstraction for openssl ruby gem
86
+ summary: ECDSA, EdDSA, RSA-PSS and RSA-PKCS#1 algorithms for ruby
70
87
  test_files: []
data/.travis.yml DELETED
@@ -1,8 +0,0 @@
1
- ---
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.7.0
6
- - 2.6.5
7
- - 2.5.7
8
- before_install: gem install bundler -v 2.1.4