openssl 2.1.3 → 3.1.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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +302 -1
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +77 -62
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +59 -43
  8. data/ext/openssl/ossl.c +110 -64
  9. data/ext/openssl/ossl.h +33 -10
  10. data/ext/openssl/ossl_asn1.c +51 -13
  11. data/ext/openssl/ossl_bn.c +275 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +39 -31
  14. data/ext/openssl/ossl_config.c +412 -41
  15. data/ext/openssl/ossl_config.h +4 -7
  16. data/ext/openssl/ossl_digest.c +25 -60
  17. data/ext/openssl/ossl_engine.c +18 -27
  18. data/ext/openssl/ossl_hmac.c +60 -145
  19. data/ext/openssl/ossl_kdf.c +14 -22
  20. data/ext/openssl/ossl_ns_spki.c +1 -1
  21. data/ext/openssl/ossl_ocsp.c +11 -64
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +21 -3
  24. data/ext/openssl/ossl_pkcs7.c +45 -78
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1295 -178
  27. data/ext/openssl/ossl_pkey.h +36 -73
  28. data/ext/openssl/ossl_pkey_dh.c +130 -340
  29. data/ext/openssl/ossl_pkey_dsa.c +100 -405
  30. data/ext/openssl/ossl_pkey_ec.c +192 -335
  31. data/ext/openssl/ossl_pkey_rsa.c +110 -489
  32. data/ext/openssl/ossl_rand.c +2 -32
  33. data/ext/openssl/ossl_ssl.c +556 -442
  34. data/ext/openssl/ossl_ssl_session.c +28 -29
  35. data/ext/openssl/ossl_ts.c +1539 -0
  36. data/ext/openssl/ossl_ts.h +16 -0
  37. data/ext/openssl/ossl_x509.c +0 -6
  38. data/ext/openssl/ossl_x509cert.c +169 -13
  39. data/ext/openssl/ossl_x509crl.c +13 -10
  40. data/ext/openssl/ossl_x509ext.c +15 -2
  41. data/ext/openssl/ossl_x509name.c +15 -4
  42. data/ext/openssl/ossl_x509req.c +13 -10
  43. data/ext/openssl/ossl_x509revoked.c +3 -3
  44. data/ext/openssl/ossl_x509store.c +154 -70
  45. data/lib/openssl/bn.rb +1 -1
  46. data/lib/openssl/buffering.rb +37 -5
  47. data/lib/openssl/cipher.rb +1 -1
  48. data/lib/openssl/digest.rb +10 -12
  49. data/lib/openssl/hmac.rb +78 -0
  50. data/lib/openssl/marshal.rb +30 -0
  51. data/lib/openssl/pkcs5.rb +1 -1
  52. data/lib/openssl/pkey.rb +447 -1
  53. data/lib/openssl/ssl.rb +52 -9
  54. data/lib/openssl/version.rb +5 -0
  55. data/lib/openssl/x509.rb +177 -1
  56. data/lib/openssl.rb +24 -9
  57. metadata +10 -79
  58. data/ext/openssl/deprecation.rb +0 -27
  59. data/ext/openssl/ossl_version.h +0 -15
  60. data/ext/openssl/ruby_missing.h +0 -24
  61. data/lib/openssl/config.rb +0 -492
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenSSL
4
+ class HMAC
5
+ # Securely compare with another HMAC instance in constant time.
6
+ def ==(other)
7
+ return false unless HMAC === other
8
+ return false unless self.digest.bytesize == other.digest.bytesize
9
+
10
+ OpenSSL.fixed_length_secure_compare(self.digest, other.digest)
11
+ end
12
+
13
+ # :call-seq:
14
+ # hmac.base64digest -> string
15
+ #
16
+ # Returns the authentication code an a Base64-encoded string.
17
+ def base64digest
18
+ [digest].pack("m0")
19
+ end
20
+
21
+ class << self
22
+ # :call-seq:
23
+ # HMAC.digest(digest, key, data) -> aString
24
+ #
25
+ # Returns the authentication code as a binary string. The _digest_ parameter
26
+ # specifies the digest algorithm to use. This may be a String representing
27
+ # the algorithm name or an instance of OpenSSL::Digest.
28
+ #
29
+ # === Example
30
+ # key = 'key'
31
+ # data = 'The quick brown fox jumps over the lazy dog'
32
+ #
33
+ # hmac = OpenSSL::HMAC.digest('SHA1', key, data)
34
+ # #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9"
35
+ def digest(digest, key, data)
36
+ hmac = new(key, digest)
37
+ hmac << data
38
+ hmac.digest
39
+ end
40
+
41
+ # :call-seq:
42
+ # HMAC.hexdigest(digest, key, data) -> aString
43
+ #
44
+ # Returns the authentication code as a hex-encoded string. The _digest_
45
+ # parameter specifies the digest algorithm to use. This may be a String
46
+ # representing the algorithm name or an instance of OpenSSL::Digest.
47
+ #
48
+ # === Example
49
+ # key = 'key'
50
+ # data = 'The quick brown fox jumps over the lazy dog'
51
+ #
52
+ # hmac = OpenSSL::HMAC.hexdigest('SHA1', key, data)
53
+ # #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
54
+ def hexdigest(digest, key, data)
55
+ hmac = new(key, digest)
56
+ hmac << data
57
+ hmac.hexdigest
58
+ end
59
+
60
+ # :call-seq:
61
+ # HMAC.base64digest(digest, key, data) -> aString
62
+ #
63
+ # Returns the authentication code as a Base64-encoded string. The _digest_
64
+ # parameter specifies the digest algorithm to use. This may be a String
65
+ # representing the algorithm name or an instance of OpenSSL::Digest.
66
+ #
67
+ # === Example
68
+ # key = 'key'
69
+ # data = 'The quick brown fox jumps over the lazy dog'
70
+ #
71
+ # hmac = OpenSSL::HMAC.base64digest('SHA1', key, data)
72
+ # #=> "3nybhbi3iqa8ino29wqQcBydtNk="
73
+ def base64digest(digest, key, data)
74
+ [digest(digest, key, data)].pack("m0")
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ #--
3
+ # = Ruby-space definitions to add DER (de)serialization to classes
4
+ #
5
+ # = Info
6
+ # 'OpenSSL for Ruby 2' project
7
+ # Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz>
8
+ # All rights reserved.
9
+ #
10
+ # = Licence
11
+ # This program is licensed under the same licence as Ruby.
12
+ # (See the file 'LICENCE'.)
13
+ #++
14
+ module OpenSSL
15
+ module Marshal
16
+ def self.included(base)
17
+ base.extend(ClassMethods)
18
+ end
19
+
20
+ module ClassMethods
21
+ def _load(string)
22
+ new(string)
23
+ end
24
+ end
25
+
26
+ def _dump(_level)
27
+ to_der
28
+ end
29
+ end
30
+ end
data/lib/openssl/pkcs5.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #--
3
3
  # Ruby/OpenSSL Project
