putty-key 1.0.1 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -1
  3. data/CHANGES.md +23 -0
  4. data/Gemfile +10 -5
  5. data/LICENSE +1 -1
  6. data/README.md +32 -6
  7. data/Rakefile +24 -0
  8. data/lib/putty/key/argon2_params.rb +101 -0
  9. data/lib/putty/key/error.rb +17 -0
  10. data/lib/putty/key/libargon2.rb +54 -0
  11. data/lib/putty/key/openssl.rb +279 -48
  12. data/lib/putty/key/ppk.rb +482 -104
  13. data/lib/putty/key/util.rb +10 -10
  14. data/lib/putty/key/version.rb +1 -1
  15. data/lib/putty/key.rb +6 -6
  16. data/putty-key.gemspec +11 -2
  17. data/test/argon2_params_test.rb +144 -0
  18. data/test/fixtures/{dss-1024-encrypted.ppk → dss-1024-encrypted-format-2.ppk} +17 -17
  19. data/test/fixtures/dss-1024-encrypted-format-3.ppk +22 -0
  20. data/test/fixtures/{dss-1024.ppk → dss-1024-format-2.ppk} +17 -17
  21. data/test/fixtures/dss-1024-format-3.ppk +17 -0
  22. data/test/fixtures/{ecdsa-sha2-nistp256-encrypted.ppk → ecdsa-sha2-nistp256-encrypted-format-2.ppk} +10 -10
  23. data/test/fixtures/ecdsa-sha2-nistp256-encrypted-format-3.ppk +15 -0
  24. data/test/fixtures/{ecdsa-sha2-nistp256.ppk → ecdsa-sha2-nistp256-format-2.ppk} +10 -10
  25. data/test/fixtures/ecdsa-sha2-nistp256-format-3.ppk +10 -0
  26. data/test/fixtures/{ecdsa-sha2-nistp384-encrypted.ppk → ecdsa-sha2-nistp384-encrypted-format-2.ppk} +11 -11
  27. data/test/fixtures/ecdsa-sha2-nistp384-encrypted-format-3.ppk +16 -0
  28. data/test/fixtures/{ecdsa-sha2-nistp384.ppk → ecdsa-sha2-nistp384-format-2.ppk} +11 -11
  29. data/test/fixtures/ecdsa-sha2-nistp384-format-3.ppk +11 -0
  30. data/test/fixtures/{ecdsa-sha2-nistp521-encrypted.ppk → ecdsa-sha2-nistp521-encrypted-format-2.ppk} +12 -12
  31. data/test/fixtures/ecdsa-sha2-nistp521-encrypted-format-3.ppk +17 -0
  32. data/test/fixtures/{ecdsa-sha2-nistp521.ppk → ecdsa-sha2-nistp521-format-2.ppk} +12 -12
  33. data/test/fixtures/ecdsa-sha2-nistp521-format-3.ppk +12 -0
  34. data/test/fixtures/{rsa-2048-encrypted.ppk → rsa-2048-encrypted-format-2.ppk} +26 -26
  35. data/test/fixtures/rsa-2048-encrypted-format-3.ppk +31 -0
  36. data/test/fixtures/{rsa-2048.ppk → rsa-2048-format-2.ppk} +26 -26
  37. data/test/fixtures/rsa-2048-format-3.ppk +26 -0
  38. data/test/fixtures/test-blank-comment.ppk +11 -11
  39. data/test/fixtures/test-empty-blobs-encrypted.ppk +6 -0
  40. data/test/fixtures/test-empty-blobs.ppk +6 -0
  41. data/test/fixtures/{test-encrypted.ppk → test-encrypted-format-2.ppk} +11 -11
  42. data/test/fixtures/test-encrypted-format-3.ppk +16 -0
  43. data/test/fixtures/test-encrypted-type-d-format-3.ppk +16 -0
  44. data/test/fixtures/test-encrypted-type-i-format-3.ppk +16 -0
  45. data/test/fixtures/{test-unix-line-endings.ppk → test-format-2.ppk} +0 -0
  46. data/test/fixtures/test-format-3.ppk +11 -0
  47. data/test/fixtures/test-invalid-argon2-memory-for-libargon2.ppk +16 -0
  48. data/test/fixtures/test-invalid-argon2-memory-maximum.ppk +16 -0
  49. data/test/fixtures/test-invalid-argon2-memory.ppk +16 -0
  50. data/test/fixtures/test-invalid-argon2-parallelism-maximum.ppk +16 -0
  51. data/test/fixtures/test-invalid-argon2-parallelism.ppk +16 -0
  52. data/test/fixtures/test-invalid-argon2-passes-maximum.ppk +16 -0
  53. data/test/fixtures/test-invalid-argon2-passes.ppk +16 -0
  54. data/test/fixtures/test-invalid-argon2-salt.ppk +16 -0
  55. data/test/fixtures/test-invalid-blob-lines.ppk +11 -11
  56. data/test/fixtures/test-invalid-encryption-type.ppk +11 -11
  57. data/test/fixtures/test-invalid-format-1.ppk +11 -11
  58. data/test/fixtures/{test-invalid-format-3.ppk → test-invalid-format-4.ppk} +11 -11
  59. data/test/fixtures/test-invalid-key-derivation.ppk +16 -0
  60. data/test/fixtures/test-invalid-private-mac.ppk +11 -11
  61. data/test/fixtures/test-legacy-mac-line-endings.ppk +1 -0
  62. data/test/fixtures/test-missing-final-line-ending.ppk +11 -0
  63. data/test/fixtures/test-truncated.ppk +10 -10
  64. data/test/fixtures/{test.ppk → test-windows-line-endings.ppk} +0 -0
  65. data/test/openssl_test.rb +243 -53
  66. data/test/ppk_test.rb +325 -44
  67. data/test/test_helper.rb +10 -3
  68. data.tar.gz.sig +0 -0
  69. metadata +73 -23
  70. metadata.gz.sig +0 -0
