cose 0.5.0 → 0.6.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: eb978af65e0e7ba43a06e776b45792856bec76e58a7ce6d1d3d88619c6fca09e
4
- data.tar.gz: c8cdf73b87523e266c36076c542cf91bb5e252bda826523308b4adc355ce1c6d
3
+ metadata.gz: 32030549359b2c5afe6862546965c13f4071b55c9ace03a6385ce5c62c3af7bc
4
+ data.tar.gz: 46e4769b04dadb56b998ae807a2cfe80e73c95c131c93b8b6424d5752f1aae0a
5
5
  SHA512:
6
- metadata.gz: bc8f10f840915de994963318cf3fb5f138eb836bd391280029cceb7b5b4c9a95577dd281be1d67f1dc36def4a5a809af6e4ff665dc26e0cf30990219248cf043
7
- data.tar.gz: 87ec47c8278246a0fdbec217a1d13b6588aed62400bfd49010d4573dab75b70a436867fe8d4fb895b784bbe29783c28e2910f576f213aeda8d830662f1067f7f
6
+ metadata.gz: 907c461c040d4e80b19403922557a7098e30cb348a829f9252ed74ab4c9f8d3ca62ba24f75ddc6e4df6c19de95f900be53483dbc4c97ded66927433513a38ce0
7
+ data.tar.gz: 8142ebaaf7c32486f60f29243e689ae5bf96a4a39eed87838c55eeed8a13cc102e7dbd14d489749da9cff5ac149aa4a97c172f113e69f70e0658d285f3571063
data/.rubocop.yml CHANGED
@@ -16,6 +16,7 @@ Lint:
16
16
 
17
17
  Metrics/LineLength:
18
18
  Max: 120
19
+ IgnoreCopDirectives: true
19
20
 
20
21
  Naming:
21
22
  Enabled: true
data/.travis.yml CHANGED
@@ -4,16 +4,25 @@ language: ruby
4
4
  rvm:
5
5
  - ruby-head
6
6
  - 2.6.2
7
- - 2.5.4
8
- - 2.4.5
7
+ - 2.5.5
8
+ - 2.4.6
9
+ - 2.3.8
10
+ - 2.2.10
9
11
 
10
12
  gemfile:
11
13
  - gemfiles/openssl_2_0.gemfile
12
14
  - gemfiles/openssl_2_1.gemfile
15
+ - gemfiles/openssl_default.gemfile
13
16
 
14
- before_install: gem install bundler -v 2.0.1
17
+ before_install: gem install bundler -v '~> 1.17'
15
18
 
16
19
  matrix:
17
20
  fast_finish: true
18
21
  allow_failures:
19
22
  - rvm: ruby-head
23
+ - rvm: 2.2.10
24
+ exclude:
25
+ - rvm: 2.2.10
26
+ gemfile: gemfiles/openssl_2_0.gemfile
27
+ - rvm: 2.2.10
28
+ gemfile: gemfiles/openssl_2_1.gemfile
data/Appraisals CHANGED
@@ -5,3 +5,6 @@ end
5
5
  appraise "openssl_2_1" do
6
6
  gem "openssl", "~> 2.1.0"
7
7
  end
8
+
9
+ appraise "openssl_default" do
10
+ end
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.6.0] - 2019-04-03
4
+
5
+ ### Added
6
+
7
+ - Support Key Common Parameters (`#base_iv`, `key_ops`, `#alg` and `#kid`)
8
+ - Support OKP Key
9
+ - Support RSA private key serialization
10
+ - Works with ruby 2.3
11
+
12
+ ### Changed
13
+
14
+ - Key type-specific parameters names better match RFC
15
+
3
16
  ## [v0.5.0] - 2019-03-25
4
17
 
5
18
  ### Added
@@ -54,6 +67,7 @@
54
67
  - EC2 key object
55
68
  - Works with ruby 2.5
56
69
 
70
+ [v0.6.0]: https://github.com/cedarcode/cose-ruby/compare/v0.5.0...v0.6.0/
57
71
  [v0.5.0]: https://github.com/cedarcode/cose-ruby/compare/v0.4.1...v0.5.0/
58
72
  [v0.4.1]: https://github.com/cedarcode/cose-ruby/compare/v0.4.0...v0.4.1/