4
4
  # Copyright (C) 2017 Ruby/OpenSSL Project Authors
data/lib/openssl/pkey.rb CHANGED
@@ -1,11 +1,298 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #--
3
3
  # Ruby/OpenSSL Project
4
4
  # Copyright (C) 2017 Ruby/OpenSSL Project Authors
5
5
  #++
6
6
 
7
+ require_relative 'marshal'
8
+
7
9
  module OpenSSL::PKey
10
+ class DH
11
+ include OpenSSL::Marshal
12
+
13
+ # :call-seq:
14
+ # dh.public_key -> dhnew
15
+ #
16
+ # Returns a new DH instance that carries just the \DH parameters.
17
+ #
18
+ # Contrary to the method name, the returned DH object contains only
19
+ # parameters and not the public key.
20
+ #
21
+ # This method is provided for backwards compatibility. In most cases, there
22
+ # is no need to call this method.
23
+ #
24
+ # For the purpose of re-generating the key pair while keeping the
25
+ # parameters, check OpenSSL::PKey.generate_key.
26
+ #
27
+ # Example:
28
+ # # OpenSSL::PKey::DH.generate by default generates a random key pair
29
+ # dh1 = OpenSSL::PKey::DH.generate(2048)
30
+ # p dh1.priv_key #=> #<OpenSSL::BN 1288347...>
31
+ # dhcopy = dh1.public_key
32
+ # p dhcopy.priv_key #=> nil
33
+ def public_key
34
+ DH.new(to_der)
35
+ end
36
+
37
+ # :call-seq:
38
+ # dh.compute_key(pub_bn) -> string
39
+ #
40
+ # Returns a String containing a shared secret computed from the other
41
+ # party's public value.
42
+ #
43
+ # This method is provided for backwards compatibility, and calls #derive
44
+ # internally.
45
+ #
46
+ # === Parameters
47
+ # * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by
48
+ # DH#public_key as that contains the DH parameters only.
49
+ def compute_key(pub_bn)
50
+ # FIXME: This is constructing an X.509 SubjectPublicKeyInfo and is very
51
+ # inefficient
52
+ obj = OpenSSL::ASN1.Sequence([
53
+ OpenSSL::ASN1.Sequence([
54
+ OpenSSL::ASN1.ObjectId("dhKeyAgreement"),
55
+ OpenSSL::ASN1.Sequence([
56
+ OpenSSL::ASN1.Integer(p),
57
+ OpenSSL::ASN1.Integer(g),
58
+ ]),
59
+ ]),
60
+ OpenSSL::ASN1.BitString(OpenSSL::ASN1.Integer(pub_bn).to_der),
61
+ ])
62
+ derive(OpenSSL::PKey.read(obj.to_der))
63
+ end
64
+
65
+ # :call-seq:
66
+ # dh.generate_key! -> self
67
+ #
68
+ # Generates a private and public key unless a private key already exists.
69
+ # If this DH instance was generated from public \DH parameters (e.g. by
70
+ # encoding the result of DH#public_key), then this method needs to be
71
+ # called first in order to generate the per-session keys before performing
72
+ # the actual key exchange.
73
+ #
74
+ # <b>Deprecated in version 3.0</b>. This method is incompatible with
75
+ # OpenSSL 3.0.0 or later.
76
+ #
77
+ # See also OpenSSL::PKey.generate_key.
78
+ #
79
+ # Example:
80
+ # # DEPRECATED USAGE: This will not work on OpenSSL 3.0 or later
81
+ # dh0 = OpenSSL::PKey::DH.new(2048)
82
+ # dh = dh0.public_key # #public_key only copies the DH parameters (contrary to the name)
83
+ # dh.generate_key!
84
+ # puts dh.private? # => true
85
+ # puts dh0.pub_key == dh.pub_key #=> false
86
+ #
87
+ # # With OpenSSL::PKey.generate_key
88
+ # dh0 = OpenSSL::PKey::DH.new(2048)
89
+ # dh = OpenSSL::PKey.generate_key(dh0)
90
+ # puts dh0.pub_key == dh.pub_key #=> false
91
+ def generate_key!
92
+ if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x30000000
93
+ raise DHError, "OpenSSL::PKey::DH is immutable on OpenSSL 3.0; " \
94
+ "use OpenSSL::PKey.generate_key instead"
95
+ end
96
+
97
+ unless priv_key
98
+ tmp = OpenSSL::PKey.generate_key(self)
99
+ set_key(tmp.pub_key, tmp.priv_key)
100
+ end
101
+ self
102
+ end
103
+
104
+ class << self
105
+ # :call-seq:
106
+ # DH.generate(size, generator = 2) -> dh
107
+ #
108
+ # Creates a new DH instance from scratch by generating random parameters
109
+ # and a key pair.
110
+ #
111
+ # See also OpenSSL::PKey.generate_parameters and
112
+ # OpenSSL::PKey.generate_key.
113
+ #
114
+ # +size+::
115
+ # The desired key size in bits.
116
+ # +generator+::
117
+ # The generator.
118
+ def generate(size, generator = 2, &blk)
119
+ dhparams = OpenSSL::PKey.generate_parameters("DH", {
120
+ "dh_paramgen_prime_len" => size,
121
+ "dh_paramgen_generator" => generator,
122
+ }, &blk)
123
+ OpenSSL::PKey.generate_key(dhparams)
124
+ end
125
+
126
+ # Handle DH.new(size, generator) form here; new(str) and new() forms
127
+ # are handled by #initialize
128
+ def new(*args, &blk) # :nodoc:
129
+ if args[0].is_a?(Integer)
130
+ generate(*args, &blk)
131
+ else
132
+ super
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ class DSA
139
+ include OpenSSL::Marshal
140
+
141
+ # :call-seq:
142
+ # dsa.public_key -> dsanew
143
+ #
144
+ # Returns a new DSA instance that carries just the \DSA parameters and the
145
+ # public key.
146
+ #
147
+ # This method is provided for backwards compatibility. In most cases, there
148
+ # is no need to call this method.
149
+ #
150
+ # For the purpose of serializing the public key, to PEM or DER encoding of
151
+ # X.509 SubjectPublicKeyInfo format, check PKey#public_to_pem and
152
+ # PKey#public_to_der.
153
+ def public_key
154
+ OpenSSL::PKey.read(public_to_der)
155
+ end
156
+
157
+ class << self
158
+ # :call-seq:
159
+ # DSA.generate(size) -> dsa
160
+ #
161
+ # Creates a new DSA instance by generating a private/public key pair
162
+ # from scratch.
163
+ #
164
+ # See also OpenSSL::PKey.generate_parameters and
165
+ # OpenSSL::PKey.generate_key.
166
+ #
167
+ # +size+::
168
+ # The desired key size in bits.
169
+ def generate(size, &blk)
170
+ # FIPS 186-4 specifies four (L,N) pairs: (1024,160), (2048,224),
171
+ # (2048,256), and (3072,256).
172
+ #
173
+ # q size is derived here with compatibility with
174
+ # DSA_generator_parameters_ex() which previous versions of ruby/openssl
175
+ # used to call.
176
+ qsize = size >= 2048 ? 256 : 160
177
+ dsaparams = OpenSSL::PKey.generate_parameters("DSA", {
178
+ "dsa_paramgen_bits" => size,
179
+ "dsa_paramgen_q_bits" => qsize,
180
+ }, &blk)
181
+ OpenSSL::PKey.generate_key(dsaparams)
182
+ end
183
+
184
+ # Handle DSA.new(size) form here; new(str) and new() forms
185
+ # are handled by #initialize
186
+ def new(*args, &blk) # :nodoc:
187
+ if args[0].is_a?(Integer)
188
+ generate(*args, &blk)
189
+ else
190
+ super
191
+ end
192
+ end
193
+ end
194
+
195
+ # :call-seq:
196
+ # dsa.syssign(string) -> string
197
+ #
198
+ # Computes and returns the \DSA signature of +string+, where +string+ is
199
+ # expected to be an already-computed message digest of the original input
200
+ # data. The signature is issued using the private key of this DSA instance.
201
+ #
202
+ # <b>Deprecated in version 3.0</b>.
203
+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead.
204
+ #
205
+ # +string+::
206
+ # A message digest of the original input data to be signed.
207
+ #
208
+ # Example:
209
+ # dsa = OpenSSL::PKey::DSA.new(2048)
210
+ # doc = "Sign me"
211
+ # digest = OpenSSL::Digest.digest('SHA1', doc)
212
+ #
213
+ # # With legacy #syssign and #sysverify:
214
+ # sig = dsa.syssign(digest)
215
+ # p dsa.sysverify(digest, sig) #=> true
216
+ #
217
+ # # With #sign_raw and #verify_raw:
218
+ # sig = dsa.sign_raw(nil, digest)
219
+ # p dsa.verify_raw(nil, sig, digest) #=> true
220
+ def syssign(string)
221
+ q or raise OpenSSL::PKey::DSAError, "incomplete DSA"
222
+ private? or raise OpenSSL::PKey::DSAError, "Private DSA key needed!"
223
+ begin
224
+ sign_raw(nil, string)
225
+ rescue OpenSSL::PKey::PKeyError
226
+ raise OpenSSL::PKey::DSAError, $!.message
227
+ end
228
+ end
229
+
230
+ # :call-seq:
231
+ # dsa.sysverify(digest, sig) -> true | false
232
+ #
233
+ # Verifies whether the signature is valid given the message digest input.
234
+ # It does so by validating +sig+ using the public key of this DSA instance.
235
+ #
236
+ # <b>Deprecated in version 3.0</b>.
237
+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead.
238
+ #
239
+ # +digest+::
240
+ # A message digest of the original input data to be signed.
241
+ # +sig+::
242
+ # A \DSA signature value.
243
+ def sysverify(digest, sig)
244
+ verify_raw(nil, sig, digest)
245
+ rescue OpenSSL::PKey::PKeyError
246
+ raise OpenSSL::PKey::DSAError, $!.message
247
+ end
248
+ end
249
+
8
250
  if defined?(EC)
