openssl-signature_algorithm 0.4.0 → 1.3.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: b7bc92eb1796a3b0f57e24b861d0eab80d3889189b2dcf48988f205e9d81cd69
4
- data.tar.gz: 365f011c31592f9d3d34a58a45b8ce3713227efbe5ea4a3bfc5fac0f87e68d14
3
+ metadata.gz: 05b32cb5c229b287708d0931b8ac52b8c90c98f53d31e146df38406870300e95
4
+ data.tar.gz: 0b35e770ff3342d8d7d7008f8a76a4cb40e63dfe756676276e84e72da0af6677
5
5
  SHA512:
6
- metadata.gz: 8f13ef1875e61ff4318e2888bba525388dbdddf6295a8eac737cfb02dc070a5d6de38b57297374368b1e8d0a8b1e380b6e1fa12c0d0c004a3300c1fe1d1763f6
7
- data.tar.gz: 96f2e6e633eb38af1d5df34ca33d1428f5fee4ee7945eb92354e481810601a13ce689705aaea29f84984a78eb8e46619fe48b7a623a1c93239f7b8c5fc544ec0
6
+ metadata.gz: f5bfe46225bf0fa061ef6046d94e7297bfd124be0b95cd4fc3cc125f8fcd58a288a8945a64f9af8f50ff3fdd22c148e3495bd643c9de5b535ca8ecb14c266649
7
+ data.tar.gz: 34a46fea3bde198cdbbc3b9e024dec9d635aa8c15484a819d8350bdd3b3a996dff75b6f64b6f9971f890c2796873594c555e0970f83a0e72adce9b22bf54c992
@@ -0,0 +1,54 @@
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.2.0
20
+ - 3.1.3
21
+ - 3.0.5
22
+ - 2.7.7
23
+ - 2.6.6
24
+ - 2.5.8
25
+ - 2.4.10
26
+ gemfile:
27
+ - openssl_3_1
28
+ - openssl_3_0
29
+ - openssl_2_2
30
+ - openssl_2_1
31
+ exclude:
32
+ - ruby-version: '2.4.10'
33
+ gemfile: openssl_3_0
34
+ - ruby-version: '2.5.8'
35
+ gemfile: openssl_3_0
36
+ - ruby-version: '2.4.10'
37
+ gemfile: openssl_3_1
38
+ - ruby-version: '2.5.8'
39
+ gemfile: openssl_3_1
40
+ env:
41
+ BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
42
+ steps:
43
+ - uses: actions/checkout@v2
44
+ - run: rm Gemfile.lock
45
+ - name: Set up Ruby ${{ matrix.ruby }}
46
+ uses: ruby/setup-ruby@v1
47
+ with:
48
+ ruby-version: ${{ matrix.ruby-version }}
49
+ bundler-cache: true
50
+ - name: Run rubocop
51
+ run: bundle exec rubocop
52
+ if: ${{ matrix.ruby == '3.2.0' }}
53
+ - name: Run tests
54
+ run: bundle exec rspec
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,10 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 2.4
3
3
  DisabledByDefault: true
4
+ NewCops: disable
5
+ Exclude:
6
+ - "gemfiles/**/*"
7
+ - "vendor/bundle/**/*"
4
8
 
5
9
  Bundler:
6
10
  Enabled: true
@@ -17,6 +21,9 @@ Layout/LineLength:
17
21
  Lint:
18
22
  Enabled: true
19
23
 
24
+ Lint/MissingSuper:
25
+ Enabled: false
26
+
20
27
  Naming:
21
28
  Enabled: true
22
29
 
@@ -26,9 +33,6 @@ Security:
26
33
  Style/BlockComments:
27
34
  Enabled: true
28
35
 
29
- Style/BracesAroundHashParameters:
30
- Enabled: true
31
-
32
36
  Style/CaseEquality:
33
37
  Enabled: true
34
38
 