@@ -25,10 +25,266 @@ module PuTTY
25
25
 
26
26
  private_constant :SSH_CURVES
27
27
 
28
+ # OpenSSL version helper methods.
29
+ #
30
+ # @private
31
+ module Version
32
+ class << self
33
+ # Determines if the Ruby OpenSSL wrapper is using the OpenSSL library
34
+ # (not LibreSSL and not JRuby) and if the version matches the required
35
+ # version.
36
+ #
37
+ # @param major [Integer] The required major version. `nil` if any
38
+ # version of OpenSSL is sufficient.
39
+ # @param minor [Integer] The required minor version.
40
+ # @param fix [Integer] The required fix version.
41
+ # @param patch [Integer] The required patch version.
42
+ # @return [Boolean] `true` if the requirements are met, otherwise
43
+ # `false`.
44
+ def openssl?(major = nil, minor = 0, fix = 0, patch = 0)
45
+ return false if ::OpenSSL::OPENSSL_VERSION.include?('LibreSSL')
46
+ return false if ::OpenSSL::OPENSSL_VERSION.include?('JRuby')
47
+ return true unless major
48
+ required_version = major * 0x10000000 + minor * 0x100000 + fix * 0x1000 + patch * 0x10
49
+ ::OpenSSL::OPENSSL_VERSION_NUMBER >= required_version
50
+ end
51
+ end
52
+ end
53
+ private_constant :Version
54
+
55
+ # Methods to build OpenSSL private keys from a {PPK}.
56
+ #
57
+ # @private
58
+ module PKeyBuilding
59
+ class << self
60
+ # Creates a new OpenSSL DSA private key for the given DSA {PPK}.
61
+ #
62
+ # @param ppk [PPK] A DSA {PPK}.
63
+ # @return [::OpenSSL::PKey::DSA] The OpenSSL DSA private key.
64
+ def ppk_to_dsa(ppk)
65
+ _, p, q, g, pub_key = Util.ssh_unpack(ppk.public_blob, :string, :mpint, :mpint, :mpint, :mpint)
66
+ priv_key = Util.ssh_unpack(ppk.private_blob, :mpint).first
67
+ dsa_from_params(p, q, g, pub_key, priv_key)
68
+ end
69
+
70
+ # Creates a new OpenSSL RSA private key for the given RSA {PPK}.
71
+ #
72
+ # @param ppk [PPK] An RSA {PPK}.
73
+ # @return [::OpenSSL::PKey::RSA] The OpenSSL RSA private key.
74
+ def ppk_to_rsa(ppk)
75
+ _, e, n = Util.ssh_unpack(ppk.public_blob, :string, :mpint, :mpint)
76
+ d, p, q, iqmp = Util.ssh_unpack(ppk.private_blob, :mpint, :mpint, :mpint, :mpint)
77
+ dmp1 = d % (p - 1)
78
+ dmq1 = d % (q - 1)
79
+ rsa_from_params(e, n, d, p, q, iqmp, dmp1, dmq1)
80
+ end
81
+
82
+ # Creates a new OpenSSL EC private key for the given EC {PPK}.
83
+ #
84
+ # @param ppk [PPK] An EC {PPK}.
85
+ # @param ppk_curve [String] The PPK curve name extracted from the
86
+ # PPK algorithm name.
87
+ # @return [::OpenSSL::PKey::EC] The OpenSSL EC private key.
88
+ def ppk_to_ec(ppk, ppk_curve)
89
+ curve = OPENSSL_CURVES[ppk_curve]
90
+ _, _, pub_key = Util.ssh_unpack(ppk.public_blob, :string, :string, :mpint)
91
+ priv_key = Util.ssh_unpack(ppk.private_blob, :mpint).first
92
+ ec_from_params(curve, pub_key, priv_key)
93
+ end
94
+
95
+ private
96
+
97
+ if Version.openssl?(3)
98
+ # OpenSSL v3 private keys are immutable. The Ruby OpenSSL wrapper
99
+ # doesn't provide a method to construct private keys using the
100
+ # parameters. Build DER (ASN.1) encoded versions of the keys.
101
+ #
102
+ # In theory this should be usable universally. However
103
+ # ::OpenSSL::PKey::EC::Point#to_octet_string is only supported from
104
+ # Ruby >= 2.4 and there are issues with JRuby's OpenSSL library
105
+ # (that doesn't make use of OpenSSL).
106
+
107
+ # :nocov_no_openssl3:
108
+
109
+ # Creates a new OpenSSL DSA private key with the given parameters.
110
+ #
111
+ # @param p [::OpenSSL::BN] The p parameter (prime).
112
+ # @param q [::OpenSSL::BN] The q parameter (prime).
113
+ # @param g [::OpenSSL::BN] The g parameter.
114
+ # @param pub_key [::OpenSSL::BN] The public key.
115
+ # @param priv_key [::OpenSSL::BN] The private key.
116
+ # @return [::OpenSSL::PKey::DSA] The OpenSSL DSA private key.
117
+ def dsa_from_params(p, q, g, pub_key, priv_key)
118
+ # https://www.openssl.org/docs/man3.0/man1/openssl-dsa.html (outform parameter).
119
+ sequence = [
120
+ ::OpenSSL::ASN1::Integer.new(0),
121
+ ::OpenSSL::ASN1::Integer.new(p),
122
+ ::OpenSSL::ASN1::Integer.new(q),
123
+ ::OpenSSL::ASN1::Integer.new(g),
124
+ ::OpenSSL::ASN1::Integer.new(pub_key),
125
+ ::OpenSSL::ASN1::Integer.new(priv_key)
126
+ ]
127
+
128
+ ::OpenSSL::PKey::DSA.new(::OpenSSL::ASN1::Sequence.new(sequence).to_der)
129
+ end
130
+
131
+ # Creates a new OpenSSL RSA private key with the given parameters.
132
+ #
133
+ # @param e [::OpenSSL::BN] The public key exponent.
134
+ # @param n [::OpenSSL::BN] The modulus.
135
+ # @param d [::OpenSSL::BN] The private key exponent.
136
+ # @param p [::OpenSSL::BN] The p prime.
137
+ # @param q [::OpenSSL::BN] The q prime.
138
+ # @param iqmp [::OpenSSL::BN] The inverse of q, mod p.
139
+ # @param dmp1 [::OpenSSL::BN] `d` mod (`p` - 1).
140
+ # @param dmq1 [::OpenSSL::BN] `d` mod (`q` - 1).
141
+ # @return [::OpenSSL::PKey::RSA] The OpenSSL RSA private key.
142
+ def rsa_from_params(e, n, d, p, q, iqmp, dmp1, dmq1)
143
+ # RFC 3447 Appendix A.1.2
144
+ sequence = [
145
+ ::OpenSSL::ASN1::Integer.new(0),
146
+ ::OpenSSL::ASN1::Integer.new(n),
147
+ ::OpenSSL::ASN1::Integer.new(e),
148
+ ::OpenSSL::ASN1::Integer.new(d),
149
+ ::OpenSSL::ASN1::Integer.new(p),
150
+ ::OpenSSL::ASN1::Integer.new(q),
151
+ ::OpenSSL::ASN1::Integer.new(dmp1),
152
+ ::OpenSSL::ASN1::Integer.new(dmq1),
153
+ ::OpenSSL::ASN1::Integer.new(iqmp)
154
+ ]
155
+
156
+ ::OpenSSL::PKey::RSA.new(::OpenSSL::ASN1::Sequence.new(sequence).to_der)
157
+ end
158
+
159
+ # Creates a new OpenSSL EC private key with the given parameters.
160
+ #
161
+ # @param curve [String] The name of the OpenSSL EC curve.
162
+ # @param pub_key [::OpenSSL::BN] The public key.
163
+ # @param priv_key [::OpenSSL::BN] The private key.
164
+ # @return [::OpenSSL::PKey::EC] The OpenSSL EC private key.
165
+ def ec_from_params(curve, pub_key, priv_key)
166
+ group = ::OpenSSL::PKey::EC::Group.new(curve)
167
+ point = ::OpenSSL::PKey::EC::Point.new(group, pub_key)
168
+ point_string = point.to_octet_string(:uncompressed)
169
+
170
+ # RFC 5915 Section 3
171
+ sequence = [
172
+ ::OpenSSL::ASN1::Integer.new(1),
173
+ ::OpenSSL::ASN1::OctetString.new(priv_key.to_s(2)),
174
+ ::OpenSSL::ASN1::ObjectId.new(curve, 0, :EXPLICIT),
175
+ ::OpenSSL::ASN1::BitString.new(point_string, 1, :EXPLICIT)
176
+ ]
177
+
178
+ ::OpenSSL::PKey::EC.new(::OpenSSL::ASN1::Sequence.new(sequence).to_der)
179
+ end
180
+ # :nocov_no_openssl3:
181
+ else
182
+ # :nocov_openssl3:
183
+ if ::OpenSSL::PKey::DSA.new.respond_to?(:set_key)
184
+ # :nocov_no_openssl_pkey_dsa_set_key:
185
+
186
+ # Creates a new OpenSSL DSA private key with the given parameters.
187
+ #
188
+ # @param p [::OpenSSL::BN] The p parameter.
189
+ # @param q [::OpenSSL::BN] The q parameter.
190
+ # @param g [::OpenSSL::BN] The g parameter.
191
+ # @param pub_key [::OpenSSL::BN] The public key.
192
+ # @param priv_key [::OpenSSL::BN] The private key.
193
+ # @return [::OpenSSL::PKey::DSA] The OpenSSL DSA private key.
194
+ def dsa_from_params(p, q, g, pub_key, priv_key)
195
+ ::OpenSSL::PKey::DSA.new.tap do |pkey|
196
+ pkey.set_key(pub_key, priv_key)
197
+ pkey.set_pqg(p, q, g)
198
+ end
199
+ end
200
+ # :nocov_no_openssl_pkey_dsa_set_key:
201
+ else
202
+ # :nocov_openssl_pkey_dsa_set_key:
203
+ # Creates a new OpenSSL DSA private key with the given parameters.
204
+ #
205
+ # @param p [::OpenSSL::BN] The p parameter.
206
+ # @param q [::OpenSSL::BN] The q parameter.
207
+ # @param g [::OpenSSL::BN] The g parameter.
208
+ # @param pub_key [::OpenSSL::BN] The public key.
209
+ # @param priv_key [::OpenSSL::BN] The private key.
210
+ # @return [::OpenSSL::PKey::DSA] The OpenSSL DSA private key.
211
+ def dsa_from_params(p, q, g, pub_key, priv_key)
212
+ ::OpenSSL::PKey::DSA.new.tap do |pkey|
213
+ pkey.p, pkey.q, pkey.g, pkey.pub_key, pkey.priv_key = p, q, g, pub_key, priv_key
214
+ end
215
+ end
216
+ # :nocov_openssl_pkey_dsa_set_key:
217
+ end
218
+
219
+ if ::OpenSSL::PKey::RSA.new.respond_to?(:set_factors)
220
+ # :nocov_no_openssl_pkey_rsa_set_factors:
221
+
222
+ # Creates a new OpenSSL RSA private key with the given parameters.
223
+ #
224
+ # @param e [::OpenSSL::BN] The public key exponent.
225
+ # @param n [::OpenSSL::BN] The modulus.
226
+ # @param d [::OpenSSL::BN] The private key exponent.
227
+ # @param p [::OpenSSL::BN] The p prime.
228
+ # @param q [::OpenSSL::BN] The q prime.
229
+ # @param iqmp [::OpenSSL::BN] The inverse of q, mod p.
230
+ # @param dmp1 [::OpenSSL::BN] `d` mod (`p` - 1).
231
+ # @param dmq1 [::OpenSSL::BN] `d` mod (`q` - 1).
232
+ # @return [::OpenSSL::PKey::RSA] The OpenSSL RSA private key.
233
+ def rsa_from_params(e, n, d, p, q, iqmp, dmp1, dmq1)
234
+ ::OpenSSL::PKey::RSA.new.tap do |pkey|
235
+ pkey.set_factors(p, q)
236
+ pkey.set_key(n, e, d)
237
+ pkey.set_crt_params(dmp1, dmq1, iqmp)
238
+ end
239
+ end
240
+ # :nocov_no_openssl_pkey_rsa_set_factors:
241
+ else
242
+ # :nocov_openssl_pkey_rsa_set_factors:
243
+
244
+ # Creates a new OpenSSL RSA private key with the given parameters.
245
+ #
246
+ # @param e [::OpenSSL::BN] The public key exponent.
247
+ # @param n [::OpenSSL::BN] The modulus.
248
+ # @param d [::OpenSSL::BN] The private key exponent.
249
+ # @param p [::OpenSSL::BN] The p prime.
250
+ # @param q [::OpenSSL::BN] The q prime.
251
+ # @param iqmp [::OpenSSL::BN] The inverse of q, mod p.
252
+ # @param dmp1 [::OpenSSL::BN] `d` mod (`p` - 1).
253
+ # @param dmq1 [::OpenSSL::BN] `d` mod (`q` - 1).
254
+ # @return [::OpenSSL::PKey::RSA] The OpenSSL RSA private key.
255
+ def rsa_from_params(e, n, d, p, q, iqmp, dmp1, dmq1)
256
+ ::OpenSSL::PKey::RSA.new.tap do |pkey|
257
+ pkey.e, pkey.n, pkey.d, pkey.p, pkey.q, pkey.iqmp, pkey.dmp1, pkey.dmq1 = e, n, d, p, q, iqmp, dmp1, dmq1
258
+ end
259
+ end
260
+ # :nocov_openssl_pkey_rsa_set_factors:
261
+ end
262
+
263
+ # Creates a new OpenSSL EC private key with the given parameters.
264
+ #
265
+ # @param curve [String] The name of the OpenSSL EC curve.
266
+ # @param pub_key [::OpenSSL::BN] The public key.
267
+ # @param priv_key [::OpenSSL::BN] The private key.
268
+ # @return [::OpenSSL::PKey::EC] The OpenSSL EC private key.
269
+ def ec_from_params(curve, pub_key, priv_key)
270
+ # Old versions of jruby-openssl don't include an EC class (version 0.9.16).
271
+ ec_class = (::OpenSSL::PKey::EC rescue raise ArgumentError, "Unsupported algorithm: #{ppk.algorithm}")
272
+
273
+ ec_class.new(curve).tap do |pkey|
274
+ group = pkey.group || ::OpenSSL::PKey::EC::Group.new(curve)
275
+ pkey.public_key = ::OpenSSL::PKey::EC::Point.new(group, pub_key)
276
+ pkey.private_key = priv_key
277
+ end
278
+ end
279
+ # :nocov_openssl3:
280
+ end
281
+ end
282
+ end
283
+ private_constant :PKeyBuilding
284
+
28
285
  # The {ClassMethods} module is used to extend `OpenSSL::PKey` when