251
+ class EC
252
+ include OpenSSL::Marshal
253
+
254
+ # :call-seq:
255
+ # key.dsa_sign_asn1(data) -> String
256
+ #
257
+ # <b>Deprecated in version 3.0</b>.
258
+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead.
259
+ def dsa_sign_asn1(data)
260
+ sign_raw(nil, data)
261
+ rescue OpenSSL::PKey::PKeyError
262
+ raise OpenSSL::PKey::ECError, $!.message
263
+ end
264
+
265
+ # :call-seq:
266
+ # key.dsa_verify_asn1(data, sig) -> true | false
267
+ #
268
+ # <b>Deprecated in version 3.0</b>.
269
+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead.
270
+ def dsa_verify_asn1(data, sig)
271
+ verify_raw(nil, sig, data)
272
+ rescue OpenSSL::PKey::PKeyError
273
+ raise OpenSSL::PKey::ECError, $!.message
274
+ end
275
+
276
+ # :call-seq:
277
+ # ec.dh_compute_key(pubkey) -> string
278
+ #
279
+ # Derives a shared secret by ECDH. _pubkey_ must be an instance of
280
+ # OpenSSL::PKey::EC::Point and must belong to the same group.
281
+ #
282
+ # This method is provided for backwards compatibility, and calls #derive
283
+ # internally.
284
+ def dh_compute_key(pubkey)
285
+ obj = OpenSSL::ASN1.Sequence([
286
+ OpenSSL::ASN1.Sequence([
287
+ OpenSSL::ASN1.ObjectId("id-ecPublicKey"),
288
+ group.to_der,
289
+ ]),
290
+ OpenSSL::ASN1.BitString(pubkey.to_octet_string(:uncompressed)),
291
+ ])
292
+ derive(OpenSSL::PKey.read(obj.to_der))
293
+ end
294
+ end
295
+
9
296
  class EC::Point
