cose 1.0.0 → 1.2.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: f3fdc6957e5130367c9a1e8ab223b5c145d6caca1c04b01552410ef6d14bc740
4
- data.tar.gz: 6849a1803ff3bb2e92bdf90b4226c8d023b07012b7cb18a915b9f816aed2e1dc
3
+ metadata.gz: 3065ed49e2bb4795f22f0fe132fd1645f7db6062ce7102cf6fde7aeb23859657
4
+ data.tar.gz: c4dc7b4bab6fd4c2898be067c60ca52b43ca743ee8b1dae5359a1a659a0f8d2c
5
5
  SHA512:
6
- metadata.gz: cc1093c925a437283fb6b7658bacd6bcd2f8427962dd4f1a5ac9a9a81341a5beaa8f1d21ce40b74372dd86fddf5df1f7702a6790f79d166fd1a5ea8ca359d66a
7
- data.tar.gz: 6d11eb89cfc72edaaa9d3533c87f39d509efcff65d7c10070321c39144f91b3ef421bf8dd32b250d621f31fde8a766c98e2c516d8091af802749c707a25ee9d0
6
+ metadata.gz: ce3922d45c7dfca8cc649e89e775169ade6bc2ea7d5fdad829380452c7337c79989b33c198105fc134e36719bc147324678638c0e5235fd4a5776412c2e9d07f
7
+ data.tar.gz: ae49b8afa26ee2bf25f90f3052f9cd9cf20f68c12b2541859b80c524e9b0d8a9d9b433dd82f247ade6b2430bff852eb67c83724ee60edf61676b0505096a393d
@@ -0,0 +1,38 @@
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:
19
+ - 3.0.0
20
+ - 2.7.2
21
+ - 2.6.6
22
+ - 2.5.8
23
+ - 2.4.10
24
+ gemfile:
25
+ - openssl_3_0
26
+ - openssl_2_2
27
+ - openssl_2_1
28
+ - openssl_2_0
29
+ - openssl_default
30
+ env:
31
+ BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
32
+ steps:
33
+ - uses: actions/checkout@v2
34
+ - uses: ruby/setup-ruby@v1
35
+ with:
36
+ ruby-version: ${{ matrix.ruby }}
37
+ bundler-cache: true
38
+ - run: bundle exec rake
data/Appraisals CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- appraise "openssl_head" do
4
- gem "openssl", git: "https://github.com/ruby/openssl"
3
+ appraise "openssl_2_2" do
4
+ gem "openssl", "~> 2.2.0"
5
5
  end
6
6
 
7
7
  appraise "openssl_2_1" do
@@ -12,5 +12,9 @@ appraise "openssl_2_0" do
12
12
  gem "openssl", "~> 2.0.0"
13
13
  end
14
14
 
15
+ appraise "openssl_3_0" do
16
+ gem "openssl", "~> 3.0.0"
17
+ end
18
+
15
19
  appraise "openssl_default" do
16
20
  end
data/CHANGELOG.md CHANGED
@@ -1,12 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.2.1] - 2022-07-03
4
+
5
+ - Support OpenSSL ~>3.0.0. Credits to @ClearlyClaire <3
6
+
7
+ ## [v1.2.0] - 2020-07-10
8
+
9
+ ### Added
10
+
11
+ - Support ES256K signature algorithm
12
+
13
+ ## [v1.1.0] - 2020-07-09
14
+
15
+ ### Dependencies
16
+
17
+ - Update `openssl-signature_algorithm` runtime dependency from `~> 0.4.0` to `~> 1.0`.
18
+
3
19
  ## [v1.0.0] - 2020-03-29
4
20
 
5
21
  ### Added
6
22
 
7
23
  - Signature verification validates key `alg` is compatible with the signature algorithm
8
24
 
9
- NOTE: No breaking changes. Moving out of v0.x` to express the intention to keep the public API stable.
25
+ NOTE: No breaking changes. Moving out of `v0.x` to express the intention to keep the public API stable.
10
26
 
11
27
  ## [v0.11.0] - 2020-01-30
12
28
 
@@ -123,6 +139,9 @@ NOTE: No breaking changes. Moving out of v0.x` to express the intention to keep
123
139
  - EC2 key object