29
286
  # using the PuTTY::Key refinement or calling {PuTTY::Key.global_install}.
30
287
  # This adds a `from_ppk` class method to `OpenSSL::PKey`.
31
- #
32
288
  module ClassMethods
33
289
  # Creates a new `OpenSSL::PKey` from a PuTTY private key (instance of
34
290
  # {PPK}).
@@ -50,53 +306,11 @@ module PuTTY
50
306
 
51
307
  case ppk.algorithm
52
308
  when 'ssh-dss'
53
- ::OpenSSL::PKey::DSA.new.tap do |pkey|
54
- _, p, q, g, pub_key = Util.ssh_unpack(ppk.public_blob, :string, :mpint, :mpint, :mpint, :mpint)
55
- priv_key = Util.ssh_unpack(ppk.private_blob, :mpint).first
56
-
57
- if pkey.respond_to?(:set_key)
58
- # :nocov_no_openssl_pkey_dsa_set_key:
59
- pkey.set_key(pub_key, priv_key)
60
- pkey.set_pqg(p, q, g)
61
- # :nocov_no_openssl_pkey_dsa_set_key:
62
- else
63
- # :nocov_openssl_pkey_dsa_set_key:
64
- pkey.p, pkey.q, pkey.g, pkey.pub_key, pkey.priv_key = p, q, g, pub_key, priv_key
65
- # :nocov_openssl_pkey_dsa_set_key:
66
- end
67
- end
309
+ PKeyBuilding.ppk_to_dsa(ppk)
68
310
  when 'ssh-rsa'