10
297
  # :call-seq:
11
298
  # point.to_bn([conversion_form]) -> OpenSSL::BN
@@ -22,4 +309,163 @@ module OpenSSL::PKey
22
309
  end
23
310
  end
24
311
  end
312
+
313
+ class RSA
314
+ include OpenSSL::Marshal
315
+
316
+ # :call-seq:
317
+ # rsa.public_key -> rsanew
318
+ #
319
+ # Returns a new RSA instance that carries just the public key components.
320
+ #
321
+ # This method is provided for backwards compatibility. In most cases, there
322
+ # is no need to call this method.
323
+ #
324
+ # For the purpose of serializing the public key, to PEM or DER encoding of
325
+ # X.509 SubjectPublicKeyInfo format, check PKey#public_to_pem and
326
+ # PKey#public_to_der.
327
+ def public_key
328
+ OpenSSL::PKey.read(public_to_der)
329
+ end
330
+
331
+ class << self
332
+ # :call-seq:
333
+ # RSA.generate(size, exponent = 65537) -> RSA
334
+ #
335
+ # Generates an \RSA keypair.
336
+ #
337
+ # See also OpenSSL::PKey.generate_key.
338
+ #
339
+ # +size+::
340
+ # The desired key size in bits.
341
+ # +exponent+::
342
+ # An odd Integer, normally 3, 17, or 65537.
343
+ def generate(size, exp = 0x10001, &blk)
344
+ OpenSSL::PKey.generate_key("RSA", {
345
+ "rsa_keygen_bits" => size,
346
+ "rsa_keygen_pubexp" => exp,
347
+ }, &blk)
348
+ end
349
+
350
+ # Handle RSA.new(size, exponent) form here; new(str) and new() forms
351
+ # are handled by #initialize
352
+ def new(*args, &blk) # :nodoc:
353
+ if args[0].is_a?(Integer)
354
+ generate(*args, &blk)
355
+ else
356
+ super
357
+ end
358
+ end
359
+ end
360
+
361
+ # :call-seq:
362
+ # rsa.private_encrypt(string) -> String
363
+ # rsa.private_encrypt(string, padding) -> String
364
+ #
365
+ # Encrypt +string+ with the private key. +padding+ defaults to
366
+ # PKCS1_PADDING, which is known to be insecure but is kept for backwards
367
+ # compatibility. The encrypted string output can be decrypted using
368
+ # #public_decrypt.
369
+ #
370
+ # <b>Deprecated in version 3.0</b>.
371
+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw, and
372
+ # PKey::PKey#verify_recover instead.
373
+ def private_encrypt(string, padding = PKCS1_PADDING)
374
+ n or raise OpenSSL::PKey::RSAError, "incomplete RSA"
375
+ private? or raise OpenSSL::PKey::RSAError, "private key needed."
376
+ begin
377
+ sign_raw(nil, string, {
378
+ "rsa_padding_mode" => translate_padding_mode(padding),
379
+ })
380
+ rescue OpenSSL::PKey::PKeyError
381
+ raise OpenSSL::PKey::RSAError, $!.message
382
+ end
383
+ end
384
+
385
+ # :call-seq:
386
+ # rsa.public_decrypt(string) -> String
387
+ # rsa.public_decrypt(string, padding) -> String
388
+ #
389
+ # Decrypt +string+, which has been encrypted with the private key, with the
390
+ # public key. +padding+ defaults to PKCS1_PADDING which is known to be
391
+ # insecure but is kept for backwards compatibility.
392
+ #
393
+ # <b>Deprecated in version 3.0</b>.
394
+ # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw, and
395
+ # PKey::PKey#verify_recover instead.
396
+ def public_decrypt(string, padding = PKCS1_PADDING)
397
+ n or raise OpenSSL::PKey::RSAError, "incomplete RSA"
398
+ begin
399
+ verify_recover(nil, string, {
400
+ "rsa_padding_mode" => translate_padding_mode(padding),
401
+ })
402
+ rescue OpenSSL::PKey::PKeyError
403
+ raise OpenSSL::PKey::RSAError, $!.message
404
+ end
405
+ end
406
+
407
+ # :call-seq:
408
+ # rsa.public_encrypt(string) -> String
409
+ # rsa.public_encrypt(string, padding) -> String
410
+ #
411
+ # Encrypt +string+ with the public key. +padding+ defaults to
412
+ # PKCS1_PADDING, which is known to be insecure but is kept for backwards
413
+ # compatibility. The encrypted string output can be decrypted using
414
+ # #private_decrypt.
415
+ #
416
+ # <b>Deprecated in version 3.0</b>.
417
+ # Consider using PKey::PKey#encrypt and PKey::PKey#decrypt instead.
418
+ def public_encrypt(data, padding = PKCS1_PADDING)
419
+ n or raise OpenSSL::PKey::RSAError, "incomplete RSA"
420
+ begin
421
+ encrypt(data, {
422
+ "rsa_padding_mode" => translate_padding_mode(padding),
423
+ })
424
+ rescue OpenSSL::PKey::PKeyError
425
+ raise OpenSSL::PKey::RSAError, $!.message
426
+ end
427
+ end
428
+
429
+ # :call-seq:
430
+ # rsa.private_decrypt(string) -> String
431
+ # rsa.private_decrypt(string, padding) -> String
432
+ #
433
+ # Decrypt +string+, which has been encrypted with the public key, with the
434
+ # private key. +padding+ defaults to PKCS1_PADDING, which is known to be
435
+ # insecure but is kept for backwards compatibility.
436
+ #
437
+ # <b>Deprecated in version 3.0</b>.
438
+ # Consider using PKey::PKey#encrypt and PKey::PKey#decrypt instead.
439
+ def private_decrypt(data, padding = PKCS1_PADDING)
440
+ n or raise OpenSSL::PKey::RSAError, "incomplete RSA"
441
+ private? or raise OpenSSL::PKey::RSAError, "private key needed."
442
+ begin
443
+ decrypt(data, {
444
+ "rsa_padding_mode" => translate_padding_mode(padding),
445
+ })
446
+ rescue OpenSSL::PKey::PKeyError
447
+ raise OpenSSL::PKey::RSAError, $!.message
448
+ end
449
+ end
450
+
451
+ PKCS1_PADDING = 1
452
+ SSLV23_PADDING = 2
453
+ NO_PADDING = 3
454
+ PKCS1_OAEP_PADDING = 4
455
+
456
+ private def translate_padding_mode(num)
457
+ case num
458
+ when PKCS1_PADDING
459
+ "pkcs1"
460
+ when SSLV23_PADDING
461
+ "sslv23"
462
+ when NO_PADDING
463
+ "none"
464
+ when PKCS1_OAEP_PADDING
465
+ "oaep"
466
+ else
467
+ raise OpenSSL::PKey::PKeyError, "unsupported padding mode"
468
+ end
469
+ end
470
+ end
25
471
  end