data/Appraisals ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ appraise "openssl_3_1" do
4
+ gem "openssl", "~> 3.1.0"
5
+ end
6
+
7
+ appraise "openssl_3_0" do
8
+ gem "openssl", "~> 3.0.0"
9
+ end
10
+
11
+ appraise "openssl_2_2" do
12
+ gem "openssl", "~> 2.2.0"
13
+ end
14
+
15
+ appraise "openssl_2_1" do
16
+ gem "openssl", "~> 2.1.0"
17
+ end
data/CHANGELOG.md CHANGED
@@ -1,5 +1,65 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.3.0] - 2023-02-15
4
+
5
+ - Loose OpenSSL dependency to support 3.1 users. Thanks @bdewater <3
6
+
7
+ ## [v1.2.1] - 2022-06-05
8
+
9
+ - Support OpenSSL ~>3.0.0. Credits to @ClearlyClaire <3
10
+
11
+ ## [v1.1.1] - 2021-02-11
12
+
13
+ ### Fixed
14
+
15
+ - Fix error asking for ed25519 gem when actually not using EdDSA
16
+
17
+ ## [v1.1.0] - 2021-02-11
18
+
19
+ ### Added
20
+
21
+ - EdDSA support added (requires adding the `ed25519` gem to your `Gemfile`) ([@santiagorodriguez96])
22
+
23
+ ## [v1.0.0] - 2020-07-08
24
+
25
+ ### Added
26
+
27
+ - ECDSA with **secp256k1** curve support added:
28
+ ```rb
29
+ OpenSSL::SignatureAlgorithm::ECDSA.new(curve: "secp256k1")
30
+ ```
31
+ - Algorithm **arguments** are now **optional**. The following works:
32
+
33
+ ```rb
34
+ OpenSSL::SignatureAlgorithm::ECDSA.new
35
+ # defaults to ECDSA with SHA-256 and NIST P256 curve
36
+ # Same as OpenSSL::SignatureAlgorithm::ECDSA.new(hash_function: "SHA256", curve: "prime256v1")
37
+
38
+ OpenSSL::SignatureAlgorithm::RSAPSS.new
39
+ # defaults to SHA-256
40
+ # Same as OpenSSL::SignatureAlgorithm::RSAPSS.new(hash_function: "SHA256")
41
+
42
+ OpenSSL::SignatureAlgorithm::RSAPKCS1.new
43
+ # defaults to SHA-256
44
+ # Same as OpenSSL::SignatureAlgorithm::RSAPSS.new(hash_function: "SHA256")
45
+ ```
46
+
47
+ ### Changed
48
+
49
+ - 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:
50
+ ```rb
51
+ # Change this
52
+ # OpenSSL::SignatureAlgorithm::ECDSA.new("256")
53
+ # to
54
+ OpenSSL::SignatureAlgorithm::ECDSA.new(hash_function: "SHA256")
55
+ ```
56
+ ```rb
57
+ # Change this
58
+ # OpenSSL::SignatureAlgorithm::RSAPSS.new("384")
59
+ # to
60
+ OpenSSL::SignatureAlgorithm::RSAPSS.new(hash_function: "SHA384")
61
+ ```
62
+
3
63
  ## [v0.4.0] - 2020-01-31
4
64
 
5
65
  ### Added
@@ -32,8 +92,17 @@
32
92
  - `OpenSSL::SignatureAlgorithm::RSAPSS`
33
93
  - `OpenSSL::SignatureAlgorithm::RSAPKCS1`
34
94
 
