summaryrefslogtreecommitdiff
path: root/ext/openssl/lib
diff options
context:
space:
mode:
Diffstat (limited to 'ext/openssl/lib')
-rw-r--r--ext/openssl/lib/openssl.rb16
-rw-r--r--ext/openssl/lib/openssl/bn.rb2
-rw-r--r--ext/openssl/lib/openssl/buffering.rb90
-rw-r--r--ext/openssl/lib/openssl/cipher.rb2
-rw-r--r--ext/openssl/lib/openssl/digest.rb34
-rw-r--r--ext/openssl/lib/openssl/marshal.rb2
-rw-r--r--ext/openssl/lib/openssl/pkey.rb140
-rw-r--r--ext/openssl/lib/openssl/ssl.rb170
-rw-r--r--ext/openssl/lib/openssl/version.rb3
-rw-r--r--ext/openssl/lib/openssl/x509.rb21
10 files changed, 273 insertions, 207 deletions
diff --git a/ext/openssl/lib/openssl.rb b/ext/openssl/lib/openssl.rb
index 8a342f15b6..98fa8d39f2 100644
--- a/ext/openssl/lib/openssl.rb
+++ b/ext/openssl/lib/openssl.rb
@@ -7,28 +7,32 @@
= Licence
This program is licensed under the same licence as Ruby.
- (See the file 'LICENCE'.)
+ (See the file 'COPYING'.)
=end
require 'openssl.so'
require_relative 'openssl/bn'
-require_relative 'openssl/pkey'
require_relative 'openssl/cipher'
require_relative 'openssl/digest'
require_relative 'openssl/hmac'
-require_relative 'openssl/x509'
-require_relative 'openssl/ssl'
require_relative 'openssl/pkcs5'
+require_relative 'openssl/pkey'
+require_relative 'openssl/ssl'
require_relative 'openssl/version'
+require_relative 'openssl/x509'
module OpenSSL
- # call-seq:
- # OpenSSL.secure_compare(string, string) -> boolean
+ # :call-seq:
+ # OpenSSL.secure_compare(string, string) -> true or false
#
# Constant time memory comparison. Inputs are hashed using SHA-256 to mask
# the length of the secret. Returns +true+ if the strings are identical,
# +false+ otherwise.
+ #
+ # This method is expensive due to the SHA-256 hashing. In most cases, where
+ # the input lengths are known to be equal or are not sensitive,
+ # OpenSSL.fixed_length_secure_compare should be used instead.
def self.secure_compare(a, b)
hashed_a = OpenSSL::Digest.digest('SHA256', a)
hashed_b = OpenSSL::Digest.digest('SHA256', b)
diff --git a/ext/openssl/lib/openssl/bn.rb b/ext/openssl/lib/openssl/bn.rb
index 0a5e11b4c2..e4889a140c 100644
--- a/ext/openssl/lib/openssl/bn.rb
+++ b/ext/openssl/lib/openssl/bn.rb
@@ -10,7 +10,7 @@
#
# = Licence
# This program is licensed under the same licence as Ruby.
-# (See the file 'LICENCE'.)
+# (See the file 'COPYING'.)
#++
module OpenSSL
diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb
index d47e1082ef..1464a4292d 100644
--- a/ext/openssl/lib/openssl/buffering.rb
+++ b/ext/openssl/lib/openssl/buffering.rb
@@ -8,7 +8,7 @@
#
#= Licence
# This program is licensed under the same licence as Ruby.
-# (See the file 'LICENCE'.)
+# (See the file 'COPYING'.)
#++
##
@@ -24,25 +24,21 @@ module OpenSSL::Buffering
# A buffer which will retain binary encoding.
class Buffer < String
- BINARY = Encoding::BINARY
-
- def initialize
- super
-
- force_encoding(BINARY)
- end
+ unless String.method_defined?(:append_as_bytes)
+ alias_method :_append, :<<
+ def append_as_bytes(string)
+ if string.encoding == Encoding::BINARY
+ _append(string)
+ else
+ _append(string.b)
+ end
- def << string
- if string.encoding == BINARY
- super(string)
- else
- super(string.b)
+ self
end
-
- return self
end
- alias concat <<
+ undef_method :concat
+ undef_method :<<
end
##
@@ -77,7 +73,7 @@ module OpenSSL::Buffering
def fill_rbuff
begin
- @rbuffer << self.sysread(BLOCK_SIZE)
+ @rbuffer.append_as_bytes(self.sysread(BLOCK_SIZE))
rescue Errno::EAGAIN
retry
rescue EOFError
@@ -93,9 +89,7 @@ module OpenSSL::Buffering
nil
else
size = @rbuffer.size unless size
- ret = @rbuffer[0, size]
- @rbuffer[0, size] = ""
- ret
+ @rbuffer.slice!(0, size)
end
end
@@ -106,8 +100,13 @@ module OpenSSL::Buffering
#
# Get the next 8bit byte from `ssl`. Returns `nil` on EOF
def getbyte
- byte = read(1)
- byte && byte.unpack1("C")
+ read(1)&.ord
+ end
+
+ # Get the next 8bit byte. Raises EOFError on EOF
+ def readbyte
+ raise EOFError if eof?
+ getbyte
end
##
@@ -232,7 +231,7 @@ module OpenSSL::Buffering
#
# Unlike IO#gets the separator must be provided if a limit is provided.
- def gets(eol=$/, limit=nil)
+ def gets(eol=$/, limit=nil, chomp: false)
idx = @rbuffer.index(eol)
until @eof
break if idx
@@ -247,7 +246,11 @@ module OpenSSL::Buffering
if size && limit && limit >= 0
size = [size, limit].min
end
- consume_rbuff(size)
+ line = consume_rbuff(size)
+ if chomp && line
+ line.chomp!(eol)
+ end
+ line
end
##
@@ -345,17 +348,32 @@ module OpenSSL::Buffering
def do_write(s)
@wbuffer = Buffer.new unless defined? @wbuffer
- @wbuffer << s
- @wbuffer.force_encoding(Encoding::BINARY)
+ @wbuffer.append_as_bytes(s)
+
@sync ||= false
- if @sync or @wbuffer.size > BLOCK_SIZE
- until @wbuffer.empty?
- begin
- nwrote = syswrite(@wbuffer)
- rescue Errno::EAGAIN
- retry
+ buffer_size = @wbuffer.bytesize
+ if @sync or buffer_size > BLOCK_SIZE
+ nwrote = 0
+ begin
+ while nwrote < buffer_size do
+ begin
+ chunk = if nwrote > 0
+ @wbuffer.byteslice(nwrote, @wbuffer.bytesize)
+ else
+ @wbuffer
+ end
+
+ nwrote += syswrite(chunk)
+ rescue Errno::EAGAIN
+ retry
+ end
+ end
+ ensure
+ if nwrote < @wbuffer.bytesize
+ @wbuffer[0, nwrote] = ""
+ else
+ @wbuffer.clear
end
- @wbuffer[0, nwrote] = ""
end
end
end
@@ -432,10 +450,10 @@ module OpenSSL::Buffering
def puts(*args)
s = Buffer.new
if args.empty?
- s << "\n"
+ s.append_as_bytes("\n")
end
args.each{|arg|
- s << arg.to_s
+ s.append_as_bytes(arg.to_s)
s.sub!(/(?<!\n)\z/, "\n")
}
do_write(s)
@@ -449,7 +467,7 @@ module OpenSSL::Buffering
def print(*args)
s = Buffer.new
- args.each{ |arg| s << arg.to_s }
+ args.each{ |arg| s.append_as_bytes(arg.to_s) }
do_write(s)
nil
end
diff --git a/ext/openssl/lib/openssl/cipher.rb b/ext/openssl/lib/openssl/cipher.rb
index 8ad8c35dd3..ab75ac8e1a 100644
--- a/ext/openssl/lib/openssl/cipher.rb
+++ b/ext/openssl/lib/openssl/cipher.rb
@@ -9,7 +9,7 @@
#
# = Licence
# This program is licensed under the same licence as Ruby.
-# (See the file 'LICENCE'.)
+# (See the file 'COPYING'.)
#++
module OpenSSL
diff --git a/ext/openssl/lib/openssl/digest.rb b/ext/openssl/lib/openssl/digest.rb
index 2ff8398e44..4e6dea8d03 100644
--- a/ext/openssl/lib/openssl/digest.rb
+++ b/ext/openssl/lib/openssl/digest.rb
@@ -9,7 +9,7 @@
#
# = Licence
# This program is licensed under the same licence as Ruby.
-# (See the file 'LICENCE'.)
+# (See the file 'COPYING'.)
#++
module OpenSSL
@@ -18,30 +18,30 @@ module OpenSSL
# Return the hash value computed with _name_ Digest. _name_ is either the
# long name or short name of a supported digest algorithm.
#
- # === Examples
+ # === Example
#
# OpenSSL::Digest.digest("SHA256", "abc")
- #
- # which is equivalent to:
- #
- # OpenSSL::Digest.digest('SHA256', "abc")
def self.digest(name, data)
super(data, name)
end
%w(MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512).each do |name|
- klass = Class.new(self) {
- define_method(:initialize, ->(data = nil) {super(name, data)})
- }
-
- singleton = (class << klass; self; end)
-
- singleton.class_eval{
- define_method(:digest) {|data| new.digest(data)}
- define_method(:hexdigest) {|data| new.hexdigest(data)}
- }
+ klass = Class.new(self)
+ klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
+ def initialize(data = nil)
+ super("#{name}", data)
+ end
+ RUBY
+ klass.singleton_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
+ def digest(data)
+ new.digest(data)
+ end
+ def hexdigest(data)
+ new.hexdigest(data)
+ end
+ RUBY
const_set(name.tr('-', '_'), klass)
end
@@ -61,7 +61,7 @@ module OpenSSL
# OpenSSL::Digest("MD5")
# # => OpenSSL::Digest::MD5
#
- # Digest("Foo")
+ # OpenSSL::Digest("Foo")
# # => NameError: wrong constant name Foo
def Digest(name)
diff --git a/ext/openssl/lib/openssl/marshal.rb b/ext/openssl/lib/openssl/marshal.rb
index af5647192a..eb8eda4748 100644
--- a/ext/openssl/lib/openssl/marshal.rb
+++ b/ext/openssl/lib/openssl/marshal.rb
@@ -9,7 +9,7 @@
#
# = Licence
# This program is licensed under the same licence as Ruby.
-# (See the file 'LICENCE'.)
+# (See the file 'COPYING'.)
#++
module OpenSSL
module Marshal
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
index c3e0629091..39871e15dd 100644
--- a/ext/openssl/lib/openssl/pkey.rb
+++ b/ext/openssl/lib/openssl/pkey.rb
@@ -7,6 +7,9 @@
require_relative 'marshal'
module OpenSSL::PKey
+ # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError.
+ DHError = PKeyError
+
class DH
include OpenSSL::Marshal
@@ -35,6 +38,18 @@ module OpenSSL::PKey
end
# :call-seq:
+ # dh.params -> hash
+ #
+ # Stores all parameters of key to a Hash.
+ #
+ # The hash has keys 'p', 'q', 'g', 'pub_key', and 'priv_key'.
+ def params
+ %w{p q g pub_key priv_key}.map { |name|
+ [name, send(name)]
+ }.to_h
+ end
+
+ # :call-seq:
# dh.compute_key(pub_bn) -> string
#
# Returns a String containing a shared secret computed from the other
@@ -90,7 +105,7 @@ module OpenSSL::PKey
# puts dh0.pub_key == dh.pub_key #=> false
def generate_key!
if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x30000000
- raise DHError, "OpenSSL::PKey::DH is immutable on OpenSSL 3.0; " \
+ raise PKeyError, "OpenSSL::PKey::DH is immutable on OpenSSL 3.0; " \
"use OpenSSL::PKey.generate_key instead"
end
@@ -135,6 +150,9 @@ module OpenSSL::PKey
end
end
+ # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError.
+ DSAError = PKeyError
+
class DSA
include OpenSSL::Marshal
@@ -154,6 +172,18 @@ module OpenSSL::PKey
OpenSSL::PKey.read(public_to_der)
end
+ # :call-seq:
+ # dsa.params -> hash
+ #
+ # Stores all parameters of key to a Hash.
+ #
+ # The hash has keys 'p', 'q', 'g', 'pub_key', and 'priv_key'.
+ def params
+ %w{p q g pub_key priv_key}.map { |name|
+ [name, send(name)]
+ }.to_h
+ end
+
class << self
# :call-seq:
# DSA.generate(size) -> dsa
@@ -167,8 +197,16 @@ module OpenSSL::PKey
# +size+::
# The desired key size in bits.
def generate(size, &blk)
+ # FIPS 186-4 specifies four (L,N) pairs: (1024,160), (2048,224),
+ # (2048,256), and (3072,256).
+ #
+ # q size is derived here with compatibility with
+ # DSA_generator_parameters_ex() which previous versions of ruby/openssl
+ # used to call.
+ qsize = size >= 2048 ? 256 : 160
dsaparams = OpenSSL::PKey.generate_parameters("DSA", {
"dsa_paramgen_bits" => size,
+ "dsa_paramgen_q_bits" => qsize,
}, &blk)
OpenSSL::PKey.generate_key(dsaparams)
end
@@ -210,13 +248,9 @@ module OpenSSL::PKey
# sig = dsa.sign_raw(nil, digest)
# p dsa.verify_raw(nil, sig, digest) #=> true
def syssign(string)
- q or raise OpenSSL::PKey::DSAError, "incomplete DSA"
- private? or raise OpenSSL::PKey::DSAError, "Private DSA key needed!"
- begin
- sign_raw(nil, string)
- rescue OpenSSL::PKey::PKeyError
- raise OpenSSL::PKey::DSAError, $!.message
- end
+ q or raise PKeyError, "incomplete DSA"
+ private? or raise PKeyError, "Private DSA key needed!"
+ sign_raw(nil, string)
end
# :call-seq:
@@ -234,12 +268,13 @@ module OpenSSL::PKey
# A \DSA signature value.
def sysverify(digest, sig)
verify_raw(nil, sig, digest)
- rescue OpenSSL::PKey::PKeyError
- raise OpenSSL::PKey::DSAError, $!.message
end
end
if defined?(EC)
+ # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError.
+ ECError = PKeyError
+
class EC
include OpenSSL::Marshal
@@ -250,8 +285,6 @@ module OpenSSL::PKey
# Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead.
def dsa_sign_asn1(data)
sign_raw(nil, data)
- rescue OpenSSL::PKey::PKeyError
- raise OpenSSL::PKey::ECError, $!.message
end
# :call-seq:
@@ -261,8 +294,6 @@ module OpenSSL::PKey
# Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead.
def dsa_verify_asn1(data, sig)
verify_raw(nil, sig, data)
- rescue OpenSSL::PKey::PKeyError
- raise OpenSSL::PKey::ECError, $!.message
end
# :call-seq:
@@ -302,6 +333,9 @@ module OpenSSL::PKey
end
end
+ # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError.
+ RSAError = PKeyError
+
class RSA
include OpenSSL::Marshal
@@ -320,6 +354,18 @@ module OpenSSL::PKey
OpenSSL::PKey.read(public_to_der)
end
+ # :call-seq:
+ # rsa.params -> hash
+ #
+ # Stores all parameters of key to a Hash.
+ #
+ # The hash has keys 'n', 'e', 'd', 'p', 'q', 'dmp1', 'dmq1', and 'iqmp'.
+ def params
+ %w{n e d p q dmp1 dmq1 iqmp}.map { |name|
+ [name, send(name)]
+ }.to_h
+ end
+
class << self
# :call-seq:
# RSA.generate(size, exponent = 65537) -> RSA
@@ -355,22 +401,19 @@ module OpenSSL::PKey
# rsa.private_encrypt(string, padding) -> String
#
# Encrypt +string+ with the private key. +padding+ defaults to
- # PKCS1_PADDING. The encrypted string output can be decrypted using
+ # PKCS1_PADDING, which is known to be insecure but is kept for backwards
+ # compatibility. The encrypted string output can be decrypted using
# #public_decrypt.
#
# <b>Deprecated in version 3.0</b>.
# Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw, and
# PKey::PKey#verify_recover instead.
def private_encrypt(string, padding = PKCS1_PADDING)
- n or raise OpenSSL::PKey::RSAError, "incomplete RSA"
- private? or raise OpenSSL::PKey::RSAError, "private key needed."
- begin
- sign_raw(nil, string, {
- "rsa_padding_mode" => translate_padding_mode(padding),
- })
- rescue OpenSSL::PKey::PKeyError
- raise OpenSSL::PKey::RSAError, $!.message
- end
+ n or raise PKeyError, "incomplete RSA"
+ private? or raise PKeyError, "private key needed."
+ sign_raw(nil, string, {
+ "rsa_padding_mode" => translate_padding_mode(padding),
+ })
end
# :call-seq:
@@ -378,20 +421,17 @@ module OpenSSL::PKey
# rsa.public_decrypt(string, padding) -> String
#
# Decrypt +string+, which has been encrypted with the private key, with the
- # public key. +padding+ defaults to PKCS1_PADDING.
+ # public key. +padding+ defaults to PKCS1_PADDING which is known to be
+ # insecure but is kept for backwards compatibility.
#
# <b>Deprecated in version 3.0</b>.
# Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw, and
# PKey::PKey#verify_recover instead.
def public_decrypt(string, padding = PKCS1_PADDING)
- n or raise OpenSSL::PKey::RSAError, "incomplete RSA"
- begin
- verify_recover(nil, string, {
- "rsa_padding_mode" => translate_padding_mode(padding),
- })
- rescue OpenSSL::PKey::PKeyError
- raise OpenSSL::PKey::RSAError, $!.message
- end
+ n or raise PKeyError, "incomplete RSA"
+ verify_recover(nil, string, {
+ "rsa_padding_mode" => translate_padding_mode(padding),
+ })
end
# :call-seq:
@@ -399,20 +439,17 @@ module OpenSSL::PKey
# rsa.public_encrypt(string, padding) -> String
#
# Encrypt +string+ with the public key. +padding+ defaults to
- # PKCS1_PADDING. The encrypted string output can be decrypted using
+ # PKCS1_PADDING, which is known to be insecure but is kept for backwards
+ # compatibility. The encrypted string output can be decrypted using
# #private_decrypt.
#
# <b>Deprecated in version 3.0</b>.
# Consider using PKey::PKey#encrypt and PKey::PKey#decrypt instead.
def public_encrypt(data, padding = PKCS1_PADDING)
- n or raise OpenSSL::PKey::RSAError, "incomplete RSA"
- begin
- encrypt(data, {
- "rsa_padding_mode" => translate_padding_mode(padding),
- })
- rescue OpenSSL::PKey::PKeyError
- raise OpenSSL::PKey::RSAError, $!.message
- end
+ n or raise PKeyError, "incomplete RSA"
+ encrypt(data, {
+ "rsa_padding_mode" => translate_padding_mode(padding),
+ })
end
# :call-seq:
@@ -420,20 +457,17 @@ module OpenSSL::PKey
# rsa.private_decrypt(string, padding) -> String
#
# Decrypt +string+, which has been encrypted with the public key, with the
- # private key. +padding+ defaults to PKCS1_PADDING.
+ # private key. +padding+ defaults to PKCS1_PADDING, which is known to be
+ # insecure but is kept for backwards compatibility.
#
# <b>Deprecated in version 3.0</b>.
# Consider using PKey::PKey#encrypt and PKey::PKey#decrypt instead.
def private_decrypt(data, padding = PKCS1_PADDING)
- n or raise OpenSSL::PKey::RSAError, "incomplete RSA"
- private? or raise OpenSSL::PKey::RSAError, "private key needed."
- begin
- decrypt(data, {
- "rsa_padding_mode" => translate_padding_mode(padding),
- })
- rescue OpenSSL::PKey::PKeyError
- raise OpenSSL::PKey::RSAError, $!.message
- end
+ n or raise PKeyError, "incomplete RSA"
+ private? or raise PKeyError, "private key needed."
+ decrypt(data, {
+ "rsa_padding_mode" => translate_padding_mode(padding),
+ })
end
PKCS1_PADDING = 1
@@ -452,7 +486,7 @@ module OpenSSL::PKey
when PKCS1_OAEP_PADDING
"oaep"
else
- raise OpenSSL::PKey::PKeyError, "unsupported padding mode"
+ raise PKeyError, "unsupported padding mode"
end
end
end
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
index a9103ecd27..3268c126b9 100644
--- a/ext/openssl/lib/openssl/ssl.rb
+++ b/ext/openssl/lib/openssl/ssl.rb
@@ -7,10 +7,13 @@
= Licence
This program is licensed under the same licence as Ruby.
- (See the file 'LICENCE'.)
+ (See the file 'COPYING'.)
=end
require "openssl/buffering"
+
+if defined?(OpenSSL::SSL)
+
require "io/nonblock"
require "ipaddr"
require "socket"
@@ -19,7 +22,6 @@ module OpenSSL
module SSL
class SSLContext
DEFAULT_PARAMS = { # :nodoc:
- :min_version => OpenSSL::SSL::TLS1_VERSION,
:verify_mode => OpenSSL::SSL::VERIFY_PEER,
:verify_hostname => true,
:options => -> {
@@ -30,28 +32,9 @@ module OpenSSL
}.call
}
- if defined?(OpenSSL::PKey::DH)
- DEFAULT_2048 = OpenSSL::PKey::DH.new <<-_end_of_pem_
------BEGIN DH PARAMETERS-----
-MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY
-JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab
-VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6
-YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
-1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD
-7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg==
------END DH PARAMETERS-----
- _end_of_pem_
- private_constant :DEFAULT_2048
-
- DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen| # :nodoc:
- warn "using default DH parameters." if $VERBOSE
- DEFAULT_2048
- }
- end
-
- if !(OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") &&
- OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000)
+ if !OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL")
DEFAULT_PARAMS.merge!(
+ min_version: OpenSSL::SSL::TLS1_VERSION,
ciphers: %w{
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-GCM-SHA256
@@ -83,26 +66,13 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
AES256-SHA256
AES128-SHA
AES256-SHA
- }.join(":"),
+ }.join(":").freeze,
)
end
+ DEFAULT_PARAMS.freeze
DEFAULT_CERT_STORE = OpenSSL::X509::Store.new # :nodoc:
DEFAULT_CERT_STORE.set_default_paths
- DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
-
- # A callback invoked when DH parameters are required for ephemeral DH key
- # exchange.
- #
- # The callback is invoked with the SSLSocket, a
- # flag indicating the use of an export cipher and the keylength
- # required.
- #
- # The callback must return an OpenSSL::PKey::DH instance of the correct
- # key length.
- #
- # <b>Deprecated in version 3.0.</b> Use #tmp_dh= instead.
- attr_accessor :tmp_dh_callback
# A callback invoked at connect time to distinguish between multiple
# server names.
@@ -122,7 +92,6 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
# that this form is deprecated. New applications should use #min_version=
# and #max_version= as necessary.
def initialize(version = nil)
- self.options |= OpenSSL::SSL::OP_ALL
self.ssl_version = version if version
self.verify_mode = OpenSSL::SSL::VERIFY_NONE
self.verify_hostname = false
@@ -142,54 +111,24 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
# used.
def set_params(params={})
params = DEFAULT_PARAMS.merge(params)
- self.options = params.delete(:options) # set before min_version/max_version
+ self.options |= params.delete(:options) # set before min_version/max_version
params.each{|name, value| self.__send__("#{name}=", value) }
if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
unless self.ca_file or self.ca_path or self.cert_store
- self.cert_store = DEFAULT_CERT_STORE
+ if not defined?(Ractor) or Ractor.current == Ractor.main
+ self.cert_store = DEFAULT_CERT_STORE
+ else
+ self.cert_store = Ractor.current[:__openssl_default_store__] ||=
+ OpenSSL::X509::Store.new.tap { |store|
+ store.set_default_paths
+ }
+ end
end
end
return params
end
# call-seq:
- # ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION
- # ctx.min_version = :TLS1_2
- # ctx.min_version = nil
- #
- # Sets the lower bound on the supported SSL/TLS protocol version. The
- # version may be specified by an integer constant named
- # OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version".
- #
- # Be careful that you don't overwrite OpenSSL::SSL::OP_NO_{SSL,TLS}v*
- # options by #options= once you have called #min_version= or
- # #max_version=.
- #
- # === Example
- # ctx = OpenSSL::SSL::SSLContext.new
- # ctx.min_version = OpenSSL::SSL::TLS1_1_VERSION
- # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
- #
- # sock = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx)
- # sock.connect # Initiates a connection using either TLS 1.1 or TLS 1.2
- def min_version=(version)
- set_minmax_proto_version(version, @max_proto_version ||= nil)
- @min_proto_version = version
- end
-
- # call-seq:
- # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
- # ctx.max_version = :TLS1_2
- # ctx.max_version = nil
- #
- # Sets the upper bound of the supported SSL/TLS protocol version. See
- # #min_version= for the possible values.
- def max_version=(version)
- set_minmax_proto_version(@min_proto_version ||= nil, version)
- @max_proto_version = version
- end
-
- # call-seq:
# ctx.ssl_version = :TLSv1
# ctx.ssl_version = "SSLv23"
#
@@ -213,8 +152,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
end
version = METHODS_MAP[meth.intern] or
raise ArgumentError, "unknown SSL method `%s'" % meth
- set_minmax_proto_version(version, version)
- @min_proto_version = @max_proto_version = version
+ self.min_version = self.max_version = version
end
METHODS_MAP = {
@@ -249,6 +187,14 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
to_io.peeraddr
end
+ def local_address
+ to_io.local_address
+ end
+
+ def remote_address
+ to_io.remote_address
+ end
+
def setsockopt(level, optname, optval)
to_io.setsockopt(level, optname, optval)
end
@@ -268,6 +214,36 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
def do_not_reverse_lookup=(flag)
to_io.do_not_reverse_lookup = flag
end
+
+ def close_on_exec=(value)
+ to_io.close_on_exec = value
+ end
+
+ def close_on_exec?
+ to_io.close_on_exec?
+ end
+
+ def wait(*args)
+ to_io.wait(*args)
+ end
+
+ def wait_readable(*args)
+ to_io.wait_readable(*args)
+ end
+
+ def wait_writable(*args)
+ to_io.wait_writable(*args)
+ end
+
+ if IO.method_defined?(:timeout)
+ def timeout
+ to_io.timeout
+ end
+
+ def timeout=(value)
+ to_io.timeout=(value)
+ end
+ end
end
def verify_certificate_identity(cert, hostname)
@@ -418,6 +394,32 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
nil
end
+ # Close the stream for reading.
+ # This method is ignored by OpenSSL as there is no reasonable way to
+ # implement it, but exists for compatibility with IO.
+ def close_read
+ # Unsupported and ignored.
+ # Just don't read any more.
+ end
+
+ # Closes the stream for writing. The behavior of this method depends on
+ # the version of OpenSSL and the TLS protocol in use.
+ #
+ # - Sends a 'close_notify' alert to the peer.
+ # - Does not wait for the peer's 'close_notify' alert in response.
+ #
+ # In TLS 1.2 and earlier:
+ # - On receipt of a 'close_notify' alert, responds with a 'close_notify'
+ # alert of its own and close down the connection immediately,
+ # discarding any pending writes.
+ #
+ # Therefore, on TLS 1.2, this method will cause the connection to be
+ # completely shut down. On TLS 1.3, the connection will remain open for
+ # reading only.
+ def close_write
+ stop
+ end
+
private
def using_anon_cipher?
@@ -430,10 +432,6 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
@context.client_cert_cb
end
- def tmp_dh_callback
- @context.tmp_dh_callback || OpenSSL::SSL::SSLContext::DEFAULT_TMP_DH_CALLBACK
- end
-
def session_new_cb
@context.session_new_cb
end
@@ -491,7 +489,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
unless ctx.session_id_context
# see #6137 - session id may not exceed 32 bytes
prng = ::Random.new($0.hash)
- session_id = prng.bytes(16).unpack('H*')[0]
+ session_id = prng.bytes(16).unpack1('H*')
@ctx.session_id_context = session_id
end
@start_immediately = true
@@ -540,3 +538,5 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
end
end
end
+
+end
diff --git a/ext/openssl/lib/openssl/version.rb b/ext/openssl/lib/openssl/version.rb
index 5e60604353..395a720a31 100644
--- a/ext/openssl/lib/openssl/version.rb
+++ b/ext/openssl/lib/openssl/version.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
module OpenSSL
- VERSION = "3.0.0"
+ # The version string of Ruby/OpenSSL.
+ VERSION = "4.0.2"
end
diff --git a/ext/openssl/lib/openssl/x509.rb b/ext/openssl/lib/openssl/x509.rb
index f973f4f4dc..66765ffeab 100644
--- a/ext/openssl/lib/openssl/x509.rb
+++ b/ext/openssl/lib/openssl/x509.rb
@@ -9,7 +9,7 @@
#
# = Licence
# This program is licensed under the same licence as Ruby.
-# (See the file 'LICENCE'.)
+# (See the file 'COPYING'.)
#++
require_relative 'marshal'
@@ -122,8 +122,8 @@ module OpenSSL
include Helpers
# Get the distributionPoint fullName URI from the certificate's CRL
- # distribution points extension, as described in RFC5280 Section
- # 4.2.1.13
+ # distribution points extension, as described in RFC 5280 Section
+ # 4.2.1.13.
#
# Returns an array of strings or nil or raises ASN1::ASN1Error.
def crl_uris
@@ -135,19 +135,19 @@ module OpenSSL
raise ASN1::ASN1Error, "invalid extension"
end
- crl_uris = cdp_asn1.map do |crl_distribution_point|
+ crl_uris = cdp_asn1.flat_map do |crl_distribution_point|
distribution_point = crl_distribution_point.value.find do |v|
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
end
full_name = distribution_point&.value&.find do |v|
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
end
- full_name&.value&.find do |v|
+ full_name&.value&.select do |v|
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 6 # uniformResourceIdentifier
end
end
- crl_uris&.map(&:value)
+ crl_uris.empty? ? nil : crl_uris.map(&:value)
end
end
@@ -346,6 +346,15 @@ module OpenSSL
include Extension::CRLDistributionPoints
include Extension::AuthorityInfoAccess
+ def inspect
+ "#<#{self.class}: " \
+ "subject=#{subject.inspect}, " \
+ "issuer=#{issuer.inspect}, " \
+ "serial=#{serial.inspect}, " \
+ "not_before=#{not_before.inspect rescue "(error)"}, " \
+ "not_after=#{not_after.inspect rescue "(error)"}>"
+ end
+
def pretty_print(q)
q.object_group(self) {
q.breakable