59
73
  [v0.4.0]: https://github.com/cedarcode/cose-ruby/compare/v0.3.0...v0.4.0/
data/README.md CHANGED
@@ -30,48 +30,65 @@ Or install it yourself as:
30
30
  ```ruby
31
31
  cbor_data = "..."
32
32
 
33
- cose_key = COSE::Key.deserialize(cbor_data)
33
+ key = COSE::Key.deserialize(cbor_data)
34
34
  ```
35
35
 
36
36
  Once you have a `COSE::Key` instance you can either access key parameters directly and/or convert it to an
37
- `OpenSSL::PKey::PKey` instance for operating with it (encrypting/decrypting, signing/verifying, etc).
37
+ `OpenSSL::PKey::PKey` instance (if supported for the key type) for operating with it
38
+ (encrypting/decrypting, signing/verifying, etc).
38
39
 
39
40
  ```ruby
40
41
  # Convert to an OpenSSL::PKey::PKey
41
- openssl_pkey = cose_key.to_pkey
42
+ if key.respond_to?(:to_pkey)
43
+ openssl_pkey = key.to_pkey
44
+ end
42
45
 
43
46
  # Access COSE key parameters
44
47
  case key
48
+ when COSE::Key::OKP
49
+ key.crv
50
+ key.x
51
+ key.d
45
52
  when COSE::Key::EC2
46
- key.curve
47
- key.x_coordinate
48
- key.y_coordinate
49
- key.d_coordinate
53
+ key.crv
54
+ key.x
55
+ key.y
56
+ key.d
50
57
  when COSE::Key::RSA
51
- key.modulus_n
52
- key.public_exponent_e
53
- key.private_exponent_d
54
- key.prime_factor_p
55
- key.prime_factor_q
56
- key.d_p
57
- key.d_q
58
- key.q_inv
58
+ key.n
59
+ key.e
60
+ key.d
61
+ key.p
62
+ key.q
63
+ key.dp
64
+ key.dq
65
+ key.qinv
59
66
  when COSE::Key::Symmetric
60
- key.key_value
67
+ key.k
61
68
  end
62
69
  ```
63
70
 
64
71
  If you already know which COSE key type is encoded in the CBOR data, then:
65
72
 
73
+ ```ruby
74
+ okp_key_cbor = "..."
75
+
76
+ cose_okp_key = COSE::Key::OKP.deserialize(okp_key_cbor)
77
+
78
+ cose_okp_key.crv
79
+ cose_okp_key.x
80
+ cose_okp_key.d
81
+ ```
82
+
66
83
  ```ruby
67
84
  ec2_key_cbor = "..."
68
85
 
69
86
  cose_ec2_key = COSE::Key::EC2.deserialize(ec2_key_cbor)
70
87
 
71
- cose_ec2_key.curve
72
- cose_ec2_key.x_coordinate
73
- cose_ec2_key.y_coordinate
74
- cose_ec2_key.d_coordinate
88
+ cose_ec2_key.crv
89
+ cose_ec2_key.x
90
+ cose_ec2_key.y
91
+ cose_ec2_key.d
75
92
 
76
93
  # or
77
94
 
@@ -83,7 +100,7 @@ symmetric_key_cbor = "..."
83
100
 
84
101
  cose_symmetric_key = COSE::Key::Symmetric.deserialize(symmetric_key_cbor)
85
102
 
86
- cose_symmetric_key.key_value
103
+ cose_symmetric_key.k
87
104
  ```
88
105
 