95
+ [v1.3.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v1.2.1...v1.3.0/
96
+ [v1.2.1]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v1.1.1...v1.2.1/
97
+ [v1.1.1]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v1.1.0...v1.1.1/
98
+ [v1.1.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v1.0.0...v1.1.0/
99
+ [v1.0.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.4.0...v1.0.0/
35
100
  [v0.4.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.3.0...v0.4.0/
36
101
  [v0.3.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.2.0...v0.3.0/
37
102
  [v0.2.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.1.1...v0.2.0/
38
103
  [v0.1.1]: https://github.com/cedarcode/openssl-signature_algorithm/compare/v0.1.0...v0.1.1/
39
104
  [v0.1.0]: https://github.com/cedarcode/openssl-signature_algorithm/compare/41887c277dc7fa0c884ccf8924cf990ff76784d9...v0.1.0/
105
+
106
+ [@santiagorodriguez96]: https://github.com/santiagorodriguez96
107
+ [@ClearlyClaire]: https://github.com/clearlyclaire
108
+ [@bdewater]: https://github.com/bdewater
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", "~> 1.0"
data/Gemfile.lock CHANGED
@@ -1,52 +1,69 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openssl-signature_algorithm (0.4.0)
4
+ openssl-signature_algorithm (1.2.1)
5
+ openssl (> 2.0)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
8
9
  specs:
9
- ast (2.4.0)
10
+ appraisal (2.2.0)
11
+ bundler
12
+ rake
13
+ thor (>= 0.14.0)
14
+ ast (2.4.2)
10
15
  byebug (11.1.1)
11
16
  diff-lcs (1.3)
12
- jaro_winkler (1.5.4)
13
- parallel (1.19.1)
14
- parser (2.7.0.2)
15
- ast (~> 2.4.0)
16
- rainbow (3.0.0)
17
- rake (12.3.3)
17
+ ed25519 (1.2.4)
18
+ json (2.6.3)
19
+ openssl (3.0.0)
20
+ parallel (1.22.1)
21
+ parser (3.2.1.0)
22
+ ast (~> 2.4.1)
23
+ rainbow (3.1.1)
24
+ rake (13.0.1)
25
+ regexp_parser (2.7.0)
26
+ rexml (3.2.5)
18
27
  rspec (3.9.0)
19
28
  rspec-core (~> 3.9.0)
20
29
  rspec-expectations (~> 3.9.0)
21
30
  rspec-mocks (~> 3.9.0)
22
31
  rspec-core (3.9.1)
23
32
  rspec-support (~> 3.9.1)
24
- rspec-expectations (3.9.0)
33
+ rspec-expectations (3.9.1)
25
34
  diff-lcs (>= 1.2.0, < 2.0)
26
35
  rspec-support (~> 3.9.0)
27
36
  rspec-mocks (3.9.1)
28
37
  diff-lcs (>= 1.2.0, < 2.0)
29
38
  rspec-support (~> 3.9.0)
30
39
  rspec-support (3.9.2)
31
- rubocop (0.79.0)
32
- jaro_winkler (~> 1.5.1)
40
+ rubocop (1.45.1)
41
+ json (~> 2.3)
33
42
  parallel (~> 1.10)
34
- parser (>= 2.7.0.1)
43
+ parser (>= 3.2.0.0)
35
44
  rainbow (>= 2.2.2, < 4.0)
45
+ regexp_parser (>= 1.8, < 3.0)
46
+ rexml (>= 3.2.5, < 4.0)
47
+ rubocop-ast (>= 1.24.1, < 2.0)
36
48
  ruby-progressbar (~> 1.7)
37
- unicode-display_width (>= 1.4.0, < 1.7)
38
- ruby-progressbar (1.10.1)
39
- unicode-display_width (1.6.1)
49
+ unicode-display_width (>= 2.4.0, < 3.0)
50
+ rubocop-ast (1.24.1)
51
+ parser (>= 3.1.1.0)
52
+ ruby-progressbar (1.11.0)
53
+ thor (1.0.1)
54
+ unicode-display_width (2.4.2)
40
55
 
41
56
  PLATFORMS
42
57
  ruby
43
58
 
44
59
  DEPENDENCIES
60
+ appraisal (~> 2.2)
45
61
  byebug (~> 11.0)
62
+ ed25519 (~> 1.2)
46
63
  openssl-signature_algorithm!
47
- rake (~> 12.0)
64
+ rake (~> 13.0)
48
65
  rspec (~> 3.0)
49
- rubocop (~> 0.79.0)
66
+ rubocop (~> 1.0)
50
67
 
51
68
  BUNDLED WITH
52
- 2.1.4
69
+ 2.3.26
data/README.md CHANGED
@@ -1,12 +1,18 @@
1
1
  # OpenSSL::SignatureAlgorithm
2
2
 
3
- Provides `OpenSSL::SignatureAlgorithm::ECDSA`, `OpenSSL::SignatureAlgorithm::RSAPSS`
4
- and `OpenSSL::SignatureAlgorithm::RSAPKCS1` ruby object wrapers on top of `OpenSSL::PKey::EC`
5
- and `OpenSSL::PKey::RSA`, so that you can reason in terms of signature algorithms when
6
- signing and/or verifying signatures, instead of keys.
3
+ > ECDSA, EdDSA, RSA-PSS and RSA-PKCS#1 signature algorithms for ruby
4
+
5
+ Sign and verify using signature algorithm wrappers, instead of key objects.
6
+
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.
7
13
 
8
14
  [![Gem](https://img.shields.io/gem/v/openssl-signature_algorithm.svg?style=flat-square&color=informational)](https://rubygems.org/gems/openssl-signature_algorithm)
9
- [![Travis](https://img.shields.io/travis/cedarcode/openssl-signature_algorithm.svg?style=flat-square)](https://travis-ci.org/cedarcode/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)
10
16
 
11
17
  ## Installation
12
18
 
@@ -32,7 +38,7 @@ Or install it yourself as:
32
38
  to_be_signed = "to-be-signed"
33
39
 
34
40
  # Signer
35
- algorithm = OpenSSL::SignatureAlgorithm::ECDSA.new("256")
41
+ algorithm = OpenSSL::SignatureAlgorithm::ECDSA.new
36
42
  signing_key = algorithm.generate_signing_key
37
43
  signature = algorithm.sign(to_be_signed)
38
44
 
@@ -41,7 +47,31 @@ verify_key_string = signing_key.verify_key.serialize
41
47
 
42
48
  # Verifier
43
49
  verify_key = OpenSSL::SignatureAlgorithm::ECDSA::VerifyKey.deserialize(verify_key_string)
44
- algorithm = OpenSSL::SignatureAlgorithm::ECDSA.new("256")
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
66
+ signing_key = algorithm.generate_signing_key
67
+ signature = algorithm.sign(to_be_signed)
68
+
69
+ # Signer sends verify key to Verifier
70
+ verify_key_string = signing_key.verify_key.serialize
71
+
72
+ # Verifier
73
+ verify_key = OpenSSL::SignatureAlgorithm::EdDSA::VerifyKey.deserialize(verify_key_string)
74
+ algorithm = OpenSSL::SignatureAlgorithm::EdDSA.new
45
75
  algorithm.verify_key = verify_key
46
76
  algorithm.verify(signature, to_be_signed)
47
77
  ```
@@ -52,7 +82,7 @@ algorithm.verify(signature, to_be_signed)
52
82
  to_be_signed = "to-be-signed"
53
83
 
54
84
  # Signer
55
- algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new("256")
85
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new
56
86
  signing_key = algorithm.generate_signing_key
57
87
  signature = algorithm.sign(to_be_signed)
58
88
 
@@ -61,7 +91,7 @@ verify_key_string = signing_key.verify_key.serialize
61
91
 
62
92
  # Verifier
63
93
  verify_key = OpenSSL::SignatureAlgorithm::RSAPSS::VerifyKey.deserialize(verify_key_string)
64
- algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new("256")
94
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPSS.new
65
95
  algorithm.verify_key = verify_key
66
96
  algorithm.verify(signature, to_be_signed)
67
97
  ```
@@ -72,7 +102,7 @@ algorithm.verify(signature, to_be_signed)
72
102
  to_be_signed = "to-be-signed"
73
103
 
74
104
  # Signer
75
- algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new("256")
105
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new
76
106
  signing_key = algorithm.generate_signing_key
77
107
  signature = algorithm.sign(to_be_signed)
78
108
 
@@ -81,7 +111,7 @@ verify_key_string = signing_key.verify_key.serialize
81
111
 
82
112
  # Verifier
83
113
  verify_key = OpenSSL::SignatureAlgorithm::RSAPKCS1::VerifyKey.deserialize(verify_key_string)
84
- algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new("256")
114
+ algorithm = OpenSSL::SignatureAlgorithm::RSAPKCS1.new
85
115
  algorithm.verify_key = verify_key
86
116
  algorithm.verify(signature, to_be_signed)
87
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 "ed25519", "~> 1.2"
8
+ gem "rake", "~> 13.0"
9
+ gem "rspec", "~> 3.0"
10
+ gem "rubocop", "~> 1.0"
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 "ed25519", "~> 1.2"
8
+ gem "rake", "~> 13.0"
9
+ gem "rspec", "~> 3.0"
10
+ gem "rubocop", "~> 1.0"
11
+ gem "openssl", "~> 2.2.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 "ed25519", "~> 1.2"
8
+ gem "rake", "~> 13.0"
9
+ gem "rspec", "~> 3.0"
10
+ gem "rubocop", "~> 1.0"
11
+ gem "openssl", "~> 3.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 "ed25519", "~> 1.2"
8
+ gem "rake", "~> 13.0"
9
+ gem "rspec", "~> 3.0"
10
+ gem "rubocop", "~> 1.0"
11
+ gem "openssl", "~> 3.1.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
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "delegate"
3
4
  require "openssl"
4
5
  require "openssl/signature_algorithm/base"
5
6
 
@@ -8,9 +9,9 @@ module OpenSSL
8
9
  class ECDSA < Base
9
10
  BYTE_LENGTH = 8
10
11
 
11
- class SigningKey < OpenSSL::PKey::EC
12
+ class SigningKey < DelegateClass(OpenSSL::PKey::EC)
12
13
  def initialize(*args)
13
- super(*args).generate_key
14
+ super(OpenSSL::PKey::EC.generate(*args))
14
15
  end
15
16
 
16
17
  def verify_key
@@ -18,7 +19,11 @@ module OpenSSL
18
19
  end
19
20
  end
20
21
 
21
- class VerifyKey < OpenSSL::PKey::EC::Point
22
+ class VerifyKey < DelegateClass(OpenSSL::PKey::EC::Point)
23
+ def initialize(*args)
24
+ super(OpenSSL::PKey::EC::Point.new(*args))
25
+ end
26
+
22
27
  def self.deserialize(pem_string)
23
28
  new(OpenSSL::PKey::EC.new(pem_string).public_key)
24
29
  end
@@ -30,10 +35,20 @@ module OpenSSL
30
35
  def ec_key
31
36
  @ec_key ||=
32
37
  begin
33
- ec_key = OpenSSL::PKey::EC.new(group)
34
- ec_key.public_key = self
35
-
36
- ec_key
38
+ # RFC5480 SubjectPublicKeyInfo
39
+ asn1 = OpenSSL::ASN1::Sequence(
40
+ [
41
+ OpenSSL::ASN1::Sequence(
42
+ [
43
+ OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
44
+ OpenSSL::ASN1::ObjectId(group.curve_name),
45
+ ]
46
+ ),
47
+ OpenSSL::ASN1::BitString(to_octet_string(:uncompressed))
48
+ ]
49
+ )
50
+
51
+ OpenSSL::PKey::EC.new(asn1.to_der)
37
52
  end
38
53
  end
39
54
 
@@ -42,19 +57,25 @@ module OpenSSL
42
57
  end
43
58
  end
44
59
 
45
- CURVE_BY_DIGEST_LENGTH = {
46
- "256" => "prime256v1",
47
- "384" => "secp384r1",
48
- "512" => "secp521r1"
49
- }.freeze
60
+ ACCEPTED_PARAMETERS = [
61
+ { curve: "prime256v1", hash_function: "SHA256" },
62
+ { curve: "secp384r1", hash_function: "SHA384" },
63
+ { curve: "secp521r1", hash_function: "SHA512" },
64
+ { curve: "secp256k1", hash_function: "SHA256" }
65
+ ].freeze
66
+
67
+ attr_reader :curve, :hash_function
68
+
69
+ def initialize(curve: nil, hash_function: nil)
70
+ @curve, @hash_function = pick_parameters(curve, hash_function)
71
+ end
50
72
 
51
73
  def generate_signing_key
52
- @signing_key = SigningKey.new(curve_name)
74
+ @signing_key = SigningKey.new(curve)
53
75
  end
54
76
 
55
- def curve_name
56
- CURVE_BY_DIGEST_LENGTH[digest_length] ||
57
- raise(OpenSSL::SignatureAlgorithm::Error, "Unsupported digest length #{digest_length}")
77
+ def compatible_verify_key?(key)
78
+ super && key.respond_to?(:group) && key.group.curve_name == curve
58
79
  end
59
80
 
60
81
  private
@@ -79,6 +100,28 @@ module OpenSSL
79
100
  def verify_key_length
80
101
  verify_key.group.degree
81
102
  end
103
+
104
+ def pick_parameters(curve, hash_function)
105
+ parameters = ACCEPTED_PARAMETERS.detect do |params|
106
+ if curve
107
+ if hash_function
108
+ params[:curve] == curve && params[:hash_function] == hash_function
109
+ else
110
+ params[:curve] == curve
111
+ end
112
+ elsif hash_function
113
+ params[:hash_function] == hash_function
114
+ else
115
+ true
116
+ end
117
+ end
118
+
119
+ if parameters
120
+ [parameters[:curve], parameters[:hash_function]]
121
+ else
122
+ raise(OpenSSL::SignatureAlgorithm::UnsupportedParameterError, "Unsupported algorithm parameters")
123
+ end
124
+ end
82
125
  end
83
126
  end
84
127
  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,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+ require "openssl"
5
+ require "openssl/signature_algorithm/base"
6
+
7
+ module OpenSSL
8
+ module SignatureAlgorithm
9
+ class RSA < Base
10
+ class SigningKey < DelegateClass(OpenSSL::PKey::RSA)
11
+ def initialize(*args)
12
+ super(OpenSSL::PKey::RSA.new(*args))
13
+ end
14
+
15
+ def verify_key
16
+ VerifyKey.new(public_key.to_pem)
17
+ end
18
+ end
19
+
20
+ class VerifyKey < DelegateClass(OpenSSL::PKey::RSA)
21
+ class << self
22
+ alias_method :deserialize, :new
23
+ end
24
+
25
+ def initialize(*args)
26
+ super(OpenSSL::PKey::RSA.new(*args))
27
+ end
28
+
29
+ def serialize
30
+ to_pem
31
+ end
32
+ end
33
+
34
+ ACCEPTED_HASH_FUNCTIONS = ["SHA256", "SHA384", "SHA512"].freeze
35
+ DEFAULT_KEY_SIZE = 2048
36
+
37
+ attr_reader :hash_function
38
+
39
+ def initialize(hash_function: self.class::ACCEPTED_HASH_FUNCTIONS.first)
40
+ if self.class::ACCEPTED_HASH_FUNCTIONS.include?(hash_function)
41
+ @hash_function = hash_function
42
+ else
43
+ raise(OpenSSL::SignatureAlgorithm::UnsupportedParameterError, "Unsupported hash function '#{hash_function}'")
44
+ end
45
+ end
46
+
47
+ def generate_signing_key(size: DEFAULT_KEY_SIZE)
48
+ @signing_key = SigningKey.new(size)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,32 +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
- 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
- DEFAULT_KEY_SIZE = 2048
26
-
27
- def generate_signing_key(size: DEFAULT_KEY_SIZE)
28
- @signing_key = SigningKey.new(size)
29
- end
8
+ class RSAPKCS1 < RSA
30
9
  end
31
10
  end
32
11
  end
@@ -1,33 +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
- 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
- DEFAULT_KEY_SIZE = 2048
26
-
27
- def generate_signing_key(size: DEFAULT_KEY_SIZE)
28
- @signing_key = SigningKey.new(size)
29
- end
30
-
8
+ class RSAPSS < RSA
31
9
  def sign(data)
32
10
  signing_key.sign_pss(hash_function, data, salt_length: :max, mgf1_hash: mgf1_hash_function)
33
11
  end
@@ -39,7 +17,7 @@ module OpenSSL
39
17
  verification_data,
40
18
  salt_length: :auto,
41
19
  mgf1_hash: mgf1_hash_function
42
- ) || raise(OpenSSL::SignatureAlgorithm::Error, "Signature verification failed")
20
+ ) || raise(OpenSSL::SignatureAlgorithm::SignatureVerificationError, "Signature verification failed")
43
21
  end
44
22
 
45
23
  def mgf1_hash_function
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OpenSSL
4
4
  module SignatureAlgorithm
5
- VERSION = "0.4.0"
5
+ VERSION = "1.3.0"
6
6
  end
7
7
  end
@@ -9,14 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ["gonzalo@cedarcode.com"]
10
10
  spec.license = "Apache-2.0"
11
11
 
12
- spec.summary = "OpenSSL::SignatureAlgorithm helpers for signing and verifying signatures with openssl ruby gem"
13
-
14
- spec.description = <<-DESC
15
- Provides OpenSSL::SignatureAlgorithm::ECDSA, OpenSSL::SignatureAlgorithm::RSAPSS
16
- and OpenSSL::SignatureAlgorithm::RSAPKCS1 ruby object wrapers on top of OpenSSL::PKey::EC
17
- and OpenSSL::PKey::RSA, so that you can reason in terms of signature algorithms when
18
- signing and/or verifying signatures, instead of keys.
19
- DESC
12
+ spec.summary = "ECDSA, EdDSA, RSA-PSS and RSA-PKCS#1 algorithms for ruby"
13
+ spec.description = spec.summary
20
14
 
21
15
  spec.homepage = "https://github.com/cedarcode/openssl-signature_algorithm"
22
16
  spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
@@ -33,4 +27,6 @@ Gem::Specification.new do |spec|
33
27
  spec.bindir = "exe"
34
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
35
29
  spec.require_paths = ["lib"]
30
+
31
+ spec.add_runtime_dependency "openssl", "> 2.0"
36
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.4.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gonzalo Rodriguez
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-31 00:00:00.000000000 Z
12
- dependencies: []
13
- description: |2
14
- Provides OpenSSL::SignatureAlgorithm::ECDSA, OpenSSL::SignatureAlgorithm::RSAPSS
15
- and OpenSSL::SignatureAlgorithm::RSAPKCS1 ruby object wrapers on top of OpenSSL::PKey::EC
16
- and OpenSSL::PKey::RSA, so that you can reason in terms of signature algorithms when
17
- signing and/or verifying signatures, instead of keys.
11
+ date: 2023-02-15 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,17 @@ files:
33
44
  - Rakefile
34
45
  - bin/console
35
46
  - bin/setup
47
+ - gemfiles/.bundle/config
48
+ - gemfiles/openssl_2_1.gemfile
49
+ - gemfiles/openssl_2_2.gemfile
50
+ - gemfiles/openssl_3_0.gemfile
51
+ - gemfiles/openssl_3_1.gemfile
36
52
  - lib/openssl/signature_algorithm.rb
37
53
  - lib/openssl/signature_algorithm/base.rb
38
54
  - lib/openssl/signature_algorithm/ecdsa.rb
55
+ - lib/openssl/signature_algorithm/eddsa.rb
39
56
  - lib/openssl/signature_algorithm/error.rb
57
+ - lib/openssl/signature_algorithm/rsa.rb
40
58
  - lib/openssl/signature_algorithm/rsapkcs1.rb
41
59
  - lib/openssl/signature_algorithm/rsapss.rb
42
60
  - lib/openssl/signature_algorithm/version.rb
@@ -48,7 +66,7 @@ metadata:
48
66
  homepage_uri: https://github.com/cedarcode/openssl-signature_algorithm
49
67
  source_code_uri: https://github.com/cedarcode/openssl-signature_algorithm
50
68
  changelog_uri: https://github.com/cedarcode/openssl-signature_algorithm/blob/master/CHANGELOG.md
51
- post_install_message:
69
+ post_install_message:
52
70
  rdoc_options: []
53
71
  require_paths:
54
72
  - lib
@@ -63,9 +81,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
81
  - !ruby/object:Gem::Version
64
82
  version: '0'
65
83
  requirements: []
66
- rubygems_version: 3.1.2
67
- signing_key:
84
+ rubygems_version: 3.2.32
85
+ signing_key:
68
86
  specification_version: 4
69
- summary: OpenSSL::SignatureAlgorithm helpers for signing and verifying signatures
70
- with openssl ruby gem
87
+ summary: ECDSA, EdDSA, RSA-PSS and RSA-PKCS#1 algorithms for ruby
71
88
  test_files: []
data/.travis.yml DELETED
@@ -1,10 +0,0 @@
1
- ---
2
- dist: bionic
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.7.0
7
- - 2.6.5
8
- - 2.5.7
9
- - 2.4.9
10
- before_install: gem install bundler -v 2.1.4