69
- ::OpenSSL::PKey::RSA.new.tap do |pkey|
70
- _, e, n = Util.ssh_unpack(ppk.public_blob, :string, :mpint, :mpint)
71
- d, p, q, iqmp = Util.ssh_unpack(ppk.private_blob, :mpint, :mpint, :mpint, :mpint)
72
-
73
- dmp1 = d % (p - 1)
74
- dmq1 = d % (q - 1)
75
-
76
- if pkey.respond_to?(:set_factors)
77
- # :nocov_no_openssl_pkey_rsa_set_factors:
78
- pkey.set_factors(p, q)
79
- pkey.set_key(n, e, d)
80
- pkey.set_crt_params(dmp1, dmq1, iqmp)
81
- # :nocov_no_openssl_pkey_rsa_set_factors:
82
- else
83
- # :nocov_openssl_pkey_rsa_set_factors:
84
- pkey.e, pkey.n, pkey.d, pkey.p, pkey.q, pkey.iqmp, pkey.dmp1, pkey.dmq1 = e, n, d, p, q, iqmp, dmp1, dmq1
85
- # :nocov_openssl_pkey_rsa_set_factors:
86
- end
87
- end
311
+ PKeyBuilding.ppk_to_rsa(ppk)
88
312
  when /\Aecdsa-sha2-(nistp(?:256|384|521))\z/