124
140
  - Works with ruby 2.5
125
141
 
142
+ [v1.2.0]: https://github.com/cedarcode/cose-ruby/compare/v1.2.0...v1.2.1/
143
+ [v1.2.0]: https://github.com/cedarcode/cose-ruby/compare/v1.1.0...v1.2.0/
144
+ [v1.1.0]: https://github.com/cedarcode/cose-ruby/compare/v1.0.0...v1.1.0/
126
145
  [v1.0.0]: https://github.com/cedarcode/cose-ruby/compare/v0.11.0...v1.0.0/
127
146
  [v0.11.0]: https://github.com/cedarcode/cose-ruby/compare/v0.10.0...v0.11.0/
128
147
  [v0.10.0]: https://github.com/cedarcode/cose-ruby/compare/v0.9.0...v0.10.0/
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Ruby implementation of RFC [8152](https://tools.ietf.org/html/rfc8152) CBOR Object Signing and Encryption (COSE)
4
4
 
5
5
  [![Gem](https://img.shields.io/gem/v/cose.svg?style=flat-square&color=informational)](https://rubygems.org/gems/cose)
6
- [![Travis](https://img.shields.io/travis/cedarcode/cose-ruby.svg?style=flat-square)](https://travis-ci.org/cedarcode/cose-ruby)
6
+ [![Actions Build](https://github.com/cedarcode/cose-ruby/workflows/build/badge.svg)](https://github.com/cedarcode/cose-ruby/actions)
7
7
 
8
8
  ## Installation
9
9
 
data/bin/setup CHANGED
@@ -3,6 +3,8 @@ set -euo pipefail
3
3
  IFS=$'\n\t'
4
4
  set -vx
5
5
 
6
+ git submodule update --init --recursive
7
+
6
8
  bundle install
7
9
 
8
10
  # Do any other automated setup that you need to do here
data/cose.gemspec CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.required_ruby_version = ">= 2.4"
33
33
 
34
34
  spec.add_dependency "cbor", "~> 0.5.9"
35
- spec.add_dependency "openssl-signature_algorithm", "~> 0.4.0"
35
+ spec.add_dependency "openssl-signature_algorithm", "~> 1.0"
36
36
 
37
37
  spec.add_development_dependency "appraisal", "~> 2.2.0"
38
38
  spec.add_development_dependency "bundler", ">= 1.17", "< 3"
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "openssl", git: "https://github.com/ruby/openssl"
5
+ gem "openssl", "~> 2.2.0"
6
6
 
7
7
  gemspec path: "../"
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "cose/algorithm/signature_algorithm"
4
4
  require "cose/error"
5
+ require "cose/key/curve"
5
6
  require "cose/key/ec2"
6
7
  require "openssl"
7
8
  require "openssl/signature_algorithm/ecdsa"
@@ -9,12 +10,13 @@ require "openssl/signature_algorithm/ecdsa"
9
10
  module COSE
10
11
  module Algorithm
11
12
  class ECDSA < SignatureAlgorithm
12
- attr_reader :hash_function
13
+ attr_reader :hash_function, :curve
13
14
 
14
- def initialize(*args, hash_function:)
15
+ def initialize(*args, hash_function:, curve_name:)
15
16
  super(*args)
16
17
 
17
18
  @hash_function = hash_function
19
+ @curve = COSE::Key::Curve.by_name(curve_name) || raise("Couldn't find curve with name='#{curve_name}'")
18
20
  end
19
21
 
20
22
  private
@@ -29,6 +31,14 @@ module COSE
29
31
  OpenSSL::SignatureAlgorithm::ECDSA
30
32
  end
31
33
 
34
+ def signature_algorithm_parameters
35
+ if curve
36
+ super.merge(curve: curve.pkey_name)
37
+ else
38
+ super
39
+ end
40
+ end
41
+
32
42
  def to_pkey(key)
33
43
  case key
34
44
  when COSE::Key::EC2
@@ -20,7 +20,7 @@ module COSE
20
20
  private
21
21
 
22
22
  def valid_signature?(key, signature, verification_data)
23
- signature_algorithm = signature_algorithm_class.new(hash_function[3..-1])
23
+ signature_algorithm = signature_algorithm_class.new(**signature_algorithm_parameters)
24
24
  signature_algorithm.verify_key = to_pkey(key)
25
25
 
26
26
  begin
@@ -30,6 +30,10 @@ module COSE
30
30
  end
31
31
  end
32
32
 
33
+ def signature_algorithm_parameters
34
+ { hash_function: hash_function }
35
+ end
36
+
33
37
  def to_cose_key(key)
34
38
  case key
35
39
  when COSE::Key::Base
@@ -26,9 +26,10 @@ module COSE
26
26
  @registered_by_name[name]
27
27
  end
28
28
 
29
- register(ECDSA.new(-7, "ES256", hash_function: "SHA256"))
30
- register(ECDSA.new(-35, "ES384", hash_function: "SHA384"))
31
- register(ECDSA.new(-36, "ES512", hash_function: "SHA512"))
29
+ register(ECDSA.new(-7, "ES256", hash_function: "SHA256", curve_name: "P-256"))
30
+ register(ECDSA.new(-35, "ES384", hash_function: "SHA384", curve_name: "P-384"))
31
+ register(ECDSA.new(-36, "ES512", hash_function: "SHA512", curve_name: "P-521"))
32
+ register(ECDSA.new(-47, "ES256K", hash_function: "SHA256", curve_name: "secp256k1"))
32
33
  register(RSAPSS.new(-37, "PS256", hash_function: "SHA256", salt_length: 32))
33
34
  register(RSAPSS.new(-38, "PS384", hash_function: "SHA384", salt_length: 48))
34
35
  register(RSAPSS.new(-39, "PS512", hash_function: "SHA512", salt_length: 64))
data/lib/cose/key/base.rb CHANGED
@@ -41,14 +41,12 @@ module COSE
41
41
  end
42
42
 
43
43
  def map
44
- map = {
44
+ {
45
45
  LABEL_BASE_IV => base_iv,
46
46
  LABEL_KEY_OPS => key_ops,
47
47
  LABEL_ALG => alg,
48
48
  LABEL_KID => kid,
49
- }
50
-
51
- map.reject { |_k, v| v.nil? }
49
+ }.compact
52
50
  end
53
51
  end
54
52
  end
@@ -32,3 +32,4 @@ end
32
32
  COSE::Key::Curve.register(1, "P-256", "prime256v1")
33
33
  COSE::Key::Curve.register(2, "P-384", "secp384r1")
34
34
  COSE::Key::Curve.register(3, "P-521", "secp521r1")
35
+ COSE::Key::Curve.register(8, "secp256k1", "secp256k1")
@@ -35,13 +35,11 @@ module COSE
35
35
  end
36
36
 
37
37
  def map
38
- map = super.merge(
38
+ super.merge(
39
39
  LABEL_CRV => crv,
40
40
  LABEL_X => x,
41
41
  LABEL_D => d
42
- )
43
-
44
- map.reject { |_k, v| v.nil? }
42
+ ).compact
45
43
  end
46
44
  end
47
45
  end
data/lib/cose/key/ec2.rb CHANGED
@@ -59,12 +59,10 @@ module COSE
59
59
  end
60
60
 
61
61
  def map
62
- map = super.merge(
62
+ super.merge(
63
63
  Base::LABEL_KTY => KTY_EC2,
64
64
  LABEL_Y => y,
65
- )
66
-
67
- map.reject { |_k, v| v.nil? }
65
+ ).compact
68
66
  end
69
67
 
70
68
  def to_pkey
@@ -73,13 +71,31 @@ module COSE
73
71
  pkey = OpenSSL::PKey::EC.new(group)
74
72
  public_key_bn = OpenSSL::BN.new("\x04" + x + y, 2)
75
73
  public_key_point = OpenSSL::PKey::EC::Point.new(group, public_key_bn)
76
- pkey.public_key = public_key_point
74
+
75
+ # RFC5480 SubjectPublicKeyInfo
76
+ asn1 = OpenSSL::ASN1::Sequence([
77
+ OpenSSL::ASN1::Sequence([
78
+ OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
79
+ OpenSSL::ASN1::ObjectId(curve.pkey_name),
80
+ ]),
81
+ OpenSSL::ASN1::BitString(public_key_point.to_octet_string(:uncompressed))
82
+ ])
77
83
 
78
84
  if d
79
- pkey.private_key = OpenSSL::BN.new(d, 2)
85
+ # RFC5915 ECPrivateKey
86
+ asn1 = OpenSSL::ASN1::Sequence([
87
+ OpenSSL::ASN1::Integer.new(1),
88
+ # Not properly padded but OpenSSL doesn't mind
89
+ OpenSSL::ASN1::OctetString(OpenSSL::BN.new(d, 2).to_s(2)),
90
+ OpenSSL::ASN1::ObjectId(curve.pkey_name, 0, :EXPLICIT),
91
+ OpenSSL::ASN1::BitString(public_key_point.to_octet_string(:uncompressed), 1, :EXPLICIT),
92
+ ])
93
+
94
+ der = asn1.to_der
95
+ return OpenSSL::PKey::EC.new(der)
80
96
  end
81
97
 
82
- pkey
98
+ OpenSSL::PKey::EC.new(asn1.to_der)
83
99
  else
84
100
  raise "Unsupported curve #{crv}"
85
101
  end
data/lib/cose/key/rsa.rb CHANGED
@@ -74,7 +74,7 @@ module COSE
74
74
  end
75
75
 
76
76
  def map
77
- map = super.merge(
77
+ super.merge(
78
78
  Base::LABEL_KTY => KTY_RSA,
79
79
  LABEL_N => n,
80
80
  LABEL_E => e,
@@ -84,37 +84,32 @@ module COSE
84
84
  LABEL_DP => dp,
85
85
  LABEL_DQ => dq,
86
86
  LABEL_QINV => qinv
87
- )
88
-
89
- map.reject { |_k, v| v.nil? }
87
+ ).compact
90
88
  end
91
89
 
92
90
  def to_pkey
93
- pkey = OpenSSL::PKey::RSA.new
94
-
95
- if pkey.respond_to?(:set_key)
96
- pkey.set_key(bn(n), bn(e), bn(d))
97
- else
98
- pkey.n = bn(n)
99
- pkey.e = bn(e)
100
- pkey.d = bn(d)
101
- end
91
+ # PKCS#1 RSAPublicKey
92
+ asn1 = OpenSSL::ASN1::Sequence([
93
+ OpenSSL::ASN1::Integer.new(bn(n)),
94
+ OpenSSL::ASN1::Integer.new(bn(e)),
95
+ ])
96
+ pkey = OpenSSL::PKey::RSA.new(asn1.to_der)
102
97
 
103
98
  if private?
104
- if pkey.respond_to?(:set_factors)
105
- pkey.set_factors(bn(p), bn(q))
106
- else
107
- pkey.p = bn(p)
108
- pkey.q = bn(q)
109
- end
110
-
111
- if pkey.respond_to?(:set_crt_params)
112
- pkey.set_crt_params(bn(dp), bn(dq), bn(qinv))
113
- else
114
- pkey.dmp1 = bn(dp)
115
- pkey.dmq1 = bn(dq)
116
- pkey.iqmp = bn(qinv)
117
- end
99
+ # PKCS#1 RSAPrivateKey
100
+ asn1 = OpenSSL::ASN1::Sequence([
101
+ OpenSSL::ASN1::Integer.new(0),
102
+ OpenSSL::ASN1::Integer.new(bn(n)),
103
+ OpenSSL::ASN1::Integer.new(bn(e)),
104
+ OpenSSL::ASN1::Integer.new(bn(d)),
105
+ OpenSSL::ASN1::Integer.new(bn(p)),
106
+ OpenSSL::ASN1::Integer.new(bn(q)),
107
+ OpenSSL::ASN1::Integer.new(bn(dp)),
108
+ OpenSSL::ASN1::Integer.new(bn(dq)),
109
+ OpenSSL::ASN1::Integer.new(bn(qinv)),
110
+ ])
111
+
112
+ pkey = OpenSSL::PKey::RSA.new(asn1.to_der)
118
113
  end
119
114
 
120
115
  pkey
data/lib/cose/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module COSE
4
- VERSION = "1.0.0"
4
+ VERSION = "1.2.1"
5
5
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cose
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gonzalo Rodriguez
8
8
  - Braulio Martinez
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-03-29 00:00:00.000000000 Z
12
+ date: 2022-07-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cbor
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 0.4.0
34
+ version: '1.0'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 0.4.0
41
+ version: '1.0'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: appraisal
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -143,7 +143,7 @@ dependencies:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
145
  version: '1.4'
146
- description:
146
+ description:
147
147
  email:
148
148
  - gonzalo@cedarcode.com
149
149
  - braulio@cedarcode.com
@@ -151,11 +151,11 @@ executables: []
151
151
  extensions: []
152
152
  extra_rdoc_files: []
153
153
  files:
154
+ - ".github/workflows/build.yml"
154
155
  - ".gitignore"
155
156
  - ".gitmodules"
156
157
  - ".rspec"
157
158
  - ".rubocop.yml"
158
- - ".travis.yml"
159
159
  - Appraisals
160
160
  - CHANGELOG.md
161
161
  - Gemfile
@@ -168,8 +168,8 @@ files:
168
168
  - cose.gemspec
169
169
  - gemfiles/openssl_2_0.gemfile
170
170
  - gemfiles/openssl_2_1.gemfile
171
+ - gemfiles/openssl_2_2.gemfile
171
172
  - gemfiles/openssl_default.gemfile
172
- - gemfiles/openssl_head.gemfile
173
173
  - lib/cose.rb
174
174
  - lib/cose/algorithm.rb
175
175
  - lib/cose/algorithm/base.rb
@@ -204,7 +204,7 @@ metadata:
204
204
  bug_tracker_uri: https://github.com/cedarcode/cose-ruby/issues
205
205
  changelog_uri: https://github.com/cedarcode/cose-ruby/blob/master/CHANGELOG.md
206
206
  source_code_uri: https://github.com/cedarcode/cose-ruby
207
- post_install_message:
207
+ post_install_message:
208
208
  rdoc_options: []
209
209
  require_paths:
210
210
  - lib
@@ -219,8 +219,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
219
  - !ruby/object:Gem::Version
220
220
  version: '0'
221
221
  requirements: []
222
- rubygems_version: 3.1.2
223
- signing_key:
222
+ rubygems_version: 3.2.32
223
+ signing_key:
224
224
  specification_version: 4
225
225
  summary: Ruby implementation of RFC 8152 CBOR Object Signing and Encryption (COSE)
226
226
  test_files: []
data/.travis.yml DELETED
@@ -1,24 +0,0 @@
1
- dist: bionic
2
- language: ruby
3
- cache: bundler
4
-
5
- rvm:
6
- - ruby-head
7
- - 2.7.0
8
- - 2.6.5
9
- - 2.5.7
10
- - 2.4.9
11
-
12
- gemfile:
13
- - gemfiles/openssl_head.gemfile
14
- - gemfiles/openssl_2_1.gemfile
15
- - gemfiles/openssl_2_0.gemfile
16
- - gemfiles/openssl_default.gemfile
17
-
18
- before_install: gem install bundler -v '~> 2.0'
19
-
20
- matrix:
21
- fast_finish: true
22
- allow_failures:
23
- - rvm: ruby-head
24
- - gemfile: gemfiles/openssl_head.gemfile