data/lib/openssl/ssl.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  =begin
3
3
  = Info
4
4
  'OpenSSL for Ruby 2' project
@@ -11,8 +11,12 @@
11
11
  =end
12
12
 
13
13
  require "openssl/buffering"
14
+
15
+ if defined?(OpenSSL::SSL)
16
+
14
17
  require "io/nonblock"
15
18
  require "ipaddr"
19
+ require "socket"
16
20
 
17
21
  module OpenSSL
18
22
  module SSL
@@ -90,15 +94,17 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
90
94
  DEFAULT_CERT_STORE.set_default_paths
91
95
  DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
92
96
 
93
- # A callback invoked when DH parameters are required.
97
+ # A callback invoked when DH parameters are required for ephemeral DH key
98
+ # exchange.
94
99
  #
95
- # The callback is invoked with the Session for the key exchange, an
100
+ # The callback is invoked with the SSLSocket, a
96
101
  # flag indicating the use of an export cipher and the keylength
97
102
  # required.
98
103
  #
99
104
  # The callback must return an OpenSSL::PKey::DH instance of the correct
100
105
  # key length.
101
-
106
+ #
107
+ # <b>Deprecated in version 3.0.</b> Use #tmp_dh= instead.
102
108
  attr_accessor :tmp_dh_callback