89
- curve = OPENSSL_CURVES[$1]
90
-
91
- # Old versions of jruby-openssl don't include an EC class (version 0.9.16).
92
- ec_class = (::OpenSSL::PKey::EC rescue raise ArgumentError, "Unsupported algorithm: #{ppk.algorithm}")
93
-
94
- ec_class.new(curve).tap do |pkey|
95
- _, _, point = Util.ssh_unpack(ppk.public_blob, :string, :string, :mpint)
96
- group = pkey.group || ::OpenSSL::PKey::EC::Group.new(curve)
97
- pkey.public_key = ::OpenSSL::PKey::EC::Point.new(group, point)
98
- pkey.private_key = Util.ssh_unpack(ppk.private_blob, :mpint).first
99
- end
313
+ PKeyBuilding.ppk_to_ec(ppk, $1)
100
314
  else
101
315
  raise ArgumentError, "Unsupported algorithm: #{ppk.algorithm}"
102
316
  end
@@ -201,13 +415,30 @@ module PuTTY
201
415
  end
202
416
 
203
417
  OpenSSL.const_get(:PKEY_CLASSES).each do |name, openssl_class|
418
+ mod = OpenSSL.const_get(name)
204
419
  refine openssl_class do
205
- include OpenSSL.const_get(name)
420
+ if defined?(::Refinement) && kind_of?(::Refinement)
421
+ # :nocov_no_refinement_class:
422
+ import_methods(mod)
423
+ # :nocov_no_refinement_class:
424
+ else
425
+ # :nocov_refinement_class:
426
+ include mod
427
+ # :nocov_refinement_class:
428
+ end
206
429
  end if respond_to?(:refine, true)
207
430
  end
208
431
 
209
432
  refine ::OpenSSL::PKey.singleton_class do
210
- include OpenSSL::ClassMethods
433
+ if defined?(::Refinement) && kind_of?(::Refinement)
434
+ # :nocov_no_refinement_class:
435
+ import_methods(OpenSSL::ClassMethods)
436
+ # :nocov_no_refinement_class:
437
+ else
438
+ # :nocov_refinement_class:
439
+ include OpenSSL::ClassMethods
440
+ # :nocov_refinement_class:
441
+ end
211
442
  end if respond_to?(:refine, true)
212
443
  end
213
444
  end