summaryrefslogtreecommitdiff
path: root/ext/openssl/lib/openssl
diff options
context:
space:
mode:
Diffstat (limited to 'ext/openssl/lib/openssl')
-rw-r--r--ext/openssl/lib/openssl/buffering.rb25
-rw-r--r--ext/openssl/lib/openssl/digest.rb6
-rw-r--r--ext/openssl/lib/openssl/pkey.rb70
-rw-r--r--ext/openssl/lib/openssl/ssl.rb103
-rw-r--r--ext/openssl/lib/openssl/version.rb2
-rw-r--r--ext/openssl/lib/openssl/x509.rb18
6 files changed, 169 insertions, 55 deletions
diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb
index 116179d21f..68aa7bc970 100644
--- a/ext/openssl/lib/openssl/buffering.rb
+++ b/ext/openssl/lib/openssl/buffering.rb
@@ -93,19 +93,7 @@ module OpenSSL::Buffering
nil
else
size = @rbuffer.size unless size
- ret = @rbuffer[0, size]
- @rbuffer[0, size] = ""
- ret
- end
- end
-
- if "".respond_to?(:unpack1)
- def unpack_byte(str)
- str.unpack1("C")
- end
- else
- def unpack_byte(str)
- str.unpack("C").first
+ @rbuffer.slice!(0, size)
end
end
@@ -116,8 +104,7 @@ module OpenSSL::Buffering
#
# Get the next 8bit byte from `ssl`. Returns `nil` on EOF
def getbyte
- byte = read(1)
- byte && unpack_byte(byte)
+ read(1)&.ord
end
##
@@ -242,7 +229,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
@@ -257,7 +244,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
##
diff --git a/ext/openssl/lib/openssl/digest.rb b/ext/openssl/lib/openssl/digest.rb
index 2ff8398e44..0f35ddadd3 100644
--- a/ext/openssl/lib/openssl/digest.rb
+++ b/ext/openssl/lib/openssl/digest.rb
@@ -18,13 +18,9 @@ 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)
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
index f6bf5892b0..0414658a10 100644
--- a/ext/openssl/lib/openssl/pkey.rb
+++ b/ext/openssl/lib/openssl/pkey.rb
@@ -47,9 +47,19 @@ module OpenSSL::PKey
# * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by
# DH#public_key as that contains the DH parameters only.
def compute_key(pub_bn)
- peer = dup
- peer.set_key(pub_bn, nil)
- derive(peer)
+ # FIXME: This is constructing an X.509 SubjectPublicKeyInfo and is very
+ # inefficient
+ obj = OpenSSL::ASN1.Sequence([
+ OpenSSL::ASN1.Sequence([
+ OpenSSL::ASN1.ObjectId("dhKeyAgreement"),
+ OpenSSL::ASN1.Sequence([
+ OpenSSL::ASN1.Integer(p),
+ OpenSSL::ASN1.Integer(g),
+ ]),
+ ]),
+ OpenSSL::ASN1.BitString(OpenSSL::ASN1.Integer(pub_bn).to_der),
+ ])
+ derive(OpenSSL::PKey.read(obj.to_der))
end
# :call-seq:
@@ -61,14 +71,29 @@ module OpenSSL::PKey
# called first in order to generate the per-session keys before performing
# the actual key exchange.
#
+ # <b>Deprecated in version 3.0</b>. This method is incompatible with
+ # OpenSSL 3.0.0 or later.
+ #
# See also OpenSSL::PKey.generate_key.
#
# Example:
- # dh = OpenSSL::PKey::DH.new(2048)
- # public_key = dh.public_key #contains no private/public key yet
- # public_key.generate_key!
- # puts public_key.private? # => true
+ # # DEPRECATED USAGE: This will not work on OpenSSL 3.0 or later
+ # dh0 = OpenSSL::PKey::DH.new(2048)
+ # dh = dh0.public_key # #public_key only copies the DH parameters (contrary to the name)
+ # dh.generate_key!
+ # puts dh.private? # => true
+ # puts dh0.pub_key == dh.pub_key #=> false
+ #
+ # # With OpenSSL::PKey.generate_key
+ # dh0 = OpenSSL::PKey::DH.new(2048)
+ # dh = OpenSSL::PKey.generate_key(dh0)
+ # 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; " \
+ "use OpenSSL::PKey.generate_key instead"
+ end
+
unless priv_key
tmp = OpenSSL::PKey.generate_key(self)
set_key(tmp.pub_key, tmp.priv_key)
@@ -142,8 +167,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
@@ -249,9 +282,14 @@ module OpenSSL::PKey
# This method is provided for backwards compatibility, and calls #derive
# internally.
def dh_compute_key(pubkey)
- peer = OpenSSL::PKey::EC.new(group)
- peer.public_key = pubkey
- derive(peer)
+ obj = OpenSSL::ASN1.Sequence([
+ OpenSSL::ASN1.Sequence([
+ OpenSSL::ASN1.ObjectId("id-ecPublicKey"),
+ group.to_der,
+ ]),
+ OpenSSL::ASN1.BitString(pubkey.to_octet_string(:uncompressed)),
+ ])
+ derive(OpenSSL::PKey.read(obj.to_der))
end
end
@@ -325,7 +363,8 @@ 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>.
@@ -348,7 +387,8 @@ 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
@@ -369,7 +409,8 @@ 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>.
@@ -390,7 +431,8 @@ 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.
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
index 0930a53017..d28bf1a374 100644
--- a/ext/openssl/lib/openssl/ssl.rb
+++ b/ext/openssl/lib/openssl/ssl.rb
@@ -11,6 +11,9 @@
=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 => -> {
@@ -31,27 +33,28 @@ module OpenSSL
}
if defined?(OpenSSL::PKey::DH)
- DEFAULT_2048 = OpenSSL::PKey::DH.new <<-_end_of_pem_
+ DH_ffdhe2048 = 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==
+MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
+87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
+YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
+7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
+ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
-----END DH PARAMETERS-----
_end_of_pem_
- private_constant :DEFAULT_2048
+ private_constant :DH_ffdhe2048
DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen| # :nodoc:
warn "using default DH parameters." if $VERBOSE
- DEFAULT_2048
+ DH_ffdhe2048
}
end
if !(OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") &&
OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000)
DEFAULT_PARAMS.merge!(
+ min_version: OpenSSL::SSL::TLS1_VERSION,
ciphers: %w{
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-GCM-SHA256
@@ -91,15 +94,17 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
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.
+ # A callback invoked when DH parameters are required for ephemeral DH key
+ # exchange.
#
- # The callback is invoked with the Session for the key exchange, an
+ # 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
@@ -247,6 +252,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
@@ -266,6 +279,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)
@@ -416,6 +459,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?
@@ -432,10 +501,6 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
@context.tmp_dh_callback || OpenSSL::SSL::SSLContext::DEFAULT_TMP_DH_CALLBACK
end
- def tmp_ecdh_callback
- @context.tmp_ecdh_callback
- end
-
def session_new_cb
@context.session_new_cb
end
@@ -493,7 +558,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
@@ -542,3 +607,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 9c7515ba0f..9315a79381 100644
--- a/ext/openssl/lib/openssl/version.rb
+++ b/ext/openssl/lib/openssl/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module OpenSSL
- VERSION = "2.2.0"
+ VERSION = "3.2.0"
end
diff --git a/ext/openssl/lib/openssl/x509.rb b/ext/openssl/lib/openssl/x509.rb
index 448941f75e..f973f4f4dc 100644
--- a/ext/openssl/lib/openssl/x509.rb
+++ b/ext/openssl/lib/openssl/x509.rb
@@ -279,11 +279,29 @@ module OpenSSL
end
class << self
+ # Parses the UTF-8 string representation of a distinguished name,
+ # according to RFC 2253.
+ #
+ # See also #to_utf8 for the opposite operation.
def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
self.new(ary, template)
end
+ # Parses the string representation of a distinguished name. Two
+ # different forms are supported:
+ #
+ # - \OpenSSL format (<tt>X509_NAME_oneline()</tt>) used by
+ # <tt>#to_s</tt>. For example: <tt>/DC=com/DC=example/CN=nobody</tt>
+ # - \OpenSSL format (<tt>X509_NAME_print()</tt>)
+ # used by <tt>#to_s(OpenSSL::X509::Name::COMPAT)</tt>. For example:
+ # <tt>DC=com, DC=example, CN=nobody</tt>
+ #
+ # Neither of them is standardized and has quirks and inconsistencies
+ # in handling of escaped characters or multi-valued RDNs.
+ #
+ # Use of this method is discouraged in new applications. See
+ # Name.parse_rfc2253 and #to_utf8 for the alternative.
def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
if str.start_with?("/")
# /A=B/C=D format