103
109
 
104
110
  # A callback invoked at connect time to distinguish between multiple
@@ -121,6 +127,8 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
121
127
  def initialize(version = nil)
122
128
  self.options |= OpenSSL::SSL::OP_ALL
123
129
  self.ssl_version = version if version
130
+ self.verify_mode = OpenSSL::SSL::VERIFY_NONE
131
+ self.verify_hostname = false
124
132
  end
125
133
 
126
134
  ##
@@ -231,6 +239,11 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
231
239
  end
232
240
 
233
241
  module SocketForwarder
242
+ # The file descriptor for the socket.
243
+ def fileno
244
+ to_io.fileno
245
+ end
246
+
234
247
  def addr
235
248
  to_io.addr
236
249
  end
@@ -424,10 +437,6 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
424
437
  @context.tmp_dh_callback || OpenSSL::SSL::SSLContext::DEFAULT_TMP_DH_CALLBACK
425
438
  end
426
439
 
427
- def tmp_ecdh_callback
428
- @context.tmp_ecdh_callback
429
- end
430
-
431
440
  def session_new_cb
432
441
  @context.session_new_cb
433
442
  end
@@ -435,6 +444,38 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
435
444
  def session_get_cb
436
445
  @context.session_get_cb
437
446
  end
447
+
448
+ class << self
449
+
450
+ # call-seq:
451
+ # open(remote_host, remote_port, local_host=nil, local_port=nil, context: nil)
452
+ #
453
+ # Creates a new instance of SSLSocket.
454
+ # _remote\_host_ and _remote\_port_ are used to open TCPSocket.
455
+ # If _local\_host_ and _local\_port_ are specified,
456
+ # then those parameters are used on the local end to establish the connection.
457
+ # If _context_ is provided,
458
+ # the SSL Sockets initial params will be taken from the context.
459
+ #
460
+ # === Examples
461
+ #
462
+ # sock = OpenSSL::SSL::SSLSocket.open('localhost', 443)
463
+ # sock.connect # Initiates a connection to localhost:443
464
+ #
465
+ # with SSLContext:
466
+ #
467
+ # ctx = OpenSSL::SSL::SSLContext.new
468
+ # sock = OpenSSL::SSL::SSLSocket.open('localhost', 443, context: ctx)
469
+ # sock.connect # Initiates a connection to localhost:443 with SSLContext
470
+ def open(remote_host, remote_port, local_host=nil, local_port=nil, context: nil)
471
+ sock = ::TCPSocket.open(remote_host, remote_port, local_host, local_port)
472
+ if context.nil?
473
+ return OpenSSL::SSL::SSLSocket.new(sock)
474
+ else
475
+ return OpenSSL::SSL::SSLSocket.new(sock, context)
476
+ end
477
+ end
478
+ end
438
479
  end
439
480
 
440
481
  ##
@@ -465,7 +506,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
465
506
  end
466
507
 
467
508
  # See TCPServer#listen for details.
468
- def listen(backlog=5)
509
+ def listen(backlog=Socket::SOMAXCONN)
469
510
  @svr.listen(backlog)
470
511
  end
471
512
 
@@ -502,3 +543,5 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
502
543
  end
503
544
  end
504
545
  end
546
+
547
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenSSL
4
+ VERSION = "3.1.0"
5
+ end