89
106
  ```ruby
@@ -91,14 +108,14 @@ rsa_key_cbor = "..."
91
108
 
92
109
  cose_rsa_key = COSE::Key::RSA.deserialize(rsa_key_cbor)
93
110
 
94
- cose_rsa_key.modulus_n
95
- cose_rsa_key.public_exponent_e
96
- cose_rsa_key.private_exponent_d
97
- cose_rsa_key.prime_factor_p
98
- cose_rsa_key.prime_factor_q
99
- cose_rsa_key.d_p
100
- cose_rsa_key.d_q
101
- cose_rsa_key.q_inv
111
+ cose_rsa_key.n
112
+ cose_rsa_key.e
113
+ cose_rsa_key.d
114
+ cose_rsa_key.p
115
+ cose_rsa_key.q
116
+ cose_rsa_key.dp
117
+ cose_rsa_key.dq
118
+ cose_rsa_key.qinv
102
119
 
103
120
  # or
104
121
 
data/cose.gemspec CHANGED
@@ -35,7 +35,7 @@ Gem::Specification.new do |spec|
35
35
 
36
36
  spec.add_development_dependency "appraisal", "~> 2.2.0"
37
37
  spec.add_development_dependency "bundler", ">= 1.17", "< 3"
38
- spec.add_development_dependency "byebug", "~> 11.0"
38
+ spec.add_development_dependency "byebug", ">= 10.0"
39
39
  spec.add_development_dependency "rake", "~> 12.3"
40
40
  spec.add_development_dependency "rspec", "~> 3.8"
41
41
  spec.add_development_dependency "rubocop", "0.65.0"
@@ -0,0 +1,5 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec path: "../"
data/lib/cose/key.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "cbor"
2
2
  require "cose/key/ec2"
3
+ require "cose/key/okp"
3
4
  require "cose/key/rsa"
4
5
  require "cose/key/symmetric"
5
6
  require "openssl"
@@ -23,12 +24,16 @@ module COSE
23
24
  map = CBOR.decode(data)
24
25
 
25
26
  case map[Base::LABEL_KTY]
27
+ when COSE::Key::OKP::KTY_OKP
28
+ COSE::Key::OKP.from_map(map)
26
29
  when COSE::Key::EC2::KTY_EC2
27
30
  COSE::Key::EC2.from_map(map)
28
31
  when COSE::Key::RSA::KTY_RSA
29
32
  COSE::Key::RSA.from_map(map)
30
33
  when COSE::Key::Symmetric::KTY_SYMMETRIC
31
34
  COSE::Key::Symmetric.from_map(map)
35
+ when nil
36
+ raise UnknownKeyType, "Missing required key type kty label"
32
37
  else
33
38
  raise UnknownKeyType, "Unsupported or unknown key type #{map[Base::LABEL_KTY]}"
34
39
  end
data/lib/cose/key/base.rb CHANGED
@@ -5,16 +5,50 @@ require "cbor"
5
5
  module COSE
6
6
  module Key
7
7
  class Base
8
+ LABEL_BASE_IV = 5
9
+ LABEL_KEY_OPS = 4
10
+ LABEL_ALG = 3
11
+ LABEL_KID = 2
8
12
  LABEL_KTY = 1
9
13
 
10
14
  def self.deserialize(cbor)
11
15
  from_map(CBOR.decode(cbor))
12
16
  end
13
17
 
14
- def self.enforce_type(map, kty, error_message)
15
- if map[LABEL_KTY] != kty
16
- raise error_message
17
- end
18
+ def self.from_map(map)
19
+ enforce_type(map)
20
+
21
+ new(
22
+ base_iv: map[LABEL_BASE_IV],
23
+ key_ops: map[LABEL_KEY_OPS],
24
+ alg: map[LABEL_ALG],
25
+ kid: map[LABEL_KID],
26
+ **keyword_arguments_for_initialize(map)
27
+ )
28
+ end
29
+
30
+ attr_reader :kid, :alg, :key_ops, :base_iv
31
+
32
+ def initialize(kid: nil, alg: nil, key_ops: nil, base_iv: nil)
33
+ @kid = kid
34
+ @alg = alg
35
+ @key_ops = key_ops
36
+ @base_iv = base_iv
37
+ end
38
+
39
+ def serialize
40
+ CBOR.encode(map)
41
+ end
42
+
43
+ def map
44
+ map = {
45
+ LABEL_BASE_IV => base_iv,
46
+ LABEL_KEY_OPS => key_ops,
47
+ LABEL_ALG => alg,
48
+ LABEL_KID => kid,
49
+ }
50
+
51
+ map.reject { |_k, v| v.nil? }
18
52
  end
19
53
  end
20
54
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cose/key/base"
4
+ require "openssl"
5
+
6
+ module COSE
7
+ module Key
8
+ class CurveKey < Base
9
+ LABEL_CRV = -1
10
+ LABEL_X = -2
11
+ LABEL_D = -4
12
+
13
+ attr_reader :crv, :d, :x
14
+
15
+ def self.keyword_arguments_for_initialize(map)
16
+ {
17
+ crv: map[LABEL_CRV],
18
+ x: map[LABEL_X],
19
+ d: map[LABEL_D]
20
+ }
21
+ end
22
+
23
+ def initialize(crv:, x: nil, d: nil, **keyword_arguments) # rubocop:disable Naming/UncommunicativeMethodParamName
24
+ super(**keyword_arguments)
25
+
26
+ if !crv
27
+ raise ArgumentError, "Required crv is missing"
28
+ elsif !x && !d
29
+ raise ArgumentError, "x and d cannot be missing simultaneously"
30
+ else
31
+ @crv = crv
32
+ @x = x
33
+ @d = d
34
+ end
35
+ end
36
+
37
+ def map
38
+ map = super.merge(
39
+ LABEL_CRV => crv,
40
+ LABEL_X => x,
41
+ LABEL_D => d
42
+ )
43
+
44
+ map.reject { |_k, v| v.nil? }
45
+ end
46
+ end
47
+ end
48
+ end
data/lib/cose/key/ec2.rb CHANGED
@@ -1,17 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "cose/key/base"
3
+ require "cose/key/curve_key"
4
4
  require "openssl"
5
5
 
6
6
  module COSE
7
7
  module Key
8
- class EC2 < Base
9
- ALG_LABEL = 3
10
-
11
- CRV_LABEL = -1
12
- D_LABEL = -4
13
- X_LABEL = -2
14
- Y_LABEL = -3
8
+ class EC2 < CurveKey
9
+ LABEL_Y = -3
15
10
 
16
11
  KTY_EC2 = 2
17
12
  CRV_P256 = 1
@@ -24,6 +19,12 @@ module COSE
24
19
  CRV_P521 => "secp521r1"
25
20
  }.freeze
26
21
 
22
+ def self.enforce_type(map)
23
+ if map[LABEL_KTY] != KTY_EC2
24
+ raise "Not an EC2 key"
25
+ end
26
+ end
27
+
27
28
  def self.from_pkey(pkey)
28
29
  curve = PKEY_CURVES.key(pkey.group.curve_name) || raise("Unsupported EC curve #{pkey.group.curve_name}")
29
30
 
@@ -42,73 +43,58 @@ module COSE
42
43
 
43
44
  coordinate_length = bytes.size / 2
44
45
 
45
- x_coordinate = bytes[0..(coordinate_length - 1)]
46
- y_coordinate = bytes[coordinate_length..-1]
46
+ x = bytes[0..(coordinate_length - 1)]
47
+ y = bytes[coordinate_length..-1]
47
48
  end
48
49
 
49
50
  if private_key
50
- d_coordinate = private_key.to_s(2)
51
+ d = private_key.to_s(2)
51
52
  end
52
53
 
53
- new(curve: curve, x_coordinate: x_coordinate, y_coordinate: y_coordinate, d_coordinate: d_coordinate)
54
+ new(crv: curve, x: x, y: y, d: d)
54
55
  end
55
56
 
56
- attr_reader :algorithm, :curve, :d_coordinate, :x_coordinate, :y_coordinate
57
+ attr_reader :y
57
58
 
58
- def initialize(algorithm: nil, curve:, d_coordinate: nil, x_coordinate:, y_coordinate:)
59
- if !curve
60
- raise ArgumentError, "Required curve is missing"
61
- elsif !x_coordinate
62
- raise ArgumentError, "Required x-coordinate is missing"
63
- elsif !y_coordinate
64
- raise ArgumentError, "Required y-coordinate is missing"
59
+ def initialize(y: nil, **keyword_arguments) # rubocop:disable Naming/UncommunicativeMethodParamName
60
+ if (!y || !keyword_arguments[:x]) && !keyword_arguments[:d]
61
+ raise ArgumentError, "Both x and y are required if d is missing"
65
62
  else
66
- @algorithm = algorithm
67
- @curve = curve
68
- @d_coordinate = d_coordinate
69
- @x_coordinate = x_coordinate
70
- @y_coordinate = y_coordinate
63
+ super(**keyword_arguments)
64
+
65
+ @y = y
71
66
  end
72
67
  end
73
68
 
74
- def serialize
75
- CBOR.encode(
69
+ def map
70
+ map = super.merge(
76
71
  Base::LABEL_KTY => KTY_EC2,
77
- CRV_LABEL => curve,
78
- X_LABEL => x_coordinate,
79
- Y_LABEL => y_coordinate,
80
- D_LABEL => d_coordinate
72
+ LABEL_Y => y,
81
73
  )
74
+
75
+ map.reject { |_k, v| v.nil? }
82
76
  end
83
77
 
84
78
  def to_pkey
85
- if PKEY_CURVES[curve]
86
- group = OpenSSL::PKey::EC::Group.new(PKEY_CURVES[curve])
79
+ if PKEY_CURVES[crv]
80
+ group = OpenSSL::PKey::EC::Group.new(PKEY_CURVES[crv])
87
81
  pkey = OpenSSL::PKey::EC.new(group)
88
- public_key_bn = OpenSSL::BN.new("\x04" + x_coordinate + y_coordinate, 2)
82
+ public_key_bn = OpenSSL::BN.new("\x04" + x + y, 2)
89
83
  public_key_point = OpenSSL::PKey::EC::Point.new(group, public_key_bn)
90
84
  pkey.public_key = public_key_point
91
85
 
92
- if d_coordinate
93
- pkey.private_key = OpenSSL::BN.new(d_coordinate, 2)
86
+ if d
87
+ pkey.private_key = OpenSSL::BN.new(d, 2)
94
88
  end
95
89
 
96
90
  pkey
97
91
  else
98
- raise "Unsupported curve #{curve}"
92
+ raise "Unsupported curve #{crv}"
99
93
  end
100
94
  end
101
95
 
102
- def self.from_map(map)
103
- enforce_type(map, KTY_EC2, "Not an EC2 key")
104
-
105
- new(
106
- algorithm: map[ALG_LABEL],
107
- curve: map[CRV_LABEL],
108
- d_coordinate: map[D_LABEL],
109
- x_coordinate: map[X_LABEL],
110
- y_coordinate: map[Y_LABEL]
111
- )
96
+ def self.keyword_arguments_for_initialize(map)
97
+ super.merge(y: map[LABEL_Y])
112
98
  end
113
99
  end
114
100
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cose/key/curve_key"
4
+ require "openssl"
5
+
6
+ module COSE
7
+ module Key
8
+ class OKP < CurveKey
9
+ KTY_OKP = 1
10
+
11
+ def self.enforce_type(map)
12
+ if map[LABEL_KTY] != KTY_OKP
13
+ raise "Not an OKP key"
14
+ end
15
+ end
16
+
17
+ def map
18
+ super.merge(LABEL_KTY => KTY_OKP)
19
+ end
20
+ end
21
+ end
22
+ end
data/lib/cose/key/rsa.rb CHANGED
@@ -11,99 +11,124 @@ module COSE
11
11
  LABEL_D = -3
12
12
  LABEL_P = -4
13
13
  LABEL_Q = -5
14
- LABEL_D_P = -6
15
- LABEL_D_Q = -7
16
- LABEL_Q_INV = -8
14
+ LABEL_DP = -6
15
+ LABEL_DQ = -7
16
+ LABEL_QINV = -8
17
17
 
18
18
  KTY_RSA = 3
19
19
 
20
+ def self.enforce_type(map)
21
+ if map[LABEL_KTY] != KTY_RSA
22
+ raise "Not an RSA key"
23
+ end
24
+ end
25
+
20
26
  def self.from_pkey(pkey)
21
27
  params = pkey.params
22
28
 
23
29
  attributes = {
24
- modulus_n: params["n"].to_s(2),
25
- public_exponent_e: params["e"].to_s(2)
30
+ n: params["n"].to_s(2),
31
+ e: params["e"].to_s(2)
26
32
  }
27
33
 
28
34
  if pkey.private?
29
35
  attributes.merge!(
30
- private_exponent_d: params["d"].to_s(2),
31
- prime_factor_p: params["p"].to_s(2),
32
- prime_factor_q: params["q"].to_s(2),
33
- d_p: params["dmp1"].to_s(2),
34
- d_q: params["dmq1"].to_s(2),
35
- q_inv: params["iqmp"].to_s(2)
36
+ d: params["d"].to_s(2),
37
+ p: params["p"].to_s(2),
38
+ q: params["q"].to_s(2),
39
+ dp: params["dmp1"].to_s(2),
40
+ dq: params["dmq1"].to_s(2),
41
+ qinv: params["iqmp"].to_s(2)
36
42
  )
37
43
  end
38
44
 
39
45
  new(attributes)
40
46
  end
41
47
 
42
- attr_reader(
43
- :modulus_n,
44
- :public_exponent_e,
45
- :private_exponent_d,
46
- :prime_factor_p,
47
- :prime_factor_q,
48
- :d_p,
49
- :d_q,
50
- :q_inv
51
- )
52
-
53
- def initialize(
54
- modulus_n:,
55
- public_exponent_e:,
56
- private_exponent_d: nil,
57
- prime_factor_p: nil,
58
- prime_factor_q: nil,
59
- d_p: nil,
60
- d_q: nil,
61
- q_inv: nil
62
- )
63
- if !modulus_n
64
- raise ArgumentError, "Required modulus_n is missing"
65
- elsif !public_exponent_e
66
- raise ArgumentError, "Required public_exponent_e is missing"
48
+ attr_reader :n, :e, :d, :p, :q, :dp, :dq, :qinv
49
+
50
+ def initialize(n:, e:, d: nil, p: nil, q: nil, dp: nil, dq: nil, qinv: nil, **keyword_arguments) # rubocop:disable Naming/UncommunicativeMethodParamName
51
+ super(**keyword_arguments)
52
+
53
+ if !n
54
+ raise ArgumentError, "Required public field n is missing"
55
+ elsif !e
56
+ raise ArgumentError, "Required public field e is missing"
67
57
  else
68
- @modulus_n = modulus_n
69
- @public_exponent_e = public_exponent_e
70
- @private_exponent_d = private_exponent_d
71
- @prime_factor_p = prime_factor_p
72
- @prime_factor_q = prime_factor_q
73
- @d_p = d_p
74
- @d_q = d_q
75
- @q_inv = q_inv
58
+ private_fields = { d: d, p: p, q: q, dp: dp, dq: dq, qinv: qinv }
59
+
60
+ if private_fields.values.all?(&:nil?) || private_fields.values.none?(&:nil?)
61
+ @n = n
62
+ @e = e
63
+ @d = d
64
+ @p = p
65
+ @q = q
66
+ @dp = dp
67
+ @dq = dq
68
+ @qinv = qinv
69
+ else
70
+ missing = private_fields.detect { |_k, v| v.nil? }[0]
71
+ raise ArgumentError, "Incomplete private fields, #{missing} is missing"
72
+ end
76
73
  end
77
74
  end
78
75
 
79
- def serialize
80
- CBOR.encode(
76
+ def map
77
+ map = super.merge(
81
78
  Base::LABEL_KTY => KTY_RSA,
82
- LABEL_N => modulus_n,
83
- LABEL_E => public_exponent_e,
84
- LABEL_D => private_exponent_d,
85
- LABEL_P => prime_factor_p,
86
- LABEL_Q => prime_factor_q,
87
- LABEL_D_P => d_p,
88
- LABEL_D_Q => d_q,
89
- LABEL_Q_INV => q_inv
79
+ LABEL_N => n,
80
+ LABEL_E => e,
81
+ LABEL_D => d,
82
+ LABEL_P => p,
83
+ LABEL_Q => q,
84
+ LABEL_DP => dp,
85
+ LABEL_DQ => dq,
86
+ LABEL_QINV => qinv
90
87
  )
88
+
89
+ map.reject { |_k, v| v.nil? }
91
90
  end
92
91
 
93
92
  def to_pkey
94
93
  pkey = OpenSSL::PKey::RSA.new
95
94
 
96
- pkey.set_key(bn(modulus_n), bn(public_exponent_e), bn(private_exponent_d))
97
- pkey.set_factors(bn(prime_factor_p), bn(prime_factor_q))
98
- pkey.set_crt_params(bn(d_p), bn(d_q), bn(q_inv))
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
102
+
103
+ if pkey.respond_to?(:set_factors)
104
+ pkey.set_factors(bn(p), bn(q))
105
+ else
106
+ pkey.p = bn(p)
107
+ pkey.q = bn(q)
108
+ end
109
+
110
+ if pkey.respond_to?(:set_crt_params)
111
+ pkey.set_crt_params(bn(dp), bn(dq), bn(qinv))
112
+ else
113
+ pkey.dmp1 = bn(dp)
114
+ pkey.dmq1 = bn(dq)
115
+ pkey.iqmp = bn(qinv)
116
+ end
99
117
 
100
118
  pkey
101
119
  end
102
120
 
103
- def self.from_map(map)
104
- enforce_type(map, KTY_RSA, "Not an RSA key")
105
-
106
- new(modulus_n: map[LABEL_N], public_exponent_e: map[LABEL_E])
121
+ def self.keyword_arguments_for_initialize(map)
122
+ {
123
+ n: map[LABEL_N],
124
+ e: map[LABEL_E],
125
+ d: map[LABEL_D],
126
+ p: map[LABEL_P],
127
+ q: map[LABEL_Q],
128
+ dp: map[LABEL_DP],
129
+ dq: map[LABEL_DQ],
130
+ qinv: map[LABEL_QINV]
131
+ }
107
132
  end
108
133
 
109
134
  private
@@ -5,23 +5,34 @@ require "cose/key/base"
5
5
  module COSE
6
6
  module Key
7
7
  class Symmetric < Base
8
- K_LABEL = -1
8
+ LABEL_K = -1
9
+
9
10
  KTY_SYMMETRIC = 4
10
11
 
11
- attr_reader :key_value
12
+ attr_reader :k
12
13
 
13
- def initialize(key_value:)
14
- if !key_value
15
- raise ArgumentError, "Required key value is missing"
14
+ def self.enforce_type(map)
15
+ if map[LABEL_KTY] != KTY_SYMMETRIC
16
+ raise "Not a Symmetric key"
16
17
  end
18
+ end
19
+
20
+ def initialize(k:, **keyword_arguments) # rubocop:disable Naming/UncommunicativeMethodParamName
21
+ super(**keyword_arguments)
17
22
 
18
- @key_value = key_value
23
+ if !k
24
+ raise ArgumentError, "Required key value k is missing"
25
+ else
26
+ @k = k
27
+ end
19
28
  end
20
29
 
21
- def self.from_map(map)
22
- enforce_type(map, KTY_SYMMETRIC, "Not a Symmetric key")
30
+ def map
31
+ super.merge(LABEL_KTY => KTY_SYMMETRIC, LABEL_K => k)
32
+ end
23
33
 
24
- new(key_value: map[K_LABEL])
34
+ def self.keyword_arguments_for_initialize(map)
35
+ { k: map[LABEL_K] }
25
36
  end
26
37
  end
27
38
  end
data/lib/cose/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module COSE
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gonzalo Rodriguez
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2019-03-25 00:00:00.000000000 Z
12
+ date: 2019-04-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cbor
@@ -63,16 +63,16 @@ dependencies:
63
63
  name: byebug
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '11.0'
68
+ version: '10.0'
69
69
  type: :development
70
70
  prerelease: false
71
71
  version_requirements: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '11.0'
75
+ version: '10.0'
76
76
  - !ruby/object:Gem::Dependency
77
77
  name: rake
78
78
  requirement: !ruby/object:Gem::Requirement
@@ -138,12 +138,15 @@ files:
138
138
  - cose.gemspec
139
139
  - gemfiles/openssl_2_0.gemfile
140
140
  - gemfiles/openssl_2_1.gemfile
141
+ - gemfiles/openssl_default.gemfile
141
142
  - lib/cose.rb
142
143
  - lib/cose/encrypt.rb
143
144
  - lib/cose/encrypt0.rb
144
145
  - lib/cose/key.rb
145
146
  - lib/cose/key/base.rb
147
+ - lib/cose/key/curve_key.rb
146
148
  - lib/cose/key/ec2.rb
149
+ - lib/cose/key/okp.rb
147
150
  - lib/cose/key/rsa.rb
148
151
  - lib/cose/key/symmetric.rb
149
152
  - lib/cose/mac.rb