Toshaan Bharvani
1 year ago
commit
9d743fcd4f
51 changed files with 16530 additions and 0 deletions
@ -0,0 +1,303 @@ |
|||||||
|
/* SystemTap tapset to make it easier to trace Ruby 2.0 |
||||||
|
* |
||||||
|
* All probes provided by Ruby can be listed using following command |
||||||
|
* (the path to the library must be adjuste appropriately): |
||||||
|
* |
||||||
|
* stap -L 'process("@LIBRARY_PATH@").mark("*")' |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.array.create - Allocation of new array. |
||||||
|
* |
||||||
|
* @size: Number of elements (an int) |
||||||
|
* @file: The file name where the method is being called (string) |
||||||
|
* @line: The line number where the method is being called (int) |
||||||
|
*/ |
||||||
|
probe ruby.array.create = |
||||||
|
process("@LIBRARY_PATH@").mark("array__create") |
||||||
|
{ |
||||||
|
size = $arg1 |
||||||
|
file = user_string($arg2) |
||||||
|
line = $arg3 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.cmethod.entry - Fired just before a method implemented in C is entered. |
||||||
|
* |
||||||
|
* @classname: Name of the class (string) |
||||||
|
* @methodname: The method about bo be executed (string) |
||||||
|
* @file: The file name where the method is being called (string) |
||||||
|
* @line: The line number where the method is being called (int) |
||||||
|
*/ |
||||||
|
probe ruby.cmethod.entry = |
||||||
|
process("@LIBRARY_PATH@").mark("cmethod__entry") |
||||||
|
{ |
||||||
|
classname = user_string($arg1) |
||||||
|
methodname = user_string($arg2) |
||||||
|
file = user_string($arg3) |
||||||
|
line = $arg4 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.cmethod.return - Fired just after a method implemented in C has returned. |
||||||
|
* |
||||||
|
* @classname: Name of the class (string) |
||||||
|
* @methodname: The executed method (string) |
||||||
|
* @file: The file name where the method is being called (string) |
||||||
|
* @line: The line number where the method is being called (int) |
||||||
|
*/ |
||||||
|
probe ruby.cmethod.return = |
||||||
|
process("@LIBRARY_PATH@").mark("cmethod__return") |
||||||
|
{ |
||||||
|
classname = user_string($arg1) |
||||||
|
methodname = user_string($arg2) |
||||||
|
file = user_string($arg3) |
||||||
|
line = $arg4 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.find.require.entry - Fired when require starts to search load |
||||||
|
* path for suitable file to require. |
||||||
|
* |
||||||
|
* @requiredfile: The name of the file to be required (string) |
||||||
|
* @file: The file name where the method is being called (string) |
||||||
|
* @line: The line number where the method is being called (int) |
||||||
|
*/ |
||||||
|
probe ruby.find.require.entry = |
||||||
|
process("@LIBRARY_PATH@").mark("find__require__entry") |
||||||
|
{ |
||||||
|
requiredfile = user_string($arg1) |
||||||
|
file = user_string($arg2) |
||||||
|
line = $arg3 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.find.require.return - Fired just after require has finished |
||||||
|
* search of load path for suitable file to require. |
||||||
|
* |
||||||
|
* @requiredfile: The name of the file to be required (string) |
||||||
|
* @file: The file name where the method is being called (string) |
||||||
|
* @line: The line number where the method is being called (int) |
||||||
|
*/ |
||||||
|
probe ruby.find.require.return = |
||||||
|
process("@LIBRARY_PATH@").mark("find__require__return") |
||||||
|
{ |
||||||
|
requiredfile = user_string($arg1) |
||||||
|
file = user_string($arg2) |
||||||
|
line = $arg3 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.gc.mark.begin - Fired when a GC mark phase is about to start. |
||||||
|
* |
||||||
|
* It takes no arguments. |
||||||
|
*/ |
||||||
|
probe ruby.gc.mark.begin = |
||||||
|
process("@LIBRARY_PATH@").mark("gc__mark__begin") |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.gc.mark.end - Fired when a GC mark phase has ended. |
||||||
|
* |
||||||
|
* It takes no arguments. |
||||||
|
*/ |
||||||
|
probe ruby.gc.mark.end = |
||||||
|
process("@LIBRARY_PATH@").mark("gc__mark__end") |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.gc.sweep.begin - Fired when a GC sweep phase is about to start. |
||||||
|
* |
||||||
|
* It takes no arguments. |
||||||
|
*/ |
||||||
|
probe ruby.gc.sweep.begin = |
||||||
|
process("@LIBRARY_PATH@").mark("gc__sweep__begin") |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.gc.sweep.end - Fired when a GC sweep phase has ended. |
||||||
|
* |
||||||
|
* It takes no arguments. |
||||||
|
*/ |
||||||
|
probe ruby.gc.sweep.end = |
||||||
|
process("@LIBRARY_PATH@").mark("gc__sweep__end") |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.hash.create - Allocation of new hash. |
||||||
|
* |
||||||
|
* @size: Number of elements (int) |
||||||
|
* @file: The file name where the method is being called (string) |
||||||
|
* @line: The line number where the method is being called (int) |
||||||
|
*/ |
||||||
|
probe ruby.hash.create = |
||||||
|
process("@LIBRARY_PATH@").mark("hash__create") |
||||||
|
{ |
||||||
|
size = $arg1 |
||||||
|
file = user_string($arg2) |
||||||
|
line = $arg3 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.load.entry - Fired when calls to "load" are made. |
||||||
|
* |
||||||
|
* @loadedfile: The name of the file to be loaded (string) |
||||||
|
* @file: The file name where the method is being called (string) |
||||||
|
* @line: The line number where the method is being called (int) |
||||||
|
*/ |
||||||
|
probe ruby.load.entry = |
||||||
|
process("@LIBRARY_PATH@").mark("load__entry") |
||||||
|
{ |
||||||
|
loadedfile = user_string($arg1) |
||||||
|
file = user_string($arg2) |
||||||
|
line = $arg3 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.load.return - Fired just after require has finished |
||||||
|
* search of load path for suitable file to require. |
||||||
|
* |
||||||
|
* @loadedfile: The name of the file that was loaded (string) |
||||||
|
*/ |
||||||
|
probe ruby.load.return = |
||||||
|
process("@LIBRARY_PATH@").mark("load__return") |
||||||
|
{ |
||||||
|
loadedfile = user_string($arg1) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.method.entry - Fired just before a method implemented in Ruby is entered. |
||||||
|
* |
||||||
|
* @classname: Name of the class (string) |
||||||
|
* @methodname: The method about bo be executed (string) |
||||||
|
* @file: The file name where the method is being called (string) |
||||||
|
* @line: The line number where the method is being called (int) |
||||||
|
*/ |
||||||
|
probe ruby.method.entry = |
||||||
|
process("@LIBRARY_PATH@").mark("method__entry") |
||||||
|
{ |
||||||
|
classname = user_string($arg1) |
||||||
|
methodname = user_string($arg2) |
||||||
|
file = user_string($arg3) |
||||||
|
line = $arg4 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.method.return - Fired just after a method implemented in Ruby has returned. |
||||||
|
* |
||||||
|
* @classname: Name of the class (string) |
||||||
|
* @methodname: The executed method (string) |
||||||
|
* @file: The file name where the method is being called (string) |
||||||
|
* @line: The line number where the method is being called (int) |
||||||
|
*/ |
||||||
|
probe ruby.method.return = |
||||||
|
process("@LIBRARY_PATH@").mark("method__return") |
||||||
|
{ |
||||||
|
classname = user_string($arg1) |
||||||
|
methodname = user_string($arg2) |
||||||
|
file = user_string($arg3) |
||||||
|
line = $arg4 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.object.create - Allocation of new object. |
||||||
|
* |
||||||
|
* @classname: Name of the class (string) |
||||||
|
* @file: The file name where the method is being called (string) |
||||||
|
* @line: The line number where the method is being called (int) |
||||||
|
*/ |
||||||
|
probe ruby.object.create = |
||||||
|
process("@LIBRARY_PATH@").mark("object__create") |
||||||
|
{ |
||||||
|
classname = user_string($arg1) |
||||||
|
file = user_string($arg2) |
||||||
|
line = $arg3 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.parse.begin - Fired just before a Ruby source file is parsed. |
||||||
|
* |
||||||
|
* @parsedfile: The name of the file to be parsed (string) |
||||||
|
* @parsedline: The line number of beginning of parsing (int) |
||||||
|
*/ |
||||||
|
probe ruby.parse.begin = |
||||||
|
process("@LIBRARY_PATH@").mark("parse__begin") |
||||||
|
{ |
||||||
|
parsedfile = user_string($arg1) |
||||||
|
parsedline = $arg2 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.parse.end - Fired just after a Ruby source file was parsed. |
||||||
|
* |
||||||
|
* @parsedfile: The name of parsed the file (string) |
||||||
|
* @parsedline: The line number of beginning of parsing (int) |
||||||
|
*/ |
||||||
|
probe ruby.parse.end = |
||||||
|
process("@LIBRARY_PATH@").mark("parse__end") |
||||||
|
{ |
||||||
|
parsedfile = user_string($arg1) |
||||||
|
parsedline = $arg2 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.raise - Fired when an exception is raised. |
||||||
|
* |
||||||
|
* @classname: The class name of the raised exception (string) |
||||||
|
* @file: The name of the file where the exception was raised (string) |
||||||
|
* @line: The line number in the file where the exception was raised (int) |
||||||
|
*/ |
||||||
|
probe ruby.raise = |
||||||
|
process("@LIBRARY_PATH@").mark("raise") |
||||||
|
{ |
||||||
|
classname = user_string($arg1) |
||||||
|
file = user_string($arg2) |
||||||
|
line = $arg3 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.require.entry - Fired on calls to rb_require_safe (when a file |
||||||
|
* is required). |
||||||
|
* |
||||||
|
* @requiredfile: The name of the file to be required (string) |
||||||
|
* @file: The file that called "require" (string) |
||||||
|
* @line: The line number where the call to require was made(int) |
||||||
|
*/ |
||||||
|
probe ruby.require.entry = |
||||||
|
process("@LIBRARY_PATH@").mark("require__entry") |
||||||
|
{ |
||||||
|
requiredfile = user_string($arg1) |
||||||
|
file = user_string($arg2) |
||||||
|
line = $arg3 |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.require.return - Fired just after require has finished |
||||||
|
* search of load path for suitable file to require. |
||||||
|
* |
||||||
|
* @requiredfile: The file that was required (string) |
||||||
|
*/ |
||||||
|
probe ruby.require.return = |
||||||
|
process("@LIBRARY_PATH@").mark("require__return") |
||||||
|
{ |
||||||
|
requiredfile = user_string($arg1) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* probe ruby.string.create - Allocation of new string. |
||||||
|
* |
||||||
|
* @size: Number of elements (an int) |
||||||
|
* @file: The file name where the method is being called (string) |
||||||
|
* @line: The line number where the method is being called (int) |
||||||
|
*/ |
||||||
|
probe ruby.string.create = |
||||||
|
process("@LIBRARY_PATH@").mark("string__create") |
||||||
|
{ |
||||||
|
size = $arg1 |
||||||
|
file = user_string($arg2) |
||||||
|
line = $arg3 |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
%ruby_libdir %{_datadir}/%{name} |
||||||
|
%ruby_libarchdir %{_libdir}/%{name} |
||||||
|
|
||||||
|
# This is the local lib/arch and should not be used for packaging. |
||||||
|
%ruby_sitedir site_ruby |
||||||
|
%ruby_sitelibdir %{_prefix}/local/share/%{name}/%{ruby_sitedir} |
||||||
|
%ruby_sitearchdir %{_prefix}/local/%{_lib}/%{name}/%{ruby_sitedir} |
||||||
|
|
||||||
|
# This is the general location for libs/archs compatible with all |
||||||
|
# or most of the Ruby versions available in the Fedora repositories. |
||||||
|
%ruby_vendordir vendor_ruby |
||||||
|
%ruby_vendorlibdir %{ruby_libdir}/%{ruby_vendordir} |
||||||
|
%ruby_vendorarchdir %{ruby_libarchdir}/%{ruby_vendordir} |
||||||
|
|
||||||
|
# For ruby packages we want to filter out any provides caused by private |
||||||
|
# libs in %%{ruby_vendorarchdir}/%%{ruby_sitearchdir}. |
||||||
|
# |
||||||
|
# Note that this must be invoked in the spec file, preferably as |
||||||
|
# "%{?ruby_default_filter}", before any %description block. |
||||||
|
%ruby_default_filter %{expand: \ |
||||||
|
%global __provides_exclude_from %{?__provides_exclude_from:%{__provides_exclude_from}|}^(%{ruby_vendorarchdir}|%{ruby_sitearchdir})/.*\\\\.so$ \ |
||||||
|
} |
@ -0,0 +1,186 @@ |
|||||||
|
# The RubyGems root folder. |
||||||
|
%gem_dir %{_datadir}/gems |
||||||
|
%gem_archdir %{_libdir}/gems |
||||||
|
|
||||||
|
# Common gem locations and files. |
||||||
|
%gem_instdir %{gem_dir}/gems/%{gem_name}-%{version}%{?prerelease} |
||||||
|
%gem_extdir_mri %{gem_archdir}/%{name}/%{gem_name}-%{version}%{?prerelease} |
||||||
|
%gem_libdir %{gem_instdir}/lib |
||||||
|
%gem_cache %{gem_dir}/cache/%{gem_name}-%{version}%{?prerelease}.gem |
||||||
|
%gem_spec %{gem_dir}/specifications/%{gem_name}-%{version}%{?prerelease}.gemspec |
||||||
|
%gem_docdir %{gem_dir}/doc/%{gem_name}-%{version}%{?prerelease} |
||||||
|
%gem_plugin %{gem_dir}/plugins/%{gem_name}_plugin.rb |
||||||
|
|
||||||
|
|
||||||
|
# %gem_install - Install gem into appropriate directory. |
||||||
|
# |
||||||
|
# Usage: %gem_install [options] |
||||||
|
# |
||||||
|
# -n <gem_file> Overrides gem file name for installation. |
||||||
|
# -d <install_dir> Set installation directory. |
||||||
|
# |
||||||
|
%gem_install(d:n:) \ |
||||||
|
mkdir -p %{-d*}%{!?-d:.%{gem_dir}} \ |
||||||
|
\ |
||||||
|
CONFIGURE_ARGS="--with-cflags='%{optflags}' --with-cxxflags='%{optflags}' --with-ldflags='%{build_ldflags}' $CONFIGURE_ARGS" \\\ |
||||||
|
gem install \\\ |
||||||
|
-V \\\ |
||||||
|
--local \\\ |
||||||
|
--build-root %{-d*}%{!?-d:.} \\\ |
||||||
|
--force \\\ |
||||||
|
--document=ri,rdoc \\\ |
||||||
|
%{-n*}%{!?-n:%{gem_name}-%{version}%{?prerelease}.gem} \ |
||||||
|
%{nil} |
||||||
|
|
||||||
|
|
||||||
|
# The 'read' command in %%gemspec_* macros is not essential, but it is usefull |
||||||
|
# to make the sript appear in build log. |
||||||
|
|
||||||
|
|
||||||
|
# %gemspec_add_dep - Add dependency into .gemspec. |
||||||
|
# |
||||||
|
# Usage: %gemspec_add_dep -g <gem> [options] [requirements] |
||||||
|
# |
||||||
|
# Add dependency named <gem> to .gemspec file. The macro adds runtime |
||||||
|
# dependency by default. The [requirements] argument can be used to specify |
||||||
|
# the dependency constraints more precisely. It is expected to be valid Ruby |
||||||
|
# code. |
||||||
|
# |
||||||
|
# -s <gemspec_file> Overrides the default .gemspec location. |
||||||
|
# -d Add development dependecy. |
||||||
|
# |
||||||
|
%gemspec_add_dep(g:s:d) \ |
||||||
|
read -d '' gemspec_add_dep_script << 'EOR' || : \ |
||||||
|
gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}%{?prerelease}.gemspec}' \ |
||||||
|
\ |
||||||
|
name = '%{-g*}' \ |
||||||
|
requirements = %{*}%{!?1:nil} \ |
||||||
|
\ |
||||||
|
type = :%{!?-d:runtime}%{?-d:development} \ |
||||||
|
\ |
||||||
|
spec = Gem::Specification.load(gemspec_file) \ |
||||||
|
abort("#{gemspec_file} is not accessible.") unless spec \ |
||||||
|
\ |
||||||
|
dep = spec.dependencies.detect { |d| d.type == type && d.name == name } \ |
||||||
|
if dep \ |
||||||
|
dep.requirement.concat requirements \ |
||||||
|
else \ |
||||||
|
spec.public_send "add_#{type}_dependency", name, requirements \ |
||||||
|
end \ |
||||||
|
File.write gemspec_file, spec.to_ruby \ |
||||||
|
EOR\ |
||||||
|
echo "$gemspec_add_dep_script" | ruby \ |
||||||
|
unset -v gemspec_add_dep_script \ |
||||||
|
%{nil} |
||||||
|
|
||||||
|
|
||||||
|
# %gemspec_remove_dep - Remove dependency from .gemspec. |
||||||
|
# |
||||||
|
# Usage: %gemspec_remove_dep -g <gem> [options] [requirements] |
||||||
|
# |
||||||
|
# Remove dependency named <gem> from .gemspec file. The macro removes runtime |
||||||
|
# dependency by default. The [requirements] argument can be used to specify |
||||||
|
# the dependency constraints more precisely. It is expected to be valid Ruby |
||||||
|
# code. The macro fails if these specific requirements can't be removed. |
||||||
|
# |
||||||
|
# -s <gemspec_file> Overrides the default .gemspec location. |
||||||
|
# -d Remove development dependecy. |
||||||
|
# |
||||||
|
%gemspec_remove_dep(g:s:d) \ |
||||||
|
read -d '' gemspec_remove_dep_script << 'EOR' || : \ |
||||||
|
gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}%{?prerelease}.gemspec}' \ |
||||||
|
\ |
||||||
|
name = '%{-g*}' \ |
||||||
|
requirements = %{*}%{!?1:nil} \ |
||||||
|
\ |
||||||
|
type = :%{!?-d:runtime}%{?-d:development} \ |
||||||
|
\ |
||||||
|
spec = Gem::Specification.load(gemspec_file) \ |
||||||
|
abort("#{gemspec_file} is not accessible.") unless spec \ |
||||||
|
\ |
||||||
|
dep = spec.dependencies.detect { |d| d.type == type && d.name == name } \ |
||||||
|
if dep \ |
||||||
|
if requirements \ |
||||||
|
requirements = Gem::Requirement.create(requirements).requirements \ |
||||||
|
requirements.each do |r| \ |
||||||
|
unless dep.requirement.requirements.reject! { |dependency_requirements| dependency_requirements == r } \ |
||||||
|
abort("Requirement '#{r.first} #{r.last}' was not possible to remove for dependency '#{dep}'!") \ |
||||||
|
end \ |
||||||
|
end \ |
||||||
|
spec.dependencies.delete dep if dep.requirement.requirements.empty? \ |
||||||
|
else \ |
||||||
|
spec.dependencies.delete dep \ |
||||||
|
end \ |
||||||
|
else \ |
||||||
|
abort("Dependency '#{name}' was not found!") \ |
||||||
|
end \ |
||||||
|
File.write gemspec_file, spec.to_ruby \ |
||||||
|
EOR\ |
||||||
|
echo "$gemspec_remove_dep_script" | ruby \ |
||||||
|
unset -v gemspec_remove_dep_script \ |
||||||
|
%{nil} |
||||||
|
|
||||||
|
|
||||||
|
# %%gemspec_add_file - Add files to various files lists in .gemspec. |
||||||
|
# |
||||||
|
# Usage: %%gemspec_add_file [options] <file> |
||||||
|
# |
||||||
|
# Add files to .gemspec file. <file> is expected to be valid Ruby code. |
||||||
|
# Path to file is expected. Does not check real files in any way. |
||||||
|
# By default, `files` list is edited. |
||||||
|
# |
||||||
|
# -s <gemspec_file> Overrides the default .gemspec location. |
||||||
|
# -t Edit test_files only. |
||||||
|
# -r Edit extra_rdoc_files only. |
||||||
|
# |
||||||
|
%gemspec_add_file(s:tr) \ |
||||||
|
read -d '' gemspec_add_file_script << 'EOR' || : \ |
||||||
|
gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}%{?prerelease}.gemspec}' \ |
||||||
|
\ |
||||||
|
abort("gemspec_add_file: Use only one '-t' or '-r' at a time.") if "%{?-t}%{?-r}" == "-t-r" \ |
||||||
|
\ |
||||||
|
filenames = %{*}%{!?1:nil} \ |
||||||
|
filenames = Array(filenames) \ |
||||||
|
\ |
||||||
|
spec = Gem::Specification.load(gemspec_file) \ |
||||||
|
abort("#{gemspec_file} is not accessible.") unless spec \ |
||||||
|
\ |
||||||
|
spec.%{?-t:test_}%{?-r:extra_rdoc_}files += filenames \ |
||||||
|
File.write gemspec_file, spec.to_ruby \ |
||||||
|
EOR\ |
||||||
|
echo "$gemspec_add_file_script" | ruby \ |
||||||
|
unset -v gemspec_add_file_script \ |
||||||
|
%{nil} |
||||||
|
|
||||||
|
|
||||||
|
# %%gemspec_remove_file - Remove files from various files lists in .gemspec. |
||||||
|
# |
||||||
|
# Usage: %%gemspec_remove_file [options] <file> |
||||||
|
# |
||||||
|
# Remove files from .gemspec file. <file> is expected to be valid Ruby code. |
||||||
|
# Path to file is expected. Does not check/remove real files in any way. |
||||||
|
# By default, `files` list is edited. File has to be removed from `test_files` |
||||||
|
# first in order to be removable from `files`. |
||||||
|
# |
||||||
|
# -s <gemspec_file> Overrides the default .gemspec location. |
||||||
|
# -t Edit test_files only. |
||||||
|
# -r Edit extra_rdoc_files only. |
||||||
|
# |
||||||
|
%gemspec_remove_file(s:tr) \ |
||||||
|
read -d '' gemspec_remove_file_script << 'EOR' || : \ |
||||||
|
gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}%{?prerelease}.gemspec}' \ |
||||||
|
\ |
||||||
|
abort("gemspec_remove_file: Use only one '-t' or '-r' at a time.") if "%{?-t}%{?-r}" == "-t-r" \ |
||||||
|
\ |
||||||
|
filenames = %{*}%{!?1:nil} \ |
||||||
|
filenames = Array(filenames) \ |
||||||
|
\ |
||||||
|
spec = Gem::Specification.load(gemspec_file) \ |
||||||
|
abort("#{gemspec_file} is not accessible.") unless spec \ |
||||||
|
\ |
||||||
|
spec.%{?-t:test_}%{?-r:extra_rdoc_}files -= filenames \ |
||||||
|
File.write gemspec_file, spec.to_ruby \ |
||||||
|
EOR\ |
||||||
|
echo "$gemspec_remove_file_script" | ruby \ |
||||||
|
unset -v gemspec_remove_file_script \ |
||||||
|
%{nil} |
@ -0,0 +1,148 @@ |
|||||||
|
module Gem |
||||||
|
class << self |
||||||
|
|
||||||
|
## |
||||||
|
# Returns full path of previous but one directory of dir in path |
||||||
|
# E.g. for '/usr/share/ruby', 'ruby', it returns '/usr' |
||||||
|
|
||||||
|
def previous_but_one_dir_to(path, dir) |
||||||
|
return unless path |
||||||
|
|
||||||
|
split_path = path.split(File::SEPARATOR) |
||||||
|
File.join(split_path.take_while { |one_dir| one_dir !~ /^#{dir}$/ }[0..-2]) |
||||||
|
end |
||||||
|
private :previous_but_one_dir_to |
||||||
|
|
||||||
|
## |
||||||
|
# Detects --install-dir option specified on command line. |
||||||
|
|
||||||
|
def opt_install_dir? |
||||||
|
@opt_install_dir ||= ARGV.include?('--install-dir') || ARGV.include?('-i') |
||||||
|
end |
||||||
|
private :opt_install_dir? |
||||||
|
|
||||||
|
## |
||||||
|
# Detects --build-root option specified on command line. |
||||||
|
|
||||||
|
def opt_build_root? |
||||||
|
@opt_build_root ||= ARGV.include?('--build-root') |
||||||
|
end |
||||||
|
private :opt_build_root? |
||||||
|
|
||||||
|
## |
||||||
|
# Tries to detect, if arguments and environment variables suggest that |
||||||
|
# 'gem install' is executed from rpmbuild. |
||||||
|
|
||||||
|
def rpmbuild? |
||||||
|
@rpmbuild ||= ENV['RPM_PACKAGE_NAME'] && (opt_install_dir? || opt_build_root?) |
||||||
|
end |
||||||
|
private :rpmbuild? |
||||||
|
|
||||||
|
## |
||||||
|
# Default gems locations allowed on FHS system (/usr, /usr/share). |
||||||
|
# The locations are derived from directories specified during build |
||||||
|
# configuration. |
||||||
|
|
||||||
|
def default_locations |
||||||
|
@default_locations ||= { |
||||||
|
:system => previous_but_one_dir_to(RbConfig::CONFIG['vendordir'], RbConfig::CONFIG['RUBY_INSTALL_NAME']), |
||||||
|
:local => previous_but_one_dir_to(RbConfig::CONFIG['sitedir'], RbConfig::CONFIG['RUBY_INSTALL_NAME']) |
||||||
|
} |
||||||
|
end |
||||||
|
|
||||||
|
## |
||||||
|
# For each location provides set of directories for binaries (:bin_dir) |
||||||
|
# platform independent (:gem_dir) and dependent (:ext_dir) files. |
||||||
|
|
||||||
|
def default_dirs |
||||||
|
@libdir ||= case RUBY_PLATFORM |
||||||
|
when 'java' |
||||||
|
RbConfig::CONFIG['datadir'] |
||||||
|
else |
||||||
|
RbConfig::CONFIG['libdir'] |
||||||
|
end |
||||||
|
|
||||||
|
@default_dirs ||= default_locations.inject(Hash.new) do |hash, location| |
||||||
|
destination, path = location |
||||||
|
|
||||||
|
hash[destination] = if path |
||||||
|
{ |
||||||
|
:bin_dir => File.join(path, RbConfig::CONFIG['bindir'].split(File::SEPARATOR).last), |
||||||
|
:gem_dir => File.join(path, RbConfig::CONFIG['datadir'].split(File::SEPARATOR).last, 'gems'), |
||||||
|
:ext_dir => File.join(path, @libdir.split(File::SEPARATOR).last, 'gems') |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
:bin_dir => '', |
||||||
|
:gem_dir => '', |
||||||
|
:ext_dir => '' |
||||||
|
} |
||||||
|
end |
||||||
|
|
||||||
|
hash |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
## |
||||||
|
# Remove methods we are going to override. This avoids "method redefined;" |
||||||
|
# warnings otherwise issued by Ruby. |
||||||
|
|
||||||
|
remove_method :operating_system_defaults if method_defined? :operating_system_defaults |
||||||
|
remove_method :default_dir if method_defined? :default_dir |
||||||
|
remove_method :default_path if method_defined? :default_path |
||||||
|
remove_method :default_ext_dir_for if method_defined? :default_ext_dir_for |
||||||
|
|
||||||
|
## |
||||||
|
# Regular user installs into user directory, root manages /usr/local. |
||||||
|
|
||||||
|
def operating_system_defaults |
||||||
|
unless opt_build_root? |
||||||
|
options = if Process.uid == 0 |
||||||
|
"--install-dir=#{Gem.default_dirs[:local][:gem_dir]} --bindir #{Gem.default_dirs[:local][:bin_dir]}" |
||||||
|
else |
||||||
|
"--user-install --bindir #{File.join [Dir.home, 'bin']}" |
||||||
|
end |
||||||
|
|
||||||
|
{"gem" => options} |
||||||
|
else |
||||||
|
{} |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
## |
||||||
|
# RubyGems default overrides. |
||||||
|
|
||||||
|
def default_dir |
||||||
|
Gem.default_dirs[:system][:gem_dir] |
||||||
|
end |
||||||
|
|
||||||
|
def default_path |
||||||
|
path = default_dirs.collect {|location, paths| paths[:gem_dir]} |
||||||
|
path.unshift Gem.user_dir if File.exist? Gem.user_home |
||||||
|
path |
||||||
|
end |
||||||
|
|
||||||
|
def default_ext_dir_for base_dir |
||||||
|
dir = if rpmbuild? |
||||||
|
build_dir = base_dir.chomp Gem.default_dirs[:system][:gem_dir] |
||||||
|
if build_dir != base_dir |
||||||
|
File.join build_dir, Gem.default_dirs[:system][:ext_dir] |
||||||
|
end |
||||||
|
else |
||||||
|
dirs = Gem.default_dirs.detect {|location, paths| paths[:gem_dir] == base_dir} |
||||||
|
dirs && dirs.last[:ext_dir] |
||||||
|
end |
||||||
|
dir && File.join(dir, RbConfig::CONFIG['RUBY_INSTALL_NAME']) |
||||||
|
end |
||||||
|
|
||||||
|
# This method should be available since RubyGems 2.2 until RubyGems 3.0. |
||||||
|
# https://github.com/rubygems/rubygems/issues/749 |
||||||
|
if method_defined? :install_extension_in_lib |
||||||
|
remove_method :install_extension_in_lib |
||||||
|
|
||||||
|
def install_extension_in_lib |
||||||
|
false |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,25 @@ |
|||||||
|
From 28cc0749d6729aa2444661ee7b411e183fe220b0 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Mon, 19 Nov 2012 15:14:51 +0100 |
||||||
|
Subject: [PATCH] Verbose mkmf. |
||||||
|
|
||||||
|
--- |
||||||
|
lib/mkmf.rb | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/lib/mkmf.rb b/lib/mkmf.rb |
||||||
|
index 682eb46..e6b1445 100644 |
||||||
|
--- a/lib/mkmf.rb |
||||||
|
+++ b/lib/mkmf.rb |
||||||
|
@@ -1930,7 +1930,7 @@ def configuration(srcdir) |
||||||
|
SHELL = /bin/sh |
||||||
|
|
||||||
|
# V=0 quiet, V=1 verbose. other values don't work. |
||||||
|
-V = 0 |
||||||
|
+V = 1 |
||||||
|
Q1 = $(V:1=) |
||||||
|
Q = $(Q1:0=@) |
||||||
|
ECHO1 = $(V:1=@ #{CONFIG['NULLCMD']}) |
||||||
|
-- |
||||||
|
1.8.3.1 |
||||||
|
|
@ -0,0 +1,28 @@ |
|||||||
|
From 07c666ba5c3360dd6f43605a8ac7c85c99c1721f Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Tue, 1 Oct 2013 12:22:40 +0200 |
||||||
|
Subject: [PATCH] Allow to configure libruby.so placement. |
||||||
|
|
||||||
|
--- |
||||||
|
configure.ac | 5 +++++ |
||||||
|
1 file changed, 5 insertions(+) |
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac |
||||||
|
index d261ea57b5..3c13076b82 100644 |
||||||
|
--- a/configure.ac |
||||||
|
+++ b/configure.ac |
||||||
|
@@ -3240,6 +3240,11 @@ AS_IF([test ${multiarch+set}], [ |
||||||
|
]) |
||||||
|
|
||||||
|
archlibdir='${libdir}/${arch}' |
||||||
|
+AC_ARG_WITH(archlibdir, |
||||||
|
+ AS_HELP_STRING([--with-archlibdir=DIR], |
||||||
|
+ [prefix for libruby [[LIBDIR/ARCH]]]), |
||||||
|
+ [archlibdir="$withval"]) |
||||||
|
+ |
||||||
|
sitearchlibdir='${libdir}/${sitearch}' |
||||||
|
archincludedir='${includedir}/${arch}' |
||||||
|
sitearchincludedir='${includedir}/${sitearch}' |
||||||
|
-- |
||||||
|
2.22.0 |
||||||
|
|
@ -0,0 +1,80 @@ |
|||||||
|
From e24d97c938c481450ed80ec83e5399595946c1ae Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Fri, 8 Feb 2013 22:48:41 +0100 |
||||||
|
Subject: [PATCH] Prevent duplicated paths when empty version string is |
||||||
|
configured. |
||||||
|
|
||||||
|
--- |
||||||
|
configure.ac | 3 ++- |
||||||
|
loadpath.c | 12 ++++++++++++ |
||||||
|
tool/mkconfig.rb | 2 +- |
||||||
|
3 files changed, 15 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac |
||||||
|
index c42436c23d..d261ea57b5 100644 |
||||||
|
--- a/configure.ac |
||||||
|
+++ b/configure.ac |
||||||
|
@@ -3881,7 +3881,8 @@ AS_CASE(["$ruby_version_dir_name"], |
||||||
|
ruby_version_dir=/'${ruby_version_dir_name}' |
||||||
|
|
||||||
|
if test -z "${ruby_version_dir_name}"; then |
||||||
|
- AC_MSG_ERROR([No ruby version, No place for bundled libraries]) |
||||||
|
+ unset ruby_version_dir |
||||||
|
+ AC_DEFINE(RUBY_LIB_VERSION_BLANK, 1) |
||||||
|
fi |
||||||
|
|
||||||
|
rubylibdir='${rubylibprefix}'${ruby_version_dir} |
||||||
|
diff --git a/loadpath.c b/loadpath.c |
||||||
|
index 9160031..0d4d953 100644 |
||||||
|
--- a/loadpath.c |
||||||
|
+++ b/loadpath.c |
||||||
|
@@ -65,21 +65,33 @@ const char ruby_initial_load_paths[] = |
||||||
|
RUBY_SEARCH_PATH "\0" |
||||||
|
#endif |
||||||
|
#ifndef NO_RUBY_SITE_LIB |
||||||
|
+#ifdef RUBY_LIB_VERSION_BLANK |
||||||
|
+ RUBY_SITE_LIB "\0" |
||||||
|
+#else |
||||||
|
RUBY_SITE_LIB2 "\0" |
||||||
|
+#endif |
||||||
|
#ifdef RUBY_THINARCH |
||||||
|
RUBY_SITE_ARCH_LIB_FOR(RUBY_THINARCH) "\0" |
||||||
|
#endif |
||||||
|
RUBY_SITE_ARCH_LIB_FOR(RUBY_SITEARCH) "\0" |
||||||
|
+#ifndef RUBY_LIB_VERSION_BLANK |
||||||
|
RUBY_SITE_LIB "\0" |
||||||
|
#endif |
||||||
|
+#endif |
||||||
|
|
||||||
|
#ifndef NO_RUBY_VENDOR_LIB |
||||||
|
+#ifdef RUBY_LIB_VERSION_BLANK |
||||||
|
+ RUBY_VENDOR_LIB "\0" |
||||||
|
+#else |
||||||
|
RUBY_VENDOR_LIB2 "\0" |
||||||
|
+#endif |
||||||
|
#ifdef RUBY_THINARCH |
||||||
|
RUBY_VENDOR_ARCH_LIB_FOR(RUBY_THINARCH) "\0" |
||||||
|
#endif |
||||||
|
RUBY_VENDOR_ARCH_LIB_FOR(RUBY_SITEARCH) "\0" |
||||||
|
+#ifndef RUBY_LIB_VERSION_BLANK |
||||||
|
RUBY_VENDOR_LIB "\0" |
||||||
|
+#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
RUBY_LIB "\0" |
||||||
|
diff --git a/tool/mkconfig.rb b/tool/mkconfig.rb |
||||||
|
index 07076d4..35e6c3c 100755 |
||||||
|
--- a/tool/mkconfig.rb |
||||||
|
+++ b/tool/mkconfig.rb |
||||||
|
@@ -114,7 +114,7 @@ |
||||||
|
val = val.gsub(/\$(?:\$|\{?(\w+)\}?)/) {$1 ? "$(#{$1})" : $&}.dump |
||||||
|
case name |
||||||
|
when /^prefix$/ |
||||||
|
- val = "(TOPDIR || DESTDIR + #{val})" |
||||||
|
+ val = "(((TOPDIR && TOPDIR.empty?) ? nil : TOPDIR) || DESTDIR + #{val})" |
||||||
|
when /^ARCH_FLAG$/ |
||||||
|
val = "arch_flag || #{val}" if universal |
||||||
|
when /^UNIVERSAL_ARCHNAMES$/ |
||||||
|
-- |
||||||
|
1.9.0 |
||||||
|
|
@ -0,0 +1,25 @@ |
|||||||
|
From 2089cab72b38d6d5e7ba2b596e41014209acad30 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Mon, 19 Nov 2012 14:37:28 +0100 |
||||||
|
Subject: [PATCH] Always use i386. |
||||||
|
|
||||||
|
--- |
||||||
|
configure.ac | 2 ++ |
||||||
|
1 file changed, 2 insertions(+) |
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac |
||||||
|
index 3c13076b82..93af30321d 100644 |
||||||
|
--- a/configure.ac |
||||||
|
+++ b/configure.ac |
||||||
|
@@ -3945,6 +3945,8 @@ AC_SUBST(vendorarchdir)dnl |
||||||
|
AC_SUBST(CONFIGURE, "`echo $0 | sed 's|.*/||'`")dnl |
||||||
|
AC_SUBST(configure_args, "`echo "${ac_configure_args}" | sed 's/\\$/$$/g'`")dnl |
||||||
|
|
||||||
|
+target_cpu=`echo $target_cpu | sed s/i.86/i386/` |
||||||
|
+ |
||||||
|
AS_IF([test "${universal_binary-no}" = yes ], [ |
||||||
|
arch="universal-${target_os}" |
||||||
|
AS_IF([test "${rb_cv_architecture_available}" = yes], [ |
||||||
|
-- |
||||||
|
1.8.3.1 |
||||||
|
|
@ -0,0 +1,97 @@ |
|||||||
|
From 94da59aafacc6a9efe829529eb51385588d6f149 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Fri, 11 Nov 2011 13:14:45 +0100 |
||||||
|
Subject: [PATCH] Allow to install RubyGems into custom location, outside of |
||||||
|
Ruby tree. |
||||||
|
|
||||||
|
--- |
||||||
|
configure.ac | 5 +++++ |
||||||
|
loadpath.c | 4 ++++ |
||||||
|
template/verconf.h.tmpl | 3 +++ |
||||||
|
tool/rbinstall.rb | 10 ++++++++++ |
||||||
|
4 files changed, 22 insertions(+) |
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac |
||||||
|
index 93af30321d..bc13397e0e 100644 |
||||||
|
--- a/configure.ac |
||||||
|
+++ b/configure.ac |
||||||
|
@@ -3917,6 +3917,10 @@ AC_ARG_WITH(vendorarchdir, |
||||||
|
[vendorarchdir=$withval], |
||||||
|
[vendorarchdir=${multiarch+'${rubysitearchprefix}/vendor_ruby'${ruby_version_dir}}${multiarch-'${vendorlibdir}/${sitearch}'}]) |
||||||
|
|
||||||
|
+AC_ARG_WITH(rubygemsdir, |
||||||
|
+ AS_HELP_STRING([--with-rubygemsdir=DIR], [custom rubygems directory]), |
||||||
|
+ [rubygemsdir=$withval]) |
||||||
|
+ |
||||||
|
AS_IF([test "${LOAD_RELATIVE+set}"], [ |
||||||
|
AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE) |
||||||
|
RUBY_EXEC_PREFIX='' |
||||||
|
@@ -3941,6 +3945,7 @@ AC_SUBST(sitearchdir)dnl |
||||||
|
AC_SUBST(vendordir)dnl |
||||||
|
AC_SUBST(vendorlibdir)dnl |
||||||
|
AC_SUBST(vendorarchdir)dnl |
||||||
|
+AC_SUBST(rubygemsdir)dnl |
||||||
|
|
||||||
|
AC_SUBST(CONFIGURE, "`echo $0 | sed 's|.*/||'`")dnl |
||||||
|
AC_SUBST(configure_args, "`echo "${ac_configure_args}" | sed 's/\\$/$$/g'`")dnl |
||||||
|
diff --git a/loadpath.c b/loadpath.c |
||||||
|
index 623dc9d..74c5d9e 100644 |
||||||
|
--- a/loadpath.c |
||||||
|
+++ b/loadpath.c |
||||||
|
@@ -94,6 +94,10 @@ const char ruby_initial_load_paths[] = |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
+#ifdef RUBYGEMS_DIR |
||||||
|
+ RUBYGEMS_DIR "\0" |
||||||
|
+#endif |
||||||
|
+ |
||||||
|
RUBY_LIB "\0" |
||||||
|
#ifdef RUBY_THINARCH |
||||||
|
RUBY_ARCH_LIB_FOR(RUBY_THINARCH) "\0" |
||||||
|
diff --git a/template/verconf.h.tmpl b/template/verconf.h.tmpl |
||||||
|
index 79c003e..34f2382 100644 |
||||||
|
--- a/template/verconf.h.tmpl |
||||||
|
+++ b/template/verconf.h.tmpl |
||||||
|
@@ -36,6 +36,9 @@ |
||||||
|
% if C["RUBY_SEARCH_PATH"] |
||||||
|
#define RUBY_SEARCH_PATH "${RUBY_SEARCH_PATH}" |
||||||
|
% end |
||||||
|
+% if C["rubygemsdir"] |
||||||
|
+#define RUBYGEMS_DIR "${rubygemsdir}" |
||||||
|
+% end |
||||||
|
% |
||||||
|
% R = {} |
||||||
|
% R["ruby_version"] = '"RUBY_LIB_VERSION"' |
||||||
|
diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb |
||||||
|
index e9110a17ca..76a1f0a315 100755 |
||||||
|
--- a/tool/rbinstall.rb |
||||||
|
+++ b/tool/rbinstall.rb |
||||||
|
@@ -349,6 +349,7 @@ def CONFIG.[](name, mandatory = false) |
||||||
|
vendorlibdir = CONFIG["vendorlibdir"] |
||||||
|
vendorarchlibdir = CONFIG["vendorarchdir"] |
||||||
|
end |
||||||
|
+rubygemsdir = CONFIG["rubygemsdir"] |
||||||
|
mandir = CONFIG["mandir", true] |
||||||
|
docdir = CONFIG["docdir", true] |
||||||
|
enable_shared = CONFIG["ENABLE_SHARED"] == 'yes' |
||||||
|
@@ -581,7 +582,16 @@ def stub |
||||||
|
install?(:local, :comm, :lib) do |
||||||
|
prepare "library scripts", rubylibdir |
||||||
|
noinst = %w[*.txt *.rdoc *.gemspec] |
||||||
|
+ # Bundler carries "rubygems.rb" file, so it must be specialcased :/ |
||||||
|
+ noinst += %w[rubygems.rb rubygems/ bundler.rb bundler/] if rubygemsdir |
||||||
|
install_recursive(File.join(srcdir, "lib"), rubylibdir, :no_install => noinst, :mode => $data_mode) |
||||||
|
+ if rubygemsdir |
||||||
|
+ noinst = %w[*.txt *.rdoc *.gemspec] |
||||||
|
+ install_recursive(File.join(srcdir, "lib", "rubygems"), File.join(rubygemsdir, "rubygems"), :no_install => noinst, :mode => $data_mode) |
||||||
|
+ install(File.join(srcdir, "lib", "rubygems.rb"), File.join(rubygemsdir, "rubygems.rb"), :mode => $data_mode) |
||||||
|
+ install_recursive(File.join(srcdir, "lib", "bundler"), File.join(rubylibdir, "bundler"), :no_install => noinst, :mode => $data_mode) |
||||||
|
+ install(File.join(srcdir, "lib", "bundler.rb"), rubylibdir, :mode => $data_mode) |
||||||
|
+ end |
||||||
|
end |
||||||
|
|
||||||
|
install?(:local, :comm, :hdr, :'comm-hdr') do |
||||||
|
-- |
||||||
|
1.8.3.1 |
||||||
|
|
@ -0,0 +1,288 @@ |
|||||||
|
From 4fc1be3af3f58621bb751c9e63c208b15c0e8d16 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Tue, 31 Mar 2015 16:21:04 +0200 |
||||||
|
Subject: [PATCH 1/4] Use ruby_version_dir_name for versioned directories. |
||||||
|
|
||||||
|
This disallows changing the ruby_version constant by --with-ruby-version |
||||||
|
configuration options. The two places version numbers are disallowed as |
||||||
|
well, since there are a lot of places which cannot handle this format |
||||||
|
properly. |
||||||
|
|
||||||
|
ruby_version_dir_name now specifies custom version string for versioned |
||||||
|
directories, e.g. instead of default X.Y.Z, you can specify whatever |
||||||
|
string. |
||||||
|
--- |
||||||
|
configure.ac | 64 ++++++++++++++++++++++++--------------------- |
||||||
|
template/ruby.pc.in | 1 + |
||||||
|
2 files changed, 35 insertions(+), 30 deletions(-) |
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac |
||||||
|
index 80b137e380..63cd3b4f8b 100644 |
||||||
|
--- a/configure.ac |
||||||
|
+++ b/configure.ac |
||||||
|
@@ -3832,9 +3832,6 @@ AS_CASE(["$target_os"], |
||||||
|
rubyw_install_name='$(RUBYW_INSTALL_NAME)' |
||||||
|
]) |
||||||
|
|
||||||
|
-rubylibdir='${rubylibprefix}/${ruby_version}' |
||||||
|
-rubyarchdir=${multiarch+'${rubyarchprefix}/${ruby_version}'}${multiarch-'${rubylibdir}/${arch}'} |
||||||
|
- |
||||||
|
rubyarchprefix=${multiarch+'${archlibdir}/${RUBY_BASE_NAME}'}${multiarch-'${rubylibprefix}/${arch}'} |
||||||
|
AC_ARG_WITH(rubyarchprefix, |
||||||
|
AS_HELP_STRING([--with-rubyarchprefix=DIR], |
||||||
|
@@ -3857,56 +3854,62 @@ AC_ARG_WITH(ridir, |
||||||
|
AC_SUBST(ridir) |
||||||
|
AC_SUBST(RI_BASE_NAME) |
||||||
|
|
||||||
|
-AC_ARG_WITH(ruby-version, |
||||||
|
- AS_HELP_STRING([--with-ruby-version=STR], [ruby version string for version specific directories [[full]] (full|minor|STR)]), |
||||||
|
- [ruby_version=$withval], |
||||||
|
- [ruby_version=full]) |
||||||
|
unset RUBY_LIB_VERSION |
||||||
|
-unset RUBY_LIB_VERSION_STYLE |
||||||
|
-AS_CASE(["$ruby_version"], |
||||||
|
- [full], [RUBY_LIB_VERSION_STYLE='3 /* full */'], |
||||||
|
- [minor], [RUBY_LIB_VERSION_STYLE='2 /* minor */']) |
||||||
|
-AS_IF([test ${RUBY_LIB_VERSION_STYLE+set}], [ |
||||||
|
- { |
||||||
|
- echo "#define RUBY_LIB_VERSION_STYLE $RUBY_LIB_VERSION_STYLE" |
||||||
|
- echo '#define STRINGIZE(x) x' |
||||||
|
- test -f revision.h -o -f "${srcdir}/revision.h" || echo '#define RUBY_REVISION 0' |
||||||
|
- echo '#include "version.h"' |
||||||
|
- echo 'ruby_version=RUBY_LIB_VERSION' |
||||||
|
- } > conftest.c |
||||||
|
- ruby_version="`$CPP -I. -I"${srcdir}" -I"${srcdir}/include" conftest.c | sed '/^ruby_version=/!d;s/ //g'`" |
||||||
|
- eval $ruby_version |
||||||
|
-], [test -z "${ruby_version}"], [ |
||||||
|
- AC_MSG_ERROR([No ruby version, No place for bundled libraries]) |
||||||
|
-], [ |
||||||
|
- RUBY_LIB_VERSION="${ruby_version}" |
||||||
|
-]) |
||||||
|
+RUBY_LIB_VERSION_STYLE='3 /* full */' |
||||||
|
+{ |
||||||
|
+echo "#define RUBY_LIB_VERSION_STYLE $RUBY_LIB_VERSION_STYLE" |
||||||
|
+echo '#define STRINGIZE(x) x' |
||||||
|
+test -f revision.h -o -f "${srcdir}/revision.h" || echo '#define RUBY_REVISION 0' |
||||||
|
+echo '#include "version.h"' |
||||||
|
+echo 'ruby_version=RUBY_LIB_VERSION' |
||||||
|
+} > conftest.c |
||||||
|
+ruby_version="`$CPP -I. -I"${srcdir}" -I"${srcdir}/include" conftest.c | sed '/^ruby_version=/!d;s/ //g'`" |
||||||
|
+eval $ruby_version |
||||||
|
+ |
||||||
|
+RUBY_LIB_VERSION="${ruby_version}" |
||||||
|
+ |
||||||
|
AC_SUBST(RUBY_LIB_VERSION_STYLE) |
||||||
|
AC_SUBST(RUBY_LIB_VERSION) |
||||||
|
|
||||||
|
+AC_ARG_WITH(ruby-version, |
||||||
|
+ AS_HELP_STRING([--with-ruby-version=STR], [ruby version string for version specific directories [[full]] (full|STR)]), |
||||||
|
+ [ruby_version_dir_name=$withval], |
||||||
|
+ [ruby_version_dir_name=full]) |
||||||
|
+AS_CASE(["$ruby_version_dir_name"], |
||||||
|
+ [full], [ruby_version_dir_name='${ruby_version}']) |
||||||
|
+ |
||||||
|
+ruby_version_dir=/'${ruby_version_dir_name}' |
||||||
|
+ |
||||||
|
+if test -z "${ruby_version_dir_name}"; then |
||||||
|
+ AC_MSG_ERROR([No ruby version, No place for bundled libraries]) |
||||||
|
+fi |
||||||
|
+ |
||||||
|
+rubylibdir='${rubylibprefix}'${ruby_version_dir} |
||||||
|
+rubyarchdir=${multiarch+'${rubyarchprefix}'${ruby_version_dir}}${multiarch-'${rubylibdir}/${arch}'} |
||||||
|
+ |
||||||
|
AC_ARG_WITH(sitedir, |
||||||
|
AS_HELP_STRING([--with-sitedir=DIR], [site libraries in DIR [[RUBY_LIB_PREFIX/site_ruby]], "no" to disable site directory]), |
||||||
|
[sitedir=$withval], |
||||||
|
[sitedir='${rubylibprefix}/site_ruby']) |
||||||
|
-sitelibdir='${sitedir}/${ruby_version}' |
||||||
|
+sitelibdir='${sitedir}'${ruby_version_dir} |
||||||
|
|
||||||
|
AC_ARG_WITH(sitearchdir, |
||||||
|
AS_HELP_STRING([--with-sitearchdir=DIR], |
||||||
|
[architecture dependent site libraries in DIR [[SITEDIR/SITEARCH]], "no" to disable site directory]), |
||||||
|
[sitearchdir=$withval], |
||||||
|
- [sitearchdir=${multiarch+'${rubysitearchprefix}/site_ruby/${ruby_version}'}${multiarch-'${sitelibdir}/${sitearch}'}]) |
||||||
|
+ [sitearchdir=${multiarch+'${rubysitearchprefix}/site_ruby'${ruby_version_dir}}${multiarch-'${sitelibdir}/${sitearch}'}]) |
||||||
|
|
||||||
|
AC_ARG_WITH(vendordir, |
||||||
|
AS_HELP_STRING([--with-vendordir=DIR], [vendor libraries in DIR [[RUBY_LIB_PREFIX/vendor_ruby]], "no" to disable vendor directory]), |
||||||
|
[vendordir=$withval], |
||||||
|
[vendordir='${rubylibprefix}/vendor_ruby']) |
||||||
|
-vendorlibdir='${vendordir}/${ruby_version}' |
||||||
|
+vendorlibdir='${vendordir}'${ruby_version_dir} |
||||||
|
|
||||||
|
AC_ARG_WITH(vendorarchdir, |
||||||
|
AS_HELP_STRING([--with-vendorarchdir=DIR], |
||||||
|
[architecture dependent vendor libraries in DIR [[VENDORDIR/SITEARCH]], "no" to disable vendor directory]), |
||||||
|
[vendorarchdir=$withval], |
||||||
|
- [vendorarchdir=${multiarch+'${rubysitearchprefix}/vendor_ruby/${ruby_version}'}${multiarch-'${vendorlibdir}/${sitearch}'}]) |
||||||
|
+ [vendorarchdir=${multiarch+'${rubysitearchprefix}/vendor_ruby'${ruby_version_dir}}${multiarch-'${vendorlibdir}/${sitearch}'}]) |
||||||
|
|
||||||
|
AS_IF([test "${LOAD_RELATIVE+set}"], [ |
||||||
|
AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE) |
||||||
|
@@ -3923,6 +3926,7 @@ AC_SUBST(sitearchincludedir)dnl |
||||||
|
AC_SUBST(arch)dnl |
||||||
|
AC_SUBST(sitearch)dnl |
||||||
|
AC_SUBST(ruby_version)dnl |
||||||
|
+AC_SUBST(ruby_version_dir_name)dnl |
||||||
|
AC_SUBST(rubylibdir)dnl |
||||||
|
AC_SUBST(rubyarchdir)dnl |
||||||
|
AC_SUBST(sitedir)dnl |
||||||
|
diff --git a/template/ruby.pc.in b/template/ruby.pc.in |
||||||
|
index 8a2c066..c81b211 100644 |
||||||
|
--- a/template/ruby.pc.in |
||||||
|
+++ b/template/ruby.pc.in |
||||||
|
@@ -9,6 +9,7 @@ MAJOR=@MAJOR@ |
||||||
|
MINOR=@MINOR@ |
||||||
|
TEENY=@TEENY@ |
||||||
|
ruby_version=@ruby_version@ |
||||||
|
+ruby_version_dir_name=@ruby_version_dir_name@ |
||||||
|
RUBY_API_VERSION=@RUBY_API_VERSION@ |
||||||
|
RUBY_PROGRAM_VERSION=@RUBY_PROGRAM_VERSION@ |
||||||
|
RUBY_BASE_NAME=@RUBY_BASE_NAME@ |
||||||
|
-- |
||||||
|
2.1.0 |
||||||
|
|
||||||
|
|
||||||
|
From 518850aba6eee76de7715aae8d37330e34b01983 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Tue, 31 Mar 2015 16:37:26 +0200 |
||||||
|
Subject: [PATCH 2/4] Add ruby_version_dir_name support for RDoc. |
||||||
|
|
||||||
|
--- |
||||||
|
lib/rdoc/ri/paths.rb | 2 +- |
||||||
|
tool/rbinstall.rb | 2 +- |
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/rdoc/ri/paths.rb b/lib/rdoc/ri/paths.rb |
||||||
|
index 970cb91..5bf8230 100644 |
||||||
|
--- a/lib/rdoc/ri/paths.rb |
||||||
|
+++ b/lib/rdoc/ri/paths.rb |
||||||
|
@@ -10,7 +10,7 @@ module RDoc::RI::Paths |
||||||
|
#:stopdoc: |
||||||
|
require 'rbconfig' |
||||||
|
|
||||||
|
- version = RbConfig::CONFIG['ruby_version'] |
||||||
|
+ version = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] |
||||||
|
|
||||||
|
BASE = File.join RbConfig::CONFIG['ridir'], version |
||||||
|
|
||||||
|
diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb |
||||||
|
index d4c110e..d39c9a6 100755 |
||||||
|
--- a/tool/rbinstall.rb |
||||||
|
+++ b/tool/rbinstall.rb |
||||||
|
@@ -439,7 +439,7 @@ def CONFIG.[](name, mandatory = false) |
||||||
|
|
||||||
|
install?(:doc, :rdoc) do |
||||||
|
if $rdocdir |
||||||
|
- ridatadir = File.join(CONFIG['ridir'], CONFIG['ruby_version'], "system") |
||||||
|
+ ridatadir = File.join(CONFIG['ridir'], CONFIG['ruby_version_dir_name'] || CONFIG['ruby_version'], "system") |
||||||
|
prepare "rdoc", ridatadir |
||||||
|
install_recursive($rdocdir, ridatadir, :no_install => rdoc_noinst, :mode => $data_mode) |
||||||
|
end |
||||||
|
-- |
||||||
|
2.23.0 |
||||||
|
|
||||||
|
|
||||||
|
From 9f0ec0233f618cbb862629816b22491c3df79578 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Tue, 31 Mar 2015 16:37:44 +0200 |
||||||
|
Subject: [PATCH 3/4] Add ruby_version_dir_name support for RubyGems. |
||||||
|
|
||||||
|
--- |
||||||
|
lib/rubygems/defaults.rb | 9 +++++---- |
||||||
|
test/rubygems/test_gem.rb | 5 +++-- |
||||||
|
2 files changed, 8 insertions(+), 6 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb |
||||||
|
index d4ff4a262c..3f9a5bf590 100644 |
||||||
|
--- a/lib/rubygems/defaults.rb |
||||||
|
+++ b/lib/rubygems/defaults.rb |
||||||
|
@@ -38,13 +38,13 @@ def self.default_dir |
||||||
|
[ |
||||||
|
File.dirname(RbConfig::CONFIG['sitedir']), |
||||||
|
'Gems', |
||||||
|
- RbConfig::CONFIG['ruby_version'], |
||||||
|
+ RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] |
||||||
|
] |
||||||
|
else |
||||||
|
[ |
||||||
|
RbConfig::CONFIG['rubylibprefix'], |
||||||
|
'gems', |
||||||
|
- RbConfig::CONFIG['ruby_version'], |
||||||
|
+ RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] |
||||||
|
] |
||||||
|
end |
||||||
|
|
||||||
|
@@ -117,7 +117,8 @@ def self.user_dir |
||||||
|
gem_dir = File.join(Gem.user_home, ".gem") |
||||||
|
gem_dir = File.join(Gem.data_home, "gem") unless File.exist?(gem_dir) |
||||||
|
parts = [gem_dir, ruby_engine] |
||||||
|
- parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty? |
||||||
|
+ ruby_version_dir_name = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] |
||||||
|
+ parts << ruby_version_dir_name unless ruby_version_dir_name.empty? |
||||||
|
File.join parts |
||||||
|
end |
||||||
|
|
||||||
|
@@ -252,7 +253,7 @@ def self.vendor_dir # :nodoc: |
||||||
|
return nil unless RbConfig::CONFIG.key? 'vendordir' |
||||||
|
|
||||||
|
File.join RbConfig::CONFIG['vendordir'], 'gems', |
||||||
|
- RbConfig::CONFIG['ruby_version'] |
||||||
|
+ RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] |
||||||
|
end |
||||||
|
|
||||||
|
## |
||||||
|
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb |
||||||
|
index b25068405d..e9fef4a311 100644 |
||||||
|
--- a/test/rubygems/test_gem.rb |
||||||
|
+++ b/test/rubygems/test_gem.rb |
||||||
|
@@ -1440,7 +1440,8 @@ def test_self_use_paths |
||||||
|
|
||||||
|
def test_self_user_dir |
||||||
|
parts = [@userhome, '.gem', Gem.ruby_engine] |
||||||
|
- parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty? |
||||||
|
+ ruby_version_dir_name = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] |
||||||
|
+ parts << ruby_version_dir_name unless ruby_version_dir_name.empty? |
||||||
|
|
||||||
|
FileUtils.mkdir_p File.join(parts) |
||||||
|
|
||||||
|
@@ -1516,7 +1517,7 @@ def test_self_vendor_dir |
||||||
|
vendordir(File.join(@tempdir, 'vendor')) do |
||||||
|
expected = |
||||||
|
File.join RbConfig::CONFIG['vendordir'], 'gems', |
||||||
|
- RbConfig::CONFIG['ruby_version'] |
||||||
|
+ RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] |
||||||
|
|
||||||
|
assert_equal expected, Gem.vendor_dir |
||||||
|
end |
||||||
|
-- |
||||||
|
2.1.0 |
||||||
|
|
||||||
|
|
||||||
|
From 88c38a030c22dbf9422ece847bdfbf87d6659313 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Wed, 1 Apr 2015 14:55:37 +0200 |
||||||
|
Subject: [PATCH 4/4] Let headers directories follow the configured version |
||||||
|
name. |
||||||
|
|
||||||
|
--- |
||||||
|
configure.ac | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac |
||||||
|
index a00f2b6776..999e2d6d5d 100644 |
||||||
|
--- a/configure.ac |
||||||
|
+++ b/configure.ac |
||||||
|
@@ -107,7 +107,7 @@ RUBY_BASE_NAME=`echo ruby | sed "$program_transform_name"` |
||||||
|
RUBYW_BASE_NAME=`echo rubyw | sed "$program_transform_name"` |
||||||
|
AC_SUBST(RUBY_BASE_NAME) |
||||||
|
AC_SUBST(RUBYW_BASE_NAME) |
||||||
|
-AC_SUBST(RUBY_VERSION_NAME, '${RUBY_BASE_NAME}-${ruby_version}') |
||||||
|
+AC_SUBST(RUBY_VERSION_NAME, '${RUBY_BASE_NAME}-${ruby_version_dir_name}') |
||||||
|
|
||||||
|
dnl checks for alternative programs |
||||||
|
AC_CANONICAL_BUILD |
||||||
|
-- |
||||||
|
2.1.0 |
||||||
|
|
@ -0,0 +1,77 @@ |
|||||||
|
From eca084e4079c77c061045df9c21b219175b05228 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Mon, 6 Jan 2020 13:56:04 +0100 |
||||||
|
Subject: [PATCH] Initialize ABRT hook. |
||||||
|
|
||||||
|
The ABRT hook used to be initialized by preludes via patches [[1], [2]]. |
||||||
|
Unfortunately, due to [[3]] and especially since [[4]], this would |
||||||
|
require boostrapping [[5]]. |
||||||
|
|
||||||
|
To keep the things simple for now, load the ABRT hook via C. |
||||||
|
|
||||||
|
[1]: https://bugs.ruby-lang.org/issues/8566 |
||||||
|
[2]: https://bugs.ruby-lang.org/issues/15306 |
||||||
|
[3]: https://bugs.ruby-lang.org/issues/16254 |
||||||
|
[4]: https://github.com/ruby/ruby/pull/2735 |
||||||
|
[5]: https://lists.fedoraproject.org/archives/list/ruby-sig@lists.fedoraproject.org/message/LH6L6YJOYQT4Y5ZNOO4SLIPTUWZ5V45Q/ |
||||||
|
--- |
||||||
|
abrt.c | 12 ++++++++++++ |
||||||
|
common.mk | 3 ++- |
||||||
|
ruby.c | 4 ++++ |
||||||
|
3 files changed, 18 insertions(+), 1 deletion(-) |
||||||
|
create mode 100644 abrt.c |
||||||
|
|
||||||
|
diff --git a/abrt.c b/abrt.c |
||||||
|
new file mode 100644 |
||||||
|
index 0000000000..74b0bd5c0f |
||||||
|
--- /dev/null |
||||||
|
+++ b/abrt.c |
||||||
|
@@ -0,0 +1,12 @@ |
||||||
|
+#include "internal.h" |
||||||
|
+ |
||||||
|
+void |
||||||
|
+Init_abrt(void) |
||||||
|
+{ |
||||||
|
+ rb_eval_string( |
||||||
|
+ " begin\n" |
||||||
|
+ " require 'abrt'\n" |
||||||
|
+ " rescue LoadError\n" |
||||||
|
+ " end\n" |
||||||
|
+ ); |
||||||
|
+} |
||||||
|
diff --git a/common.mk b/common.mk |
||||||
|
index b2e5b2b6d0..f39f81da5c 100644 |
||||||
|
--- a/common.mk |
||||||
|
+++ b/common.mk |
||||||
|
@@ -81,7 +81,8 @@ ENC_MK = enc.mk |
||||||
|
MAKE_ENC = -f $(ENC_MK) V="$(V)" UNICODE_HDR_DIR="$(UNICODE_HDR_DIR)" \ |
||||||
|
RUBY="$(MINIRUBY)" MINIRUBY="$(MINIRUBY)" $(mflags) |
||||||
|
|
||||||
|
-COMMONOBJS = array.$(OBJEXT) \ |
||||||
|
+COMMONOBJS = abrt.$(OBJEXT) \ |
||||||
|
+ array.$(OBJEXT) \ |
||||||
|
ast.$(OBJEXT) \ |
||||||
|
bignum.$(OBJEXT) \ |
||||||
|
class.$(OBJEXT) \ |
||||||
|
diff --git a/ruby.c b/ruby.c |
||||||
|
index 60c57d6259..1eec16f2c8 100644 |
||||||
|
--- a/ruby.c |
||||||
|
+++ b/ruby.c |
||||||
|
@@ -1489,10 +1489,14 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt) |
||||||
|
|
||||||
|
void Init_builtin_features(void); |
||||||
|
|
||||||
|
+/* abrt.c */ |
||||||
|
+void Init_abrt(void); |
||||||
|
+ |
||||||
|
static void |
||||||
|
ruby_init_prelude(void) |
||||||
|
{ |
||||||
|
Init_builtin_features(); |
||||||
|
+ Init_abrt(); |
||||||
|
rb_const_remove(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX")); |
||||||
|
} |
||||||
|
|
||||||
|
-- |
||||||
|
2.24.1 |
||||||
|
|
@ -0,0 +1,34 @@ |
|||||||
|
From 9b42fce32bff25e0569581f76f532b9d57865aef Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Mon, 27 Jul 2020 14:56:05 +0200 |
||||||
|
Subject: [PATCH] Timeout the test_bug_reporter_add witout raising error. |
||||||
|
|
||||||
|
While timeouting the threads might be still good idea, it does not seems |
||||||
|
the timeout impacts the TestBugReporter#test_bug_reporter_add result, |
||||||
|
because the output of the child process has been already collected |
||||||
|
earlier. |
||||||
|
|
||||||
|
It seems that when the system is under heavy load, the thread might not |
||||||
|
be sheduled to finish its processing. Even finishing the child process |
||||||
|
might take tens of seconds and therefore the test case finish might take |
||||||
|
a while. |
||||||
|
--- |
||||||
|
test/-ext-/bug_reporter/test_bug_reporter.rb | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/test/-ext-/bug_reporter/test_bug_reporter.rb b/test/-ext-/bug_reporter/test_bug_reporter.rb |
||||||
|
index 628fcd0340..2c677cc8a7 100644 |
||||||
|
--- a/test/-ext-/bug_reporter/test_bug_reporter.rb |
||||||
|
+++ b/test/-ext-/bug_reporter/test_bug_reporter.rb |
||||||
|
@@ -21,7 +21,7 @@ def test_bug_reporter_add |
||||||
|
args = ["--disable-gems", "-r-test-/bug_reporter", |
||||||
|
"-C", tmpdir] |
||||||
|
stdin = "register_sample_bug_reporter(12345); Process.kill :SEGV, $$" |
||||||
|
- assert_in_out_err(args, stdin, [], expected_stderr, encoding: "ASCII-8BIT") |
||||||
|
+ assert_in_out_err(args, stdin, [], expected_stderr, encoding: "ASCII-8BIT", timeout_error: nil) |
||||||
|
ensure |
||||||
|
FileUtils.rm_rf(tmpdir) if tmpdir |
||||||
|
end |
||||||
|
-- |
||||||
|
2.27.0 |
||||||
|
|
@ -0,0 +1,84 @@ |
|||||||
|
From 202ff1372a40a8adf9aac74bfe8a39141b0c57e5 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Mon, 27 Sep 2021 00:38:38 +0900 |
||||||
|
Subject: [PATCH] ext/openssl/extconf.rb: require OpenSSL version >= 1.0.1, < 3 |
||||||
|
|
||||||
|
Ruby/OpenSSL 2.1.x and 2.2.x will not support OpenSSL 3.0 API. Let's |
||||||
|
make extconf.rb explicitly check the version number to be within the |
||||||
|
acceptable range, since it will not compile anyway. |
||||||
|
|
||||||
|
Reference: https://bugs.ruby-lang.org/issues/18192 |
||||||
|
--- |
||||||
|
ext/openssl/extconf.rb | 43 ++++++++++++++++++++++++------------------ |
||||||
|
1 file changed, 25 insertions(+), 18 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb |
||||||
|
index 264130bb..7e817ae2 100644 |
||||||
|
--- a/ext/openssl/extconf.rb |
||||||
|
+++ b/ext/openssl/extconf.rb |
||||||
|
@@ -33,9 +33,6 @@ |
||||||
|
have_library("ws2_32") |
||||||
|
end |
||||||
|
|
||||||
|
-Logging::message "=== Checking for required stuff... ===\n" |
||||||
|
-result = pkg_config("openssl") && have_header("openssl/ssl.h") |
||||||
|
- |
||||||
|
if $mingw |
||||||
|
append_cflags '-D_FORTIFY_SOURCE=2' |
||||||
|
append_ldflags '-fstack-protector' |
||||||
|
@@ -92,19 +89,33 @@ def find_openssl_library |
||||||
|
return false |
||||||
|
end |
||||||
|
|
||||||
|
-unless result |
||||||
|
- unless find_openssl_library |
||||||
|
- Logging::message "=== Checking for required stuff failed. ===\n" |
||||||
|
- Logging::message "Makefile wasn't created. Fix the errors above.\n" |
||||||
|
- raise "OpenSSL library could not be found. You might want to use " \ |
||||||
|
- "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \ |
||||||
|
- "is installed." |
||||||
|
- end |
||||||
|
+Logging::message "=== Checking for required stuff... ===\n" |
||||||
|
+pkg_config_found = pkg_config("openssl") && have_header("openssl/ssl.h") |
||||||
|
+ |
||||||
|
+if !pkg_config_found && !find_openssl_library |
||||||
|
+ Logging::message "=== Checking for required stuff failed. ===\n" |
||||||
|
+ Logging::message "Makefile wasn't created. Fix the errors above.\n" |
||||||
|
+ raise "OpenSSL library could not be found. You might want to use " \ |
||||||
|
+ "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \ |
||||||
|
+ "is installed." |
||||||
|
end |
||||||
|
|
||||||
|
-unless checking_for("OpenSSL version is 1.0.1 or later") { |
||||||
|
- try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") } |
||||||
|
- raise "OpenSSL >= 1.0.1 or LibreSSL is required" |
||||||
|
+version_ok = if have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h") |
||||||
|
+ is_libressl = true |
||||||
|
+ checking_for("LibreSSL version >= 2.5.0") { |
||||||
|
+ try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x20500000L", "openssl/opensslv.h") } |
||||||
|
+else |
||||||
|
+ checking_for("OpenSSL version >= 1.0.1 and < 3.0.0") { |
||||||
|
+ try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") && |
||||||
|
+ !try_static_assert("OPENSSL_VERSION_MAJOR >= 3", "openssl/opensslv.h") } |
||||||
|
+end |
||||||
|
+unless version_ok |
||||||
|
+ raise "OpenSSL >= 1.0.1, < 3.0.0 or LibreSSL >= 2.5.0 is required" |
||||||
|
+end |
||||||
|
+ |
||||||
|
+# Prevent wincrypt.h from being included, which defines conflicting macro with openssl/x509.h |
||||||
|
+if is_libressl && ($mswin || $mingw) |
||||||
|
+ $defs.push("-DNOCRYPT") |
||||||
|
end |
||||||
|
|
||||||
|
Logging::message "=== Checking for OpenSSL features... ===\n" |
||||||
|
@@ -116,10 +127,6 @@ def find_openssl_library |
||||||
|
have_func("ENGINE_load_#{name}()", "openssl/engine.h") |
||||||
|
} |
||||||
|
|
||||||
|
-if ($mswin || $mingw) && have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h") |
||||||
|
- $defs.push("-DNOCRYPT") |
||||||
|
-end |
||||||
|
- |
||||||
|
# added in 1.0.2 |
||||||
|
have_func("EC_curve_nist2nid") |
||||||
|
have_func("X509_REVOKED_dup") |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,630 @@ |
|||||||
|
From 316cb2a41f154e4663d7e7fead60cfc0bfa86af9 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Mon, 12 Apr 2021 13:55:10 +0900 |
||||||
|
Subject: [PATCH 1/2] pkey: do not check NULL argument in ossl_pkey_new() |
||||||
|
|
||||||
|
Passing NULL to ossl_pkey_new() makes no sense in the first place, and |
||||||
|
in fact it is ensured not to be NULL in all cases. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_pkey.c | 6 +----- |
||||||
|
ext/openssl/ossl_pkey.h | 1 + |
||||||
|
2 files changed, 2 insertions(+), 5 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c |
||||||
|
index f9f5162e..820e4a2c 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.c |
||||||
|
+++ b/ext/openssl/ossl_pkey.c |
||||||
|
@@ -38,12 +38,8 @@ static VALUE |
||||||
|
pkey_new0(EVP_PKEY *pkey) |
||||||
|
{ |
||||||
|
VALUE klass, obj; |
||||||
|
- int type; |
||||||
|
|
||||||
|
- if (!pkey || (type = EVP_PKEY_base_id(pkey)) == EVP_PKEY_NONE) |
||||||
|
- ossl_raise(rb_eRuntimeError, "pkey is empty"); |
||||||
|
- |
||||||
|
- switch (type) { |
||||||
|
+ switch (EVP_PKEY_base_id(pkey)) { |
||||||
|
#if !defined(OPENSSL_NO_RSA) |
||||||
|
case EVP_PKEY_RSA: klass = cRSA; break; |
||||||
|
#endif |
||||||
|
diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h |
||||||
|
index 4beede22..f0476780 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.h |
||||||
|
+++ b/ext/openssl/ossl_pkey.h |
||||||
|
@@ -35,6 +35,7 @@ extern const rb_data_type_t ossl_evp_pkey_type; |
||||||
|
} \ |
||||||
|
} while (0) |
||||||
|
|
||||||
|
+/* Takes ownership of the EVP_PKEY */ |
||||||
|
VALUE ossl_pkey_new(EVP_PKEY *); |
||||||
|
void ossl_pkey_check_public_key(const EVP_PKEY *); |
||||||
|
EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE); |
||||||
|
|
||||||
|
From 74f6c6175688502a5bf27ae35367616858630c0f Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Mon, 12 Apr 2021 18:32:40 +0900 |
||||||
|
Subject: [PATCH 2/2] pkey: allocate EVP_PKEY on #initialize |
||||||
|
|
||||||
|
Allocate an EVP_PKEY when the content is ready: when #initialize |
||||||
|
or #initialize_copy is called, rather than when a T_DATA is allocated. |
||||||
|
This is more natural because the lower level API has been deprecated |
||||||
|
and an EVP_PKEY is becoming the minimum unit of handling keys. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_pkey.c | 15 ++---- |
||||||
|
ext/openssl/ossl_pkey.h | 15 ++---- |
||||||
|
ext/openssl/ossl_pkey_dh.c | 71 +++++++++++++++++++-------- |
||||||
|
ext/openssl/ossl_pkey_dsa.c | 93 ++++++++++++++++++++--------------- |
||||||
|
ext/openssl/ossl_pkey_ec.c | 91 +++++++++++++++++++---------------- |
||||||
|
ext/openssl/ossl_pkey_rsa.c | 96 ++++++++++++++++++++++--------------- |
||||||
|
6 files changed, 218 insertions(+), 163 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c |
||||||
|
index 820e4a2c..ea75d63f 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.c |
||||||
|
+++ b/ext/openssl/ossl_pkey.c |
||||||
|
@@ -54,8 +54,8 @@ pkey_new0(EVP_PKEY *pkey) |
||||||
|
#endif |
||||||
|
default: klass = cPKey; break; |
||||||
|
} |
||||||
|
- obj = NewPKey(klass); |
||||||
|
- SetPKey(obj, pkey); |
||||||
|
+ obj = rb_obj_alloc(klass); |
||||||
|
+ RTYPEDDATA_DATA(obj) = pkey; |
||||||
|
return obj; |
||||||
|
} |
||||||
|
|
||||||
|
@@ -511,16 +511,7 @@ DupPKeyPtr(VALUE obj) |
||||||
|
static VALUE |
||||||
|
ossl_pkey_alloc(VALUE klass) |
||||||
|
{ |
||||||
|
- EVP_PKEY *pkey; |
||||||
|
- VALUE obj; |
||||||
|
- |
||||||
|
- obj = NewPKey(klass); |
||||||
|
- if (!(pkey = EVP_PKEY_new())) { |
||||||
|
- ossl_raise(ePKeyError, NULL); |
||||||
|
- } |
||||||
|
- SetPKey(obj, pkey); |
||||||
|
- |
||||||
|
- return obj; |
||||||
|
+ return TypedData_Wrap_Struct(klass, &ossl_evp_pkey_type, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h |
||||||
|
index f0476780..ed18bc69 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.h |
||||||
|
+++ b/ext/openssl/ossl_pkey.h |
||||||
|
@@ -15,19 +15,10 @@ extern VALUE cPKey; |
||||||
|
extern VALUE ePKeyError; |
||||||
|
extern const rb_data_type_t ossl_evp_pkey_type; |
||||||
|
|
||||||
|
-#define OSSL_PKEY_SET_PRIVATE(obj) rb_iv_set((obj), "private", Qtrue) |
||||||
|
-#define OSSL_PKEY_SET_PUBLIC(obj) rb_iv_set((obj), "private", Qfalse) |
||||||
|
-#define OSSL_PKEY_IS_PRIVATE(obj) (rb_iv_get((obj), "private") == Qtrue) |
||||||
|
+/* For ENGINE */ |
||||||
|
+#define OSSL_PKEY_SET_PRIVATE(obj) rb_ivar_set((obj), rb_intern("private"), Qtrue) |
||||||
|
+#define OSSL_PKEY_IS_PRIVATE(obj) (rb_attr_get((obj), rb_intern("private")) == Qtrue) |
||||||
|
|
||||||
|
-#define NewPKey(klass) \ |
||||||
|
- TypedData_Wrap_Struct((klass), &ossl_evp_pkey_type, 0) |
||||||
|
-#define SetPKey(obj, pkey) do { \ |
||||||
|
- if (!(pkey)) { \ |
||||||
|
- rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!"); \ |
||||||
|
- } \ |
||||||
|
- RTYPEDDATA_DATA(obj) = (pkey); \ |
||||||
|
- OSSL_PKEY_SET_PUBLIC(obj); \ |
||||||
|
-} while (0) |
||||||
|
#define GetPKey(obj, pkey) do {\ |
||||||
|
TypedData_Get_Struct((obj), EVP_PKEY, &ossl_evp_pkey_type, (pkey)); \ |
||||||
|
if (!(pkey)) { \ |
||||||
|
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c |
||||||
|
index ca782bbe..04c11b21 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_dh.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_dh.c |
||||||
|
@@ -72,34 +72,57 @@ static VALUE |
||||||
|
ossl_dh_initialize(int argc, VALUE *argv, VALUE self) |
||||||
|
{ |
||||||
|
EVP_PKEY *pkey; |
||||||
|
+ int type; |
||||||
|
DH *dh; |
||||||
|
- BIO *in; |
||||||
|
+ BIO *in = NULL; |
||||||
|
VALUE arg; |
||||||
|
|
||||||
|
- GetPKey(self, pkey); |
||||||
|
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); |
||||||
|
+ if (pkey) |
||||||
|
+ rb_raise(rb_eTypeError, "pkey already initialized"); |
||||||
|
+ |
||||||
|
/* The DH.new(size, generator) form is handled by lib/openssl/pkey.rb */ |
||||||
|
if (rb_scan_args(argc, argv, "01", &arg) == 0) { |
||||||
|
dh = DH_new(); |
||||||
|
if (!dh) |
||||||
|
ossl_raise(eDHError, "DH_new"); |
||||||
|
+ goto legacy; |
||||||
|
} |
||||||
|
- else { |
||||||
|
- arg = ossl_to_der_if_possible(arg); |
||||||
|
- in = ossl_obj2bio(&arg); |
||||||
|
- dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); |
||||||
|
- if (!dh){ |
||||||
|
- OSSL_BIO_reset(in); |
||||||
|
- dh = d2i_DHparams_bio(in, NULL); |
||||||
|
- } |
||||||
|
- BIO_free(in); |
||||||
|
- if (!dh) { |
||||||
|
- ossl_raise(eDHError, NULL); |
||||||
|
- } |
||||||
|
+ |
||||||
|
+ arg = ossl_to_der_if_possible(arg); |
||||||
|
+ in = ossl_obj2bio(&arg); |
||||||
|
+ |
||||||
|
+ /* |
||||||
|
+ * On OpenSSL <= 1.1.1 and current versions of LibreSSL, the generic |
||||||
|
+ * routine does not support DER-encoded parameters |
||||||
|
+ */ |
||||||
|
+ dh = d2i_DHparams_bio(in, NULL); |
||||||
|
+ if (dh) |
||||||
|
+ goto legacy; |
||||||
|
+ OSSL_BIO_reset(in); |
||||||
|
+ |
||||||
|
+ pkey = ossl_pkey_read_generic(in, Qnil); |
||||||
|
+ BIO_free(in); |
||||||
|
+ if (!pkey) |
||||||
|
+ ossl_raise(eDHError, "could not parse pkey"); |
||||||
|
+ |
||||||
|
+ type = EVP_PKEY_base_id(pkey); |
||||||
|
+ if (type != EVP_PKEY_DH) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
+ rb_raise(eDHError, "incorrect pkey type: %s", OBJ_nid2sn(type)); |
||||||
|
} |
||||||
|
- if (!EVP_PKEY_assign_DH(pkey, dh)) { |
||||||
|
- DH_free(dh); |
||||||
|
- ossl_raise(eDHError, NULL); |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
+ return self; |
||||||
|
+ |
||||||
|
+ legacy: |
||||||
|
+ BIO_free(in); |
||||||
|
+ pkey = EVP_PKEY_new(); |
||||||
|
+ if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
+ DH_free(dh); |
||||||
|
+ ossl_raise(eDHError, "EVP_PKEY_assign_DH"); |
||||||
|
} |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
@@ -110,15 +133,14 @@ ossl_dh_initialize_copy(VALUE self, VALUE other) |
||||||
|
DH *dh, *dh_other; |
||||||
|
const BIGNUM *pub, *priv; |
||||||
|
|
||||||
|
- GetPKey(self, pkey); |
||||||
|
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) |
||||||
|
- ossl_raise(eDHError, "DH already initialized"); |
||||||
|
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); |
||||||
|
+ if (pkey) |
||||||
|
+ rb_raise(rb_eTypeError, "pkey already initialized"); |
||||||
|
GetDH(other, dh_other); |
||||||
|
|
||||||
|
dh = DHparams_dup(dh_other); |
||||||
|
if (!dh) |
||||||
|
ossl_raise(eDHError, "DHparams_dup"); |
||||||
|
- EVP_PKEY_assign_DH(pkey, dh); |
||||||
|
|
||||||
|
DH_get0_key(dh_other, &pub, &priv); |
||||||
|
if (pub) { |
||||||
|
@@ -133,6 +155,13 @@ ossl_dh_initialize_copy(VALUE self, VALUE other) |
||||||
|
DH_set0_key(dh, pub2, priv2); |
||||||
|
} |
||||||
|
|
||||||
|
+ pkey = EVP_PKEY_new(); |
||||||
|
+ if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
+ DH_free(dh); |
||||||
|
+ ossl_raise(eDHError, "EVP_PKEY_assign_DH"); |
||||||
|
+ } |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c |
||||||
|
index 7af00eeb..15724548 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_dsa.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_dsa.c |
||||||
|
@@ -83,50 +83,59 @@ VALUE eDSAError; |
||||||
|
static VALUE |
||||||
|
ossl_dsa_initialize(int argc, VALUE *argv, VALUE self) |
||||||
|
{ |
||||||
|
- EVP_PKEY *pkey, *tmp; |
||||||
|
- DSA *dsa = NULL; |
||||||
|
- BIO *in; |
||||||
|
+ EVP_PKEY *pkey; |
||||||
|
+ DSA *dsa; |
||||||
|
+ BIO *in = NULL; |
||||||
|
VALUE arg, pass; |
||||||
|
+ int type; |
||||||
|
+ |
||||||
|
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); |
||||||
|
+ if (pkey) |
||||||
|
+ rb_raise(rb_eTypeError, "pkey already initialized"); |
||||||
|
|
||||||
|
- GetPKey(self, pkey); |
||||||
|
/* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ |
||||||
|
rb_scan_args(argc, argv, "02", &arg, &pass); |
||||||
|
if (argc == 0) { |
||||||
|
dsa = DSA_new(); |
||||||
|
if (!dsa) |
||||||
|
ossl_raise(eDSAError, "DSA_new"); |
||||||
|
+ goto legacy; |
||||||
|
} |
||||||
|
- else { |
||||||
|
- pass = ossl_pem_passwd_value(pass); |
||||||
|
- arg = ossl_to_der_if_possible(arg); |
||||||
|
- in = ossl_obj2bio(&arg); |
||||||
|
- |
||||||
|
- tmp = ossl_pkey_read_generic(in, pass); |
||||||
|
- if (tmp) { |
||||||
|
- if (EVP_PKEY_base_id(tmp) != EVP_PKEY_DSA) |
||||||
|
- rb_raise(eDSAError, "incorrect pkey type: %s", |
||||||
|
- OBJ_nid2sn(EVP_PKEY_base_id(tmp))); |
||||||
|
- dsa = EVP_PKEY_get1_DSA(tmp); |
||||||
|
- EVP_PKEY_free(tmp); |
||||||
|
- } |
||||||
|
- if (!dsa) { |
||||||
|
- OSSL_BIO_reset(in); |
||||||
|
-#define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \ |
||||||
|
- (d2i_of_void *)d2i_DSAPublicKey, PEM_STRING_DSA_PUBLIC, (bp), (void **)(x), (cb), (u)) |
||||||
|
- dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL); |
||||||
|
-#undef PEM_read_bio_DSAPublicKey |
||||||
|
- } |
||||||
|
- BIO_free(in); |
||||||
|
- if (!dsa) { |
||||||
|
- ossl_clear_error(); |
||||||
|
- ossl_raise(eDSAError, "Neither PUB key nor PRIV key"); |
||||||
|
- } |
||||||
|
- } |
||||||
|
- if (!EVP_PKEY_assign_DSA(pkey, dsa)) { |
||||||
|
- DSA_free(dsa); |
||||||
|
- ossl_raise(eDSAError, NULL); |
||||||
|
+ |
||||||
|
+ pass = ossl_pem_passwd_value(pass); |
||||||
|
+ arg = ossl_to_der_if_possible(arg); |
||||||
|
+ in = ossl_obj2bio(&arg); |
||||||
|
+ |
||||||
|
+ /* DER-encoded DSAPublicKey format isn't supported by the generic routine */ |
||||||
|
+ dsa = (DSA *)PEM_ASN1_read_bio((d2i_of_void *)d2i_DSAPublicKey, |
||||||
|
+ PEM_STRING_DSA_PUBLIC, |
||||||
|
+ in, NULL, NULL, NULL); |
||||||
|
+ if (dsa) |
||||||
|
+ goto legacy; |
||||||
|
+ OSSL_BIO_reset(in); |
||||||
|
+ |
||||||
|
+ pkey = ossl_pkey_read_generic(in, pass); |
||||||
|
+ BIO_free(in); |
||||||
|
+ if (!pkey) |
||||||
|
+ ossl_raise(eDSAError, "Neither PUB key nor PRIV key"); |
||||||
|
+ |
||||||
|
+ type = EVP_PKEY_base_id(pkey); |
||||||
|
+ if (type != EVP_PKEY_DSA) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
+ rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type)); |
||||||
|
} |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
+ return self; |
||||||
|
|
||||||
|
+ legacy: |
||||||
|
+ BIO_free(in); |
||||||
|
+ pkey = EVP_PKEY_new(); |
||||||
|
+ if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa) != 1) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
+ DSA_free(dsa); |
||||||
|
+ ossl_raise(eDSAError, "EVP_PKEY_assign_DSA"); |
||||||
|
+ } |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
@@ -136,16 +145,24 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other) |
||||||
|
EVP_PKEY *pkey; |
||||||
|
DSA *dsa, *dsa_new; |
||||||
|
|
||||||
|
- GetPKey(self, pkey); |
||||||
|
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) |
||||||
|
- ossl_raise(eDSAError, "DSA already initialized"); |
||||||
|
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); |
||||||
|
+ if (pkey) |
||||||
|
+ rb_raise(rb_eTypeError, "pkey already initialized"); |
||||||
|
GetDSA(other, dsa); |
||||||
|
|
||||||
|
- dsa_new = ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, (d2i_of_void *)d2i_DSAPrivateKey, (char *)dsa); |
||||||
|
+ dsa_new = (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, |
||||||
|
+ (d2i_of_void *)d2i_DSAPrivateKey, |
||||||
|
+ (char *)dsa); |
||||||
|
if (!dsa_new) |
||||||
|
ossl_raise(eDSAError, "ASN1_dup"); |
||||||
|
|
||||||
|
- EVP_PKEY_assign_DSA(pkey, dsa_new); |
||||||
|
+ pkey = EVP_PKEY_new(); |
||||||
|
+ if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa_new) != 1) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
+ DSA_free(dsa_new); |
||||||
|
+ ossl_raise(eDSAError, "EVP_PKEY_assign_DSA"); |
||||||
|
+ } |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
|
||||||
|
return self; |
||||||
|
} |
||||||
|
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c |
||||||
|
index db80d112..71e63969 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_ec.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_ec.c |
||||||
|
@@ -114,13 +114,16 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg) |
||||||
|
VALUE obj; |
||||||
|
|
||||||
|
obj = rb_obj_alloc(klass); |
||||||
|
- GetPKey(obj, pkey); |
||||||
|
|
||||||
|
ec = ec_key_new_from_group(arg); |
||||||
|
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { |
||||||
|
+ pkey = EVP_PKEY_new(); |
||||||
|
+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
EC_KEY_free(ec); |
||||||
|
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); |
||||||
|
} |
||||||
|
+ RTYPEDDATA_DATA(obj) = pkey; |
||||||
|
+ |
||||||
|
if (!EC_KEY_generate_key(ec)) |
||||||
|
ossl_raise(eECError, "EC_KEY_generate_key"); |
||||||
|
|
||||||
|
@@ -141,51 +144,54 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg) |
||||||
|
static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) |
||||||
|
{ |
||||||
|
EVP_PKEY *pkey; |
||||||
|
- EC_KEY *ec = NULL; |
||||||
|
+ EC_KEY *ec; |
||||||
|
+ BIO *in; |
||||||
|
VALUE arg, pass; |
||||||
|
+ int type; |
||||||
|
|
||||||
|
- GetPKey(self, pkey); |
||||||
|
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) |
||||||
|
- ossl_raise(eECError, "EC_KEY already initialized"); |
||||||
|
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); |
||||||
|
+ if (pkey) |
||||||
|
+ rb_raise(rb_eTypeError, "pkey already initialized"); |
||||||
|
|
||||||
|
rb_scan_args(argc, argv, "02", &arg, &pass); |
||||||
|
- |
||||||
|
if (NIL_P(arg)) { |
||||||
|
if (!(ec = EC_KEY_new())) |
||||||
|
- ossl_raise(eECError, NULL); |
||||||
|
- } else if (rb_obj_is_kind_of(arg, cEC)) { |
||||||
|
- EC_KEY *other_ec = NULL; |
||||||
|
+ ossl_raise(eECError, "EC_KEY_new"); |
||||||
|
+ goto legacy; |
||||||
|
+ } |
||||||
|
+ else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { |
||||||
|
+ ec = ec_key_new_from_group(arg); |
||||||
|
+ goto legacy; |
||||||
|
+ } |
||||||
|
|
||||||
|
- GetEC(arg, other_ec); |
||||||
|
- if (!(ec = EC_KEY_dup(other_ec))) |
||||||
|
- ossl_raise(eECError, NULL); |
||||||
|
- } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { |
||||||
|
- ec = ec_key_new_from_group(arg); |
||||||
|
- } else { |
||||||
|
- BIO *in = ossl_obj2bio(&arg); |
||||||
|
- EVP_PKEY *tmp; |
||||||
|
- pass = ossl_pem_passwd_value(pass); |
||||||
|
- tmp = ossl_pkey_read_generic(in, pass); |
||||||
|
- if (tmp) { |
||||||
|
- if (EVP_PKEY_base_id(tmp) != EVP_PKEY_EC) |
||||||
|
- rb_raise(eECError, "incorrect pkey type: %s", |
||||||
|
- OBJ_nid2sn(EVP_PKEY_base_id(tmp))); |
||||||
|
- ec = EVP_PKEY_get1_EC_KEY(tmp); |
||||||
|
- EVP_PKEY_free(tmp); |
||||||
|
- } |
||||||
|
- BIO_free(in); |
||||||
|
+ pass = ossl_pem_passwd_value(pass); |
||||||
|
+ arg = ossl_to_der_if_possible(arg); |
||||||
|
+ in = ossl_obj2bio(&arg); |
||||||
|
|
||||||
|
- if (!ec) { |
||||||
|
- ossl_clear_error(); |
||||||
|
- ec = ec_key_new_from_group(arg); |
||||||
|
- } |
||||||
|
+ pkey = ossl_pkey_read_generic(in, pass); |
||||||
|
+ BIO_free(in); |
||||||
|
+ if (!pkey) { |
||||||
|
+ ossl_clear_error(); |
||||||
|
+ ec = ec_key_new_from_group(arg); |
||||||
|
+ goto legacy; |
||||||
|
} |
||||||
|
|
||||||
|
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { |
||||||
|
- EC_KEY_free(ec); |
||||||
|
- ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); |
||||||
|
+ type = EVP_PKEY_base_id(pkey); |
||||||
|
+ if (type != EVP_PKEY_EC) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
+ rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type)); |
||||||
|
} |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
+ return self; |
||||||
|
|
||||||
|
+ legacy: |
||||||
|
+ pkey = EVP_PKEY_new(); |
||||||
|
+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
+ EC_KEY_free(ec); |
||||||
|
+ ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); |
||||||
|
+ } |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
@@ -195,18 +201,21 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other) |
||||||
|
EVP_PKEY *pkey; |
||||||
|
EC_KEY *ec, *ec_new; |
||||||
|
|
||||||
|
- GetPKey(self, pkey); |
||||||
|
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) |
||||||
|
- ossl_raise(eECError, "EC already initialized"); |
||||||
|
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); |
||||||
|
+ if (pkey) |
||||||
|
+ rb_raise(rb_eTypeError, "pkey already initialized"); |
||||||
|
GetEC(other, ec); |
||||||
|
|
||||||
|
ec_new = EC_KEY_dup(ec); |
||||||
|
if (!ec_new) |
||||||
|
ossl_raise(eECError, "EC_KEY_dup"); |
||||||
|
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) { |
||||||
|
- EC_KEY_free(ec_new); |
||||||
|
- ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); |
||||||
|
+ |
||||||
|
+ pkey = EVP_PKEY_new(); |
||||||
|
+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec_new) != 1) { |
||||||
|
+ EC_KEY_free(ec_new); |
||||||
|
+ ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); |
||||||
|
} |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
|
||||||
|
return self; |
||||||
|
} |
||||||
|
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c |
||||||
|
index 8ebd3ec5..b8dbc0e1 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_rsa.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_rsa.c |
||||||
|
@@ -76,51 +76,62 @@ VALUE eRSAError; |
||||||
|
static VALUE |
||||||
|
ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) |
||||||
|
{ |
||||||
|
- EVP_PKEY *pkey, *tmp; |
||||||
|
- RSA *rsa = NULL; |
||||||
|
- BIO *in; |
||||||
|
+ EVP_PKEY *pkey; |
||||||
|
+ RSA *rsa; |
||||||
|
+ BIO *in = NULL; |
||||||
|
VALUE arg, pass; |
||||||
|
+ int type; |
||||||
|
+ |
||||||
|
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); |
||||||
|
+ if (pkey) |
||||||
|
+ rb_raise(rb_eTypeError, "pkey already initialized"); |
||||||
|
|
||||||
|
- GetPKey(self, pkey); |
||||||
|
/* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ |
||||||
|
rb_scan_args(argc, argv, "02", &arg, &pass); |
||||||
|
if (argc == 0) { |
||||||
|
rsa = RSA_new(); |
||||||
|
if (!rsa) |
||||||
|
ossl_raise(eRSAError, "RSA_new"); |
||||||
|
+ goto legacy; |
||||||
|
} |
||||||
|
- else { |
||||||
|
- pass = ossl_pem_passwd_value(pass); |
||||||
|
- arg = ossl_to_der_if_possible(arg); |
||||||
|
- in = ossl_obj2bio(&arg); |
||||||
|
- |
||||||
|
- tmp = ossl_pkey_read_generic(in, pass); |
||||||
|
- if (tmp) { |
||||||
|
- if (EVP_PKEY_base_id(tmp) != EVP_PKEY_RSA) |
||||||
|
- rb_raise(eRSAError, "incorrect pkey type: %s", |
||||||
|
- OBJ_nid2sn(EVP_PKEY_base_id(tmp))); |
||||||
|
- rsa = EVP_PKEY_get1_RSA(tmp); |
||||||
|
- EVP_PKEY_free(tmp); |
||||||
|
- } |
||||||
|
- if (!rsa) { |
||||||
|
- OSSL_BIO_reset(in); |
||||||
|
- rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); |
||||||
|
- } |
||||||
|
- if (!rsa) { |
||||||
|
- OSSL_BIO_reset(in); |
||||||
|
- rsa = d2i_RSAPublicKey_bio(in, NULL); |
||||||
|
- } |
||||||
|
- BIO_free(in); |
||||||
|
- if (!rsa) { |
||||||
|
- ossl_clear_error(); |
||||||
|
- ossl_raise(eRSAError, "Neither PUB key nor PRIV key"); |
||||||
|
- } |
||||||
|
- } |
||||||
|
- if (!EVP_PKEY_assign_RSA(pkey, rsa)) { |
||||||
|
- RSA_free(rsa); |
||||||
|
- ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); |
||||||
|
+ |
||||||
|
+ pass = ossl_pem_passwd_value(pass); |
||||||
|
+ arg = ossl_to_der_if_possible(arg); |
||||||
|
+ in = ossl_obj2bio(&arg); |
||||||
|
+ |
||||||
|
+ /* First try RSAPublicKey format */ |
||||||
|
+ rsa = d2i_RSAPublicKey_bio(in, NULL); |
||||||
|
+ if (rsa) |
||||||
|
+ goto legacy; |
||||||
|
+ OSSL_BIO_reset(in); |
||||||
|
+ rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); |
||||||
|
+ if (rsa) |
||||||
|
+ goto legacy; |
||||||
|
+ OSSL_BIO_reset(in); |
||||||
|
+ |
||||||
|
+ /* Use the generic routine */ |
||||||
|
+ pkey = ossl_pkey_read_generic(in, pass); |
||||||
|
+ BIO_free(in); |
||||||
|
+ if (!pkey) |
||||||
|
+ ossl_raise(eRSAError, "Neither PUB key nor PRIV key"); |
||||||
|
+ |
||||||
|
+ type = EVP_PKEY_base_id(pkey); |
||||||
|
+ if (type != EVP_PKEY_RSA) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
+ rb_raise(eRSAError, "incorrect pkey type: %s", OBJ_nid2sn(type)); |
||||||
|
} |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
+ return self; |
||||||
|
|
||||||
|
+ legacy: |
||||||
|
+ BIO_free(in); |
||||||
|
+ pkey = EVP_PKEY_new(); |
||||||
|
+ if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa) != 1) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
+ RSA_free(rsa); |
||||||
|
+ ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); |
||||||
|
+ } |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
@@ -130,16 +141,23 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other) |
||||||
|
EVP_PKEY *pkey; |
||||||
|
RSA *rsa, *rsa_new; |
||||||
|
|
||||||
|
- GetPKey(self, pkey); |
||||||
|
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) |
||||||
|
- ossl_raise(eRSAError, "RSA already initialized"); |
||||||
|
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); |
||||||
|
+ if (pkey) |
||||||
|
+ rb_raise(rb_eTypeError, "pkey already initialized"); |
||||||
|
GetRSA(other, rsa); |
||||||
|
|
||||||
|
- rsa_new = ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, (d2i_of_void *)d2i_RSAPrivateKey, (char *)rsa); |
||||||
|
+ rsa_new = (RSA *)ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, |
||||||
|
+ (d2i_of_void *)d2i_RSAPrivateKey, |
||||||
|
+ (char *)rsa); |
||||||
|
if (!rsa_new) |
||||||
|
ossl_raise(eRSAError, "ASN1_dup"); |
||||||
|
|
||||||
|
- EVP_PKEY_assign_RSA(pkey, rsa_new); |
||||||
|
+ pkey = EVP_PKEY_new(); |
||||||
|
+ if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa_new) != 1) { |
||||||
|
+ RSA_free(rsa_new); |
||||||
|
+ ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); |
||||||
|
+ } |
||||||
|
+ RTYPEDDATA_DATA(self) = pkey; |
||||||
|
|
||||||
|
return self; |
||||||
|
} |
||||||
|
|
@ -0,0 +1,358 @@ |
|||||||
|
From f2cf3afc6fa1e13e960f732c0bc658ad408ee219 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Fri, 12 Jun 2020 14:12:59 +0900 |
||||||
|
Subject: [PATCH 1/3] pkey: fix potential memory leak in PKey#sign |
||||||
|
|
||||||
|
Fix potential leak of EVP_MD_CTX object in an error path. This path is |
||||||
|
normally unreachable, since the size of a signature generated by any |
||||||
|
supported algorithms would not be larger than LONG_MAX. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_pkey.c | 8 ++++++-- |
||||||
|
1 file changed, 6 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c |
||||||
|
index df8b425a0f..7488190e0e 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.c |
||||||
|
+++ b/ext/openssl/ossl_pkey.c |
||||||
|
@@ -777,8 +777,10 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) |
||||||
|
EVP_MD_CTX_free(ctx); |
||||||
|
ossl_raise(ePKeyError, "EVP_DigestSign"); |
||||||
|
} |
||||||
|
- if (siglen > LONG_MAX) |
||||||
|
+ if (siglen > LONG_MAX) { |
||||||
|
+ EVP_MD_CTX_free(ctx); |
||||||
|
rb_raise(ePKeyError, "signature would be too large"); |
||||||
|
+ } |
||||||
|
sig = ossl_str_new(NULL, (long)siglen, &state); |
||||||
|
if (state) { |
||||||
|
EVP_MD_CTX_free(ctx); |
||||||
|
@@ -799,8 +801,10 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) |
||||||
|
EVP_MD_CTX_free(ctx); |
||||||
|
ossl_raise(ePKeyError, "EVP_DigestSignFinal"); |
||||||
|
} |
||||||
|
- if (siglen > LONG_MAX) |
||||||
|
+ if (siglen > LONG_MAX) { |
||||||
|
+ EVP_MD_CTX_free(ctx); |
||||||
|
rb_raise(ePKeyError, "signature would be too large"); |
||||||
|
+ } |
||||||
|
sig = ossl_str_new(NULL, (long)siglen, &state); |
||||||
|
if (state) { |
||||||
|
EVP_MD_CTX_free(ctx); |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
||||||
|
|
||||||
|
From 8b30ce20eb9e03180c28288e29a96308e594f860 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Fri, 2 Apr 2021 23:58:48 +0900 |
||||||
|
Subject: [PATCH 2/3] pkey: prepare pkey_ctx_apply_options() for usage by other |
||||||
|
operations |
||||||
|
|
||||||
|
The routine to apply Hash to EVP_PKEY_CTX_ctrl_str() is currently used |
||||||
|
by key generation, but it is useful for other operations too. Let's |
||||||
|
change it to a slightly more generic name. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_pkey.c | 22 ++++++++++++++-------- |
||||||
|
1 file changed, 14 insertions(+), 8 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c |
||||||
|
index 7488190e0e..fed4a2b81f 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.c |
||||||
|
+++ b/ext/openssl/ossl_pkey.c |
||||||
|
@@ -198,7 +198,7 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self) |
||||||
|
} |
||||||
|
|
||||||
|
static VALUE |
||||||
|
-pkey_gen_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v)) |
||||||
|
+pkey_ctx_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v)) |
||||||
|
{ |
||||||
|
VALUE key = rb_ary_entry(i, 0), value = rb_ary_entry(i, 1); |
||||||
|
EVP_PKEY_CTX *ctx = (EVP_PKEY_CTX *)ctx_v; |
||||||
|
@@ -214,15 +214,25 @@ pkey_gen_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v)) |
||||||
|
} |
||||||
|
|
||||||
|
static VALUE |
||||||
|
-pkey_gen_apply_options0(VALUE args_v) |
||||||
|
+pkey_ctx_apply_options0(VALUE args_v) |
||||||
|
{ |
||||||
|
VALUE *args = (VALUE *)args_v; |
||||||
|
|
||||||
|
rb_block_call(args[1], rb_intern("each"), 0, NULL, |
||||||
|
- pkey_gen_apply_options_i, args[0]); |
||||||
|
+ pkey_ctx_apply_options_i, args[0]); |
||||||
|
return Qnil; |
||||||
|
} |
||||||
|
|
||||||
|
+static void |
||||||
|
+pkey_ctx_apply_options(EVP_PKEY_CTX *ctx, VALUE options, int *state) |
||||||
|
+{ |
||||||
|
+ VALUE args[2]; |
||||||
|
+ args[0] = (VALUE)ctx; |
||||||
|
+ args[1] = options; |
||||||
|
+ |
||||||
|
+ rb_protect(pkey_ctx_apply_options0, (VALUE)args, state); |
||||||
|
+} |
||||||
|
+ |
||||||
|
struct pkey_blocking_generate_arg { |
||||||
|
EVP_PKEY_CTX *ctx; |
||||||
|
EVP_PKEY *pkey; |
||||||
|
@@ -330,11 +340,7 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam) |
||||||
|
} |
||||||
|
|
||||||
|
if (!NIL_P(options)) { |
||||||
|
- VALUE args[2]; |
||||||
|
- |
||||||
|
- args[0] = (VALUE)ctx; |
||||||
|
- args[1] = options; |
||||||
|
- rb_protect(pkey_gen_apply_options0, (VALUE)args, &state); |
||||||
|
+ pkey_ctx_apply_options(ctx, options, &state); |
||||||
|
if (state) { |
||||||
|
EVP_PKEY_CTX_free(ctx); |
||||||
|
rb_jump_tag(state); |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
||||||
|
|
||||||
|
From 4c7b0f91da666961d11908b94520db4e09ce4e67 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Sat, 18 Jul 2020 20:40:39 +0900 |
||||||
|
Subject: [PATCH 3/3] pkey: allow setting algorithm-specific options in #sign |
||||||
|
and #verify |
||||||
|
|
||||||
|
Similarly to OpenSSL::PKey.generate_key and .generate_parameters, let |
||||||
|
OpenSSL::PKey::PKey#sign and #verify take an optional parameter for |
||||||
|
specifying control strings for EVP_PKEY_CTX_ctrl_str(). |
||||||
|
--- |
||||||
|
ext/openssl/ossl_pkey.c | 113 ++++++++++++++++++++++------------ |
||||||
|
test/openssl/test_pkey_rsa.rb | 34 +++++----- |
||||||
|
2 files changed, 89 insertions(+), 58 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c |
||||||
|
index fed4a2b81f..22e9f19982 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.c |
||||||
|
+++ b/ext/openssl/ossl_pkey.c |
||||||
|
@@ -739,33 +739,51 @@ ossl_pkey_public_to_pem(VALUE self) |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
- * call-seq: |
||||||
|
- * pkey.sign(digest, data) -> String |
||||||
|
+ * call-seq: |
||||||
|
+ * pkey.sign(digest, data [, options]) -> string |
||||||
|
* |
||||||
|
- * To sign the String _data_, _digest_, an instance of OpenSSL::Digest, must |
||||||
|
- * be provided. The return value is again a String containing the signature. |
||||||
|
- * A PKeyError is raised should errors occur. |
||||||
|
- * Any previous state of the Digest instance is irrelevant to the signature |
||||||
|
- * outcome, the digest instance is reset to its initial state during the |
||||||
|
- * operation. |
||||||
|
+ * Hashes and signs the +data+ using a message digest algorithm +digest+ and |
||||||
|
+ * a private key +pkey+. |
||||||
|
* |
||||||
|
- * == Example |
||||||
|
- * data = 'Sign me!' |
||||||
|
- * digest = OpenSSL::Digest.new('SHA256') |
||||||
|
- * pkey = OpenSSL::PKey::RSA.new(2048) |
||||||
|
- * signature = pkey.sign(digest, data) |
||||||
|
+ * See #verify for the verification operation. |
||||||
|
+ * |
||||||
|
+ * See also the man page EVP_DigestSign(3). |
||||||
|
+ * |
||||||
|
+ * +digest+:: |
||||||
|
+ * A String that represents the message digest algorithm name, or +nil+ |
||||||
|
+ * if the PKey type requires no digest algorithm. |
||||||
|
+ * For backwards compatibility, this can be an instance of OpenSSL::Digest. |
||||||
|
+ * Its state will not affect the signature. |
||||||
|
+ * +data+:: |
||||||
|
+ * A String. The data to be hashed and signed. |
||||||
|
+ * +options+:: |
||||||
|
+ * A Hash that contains algorithm specific control operations to \OpenSSL. |
||||||
|
+ * See OpenSSL's man page EVP_PKEY_CTX_ctrl_str(3) for details. |
||||||
|
+ * +options+ parameter was added in version 2.3. |
||||||
|
+ * |
||||||
|
+ * Example: |
||||||
|
+ * data = "Sign me!" |
||||||
|
+ * pkey = OpenSSL::PKey.generate_key("RSA", rsa_keygen_bits: 2048) |
||||||
|
+ * signopts = { rsa_padding_mode: "pss" } |
||||||
|
+ * signature = pkey.sign("SHA256", data, signopts) |
||||||
|
+ * |
||||||
|
+ * # Creates a copy of the RSA key pkey, but without the private components |
||||||
|
+ * pub_key = pkey.public_key |
||||||
|
+ * puts pub_key.verify("SHA256", signature, data, signopts) # => true |
||||||
|
*/ |
||||||
|
static VALUE |
||||||
|
-ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) |
||||||
|
+ossl_pkey_sign(int argc, VALUE *argv, VALUE self) |
||||||
|
{ |
||||||
|
EVP_PKEY *pkey; |
||||||
|
+ VALUE digest, data, options, sig; |
||||||
|
const EVP_MD *md = NULL; |
||||||
|
EVP_MD_CTX *ctx; |
||||||
|
+ EVP_PKEY_CTX *pctx; |
||||||
|
size_t siglen; |
||||||
|
int state; |
||||||
|
- VALUE sig; |
||||||
|
|
||||||
|
pkey = GetPrivPKeyPtr(self); |
||||||
|
+ rb_scan_args(argc, argv, "21", &digest, &data, &options); |
||||||
|
if (!NIL_P(digest)) |
||||||
|
md = ossl_evp_get_digestbyname(digest); |
||||||
|
StringValue(data); |
||||||
|
@@ -773,10 +791,17 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) |
||||||
|
ctx = EVP_MD_CTX_new(); |
||||||
|
if (!ctx) |
||||||
|
ossl_raise(ePKeyError, "EVP_MD_CTX_new"); |
||||||
|
- if (EVP_DigestSignInit(ctx, NULL, md, /* engine */NULL, pkey) < 1) { |
||||||
|
+ if (EVP_DigestSignInit(ctx, &pctx, md, /* engine */NULL, pkey) < 1) { |
||||||
|
EVP_MD_CTX_free(ctx); |
||||||
|
ossl_raise(ePKeyError, "EVP_DigestSignInit"); |
||||||
|
} |
||||||
|
+ if (!NIL_P(options)) { |
||||||
|
+ pkey_ctx_apply_options(pctx, options, &state); |
||||||
|
+ if (state) { |
||||||
|
+ EVP_MD_CTX_free(ctx); |
||||||
|
+ rb_jump_tag(state); |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER) |
||||||
|
if (EVP_DigestSign(ctx, NULL, &siglen, (unsigned char *)RSTRING_PTR(data), |
||||||
|
RSTRING_LEN(data)) < 1) { |
||||||
|
@@ -828,35 +853,40 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
- * call-seq: |
||||||
|
- * pkey.verify(digest, signature, data) -> String |
||||||
|
+ * call-seq: |
||||||
|
+ * pkey.verify(digest, signature, data [, options]) -> true or false |
||||||
|
* |
||||||
|
- * To verify the String _signature_, _digest_, an instance of |
||||||
|
- * OpenSSL::Digest, must be provided to re-compute the message digest of the |
||||||
|
- * original _data_, also a String. The return value is +true+ if the |
||||||
|
- * signature is valid, +false+ otherwise. A PKeyError is raised should errors |
||||||
|
- * occur. |
||||||
|
- * Any previous state of the Digest instance is irrelevant to the validation |
||||||
|
- * outcome, the digest instance is reset to its initial state during the |
||||||
|
- * operation. |
||||||
|
+ * Verifies the +signature+ for the +data+ using a message digest algorithm |
||||||
|
+ * +digest+ and a public key +pkey+. |
||||||
|
* |
||||||
|
- * == Example |
||||||
|
- * data = 'Sign me!' |
||||||
|
- * digest = OpenSSL::Digest.new('SHA256') |
||||||
|
- * pkey = OpenSSL::PKey::RSA.new(2048) |
||||||
|
- * signature = pkey.sign(digest, data) |
||||||
|
- * pub_key = pkey.public_key |
||||||
|
- * puts pub_key.verify(digest, signature, data) # => true |
||||||
|
+ * Returns +true+ if the signature is successfully verified, +false+ otherwise. |
||||||
|
+ * The caller must check the return value. |
||||||
|
+ * |
||||||
|
+ * See #sign for the signing operation and an example. |
||||||
|
+ * |
||||||
|
+ * See also the man page EVP_DigestVerify(3). |
||||||
|
+ * |
||||||
|
+ * +digest+:: |
||||||
|
+ * See #sign. |
||||||
|
+ * +signature+:: |
||||||
|
+ * A String containing the signature to be verified. |
||||||
|
+ * +data+:: |
||||||
|
+ * See #sign. |
||||||
|
+ * +options+:: |
||||||
|
+ * See #sign. +options+ parameter was added in version 2.3. |
||||||
|
*/ |
||||||
|
static VALUE |
||||||
|
-ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) |
||||||
|
+ossl_pkey_verify(int argc, VALUE *argv, VALUE self) |
||||||
|
{ |
||||||
|
EVP_PKEY *pkey; |
||||||
|
+ VALUE digest, sig, data, options; |
||||||
|
const EVP_MD *md = NULL; |
||||||
|
EVP_MD_CTX *ctx; |
||||||
|
- int ret; |
||||||
|
+ EVP_PKEY_CTX *pctx; |
||||||
|
+ int state, ret; |
||||||
|
|
||||||
|
GetPKey(self, pkey); |
||||||
|
+ rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options); |
||||||
|
ossl_pkey_check_public_key(pkey); |
||||||
|
if (!NIL_P(digest)) |
||||||
|
md = ossl_evp_get_digestbyname(digest); |
||||||
|
@@ -866,10 +896,17 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) |
||||||
|
ctx = EVP_MD_CTX_new(); |
||||||
|
if (!ctx) |
||||||
|
ossl_raise(ePKeyError, "EVP_MD_CTX_new"); |
||||||
|
- if (EVP_DigestVerifyInit(ctx, NULL, md, /* engine */NULL, pkey) < 1) { |
||||||
|
+ if (EVP_DigestVerifyInit(ctx, &pctx, md, /* engine */NULL, pkey) < 1) { |
||||||
|
EVP_MD_CTX_free(ctx); |
||||||
|
ossl_raise(ePKeyError, "EVP_DigestVerifyInit"); |
||||||
|
} |
||||||
|
+ if (!NIL_P(options)) { |
||||||
|
+ pkey_ctx_apply_options(pctx, options, &state); |
||||||
|
+ if (state) { |
||||||
|
+ EVP_MD_CTX_free(ctx); |
||||||
|
+ rb_jump_tag(state); |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER) |
||||||
|
ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig), |
||||||
|
RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data), |
||||||
|
@@ -1042,8 +1079,8 @@ Init_ossl_pkey(void) |
||||||
|
rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); |
||||||
|
rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); |
||||||
|
|
||||||
|
- rb_define_method(cPKey, "sign", ossl_pkey_sign, 2); |
||||||
|
- rb_define_method(cPKey, "verify", ossl_pkey_verify, 3); |
||||||
|
+ rb_define_method(cPKey, "sign", ossl_pkey_sign, -1); |
||||||
|
+ rb_define_method(cPKey, "verify", ossl_pkey_verify, -1); |
||||||
|
rb_define_method(cPKey, "derive", ossl_pkey_derive, -1); |
||||||
|
|
||||||
|
id_private_q = rb_intern("private?"); |
||||||
|
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb |
||||||
|
index 88164c3b52..d1e68dbc9f 100644 |
||||||
|
--- a/test/openssl/test_pkey_rsa.rb |
||||||
|
+++ b/test/openssl/test_pkey_rsa.rb |
||||||
|
@@ -117,27 +117,21 @@ def test_sign_verify |
||||||
|
assert_equal false, rsa1024.verify("SHA256", signature1, data) |
||||||
|
end |
||||||
|
|
||||||
|
- def test_digest_state_irrelevant_sign |
||||||
|
+ def test_sign_verify_options |
||||||
|
key = Fixtures.pkey("rsa1024") |
||||||
|
- digest1 = OpenSSL::Digest.new('SHA1') |
||||||
|
- digest2 = OpenSSL::Digest.new('SHA1') |
||||||
|
- data = 'Sign me!' |
||||||
|
- digest1 << 'Change state of digest1' |
||||||
|
- sig1 = key.sign(digest1, data) |
||||||
|
- sig2 = key.sign(digest2, data) |
||||||
|
- assert_equal(sig1, sig2) |
||||||
|
- end |
||||||
|
- |
||||||
|
- def test_digest_state_irrelevant_verify |
||||||
|
- key = Fixtures.pkey("rsa1024") |
||||||
|
- digest1 = OpenSSL::Digest.new('SHA1') |
||||||
|
- digest2 = OpenSSL::Digest.new('SHA1') |
||||||
|
- data = 'Sign me!' |
||||||
|
- sig = key.sign(digest1, data) |
||||||
|
- digest1.reset |
||||||
|
- digest1 << 'Change state of digest1' |
||||||
|
- assert(key.verify(digest1, sig, data)) |
||||||
|
- assert(key.verify(digest2, sig, data)) |
||||||
|
+ data = "Sign me!" |
||||||
|
+ pssopts = { |
||||||
|
+ "rsa_padding_mode" => "pss", |
||||||
|
+ "rsa_pss_saltlen" => 20, |
||||||
|
+ "rsa_mgf1_md" => "SHA1" |
||||||
|
+ } |
||||||
|
+ sig_pss = key.sign("SHA256", data, pssopts) |
||||||
|
+ assert_equal 128, sig_pss.bytesize |
||||||
|
+ assert_equal true, key.verify("SHA256", sig_pss, data, pssopts) |
||||||
|
+ assert_equal true, key.verify_pss("SHA256", sig_pss, data, |
||||||
|
+ salt_length: 20, mgf1_hash: "SHA1") |
||||||
|
+ # Defaults to PKCS #1 v1.5 padding => verification failure |
||||||
|
+ assert_equal false, key.verify("SHA256", sig_pss, data) |
||||||
|
end |
||||||
|
|
||||||
|
def test_verify_empty_rsa |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
@ -0,0 +1,719 @@ |
|||||||
|
From 46ca47060ca8ef3419ec36c2326a81b442d9b43b Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Sun, 12 Dec 2021 01:25:20 +0900 |
||||||
|
Subject: [PATCH 1/5] pkey/dh: avoid using DH#set_key in DH#compute_key |
||||||
|
|
||||||
|
DH#set_key will not work on OpenSSL 3.0 because keys are immutable. |
||||||
|
For now, let's reimplement DH#compute_key by manually constructing a |
||||||
|
DER-encoded SubjectPublicKeyInfo structure and feeding it to |
||||||
|
OpenSSL::PKey.read. |
||||||
|
|
||||||
|
Eventually, we should implement a new method around EVP_PKEY_fromdata() |
||||||
|
and use it instead. |
||||||
|
--- |
||||||
|
ext/openssl/lib/openssl/pkey.rb | 16 +++++++++++++--- |
||||||
|
1 file changed, 13 insertions(+), 3 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb |
||||||
|
index f6bf5892..5864faa9 100644 |
||||||
|
--- a/ext/openssl/lib/openssl/pkey.rb |
||||||
|
+++ b/ext/openssl/lib/openssl/pkey.rb |
||||||
|
@@ -47,9 +47,19 @@ def public_key |
||||||
|
# * _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: |
||||||
|
|
||||||
|
From fc9aabc18df3c189cc6a76a1470ca908c4f16480 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Fri, 17 Dec 2021 02:22:25 +0900 |
||||||
|
Subject: [PATCH 2/5] pkey/ec: avoid using EC#public_key= in EC#dh_compute_key |
||||||
|
|
||||||
|
Similarly to DH#compute_key, work around it by constructing a |
||||||
|
SubjectPublicKeyInfo. This should be considered as a temporary |
||||||
|
implementation. |
||||||
|
--- |
||||||
|
ext/openssl/lib/openssl/pkey.rb | 11 ++++++++--- |
||||||
|
1 file changed, 8 insertions(+), 3 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb |
||||||
|
index 5864faa9..ba04cf4b 100644 |
||||||
|
--- a/ext/openssl/lib/openssl/pkey.rb |
||||||
|
+++ b/ext/openssl/lib/openssl/pkey.rb |
||||||
|
@@ -259,9 +259,14 @@ def dsa_verify_asn1(data, sig) |
||||||
|
# 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 |
||||||
|
|
||||||
|
|
||||||
|
From 8ee6a582c7e4614eec4f5ca5ab59898fbcb50d2a Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Fri, 22 Oct 2021 16:24:07 +0900 |
||||||
|
Subject: [PATCH 3/5] pkey/dh: deprecate OpenSSL::PKey::DH#generate_key! |
||||||
|
|
||||||
|
OpenSSL::PKey::DH#generate_key! will not work on OpenSSL 3.0 because |
||||||
|
keys are made immutable. Users should use OpenSSL::PKey.generate_key |
||||||
|
instead. |
||||||
|
--- |
||||||
|
ext/openssl/lib/openssl/pkey.rb | 23 +++++++++++++++++++---- |
||||||
|
ext/openssl/ossl_pkey_dh.c | 9 +++++---- |
||||||
|
test/openssl/test_pkey_dh.rb | 18 ++++++++++-------- |
||||||
|
3 files changed, 34 insertions(+), 16 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb |
||||||
|
index ba04cf4b..c3e06290 100644 |
||||||
|
--- a/ext/openssl/lib/openssl/pkey.rb |
||||||
|
+++ b/ext/openssl/lib/openssl/pkey.rb |
||||||
|
@@ -71,14 +71,29 @@ def compute_key(pub_bn) |
||||||
|
# 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) |
||||||
|
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c |
||||||
|
index 04c11b2157..e70d60ed19 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_dh.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_dh.c |
||||||
|
@@ -58,15 +58,16 @@ VALUE eDHError; |
||||||
|
* |
||||||
|
* Examples: |
||||||
|
* # Creating an instance from scratch |
||||||
|
- * dh = DH.new |
||||||
|
+ * # Note that this is deprecated and will not work on OpenSSL 3.0 or later. |
||||||
|
+ * dh = OpenSSL::PKey::DH.new |
||||||
|
* dh.set_pqg(bn_p, nil, bn_g) |
||||||
|
* |
||||||
|
* # Generating a parameters and a key pair |
||||||
|
- * dh = DH.new(2048) # An alias of DH.generate(2048) |
||||||
|
+ * dh = OpenSSL::PKey::DH.new(2048) # An alias of OpenSSL::PKey::DH.generate(2048) |
||||||
|
* |
||||||
|
* # Reading DH parameters |
||||||
|
- * dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet |
||||||
|
- * dh.generate_key! # -> dh with public and private key |
||||||
|
+ * dh_params = OpenSSL::PKey::DH.new(File.read('parameters.pem')) # loads parameters only |
||||||
|
+ * dh = OpenSSL::PKey.generate_key(dh_params) # generates a key pair |
||||||
|
*/ |
||||||
|
static VALUE |
||||||
|
ossl_dh_initialize(int argc, VALUE *argv, VALUE self) |
||||||
|
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb |
||||||
|
index 757704ca..ac11af38 100644 |
||||||
|
--- a/test/openssl/test_pkey_dh.rb |
||||||
|
+++ b/test/openssl/test_pkey_dh.rb |
||||||
|
@@ -26,14 +26,19 @@ def test_new_break |
||||||
|
end |
||||||
|
|
||||||
|
def test_derive_key |
||||||
|
- dh1 = Fixtures.pkey("dh1024").generate_key! |
||||||
|
- dh2 = Fixtures.pkey("dh1024").generate_key! |
||||||
|
+ params = Fixtures.pkey("dh1024") |
||||||
|
+ dh1 = OpenSSL::PKey.generate_key(params) |
||||||
|
+ dh2 = OpenSSL::PKey.generate_key(params) |
||||||
|
dh1_pub = OpenSSL::PKey.read(dh1.public_to_der) |
||||||
|
dh2_pub = OpenSSL::PKey.read(dh2.public_to_der) |
||||||
|
+ |
||||||
|
z = dh1.g.mod_exp(dh1.priv_key, dh1.p).mod_exp(dh2.priv_key, dh1.p).to_s(2) |
||||||
|
assert_equal z, dh1.derive(dh2_pub) |
||||||
|
assert_equal z, dh2.derive(dh1_pub) |
||||||
|
|
||||||
|
+ assert_raise(OpenSSL::PKey::PKeyError) { params.derive(dh1_pub) } |
||||||
|
+ assert_raise(OpenSSL::PKey::PKeyError) { dh1_pub.derive(params) } |
||||||
|
+ |
||||||
|
assert_equal z, dh1.compute_key(dh2.pub_key) |
||||||
|
assert_equal z, dh2.compute_key(dh1.pub_key) |
||||||
|
end |
||||||
|
@@ -74,19 +79,16 @@ def test_public_key |
||||||
|
end |
||||||
|
|
||||||
|
def test_generate_key |
||||||
|
- dh = Fixtures.pkey("dh1024").public_key # creates a copy |
||||||
|
+ # Deprecated in v3.0.0; incompatible with OpenSSL 3.0 |
||||||
|
+ dh = Fixtures.pkey("dh1024").public_key # creates a copy with params only |
||||||
|
assert_no_key(dh) |
||||||
|
dh.generate_key! |
||||||
|
assert_key(dh) |
||||||
|
- end |
||||||
|
|
||||||
|
- def test_key_exchange |
||||||
|
- dh = Fixtures.pkey("dh1024") |
||||||
|
dh2 = dh.public_key |
||||||
|
- dh.generate_key! |
||||||
|
dh2.generate_key! |
||||||
|
assert_equal(dh.compute_key(dh2.pub_key), dh2.compute_key(dh.pub_key)) |
||||||
|
- end |
||||||
|
+ end if !openssl?(3, 0, 0) |
||||||
|
|
||||||
|
def test_params_ok? |
||||||
|
dh0 = Fixtures.pkey("dh1024") |
||||||
|
|
||||||
|
From 5e2e66cce870ea86001dbb0eaa3092badfd37994 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Fri, 17 Dec 2021 02:21:42 +0900 |
||||||
|
Subject: [PATCH 4/5] pkey/ec: deprecate OpenSSL::PKey::EC#generate_key! |
||||||
|
|
||||||
|
OpenSSL::PKey::EC#generate_key! will not work on OpenSSL 3.0 because |
||||||
|
keys are made immutable. Users should use OpenSSL::PKey.generate_key |
||||||
|
instead. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_pkey_ec.c | 4 ++++ |
||||||
|
test/openssl/test_pkey_ec.rb | 21 +++++++++++++-------- |
||||||
|
2 files changed, 17 insertions(+), 8 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c |
||||||
|
index db80d112..398a550a 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_ec.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_ec.c |
||||||
|
@@ -442,6 +442,9 @@ ossl_ec_key_to_der(VALUE self) |
||||||
|
*/ |
||||||
|
static VALUE ossl_ec_key_generate_key(VALUE self) |
||||||
|
{ |
||||||
|
+#if OSSL_OPENSSL_PREREQ(3, 0, 0) |
||||||
|
+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); |
||||||
|
+#else |
||||||
|
EC_KEY *ec; |
||||||
|
|
||||||
|
GetEC(self, ec); |
||||||
|
@@ -449,6 +452,7 @@ static VALUE ossl_ec_key_generate_key(VALUE self) |
||||||
|
ossl_raise(eECError, "EC_KEY_generate_key"); |
||||||
|
|
||||||
|
return self; |
||||||
|
+#endif |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb |
||||||
|
index 3f5958af..33f78a4c 100644 |
||||||
|
--- a/test/openssl/test_pkey_ec.rb |
||||||
|
+++ b/test/openssl/test_pkey_ec.rb |
||||||
|
@@ -13,15 +13,13 @@ def test_ec_key |
||||||
|
# FIPS-selftest failure on some environment, so skip for now. |
||||||
|
next if ["Oakley", "X25519"].any? { |n| curve_name.start_with?(n) } |
||||||
|
|
||||||
|
- key = OpenSSL::PKey::EC.new(curve_name) |
||||||
|
- key.generate_key! |
||||||
|
- |
||||||
|
+ key = OpenSSL::PKey::EC.generate(curve_name) |
||||||
|
assert_predicate key, :private? |
||||||
|
assert_predicate key, :public? |
||||||
|
assert_nothing_raised { key.check_key } |
||||||
|
end |
||||||
|
|
||||||
|
- key1 = OpenSSL::PKey::EC.new("prime256v1").generate_key! |
||||||
|
+ key1 = OpenSSL::PKey::EC.generate("prime256v1") |
||||||
|
|
||||||
|
key2 = OpenSSL::PKey::EC.new |
||||||
|
key2.group = key1.group |
||||||
|
@@ -52,6 +50,13 @@ def test_generate |
||||||
|
assert_equal(true, ec.private?) |
||||||
|
end |
||||||
|
|
||||||
|
+ def test_generate_key |
||||||
|
+ ec = OpenSSL::PKey::EC.new("prime256v1") |
||||||
|
+ assert_equal false, ec.private? |
||||||
|
+ ec.generate_key! |
||||||
|
+ assert_equal true, ec.private? |
||||||
|
+ end if !openssl?(3, 0, 0) |
||||||
|
+ |
||||||
|
def test_marshal |
||||||
|
key = Fixtures.pkey("p256") |
||||||
|
deserialized = Marshal.load(Marshal.dump(key)) |
||||||
|
@@ -136,7 +141,7 @@ def test_sign_verify_raw |
||||||
|
end |
||||||
|
|
||||||
|
def test_dsa_sign_asn1_FIPS186_3 |
||||||
|
- key = OpenSSL::PKey::EC.new("prime256v1").generate_key! |
||||||
|
+ key = OpenSSL::PKey::EC.generate("prime256v1") |
||||||
|
size = key.group.order.num_bits / 8 + 1 |
||||||
|
dgst = (1..size).to_a.pack('C*') |
||||||
|
sig = key.dsa_sign_asn1(dgst) |
||||||
|
@@ -145,8 +150,8 @@ def test_dsa_sign_asn1_FIPS186_3 |
||||||
|
end |
||||||
|
|
||||||
|
def test_dh_compute_key |
||||||
|
- key_a = OpenSSL::PKey::EC.new("prime256v1").generate_key! |
||||||
|
- key_b = OpenSSL::PKey::EC.new(key_a.group).generate_key! |
||||||
|
+ key_a = OpenSSL::PKey::EC.generate("prime256v1") |
||||||
|
+ key_b = OpenSSL::PKey::EC.generate(key_a.group) |
||||||
|
|
||||||
|
pub_a = key_a.public_key |
||||||
|
pub_b = key_b.public_key |
||||||
|
@@ -276,7 +281,7 @@ def test_ec_group |
||||||
|
|
||||||
|
def test_ec_point |
||||||
|
group = OpenSSL::PKey::EC::Group.new("prime256v1") |
||||||
|
- key = OpenSSL::PKey::EC.new(group).generate_key! |
||||||
|
+ key = OpenSSL::PKey::EC.generate(group) |
||||||
|
point = key.public_key |
||||||
|
|
||||||
|
point2 = OpenSSL::PKey::EC::Point.new(group, point.to_bn) |
||||||
|
|
||||||
|
From 6848d2d969d90e6a400d89848ecec21076b87888 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Tue, 21 Sep 2021 18:29:59 +0900 |
||||||
|
Subject: [PATCH 5/5] pkey: deprecate PKey#set_* methods |
||||||
|
|
||||||
|
OpenSSL 3.0 made EVP_PKEY immutable. This means we can only have a const |
||||||
|
pointer of the low level struct and the following methods can no longer |
||||||
|
be provided when linked against OpenSSL 3.0: |
||||||
|
|
||||||
|
- OpenSSL::PKey::RSA#set_key |
||||||
|
- OpenSSL::PKey::RSA#set_factors |
||||||
|
- OpenSSL::PKey::RSA#set_crt_params |
||||||
|
- OpenSSL::PKey::DSA#set_pqg |
||||||
|
- OpenSSL::PKey::DSA#set_key |
||||||
|
- OpenSSL::PKey::DH#set_pqg |
||||||
|
- OpenSSL::PKey::DH#set_key |
||||||
|
- OpenSSL::PKey::EC#group= |
||||||
|
- OpenSSL::PKey::EC#private_key= |
||||||
|
- OpenSSL::PKey::EC#public_key= |
||||||
|
|
||||||
|
There is no direct replacement for this functionality at the moment. |
||||||
|
I plan to introduce a wrapper around EVP_PKEY_fromdata(), which takes |
||||||
|
all key components at once to construct an EVP_PKEY. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_pkey.h | 16 +++++++ |
||||||
|
ext/openssl/ossl_pkey_ec.c | 12 +++++ |
||||||
|
test/openssl/test_pkey_dh.rb | 38 +++++++++++----- |
||||||
|
test/openssl/test_pkey_dsa.rb | 8 +++- |
||||||
|
test/openssl/test_pkey_ec.rb | 58 ++++++++++++++---------- |
||||||
|
test/openssl/test_pkey_rsa.rb | 85 ++++++++++++++++++++++------------- |
||||||
|
6 files changed, 149 insertions(+), 68 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h |
||||||
|
index 4beede22..4536e58e 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.h |
||||||
|
+++ b/ext/openssl/ossl_pkey.h |
||||||
|
@@ -116,6 +116,7 @@ static VALUE ossl_##_keytype##_get_##_name(VALUE self) \ |
||||||
|
OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \ |
||||||
|
_type##_get0_##_group(obj, NULL, &bn)) |
||||||
|
|
||||||
|
+#if !OSSL_OPENSSL_PREREQ(3, 0, 0) |
||||||
|
#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \ |
||||||
|
/* \ |
||||||
|
* call-seq: \ |
||||||
|
@@ -173,6 +174,21 @@ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \ |
||||||
|
} \ |
||||||
|
return self; \ |
||||||
|
} |
||||||
|
+#else |
||||||
|
+#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \ |
||||||
|
+static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALUE v3) \ |
||||||
|
+{ \ |
||||||
|
+ rb_raise(ePKeyError, \ |
||||||
|
+ #_keytype"#set_"#_group"= is incompatible with OpenSSL 3.0"); \ |
||||||
|
+} |
||||||
|
+ |
||||||
|
+#define OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \ |
||||||
|
+static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \ |
||||||
|
+{ \ |
||||||
|
+ rb_raise(ePKeyError, \ |
||||||
|
+ #_keytype"#set_"#_group"= is incompatible with OpenSSL 3.0"); \ |
||||||
|
+} |
||||||
|
+#endif |
||||||
|
|
||||||
|
#define OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, _name) \ |
||||||
|
/* \ |
||||||
|
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c |
||||||
|
index 398a550a..7a6ed1c9 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_ec.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_ec.c |
||||||
|
@@ -251,6 +251,9 @@ ossl_ec_key_get_group(VALUE self) |
||||||
|
static VALUE |
||||||
|
ossl_ec_key_set_group(VALUE self, VALUE group_v) |
||||||
|
{ |
||||||
|
+#if OSSL_OPENSSL_PREREQ(3, 0, 0) |
||||||
|
+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); |
||||||
|
+#else |
||||||
|
EC_KEY *ec; |
||||||
|
EC_GROUP *group; |
||||||
|
|
||||||
|
@@ -261,6 +264,7 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v) |
||||||
|
ossl_raise(eECError, "EC_KEY_set_group"); |
||||||
|
|
||||||
|
return group_v; |
||||||
|
+#endif |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
@@ -289,6 +293,9 @@ static VALUE ossl_ec_key_get_private_key(VALUE self) |
||||||
|
*/ |
||||||
|
static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) |
||||||
|
{ |
||||||
|
+#if OSSL_OPENSSL_PREREQ(3, 0, 0) |
||||||
|
+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); |
||||||
|
+#else |
||||||
|
EC_KEY *ec; |
||||||
|
BIGNUM *bn = NULL; |
||||||
|
|
||||||
|
@@ -307,6 +314,7 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) |
||||||
|
} |
||||||
|
|
||||||
|
return private_key; |
||||||
|
+#endif |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
@@ -335,6 +343,9 @@ static VALUE ossl_ec_key_get_public_key(VALUE self) |
||||||
|
*/ |
||||||
|
static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) |
||||||
|
{ |
||||||
|
+#if OSSL_OPENSSL_PREREQ(3, 0, 0) |
||||||
|
+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); |
||||||
|
+#else |
||||||
|
EC_KEY *ec; |
||||||
|
EC_POINT *point = NULL; |
||||||
|
|
||||||
|
@@ -353,6 +364,7 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) |
||||||
|
} |
||||||
|
|
||||||
|
return public_key; |
||||||
|
+#endif |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb |
||||||
|
index ac11af38..161af189 100644 |
||||||
|
--- a/test/openssl/test_pkey_dh.rb |
||||||
|
+++ b/test/openssl/test_pkey_dh.rb |
||||||
|
@@ -107,13 +107,32 @@ def test_params_ok? |
||||||
|
end |
||||||
|
|
||||||
|
def test_dup |
||||||
|
- dh = Fixtures.pkey("dh1024") |
||||||
|
- dh2 = dh.dup |
||||||
|
- assert_equal dh.to_der, dh2.to_der # params |
||||||
|
- assert_equal_params dh, dh2 # keys |
||||||
|
- dh2.set_pqg(dh2.p + 1, nil, dh2.g) |
||||||
|
- assert_not_equal dh2.p, dh.p |
||||||
|
- assert_equal dh2.g, dh.g |
||||||
|
+ # Parameters only |
||||||
|
+ dh1 = Fixtures.pkey("dh1024") |
||||||
|
+ dh2 = dh1.dup |
||||||
|
+ assert_equal dh1.to_der, dh2.to_der |
||||||
|
+ assert_not_equal nil, dh1.p |
||||||
|
+ assert_not_equal nil, dh1.g |
||||||
|
+ assert_equal [dh1.p, dh1.g], [dh2.p, dh2.g] |
||||||
|
+ assert_equal nil, dh1.pub_key |
||||||
|
+ assert_equal nil, dh1.priv_key |
||||||
|
+ assert_equal [dh1.pub_key, dh1.priv_key], [dh2.pub_key, dh2.priv_key] |
||||||
|
+ |
||||||
|
+ # PKey is immutable in OpenSSL >= 3.0 |
||||||
|
+ if !openssl?(3, 0, 0) |
||||||
|
+ dh2.set_pqg(dh2.p + 1, nil, dh2.g) |
||||||
|
+ assert_not_equal dh2.p, dh1.p |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ # With a key pair |
||||||
|
+ dh3 = OpenSSL::PKey.generate_key(Fixtures.pkey("dh1024")) |
||||||
|
+ dh4 = dh3.dup |
||||||
|
+ assert_equal dh3.to_der, dh4.to_der |
||||||
|
+ assert_equal dh1.to_der, dh4.to_der # encodes parameters only |
||||||
|
+ assert_equal [dh1.p, dh1.g], [dh4.p, dh4.g] |
||||||
|
+ assert_not_equal nil, dh3.pub_key |
||||||
|
+ assert_not_equal nil, dh3.priv_key |
||||||
|
+ assert_equal [dh3.pub_key, dh3.priv_key], [dh4.pub_key, dh4.priv_key] |
||||||
|
end |
||||||
|
|
||||||
|
def test_marshal |
||||||
|
@@ -125,11 +144,6 @@ def test_marshal |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
- def assert_equal_params(dh1, dh2) |
||||||
|
- assert_equal(dh1.g, dh2.g) |
||||||
|
- assert_equal(dh1.p, dh2.p) |
||||||
|
- end |
||||||
|
- |
||||||
|
def assert_no_key(dh) |
||||||
|
assert_equal(false, dh.public?) |
||||||
|
assert_equal(false, dh.private?) |
||||||
|
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb |
||||||
|
index 0994607f..726b7dbf 100644 |
||||||
|
--- a/test/openssl/test_pkey_dsa.rb |
||||||
|
+++ b/test/openssl/test_pkey_dsa.rb |
||||||
|
@@ -208,8 +208,12 @@ def test_dup |
||||||
|
key = Fixtures.pkey("dsa1024") |
||||||
|
key2 = key.dup |
||||||
|
assert_equal key.params, key2.params |
||||||
|
- key2.set_pqg(key2.p + 1, key2.q, key2.g) |
||||||
|
- assert_not_equal key.params, key2.params |
||||||
|
+ |
||||||
|
+ # PKey is immutable in OpenSSL >= 3.0 |
||||||
|
+ if !openssl?(3, 0, 0) |
||||||
|
+ key2.set_pqg(key2.p + 1, key2.q, key2.g) |
||||||
|
+ assert_not_equal key.params, key2.params |
||||||
|
+ end |
||||||
|
end |
||||||
|
|
||||||
|
def test_marshal |
||||||
|
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb |
||||||
|
index 33f78a4c..ffe5a94e 100644 |
||||||
|
--- a/test/openssl/test_pkey_ec.rb |
||||||
|
+++ b/test/openssl/test_pkey_ec.rb |
||||||
|
@@ -21,11 +21,15 @@ def test_ec_key |
||||||
|
|
||||||
|
key1 = OpenSSL::PKey::EC.generate("prime256v1") |
||||||
|
|
||||||
|
- key2 = OpenSSL::PKey::EC.new |
||||||
|
- key2.group = key1.group |
||||||
|
- key2.private_key = key1.private_key |
||||||
|
- key2.public_key = key1.public_key |
||||||
|
- assert_equal key1.to_der, key2.to_der |
||||||
|
+ # PKey is immutable in OpenSSL >= 3.0; constructing an empty EC object is |
||||||
|
+ # deprecated |
||||||
|
+ if !openssl?(3, 0, 0) |
||||||
|
+ key2 = OpenSSL::PKey::EC.new |
||||||
|
+ key2.group = key1.group |
||||||
|
+ key2.private_key = key1.private_key |
||||||
|
+ key2.public_key = key1.public_key |
||||||
|
+ assert_equal key1.to_der, key2.to_der |
||||||
|
+ end |
||||||
|
|
||||||
|
key3 = OpenSSL::PKey::EC.new(key1) |
||||||
|
assert_equal key1.to_der, key3.to_der |
||||||
|
@@ -35,10 +39,14 @@ def test_ec_key |
||||||
|
|
||||||
|
key5 = key1.dup |
||||||
|
assert_equal key1.to_der, key5.to_der |
||||||
|
- key_tmp = OpenSSL::PKey::EC.new("prime256v1").generate_key! |
||||||
|
- key5.private_key = key_tmp.private_key |
||||||
|
- key5.public_key = key_tmp.public_key |
||||||
|
- assert_not_equal key1.to_der, key5.to_der |
||||||
|
+ |
||||||
|
+ # PKey is immutable in OpenSSL >= 3.0; EC object should not be modified |
||||||
|
+ if !openssl?(3, 0, 0) |
||||||
|
+ key_tmp = OpenSSL::PKey::EC.generate("prime256v1") |
||||||
|
+ key5.private_key = key_tmp.private_key |
||||||
|
+ key5.public_key = key_tmp.public_key |
||||||
|
+ assert_not_equal key1.to_der, key5.to_der |
||||||
|
+ end |
||||||
|
end |
||||||
|
|
||||||
|
def test_generate |
||||||
|
@@ -65,22 +73,26 @@ def test_marshal |
||||||
|
end |
||||||
|
|
||||||
|
def test_check_key |
||||||
|
- key = OpenSSL::PKey::EC.new("prime256v1").generate_key! |
||||||
|
- assert_equal(true, key.check_key) |
||||||
|
- assert_equal(true, key.private?) |
||||||
|
- assert_equal(true, key.public?) |
||||||
|
- key2 = OpenSSL::PKey::EC.new(key.group) |
||||||
|
- assert_equal(false, key2.private?) |
||||||
|
- assert_equal(false, key2.public?) |
||||||
|
- key2.public_key = key.public_key |
||||||
|
- assert_equal(false, key2.private?) |
||||||
|
- assert_equal(true, key2.public?) |
||||||
|
- key2.private_key = key.private_key |
||||||
|
+ key0 = Fixtures.pkey("p256") |
||||||
|
+ assert_equal(true, key0.check_key) |
||||||
|
+ assert_equal(true, key0.private?) |
||||||
|
+ assert_equal(true, key0.public?) |
||||||
|
+ |
||||||
|
+ key1 = OpenSSL::PKey.read(key0.public_to_der) |
||||||
|
+ assert_equal(true, key1.check_key) |
||||||
|
+ assert_equal(false, key1.private?) |
||||||
|
+ assert_equal(true, key1.public?) |
||||||
|
+ |
||||||
|
+ key2 = OpenSSL::PKey.read(key0.private_to_der) |
||||||
|
assert_equal(true, key2.private?) |
||||||
|
assert_equal(true, key2.public?) |
||||||
|
assert_equal(true, key2.check_key) |
||||||
|
- key2.private_key += 1 |
||||||
|
- assert_raise(OpenSSL::PKey::ECError) { key2.check_key } |
||||||
|
+ |
||||||
|
+ # EC#private_key= is deprecated in 3.0 and won't work on OpenSSL 3.0 |
||||||
|
+ if !openssl?(3, 0, 0) |
||||||
|
+ key2.private_key += 1 |
||||||
|
+ assert_raise(OpenSSL::PKey::ECError) { key2.check_key } |
||||||
|
+ end |
||||||
|
end |
||||||
|
|
||||||
|
def test_sign_verify |
||||||
|
@@ -112,7 +124,7 @@ def test_derive_key |
||||||
|
assert_equal [zIUT].pack("H*"), a.derive(b) |
||||||
|
|
||||||
|
assert_equal a.derive(b), a.dh_compute_key(b.public_key) |
||||||
|
- end |
||||||
|
+ end if !openssl?(3, 0, 0) # TODO: Test it without using #private_key= |
||||||
|
|
||||||
|
def test_sign_verify_raw |
||||||
|
key = Fixtures.pkey("p256") |
||||||
|
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb |
||||||
|
index dbe87ba4..1c7f9ccf 100644 |
||||||
|
--- a/test/openssl/test_pkey_rsa.rb |
||||||
|
+++ b/test/openssl/test_pkey_rsa.rb |
||||||
|
@@ -31,15 +31,18 @@ def test_private |
||||||
|
assert(!key4.private?) |
||||||
|
rsa1024 = Fixtures.pkey("rsa1024") |
||||||
|
|
||||||
|
- # Generated by RSA#set_key |
||||||
|
- key5 = OpenSSL::PKey::RSA.new |
||||||
|
- key5.set_key(rsa1024.n, rsa1024.e, rsa1024.d) |
||||||
|
- assert(key5.private?) |
||||||
|
- |
||||||
|
- # Generated by RSA#set_key, without d |
||||||
|
- key6 = OpenSSL::PKey::RSA.new |
||||||
|
- key6.set_key(rsa1024.n, rsa1024.e, nil) |
||||||
|
- assert(!key6.private?) |
||||||
|
+ if !openssl?(3, 0, 0) |
||||||
|
+ key = OpenSSL::PKey::RSA.new |
||||||
|
+ # Generated by RSA#set_key |
||||||
|
+ key5 = OpenSSL::PKey::RSA.new |
||||||
|
+ key5.set_key(rsa1024.n, rsa1024.e, rsa1024.d) |
||||||
|
+ assert(key5.private?) |
||||||
|
+ |
||||||
|
+ # Generated by RSA#set_key, without d |
||||||
|
+ key6 = OpenSSL::PKey::RSA.new |
||||||
|
+ key6.set_key(rsa1024.n, rsa1024.e, nil) |
||||||
|
+ assert(!key6.private?) |
||||||
|
+ end |
||||||
|
end |
||||||
|
|
||||||
|
def test_new |
||||||
|
@@ -235,36 +238,52 @@ def test_encrypt_decrypt_legacy |
||||||
|
|
||||||
|
def test_export |
||||||
|
rsa1024 = Fixtures.pkey("rsa1024") |
||||||
|
- key = OpenSSL::PKey::RSA.new |
||||||
|
|
||||||
|
- # key has only n, e and d |
||||||
|
- key.set_key(rsa1024.n, rsa1024.e, rsa1024.d) |
||||||
|
- assert_equal rsa1024.public_key.export, key.export |
||||||
|
+ pub = OpenSSL::PKey.read(rsa1024.public_to_der) |
||||||
|
+ assert_not_equal rsa1024.export, pub.export |
||||||
|
+ assert_equal rsa1024.public_to_pem, pub.export |
||||||
|
+ |
||||||
|
+ # PKey is immutable in OpenSSL >= 3.0 |
||||||
|
+ if !openssl?(3, 0, 0) |
||||||
|
+ key = OpenSSL::PKey::RSA.new |
||||||
|
|
||||||
|
- # key has only n, e, d, p and q |
||||||
|
- key.set_factors(rsa1024.p, rsa1024.q) |
||||||
|
- assert_equal rsa1024.public_key.export, key.export |
||||||
|
+ # key has only n, e and d |
||||||
|
+ key.set_key(rsa1024.n, rsa1024.e, rsa1024.d) |
||||||
|
+ assert_equal rsa1024.public_key.export, key.export |
||||||
|
|
||||||
|
- # key has n, e, d, p, q, dmp1, dmq1 and iqmp |
||||||
|
- key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp) |
||||||
|
- assert_equal rsa1024.export, key.export |
||||||
|
+ # key has only n, e, d, p and q |
||||||
|
+ key.set_factors(rsa1024.p, rsa1024.q) |
||||||
|
+ assert_equal rsa1024.public_key.export, key.export |
||||||
|
+ |
||||||
|
+ # key has n, e, d, p, q, dmp1, dmq1 and iqmp |
||||||
|
+ key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp) |
||||||
|
+ assert_equal rsa1024.export, key.export |
||||||
|
+ end |
||||||
|
end |
||||||
|
|
||||||
|
def test_to_der |
||||||
|
rsa1024 = Fixtures.pkey("rsa1024") |
||||||
|
- key = OpenSSL::PKey::RSA.new |
||||||
|
|
||||||
|
- # key has only n, e and d |
||||||
|
- key.set_key(rsa1024.n, rsa1024.e, rsa1024.d) |
||||||
|
- assert_equal rsa1024.public_key.to_der, key.to_der |
||||||
|
+ pub = OpenSSL::PKey.read(rsa1024.public_to_der) |
||||||
|
+ assert_not_equal rsa1024.to_der, pub.to_der |
||||||
|
+ assert_equal rsa1024.public_to_der, pub.to_der |
||||||
|
|
||||||
|
- # key has only n, e, d, p and q |
||||||
|
- key.set_factors(rsa1024.p, rsa1024.q) |
||||||
|
- assert_equal rsa1024.public_key.to_der, key.to_der |
||||||
|
+ # PKey is immutable in OpenSSL >= 3.0 |
||||||
|
+ if !openssl?(3, 0, 0) |
||||||
|
+ key = OpenSSL::PKey::RSA.new |
||||||
|
|
||||||
|
- # key has n, e, d, p, q, dmp1, dmq1 and iqmp |
||||||
|
- key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp) |
||||||
|
- assert_equal rsa1024.to_der, key.to_der |
||||||
|
+ # key has only n, e and d |
||||||
|
+ key.set_key(rsa1024.n, rsa1024.e, rsa1024.d) |
||||||
|
+ assert_equal rsa1024.public_key.to_der, key.to_der |
||||||
|
+ |
||||||
|
+ # key has only n, e, d, p and q |
||||||
|
+ key.set_factors(rsa1024.p, rsa1024.q) |
||||||
|
+ assert_equal rsa1024.public_key.to_der, key.to_der |
||||||
|
+ |
||||||
|
+ # key has n, e, d, p, q, dmp1, dmq1 and iqmp |
||||||
|
+ key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp) |
||||||
|
+ assert_equal rsa1024.to_der, key.to_der |
||||||
|
+ end |
||||||
|
end |
||||||
|
|
||||||
|
def test_RSAPrivateKey |
||||||
|
@@ -501,8 +520,12 @@ def test_dup |
||||||
|
key = Fixtures.pkey("rsa1024") |
||||||
|
key2 = key.dup |
||||||
|
assert_equal key.params, key2.params |
||||||
|
- key2.set_key(key2.n, 3, key2.d) |
||||||
|
- assert_not_equal key.params, key2.params |
||||||
|
+ |
||||||
|
+ # PKey is immutable in OpenSSL >= 3.0 |
||||||
|
+ if !openssl?(3, 0, 0) |
||||||
|
+ key2.set_key(key2.n, 3, key2.d) |
||||||
|
+ assert_not_equal key.params, key2.params |
||||||
|
+ end |
||||||
|
end |
||||||
|
|
||||||
|
def test_marshal |
@ -0,0 +1,27 @@ |
|||||||
|
From 47975ece4096cdab16b3f200f93ea2377dfb41ac Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Mon, 31 May 2021 14:17:21 +0900 |
||||||
|
Subject: [PATCH] test/openssl/test_pkey_rsa: disable test_no_private_exp on |
||||||
|
OpenSSL 3.0 |
||||||
|
|
||||||
|
OpenSSL::PKey::RSA#set_key does not exist when built with OpenSSL 3.0, |
||||||
|
so it is not possible to create an RSA object with incomplete state. |
||||||
|
|
||||||
|
https://github.com/ruby/openssl/commit/ca03c9c070 |
||||||
|
--- |
||||||
|
test/openssl/test_pkey_rsa.rb | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb |
||||||
|
index 4548bdb2cfa6..dbe87ba4c1b0 100644 |
||||||
|
--- a/test/openssl/test_pkey_rsa.rb |
||||||
|
+++ b/test/openssl/test_pkey_rsa.rb |
||||||
|
@@ -11,7 +11,7 @@ def test_no_private_exp |
||||||
|
key.set_factors(rsa.p, rsa.q) |
||||||
|
assert_raise(OpenSSL::PKey::RSAError){ key.private_encrypt("foo") } |
||||||
|
assert_raise(OpenSSL::PKey::RSAError){ key.private_decrypt("foo") } |
||||||
|
- end |
||||||
|
+ end if !openssl?(3, 0, 0) # Impossible state in OpenSSL 3.0 |
||||||
|
|
||||||
|
def test_private |
||||||
|
# Generated by key size and public exponent |
@ -0,0 +1,43 @@ |
|||||||
|
From 0ade5611df9f981005eed32b369d1e699e520221 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Thu, 10 Feb 2022 13:26:44 +0100 |
||||||
|
Subject: [PATCH] Don't query `RubyVM::FrozenCore` for class path. |
||||||
|
|
||||||
|
The `RubyVM::FrozenCore` class path is corrupted during GC cycle and |
||||||
|
returns random garbage, which might result in segfault. |
||||||
|
|
||||||
|
But since it is easy to detect the `RubyVM::FrozenCore`, just provide |
||||||
|
the class path explicitly as a workaround. |
||||||
|
|
||||||
|
Other possibility would be to ignore `RubyVM::FrozenCore` simlarly as |
||||||
|
TracePoint API does: |
||||||
|
|
||||||
|
https://github.com/ruby/ruby/blob/46f6575157d4c2f6bbd5693896e26a65037e5552/vm_trace.c#L411 |
||||||
|
--- |
||||||
|
vm.c | 10 +++++++++- |
||||||
|
1 file changed, 9 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/vm.c b/vm.c |
||||||
|
index 8ce8b279d4..3d189fa63a 100644 |
||||||
|
--- a/vm.c |
||||||
|
+++ b/vm.c |
||||||
|
@@ -446,7 +446,15 @@ rb_dtrace_setup(rb_execution_context_t *ec, VALUE klass, ID id, |
||||||
|
} |
||||||
|
type = BUILTIN_TYPE(klass); |
||||||
|
if (type == T_CLASS || type == T_ICLASS || type == T_MODULE) { |
||||||
|
- VALUE name = rb_class_path(klass); |
||||||
|
+ VALUE name = Qnil; |
||||||
|
+ /* |
||||||
|
+ * Special treatment for rb_mRubyVMFrozenCore wchi is broken by GC. |
||||||
|
+ * https://bugs.ruby-lang.org/issues/18257 |
||||||
|
+ */ |
||||||
|
+ if (klass == rb_mRubyVMFrozenCore) |
||||||
|
+ name = rb_str_new_cstr("RubyVM::FrozenCore"); |
||||||
|
+ else |
||||||
|
+ name = rb_class_path(klass); |
||||||
|
const char *classname, *filename; |
||||||
|
const char *methodname = rb_id2name(id); |
||||||
|
if (methodname && (filename = rb_source_location_cstr(&args->line_no)) != 0) { |
||||||
|
-- |
||||||
|
2.34.1 |
||||||
|
|
@ -0,0 +1,186 @@ |
|||||||
|
From 104b009e26c050584e4d186c8cc4e1496a14061b Mon Sep 17 00:00:00 2001 |
||||||
|
From: Nobuyoshi Nakada <nobu@ruby-lang.org> |
||||||
|
Date: Thu, 5 Aug 2021 20:09:25 +0900 |
||||||
|
Subject: [PATCH] Get rid of type-punning pointer casts [Bug #18062] |
||||||
|
|
||||||
|
--- |
||||||
|
vm_eval.c | 4 +++- |
||||||
|
vm_insnhelper.c | 7 +++++-- |
||||||
|
vm_method.c | 41 ++++++++++++++++++++++++++--------------- |
||||||
|
3 files changed, 34 insertions(+), 18 deletions(-) |
||||||
|
|
||||||
|
diff --git a/vm_eval.c b/vm_eval.c |
||||||
|
index 6d4b5c3c0b28..7ce9f157e671 100644 |
||||||
|
--- a/vm_eval.c |
||||||
|
+++ b/vm_eval.c |
||||||
|
@@ -350,9 +350,11 @@ cc_new(VALUE klass, ID mid, int argc, const rb_callable_method_entry_t *cme) |
||||||
|
{ |
||||||
|
struct rb_class_cc_entries *ccs; |
||||||
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); |
||||||
|
+ VALUE ccs_data; |
||||||
|
|
||||||
|
- if (rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs)) { |
||||||
|
+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { |
||||||
|
// ok |
||||||
|
+ ccs = (struct rb_class_cc_entries *)ccs_data; |
||||||
|
} |
||||||
|
else { |
||||||
|
ccs = vm_ccs_create(klass, cme); |
||||||
|
diff --git a/vm_insnhelper.c b/vm_insnhelper.c |
||||||
|
index 14928b2afe8e..e186376b24d7 100644 |
||||||
|
--- a/vm_insnhelper.c |
||||||
|
+++ b/vm_insnhelper.c |
||||||
|
@@ -1637,9 +1637,11 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci) |
||||||
|
const ID mid = vm_ci_mid(ci); |
||||||
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); |
||||||
|
struct rb_class_cc_entries *ccs = NULL; |
||||||
|
+ VALUE ccs_data; |
||||||
|
|
||||||
|
if (cc_tbl) { |
||||||
|
- if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { |
||||||
|
+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { |
||||||
|
+ ccs = (struct rb_class_cc_entries *)ccs_data; |
||||||
|
const int ccs_len = ccs->len; |
||||||
|
VM_ASSERT(vm_ccs_verify(ccs, mid, klass)); |
||||||
|
|
||||||
|
@@ -1706,8 +1708,9 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci) |
||||||
|
if (ccs == NULL) { |
||||||
|
VM_ASSERT(cc_tbl != NULL); |
||||||
|
|
||||||
|
- if (LIKELY(rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs))) { |
||||||
|
+ if (LIKELY(rb_id_table_lookup(cc_tbl, mid, &ccs_data))) { |
||||||
|
// rb_callable_method_entry() prepares ccs. |
||||||
|
+ ccs = (struct rb_class_cc_entries *)ccs_data; |
||||||
|
} |
||||||
|
else { |
||||||
|
// TODO: required? |
||||||
|
diff --git a/vm_method.c b/vm_method.c |
||||||
|
index 016dba1dbb18..1fd0bd57f7ca 100644 |
||||||
|
--- a/vm_method.c |
||||||
|
+++ b/vm_method.c |
||||||
|
@@ -42,11 +42,11 @@ vm_ccs_dump(VALUE klass, ID target_mid) |
||||||
|
{ |
||||||
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); |
||||||
|
if (cc_tbl) { |
||||||
|
- const struct rb_class_cc_entries *ccs; |
||||||
|
+ VALUE ccs; |
||||||
|
if (target_mid) { |
||||||
|
- if (rb_id_table_lookup(cc_tbl, target_mid, (VALUE *)&ccs)) { |
||||||
|
+ if (rb_id_table_lookup(cc_tbl, target_mid, &ccs)) { |
||||||
|
fprintf(stderr, " [CCTB] %p\n", (void *)cc_tbl); |
||||||
|
- vm_ccs_dump_i(target_mid, (VALUE)ccs, NULL); |
||||||
|
+ vm_ccs_dump_i(target_mid, ccs, NULL); |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
@@ -72,11 +72,11 @@ vm_mtbl_dump(VALUE klass, ID target_mid) |
||||||
|
fprintf(stderr, "# vm_mtbl\n"); |
||||||
|
while (klass) { |
||||||
|
rp_m(" -> ", klass); |
||||||
|
- rb_method_entry_t *me; |
||||||
|
+ VALUE me; |
||||||
|
|
||||||
|
if (RCLASS_M_TBL(klass)) { |
||||||
|
if (target_mid != 0) { |
||||||
|
- if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, (VALUE *)&me)) { |
||||||
|
+ if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, &me)) { |
||||||
|
rp_m(" [MTBL] ", me); |
||||||
|
} |
||||||
|
} |
||||||
|
@@ -90,7 +90,7 @@ vm_mtbl_dump(VALUE klass, ID target_mid) |
||||||
|
} |
||||||
|
if (RCLASS_CALLABLE_M_TBL(klass)) { |
||||||
|
if (target_mid != 0) { |
||||||
|
- if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, (VALUE *)&me)) { |
||||||
|
+ if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, &me)) { |
||||||
|
rp_m(" [CM**] ", me); |
||||||
|
} |
||||||
|
} |
||||||
|
@@ -144,10 +144,11 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) |
||||||
|
// check only current class |
||||||
|
|
||||||
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); |
||||||
|
- struct rb_class_cc_entries *ccs; |
||||||
|
+ VALUE ccs_data; |
||||||
|
|
||||||
|
// invalidate CCs |
||||||
|
- if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { |
||||||
|
+ if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { |
||||||
|
+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data; |
||||||
|
rb_vm_ccs_free(ccs); |
||||||
|
rb_id_table_delete(cc_tbl, mid); |
||||||
|
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_ccs); |
||||||
|
@@ -205,9 +206,10 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) |
||||||
|
} |
||||||
|
else { |
||||||
|
rb_vm_t *vm = GET_VM(); |
||||||
|
- if (rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) { |
||||||
|
+ VALUE cme_data = (VALUE) cme; |
||||||
|
+ if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) { |
||||||
|
rb_id_table_delete(vm->negative_cme_table, mid); |
||||||
|
- vm_me_invalidate_cache((rb_callable_method_entry_t *)cme); |
||||||
|
+ vm_me_invalidate_cache((rb_callable_method_entry_t *)cme_data); |
||||||
|
|
||||||
|
RB_DEBUG_COUNTER_INC(cc_invalidate_negative); |
||||||
|
} |
||||||
|
@@ -1023,6 +1025,7 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_ |
||||||
|
{ |
||||||
|
struct rb_id_table *mtbl; |
||||||
|
const rb_callable_method_entry_t *cme; |
||||||
|
+ VALUE cme_data; |
||||||
|
|
||||||
|
if (me) { |
||||||
|
if (me->defined_class == 0) { |
||||||
|
@@ -1032,7 +1035,8 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_ |
||||||
|
|
||||||
|
mtbl = RCLASS_CALLABLE_M_TBL(defined_class); |
||||||
|
|
||||||
|
- if (mtbl && rb_id_table_lookup(mtbl, id, (VALUE *)&cme)) { |
||||||
|
+ if (mtbl && rb_id_table_lookup(mtbl, id, &cme_data)) { |
||||||
|
+ cme = (rb_callable_method_entry_t *)cme_data; |
||||||
|
RB_DEBUG_COUNTER_INC(mc_cme_complement_hit); |
||||||
|
VM_ASSERT(callable_method_entry_p(cme)); |
||||||
|
VM_ASSERT(!METHOD_ENTRY_INVALIDATED(cme)); |
||||||
|
@@ -1076,9 +1080,10 @@ cached_callable_method_entry(VALUE klass, ID mid) |
||||||
|
ASSERT_vm_locking(); |
||||||
|
|
||||||
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); |
||||||
|
- struct rb_class_cc_entries *ccs; |
||||||
|
+ VALUE ccs_data; |
||||||
|
|
||||||
|
- if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { |
||||||
|
+ if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { |
||||||
|
+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data; |
||||||
|
VM_ASSERT(vm_ccs_p(ccs)); |
||||||
|
|
||||||
|
if (LIKELY(!METHOD_ENTRY_INVALIDATED(ccs->cme))) { |
||||||
|
@@ -1104,12 +1109,14 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_ |
||||||
|
|
||||||
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); |
||||||
|
struct rb_class_cc_entries *ccs; |
||||||
|
+ VALUE ccs_data; |
||||||
|
|
||||||
|
if (!cc_tbl) { |
||||||
|
cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2); |
||||||
|
} |
||||||
|
|
||||||
|
- if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { |
||||||
|
+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { |
||||||
|
+ ccs = (struct rb_class_cc_entries *)ccs_data; |
||||||
|
VM_ASSERT(ccs->cme == cme); |
||||||
|
} |
||||||
|
else { |
||||||
|
@@ -1123,8 +1130,12 @@ negative_cme(ID mid) |
||||||
|
{ |
||||||
|
rb_vm_t *vm = GET_VM(); |
||||||
|
const rb_callable_method_entry_t *cme; |
||||||
|
+ VALUE cme_data; |
||||||
|
|
||||||
|
- if (!rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) { |
||||||
|
+ if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) { |
||||||
|
+ cme = (rb_callable_method_entry_t *)cme_data; |
||||||
|
+ } |
||||||
|
+ else { |
||||||
|
cme = (rb_callable_method_entry_t *)rb_method_entry_alloc(mid, Qnil, Qnil, NULL); |
||||||
|
rb_id_table_insert(vm->negative_cme_table, mid, (VALUE)cme); |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
From 72317b333b85eed483ad00bcd4f40944019a7c13 Mon Sep 17 00:00:00 2001 |
||||||
|
From: "xtkoba+ruby@gmail.com" <xtkoba+ruby@gmail.com> |
||||||
|
Date: Fri, 13 Aug 2021 13:45:53 +0000 |
||||||
|
Subject: [PATCH] Ignore `DW_FORM_ref_addr` [Bug #17052] |
||||||
|
|
||||||
|
Ignore `DW_FORM_ref_addr` form and other forms that are not supposed |
||||||
|
to be used currently. |
||||||
|
--- |
||||||
|
addr2line.c | 23 ++++++++++++++++++++--- |
||||||
|
1 file changed, 20 insertions(+), 3 deletions(-) |
||||||
|
|
||||||
|
diff --git a/addr2line.c b/addr2line.c |
||||||
|
index fed1a8da84e5..92c6da5e3bea 100644 |
||||||
|
--- a/addr2line.c |
||||||
|
+++ b/addr2line.c |
||||||
|
@@ -1593,14 +1593,31 @@ di_read_cu(DebugInfoReader *reader) |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
-read_abstract_origin(DebugInfoReader *reader, uint64_t abstract_origin, line_info_t *line) |
||||||
|
+read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_origin, line_info_t *line) |
||||||
|
{ |
||||||
|
char *p = reader->p; |
||||||
|
char *q = reader->q; |
||||||
|
int level = reader->level; |
||||||
|
DIE die; |
||||||
|
|
||||||
|
- reader->p = reader->current_cu + abstract_origin; |
||||||
|
+ switch (form) { |
||||||
|
+ case DW_FORM_ref1: |
||||||
|
+ case DW_FORM_ref2: |
||||||
|
+ case DW_FORM_ref4: |
||||||
|
+ case DW_FORM_ref8: |
||||||
|
+ case DW_FORM_ref_udata: |
||||||
|
+ reader->p = reader->current_cu + abstract_origin; |
||||||
|
+ break; |
||||||
|
+ case DW_FORM_ref_addr: |
||||||
|
+ goto finish; /* not supported yet */ |
||||||
|
+ case DW_FORM_ref_sig8: |
||||||
|
+ goto finish; /* not supported yet */ |
||||||
|
+ case DW_FORM_ref_sup4: |
||||||
|
+ case DW_FORM_ref_sup8: |
||||||
|
+ goto finish; /* not supported yet */ |
||||||
|
+ default: |
||||||
|
+ goto finish; |
||||||
|
+ } |
||||||
|
if (!di_read_die(reader, &die)) goto finish; |
||||||
|
|
||||||
|
/* enumerate abbrev */ |
||||||
|
@@ -1665,7 +1682,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces, |
||||||
|
/* 1 or 3 */ |
||||||
|
break; /* goto skip_die; */ |
||||||
|
case DW_AT_abstract_origin: |
||||||
|
- read_abstract_origin(reader, v.as.uint64, &line); |
||||||
|
+ read_abstract_origin(reader, v.form, v.as.uint64, &line); |
||||||
|
break; /* goto skip_die; */ |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,523 @@ |
|||||||
|
From 8253d7c9cea16c2aa009b59db4f5d93afb74c6eb Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Tue, 30 Jun 2020 14:27:13 +0900 |
||||||
|
Subject: [PATCH 1/2] hmac: add a test case for OpenSSL::HMAC singleton methods |
||||||
|
|
||||||
|
--- |
||||||
|
test/openssl/test_hmac.rb | 9 +++++++++ |
||||||
|
1 file changed, 9 insertions(+) |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb |
||||||
|
index 9cb3c5a86..7202a5902 100644 |
||||||
|
--- a/test/openssl/test_hmac.rb |
||||||
|
+++ b/test/openssl/test_hmac.rb |
||||||
|
@@ -49,6 +49,15 @@ def test_eq |
||||||
|
refute_equal h1, h2.digest |
||||||
|
refute_equal h1, h3 |
||||||
|
end |
||||||
|
+ |
||||||
|
+ def test_singleton_methods |
||||||
|
+ # RFC 2202 2. Test Cases for HMAC-MD5 |
||||||
|
+ key = ["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*") |
||||||
|
+ digest = OpenSSL::HMAC.digest("MD5", key, "Hi There") |
||||||
|
+ assert_equal ["9294727a3638bb1c13f48ef8158bfc9d"].pack("H*"), digest |
||||||
|
+ hexdigest = OpenSSL::HMAC.hexdigest("MD5", key, "Hi There") |
||||||
|
+ assert_equal "9294727a3638bb1c13f48ef8158bfc9d", hexdigest |
||||||
|
+ end |
||||||
|
end |
||||||
|
|
||||||
|
end |
||||||
|
|
||||||
|
From 0317e2fc028be40a7d64d0e4337d3e21539613ce Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Mon, 18 May 2020 16:15:07 +0900 |
||||||
|
Subject: [PATCH 2/2] hmac: migrate from the low-level HMAC API to the EVP API |
||||||
|
|
||||||
|
Use the EVP API instead of the low-level HMAC API. Use of the HMAC API |
||||||
|
has been discouraged and is being marked as deprecated starting from |
||||||
|
OpenSSL 3.0.0. |
||||||
|
|
||||||
|
The two singleton methods OpenSSL::HMAC, HMAC.digest and HMAC.hexdigest |
||||||
|
are now in lib/openssl/hmac.rb. |
||||||
|
--- |
||||||
|
ext/openssl/extconf.rb | 3 +- |
||||||
|
ext/openssl/lib/openssl/hmac.rb | 40 +++++++ |
||||||
|
ext/openssl/openssl_missing.c | 26 ----- |
||||||
|
ext/openssl/openssl_missing.h | 10 +- |
||||||
|
ext/openssl/ossl.h | 1 - |
||||||
|
ext/openssl/ossl_hmac.c | 179 ++++++++------------------------ |
||||||
|
6 files changed, 89 insertions(+), 170 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb |
||||||
|
index 693e55cd9..063498a76 100644 |
||||||
|
--- a/ext/openssl/extconf.rb |
||||||
|
+++ b/ext/openssl/extconf.rb |
||||||
|
@@ -141,8 +141,7 @@ def find_openssl_library |
||||||
|
have_func("BN_GENCB_get_arg") |
||||||
|
have_func("EVP_MD_CTX_new") |
||||||
|
have_func("EVP_MD_CTX_free") |
||||||
|
-have_func("HMAC_CTX_new") |
||||||
|
-have_func("HMAC_CTX_free") |
||||||
|
+have_func("EVP_MD_CTX_pkey_ctx") |
||||||
|
have_func("X509_STORE_get_ex_data") |
||||||
|
have_func("X509_STORE_set_ex_data") |
||||||
|
have_func("X509_STORE_get_ex_new_index") |
||||||
|
diff --git a/ext/openssl/lib/openssl/hmac.rb b/ext/openssl/lib/openssl/hmac.rb |
||||||
|
index 3d4427611d..9bc8bc8df3 100644 |
||||||
|
--- a/ext/openssl/lib/openssl/hmac.rb |
||||||
|
+++ b/ext/openssl/lib/openssl/hmac.rb |
||||||
|
@@ -9,5 +9,45 @@ def ==(other) |
||||||
|
|
||||||
|
OpenSSL.fixed_length_secure_compare(self.digest, other.digest) |
||||||
|
end |
||||||
|
+ |
||||||
|
+ class << self |
||||||
|
+ # :call-seq: |
||||||
|
+ # HMAC.digest(digest, key, data) -> aString |
||||||
|
+ # |
||||||
|
+ # Returns the authentication code as a binary string. The _digest_ parameter |
||||||
|
+ # specifies the digest algorithm to use. This may be a String representing |
||||||
|
+ # the algorithm name or an instance of OpenSSL::Digest. |
||||||
|
+ # |
||||||
|
+ # === Example |
||||||
|
+ # key = 'key' |
||||||
|
+ # data = 'The quick brown fox jumps over the lazy dog' |
||||||
|
+ # |
||||||
|
+ # hmac = OpenSSL::HMAC.digest('SHA1', key, data) |
||||||
|
+ # #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9" |
||||||
|
+ def digest(digest, key, data) |
||||||
|
+ hmac = new(key, digest) |
||||||
|
+ hmac << data |
||||||
|
+ hmac.digest |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ # :call-seq: |
||||||
|
+ # HMAC.hexdigest(digest, key, data) -> aString |
||||||
|
+ # |
||||||
|
+ # Returns the authentication code as a hex-encoded string. The _digest_ |
||||||
|
+ # parameter specifies the digest algorithm to use. This may be a String |
||||||
|
+ # representing the algorithm name or an instance of OpenSSL::Digest. |
||||||
|
+ # |
||||||
|
+ # === Example |
||||||
|
+ # key = 'key' |
||||||
|
+ # data = 'The quick brown fox jumps over the lazy dog' |
||||||
|
+ # |
||||||
|
+ # hmac = OpenSSL::HMAC.hexdigest('SHA1', key, data) |
||||||
|
+ # #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" |
||||||
|
+ def hexdigest(digest, key, data) |
||||||
|
+ hmac = new(key, digest) |
||||||
|
+ hmac << data |
||||||
|
+ hmac.hexdigest |
||||||
|
+ end |
||||||
|
+ end |
||||||
|
end |
||||||
|
end |
||||||
|
diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c |
||||||
|
index b36ef0288..010c158dc 100644 |
||||||
|
--- a/ext/openssl/openssl_missing.c |
||||||
|
+++ b/ext/openssl/openssl_missing.c |
||||||
|
@@ -13,9 +13,6 @@ |
||||||
|
#if !defined(OPENSSL_NO_ENGINE) |
||||||
|
# include <openssl/engine.h> |
||||||
|
#endif |
||||||
|
-#if !defined(OPENSSL_NO_HMAC) |
||||||
|
-# include <openssl/hmac.h> |
||||||
|
-#endif |
||||||
|
#include <openssl/x509_vfy.h> |
||||||
|
|
||||||
|
#include "openssl_missing.h" |
||||||
|
@@ -58,29 +55,6 @@ ossl_EC_curve_nist2nid(const char *name) |
||||||
|
#endif |
||||||
|
|
||||||
|
/*** added in 1.1.0 ***/ |
||||||
|
-#if !defined(HAVE_HMAC_CTX_NEW) |
||||||
|
-HMAC_CTX * |
||||||
|
-ossl_HMAC_CTX_new(void) |
||||||
|
-{ |
||||||
|
- HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); |
||||||
|
- if (!ctx) |
||||||
|
- return NULL; |
||||||
|
- HMAC_CTX_init(ctx); |
||||||
|
- return ctx; |
||||||
|
-} |
||||||
|
-#endif |
||||||
|
- |
||||||
|
-#if !defined(HAVE_HMAC_CTX_FREE) |
||||||
|
-void |
||||||
|
-ossl_HMAC_CTX_free(HMAC_CTX *ctx) |
||||||
|
-{ |
||||||
|
- if (ctx) { |
||||||
|
- HMAC_CTX_cleanup(ctx); |
||||||
|
- OPENSSL_free(ctx); |
||||||
|
- } |
||||||
|
-} |
||||||
|
-#endif |
||||||
|
- |
||||||
|
#if !defined(HAVE_X509_CRL_GET0_SIGNATURE) |
||||||
|
void |
||||||
|
ossl_X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, |
||||||
|
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h |
||||||
|
index 7d218f86f..06d2a9082 100644 |
||||||
|
--- a/ext/openssl/openssl_missing.h |
||||||
|
+++ b/ext/openssl/openssl_missing.h |
||||||
|
@@ -54,14 +54,8 @@ int ossl_EC_curve_nist2nid(const char *); |
||||||
|
# define EVP_MD_CTX_free EVP_MD_CTX_destroy |
||||||
|
#endif |
||||||
|
|
||||||
|
-#if !defined(HAVE_HMAC_CTX_NEW) |
||||||
|
-HMAC_CTX *ossl_HMAC_CTX_new(void); |
||||||
|
-# define HMAC_CTX_new ossl_HMAC_CTX_new |
||||||
|
-#endif |
||||||
|
- |
||||||
|
-#if !defined(HAVE_HMAC_CTX_FREE) |
||||||
|
-void ossl_HMAC_CTX_free(HMAC_CTX *); |
||||||
|
-# define HMAC_CTX_free ossl_HMAC_CTX_free |
||||||
|
+#if !defined(HAVE_EVP_MD_CTX_PKEY_CTX) |
||||||
|
+# define EVP_MD_CTX_pkey_ctx(x) (x)->pctx |
||||||
|
#endif |
||||||
|
|
||||||
|
#if !defined(HAVE_X509_STORE_GET_EX_DATA) |
||||||
|
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h |
||||||
|
index c20f506bd..577eb6d6b 100644 |
||||||
|
--- a/ext/openssl/ossl.h |
||||||
|
+++ b/ext/openssl/ossl.h |
||||||
|
@@ -24,7 +24,6 @@ |
||||||
|
#include <openssl/ssl.h> |
||||||
|
#include <openssl/pkcs12.h> |
||||||
|
#include <openssl/pkcs7.h> |
||||||
|
-#include <openssl/hmac.h> |
||||||
|
#include <openssl/rand.h> |
||||||
|
#include <openssl/conf.h> |
||||||
|
#ifndef OPENSSL_NO_TS |
||||||
|
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c |
||||||
|
index 70e9fb819..a21db6c48 100644 |
||||||
|
--- a/ext/openssl/ossl_hmac.c |
||||||
|
+++ b/ext/openssl/ossl_hmac.c |
||||||
|
@@ -7,14 +7,12 @@ |
||||||
|
* This program is licensed under the same licence as Ruby. |
||||||
|
* (See the file 'LICENCE'.) |
||||||
|
*/ |
||||||
|
-#if !defined(OPENSSL_NO_HMAC) |
||||||
|
- |
||||||
|
#include "ossl.h" |
||||||
|
|
||||||
|
#define NewHMAC(klass) \ |
||||||
|
TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0) |
||||||
|
#define GetHMAC(obj, ctx) do { \ |
||||||
|
- TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \ |
||||||
|
+ TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_hmac_type, (ctx)); \ |
||||||
|
if (!(ctx)) { \ |
||||||
|
ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \ |
||||||
|
} \ |
||||||
|
@@ -36,7 +34,7 @@ VALUE eHMACError; |
||||||
|
static void |
||||||
|
ossl_hmac_free(void *ctx) |
||||||
|
{ |
||||||
|
- HMAC_CTX_free(ctx); |
||||||
|
+ EVP_MD_CTX_free(ctx); |
||||||
|
} |
||||||
|
|
||||||
|
static const rb_data_type_t ossl_hmac_type = { |
||||||
|
@@ -51,12 +49,12 @@ static VALUE |
||||||
|
ossl_hmac_alloc(VALUE klass) |
||||||
|
{ |
||||||
|
VALUE obj; |
||||||
|
- HMAC_CTX *ctx; |
||||||
|
+ EVP_MD_CTX *ctx; |
||||||
|
|
||||||
|
obj = NewHMAC(klass); |
||||||
|
- ctx = HMAC_CTX_new(); |
||||||
|
+ ctx = EVP_MD_CTX_new(); |
||||||
|
if (!ctx) |
||||||
|
- ossl_raise(eHMACError, NULL); |
||||||
|
+ ossl_raise(eHMACError, "EVP_MD_CTX"); |
||||||
|
RTYPEDDATA_DATA(obj) = ctx; |
||||||
|
|
||||||
|
return obj; |
||||||
|
@@ -76,8 +74,7 @@ ossl_hmac_alloc(VALUE klass) |
||||||
|
* === Example |
||||||
|
* |
||||||
|
* key = 'key' |
||||||
|
- * digest = OpenSSL::Digest.new('sha1') |
||||||
|
- * instance = OpenSSL::HMAC.new(key, digest) |
||||||
|
+ * instance = OpenSSL::HMAC.new(key, 'SHA1') |
||||||
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f |
||||||
|
* instance.class |
||||||
|
* #=> OpenSSL::HMAC |
||||||
|
@@ -86,7 +83,7 @@ ossl_hmac_alloc(VALUE klass) |
||||||
|
* |
||||||
|
* Two instances can be securely compared with #== in constant time: |
||||||
|
* |
||||||
|
- * other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) |
||||||
|
+ * other_instance = OpenSSL::HMAC.new('key', 'SHA1') |
||||||
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f |
||||||
|
* instance == other_instance |
||||||
|
* #=> true |
||||||
|
@@ -95,12 +92,23 @@ ossl_hmac_alloc(VALUE klass) |
||||||
|
static VALUE |
||||||
|
ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) |
||||||
|
{ |
||||||
|
- HMAC_CTX *ctx; |
||||||
|
+ EVP_MD_CTX *ctx; |
||||||
|
+ EVP_PKEY *pkey; |
||||||
|
|
||||||
|
- StringValue(key); |
||||||
|
GetHMAC(self, ctx); |
||||||
|
- HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key), |
||||||
|
- ossl_evp_get_digestbyname(digest), NULL); |
||||||
|
+ StringValue(key); |
||||||
|
+ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, |
||||||
|
+ (unsigned char *)RSTRING_PTR(key), |
||||||
|
+ RSTRING_LENINT(key)); |
||||||
|
+ if (!pkey) |
||||||
|
+ ossl_raise(eHMACError, "EVP_PKEY_new_mac_key"); |
||||||
|
+ if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest), |
||||||
|
+ NULL, pkey) != 1) { |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
+ ossl_raise(eHMACError, "EVP_DigestSignInit"); |
||||||
|
+ } |
||||||
|
+ /* Decrement reference counter; EVP_MD_CTX still keeps it */ |
||||||
|
+ EVP_PKEY_free(pkey); |
||||||
|
|
||||||
|
return self; |
||||||
|
} |
||||||
|
@@ -108,16 +116,15 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) |
||||||
|
static VALUE |
||||||
|
ossl_hmac_copy(VALUE self, VALUE other) |
||||||
|
{ |
||||||
|
- HMAC_CTX *ctx1, *ctx2; |
||||||
|
+ EVP_MD_CTX *ctx1, *ctx2; |
||||||
|
|
||||||
|
rb_check_frozen(self); |
||||||
|
if (self == other) return self; |
||||||
|
|
||||||
|
GetHMAC(self, ctx1); |
||||||
|
GetHMAC(other, ctx2); |
||||||
|
- |
||||||
|
- if (!HMAC_CTX_copy(ctx1, ctx2)) |
||||||
|
- ossl_raise(eHMACError, "HMAC_CTX_copy"); |
||||||
|
+ if (EVP_MD_CTX_copy(ctx1, ctx2) != 1) |
||||||
|
+ ossl_raise(eHMACError, "EVP_MD_CTX_copy"); |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
@@ -142,33 +149,16 @@ ossl_hmac_copy(VALUE self, VALUE other) |
||||||
|
static VALUE |
||||||
|
ossl_hmac_update(VALUE self, VALUE data) |
||||||
|
{ |
||||||
|
- HMAC_CTX *ctx; |
||||||
|
+ EVP_MD_CTX *ctx; |
||||||
|
|
||||||
|
StringValue(data); |
||||||
|
GetHMAC(self, ctx); |
||||||
|
- HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data)); |
||||||
|
+ if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1) |
||||||
|
+ ossl_raise(eHMACError, "EVP_DigestSignUpdate"); |
||||||
|
|
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
-static void |
||||||
|
-hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len) |
||||||
|
-{ |
||||||
|
- HMAC_CTX *final; |
||||||
|
- |
||||||
|
- final = HMAC_CTX_new(); |
||||||
|
- if (!final) |
||||||
|
- ossl_raise(eHMACError, "HMAC_CTX_new"); |
||||||
|
- |
||||||
|
- if (!HMAC_CTX_copy(final, ctx)) { |
||||||
|
- HMAC_CTX_free(final); |
||||||
|
- ossl_raise(eHMACError, "HMAC_CTX_copy"); |
||||||
|
- } |
||||||
|
- |
||||||
|
- HMAC_Final(final, buf, buf_len); |
||||||
|
- HMAC_CTX_free(final); |
||||||
|
-} |
||||||
|
- |
||||||
|
/* |
||||||
|
* call-seq: |
||||||
|
* hmac.digest -> string |
||||||
|
@@ -176,7 +166,7 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len) |
||||||
|
* Returns the authentication code an instance represents as a binary string. |
||||||
|
* |
||||||
|
* === Example |
||||||
|
- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) |
||||||
|
+ * instance = OpenSSL::HMAC.new('key', 'SHA1') |
||||||
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f |
||||||
|
* instance.digest |
||||||
|
* #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?" |
||||||
|
@@ -184,15 +174,16 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len) |
||||||
|
static VALUE |
||||||
|
ossl_hmac_digest(VALUE self) |
||||||
|
{ |
||||||
|
- HMAC_CTX *ctx; |
||||||
|
- unsigned int buf_len; |
||||||
|
+ EVP_MD_CTX *ctx; |
||||||
|
+ size_t buf_len; |
||||||
|
VALUE ret; |
||||||
|
|
||||||
|
GetHMAC(self, ctx); |
||||||
|
ret = rb_str_new(NULL, EVP_MAX_MD_SIZE); |
||||||
|
- hmac_final(ctx, (unsigned char *)RSTRING_PTR(ret), &buf_len); |
||||||
|
- assert(buf_len <= EVP_MAX_MD_SIZE); |
||||||
|
- rb_str_set_len(ret, buf_len); |
||||||
|
+ if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(ret), |
||||||
|
+ &buf_len) != 1) |
||||||
|
+ ossl_raise(eHMACError, "EVP_DigestSignFinal"); |
||||||
|
+ rb_str_set_len(ret, (long)buf_len); |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
@@ -207,13 +198,14 @@ ossl_hmac_digest(VALUE self) |
||||||
|
static VALUE |
||||||
|
ossl_hmac_hexdigest(VALUE self) |
||||||
|
{ |
||||||
|
- HMAC_CTX *ctx; |
||||||
|
+ EVP_MD_CTX *ctx; |
||||||
|
unsigned char buf[EVP_MAX_MD_SIZE]; |
||||||
|
- unsigned int buf_len; |
||||||
|
+ size_t buf_len; |
||||||
|
VALUE ret; |
||||||
|
|
||||||
|
GetHMAC(self, ctx); |
||||||
|
- hmac_final(ctx, buf, &buf_len); |
||||||
|
+ if (EVP_DigestSignFinal(ctx, buf, &buf_len) != 1) |
||||||
|
+ ossl_raise(eHMACError, "EVP_DigestSignFinal"); |
||||||
|
ret = rb_str_new(NULL, buf_len * 2); |
||||||
|
ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len); |
||||||
|
|
||||||
|
@@ -230,7 +222,7 @@ ossl_hmac_hexdigest(VALUE self) |
||||||
|
* === Example |
||||||
|
* |
||||||
|
* data = "The quick brown fox jumps over the lazy dog" |
||||||
|
- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) |
||||||
|
+ * instance = OpenSSL::HMAC.new('key', 'SHA1') |
||||||
|
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f |
||||||
|
* |
||||||
|
* instance.update(data) |
||||||
|
@@ -242,84 +234,17 @@ ossl_hmac_hexdigest(VALUE self) |
||||||
|
static VALUE |
||||||
|
ossl_hmac_reset(VALUE self) |
||||||
|
{ |
||||||
|
- HMAC_CTX *ctx; |
||||||
|
+ EVP_MD_CTX *ctx; |
||||||
|
+ EVP_PKEY *pkey; |
||||||
|
|
||||||
|
GetHMAC(self, ctx); |
||||||
|
- HMAC_Init_ex(ctx, NULL, 0, NULL, NULL); |
||||||
|
+ pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); |
||||||
|
+ if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_md(ctx), NULL, pkey) != 1) |
||||||
|
+ ossl_raise(eHMACError, "EVP_DigestSignInit"); |
||||||
|
|
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
-/* |
||||||
|
- * call-seq: |
||||||
|
- * HMAC.digest(digest, key, data) -> aString |
||||||
|
- * |
||||||
|
- * Returns the authentication code as a binary string. The _digest_ parameter |
||||||
|
- * specifies the digest algorithm to use. This may be a String representing |
||||||
|
- * the algorithm name or an instance of OpenSSL::Digest. |
||||||
|
- * |
||||||
|
- * === Example |
||||||
|
- * |
||||||
|
- * key = 'key' |
||||||
|
- * data = 'The quick brown fox jumps over the lazy dog' |
||||||
|
- * |
||||||
|
- * hmac = OpenSSL::HMAC.digest('sha1', key, data) |
||||||
|
- * #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9" |
||||||
|
- * |
||||||
|
- */ |
||||||
|
-static VALUE |
||||||
|
-ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data) |
||||||
|
-{ |
||||||
|
- unsigned char *buf; |
||||||
|
- unsigned int buf_len; |
||||||
|
- |
||||||
|
- StringValue(key); |
||||||
|
- StringValue(data); |
||||||
|
- buf = HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key), |
||||||
|
- RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data), |
||||||
|
- RSTRING_LEN(data), NULL, &buf_len); |
||||||
|
- |
||||||
|
- return rb_str_new((const char *)buf, buf_len); |
||||||
|
-} |
||||||
|
- |
||||||
|
-/* |
||||||
|
- * call-seq: |
||||||
|
- * HMAC.hexdigest(digest, key, data) -> aString |
||||||
|
- * |
||||||
|
- * Returns the authentication code as a hex-encoded string. The _digest_ |
||||||
|
- * parameter specifies the digest algorithm to use. This may be a String |
||||||
|
- * representing the algorithm name or an instance of OpenSSL::Digest. |
||||||
|
- * |
||||||
|
- * === Example |
||||||
|
- * |
||||||
|
- * key = 'key' |
||||||
|
- * data = 'The quick brown fox jumps over the lazy dog' |
||||||
|
- * |
||||||
|
- * hmac = OpenSSL::HMAC.hexdigest('sha1', key, data) |
||||||
|
- * #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" |
||||||
|
- * |
||||||
|
- */ |
||||||
|
-static VALUE |
||||||
|
-ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data) |
||||||
|
-{ |
||||||
|
- unsigned char buf[EVP_MAX_MD_SIZE]; |
||||||
|
- unsigned int buf_len; |
||||||
|
- VALUE ret; |
||||||
|
- |
||||||
|
- StringValue(key); |
||||||
|
- StringValue(data); |
||||||
|
- |
||||||
|
- if (!HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key), |
||||||
|
- RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data), |
||||||
|
- RSTRING_LEN(data), buf, &buf_len)) |
||||||
|
- ossl_raise(eHMACError, "HMAC"); |
||||||
|
- |
||||||
|
- ret = rb_str_new(NULL, buf_len * 2); |
||||||
|
- ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len); |
||||||
|
- |
||||||
|
- return ret; |
||||||
|
-} |
||||||
|
- |
||||||
|
/* |
||||||
|
* INIT |
||||||
|
*/ |
||||||
|
@@ -353,8 +278,7 @@ Init_ossl_hmac(void) |
||||||
|
* data1 = File.read("file1") |
||||||
|
* data2 = File.read("file2") |
||||||
|
* key = "key" |
||||||
|
- * digest = OpenSSL::Digest.new('SHA256') |
||||||
|
- * hmac = OpenSSL::HMAC.new(key, digest) |
||||||
|
+ * hmac = OpenSSL::HMAC.new(key, 'SHA256') |
||||||
|
* hmac << data1 |
||||||
|
* hmac << data2 |
||||||
|
* mac = hmac.digest |
||||||
|
@@ -364,8 +288,6 @@ Init_ossl_hmac(void) |
||||||
|
cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject); |
||||||
|
|
||||||
|
rb_define_alloc_func(cHMAC, ossl_hmac_alloc); |
||||||
|
- rb_define_singleton_method(cHMAC, "digest", ossl_hmac_s_digest, 3); |
||||||
|
- rb_define_singleton_method(cHMAC, "hexdigest", ossl_hmac_s_hexdigest, 3); |
||||||
|
|
||||||
|
rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2); |
||||||
|
rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1); |
||||||
|
@@ -378,12 +300,3 @@ Init_ossl_hmac(void) |
||||||
|
rb_define_alias(cHMAC, "inspect", "hexdigest"); |
||||||
|
rb_define_alias(cHMAC, "to_s", "hexdigest"); |
||||||
|
} |
||||||
|
- |
||||||
|
-#else /* NO_HMAC */ |
||||||
|
-# warning >>> OpenSSL is compiled without HMAC support <<< |
||||||
|
-void |
||||||
|
-Init_ossl_hmac(void) |
||||||
|
-{ |
||||||
|
- rb_warning("HMAC is not available: OpenSSL is compiled without HMAC."); |
||||||
|
-} |
||||||
|
-#endif /* NO_HMAC */ |
||||||
|
-- |
||||||
|
2.34.1 |
||||||
|
|
@ -0,0 +1,458 @@ |
|||||||
|
From 91d04f991f8b9910efea7bbe5aecb0fea2bbd5fa Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Sun, 24 Oct 2021 17:50:18 +0900 |
||||||
|
Subject: [PATCH 1/8] cipher: update test_ciphers |
||||||
|
|
||||||
|
Do not attempt to actually use all algorithms. Not all algorithms listed |
||||||
|
in OpenSSL::Cipher.ciphers are always available. |
||||||
|
--- |
||||||
|
test/openssl/test_cipher.rb | 13 +++++-------- |
||||||
|
1 file changed, 5 insertions(+), 8 deletions(-) |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb |
||||||
|
index 6d18c0c8..b5fdf0b3 100644 |
||||||
|
--- a/test/openssl/test_cipher.rb |
||||||
|
+++ b/test/openssl/test_cipher.rb |
||||||
|
@@ -135,14 +135,11 @@ def test_ctr_if_exists |
||||||
|
end |
||||||
|
|
||||||
|
def test_ciphers |
||||||
|
- OpenSSL::Cipher.ciphers.each{|name| |
||||||
|
- next if /netbsd/ =~ RUBY_PLATFORM && /idea|rc5/i =~ name |
||||||
|
- begin |
||||||
|
- assert_kind_of(OpenSSL::Cipher, OpenSSL::Cipher.new(name)) |
||||||
|
- rescue OpenSSL::Cipher::CipherError => e |
||||||
|
- raise unless /wrap/ =~ name and /wrap mode not allowed/ =~ e.message |
||||||
|
- end |
||||||
|
- } |
||||||
|
+ ciphers = OpenSSL::Cipher.ciphers |
||||||
|
+ assert_kind_of Array, ciphers |
||||||
|
+ assert_include ciphers, "aes-128-cbc" |
||||||
|
+ assert_include ciphers, "aes128" # alias of aes-128-cbc |
||||||
|
+ assert_include ciphers, "aes-128-gcm" |
||||||
|
end |
||||||
|
|
||||||
|
def test_AES |
||||||
|
|
||||||
|
From 6a60c7b2e7b6afe8b8c98d864ef2740094d86e1d Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Sat, 11 Dec 2021 16:27:42 +0900 |
||||||
|
Subject: [PATCH 2/8] hmac: fix wrong usage of EVP_DigestSignFinal() |
||||||
|
|
||||||
|
According to the manpage, the "siglen" parameter must be initialized |
||||||
|
beforehand. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_hmac.c | 4 ++-- |
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c |
||||||
|
index f89ff2f9..bfe3a74b 100644 |
||||||
|
--- a/ext/openssl/ossl_hmac.c |
||||||
|
+++ b/ext/openssl/ossl_hmac.c |
||||||
|
@@ -175,7 +175,7 @@ static VALUE |
||||||
|
ossl_hmac_digest(VALUE self) |
||||||
|
{ |
||||||
|
EVP_MD_CTX *ctx; |
||||||
|
- size_t buf_len; |
||||||
|
+ size_t buf_len = EVP_MAX_MD_SIZE; |
||||||
|
VALUE ret; |
||||||
|
|
||||||
|
GetHMAC(self, ctx); |
||||||
|
@@ -200,7 +200,7 @@ ossl_hmac_hexdigest(VALUE self) |
||||||
|
{ |
||||||
|
EVP_MD_CTX *ctx; |
||||||
|
unsigned char buf[EVP_MAX_MD_SIZE]; |
||||||
|
- size_t buf_len; |
||||||
|
+ size_t buf_len = EVP_MAX_MD_SIZE; |
||||||
|
VALUE ret; |
||||||
|
|
||||||
|
GetHMAC(self, ctx); |
||||||
|
|
||||||
|
From 46995816392a79d037df5550b2fb226652c06f42 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Sat, 11 Dec 2021 16:30:30 +0900 |
||||||
|
Subject: [PATCH 3/8] hmac: skip test_dup on OpenSSL 3.0 for now |
||||||
|
|
||||||
|
EVP_MD_CTX_copy() doesn't seem to work as intended on HMAC EVP_MD_CTX |
||||||
|
on OpenSSL 3.0.0 and causes a double free. I haven't found the root |
||||||
|
problem yet, but let's skip the test case for now. |
||||||
|
--- |
||||||
|
test/openssl/test_hmac.rb | 1 + |
||||||
|
1 file changed, 1 insertion(+) |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb |
||||||
|
index 2f53a813..47cb3718 100644 |
||||||
|
--- a/test/openssl/test_hmac.rb |
||||||
|
+++ b/test/openssl/test_hmac.rb |
||||||
|
@@ -19,6 +19,7 @@ def test_hmac |
||||||
|
end |
||||||
|
|
||||||
|
def test_dup |
||||||
|
+ pend "HMAC#initialize_copy is currently broken on OpenSSL 3.0.0" if openssl?(3, 0, 0) |
||||||
|
h1 = OpenSSL::HMAC.new("KEY", "MD5") |
||||||
|
h1.update("DATA") |
||||||
|
h = h1.dup |
||||||
|
|
||||||
|
From 69a27d8de4bd291cb4eb21a4d715b197e7da5a06 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Thu, 15 Apr 2021 00:51:58 +0900 |
||||||
|
Subject: [PATCH 4/8] engine: disable OpenSSL::Engine on OpenSSL 3.0 |
||||||
|
|
||||||
|
The entire ENGINE API is deprecated in OpenSSL 3.0 in favor of the new |
||||||
|
"Provider" concept. |
||||||
|
|
||||||
|
OpenSSL::Engine will not be defined when compiled with OpenSSL 3.0. |
||||||
|
We would need a way to interact with providers from Ruby programs, but |
||||||
|
since the concept is completely different from the ENGINE API, it will |
||||||
|
not be through the current OpenSSL::Engine interface. |
||||||
|
--- |
||||||
|
ext/openssl/openssl_missing.c | 3 --- |
||||||
|
ext/openssl/ossl.h | 8 +++++--- |
||||||
|
ext/openssl/ossl_engine.c | 3 ++- |
||||||
|
ext/openssl/ossl_pkey.c | 4 ++++ |
||||||
|
4 files changed, 11 insertions(+), 7 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c |
||||||
|
index 8b93cba6..4415703d 100644 |
||||||
|
--- a/ext/openssl/openssl_missing.c |
||||||
|
+++ b/ext/openssl/openssl_missing.c |
||||||
|
@@ -10,9 +10,6 @@ |
||||||
|
#include RUBY_EXTCONF_H |
||||||
|
|
||||||
|
#include <string.h> /* memcpy() */ |
||||||
|
-#if !defined(OPENSSL_NO_ENGINE) |
||||||
|
-# include <openssl/engine.h> |
||||||
|
-#endif |
||||||
|
#include <openssl/x509_vfy.h> |
||||||
|
|
||||||
|
#include "openssl_missing.h" |
||||||
|
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h |
||||||
|
index 3a0ab1e5..4b512689 100644 |
||||||
|
--- a/ext/openssl/ossl.h |
||||||
|
+++ b/ext/openssl/ossl.h |
||||||
|
@@ -18,6 +18,7 @@ |
||||||
|
#include <ruby/io.h> |
||||||
|
#include <ruby/thread.h> |
||||||
|
#include <openssl/opensslv.h> |
||||||
|
+ |
||||||
|
#include <openssl/err.h> |
||||||
|
#include <openssl/asn1.h> |
||||||
|
#include <openssl/x509v3.h> |
||||||
|
@@ -30,9 +31,6 @@ |
||||||
|
#include <openssl/ts.h> |
||||||
|
#endif |
||||||
|
#include <openssl/crypto.h> |
||||||
|
-#if !defined(OPENSSL_NO_ENGINE) |
||||||
|
-# include <openssl/engine.h> |
||||||
|
-#endif |
||||||
|
#if !defined(OPENSSL_NO_OCSP) |
||||||
|
# include <openssl/ocsp.h> |
||||||
|
#endif |
||||||
|
@@ -54,6 +52,10 @@ |
||||||
|
(LIBRESSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12)) |
||||||
|
#endif |
||||||
|
|
||||||
|
+#if !defined(OPENSSL_NO_ENGINE) && !OSSL_OPENSSL_PREREQ(3, 0, 0) |
||||||
|
+# define OSSL_USE_ENGINE |
||||||
|
+#endif |
||||||
|
+ |
||||||
|
/* |
||||||
|
* Common Module |
||||||
|
*/ |
||||||
|
diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c |
||||||
|
index 661a1368..1abde7f7 100644 |
||||||
|
--- a/ext/openssl/ossl_engine.c |
||||||
|
+++ b/ext/openssl/ossl_engine.c |
||||||
|
@@ -9,7 +9,8 @@ |
||||||
|
*/ |
||||||
|
#include "ossl.h" |
||||||
|
|
||||||
|
-#if !defined(OPENSSL_NO_ENGINE) |
||||||
|
+#ifdef OSSL_USE_ENGINE |
||||||
|
+# include <openssl/engine.h> |
||||||
|
|
||||||
|
#define NewEngine(klass) \ |
||||||
|
TypedData_Wrap_Struct((klass), &ossl_engine_type, 0) |
||||||
|
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c |
||||||
|
index 7030be3c..94760d32 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.c |
||||||
|
+++ b/ext/openssl/ossl_pkey.c |
||||||
|
@@ -9,6 +9,10 @@ |
||||||
|
*/ |
||||||
|
#include "ossl.h" |
||||||
|
|
||||||
|
+#ifdef OSSL_USE_ENGINE |
||||||
|
+# include <openssl/engine.h> |
||||||
|
+#endif |
||||||
|
+ |
||||||
|
/* |
||||||
|
* Classes |
||||||
|
*/ |
||||||
|
|
||||||
|
From b1ee2f23b28c2d0b14fd9b4b9fef13e870370746 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Wed, 17 Nov 2021 11:39:06 +0900 |
||||||
|
Subject: [PATCH 5/8] ssl: add constants for new SSL_OP_* flags |
||||||
|
|
||||||
|
Add all SSL_OP_* constants defined in OpenSSL 3.0.0 which are not |
||||||
|
specific to DTLS. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_ssl.c | 35 +++++++++++++++++++++++++++++------ |
||||||
|
1 file changed, 29 insertions(+), 6 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c |
||||||
|
index 3b425ca7..9a0682a7 100644 |
||||||
|
--- a/ext/openssl/ossl_ssl.c |
||||||
|
+++ b/ext/openssl/ossl_ssl.c |
||||||
|
@@ -2941,13 +2941,28 @@ Init_ossl_ssl(void) |
||||||
|
rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE)); |
||||||
|
|
||||||
|
rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL)); |
||||||
|
+#ifdef SSL_OP_CLEANSE_PLAINTEXT /* OpenSSL 3.0 */ |
||||||
|
+ rb_define_const(mSSL, "OP_CLEANSE_PLAINTEXT", ULONG2NUM(SSL_OP_CLEANSE_PLAINTEXT)); |
||||||
|
+#endif |
||||||
|
rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT)); |
||||||
|
+#ifdef SSL_OP_ENABLE_KTLS /* OpenSSL 3.0 */ |
||||||
|
+ rb_define_const(mSSL, "OP_ENABLE_KTLS", ULONG2NUM(SSL_OP_ENABLE_KTLS)); |
||||||
|
+#endif |
||||||
|
#ifdef SSL_OP_TLSEXT_PADDING /* OpenSSL 1.0.1h and OpenSSL 1.0.2 */ |
||||||
|
rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING)); |
||||||
|
#endif |
||||||
|
#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG /* OpenSSL 1.0.1f and OpenSSL 1.0.2 */ |
||||||
|
rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG)); |
||||||
|
#endif |
||||||
|
+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* OpenSSL 3.0 */ |
||||||
|
+ rb_define_const(mSSL, "OP_IGNORE_UNEXPECTED_EOF", ULONG2NUM(SSL_OP_IGNORE_UNEXPECTED_EOF)); |
||||||
|
+#endif |
||||||
|
+#ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION /* OpenSSL 3.0 */ |
||||||
|
+ rb_define_const(mSSL, "OP_ALLOW_CLIENT_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_CLIENT_RENEGOTIATION)); |
||||||
|
+#endif |
||||||
|
+#ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */ |
||||||
|
+ rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES)); |
||||||
|
+#endif |
||||||
|
#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */ |
||||||
|
rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX)); |
||||||
|
#endif |
||||||
|
@@ -2959,13 +2974,15 @@ Init_ossl_ssl(void) |
||||||
|
#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */ |
||||||
|
rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC)); |
||||||
|
#endif |
||||||
|
- rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE)); |
||||||
|
- rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG)); |
||||||
|
-#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */ |
||||||
|
- rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION)); |
||||||
|
+#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */ |
||||||
|
+ rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT)); |
||||||
|
+#endif |
||||||
|
+#ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */ |
||||||
|
+ rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA)); |
||||||
|
+#endif |
||||||
|
+#ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */ |
||||||
|
+ rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY)); |
||||||
|
#endif |
||||||
|
- rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG)); |
||||||
|
- |
||||||
|
rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3)); |
||||||
|
rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1)); |
||||||
|
rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1)); |
||||||
|
@@ -2973,6 +2990,12 @@ Init_ossl_ssl(void) |
||||||
|
#ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */ |
||||||
|
rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3)); |
||||||
|
#endif |
||||||
|
+ rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE)); |
||||||
|
+ rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG)); |
||||||
|
+#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */ |
||||||
|
+ rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION)); |
||||||
|
+#endif |
||||||
|
+ rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG)); |
||||||
|
|
||||||
|
/* SSL_OP_* flags for DTLS */ |
||||||
|
#if 0 |
||||||
|
|
||||||
|
From e168df0f3570709bfb38e9a39838bd0a7e78164c Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Sun, 12 Dec 2021 00:47:35 +0900 |
||||||
|
Subject: [PATCH 6/8] ssl: update test_options_disable_versions |
||||||
|
|
||||||
|
Use the combination of TLS 1.2 and TLS 1.3 instead of TLS 1.1 and TLS |
||||||
|
1.2 so that will the test case will be run on latest platforms. |
||||||
|
--- |
||||||
|
test/openssl/test_ssl.rb | 75 +++++++++++++++++++++------------------- |
||||||
|
1 file changed, 40 insertions(+), 35 deletions(-) |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb |
||||||
|
index 22691292..2abade06 100644 |
||||||
|
--- a/test/openssl/test_ssl.rb |
||||||
|
+++ b/test/openssl/test_ssl.rb |
||||||
|
@@ -1180,46 +1180,51 @@ def test_minmax_version |
||||||
|
end |
||||||
|
|
||||||
|
def test_options_disable_versions |
||||||
|
- # Note: Use of these OP_* flags has been deprecated since OpenSSL 1.1.0. |
||||||
|
+ # It's recommended to use SSLContext#{min,max}_version= instead in real |
||||||
|
+ # applications. The purpose of this test case is to check that SSL options |
||||||
|
+ # are properly propagated to OpenSSL library. |
||||||
|
supported = check_supported_protocol_versions |
||||||
|
+ if !defined?(OpenSSL::SSL::TLS1_3_VERSION) || |
||||||
|
+ !supported.include?(OpenSSL::SSL::TLS1_2_VERSION) || |
||||||
|
+ !supported.include?(OpenSSL::SSL::TLS1_3_VERSION) || |
||||||
|
+ !defined?(OpenSSL::SSL::OP_NO_TLSv1_3) # LibreSSL < 3.4 |
||||||
|
+ pend "this test case requires both TLS 1.2 and TLS 1.3 to be supported " \ |
||||||
|
+ "and enabled by default" |
||||||
|
+ end |
||||||
|
|
||||||
|
- if supported.include?(OpenSSL::SSL::TLS1_1_VERSION) && |
||||||
|
- supported.include?(OpenSSL::SSL::TLS1_2_VERSION) |
||||||
|
- # Server disables ~ TLS 1.1 |
||||||
|
- ctx_proc = proc { |ctx| |
||||||
|
- ctx.options |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 | |
||||||
|
- OpenSSL::SSL::OP_NO_TLSv1 | OpenSSL::SSL::OP_NO_TLSv1_1 |
||||||
|
- } |
||||||
|
- start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port| |
||||||
|
- # Client only supports TLS 1.1 |
||||||
|
- ctx1 = OpenSSL::SSL::SSLContext.new |
||||||
|
- ctx1.min_version = ctx1.max_version = OpenSSL::SSL::TLS1_1_VERSION |
||||||
|
- assert_handshake_error { server_connect(port, ctx1) { } } |
||||||
|
+ # Server disables TLS 1.2 and earlier |
||||||
|
+ ctx_proc = proc { |ctx| |
||||||
|
+ ctx.options |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 | |
||||||
|
+ OpenSSL::SSL::OP_NO_TLSv1 | OpenSSL::SSL::OP_NO_TLSv1_1 | |
||||||
|
+ OpenSSL::SSL::OP_NO_TLSv1_2 |
||||||
|
+ } |
||||||
|
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port| |
||||||
|
+ # Client only supports TLS 1.2 |
||||||
|
+ ctx1 = OpenSSL::SSL::SSLContext.new |
||||||
|
+ ctx1.min_version = ctx1.max_version = OpenSSL::SSL::TLS1_2_VERSION |
||||||
|
+ assert_handshake_error { server_connect(port, ctx1) { } } |
||||||
|
|
||||||
|
- # Client only supports TLS 1.2 |
||||||
|
- ctx2 = OpenSSL::SSL::SSLContext.new |
||||||
|
- ctx2.min_version = ctx2.max_version = OpenSSL::SSL::TLS1_2_VERSION |
||||||
|
- assert_nothing_raised { server_connect(port, ctx2) { } } |
||||||
|
- } |
||||||
|
+ # Client only supports TLS 1.3 |
||||||
|
+ ctx2 = OpenSSL::SSL::SSLContext.new |
||||||
|
+ ctx2.min_version = ctx2.max_version = OpenSSL::SSL::TLS1_3_VERSION |
||||||
|
+ assert_nothing_raised { server_connect(port, ctx2) { } } |
||||||
|
+ } |
||||||
|
|
||||||
|
- # Server only supports TLS 1.1 |
||||||
|
- ctx_proc = proc { |ctx| |
||||||
|
- ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_1_VERSION |
||||||
|
- } |
||||||
|
- start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port| |
||||||
|
- # Client disables TLS 1.1 |
||||||
|
- ctx1 = OpenSSL::SSL::SSLContext.new |
||||||
|
- ctx1.options |= OpenSSL::SSL::OP_NO_TLSv1_1 |
||||||
|
- assert_handshake_error { server_connect(port, ctx1) { } } |
||||||
|
+ # Server only supports TLS 1.2 |
||||||
|
+ ctx_proc = proc { |ctx| |
||||||
|
+ ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION |
||||||
|
+ } |
||||||
|
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port| |
||||||
|
+ # Client doesn't support TLS 1.2 |
||||||
|
+ ctx1 = OpenSSL::SSL::SSLContext.new |
||||||
|
+ ctx1.options |= OpenSSL::SSL::OP_NO_TLSv1_2 |
||||||
|
+ assert_handshake_error { server_connect(port, ctx1) { } } |
||||||
|
|
||||||
|
- # Client disables TLS 1.2 |
||||||
|
- ctx2 = OpenSSL::SSL::SSLContext.new |
||||||
|
- ctx2.options |= OpenSSL::SSL::OP_NO_TLSv1_2 |
||||||
|
- assert_nothing_raised { server_connect(port, ctx2) { } } |
||||||
|
- } |
||||||
|
- else |
||||||
|
- pend "TLS 1.1 and TLS 1.2 must be supported; skipping" |
||||||
|
- end |
||||||
|
+ # Client supports TLS 1.2 by default |
||||||
|
+ ctx2 = OpenSSL::SSL::SSLContext.new |
||||||
|
+ ctx2.options |= OpenSSL::SSL::OP_NO_TLSv1_3 |
||||||
|
+ assert_nothing_raised { server_connect(port, ctx2) { } } |
||||||
|
+ } |
||||||
|
end |
||||||
|
|
||||||
|
def test_ssl_methods_constant |
||||||
|
|
||||||
|
From ccdb6f7bfa5f988a07beecedbf2b6205b6ab8492 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Sat, 20 Mar 2021 23:16:41 +0900 |
||||||
|
Subject: [PATCH 7/8] pkey: assume a pkey always has public key components on |
||||||
|
OpenSSL 3.0 |
||||||
|
|
||||||
|
OpenSSL 3.0's EVP_PKEY_get0() returns NULL for provider-backed pkeys. |
||||||
|
This causes segfault because it was supposed to never return NULL |
||||||
|
before. |
||||||
|
|
||||||
|
We can't check the existence of public key components in this way on |
||||||
|
OpenSSL 3.0. Let's just skip it for now. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_pkey.c | 11 +++++++++++ |
||||||
|
1 file changed, 11 insertions(+) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c |
||||||
|
index 94760d32..09d45d85 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.c |
||||||
|
+++ b/ext/openssl/ossl_pkey.c |
||||||
|
@@ -428,9 +428,19 @@ ossl_pkey_s_generate_key(int argc, VALUE *argv, VALUE self) |
||||||
|
return pkey_generate(argc, argv, self, 0); |
||||||
|
} |
||||||
|
|
||||||
|
+/* |
||||||
|
+ * TODO: There is no convenient way to check the presence of public key |
||||||
|
+ * components on OpenSSL 3.0. But since keys are immutable on 3.0, pkeys without |
||||||
|
+ * these should only be created by OpenSSL::PKey.generate_parameters or by |
||||||
|
+ * parsing DER-/PEM-encoded string. We would need another flag for that. |
||||||
|
+ */ |
||||||
|
void |
||||||
|
ossl_pkey_check_public_key(const EVP_PKEY *pkey) |
||||||
|
{ |
||||||
|
+#if OSSL_OPENSSL_PREREQ(3, 0, 0) |
||||||
|
+ if (EVP_PKEY_missing_parameters(pkey)) |
||||||
|
+ ossl_raise(ePKeyError, "parameters missing"); |
||||||
|
+#else |
||||||
|
void *ptr; |
||||||
|
const BIGNUM *n, *e, *pubkey; |
||||||
|
|
||||||
|
@@ -466,6 +476,7 @@ ossl_pkey_check_public_key(const EVP_PKEY *pkey) |
||||||
|
return; |
||||||
|
} |
||||||
|
ossl_raise(ePKeyError, "public key missing"); |
||||||
|
+#endif |
||||||
|
} |
||||||
|
|
||||||
|
EVP_PKEY * |
||||||
|
|
||||||
|
From d6535d13d174cd87ae99f3e60e97f7a00e1474e5 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Mon, 12 Apr 2021 10:43:46 +0900 |
||||||
|
Subject: [PATCH 8/8] pkey: use EVP_PKEY_CTX_new_from_name() on OpenSSL 3.0 |
||||||
|
|
||||||
|
Replace EVP_PKEY_CTX_new_id() with the new EVP_PKEY_CTX_new_from_name() |
||||||
|
which takes the algorithm name in a string instead of in an NID. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_pkey.c | 6 ++++++ |
||||||
|
1 file changed, 6 insertions(+) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c |
||||||
|
index 09d45d85..2a4835a2 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.c |
||||||
|
+++ b/ext/openssl/ossl_pkey.c |
||||||
|
@@ -315,6 +315,11 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam) |
||||||
|
ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); |
||||||
|
} |
||||||
|
else { |
||||||
|
+#if OSSL_OPENSSL_PREREQ(3, 0, 0) |
||||||
|
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, StringValueCStr(alg), NULL); |
||||||
|
+ if (!ctx) |
||||||
|
+ ossl_raise(ePKeyError, "EVP_PKEY_CTX_new_from_name"); |
||||||
|
+#else |
||||||
|
const EVP_PKEY_ASN1_METHOD *ameth; |
||||||
|
ENGINE *tmpeng; |
||||||
|
int pkey_id; |
||||||
|
@@ -333,6 +338,7 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam) |
||||||
|
ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL/* engine */); |
||||||
|
if (!ctx) |
||||||
|
ossl_raise(ePKeyError, "EVP_PKEY_CTX_new_id"); |
||||||
|
+#endif |
||||||
|
} |
||||||
|
|
||||||
|
if (genparam && EVP_PKEY_paramgen_init(ctx) <= 0) { |
@ -0,0 +1,304 @@ |
|||||||
|
From 8f948ed68a4ed6c05ff66d822711e3b70ae4bb3f Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Mon, 27 Sep 2021 13:32:03 +0900 |
||||||
|
Subject: [PATCH 1/5] ext/openssl/ossl.h: add helper macros for |
||||||
|
OpenSSL/LibreSSL versions |
||||||
|
|
||||||
|
Add following convenient macros: |
||||||
|
|
||||||
|
- OSSL_IS_LIBRESSL |
||||||
|
- OSSL_OPENSSL_PREREQ(maj, min, pat) |
||||||
|
- OSSL_LIBRESSL_PREREQ(maj, min, pat) |
||||||
|
--- |
||||||
|
ext/openssl/ossl.h | 12 ++++++++++++ |
||||||
|
1 file changed, 12 insertions(+) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h |
||||||
|
index c20f506bda..a0cef29d74 100644 |
||||||
|
--- a/ext/openssl/ossl.h |
||||||
|
+++ b/ext/openssl/ossl.h |
||||||
|
@@ -42,6 +42,18 @@ |
||||||
|
#include <openssl/evp.h> |
||||||
|
#include <openssl/dh.h> |
||||||
|
|
||||||
|
+#ifndef LIBRESSL_VERSION_NUMBER |
||||||
|
+# define OSSL_IS_LIBRESSL 0 |
||||||
|
+# define OSSL_OPENSSL_PREREQ(maj, min, pat) \ |
||||||
|
+ (OPENSSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12)) |
||||||
|
+# define OSSL_LIBRESSL_PREREQ(maj, min, pat) 0 |
||||||
|
+#else |
||||||
|
+# define OSSL_IS_LIBRESSL 1 |
||||||
|
+# define OSSL_OPENSSL_PREREQ(maj, min, pat) 0 |
||||||
|
+# define OSSL_LIBRESSL_PREREQ(maj, min, pat) \ |
||||||
|
+ (LIBRESSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12)) |
||||||
|
+#endif |
||||||
|
+ |
||||||
|
/* |
||||||
|
* Common Module |
||||||
|
*/ |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
||||||
|
|
||||||
|
From bbf235091e49807ece8f3a3df95bbfcc9d3ab43d Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Sat, 22 Feb 2020 05:37:01 +0900 |
||||||
|
Subject: [PATCH 2/5] ts: use TS_VERIFY_CTX_set_certs instead of |
||||||
|
TS_VERIFY_CTS_set_certs |
||||||
|
|
||||||
|
OpenSSL 3.0 fixed the typo in the function name and replaced the |
||||||
|
current 'CTS' version with a macro. |
||||||
|
--- |
||||||
|
ext/openssl/extconf.rb | 5 ++++- |
||||||
|
ext/openssl/openssl_missing.h | 5 +++++ |
||||||
|
ext/openssl/ossl_ts.c | 2 +- |
||||||
|
3 files changed, 10 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb |
||||||
|
index 17d93443fc..09cae05b72 100644 |
||||||
|
--- a/ext/openssl/extconf.rb |
||||||
|
+++ b/ext/openssl/extconf.rb |
||||||
|
@@ -165,7 +165,7 @@ def find_openssl_library |
||||||
|
have_func("TS_STATUS_INFO_get0_status") |
||||||
|
have_func("TS_STATUS_INFO_get0_text") |
||||||
|
have_func("TS_STATUS_INFO_get0_failure_info") |
||||||
|
-have_func("TS_VERIFY_CTS_set_certs") |
||||||
|
+have_func("TS_VERIFY_CTS_set_certs(NULL, NULL)", "openssl/ts.h") |
||||||
|
have_func("TS_VERIFY_CTX_set_store") |
||||||
|
have_func("TS_VERIFY_CTX_add_flags") |
||||||
|
have_func("TS_RESP_CTX_set_time_cb") |
||||||
|
@@ -174,6 +174,9 @@ def find_openssl_library |
||||||
|
|
||||||
|
# added in 1.1.1 |
||||||
|
have_func("EVP_PKEY_check") |
||||||
|
+ |
||||||
|
+# added in 3.0.0 |
||||||
|
+have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h") |
||||||
|
|
||||||
|
Logging::message "=== Checking done. ===\n" |
||||||
|
|
||||||
|
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h |
||||||
|
index e575415f49..fe486bcfcf 100644 |
||||||
|
--- a/ext/openssl/openssl_missing.h |
||||||
|
+++ b/ext/openssl/openssl_missing.h |
||||||
|
@@ -236,4 +236,9 @@ IMPL_PKEY_GETTER(EC_KEY, ec) |
||||||
|
} while (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
+/* added in 3.0.0 */ |
||||||
|
+#if !defined(HAVE_TS_VERIFY_CTX_SET_CERTS) |
||||||
|
+# define TS_VERIFY_CTX_set_certs(ctx, crts) TS_VERIFY_CTS_set_certs(ctx, crts) |
||||||
|
+#endif |
||||||
|
+ |
||||||
|
#endif /* _OSSL_OPENSSL_MISSING_H_ */ |
||||||
|
diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c |
||||||
|
index 692c0d620f..f1da7c1947 100644 |
||||||
|
--- a/ext/openssl/ossl_ts.c |
||||||
|
+++ b/ext/openssl/ossl_ts.c |
||||||
|
@@ -820,7 +820,7 @@ ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self) |
||||||
|
X509_up_ref(cert); |
||||||
|
} |
||||||
|
|
||||||
|
- TS_VERIFY_CTS_set_certs(ctx, x509inter); |
||||||
|
+ TS_VERIFY_CTX_set_certs(ctx, x509inter); |
||||||
|
TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE); |
||||||
|
TS_VERIFY_CTX_set_store(ctx, x509st); |
||||||
|
|
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
||||||
|
|
||||||
|
From 5fba3bc1df93ab6abc3ea53be3393480f36ea259 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Fri, 19 Mar 2021 19:18:25 +0900 |
||||||
|
Subject: [PATCH 3/5] ssl: use SSL_get_rbio() to check if SSL is started or not |
||||||
|
|
||||||
|
Use SSL_get_rbio() instead of SSL_get_fd(). SSL_get_fd() internally |
||||||
|
calls SSL_get_rbio() and it's enough for our purpose. |
||||||
|
|
||||||
|
In OpenSSL 3.0, SSL_get_fd() leaves an entry in the OpenSSL error queue |
||||||
|
if BIO has not been set up yet, and we would have to clean it up. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_ssl.c | 4 ++-- |
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c |
||||||
|
index 4b7efa39f5..ec430bfb0c 100644 |
||||||
|
--- a/ext/openssl/ossl_ssl.c |
||||||
|
+++ b/ext/openssl/ossl_ssl.c |
||||||
|
@@ -1535,8 +1535,8 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self) |
||||||
|
static inline int |
||||||
|
ssl_started(SSL *ssl) |
||||||
|
{ |
||||||
|
- /* the FD is set in ossl_ssl_setup(), called by #connect or #accept */ |
||||||
|
- return SSL_get_fd(ssl) >= 0; |
||||||
|
+ /* BIO is created through ossl_ssl_setup(), called by #connect or #accept */ |
||||||
|
+ return SSL_get_rbio(ssl) != NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
||||||
|
From 0a253027e6be47c0b7fd8b664f1048f24d7ca657 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Thu, 22 Apr 2021 13:57:47 +0900 |
||||||
|
Subject: [PATCH 4/5] digest: use EVP_MD_CTX_get0_md() instead of |
||||||
|
EVP_MD_CTX_md() if exists |
||||||
|
|
||||||
|
The function was renamed in OpenSSL 3.0 due to the change of the |
||||||
|
lifetime of EVP_MD objects. They are no longer necessarily statically |
||||||
|
allocated and can be reference-counted -- when an EVP_MD_CTX is free'd, |
||||||
|
the associated EVP_MD can also become inaccessible. |
||||||
|
|
||||||
|
Currently Ruby/OpenSSL only handles builtin algorithms, so no special |
||||||
|
handling is needed except for adapting to the rename. |
||||||
|
--- |
||||||
|
ext/openssl/extconf.rb | 1 + |
||||||
|
ext/openssl/openssl_missing.h | 4 ++++ |
||||||
|
ext/openssl/ossl_digest.c | 6 +++--- |
||||||
|
ext/openssl/ossl_hmac.c | 2 +- |
||||||
|
4 files changed, 9 insertions(+), 4 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb |
||||||
|
index 98f96afe..842b7f5b 100644 |
||||||
|
--- a/ext/openssl/extconf.rb |
||||||
|
+++ b/ext/openssl/extconf.rb |
||||||
|
@@ -177,6 +177,7 @@ def find_openssl_library |
||||||
|
|
||||||
|
# added in 3.0.0 |
||||||
|
have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h") |
||||||
|
+have_func("EVP_MD_CTX_get0_md") |
||||||
|
|
||||||
|
Logging::message "=== Checking done. ===\n" |
||||||
|
|
||||||
|
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h |
||||||
|
index 1b1a54a8..64212349 100644 |
||||||
|
--- a/ext/openssl/openssl_missing.h |
||||||
|
+++ b/ext/openssl/openssl_missing.h |
||||||
|
@@ -241,4 +241,8 @@ IMPL_PKEY_GETTER(EC_KEY, ec) |
||||||
|
# define TS_VERIFY_CTX_set_certs(ctx, crts) TS_VERIFY_CTS_set_certs(ctx, crts) |
||||||
|
#endif |
||||||
|
|
||||||
|
+#ifndef HAVE_EVP_MD_CTX_GET0_MD |
||||||
|
+# define EVP_MD_CTX_get0_md(ctx) EVP_MD_CTX_md(ctx) |
||||||
|
+#endif |
||||||
|
+ |
||||||
|
#endif /* _OSSL_OPENSSL_MISSING_H_ */ |
||||||
|
diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c |
||||||
|
index b2506de7..fc326ec1 100644 |
||||||
|
--- a/ext/openssl/ossl_digest.c |
||||||
|
+++ b/ext/openssl/ossl_digest.c |
||||||
|
@@ -63,7 +63,7 @@ ossl_evp_get_digestbyname(VALUE obj) |
||||||
|
|
||||||
|
GetDigest(obj, ctx); |
||||||
|
|
||||||
|
- md = EVP_MD_CTX_md(ctx); |
||||||
|
+ md = EVP_MD_CTX_get0_md(ctx); |
||||||
|
} |
||||||
|
|
||||||
|
return md; |
||||||
|
@@ -176,7 +176,7 @@ ossl_digest_reset(VALUE self) |
||||||
|
EVP_MD_CTX *ctx; |
||||||
|
|
||||||
|
GetDigest(self, ctx); |
||||||
|
- if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) { |
||||||
|
+ if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_get0_md(ctx), NULL) != 1) { |
||||||
|
ossl_raise(eDigestError, "Digest initialization failed."); |
||||||
|
} |
||||||
|
|
||||||
|
@@ -259,7 +259,7 @@ ossl_digest_name(VALUE self) |
||||||
|
|
||||||
|
GetDigest(self, ctx); |
||||||
|
|
||||||
|
- return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx))); |
||||||
|
+ return rb_str_new_cstr(EVP_MD_name(EVP_MD_CTX_get0_md(ctx))); |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c |
||||||
|
index a21db6c4..2642728b 100644 |
||||||
|
--- a/ext/openssl/ossl_hmac.c |
||||||
|
+++ b/ext/openssl/ossl_hmac.c |
||||||
|
@@ -239,7 +239,7 @@ ossl_hmac_reset(VALUE self) |
||||||
|
|
||||||
|
GetHMAC(self, ctx); |
||||||
|
pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); |
||||||
|
- if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_md(ctx), NULL, pkey) != 1) |
||||||
|
+ if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1) |
||||||
|
ossl_raise(eHMACError, "EVP_DigestSignInit"); |
||||||
|
|
||||||
|
return self; |
||||||
|
|
||||||
|
From c106d888c62e44a11cdbba5e4d2d0cb837ec3e52 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Tue, 22 Jun 2021 18:50:17 +0900 |
||||||
|
Subject: [PATCH 5/5] hmac: use EVP_MD_CTX_get_pkey_ctx() instead of |
||||||
|
EVP_MD_CTX_pkey_ctx() |
||||||
|
|
||||||
|
OpenSSL 3.0 renamed EVP_MD_CTX_pkey_ctx() to include "get" in the |
||||||
|
function name. Adjust compatibility macro so that we can use the new |
||||||
|
function name for all OpenSSL 1.0.2-3.0. |
||||||
|
--- |
||||||
|
ext/openssl/extconf.rb | 1 + |
||||||
|
ext/openssl/openssl_missing.h | 16 ++++++++++++---- |
||||||
|
ext/openssl/ossl_hmac.c | 2 +- |
||||||
|
3 files changed, 14 insertions(+), 5 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb |
||||||
|
index 842b7f5b..d9d34b7c 100644 |
||||||
|
--- a/ext/openssl/extconf.rb |
||||||
|
+++ b/ext/openssl/extconf.rb |
||||||
|
@@ -178,6 +178,7 @@ def find_openssl_library |
||||||
|
# added in 3.0.0 |
||||||
|
have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h") |
||||||
|
have_func("EVP_MD_CTX_get0_md") |
||||||
|
+have_func("EVP_MD_CTX_get_pkey_ctx") |
||||||
|
|
||||||
|
Logging::message "=== Checking done. ===\n" |
||||||
|
|
||||||
|
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h |
||||||
|
index 64212349..55c4f378 100644 |
||||||
|
--- a/ext/openssl/openssl_missing.h |
||||||
|
+++ b/ext/openssl/openssl_missing.h |
||||||
|
@@ -42,10 +42,6 @@ int ossl_EC_curve_nist2nid(const char *); |
||||||
|
# define EVP_MD_CTX_free EVP_MD_CTX_destroy |
||||||
|
#endif |
||||||
|
|
||||||
|
-#if !defined(HAVE_EVP_MD_CTX_PKEY_CTX) |
||||||
|
-# define EVP_MD_CTX_pkey_ctx(x) (x)->pctx |
||||||
|
-#endif |
||||||
|
- |
||||||
|
#if !defined(HAVE_X509_STORE_GET_EX_DATA) |
||||||
|
# define X509_STORE_get_ex_data(x, idx) \ |
||||||
|
CRYPTO_get_ex_data(&(x)->ex_data, (idx)) |
||||||
|
@@ -245,4 +241,16 @@ IMPL_PKEY_GETTER(EC_KEY, ec) |
||||||
|
# define EVP_MD_CTX_get0_md(ctx) EVP_MD_CTX_md(ctx) |
||||||
|
#endif |
||||||
|
|
||||||
|
+/* |
||||||
|
+ * OpenSSL 1.1.0 added EVP_MD_CTX_pkey_ctx(), and then it was renamed to |
||||||
|
+ * EVP_MD_CTX_get_pkey_ctx(x) in OpenSSL 3.0. |
||||||
|
+ */ |
||||||
|
+#ifndef HAVE_EVP_MD_CTX_GET_PKEY_CTX |
||||||
|
+# ifdef HAVE_EVP_MD_CTX_PKEY_CTX |
||||||
|
+# define EVP_MD_CTX_get_pkey_ctx(x) EVP_MD_CTX_pkey_ctx(x) |
||||||
|
+# else |
||||||
|
+# define EVP_MD_CTX_get_pkey_ctx(x) (x)->pctx |
||||||
|
+# endif |
||||||
|
+#endif |
||||||
|
+ |
||||||
|
#endif /* _OSSL_OPENSSL_MISSING_H_ */ |
||||||
|
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c |
||||||
|
index 2642728b..f89ff2f9 100644 |
||||||
|
--- a/ext/openssl/ossl_hmac.c |
||||||
|
+++ b/ext/openssl/ossl_hmac.c |
||||||
|
@@ -238,7 +238,7 @@ ossl_hmac_reset(VALUE self) |
||||||
|
EVP_PKEY *pkey; |
||||||
|
|
||||||
|
GetHMAC(self, ctx); |
||||||
|
- pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); |
||||||
|
+ pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx)); |
||||||
|
if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1) |
||||||
|
ossl_raise(eHMACError, "EVP_DigestSignInit"); |
||||||
|
|
@ -0,0 +1,93 @@ |
|||||||
|
From 96684439e96aa92e10376b5be45f006772028295 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Thu, 21 Oct 2021 13:02:38 +0200 |
||||||
|
Subject: [PATCH] Properly exclude test cases. |
||||||
|
|
||||||
|
Lets consider the following scenario: |
||||||
|
|
||||||
|
~~~ |
||||||
|
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):001:0> p suite |
||||||
|
OpenSSL::TestEC |
||||||
|
=> OpenSSL::TestEC |
||||||
|
|
||||||
|
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):002:0> p all_test_methods |
||||||
|
["test_ECPrivateKey", "test_ECPrivateKey_encrypted", "test_PUBKEY", "test_check_key", "test_derive_key", "test_dh_compute_key", "test_dsa_sign_asn1_FIPS186_3", "test_ec_group", "test_ec_key", "test_ec_point", "test_ec_point_add", "test_ec_point_mul", "test_generate", "test_marshal", "test_sign_verify", "test_sign_verify_raw"] |
||||||
|
=> |
||||||
|
["test_ECPrivateKey", |
||||||
|
"test_ECPrivateKey_encrypted", |
||||||
|
"test_PUBKEY", |
||||||
|
"test_check_key", |
||||||
|
"test_derive_key", |
||||||
|
"test_dh_compute_key", |
||||||
|
"test_dsa_sign_asn1_FIPS186_3", |
||||||
|
"test_ec_group", |
||||||
|
"test_ec_key", |
||||||
|
"test_ec_point", |
||||||
|
"test_ec_point_add", |
||||||
|
"test_ec_point_mul", |
||||||
|
"test_generate", |
||||||
|
"test_marshal", |
||||||
|
"test_sign_verify", |
||||||
|
"test_sign_verify_raw"] |
||||||
|
|
||||||
|
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):003:0> p filter |
||||||
|
/\A(?=.*)(?!.*(?-mix:(?-mix:memory_leak)|(?-mix:OpenSSL::TestEC.test_check_key)))/ |
||||||
|
=> /\A(?=.*)(?!.*(?-mix:(?-mix:memory_leak)|(?-mix:OpenSSL::TestEC.test_check_key)))/ |
||||||
|
|
||||||
|
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):004:0> method = "test_check_key" |
||||||
|
=> "test_check_key" |
||||||
|
~~~ |
||||||
|
|
||||||
|
The intention here is to exclude the `test_check_key` test case. |
||||||
|
Unfortunately this does not work as expected, because the negative filter |
||||||
|
is never checked: |
||||||
|
|
||||||
|
~~~ |
||||||
|
|
||||||
|
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):005:0> filter === method |
||||||
|
=> true |
||||||
|
|
||||||
|
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):006:0> filter === "#{suite}##{method}" |
||||||
|
=> false |
||||||
|
|
||||||
|
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):007:0> filter === method || filter === "#{suite}##{method}" |
||||||
|
=> true |
||||||
|
~~~ |
||||||
|
|
||||||
|
Therefore always filter against the fully qualified method name |
||||||
|
`#{suite}##{method}`, which should provide the expected result. |
||||||
|
|
||||||
|
However, if plain string filter is used, keep checking also only the |
||||||
|
method name. |
||||||
|
|
||||||
|
This resolves [Bug #16936]. |
||||||
|
--- |
||||||
|
tool/lib/minitest/unit.rb | 12 +++++++++--- |
||||||
|
1 file changed, 9 insertions(+), 3 deletions(-) |
||||||
|
|
||||||
|
diff --git a/tool/lib/minitest/unit.rb b/tool/lib/minitest/unit.rb |
||||||
|
index c58a609bfa..d5af6cb906 100644 |
||||||
|
--- a/tool/lib/minitest/unit.rb |
||||||
|
+++ b/tool/lib/minitest/unit.rb |
||||||
|
@@ -956,9 +956,15 @@ def _run_suite suite, type |
||||||
|
|
||||||
|
all_test_methods = suite.send "#{type}_methods" |
||||||
|
|
||||||
|
- filtered_test_methods = all_test_methods.find_all { |m| |
||||||
|
- filter === m || filter === "#{suite}##{m}" |
||||||
|
- } |
||||||
|
+ filtered_test_methods = if Regexp === filter |
||||||
|
+ all_test_methods.find_all { |m| |
||||||
|
+ filter === "#{suite}##{m}" |
||||||
|
+ } |
||||||
|
+ else |
||||||
|
+ all_test_methods.find_all {|m| |
||||||
|
+ filter === m || filter === "#{suite}##{m}" |
||||||
|
+ } |
||||||
|
+ end |
||||||
|
|
||||||
|
leakchecker = LeakChecker.new |
||||||
|
|
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,229 @@ |
|||||||
|
From 3b91792d3d644d6d6b0059cb315c9fe5d3626bab Mon Sep 17 00:00:00 2001 |
||||||
|
From: Yusuke Endoh <mame@ruby-lang.org> |
||||||
|
Date: Sat, 6 Mar 2021 00:03:57 +0900 |
||||||
|
Subject: [PATCH] Support GCC's DWARF 5 [Bug #17585] |
||||||
|
|
||||||
|
Co-Authored-By: xtkoba (Tee KOBAYASHI) <xtkoba+ruby@gmail.com> |
||||||
|
--- |
||||||
|
addr2line.c | 119 ++++++++++++++++++++++++++++++++++++++++++---------- |
||||||
|
1 file changed, 97 insertions(+), 22 deletions(-) |
||||||
|
|
||||||
|
diff --git a/addr2line.c b/addr2line.c |
||||||
|
index 0029cffbca..855efb40d4 100644 |
||||||
|
--- a/addr2line.c |
||||||
|
+++ b/addr2line.c |
||||||
|
@@ -159,11 +159,12 @@ typedef struct obj_info { |
||||||
|
struct dwarf_section debug_info; |
||||||
|
struct dwarf_section debug_line; |
||||||
|
struct dwarf_section debug_ranges; |
||||||
|
+ struct dwarf_section debug_rnglists; |
||||||
|
struct dwarf_section debug_str; |
||||||
|
struct obj_info *next; |
||||||
|
} obj_info_t; |
||||||
|
|
||||||
|
-#define DWARF_SECTION_COUNT 5 |
||||||
|
+#define DWARF_SECTION_COUNT 6 |
||||||
|
|
||||||
|
static struct dwarf_section * |
||||||
|
obj_dwarf_section_at(obj_info_t *obj, int n) |
||||||
|
@@ -173,6 +174,7 @@ obj_dwarf_section_at(obj_info_t *obj, int n) |
||||||
|
&obj->debug_info, |
||||||
|
&obj->debug_line, |
||||||
|
&obj->debug_ranges, |
||||||
|
+ &obj->debug_rnglists, |
||||||
|
&obj->debug_str |
||||||
|
}; |
||||||
|
if (n < 0 || DWARF_SECTION_COUNT <= n) { |
||||||
|
@@ -411,7 +413,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line, |
||||||
|
FILL_LINE(); |
||||||
|
break; |
||||||
|
case DW_LNS_advance_pc: |
||||||
|
- a = uleb128((char **)&p); |
||||||
|
+ a = uleb128((char **)&p) * header.minimum_instruction_length; |
||||||
|
addr += a; |
||||||
|
break; |
||||||
|
case DW_LNS_advance_line: { |
||||||
|
@@ -451,7 +453,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line, |
||||||
|
/* isa = (unsigned int)*/(void)uleb128((char **)&p); |
||||||
|
break; |
||||||
|
case 0: |
||||||
|
- a = *(unsigned char *)p++; |
||||||
|
+ a = uleb128((char **)&p); |
||||||
|
op = *p++; |
||||||
|
switch (op) { |
||||||
|
case DW_LNE_end_sequence: |
||||||
|
@@ -808,6 +810,18 @@ enum |
||||||
|
DW_FORM_addrx4 = 0x2c |
||||||
|
}; |
||||||
|
|
||||||
|
+/* Range list entry encodings */ |
||||||
|
+enum { |
||||||
|
+ DW_RLE_end_of_list = 0x00, |
||||||
|
+ DW_RLE_base_addressx = 0x01, |
||||||
|
+ DW_RLE_startx_endx = 0x02, |
||||||
|
+ DW_RLE_startx_length = 0x03, |
||||||
|
+ DW_RLE_offset_pair = 0x04, |
||||||
|
+ DW_RLE_base_address = 0x05, |
||||||
|
+ DW_RLE_start_end = 0x06, |
||||||
|
+ DW_RLE_start_length = 0x07 |
||||||
|
+}; |
||||||
|
+ |
||||||
|
enum { |
||||||
|
VAL_none = 0, |
||||||
|
VAL_cstr = 1, |
||||||
|
@@ -961,6 +975,23 @@ debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj) |
||||||
|
reader->current_low_pc = 0; |
||||||
|
} |
||||||
|
|
||||||
|
+static void |
||||||
|
+di_skip_die_attributes(char **p) |
||||||
|
+{ |
||||||
|
+ for (;;) { |
||||||
|
+ uint64_t at = uleb128(p); |
||||||
|
+ uint64_t form = uleb128(p); |
||||||
|
+ if (!at && !form) break; |
||||||
|
+ switch (form) { |
||||||
|
+ default: |
||||||
|
+ break; |
||||||
|
+ case DW_FORM_implicit_const: |
||||||
|
+ sleb128(p); |
||||||
|
+ break; |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+} |
||||||
|
+ |
||||||
|
static void |
||||||
|
di_read_debug_abbrev_cu(DebugInfoReader *reader) |
||||||
|
{ |
||||||
|
@@ -975,12 +1006,7 @@ di_read_debug_abbrev_cu(DebugInfoReader *reader) |
||||||
|
prev = abbrev_number; |
||||||
|
uleb128(&p); /* tag */ |
||||||
|
p++; /* has_children */ |
||||||
|
- /* skip content */ |
||||||
|
- for (;;) { |
||||||
|
- uint64_t at = uleb128(&p); |
||||||
|
- uint64_t form = uleb128(&p); |
||||||
|
- if (!at && !form) break; |
||||||
|
- } |
||||||
|
+ di_skip_die_attributes(&p); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@@ -1244,12 +1270,7 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number) |
||||||
|
/* skip 255th record */ |
||||||
|
uleb128(&p); /* tag */ |
||||||
|
p++; /* has_children */ |
||||||
|
- /* skip content */ |
||||||
|
- for (;;) { |
||||||
|
- uint64_t at = uleb128(&p); |
||||||
|
- uint64_t form = uleb128(&p); |
||||||
|
- if (!at && !form) break; |
||||||
|
- } |
||||||
|
+ di_skip_die_attributes(&p); |
||||||
|
for (uint64_t n = uleb128(&p); abbrev_number != n; n = uleb128(&p)) { |
||||||
|
if (n == 0) { |
||||||
|
fprintf(stderr,"%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number); |
||||||
|
@@ -1257,12 +1278,7 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number) |
||||||
|
} |
||||||
|
uleb128(&p); /* tag */ |
||||||
|
p++; /* has_children */ |
||||||
|
- /* skip content */ |
||||||
|
- for (;;) { |
||||||
|
- uint64_t at = uleb128(&p); |
||||||
|
- uint64_t form = uleb128(&p); |
||||||
|
- if (!at && !form) break; |
||||||
|
- } |
||||||
|
+ di_skip_die_attributes(&p); |
||||||
|
} |
||||||
|
return p; |
||||||
|
} |
||||||
|
@@ -1390,6 +1406,21 @@ ranges_set(ranges_t *ptr, DebugInfoValue *v) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
+static uint64_t |
||||||
|
+read_dw_form_addr(DebugInfoReader *reader, char **ptr) |
||||||
|
+{ |
||||||
|
+ char *p = *ptr; |
||||||
|
+ *ptr = p + reader->format; |
||||||
|
+ if (reader->format == 4) { |
||||||
|
+ return read_uint32(&p); |
||||||
|
+ } else if (reader->format == 8) { |
||||||
|
+ return read_uint64(&p); |
||||||
|
+ } else { |
||||||
|
+ fprintf(stderr,"unknown address_size:%d", reader->address_size); |
||||||
|
+ abort(); |
||||||
|
+ } |
||||||
|
+} |
||||||
|
+ |
||||||
|
static uintptr_t |
||||||
|
ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr) |
||||||
|
{ |
||||||
|
@@ -1403,8 +1434,50 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr) |
||||||
|
} |
||||||
|
else if (ptr->ranges_set) { |
||||||
|
/* TODO: support base address selection entry */ |
||||||
|
- char *p = reader->obj->debug_ranges.ptr + ptr->ranges; |
||||||
|
+ char *p; |
||||||
|
uint64_t base = ptr->low_pc_set ? ptr->low_pc : reader->current_low_pc; |
||||||
|
+ if (reader->obj->debug_rnglists.ptr) { |
||||||
|
+ p = reader->obj->debug_rnglists.ptr + ptr->ranges; |
||||||
|
+ for (;;) { |
||||||
|
+ uint8_t rle = read_uint8(&p); |
||||||
|
+ uintptr_t base_address = 0; |
||||||
|
+ uintptr_t from, to; |
||||||
|
+ if (rle == DW_RLE_end_of_list) break; |
||||||
|
+ switch (rle) { |
||||||
|
+ case DW_RLE_base_addressx: |
||||||
|
+ uleb128(&p); |
||||||
|
+ break; |
||||||
|
+ case DW_RLE_startx_endx: |
||||||
|
+ uleb128(&p); |
||||||
|
+ uleb128(&p); |
||||||
|
+ break; |
||||||
|
+ case DW_RLE_startx_length: |
||||||
|
+ uleb128(&p); |
||||||
|
+ uleb128(&p); |
||||||
|
+ break; |
||||||
|
+ case DW_RLE_offset_pair: |
||||||
|
+ from = base_address + uleb128(&p); |
||||||
|
+ to = base_address + uleb128(&p); |
||||||
|
+ if (base + from <= addr && addr < base + to) { |
||||||
|
+ return from; |
||||||
|
+ } |
||||||
|
+ break; |
||||||
|
+ case DW_RLE_base_address: |
||||||
|
+ base_address = read_dw_form_addr(reader, &p); |
||||||
|
+ break; |
||||||
|
+ case DW_RLE_start_end: |
||||||
|
+ read_dw_form_addr(reader, &p); |
||||||
|
+ read_dw_form_addr(reader, &p); |
||||||
|
+ break; |
||||||
|
+ case DW_RLE_start_length: |
||||||
|
+ read_dw_form_addr(reader, &p); |
||||||
|
+ uleb128(&p); |
||||||
|
+ break; |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+ return false; |
||||||
|
+ } |
||||||
|
+ p = reader->obj->debug_ranges.ptr + ptr->ranges; |
||||||
|
for (;;) { |
||||||
|
uintptr_t from = read_uintptr(&p); |
||||||
|
uintptr_t to = read_uintptr(&p); |
||||||
|
@@ -1750,6 +1823,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink, |
||||||
|
".debug_info", |
||||||
|
".debug_line", |
||||||
|
".debug_ranges", |
||||||
|
+ ".debug_rnglists", |
||||||
|
".debug_str" |
||||||
|
}; |
||||||
|
|
||||||
|
@@ -2006,6 +2080,7 @@ found_mach_header: |
||||||
|
"__debug_info", |
||||||
|
"__debug_line", |
||||||
|
"__debug_ranges", |
||||||
|
+ "__debug_rnglists", |
||||||
|
"__debug_str" |
||||||
|
}; |
||||||
|
struct LP(segment_command) *scmd = (struct LP(segment_command) *)lcmd; |
@ -0,0 +1,831 @@ |
|||||||
|
From cf070378020088cd7e69b1cb08be68152ab8a078 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Sun, 17 May 2020 18:25:38 +0900 |
||||||
|
Subject: [PATCH 1/3] pkey: implement #to_text using EVP API |
||||||
|
|
||||||
|
Use EVP_PKEY_print_private() instead of the low-level API *_print() |
||||||
|
functions, such as RSA_print(). |
||||||
|
|
||||||
|
EVP_PKEY_print_*() family was added in OpenSSL 1.0.0. |
||||||
|
|
||||||
|
Note that it falls back to EVP_PKEY_print_public() and |
||||||
|
EVP_PKEY_print_params() as necessary. This is required for EVP_PKEY_DH |
||||||
|
type for which _private() fails if the private component is not set in |
||||||
|
the pkey object. |
||||||
|
|
||||||
|
Since the new API works in the same way for all key types, we now |
||||||
|
implement #to_text in the base class OpenSSL::PKey::PKey rather than in |
||||||
|
each subclass. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_pkey.c | 38 +++++++++++++++++++++++++++++++++++++ |
||||||
|
ext/openssl/ossl_pkey_dh.c | 29 ---------------------------- |
||||||
|
ext/openssl/ossl_pkey_dsa.c | 29 ---------------------------- |
||||||
|
ext/openssl/ossl_pkey_ec.c | 27 -------------------------- |
||||||
|
ext/openssl/ossl_pkey_rsa.c | 31 ------------------------------ |
||||||
|
test/openssl/test_pkey.rb | 5 +++++ |
||||||
|
6 files changed, 43 insertions(+), 116 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c |
||||||
|
index f9282b9417..21cd4b2cda 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.c |
||||||
|
+++ b/ext/openssl/ossl_pkey.c |
||||||
|
@@ -539,6 +539,43 @@ ossl_pkey_inspect(VALUE self) |
||||||
|
OBJ_nid2sn(nid)); |
||||||
|
} |
||||||
|
|
||||||
|
+/* |
||||||
|
+ * call-seq: |
||||||
|
+ * pkey.to_text -> string |
||||||
|
+ * |
||||||
|
+ * Dumps key parameters, public key, and private key components contained in |
||||||
|
+ * the key into a human-readable text. |
||||||
|
+ * |
||||||
|
+ * This is intended for debugging purpose. |
||||||
|
+ * |
||||||
|
+ * See also the man page EVP_PKEY_print_private(3). |
||||||
|
+ */ |
||||||
|
+static VALUE |
||||||
|
+ossl_pkey_to_text(VALUE self) |
||||||
|
+{ |
||||||
|
+ EVP_PKEY *pkey; |
||||||
|
+ BIO *bio; |
||||||
|
+ |
||||||
|
+ GetPKey(self, pkey); |
||||||
|
+ if (!(bio = BIO_new(BIO_s_mem()))) |
||||||
|
+ ossl_raise(ePKeyError, "BIO_new"); |
||||||
|
+ |
||||||
|
+ if (EVP_PKEY_print_private(bio, pkey, 0, NULL) == 1) |
||||||
|
+ goto out; |
||||||
|
+ OSSL_BIO_reset(bio); |
||||||
|
+ if (EVP_PKEY_print_public(bio, pkey, 0, NULL) == 1) |
||||||
|
+ goto out; |
||||||
|
+ OSSL_BIO_reset(bio); |
||||||
|
+ if (EVP_PKEY_print_params(bio, pkey, 0, NULL) == 1) |
||||||
|
+ goto out; |
||||||
|
+ |
||||||
|
+ BIO_free(bio); |
||||||
|
+ ossl_raise(ePKeyError, "EVP_PKEY_print_params"); |
||||||
|
+ |
||||||
|
+ out: |
||||||
|
+ return ossl_membio2str(bio); |
||||||
|
+} |
||||||
|
+ |
||||||
|
VALUE |
||||||
|
ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der) |
||||||
|
{ |
||||||
|
@@ -1039,6 +1076,7 @@ Init_ossl_pkey(void) |
||||||
|
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); |
||||||
|
rb_define_method(cPKey, "oid", ossl_pkey_oid, 0); |
||||||
|
rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0); |
||||||
|
+ rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0); |
||||||
|
rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); |
||||||
|
rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); |
||||||
|
rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); |
||||||
|
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c |
||||||
|
index 6b477b077c..acd3bf474e 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_dh.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_dh.c |
||||||
|
@@ -266,34 +266,6 @@ ossl_dh_get_params(VALUE self) |
||||||
|
return hash; |
||||||
|
} |
||||||
|
|
||||||
|
-/* |
||||||
|
- * call-seq: |
||||||
|
- * dh.to_text -> aString |
||||||
|
- * |
||||||
|
- * Prints all parameters of key to buffer |
||||||
|
- * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! |
||||||
|
- * Don't use :-)) (I's up to you) |
||||||
|
- */ |
||||||
|
-static VALUE |
||||||
|
-ossl_dh_to_text(VALUE self) |
||||||
|
-{ |
||||||
|
- DH *dh; |
||||||
|
- BIO *out; |
||||||
|
- VALUE str; |
||||||
|
- |
||||||
|
- GetDH(self, dh); |
||||||
|
- if (!(out = BIO_new(BIO_s_mem()))) { |
||||||
|
- ossl_raise(eDHError, NULL); |
||||||
|
- } |
||||||
|
- if (!DHparams_print(out, dh)) { |
||||||
|
- BIO_free(out); |
||||||
|
- ossl_raise(eDHError, NULL); |
||||||
|
- } |
||||||
|
- str = ossl_membio2str(out); |
||||||
|
- |
||||||
|
- return str; |
||||||
|
-} |
||||||
|
- |
||||||
|
/* |
||||||
|
* call-seq: |
||||||
|
* dh.public_key -> aDH |
||||||
|
@@ -426,7 +398,6 @@ Init_ossl_dh(void) |
||||||
|
rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1); |
||||||
|
rb_define_method(cDH, "public?", ossl_dh_is_public, 0); |
||||||
|
rb_define_method(cDH, "private?", ossl_dh_is_private, 0); |
||||||
|
- rb_define_method(cDH, "to_text", ossl_dh_to_text, 0); |
||||||
|
rb_define_method(cDH, "export", ossl_dh_export, 0); |
||||||
|
rb_define_alias(cDH, "to_pem", "export"); |
||||||
|
rb_define_alias(cDH, "to_s", "export"); |
||||||
|
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c |
||||||
|
index 1c5a8a737e..f017cceb4a 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_dsa.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_dsa.c |
||||||
|
@@ -264,34 +264,6 @@ ossl_dsa_get_params(VALUE self) |
||||||
|
return hash; |
||||||
|
} |
||||||
|
|
||||||
|
-/* |
||||||
|
- * call-seq: |
||||||
|
- * dsa.to_text -> aString |
||||||
|
- * |
||||||
|
- * Prints all parameters of key to buffer |
||||||
|
- * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! |
||||||
|
- * Don't use :-)) (I's up to you) |
||||||
|
- */ |
||||||
|
-static VALUE |
||||||
|
-ossl_dsa_to_text(VALUE self) |
||||||
|
-{ |
||||||
|
- DSA *dsa; |
||||||
|
- BIO *out; |
||||||
|
- VALUE str; |
||||||
|
- |
||||||
|
- GetDSA(self, dsa); |
||||||
|
- if (!(out = BIO_new(BIO_s_mem()))) { |
||||||
|
- ossl_raise(eDSAError, NULL); |
||||||
|
- } |
||||||
|
- if (!DSA_print(out, dsa, 0)) { /* offset = 0 */ |
||||||
|
- BIO_free(out); |
||||||
|
- ossl_raise(eDSAError, NULL); |
||||||
|
- } |
||||||
|
- str = ossl_membio2str(out); |
||||||
|
- |
||||||
|
- return str; |
||||||
|
-} |
||||||
|
- |
||||||
|
/* |
||||||
|
* call-seq: |
||||||
|
* dsa.public_key -> aDSA |
||||||
|
@@ -469,7 +441,6 @@ Init_ossl_dsa(void) |
||||||
|
|
||||||
|
rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0); |
||||||
|
rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0); |
||||||
|
- rb_define_method(cDSA, "to_text", ossl_dsa_to_text, 0); |
||||||
|
rb_define_method(cDSA, "export", ossl_dsa_export, -1); |
||||||
|
rb_define_alias(cDSA, "to_pem", "export"); |
||||||
|
rb_define_alias(cDSA, "to_s", "export"); |
||||||
|
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c |
||||||
|
index c2534251c3..ecb8305184 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_ec.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_ec.c |
||||||
|
@@ -417,32 +417,6 @@ ossl_ec_key_to_der(VALUE self) |
||||||
|
else |
||||||
|
return ossl_pkey_export_spki(self, 1); |
||||||
|
} |
||||||
|
- |
||||||
|
-/* |
||||||
|
- * call-seq: |
||||||
|
- * key.to_text => String |
||||||
|
- * |
||||||
|
- * See the OpenSSL documentation for EC_KEY_print() |
||||||
|
- */ |
||||||
|
-static VALUE ossl_ec_key_to_text(VALUE self) |
||||||
|
-{ |
||||||
|
- EC_KEY *ec; |
||||||
|
- BIO *out; |
||||||
|
- VALUE str; |
||||||
|
- |
||||||
|
- GetEC(self, ec); |
||||||
|
- if (!(out = BIO_new(BIO_s_mem()))) { |
||||||
|
- ossl_raise(eECError, "BIO_new(BIO_s_mem())"); |
||||||
|
- } |
||||||
|
- if (!EC_KEY_print(out, ec, 0)) { |
||||||
|
- BIO_free(out); |
||||||
|
- ossl_raise(eECError, "EC_KEY_print"); |
||||||
|
- } |
||||||
|
- str = ossl_membio2str(out); |
||||||
|
- |
||||||
|
- return str; |
||||||
|
-} |
||||||
|
- |
||||||
|
/* |
||||||
|
* call-seq: |
||||||
|
* key.generate_key! => self |
||||||
|
@@ -1633,7 +1607,6 @@ void Init_ossl_ec(void) |
||||||
|
rb_define_method(cEC, "export", ossl_ec_key_export, -1); |
||||||
|
rb_define_alias(cEC, "to_pem", "export"); |
||||||
|
rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0); |
||||||
|
- rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0); |
||||||
|
|
||||||
|
|
||||||
|
rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc); |
||||||
|
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c |
||||||
|
index 43f82cb29e..7a7e66dbda 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_rsa.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_rsa.c |
||||||
|
@@ -587,36 +587,6 @@ ossl_rsa_get_params(VALUE self) |
||||||
|
return hash; |
||||||
|
} |
||||||
|
|
||||||
|
-/* |
||||||
|
- * call-seq: |
||||||
|
- * rsa.to_text => String |
||||||
|
- * |
||||||
|
- * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!! |
||||||
|
- * |
||||||
|
- * Dumps all parameters of a keypair to a String |
||||||
|
- * |
||||||
|
- * Don't use :-)) (It's up to you) |
||||||
|
- */ |
||||||
|
-static VALUE |
||||||
|
-ossl_rsa_to_text(VALUE self) |
||||||
|
-{ |
||||||
|
- RSA *rsa; |
||||||
|
- BIO *out; |
||||||
|
- VALUE str; |
||||||
|
- |
||||||
|
- GetRSA(self, rsa); |
||||||
|
- if (!(out = BIO_new(BIO_s_mem()))) { |
||||||
|
- ossl_raise(eRSAError, NULL); |
||||||
|
- } |
||||||
|
- if (!RSA_print(out, rsa, 0)) { /* offset = 0 */ |
||||||
|
- BIO_free(out); |
||||||
|
- ossl_raise(eRSAError, NULL); |
||||||
|
- } |
||||||
|
- str = ossl_membio2str(out); |
||||||
|
- |
||||||
|
- return str; |
||||||
|
-} |
||||||
|
- |
||||||
|
/* |
||||||
|
* call-seq: |
||||||
|
* rsa.public_key -> RSA |
||||||
|
@@ -738,7 +708,6 @@ Init_ossl_rsa(void) |
||||||
|
|
||||||
|
rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0); |
||||||
|
rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0); |
||||||
|
- rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0); |
||||||
|
rb_define_method(cRSA, "export", ossl_rsa_export, -1); |
||||||
|
rb_define_alias(cRSA, "to_pem", "export"); |
||||||
|
rb_define_alias(cRSA, "to_s", "export"); |
||||||
|
diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb |
||||||
|
index 5307fe5b08..3630458b3c 100644 |
||||||
|
--- a/test/openssl/test_pkey.rb |
||||||
|
+++ b/test/openssl/test_pkey.rb |
||||||
|
@@ -151,4 +151,9 @@ def test_x25519 |
||||||
|
assert_equal bob_pem, bob.public_to_pem |
||||||
|
assert_equal [shared_secret].pack("H*"), alice.derive(bob) |
||||||
|
end |
||||||
|
+ |
||||||
|
+ def test_to_text |
||||||
|
+ rsa = Fixtures.pkey("rsa1024") |
||||||
|
+ assert_include rsa.to_text, "publicExponent" |
||||||
|
+ end |
||||||
|
end |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
||||||
|
|
||||||
|
From 0c45b22e485bfa62f4d704b08e3704e6444118c4 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Thu, 15 Apr 2021 19:11:32 +0900 |
||||||
|
Subject: [PATCH 2/3] pkey: implement {DH,DSA,RSA}#public_key in Ruby |
||||||
|
|
||||||
|
The low-level API that is used to implement #public_key is deprecated |
||||||
|
in OpenSSL 3.0. It is actually very simple to implement in another way, |
||||||
|
using existing methods only, in much shorter code. Let's do it. |
||||||
|
|
||||||
|
While we are at it, the documentation is updated to recommend against |
||||||
|
using #public_key. Now that OpenSSL::PKey::PKey implements public_to_der |
||||||
|
method, there is no real use case for #public_key in newly written Ruby |
||||||
|
programs. |
||||||
|
--- |
||||||
|
ext/openssl/lib/openssl/pkey.rb | 55 ++++++++++++++++++++++++++++ |
||||||
|
ext/openssl/ossl_pkey_dh.c | 63 +++++++-------------------------- |
||||||
|
ext/openssl/ossl_pkey_dsa.c | 42 ---------------------- |
||||||
|
ext/openssl/ossl_pkey_rsa.c | 58 +----------------------------- |
||||||
|
test/openssl/test_pkey_rsa.rb | 37 ++++++++++--------- |
||||||
|
5 files changed, 87 insertions(+), 168 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb |
||||||
|
index 53ee52f98b..569559e1ce 100644 |
||||||
|
--- a/ext/openssl/lib/openssl/pkey.rb |
||||||
|
+++ b/ext/openssl/lib/openssl/pkey.rb |
||||||
|
@@ -10,6 +10,30 @@ module OpenSSL::PKey |
||||||
|
class DH |
||||||
|
include OpenSSL::Marshal |
||||||
|
|
||||||
|
+ # :call-seq: |
||||||
|
+ # dh.public_key -> dhnew |
||||||
|
+ # |
||||||
|
+ # Returns a new DH instance that carries just the \DH parameters. |
||||||
|
+ # |
||||||
|
+ # Contrary to the method name, the returned DH object contains only |
||||||
|
+ # parameters and not the public key. |
||||||
|
+ # |
||||||
|
+ # This method is provided for backwards compatibility. In most cases, there |
||||||
|
+ # is no need to call this method. |
||||||
|
+ # |
||||||
|
+ # For the purpose of re-generating the key pair while keeping the |
||||||
|
+ # parameters, check OpenSSL::PKey.generate_key. |
||||||
|
+ # |
||||||
|
+ # Example: |
||||||
|
+ # # OpenSSL::PKey::DH.generate by default generates a random key pair |
||||||
|
+ # dh1 = OpenSSL::PKey::DH.generate(2048) |
||||||
|
+ # p dh1.priv_key #=> #<OpenSSL::BN 1288347...> |
||||||
|
+ # dhcopy = dh1.public_key |
||||||
|
+ # p dhcopy.priv_key #=> nil |
||||||
|
+ def public_key |
||||||
|
+ DH.new(to_der) |
||||||
|
+ end |
||||||
|
+ |
||||||
|
# :call-seq: |
||||||
|
# dh.compute_key(pub_bn) -> string |
||||||
|
# |
||||||
|
@@ -89,6 +113,22 @@ def new(*args, &blk) # :nodoc: |
||||||
|
class DSA |
||||||
|
include OpenSSL::Marshal |
||||||
|
|
||||||
|
+ # :call-seq: |
||||||
|
+ # dsa.public_key -> dsanew |
||||||
|
+ # |
||||||
|
+ # Returns a new DSA instance that carries just the \DSA parameters and the |
||||||
|
+ # public key. |
||||||
|
+ # |
||||||
|
+ # This method is provided for backwards compatibility. In most cases, there |
||||||
|
+ # is no need to call this method. |
||||||
|
+ # |
||||||
|
+ # For the purpose of serializing the public key, to PEM or DER encoding of |
||||||
|
+ # X.509 SubjectPublicKeyInfo format, check PKey#public_to_pem and |
||||||
|
+ # PKey#public_to_der. |
||||||
|
+ def public_key |
||||||
|
+ OpenSSL::PKey.read(public_to_der) |
||||||
|
+ end |
||||||
|
+ |
||||||
|
class << self |
||||||
|
# :call-seq: |
||||||
|
# DSA.generate(size) -> dsa |
||||||
|
@@ -159,6 +199,21 @@ def to_bn(conversion_form = group.point_conversion_form) |
||||||
|
class RSA |
||||||
|
include OpenSSL::Marshal |
||||||
|
|
||||||
|
+ # :call-seq: |
||||||
|
+ # rsa.public_key -> rsanew |
||||||
|
+ # |
||||||
|
+ # Returns a new RSA instance that carries just the public key components. |
||||||
|
+ # |
||||||
|
+ # This method is provided for backwards compatibility. In most cases, there |
||||||
|
+ # is no need to call this method. |
||||||
|
+ # |
||||||
|
+ # For the purpose of serializing the public key, to PEM or DER encoding of |
||||||
|
+ # X.509 SubjectPublicKeyInfo format, check PKey#public_to_pem and |
||||||
|
+ # PKey#public_to_der. |
||||||
|
+ def public_key |
||||||
|
+ OpenSSL::PKey.read(public_to_der) |
||||||
|
+ end |
||||||
|
+ |
||||||
|
class << self |
||||||
|
# :call-seq: |
||||||
|
# RSA.generate(size, exponent = 65537) -> RSA |
||||||
|
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c |
||||||
|
index acd3bf474e..a512b209d3 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_dh.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_dh.c |
||||||
|
@@ -266,48 +266,6 @@ ossl_dh_get_params(VALUE self) |
||||||
|
return hash; |
||||||
|
} |
||||||
|
|
||||||
|
-/* |
||||||
|
- * call-seq: |
||||||
|
- * dh.public_key -> aDH |
||||||
|
- * |
||||||
|
- * Returns a new DH instance that carries just the public information, i.e. |
||||||
|
- * the prime _p_ and the generator _g_, but no public/private key yet. Such |
||||||
|
- * a pair may be generated using DH#generate_key!. The "public key" needed |
||||||
|
- * for a key exchange with DH#compute_key is considered as per-session |
||||||
|
- * information and may be retrieved with DH#pub_key once a key pair has |
||||||
|
- * been generated. |
||||||
|
- * If the current instance already contains private information (and thus a |
||||||
|
- * valid public/private key pair), this information will no longer be present |
||||||
|
- * in the new instance generated by DH#public_key. This feature is helpful for |
||||||
|
- * publishing the Diffie-Hellman parameters without leaking any of the private |
||||||
|
- * per-session information. |
||||||
|
- * |
||||||
|
- * === Example |
||||||
|
- * dh = OpenSSL::PKey::DH.new(2048) # has public and private key set |
||||||
|
- * public_key = dh.public_key # contains only prime and generator |
||||||
|
- * parameters = public_key.to_der # it's safe to publish this |
||||||
|
- */ |
||||||
|
-static VALUE |
||||||
|
-ossl_dh_to_public_key(VALUE self) |
||||||
|
-{ |
||||||
|
- EVP_PKEY *pkey; |
||||||
|
- DH *orig_dh, *dh; |
||||||
|
- VALUE obj; |
||||||
|
- |
||||||
|
- obj = rb_obj_alloc(rb_obj_class(self)); |
||||||
|
- GetPKey(obj, pkey); |
||||||
|
- |
||||||
|
- GetDH(self, orig_dh); |
||||||
|
- dh = DHparams_dup(orig_dh); |
||||||
|
- if (!dh) |
||||||
|
- ossl_raise(eDHError, "DHparams_dup"); |
||||||
|
- if (!EVP_PKEY_assign_DH(pkey, dh)) { |
||||||
|
- DH_free(dh); |
||||||
|
- ossl_raise(eDHError, "EVP_PKEY_assign_DH"); |
||||||
|
- } |
||||||
|
- return obj; |
||||||
|
-} |
||||||
|
- |
||||||
|
/* |
||||||
|
* call-seq: |
||||||
|
* dh.params_ok? -> true | false |
||||||
|
@@ -384,14 +342,20 @@ Init_ossl_dh(void) |
||||||
|
* The per-session private key, an OpenSSL::BN. |
||||||
|
* |
||||||
|
* === Example of a key exchange |
||||||
|
- * dh1 = OpenSSL::PKey::DH.new(2048) |
||||||
|
- * der = dh1.public_key.to_der #you may send this publicly to the participating party |
||||||
|
- * dh2 = OpenSSL::PKey::DH.new(der) |
||||||
|
- * dh2.generate_key! #generate the per-session key pair |
||||||
|
- * symm_key1 = dh1.compute_key(dh2.pub_key) |
||||||
|
- * symm_key2 = dh2.compute_key(dh1.pub_key) |
||||||
|
+ * # you may send the parameters (der) and own public key (pub1) publicly |
||||||
|
+ * # to the participating party |
||||||
|
+ * dh1 = OpenSSL::PKey::DH.new(2048) |
||||||
|
+ * der = dh1.to_der |
||||||
|
+ * pub1 = dh1.pub_key |
||||||
|
+ * |
||||||
|
+ * # the other party generates its per-session key pair |
||||||
|
+ * dhparams = OpenSSL::PKey::DH.new(der) |
||||||
|
+ * dh2 = OpenSSL::PKey.generate_key(dhparams) |
||||||
|
+ * pub2 = dh2.pub_key |
||||||
|
* |
||||||
|
- * puts symm_key1 == symm_key2 # => true |
||||||
|
+ * symm_key1 = dh1.compute_key(pub2) |
||||||
|
+ * symm_key2 = dh2.compute_key(pub1) |
||||||
|
+ * puts symm_key1 == symm_key2 # => true |
||||||
|
*/ |
||||||
|
cDH = rb_define_class_under(mPKey, "DH", cPKey); |
||||||
|
rb_define_method(cDH, "initialize", ossl_dh_initialize, -1); |
||||||
|
@@ -402,7 +366,6 @@ Init_ossl_dh(void) |
||||||
|
rb_define_alias(cDH, "to_pem", "export"); |
||||||
|
rb_define_alias(cDH, "to_s", "export"); |
||||||
|
rb_define_method(cDH, "to_der", ossl_dh_to_der, 0); |
||||||
|
- rb_define_method(cDH, "public_key", ossl_dh_to_public_key, 0); |
||||||
|
rb_define_method(cDH, "params_ok?", ossl_dh_check_params, 0); |
||||||
|
|
||||||
|
DEF_OSSL_PKEY_BN(cDH, dh, p); |
||||||
|
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c |
||||||
|
index f017cceb4a..ab9ac781e8 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_dsa.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_dsa.c |
||||||
|
@@ -264,47 +264,6 @@ ossl_dsa_get_params(VALUE self) |
||||||
|
return hash; |
||||||
|
} |
||||||
|
|
||||||
|
-/* |
||||||
|
- * call-seq: |
||||||
|
- * dsa.public_key -> aDSA |
||||||
|
- * |
||||||
|
- * Returns a new DSA instance that carries just the public key information. |
||||||
|
- * If the current instance has also private key information, this will no |
||||||
|
- * longer be present in the new instance. This feature is helpful for |
||||||
|
- * publishing the public key information without leaking any of the private |
||||||
|
- * information. |
||||||
|
- * |
||||||
|
- * === Example |
||||||
|
- * dsa = OpenSSL::PKey::DSA.new(2048) # has public and private information |
||||||
|
- * pub_key = dsa.public_key # has only the public part available |
||||||
|
- * pub_key_der = pub_key.to_der # it's safe to publish this |
||||||
|
- * |
||||||
|
- * |
||||||
|
- */ |
||||||
|
-static VALUE |
||||||
|
-ossl_dsa_to_public_key(VALUE self) |
||||||
|
-{ |
||||||
|
- EVP_PKEY *pkey, *pkey_new; |
||||||
|
- DSA *dsa; |
||||||
|
- VALUE obj; |
||||||
|
- |
||||||
|
- GetPKeyDSA(self, pkey); |
||||||
|
- obj = rb_obj_alloc(rb_obj_class(self)); |
||||||
|
- GetPKey(obj, pkey_new); |
||||||
|
- |
||||||
|
-#define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup( \ |
||||||
|
- (i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa)) |
||||||
|
- dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey)); |
||||||
|
-#undef DSAPublicKey_dup |
||||||
|
- if (!dsa) |
||||||
|
- ossl_raise(eDSAError, "DSAPublicKey_dup"); |
||||||
|
- if (!EVP_PKEY_assign_DSA(pkey_new, dsa)) { |
||||||
|
- DSA_free(dsa); |
||||||
|
- ossl_raise(eDSAError, "EVP_PKEY_assign_DSA"); |
||||||
|
- } |
||||||
|
- return obj; |
||||||
|
-} |
||||||
|
- |
||||||
|
/* |
||||||
|
* call-seq: |
||||||
|
* dsa.syssign(string) -> aString |
||||||
|
@@ -445,7 +404,6 @@ Init_ossl_dsa(void) |
||||||
|
rb_define_alias(cDSA, "to_pem", "export"); |
||||||
|
rb_define_alias(cDSA, "to_s", "export"); |
||||||
|
rb_define_method(cDSA, "to_der", ossl_dsa_to_der, 0); |
||||||
|
- rb_define_method(cDSA, "public_key", ossl_dsa_to_public_key, 0); |
||||||
|
rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1); |
||||||
|
rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2); |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c |
||||||
|
index 7a7e66dbda..1c5476cdcd 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_rsa.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_rsa.c |
||||||
|
@@ -390,7 +390,7 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self) |
||||||
|
* data = "Sign me!" |
||||||
|
* pkey = OpenSSL::PKey::RSA.new(2048) |
||||||
|
* signature = pkey.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA256") |
||||||
|
- * pub_key = pkey.public_key |
||||||
|
+ * pub_key = OpenSSL::PKey.read(pkey.public_to_der) |
||||||
|
* puts pub_key.verify_pss("SHA256", signature, data, |
||||||
|
* salt_length: :auto, mgf1_hash: "SHA256") # => true |
||||||
|
*/ |
||||||
|
@@ -587,61 +587,6 @@ ossl_rsa_get_params(VALUE self) |
||||||
|
return hash; |
||||||
|
} |
||||||
|
|
||||||
|
-/* |
||||||
|
- * call-seq: |
||||||
|
- * rsa.public_key -> RSA |
||||||
|
- * |
||||||
|
- * Makes new RSA instance containing the public key from the private key. |
||||||
|
- */ |
||||||
|
-static VALUE |
||||||
|
-ossl_rsa_to_public_key(VALUE self) |
||||||
|
-{ |
||||||
|
- EVP_PKEY *pkey, *pkey_new; |
||||||
|
- RSA *rsa; |
||||||
|
- VALUE obj; |
||||||
|
- |
||||||
|
- GetPKeyRSA(self, pkey); |
||||||
|
- obj = rb_obj_alloc(rb_obj_class(self)); |
||||||
|
- GetPKey(obj, pkey_new); |
||||||
|
- |
||||||
|
- rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey)); |
||||||
|
- if (!rsa) |
||||||
|
- ossl_raise(eRSAError, "RSAPublicKey_dup"); |
||||||
|
- if (!EVP_PKEY_assign_RSA(pkey_new, rsa)) { |
||||||
|
- RSA_free(rsa); |
||||||
|
- ossl_raise(eRSAError, "EVP_PKEY_assign_RSA"); |
||||||
|
- } |
||||||
|
- return obj; |
||||||
|
-} |
||||||
|
- |
||||||
|
-/* |
||||||
|
- * TODO: Test me |
||||||
|
- |
||||||
|
-static VALUE |
||||||
|
-ossl_rsa_blinding_on(VALUE self) |
||||||
|
-{ |
||||||
|
- RSA *rsa; |
||||||
|
- |
||||||
|
- GetRSA(self, rsa); |
||||||
|
- |
||||||
|
- if (RSA_blinding_on(rsa, ossl_bn_ctx) != 1) { |
||||||
|
- ossl_raise(eRSAError, NULL); |
||||||
|
- } |
||||||
|
- return self; |
||||||
|
-} |
||||||
|
- |
||||||
|
-static VALUE |
||||||
|
-ossl_rsa_blinding_off(VALUE self) |
||||||
|
-{ |
||||||
|
- RSA *rsa; |
||||||
|
- |
||||||
|
- GetRSA(self, rsa); |
||||||
|
- RSA_blinding_off(rsa); |
||||||
|
- |
||||||
|
- return self; |
||||||
|
-} |
||||||
|
- */ |
||||||
|
- |
||||||
|
/* |
||||||
|
* Document-method: OpenSSL::PKey::RSA#set_key |
||||||
|
* call-seq: |
||||||
|
@@ -712,7 +657,6 @@ Init_ossl_rsa(void) |
||||||
|
rb_define_alias(cRSA, "to_pem", "export"); |
||||||
|
rb_define_alias(cRSA, "to_s", "export"); |
||||||
|
rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0); |
||||||
|
- rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0); |
||||||
|
rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1); |
||||||
|
rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1); |
||||||
|
rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1); |
||||||
|
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb |
||||||
|
index d1e68dbc9f..5f8d04e754 100644 |
||||||
|
--- a/test/openssl/test_pkey_rsa.rb |
||||||
|
+++ b/test/openssl/test_pkey_rsa.rb |
||||||
|
@@ -69,29 +69,28 @@ def test_private |
||||||
|
end |
||||||
|
|
||||||
|
def test_new |
||||||
|
- key = OpenSSL::PKey::RSA.new 512 |
||||||
|
- pem = key.public_key.to_pem |
||||||
|
- OpenSSL::PKey::RSA.new pem |
||||||
|
- assert_equal([], OpenSSL.errors) |
||||||
|
- end |
||||||
|
+ key = OpenSSL::PKey::RSA.new(512) |
||||||
|
+ assert_equal 512, key.n.num_bits |
||||||
|
+ assert_equal 65537, key.e |
||||||
|
+ assert_not_nil key.d |
||||||
|
|
||||||
|
- def test_new_exponent_default |
||||||
|
- assert_equal(65537, OpenSSL::PKey::RSA.new(512).e) |
||||||
|
+ # Specify public exponent |
||||||
|
+ key2 = OpenSSL::PKey::RSA.new(512, 3) |
||||||
|
+ assert_equal 512, key2.n.num_bits |
||||||
|
+ assert_equal 3, key2.e |
||||||
|
+ assert_not_nil key2.d |
||||||
|
end |
||||||
|
|
||||||
|
- def test_new_with_exponent |
||||||
|
- 1.upto(30) do |idx| |
||||||
|
- e = (2 ** idx) + 1 |
||||||
|
- key = OpenSSL::PKey::RSA.new(512, e) |
||||||
|
- assert_equal(e, key.e) |
||||||
|
- end |
||||||
|
- end |
||||||
|
+ def test_s_generate |
||||||
|
+ key1 = OpenSSL::PKey::RSA.generate(512) |
||||||
|
+ assert_equal 512, key1.n.num_bits |
||||||
|
+ assert_equal 65537, key1.e |
||||||
|
|
||||||
|
- def test_generate |
||||||
|
- key = OpenSSL::PKey::RSA.generate(512, 17) |
||||||
|
- assert_equal 512, key.n.num_bits |
||||||
|
- assert_equal 17, key.e |
||||||
|
- assert_not_nil key.d |
||||||
|
+ # Specify public exponent |
||||||
|
+ key2 = OpenSSL::PKey::RSA.generate(512, 3) |
||||||
|
+ assert_equal 512, key2.n.num_bits |
||||||
|
+ assert_equal 3, key2.e |
||||||
|
+ assert_not_nil key2.d |
||||||
|
end |
||||||
|
|
||||||
|
def test_new_break |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
||||||
|
|
||||||
|
From 2150af0e55b2a25c24f62006e27e0aec3dc81b57 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Fri, 10 Jul 2020 14:34:51 +0900 |
||||||
|
Subject: [PATCH 3/3] pkey/dh, pkey/ec: use EVP_PKEY_check() family |
||||||
|
|
||||||
|
Use EVP_PKEY_param_check() instead of DH_check() if available. Also, |
||||||
|
use EVP_PKEY_public_check() instead of EC_KEY_check_key(). |
||||||
|
|
||||||
|
EVP_PKEY_*check() is part of the EVP API and is meant to replace those |
||||||
|
low-level functions. They were added by OpenSSL 1.1.1. It is currently |
||||||
|
not provided by LibreSSL. |
||||||
|
--- |
||||||
|
ext/openssl/extconf.rb | 3 +++ |
||||||
|
ext/openssl/ossl_pkey_dh.c | 27 +++++++++++++++++++++++---- |
||||||
|
ext/openssl/ossl_pkey_ec.c | 23 +++++++++++++++++++---- |
||||||
|
test/openssl/test_pkey_dh.rb | 16 ++++++++++++++++ |
||||||
|
4 files changed, 61 insertions(+), 8 deletions(-) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb |
||||||
|
index b3c6647faf..17d93443fc 100644 |
||||||
|
--- a/ext/openssl/extconf.rb |
||||||
|
+++ b/ext/openssl/extconf.rb |
||||||
|
@@ -172,6 +172,9 @@ def find_openssl_library |
||||||
|
have_func("EVP_PBE_scrypt") |
||||||
|
have_func("SSL_CTX_set_post_handshake_auth") |
||||||
|
|
||||||
|
+# added in 1.1.1 |
||||||
|
+have_func("EVP_PKEY_check") |
||||||
|
+ |
||||||
|
Logging::message "=== Checking done. ===\n" |
||||||
|
|
||||||
|
create_header |
||||||
|
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c |
||||||
|
index a512b209d3..ca782bbe59 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_dh.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_dh.c |
||||||
|
@@ -273,19 +273,38 @@ ossl_dh_get_params(VALUE self) |
||||||
|
* Validates the Diffie-Hellman parameters associated with this instance. |
||||||
|
* It checks whether a safe prime and a suitable generator are used. If this |
||||||
|
* is not the case, +false+ is returned. |
||||||
|
+ * |
||||||
|
+ * See also the man page EVP_PKEY_param_check(3). |
||||||
|
*/ |
||||||
|
static VALUE |
||||||
|
ossl_dh_check_params(VALUE self) |
||||||
|
{ |
||||||
|
+ int ret; |
||||||
|
+#ifdef HAVE_EVP_PKEY_CHECK |
||||||
|
+ EVP_PKEY *pkey; |
||||||
|
+ EVP_PKEY_CTX *pctx; |
||||||
|
+ |
||||||
|
+ GetPKey(self, pkey); |
||||||
|
+ pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); |
||||||
|
+ if (!pctx) |
||||||
|
+ ossl_raise(eDHError, "EVP_PKEY_CTX_new"); |
||||||
|
+ ret = EVP_PKEY_param_check(pctx); |
||||||
|
+ EVP_PKEY_CTX_free(pctx); |
||||||
|
+#else |
||||||
|
DH *dh; |
||||||
|
int codes; |
||||||
|
|
||||||
|
GetDH(self, dh); |
||||||
|
- if (!DH_check(dh, &codes)) { |
||||||
|
- return Qfalse; |
||||||
|
- } |
||||||
|
+ ret = DH_check(dh, &codes) == 1 && codes == 0; |
||||||
|
+#endif |
||||||
|
|
||||||
|
- return codes == 0 ? Qtrue : Qfalse; |
||||||
|
+ if (ret == 1) |
||||||
|
+ return Qtrue; |
||||||
|
+ else { |
||||||
|
+ /* DH_check_ex() will put error entry on failure */ |
||||||
|
+ ossl_clear_error(); |
||||||
|
+ return Qfalse; |
||||||
|
+ } |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c |
||||||
|
index ecb8305184..829529d4b9 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey_ec.c |
||||||
|
+++ b/ext/openssl/ossl_pkey_ec.c |
||||||
|
@@ -443,20 +443,35 @@ static VALUE ossl_ec_key_generate_key(VALUE self) |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
- * call-seq: |
||||||
|
- * key.check_key => true |
||||||
|
+ * call-seq: |
||||||
|
+ * key.check_key => true |
||||||
|
* |
||||||
|
- * Raises an exception if the key is invalid. |
||||||
|
+ * Raises an exception if the key is invalid. |
||||||
|
* |
||||||
|
- * See the OpenSSL documentation for EC_KEY_check_key() |
||||||
|
+ * See also the man page EVP_PKEY_public_check(3). |
||||||
|
*/ |
||||||
|
static VALUE ossl_ec_key_check_key(VALUE self) |
||||||
|
{ |
||||||
|
+#ifdef HAVE_EVP_PKEY_CHECK |
||||||
|
+ EVP_PKEY *pkey; |
||||||
|
+ EVP_PKEY_CTX *pctx; |
||||||
|
+ int ret; |
||||||
|
+ |
||||||
|
+ GetPKey(self, pkey); |
||||||
|
+ pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); |
||||||
|
+ if (!pctx) |
||||||
|
+ ossl_raise(eDHError, "EVP_PKEY_CTX_new"); |
||||||
|
+ ret = EVP_PKEY_public_check(pctx); |
||||||
|
+ EVP_PKEY_CTX_free(pctx); |
||||||
|
+ if (ret != 1) |
||||||
|
+ ossl_raise(eECError, "EVP_PKEY_public_check"); |
||||||
|
+#else |
||||||
|
EC_KEY *ec; |
||||||
|
|
||||||
|
GetEC(self, ec); |
||||||
|
if (EC_KEY_check_key(ec) != 1) |
||||||
|
ossl_raise(eECError, "EC_KEY_check_key"); |
||||||
|
+#endif |
||||||
|
|
||||||
|
return Qtrue; |
||||||
|
} |
||||||
|
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb |
||||||
|
index 279ce1984c..f80af8f841 100644 |
||||||
|
--- a/test/openssl/test_pkey_dh.rb |
||||||
|
+++ b/test/openssl/test_pkey_dh.rb |
||||||
|
@@ -86,6 +86,22 @@ def test_key_exchange |
||||||
|
assert_equal(dh.compute_key(dh2.pub_key), dh2.compute_key(dh.pub_key)) |
||||||
|
end |
||||||
|
|
||||||
|
+ def test_params_ok? |
||||||
|
+ dh0 = Fixtures.pkey("dh1024") |
||||||
|
+ |
||||||
|
+ dh1 = OpenSSL::PKey::DH.new(OpenSSL::ASN1::Sequence([ |
||||||
|
+ OpenSSL::ASN1::Integer(dh0.p), |
||||||
|
+ OpenSSL::ASN1::Integer(dh0.g) |
||||||
|
+ ])) |
||||||
|
+ assert_equal(true, dh1.params_ok?) |
||||||
|
+ |
||||||
|
+ dh2 = OpenSSL::PKey::DH.new(OpenSSL::ASN1::Sequence([ |
||||||
|
+ OpenSSL::ASN1::Integer(dh0.p + 1), |
||||||
|
+ OpenSSL::ASN1::Integer(dh0.g) |
||||||
|
+ ])) |
||||||
|
+ assert_equal(false, dh2.params_ok?) |
||||||
|
+ end |
||||||
|
+ |
||||||
|
def test_dup |
||||||
|
dh = Fixtures.pkey("dh1024") |
||||||
|
dh2 = dh.dup |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
@ -0,0 +1,114 @@ |
|||||||
|
From 8c185e0ae5e42bf5f3d76a1a0898946671116fa3 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Wed, 3 Nov 2021 23:31:29 +0900 |
||||||
|
Subject: [PATCH 1/2] pkey: test parsing concatenated PEM string |
||||||
|
|
||||||
|
PEM-encoded private keys are sometimes stored together with irrelevant |
||||||
|
PEM blocks, such as the corresponding X.509 certificate. |
||||||
|
|
||||||
|
PEM_read_bio_*() family automatically skips unknown PEM blocks, but on |
||||||
|
OpenSSL 3.0 we will be using the new OSSL_DECODER API instead due to |
||||||
|
some breaking changes around the password callback. |
||||||
|
|
||||||
|
Let's add a test case so that we won't break the current behavior. |
||||||
|
--- |
||||||
|
test/openssl/test_pkey_rsa.rb | 6 ++++++ |
||||||
|
1 file changed, 6 insertions(+) |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb |
||||||
|
index dbe87ba4..7510658d 100644 |
||||||
|
--- a/test/openssl/test_pkey_rsa.rb |
||||||
|
+++ b/test/openssl/test_pkey_rsa.rb |
||||||
|
@@ -306,6 +306,12 @@ def test_RSAPrivateKey |
||||||
|
|
||||||
|
assert_equal asn1.to_der, rsa1024.to_der |
||||||
|
assert_equal pem, rsa1024.export |
||||||
|
+ |
||||||
|
+ # Unknown PEM prepended |
||||||
|
+ cert = issue_cert(OpenSSL::X509::Name.new([["CN", "nobody"]]), rsa1024, 1, [], nil, nil) |
||||||
|
+ str = cert.to_text + cert.to_pem + rsa1024.to_pem |
||||||
|
+ key = OpenSSL::PKey::RSA.new(str) |
||||||
|
+ assert_same_rsa rsa1024, key |
||||||
|
end |
||||||
|
|
||||||
|
def test_RSAPrivateKey_encrypted |
||||||
|
|
||||||
|
From a84ea531bbd080c3f58fe8d3dc9ffb1af2251f35 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Sat, 20 Mar 2021 23:16:16 +0900 |
||||||
|
Subject: [PATCH 2/2] pkey: use OSSL_DECODER to load encrypted PEM on OpenSSL |
||||||
|
3.0 |
||||||
|
|
||||||
|
OpenSSL 3.0 has rewritten routines to load pkeys (PEM_read_bio_* and |
||||||
|
d2i_* functions) around the newly introduced OSSL_DECODER API. |
||||||
|
|
||||||
|
This comes with a slight behavior change. They now decrypt and parse |
||||||
|
each encountered PEM block, then check the kind of the block. This used |
||||||
|
to be the reverse: they checked the PEM header to see the kind, and then |
||||||
|
decrypted the content. This means that the password callback may now be |
||||||
|
called repeatedly. |
||||||
|
|
||||||
|
Let's use the OSSL_DECODER API directly on OpenSSL 3.0 so that the |
||||||
|
return value from the password callback will be reused automatically. |
||||||
|
--- |
||||||
|
ext/openssl/ossl_pkey.c | 40 ++++++++++++++++++++++++++++++++++++++++ |
||||||
|
1 file changed, 40 insertions(+) |
||||||
|
|
||||||
|
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c |
||||||
|
index f9f5162e..b08168a5 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.c |
||||||
|
+++ b/ext/openssl/ossl_pkey.c |
||||||
|
@@ -78,6 +78,45 @@ ossl_pkey_new(EVP_PKEY *pkey) |
||||||
|
return obj; |
||||||
|
} |
||||||
|
|
||||||
|
+#if OSSL_OPENSSL_PREREQ(3, 0, 0) |
||||||
|
+# include <openssl/decoder.h> |
||||||
|
+ |
||||||
|
+EVP_PKEY * |
||||||
|
+ossl_pkey_read_generic(BIO *bio, VALUE pass) |
||||||
|
+{ |
||||||
|
+ void *ppass = (void *)pass; |
||||||
|
+ OSSL_DECODER_CTX *dctx; |
||||||
|
+ EVP_PKEY *pkey = NULL; |
||||||
|
+ int pos = 0, pos2; |
||||||
|
+ |
||||||
|
+ dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", NULL, NULL, 0, NULL, NULL); |
||||||
|
+ if (!dctx) |
||||||
|
+ goto out; |
||||||
|
+ if (OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb, ppass) != 1) |
||||||
|
+ goto out; |
||||||
|
+ |
||||||
|
+ /* First check DER */ |
||||||
|
+ if (OSSL_DECODER_from_bio(dctx, bio) == 1) |
||||||
|
+ goto out; |
||||||
|
+ |
||||||
|
+ /* Then check PEM; multiple OSSL_DECODER_from_bio() calls may be needed */ |
||||||
|
+ OSSL_BIO_reset(bio); |
||||||
|
+ if (OSSL_DECODER_CTX_set_input_type(dctx, "PEM") != 1) |
||||||
|
+ goto out; |
||||||
|
+ while (OSSL_DECODER_from_bio(dctx, bio) != 1) { |
||||||
|
+ if (BIO_eof(bio)) |
||||||
|
+ goto out; |
||||||
|
+ pos2 = BIO_tell(bio); |
||||||
|
+ if (pos2 < 0 || pos2 <= pos) |
||||||
|
+ goto out; |
||||||
|
+ pos = pos2; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ out: |
||||||
|
+ OSSL_DECODER_CTX_free(dctx); |
||||||
|
+ return pkey; |
||||||
|
+} |
||||||
|
+#else |
||||||
|
EVP_PKEY * |
||||||
|
ossl_pkey_read_generic(BIO *bio, VALUE pass) |
||||||
|
{ |
||||||
|
@@ -106,6 +145,7 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass) |
||||||
|
out: |
||||||
|
return pkey; |
||||||
|
} |
||||||
|
+#endif |
||||||
|
|
||||||
|
/* |
||||||
|
* call-seq: |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,359 @@ |
|||||||
|
From bcab8c3cd877506de75f50e0f9ed98827ed554b0 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Peter Zhu <peter@peterzhu.ca> |
||||||
|
Date: Tue, 23 Feb 2021 16:28:56 -0500 |
||||||
|
Subject: [PATCH] Use mmap for allocating heap pages |
||||||
|
|
||||||
|
--- |
||||||
|
configure.ac | 16 ++++ |
||||||
|
gc.c | 149 ++++++++++++++++++++++++++--------- |
||||||
|
test/ruby/test_gc_compact.rb | 41 ++++++---- |
||||||
|
3 files changed, 155 insertions(+), 51 deletions(-) |
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac |
||||||
|
index 2dcebdde9f..b1b190004d 100644 |
||||||
|
--- a/configure.ac |
||||||
|
+++ b/configure.ac |
||||||
|
@@ -1944,6 +1944,7 @@ AC_CHECK_FUNCS(memmem) |
||||||
|
AC_CHECK_FUNCS(mkfifo) |
||||||
|
AC_CHECK_FUNCS(mknod) |
||||||
|
AC_CHECK_FUNCS(mktime) |
||||||
|
+AC_CHECK_FUNCS(mmap) |
||||||
|
AC_CHECK_FUNCS(openat) |
||||||
|
AC_CHECK_FUNCS(pipe2) |
||||||
|
AC_CHECK_FUNCS(poll) |
||||||
|
@@ -2666,6 +2667,21 @@ main(int argc, char *argv[]) |
||||||
|
rb_cv_fork_with_pthread=yes)]) |
||||||
|
test x$rb_cv_fork_with_pthread = xyes || AC_DEFINE(CANNOT_FORK_WITH_PTHREAD) |
||||||
|
]) |
||||||
|
+ |
||||||
|
+AC_CHECK_HEADERS([sys/user.h]) |
||||||
|
+AS_IF([test "x$ac_cv_func_mmap" = xyes], [ |
||||||
|
+ AC_CACHE_CHECK([whether PAGE_SIZE is compile-time const], rb_cv_const_page_size, |
||||||
|
+ [malloc_headers=`sed -n '/MALLOC_HEADERS_BEGIN/,/MALLOC_HEADERS_END/p' ${srcdir}/gc.c` |
||||||
|
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$malloc_headers |
||||||
|
+ typedef char conftest_page[PAGE_SIZE]; |
||||||
|
+ ]], [[]])], |
||||||
|
+ [rb_cv_const_page_size=yes], |
||||||
|
+ [rb_cv_const_page_size=no])]) |
||||||
|
+]) |
||||||
|
+AS_IF([test "x$rb_cv_const_page_size" = xyes], |
||||||
|
+ [AC_DEFINE(HAVE_CONST_PAGE_SIZE, 1)], |
||||||
|
+ [AC_DEFINE(HAVE_CONST_PAGE_SIZE, 0)] |
||||||
|
+) |
||||||
|
} |
||||||
|
|
||||||
|
: "runtime section" && { |
||||||
|
diff --git a/gc.c b/gc.c |
||||||
|
index f6acf3e117..6f8e5f242d 100644 |
||||||
|
--- a/gc.c |
||||||
|
+++ b/gc.c |
||||||
|
@@ -32,6 +32,7 @@ |
||||||
|
#include <stdarg.h> |
||||||
|
#include <stdio.h> |
||||||
|
|
||||||
|
+/* MALLOC_HEADERS_BEGIN */ |
||||||
|
#ifndef HAVE_MALLOC_USABLE_SIZE |
||||||
|
# ifdef _WIN32 |
||||||
|
# define HAVE_MALLOC_USABLE_SIZE |
||||||
|
@@ -54,6 +55,12 @@ |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
+#if !defined(PAGE_SIZE) && defined(HAVE_SYS_USER_H) |
||||||
|
+/* LIST_HEAD conflicts with sys/queue.h on macOS */ |
||||||
|
+# include <sys/user.h> |
||||||
|
+#endif |
||||||
|
+/* MALLOC_HEADERS_END */ |
||||||
|
+ |
||||||
|
#ifdef HAVE_SYS_TIME_H |
||||||
|
# include <sys/time.h> |
||||||
|
#endif |
||||||
|
@@ -821,6 +828,25 @@ enum { |
||||||
|
HEAP_PAGE_BITMAP_SIZE = (BITS_SIZE * HEAP_PAGE_BITMAP_LIMIT), |
||||||
|
HEAP_PAGE_BITMAP_PLANES = 4 /* RGENGC: mark, unprotected, uncollectible, marking */ |
||||||
|
}; |
||||||
|
+#define HEAP_PAGE_ALIGN (1 << HEAP_PAGE_ALIGN_LOG) |
||||||
|
+#define HEAP_PAGE_SIZE HEAP_PAGE_ALIGN |
||||||
|
+ |
||||||
|
+#ifdef HAVE_MMAP |
||||||
|
+# if HAVE_CONST_PAGE_SIZE |
||||||
|
+/* If we have the HEAP_PAGE and it is a constant, then we can directly use it. */ |
||||||
|
+static const bool USE_MMAP_ALIGNED_ALLOC = (PAGE_SIZE <= HEAP_PAGE_SIZE); |
||||||
|
+# elif defined(PAGE_MAX_SIZE) && (PAGE_MAX_SIZE <= HEAP_PAGE_SIZE) |
||||||
|
+/* PAGE_SIZE <= HEAP_PAGE_SIZE */ |
||||||
|
+static const bool USE_MMAP_ALIGNED_ALLOC = true; |
||||||
|
+# else |
||||||
|
+/* Otherwise, fall back to determining if we can use mmap during runtime. */ |
||||||
|
+# define USE_MMAP_ALIGNED_ALLOC (use_mmap_aligned_alloc != false) |
||||||
|
+ |
||||||
|
+static bool use_mmap_aligned_alloc; |
||||||
|
+# endif |
||||||
|
+#elif !defined(__MINGW32__) && !defined(_WIN32) |
||||||
|
+static const bool USE_MMAP_ALIGNED_ALLOC = false; |
||||||
|
+#endif |
||||||
|
|
||||||
|
struct heap_page { |
||||||
|
short total_slots; |
||||||
|
@@ -1760,14 +1786,14 @@ heap_unlink_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *pag |
||||||
|
heap->total_slots -= page->total_slots; |
||||||
|
} |
||||||
|
|
||||||
|
-static void rb_aligned_free(void *ptr); |
||||||
|
+static void rb_aligned_free(void *ptr, size_t size); |
||||||
|
|
||||||
|
static void |
||||||
|
heap_page_free(rb_objspace_t *objspace, struct heap_page *page) |
||||||
|
{ |
||||||
|
heap_allocated_pages--; |
||||||
|
objspace->profile.total_freed_pages++; |
||||||
|
- rb_aligned_free(GET_PAGE_BODY(page->start)); |
||||||
|
+ rb_aligned_free(GET_PAGE_BODY(page->start), HEAP_PAGE_SIZE); |
||||||
|
free(page); |
||||||
|
} |
||||||
|
|
||||||
|
@@ -1819,7 +1845,7 @@ heap_page_allocate(rb_objspace_t *objspace) |
||||||
|
/* assign heap_page entry */ |
||||||
|
page = calloc1(sizeof(struct heap_page)); |
||||||
|
if (page == 0) { |
||||||
|
- rb_aligned_free(page_body); |
||||||
|
+ rb_aligned_free(page_body, HEAP_PAGE_SIZE); |
||||||
|
rb_memerror(); |
||||||
|
} |
||||||
|
|
||||||
|
@@ -3159,15 +3185,18 @@ Init_heap(void) |
||||||
|
{ |
||||||
|
rb_objspace_t *objspace = &rb_objspace; |
||||||
|
|
||||||
|
-#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) |
||||||
|
- /* If Ruby's heap pages are not a multiple of the system page size, we |
||||||
|
- * cannot use mprotect for the read barrier, so we must disable automatic |
||||||
|
- * compaction. */ |
||||||
|
- int pagesize; |
||||||
|
- pagesize = (int)sysconf(_SC_PAGE_SIZE); |
||||||
|
- if ((HEAP_PAGE_SIZE % pagesize) != 0) { |
||||||
|
- ruby_enable_autocompact = 0; |
||||||
|
- } |
||||||
|
+#if defined(HAVE_MMAP) && !HAVE_CONST_PAGE_SIZE && !defined(PAGE_MAX_SIZE) |
||||||
|
+ /* Need to determine if we can use mmap at runtime. */ |
||||||
|
+# ifdef PAGE_SIZE |
||||||
|
+ /* If the PAGE_SIZE macro can be used. */ |
||||||
|
+ use_mmap_aligned_alloc = PAGE_SIZE <= HEAP_PAGE_SIZE; |
||||||
|
+# elif defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) |
||||||
|
+ /* If we can use sysconf to determine the page size. */ |
||||||
|
+ use_mmap_aligned_alloc = sysconf(_SC_PAGE_SIZE) <= HEAP_PAGE_SIZE; |
||||||
|
+# else |
||||||
|
+ /* Otherwise we can't determine the system page size, so don't use mmap. */ |
||||||
|
+ use_mmap_aligned_alloc = FALSE; |
||||||
|
+# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
objspace->next_object_id = INT2FIX(OBJ_ID_INITIAL); |
||||||
|
@@ -8533,6 +8562,14 @@ gc_start_internal(rb_execution_context_t *ec, VALUE self, VALUE full_mark, VALUE |
||||||
|
|
||||||
|
/* For now, compact implies full mark / sweep, so ignore other flags */ |
||||||
|
if (RTEST(compact)) { |
||||||
|
+ /* If not MinGW, Windows, or does not have mmap, we cannot use mprotect for |
||||||
|
+ * the read barrier, so we must disable compaction. */ |
||||||
|
+#if !defined(__MINGW32__) && !defined(_WIN32) |
||||||
|
+ if (!USE_MMAP_ALIGNED_ALLOC) { |
||||||
|
+ rb_raise(rb_eNotImpError, "Compaction isn't available on this platform"); |
||||||
|
+ } |
||||||
|
+#endif |
||||||
|
+ |
||||||
|
reason |= GPR_FLAG_COMPACT; |
||||||
|
} else { |
||||||
|
if (!RTEST(full_mark)) reason &= ~GPR_FLAG_FULL_MARK; |
||||||
|
@@ -9944,16 +9981,14 @@ gc_disable(rb_execution_context_t *ec, VALUE _) |
||||||
|
static VALUE |
||||||
|
gc_set_auto_compact(rb_execution_context_t *ec, VALUE _, VALUE v) |
||||||
|
{ |
||||||
|
-#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) |
||||||
|
- /* If Ruby's heap pages are not a multiple of the system page size, we |
||||||
|
- * cannot use mprotect for the read barrier, so we must disable automatic |
||||||
|
- * compaction. */ |
||||||
|
- int pagesize; |
||||||
|
- pagesize = (int)sysconf(_SC_PAGE_SIZE); |
||||||
|
- if ((HEAP_PAGE_SIZE % pagesize) != 0) { |
||||||
|
+ /* If not MinGW, Windows, or does not have mmap, we cannot use mprotect for |
||||||
|
+ * the read barrier, so we must disable automatic compaction. */ |
||||||
|
+#if !defined(__MINGW32__) && !defined(_WIN32) |
||||||
|
+ if (!USE_MMAP_ALIGNED_ALLOC) { |
||||||
|
rb_raise(rb_eNotImpError, "Automatic compaction isn't available on this platform"); |
||||||
|
} |
||||||
|
#endif |
||||||
|
+ |
||||||
|
ruby_enable_autocompact = RTEST(v); |
||||||
|
return v; |
||||||
|
} |
||||||
|
@@ -10350,22 +10385,54 @@ rb_aligned_malloc(size_t alignment, size_t size) |
||||||
|
#elif defined _WIN32 |
||||||
|
void *_aligned_malloc(size_t, size_t); |
||||||
|
res = _aligned_malloc(size, alignment); |
||||||
|
-#elif defined(HAVE_POSIX_MEMALIGN) |
||||||
|
- if (posix_memalign(&res, alignment, size) == 0) { |
||||||
|
- return res; |
||||||
|
+#else |
||||||
|
+ if (USE_MMAP_ALIGNED_ALLOC) { |
||||||
|
+ GC_ASSERT(alignment % sysconf(_SC_PAGE_SIZE) == 0); |
||||||
|
+ |
||||||
|
+ char *ptr = mmap(NULL, alignment + size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
||||||
|
+ if (ptr == MAP_FAILED) { |
||||||
|
+ return NULL; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ char *aligned = ptr + alignment; |
||||||
|
+ aligned -= ((VALUE)aligned & (alignment - 1)); |
||||||
|
+ GC_ASSERT(aligned > ptr); |
||||||
|
+ GC_ASSERT(aligned <= ptr + alignment); |
||||||
|
+ |
||||||
|
+ size_t start_out_of_range_size = aligned - ptr; |
||||||
|
+ GC_ASSERT(start_out_of_range_size % sysconf(_SC_PAGE_SIZE) == 0); |
||||||
|
+ if (start_out_of_range_size > 0) { |
||||||
|
+ if (munmap(ptr, start_out_of_range_size)) { |
||||||
|
+ rb_bug("rb_aligned_malloc: munmap failed for start"); |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ size_t end_out_of_range_size = alignment - start_out_of_range_size; |
||||||
|
+ GC_ASSERT(end_out_of_range_size % sysconf(_SC_PAGE_SIZE) == 0); |
||||||
|
+ if (end_out_of_range_size > 0) { |
||||||
|
+ if (munmap(aligned + size, end_out_of_range_size)) { |
||||||
|
+ rb_bug("rb_aligned_malloc: munmap failed for end"); |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ res = (void *)aligned; |
||||||
|
} |
||||||
|
else { |
||||||
|
- return NULL; |
||||||
|
+# if defined(HAVE_POSIX_MEMALIGN) |
||||||
|
+ if (posix_memalign(&res, alignment, size) != 0) { |
||||||
|
+ return NULL; |
||||||
|
+ } |
||||||
|
+# elif defined(HAVE_MEMALIGN) |
||||||
|
+ res = memalign(alignment, size); |
||||||
|
+# else |
||||||
|
+ char* aligned; |
||||||
|
+ res = malloc(alignment + size + sizeof(void*)); |
||||||
|
+ aligned = (char*)res + alignment + sizeof(void*); |
||||||
|
+ aligned -= ((VALUE)aligned & (alignment - 1)); |
||||||
|
+ ((void**)aligned)[-1] = res; |
||||||
|
+ res = (void*)aligned; |
||||||
|
+# endif |
||||||
|
} |
||||||
|
-#elif defined(HAVE_MEMALIGN) |
||||||
|
- res = memalign(alignment, size); |
||||||
|
-#else |
||||||
|
- char* aligned; |
||||||
|
- res = malloc(alignment + size + sizeof(void*)); |
||||||
|
- aligned = (char*)res + alignment + sizeof(void*); |
||||||
|
- aligned -= ((VALUE)aligned & (alignment - 1)); |
||||||
|
- ((void**)aligned)[-1] = res; |
||||||
|
- res = (void*)aligned; |
||||||
|
#endif |
||||||
|
|
||||||
|
/* alignment must be a power of 2 */ |
||||||
|
@@ -10375,16 +10442,26 @@ rb_aligned_malloc(size_t alignment, size_t size) |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
-rb_aligned_free(void *ptr) |
||||||
|
+rb_aligned_free(void *ptr, size_t size) |
||||||
|
{ |
||||||
|
#if defined __MINGW32__ |
||||||
|
__mingw_aligned_free(ptr); |
||||||
|
#elif defined _WIN32 |
||||||
|
_aligned_free(ptr); |
||||||
|
-#elif defined(HAVE_MEMALIGN) || defined(HAVE_POSIX_MEMALIGN) |
||||||
|
- free(ptr); |
||||||
|
#else |
||||||
|
- free(((void**)ptr)[-1]); |
||||||
|
+ if (USE_MMAP_ALIGNED_ALLOC) { |
||||||
|
+ GC_ASSERT(size % sysconf(_SC_PAGE_SIZE) == 0); |
||||||
|
+ if (munmap(ptr, size)) { |
||||||
|
+ rb_bug("rb_aligned_free: munmap failed"); |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+ else { |
||||||
|
+# if defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_MEMALIGN) |
||||||
|
+ free(ptr); |
||||||
|
+# else |
||||||
|
+ free(((void**)ptr)[-1]); |
||||||
|
+# endif |
||||||
|
+ } |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb |
||||||
|
index 4a8cff33f4..f5cab55ba7 100644 |
||||||
|
--- a/test/ruby/test_gc_compact.rb |
||||||
|
+++ b/test/ruby/test_gc_compact.rb |
||||||
|
@@ -4,12 +4,32 @@ |
||||||
|
require 'etc' |
||||||
|
|
||||||
|
class TestGCCompact < Test::Unit::TestCase |
||||||
|
- class AutoCompact < Test::Unit::TestCase |
||||||
|
+ module SupportsCompact |
||||||
|
def setup |
||||||
|
skip "autocompact not supported on this platform" unless supports_auto_compact? |
||||||
|
super |
||||||
|
end |
||||||
|
|
||||||
|
+ private |
||||||
|
+ |
||||||
|
+ def supports_auto_compact? |
||||||
|
+ return true unless defined?(Etc::SC_PAGE_SIZE) |
||||||
|
+ |
||||||
|
+ begin |
||||||
|
+ return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0 |
||||||
|
+ rescue NotImplementedError |
||||||
|
+ rescue ArgumentError |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ true |
||||||
|
+ end |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ include SupportsCompact |
||||||
|
+ |
||||||
|
+ class AutoCompact < Test::Unit::TestCase |
||||||
|
+ include SupportsCompact |
||||||
|
+ |
||||||
|
def test_enable_autocompact |
||||||
|
before = GC.auto_compact |
||||||
|
GC.auto_compact = true |
||||||
|
@@ -59,26 +79,17 @@ def test_implicit_compaction_does_something |
||||||
|
ensure |
||||||
|
GC.auto_compact = before |
||||||
|
end |
||||||
|
- |
||||||
|
- private |
||||||
|
- |
||||||
|
- def supports_auto_compact? |
||||||
|
- return true unless defined?(Etc::SC_PAGE_SIZE) |
||||||
|
- |
||||||
|
- begin |
||||||
|
- return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0 |
||||||
|
- rescue NotImplementedError |
||||||
|
- rescue ArgumentError |
||||||
|
- end |
||||||
|
- |
||||||
|
- true |
||||||
|
- end |
||||||
|
end |
||||||
|
|
||||||
|
def os_page_size |
||||||
|
return true unless defined?(Etc::SC_PAGE_SIZE) |
||||||
|
end |
||||||
|
|
||||||
|
+ def setup |
||||||
|
+ skip "autocompact not supported on this platform" unless supports_auto_compact? |
||||||
|
+ super |
||||||
|
+ end |
||||||
|
+ |
||||||
|
def test_gc_compact_stats |
||||||
|
list = [] |
||||||
|
|
||||||
|
-- |
||||||
|
2.30.1 (Apple Git-130) |
||||||
|
|
@ -0,0 +1,29 @@ |
|||||||
|
From a9977ba2f9863e3fb1b2346589ebbca67d80536c Mon Sep 17 00:00:00 2001 |
||||||
|
From: Nobuyoshi Nakada <nobu@ruby-lang.org> |
||||||
|
Date: Sat, 14 Aug 2021 10:08:19 +0900 |
||||||
|
Subject: [PATCH] Constified addr2line.c |
||||||
|
|
||||||
|
--- |
||||||
|
addr2line.c | 6 +++--- |
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-) |
||||||
|
|
||||||
|
diff --git a/addr2line.c b/addr2line.c |
||||||
|
index 8ee4416650d3..fed1a8da84e5 100644 |
||||||
|
--- a/addr2line.c |
||||||
|
+++ b/addr2line.c |
||||||
|
@@ -1138,12 +1138,12 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa |
||||||
|
set_uint_value(v, read_uleb128(reader)); |
||||||
|
break; |
||||||
|
case DW_FORM_ref_addr: |
||||||
|
- if (reader->address_size == 4) { |
||||||
|
+ if (reader->format == 4) { |
||||||
|
set_uint_value(v, read_uint32(&reader->p)); |
||||||
|
- } else if (reader->address_size == 8) { |
||||||
|
+ } else if (reader->format == 8) { |
||||||
|
set_uint_value(v, read_uint64(&reader->p)); |
||||||
|
} else { |
||||||
|
- fprintf(stderr,"unknown address_size:%d", reader->address_size); |
||||||
|
+ fprintf(stderr,"unknown format:%d", reader->format); |
||||||
|
abort(); |
||||||
|
} |
||||||
|
break; |
@ -0,0 +1,29 @@ |
|||||||
|
From b4b5eab2a5fd0e9ac62c01102dd26d0a433c5683 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Mon, 18 May 2020 02:17:28 +0900 |
||||||
|
Subject: [PATCH] test/openssl/test_digest: do not test constants for legacy |
||||||
|
algorithms |
||||||
|
|
||||||
|
Remove availability test for MD4 and RIPEMD160 as they are considered |
||||||
|
legacy and may be missing depending on the compile-time options of |
||||||
|
OpenSSL. OpenSSL 3.0 by default disables them. |
||||||
|
--- |
||||||
|
test/openssl/test_digest.rb | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_digest.rb b/test/openssl/test_digest.rb |
||||||
|
index 8d7046e831..84c128c12f 100644 |
||||||
|
--- a/test/openssl/test_digest.rb |
||||||
|
+++ b/test/openssl/test_digest.rb |
||||||
|
@@ -54,7 +54,7 @@ def test_reset |
||||||
|
end |
||||||
|
|
||||||
|
def test_digest_constants |
||||||
|
- %w{MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512}.each do |name| |
||||||
|
+ %w{MD5 SHA1 SHA224 SHA256 SHA384 SHA512}.each do |name| |
||||||
|
assert_not_nil(OpenSSL::Digest.new(name)) |
||||||
|
klass = OpenSSL::Digest.const_get(name.tr('-', '_')) |
||||||
|
assert_not_nil(klass.new) |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
@ -0,0 +1,439 @@ |
|||||||
|
From 9596788bdd2d061bef042485af14262e9fc4020c Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Thu, 13 Aug 2020 23:20:55 +0900 |
||||||
|
Subject: [PATCH] test/openssl/test_pkcs12: fix test failures with OpenSSL 3.0 |
||||||
|
|
||||||
|
OpenSSL's PKCS12_create() by default uses pbewithSHAAnd40BitRC2-CBC for |
||||||
|
encryption of the certificates. However, in OpenSSL 3.0, the algorithm |
||||||
|
is part of the legacy provider and is not enabled by default. |
||||||
|
|
||||||
|
Specify another algorithm that is still in the default provider for |
||||||
|
these test cases. |
||||||
|
--- |
||||||
|
test/openssl/test_pkcs12.rb | 297 ++++++++++++++++++------------------ |
||||||
|
1 file changed, 149 insertions(+), 148 deletions(-) |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_pkcs12.rb b/test/openssl/test_pkcs12.rb |
||||||
|
index fdbe753b17..ec676743bc 100644 |
||||||
|
--- a/test/openssl/test_pkcs12.rb |
||||||
|
+++ b/test/openssl/test_pkcs12.rb |
||||||
|
@@ -5,6 +5,9 @@ |
||||||
|
|
||||||
|
module OpenSSL |
||||||
|
class TestPKCS12 < OpenSSL::TestCase |
||||||
|
+ DEFAULT_PBE_PKEYS = "PBE-SHA1-3DES" |
||||||
|
+ DEFAULT_PBE_CERTS = "PBE-SHA1-3DES" |
||||||
|
+ |
||||||
|
def setup |
||||||
|
super |
||||||
|
ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA") |
||||||
|
@@ -14,47 +17,41 @@ def setup |
||||||
|
["subjectKeyIdentifier","hash",false], |
||||||
|
["authorityKeyIdentifier","keyid:always",false], |
||||||
|
] |
||||||
|
- @cacert = issue_cert(ca, Fixtures.pkey("rsa2048"), 1, ca_exts, nil, nil) |
||||||
|
+ ca_key = Fixtures.pkey("rsa-1") |
||||||
|
+ @cacert = issue_cert(ca, ca_key, 1, ca_exts, nil, nil) |
||||||
|
|
||||||
|
inter_ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Intermediate CA") |
||||||
|
- inter_ca_key = OpenSSL::PKey.read <<-_EOS_ |
||||||
|
------BEGIN RSA PRIVATE KEY----- |
||||||
|
-MIICXAIBAAKBgQDp7hIG0SFMG/VWv1dBUWziAPrNmkMXJgTCAoB7jffzRtyyN04K |
||||||
|
-oq/89HAszTMStZoMigQURfokzKsjpUp8OYCAEsBtt9d5zPndWMz/gHN73GrXk3LT |
||||||
|
-ZsxEn7Xv5Da+Y9F/Hx2QZUHarV5cdZixq2NbzWGwrToogOQMh2pxN3Z/0wIDAQAB |
||||||
|
-AoGBAJysUyx3olpsGzv3OMRJeahASbmsSKTXVLZvoIefxOINosBFpCIhZccAG6UV |
||||||
|
-5c/xCvS89xBw8aD15uUfziw3AuT8QPEtHCgfSjeT7aWzBfYswEgOW4XPuWr7EeI9 |
||||||
|
-iNHGD6z+hCN/IQr7FiEBgTp6A+i/hffcSdR83fHWKyb4M7TRAkEA+y4BNd668HmC |
||||||
|
-G5MPRx25n6LixuBxrNp1umfjEI6UZgEFVpYOg4agNuimN6NqM253kcTR94QNTUs5 |
||||||
|
-Kj3EhG1YWwJBAO5rUjiOyCNVX2WUQrOMYK/c1lU7fvrkdygXkvIGkhsPoNRzLPeA |
||||||
|
-HGJszKtrKD8bNihWpWNIyqKRHfKVD7yXT+kCQGCAhVCIGTRoypcDghwljHqLnysf |
||||||
|
-ci0h5ZdPcIqc7ODfxYhFsJ/Rql5ONgYsT5Ig/+lOQAkjf+TRYM4c2xKx2/8CQBvG |
||||||
|
-jv6dy70qDgIUgqzONtlmHeYyFzn9cdBO5sShdVYHvRHjFSMEXsosqK9zvW2UqvuK |
||||||
|
-FJx7d3f29gkzynCLJDkCQGQZlEZJC4vWmWJGRKJ24P6MyQn3VsPfErSKOg4lvyM3 |
||||||
|
-Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es= |
||||||
|
------END RSA PRIVATE KEY----- |
||||||
|
- _EOS_ |
||||||
|
- @inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, ca_exts, @cacert, Fixtures.pkey("rsa2048")) |
||||||
|
+ inter_ca_key = Fixtures.pkey("rsa-2") |
||||||
|
+ @inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, ca_exts, @cacert, ca_key) |
||||||
|
|
||||||
|
exts = [ |
||||||
|
["keyUsage","digitalSignature",true], |
||||||
|
["subjectKeyIdentifier","hash",false], |
||||||
|
] |
||||||
|
ee = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Ruby PKCS12 Test Certificate") |
||||||
|
- @mykey = Fixtures.pkey("rsa1024") |
||||||
|
+ @mykey = Fixtures.pkey("rsa-3") |
||||||
|
@mycert = issue_cert(ee, @mykey, 3, exts, @inter_cacert, inter_ca_key) |
||||||
|
end |
||||||
|
|
||||||
|
- def test_create |
||||||
|
+ def test_create_single_key_single_cert |
||||||
|
pkcs12 = OpenSSL::PKCS12.create( |
||||||
|
"omg", |
||||||
|
"hello", |
||||||
|
@mykey, |
||||||
|
- @mycert |
||||||
|
+ @mycert, |
||||||
|
+ nil, |
||||||
|
+ DEFAULT_PBE_PKEYS, |
||||||
|
+ DEFAULT_PBE_CERTS, |
||||||
|
) |
||||||
|
- assert_equal @mycert.to_der, pkcs12.certificate.to_der |
||||||
|
+ assert_equal @mycert, pkcs12.certificate |
||||||
|
assert_equal @mykey.to_der, pkcs12.key.to_der |
||||||
|
assert_nil pkcs12.ca_certs |
||||||
|
+ |
||||||
|
+ der = pkcs12.to_der |
||||||
|
+ decoded = OpenSSL::PKCS12.new(der, "omg") |
||||||
|
+ assert_equal @mykey.to_der, decoded.key.to_der |
||||||
|
+ assert_equal @mycert, decoded.certificate |
||||||
|
+ assert_equal [], Array(decoded.ca_certs) |
||||||
|
end |
||||||
|
|
||||||
|
def test_create_no_pass |
||||||
|
@@ -62,14 +59,17 @@ def test_create_no_pass |
||||||
|
nil, |
||||||
|
"hello", |
||||||
|
@mykey, |
||||||
|
- @mycert |
||||||
|
+ @mycert, |
||||||
|
+ nil, |
||||||
|
+ DEFAULT_PBE_PKEYS, |
||||||
|
+ DEFAULT_PBE_CERTS, |
||||||
|
) |
||||||
|
- assert_equal @mycert.to_der, pkcs12.certificate.to_der |
||||||
|
+ assert_equal @mycert, pkcs12.certificate |
||||||
|
assert_equal @mykey.to_der, pkcs12.key.to_der |
||||||
|
assert_nil pkcs12.ca_certs |
||||||
|
|
||||||
|
decoded = OpenSSL::PKCS12.new(pkcs12.to_der) |
||||||
|
- assert_cert @mycert, decoded.certificate |
||||||
|
+ assert_equal @mycert, decoded.certificate |
||||||
|
end |
||||||
|
|
||||||
|
def test_create_with_chain |
||||||
|
@@ -80,7 +80,9 @@ def test_create_with_chain |
||||||
|
"hello", |
||||||
|
@mykey, |
||||||
|
@mycert, |
||||||
|
- chain |
||||||
|
+ chain, |
||||||
|
+ DEFAULT_PBE_PKEYS, |
||||||
|
+ DEFAULT_PBE_CERTS, |
||||||
|
) |
||||||
|
assert_equal chain, pkcs12.ca_certs |
||||||
|
end |
||||||
|
@@ -95,14 +97,16 @@ def test_create_with_chain_decode |
||||||
|
"hello", |
||||||
|
@mykey, |
||||||
|
@mycert, |
||||||
|
- chain |
||||||
|
+ chain, |
||||||
|
+ DEFAULT_PBE_PKEYS, |
||||||
|
+ DEFAULT_PBE_CERTS, |
||||||
|
) |
||||||
|
|
||||||
|
decoded = OpenSSL::PKCS12.new(pkcs12.to_der, passwd) |
||||||
|
assert_equal chain.size, decoded.ca_certs.size |
||||||
|
- assert_include_cert @cacert, decoded.ca_certs |
||||||
|
- assert_include_cert @inter_cacert, decoded.ca_certs |
||||||
|
- assert_cert @mycert, decoded.certificate |
||||||
|
+ assert_include decoded.ca_certs, @cacert |
||||||
|
+ assert_include decoded.ca_certs, @inter_cacert |
||||||
|
+ assert_equal @mycert, decoded.certificate |
||||||
|
assert_equal @mykey.to_der, decoded.key.to_der |
||||||
|
end |
||||||
|
|
||||||
|
@@ -126,8 +130,8 @@ def test_create_with_itr |
||||||
|
@mykey, |
||||||
|
@mycert, |
||||||
|
[], |
||||||
|
- nil, |
||||||
|
- nil, |
||||||
|
+ DEFAULT_PBE_PKEYS, |
||||||
|
+ DEFAULT_PBE_CERTS, |
||||||
|
2048 |
||||||
|
) |
||||||
|
|
||||||
|
@@ -138,8 +142,8 @@ def test_create_with_itr |
||||||
|
@mykey, |
||||||
|
@mycert, |
||||||
|
[], |
||||||
|
- nil, |
||||||
|
- nil, |
||||||
|
+ DEFAULT_PBE_PKEYS, |
||||||
|
+ DEFAULT_PBE_CERTS, |
||||||
|
"omg" |
||||||
|
) |
||||||
|
end |
||||||
|
@@ -152,7 +156,8 @@ def test_create_with_mac_itr |
||||||
|
@mykey, |
||||||
|
@mycert, |
||||||
|
[], |
||||||
|
- nil, |
||||||
|
+ DEFAULT_PBE_PKEYS, |
||||||
|
+ DEFAULT_PBE_CERTS, |
||||||
|
nil, |
||||||
|
nil, |
||||||
|
2048 |
||||||
|
@@ -165,148 +170,144 @@ def test_create_with_mac_itr |
||||||
|
@mykey, |
||||||
|
@mycert, |
||||||
|
[], |
||||||
|
- nil, |
||||||
|
- nil, |
||||||
|
+ DEFAULT_PBE_PKEYS, |
||||||
|
+ DEFAULT_PBE_CERTS, |
||||||
|
nil, |
||||||
|
"omg" |
||||||
|
) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
- def test_new_with_one_key_and_one_cert |
||||||
|
- # generated with: |
||||||
|
- # openssl version #=> OpenSSL 1.0.2h 3 May 2016 |
||||||
|
- # openssl pkcs12 -in <@mycert> -inkey <RSA1024> -export -out <out> |
||||||
|
- str = <<~EOF.unpack("m").first |
||||||
|
-MIIGQQIBAzCCBgcGCSqGSIb3DQEHAaCCBfgEggX0MIIF8DCCAu8GCSqGSIb3DQEH |
||||||
|
-BqCCAuAwggLcAgEAMIIC1QYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIeZPM |
||||||
|
-Rh6KiXgCAggAgIICqL6O+LCZmBzdIg6mozPF3FpY0hVbWHvTNMiDHieW3CrAanhN |
||||||
|
-YCH2/wHqH8WpFpEWwF0qEEXAWjHsIlYB4Cfqo6b7XpuZe5eVESsjNTOTMF1JCUJj |
||||||
|
-A6iNefXmCFLync1JK5LUodRDhTlKLU1WPK20X9X4vuEwHn8wt5RUb8P0E+Xh6rpS |
||||||
|
-XC4LkZKT45zF3cJa/n5+dW65ohVGNVnF9D1bCNEKHMOllK1V9omutQ9slW88hpga |
||||||
|
-LGiFsJoFOb/ESGb78KO+bd6zbX1MdKdBV+WD6t1uF/cgU65y+2A4nXs1urda+MJ7 |
||||||
|
-7iVqiB7Vnc9cANTbAkTSGNyoUDVM/NZde782/8IvddLAzUZ2EftoRDke6PvuBOVL |
||||||
|
-ljBhNWmdamrtBqzuzVZCRdWq44KZkF2Xoc9asepwIkdVmntzQF7f1Z+Ta5yg6HFp |
||||||
|
-xnr7CuM+MlHEShXkMgYtHnwAq10fDMSXIvjhi/AA5XUAusDO3D+hbtcRDcJ4uUes |
||||||
|
-dm5dhQE2qJ02Ysn4aH3o1F3RYNOzrxejHJwl0D2TCE8Ww2X342xib57+z9u03ufj |
||||||
|
-jswhiMKxy67f1LhUMq3XrT3uV6kCVXk/KUOUPcXPlPVNA5JmZeFhMp6GrtB5xJJ9 |
||||||
|
-wwBZD8UL5A2U2Mxi2OZsdUBv8eo3jnjZ284aFpt+mCjIHrLW5O0jwY8OCwSlYUoY |
||||||
|
-IY00wlabX0s82kBcIQNZbC1RSV2267ro/7A0MClc8YQ/zWN0FKY6apgtUkHJI1cL |
||||||
|
-1dc77mhnjETjwW94iLMDFy4zQfVu7IfCBqOBzygRNnqqUG66UhTs1xFnWM0mWXl/ |
||||||
|
-Zh9+AMpbRLIPaKCktIjl5juzzm+KEgkhD+707XRCFIGUYGP5bSHzGaz8PK9hj0u1 |
||||||
|
-E2SpZHUvYOcawmxtA7pmpSxl5uQjMIIC+QYJKoZIhvcNAQcBoIIC6gSCAuYwggLi |
||||||
|
-MIIC3gYLKoZIhvcNAQwKAQKgggKmMIICojAcBgoqhkiG9w0BDAEDMA4ECKB338m8 |
||||||
|
-qSzHAgIIAASCAoACFhJeqA3xx+s1qIH6udNQYY5hAL6oz7SXoGwFhDiceSyJjmAD |
||||||
|
-Dby9XWM0bPl1Gj5nqdsuI/lAM++fJeoETk+rxw8q6Ofk2zUaRRE39qgpwBwSk44o |
||||||
|
-0SAFJ6bzHpc5CFh6sZmDaUX5Lm9GtjnGFmmsPTSJT5an5JuJ9WczGBEd0nSBQhJq |
||||||
|
-xHbTGZiN8i3SXcIH531Sub+CBIFWy5lyCKgDYh/kgJFGQAaWUOjLI+7dCEESonXn |
||||||
|
-F3Jh2uPbnDF9MGJyAFoNgWFhgSpi1cf6AUi87GY4Oyur88ddJ1o0D0Kz2uw8/bpG |
||||||
|
-s3O4PYnIW5naZ8mozzbnYByEFk7PoTwM7VhoFBfYNtBoAI8+hBnPY/Y71YUojEXf |
||||||
|
-SeX6QbtkIANfzS1XuFNKElShC3DPQIHpKzaatEsfxHfP+8VOav6zcn4mioao7NHA |
||||||
|
-x7Dp6R1enFGoQOq4UNjBT8YjnkG5vW8zQHW2dAHLTJBq6x2Fzm/4Pjo/8vM1FiGl |
||||||
|
-BQdW5vfDeJ/l6NgQm3xR9ka2E2HaDqIcj1zWbN8jy/bHPFJYuF/HH8MBV/ngMIXE |
||||||
|
-vFEW/ToYv8eif0+EpUtzBsCKD4a7qYYYh87RmEVoQU96q6m+UbhpD2WztYfAPkfo |
||||||
|
-OSL9j2QHhVczhL7OAgqNeM95pOsjA9YMe7exTeqK31LYnTX8oH8WJD1xGbRSJYgu |
||||||
|
-SY6PQbumcJkc/TFPn0GeVUpiDdf83SeG50lo/i7UKQi2l1hi5Y51fQhnBnyMr68D |
||||||
|
-llSZEvSWqfDxBJkBpeg6PIYvkTpEwKRJpVQoM3uYvdqVSSnW6rydqIb+snfOrlhd |
||||||
|
-f+xCtq9xr+kHeTSqLIDRRAnMfgFRhY3IBlj6MSUwIwYJKoZIhvcNAQkVMRYEFBdb |
||||||
|
-8XGWehZ6oPj56Pf/uId46M9AMDEwITAJBgUrDgMCGgUABBRvSCB04/f8f13pp2PF |
||||||
|
-vyl2WuMdEwQIMWFFphPkIUICAggA |
||||||
|
- EOF |
||||||
|
- p12 = OpenSSL::PKCS12.new(str, "abc123") |
||||||
|
- |
||||||
|
- assert_equal @mykey.to_der, p12.key.to_der |
||||||
|
- assert_equal @mycert.subject.to_der, p12.certificate.subject.to_der |
||||||
|
- assert_equal [], Array(p12.ca_certs) |
||||||
|
- end |
||||||
|
- |
||||||
|
def test_new_with_no_keys |
||||||
|
# generated with: |
||||||
|
- # openssl pkcs12 -in <@mycert> -nokeys -export -out <out> |
||||||
|
+ # openssl pkcs12 -certpbe PBE-SHA1-3DES -in <@mycert> -nokeys -export |
||||||
|
str = <<~EOF.unpack("m").first |
||||||
|
-MIIDHAIBAzCCAuIGCSqGSIb3DQEHAaCCAtMEggLPMIICyzCCAscGCSqGSIb3DQEH |
||||||
|
-BqCCArgwggK0AgEAMIICrQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIX4+W |
||||||
|
-irqwH40CAggAgIICgOaCyo+5+6IOVoGCCL80c50bkkzAwqdXxvkKExJSdcJz2uMU |
||||||
|
-0gRrKnZEjL5wrUsN8RwZu8DvgQTEhNEkKsUgM7AWainmN/EnwohIdHZAHpm6WD67 |
||||||
|
-I9kLGp0/DHrqZrV9P2dLfhXLUSQE8PI0tqZPZ8UEABhizkViw4eISTkrOUN7pGbN |
||||||
|
-Qtx/oqgitXDuX2polbxYYDwt9vfHZhykHoKgew26SeJyZfeMs/WZ6olEI4cQUAFr |
||||||
|
-mvYGuC1AxEGTo9ERmU8Pm16j9Hr9PFk50WYe+rnk9oX3wJogQ7XUWS5kYf7XRycd |
||||||
|
-NDkNiwV/ts94bbuaGZp1YA6I48FXpIc8b5fX7t9tY0umGaWy0bARe1L7o0Y89EPe |
||||||
|
-lMg25rOM7j3uPtFG8whbSfdETSy57UxzzTcJ6UwexeaK6wb2jqEmj5AOoPLWeaX0 |
||||||
|
-LyOAszR3v7OPAcjIDYZGdrbb3MZ2f2vo2pdQfu9698BrWhXuM7Odh73RLhJVreNI |
||||||
|
-aezNOAtPyBlvGiBQBGTzRIYHSLL5Y5aVj2vWLAa7hjm5qTL5C5mFdDIo6TkEMr6I |
||||||
|
-OsexNQofEGs19kr8nARXDlcbEimk2VsPj4efQC2CEXZNzURsKca82pa62MJ8WosB |
||||||
|
-DTFd8X06zZZ4nED50vLopZvyW4fyW60lELwOyThAdG8UchoAaz2baqP0K4de44yM |
||||||
|
-Y5/yPFDu4+GoimipJfbiYviRwbzkBxYW8+958ILh0RtagLbvIGxbpaym9PqGjOzx |
||||||
|
-ShNXjLK2aAFZsEizQ8kd09quJHU/ogq2cUXdqqhmOqPnUWrJVi/VCoRB3Pv1/lE4 |
||||||
|
-mrUgr2YZ11rYvBw6g5XvNvFcSc53OKyV7SLn0dwwMTAhMAkGBSsOAwIaBQAEFEWP |
||||||
|
-1WRQykaoD4uJCpTx/wv0SLLBBAiDKI26LJK7xgICCAA= |
||||||
|
+MIIGJAIBAzCCBeoGCSqGSIb3DQEHAaCCBdsEggXXMIIF0zCCBc8GCSqGSIb3 |
||||||
|
+DQEHBqCCBcAwggW8AgEAMIIFtQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQMw |
||||||
|
+DgQIjv5c3OHvnBgCAggAgIIFiMJa8Z/w7errRvCQPXh9dGQz3eJaFq3S2gXD |
||||||
|
+rh6oiwsgIRJZvYAWgU6ll9NV7N5SgvS2DDNVuc3tsP8TPWjp+bIxzS9qmGUV |
||||||
|
+kYWuURWLMKhpF12ZRDab8jcIwBgKoSGiDJk8xHjx6L613/XcRM6ln3VeQK+C |
||||||
|
+hlW5kXniNAUAgTft25Fn61Xa8xnhmsz/fk1ycGnyGjKCnr7Mgy7KV0C1vs23 |
||||||
|
+18n8+b1ktDWLZPYgpmXuMFVh0o+HJTV3O86mkIhJonMcnOMgKZ+i8KeXaocN |
||||||
|
+JQlAPBG4+HOip7FbQT/h6reXv8/J+hgjLfqAb5aV3m03rUX9mXx66nR1tQU0 |
||||||
|
+Jq+XPfDh5+V4akIczLlMyyo/xZjI1/qupcMjr+giOGnGd8BA3cuXW+ueLQiA |
||||||
|
+PpTp+DQLVHRfz9XTZbyqOReNEtEXvO9gOlKSEY5lp65ItXVEs2Oqyf9PfU9y |
||||||
|
+DUltN6fCMilwPyyrsIBKXCu2ZLM5h65KVCXAYEX9lNqj9zrQ7vTqvCNN8RhS |
||||||
|
+ScYouTX2Eqa4Z+gTZWLHa8RCQFoyP6hd+97/Tg2Gv2UTH0myQxIVcnpdi1wy |
||||||
|
+cqb+er7tyKbcO96uSlUjpj/JvjlodtjJcX+oinEqGb/caj4UepbBwiG3vv70 |
||||||
|
+63bS3jTsOLNjDRsR9if3LxIhLa6DW8zOJiGC+EvMD1o4dzHcGVpQ/pZWCHZC |
||||||
|
++YiNJpQOBApiZluE+UZ0m3XrtHFQYk7xblTrh+FJF91wBsok0rZXLAKd8m4p |
||||||
|
+OJsc7quCq3cuHRRTzJQ4nSe01uqbwGDAYwLvi6VWy3svU5qa05eDRmgzEFTG |
||||||
|
+e84Gp/1LQCtpQFr4txkjFchO2whWS80KoQKqmLPyGm1D9Lv53Q4ZsKMgNihs |
||||||
|
+rEepuaOZMKHl4yMAYFoOXZCAYzfbhN6b2phcFAHjMUHUw9e3F0QuDk9D0tsr |
||||||
|
+riYTrkocqlOKfK4QTomx27O0ON2J6f1rtEojGgfl9RNykN7iKGzjS3914QjW |
||||||
|
+W6gGiZejxHsDPEAa4gUp0WiSUSXtD5WJgoyAzLydR2dKWsQ4WlaUXi01CuGy |
||||||
|
++xvncSn2nO3bbot8VD5H6XU1CjREVtnIfbeRYO/uofyLUP3olK5RqN6ne6Xo |
||||||
|
+eXnJ/bjYphA8NGuuuvuW1SCITmINkZDLC9cGlER9+K65RR/DR3TigkexXMeN |
||||||
|
+aJ70ivZYAl0OuhZt3TGIlAzS64TIoyORe3z7Ta1Pp9PZQarYJpF9BBIZIFor |
||||||
|
+757PHHuQKRuugiRkp8B7v4eq1BQ+VeAxCKpyZ7XrgEtbY/AWDiaKcGPKPjc3 |
||||||
|
+AqQraVeQm7kMBT163wFmZArCphzkDOI3bz2oEO8YArMgLq2Vto9jAZlqKyWr |
||||||
|
+pi2bSJxuoP1aoD58CHcWMrf8/j1LVdQhKgHQXSik2ID0H2Wc/XnglhzlVFuJ |
||||||
|
+JsNIW/EGJlZh/5WDez9U0bXqnBlu3uasPEOezdoKlcCmQlmTO5+uLHYLEtNA |
||||||
|
+EH9MtnGZebi9XS5meTuS6z5LILt8O9IHZxmT3JRPHYj287FEzotlLdcJ4Ee5 |
||||||
|
+enW41UHjLrfv4OaITO1hVuoLRGdzjESx/fHMWmxroZ1nVClxECOdT42zvIYJ |
||||||
|
+J3xBZ0gppzQ5fjoYiKjJpxTflRxUuxshk3ih6VUoKtqj/W18tBQ3g5SOlkgT |
||||||
|
+yCW8r74yZlfYmNrPyDMUQYpLUPWj2n71GF0KyPfTU5yOatRgvheh262w5BG3 |
||||||
|
+omFY7mb3tCv8/U2jdMIoukRKacpZiagofz3SxojOJq52cHnCri+gTHBMX0cO |
||||||
|
+j58ygfntHWRzst0pV7Ze2X3fdCAJ4DokH6bNJNthcgmolFJ/y3V1tJjgsdtQ |
||||||
|
+7Pjn/vE6xUV0HXE2x4yoVYNirbAMIvkN/X+atxrN0dA4AchN+zGp8TAxMCEw |
||||||
|
+CQYFKw4DAhoFAAQUQ+6XXkyhf6uYgtbibILN2IjKnOAECLiqoY45MPCrAgII |
||||||
|
+AA== |
||||||
|
EOF |
||||||
|
p12 = OpenSSL::PKCS12.new(str, "abc123") |
||||||
|
|
||||||
|
assert_equal nil, p12.key |
||||||
|
assert_equal nil, p12.certificate |
||||||
|
assert_equal 1, p12.ca_certs.size |
||||||
|
- assert_equal @mycert.subject.to_der, p12.ca_certs[0].subject.to_der |
||||||
|
+ assert_equal @mycert.subject, p12.ca_certs[0].subject |
||||||
|
end |
||||||
|
|
||||||
|
def test_new_with_no_certs |
||||||
|
# generated with: |
||||||
|
- # openssl pkcs12 -inkey <RSA1024> -nocerts -export -out <out> |
||||||
|
+ # openssl pkcs12 -inkey fixtures/openssl/pkey/rsa-1.pem -nocerts -export |
||||||
|
str = <<~EOF.unpack("m").first |
||||||
|
-MIIDJwIBAzCCAu0GCSqGSIb3DQEHAaCCAt4EggLaMIIC1jCCAtIGCSqGSIb3DQEH |
||||||
|
-AaCCAsMEggK/MIICuzCCArcGCyqGSIb3DQEMCgECoIICpjCCAqIwHAYKKoZIhvcN |
||||||
|
-AQwBAzAOBAg6AaYnJs84SwICCAAEggKAQzZH+fWSpcQYD1J7PsGSune85A++fLCQ |
||||||
|
-V7tacp2iv95GJkxwYmfTP176pJdgs00mceB9UJ/u9EX5nD0djdjjQjwo6sgKjY0q |
||||||
|
-cpVhZw8CMxw7kBD2dhtui0zT8z5hy03LePxsjEKsGiSbeVeeGbSfw/I6AAYbv+Uh |
||||||
|
-O/YPBGumeHj/D2WKnfsHJLQ9GAV3H6dv5VKYNxjciK7f/JEyZCuUQGIN64QFHDhJ |
||||||
|
-7fzLqd/ul3FZzJZO6a+dwvcgux09SKVXDRSeFmRCEX4b486iWhJJVspCo9P2KNne |
||||||
|
-ORrpybr3ZSwxyoICmjyo8gj0OSnEfdx9790Ej1takPqSA1wIdSdBLekbZqB0RBQg |
||||||
|
-DEuPOsXNo3QFi8ji1vu0WBRJZZSNC2hr5NL6lNR+DKxG8yzDll2j4W4BBIp22mAE |
||||||
|
-7QRX7kVxu17QJXQhOUac4Dd1qXmzebP8t6xkAxD9L7BWEN5OdiXWwSWGjVjMBneX |
||||||
|
-nYObi/3UT/aVc5WHMHK2BhCI1bwH51E6yZh06d5m0TQpYGUTWDJdWGBSrp3A+8jN |
||||||
|
-N2PMQkWBFrXP3smHoTEN4oZC4FWiPsIEyAkQsfKRhcV9lGKl2Xgq54ROTFLnwKoj |
||||||
|
-Z3zJScnq9qmNzvVZSMmDLkjLyDq0pxRxGKBvgouKkWY7VFFIwwBIJM39iDJ5NbBY |
||||||
|
-i1AQFTRsRSsZrNVPasCXrIq7bhMoJZb/YZOGBLNyJVqKUoYXhtwsajzSq54VlWft |
||||||
|
-JxsPayEd4Vi6O9EU1ahnj6qFEZiKFzsicgK2J1Rb8cYagrp0XWjHW0SBn5GVUWCg |
||||||
|
-GUokSFG/0JTdeYTo/sQuG4qNgJkOolRjpeI48Fciq5VUWLvVdKioXzAxMCEwCQYF |
||||||
|
-Kw4DAhoFAAQUYAuwVtGD1TdgbFK4Yal2XBgwUR4ECEawsN3rNaa6AgIIAA== |
||||||
|
+MIIJ7wIBAzCCCbUGCSqGSIb3DQEHAaCCCaYEggmiMIIJnjCCCZoGCSqGSIb3 |
||||||
|
+DQEHAaCCCYsEggmHMIIJgzCCCX8GCyqGSIb3DQEMCgECoIIJbjCCCWowHAYK |
||||||
|
+KoZIhvcNAQwBAzAOBAjX5nN8jyRKwQICCAAEgglIBIRLHfiY1mNHpl3FdX6+ |
||||||
|
+72L+ZOVXnlZ1MY9HSeg0RMkCJcm0mJ2UD7INUOGXvwpK9fr6WJUZM1IqTihQ |
||||||
|
+1dM0crRC2m23aP7KtAlXh2DYD3otseDtwoN/NE19RsiJzeIiy5TSW1d47weU |
||||||
|
++D4Ig/9FYVFPTDgMzdCxXujhvO/MTbZIjqtcS+IOyF+91KkXrHkfkGjZC7KS |
||||||
|
+WRmYw9BBuIPQEewdTI35sAJcxT8rK7JIiL/9mewbSE+Z28Wq1WXwmjL3oZm9 |
||||||
|
+lw6+f515b197GYEGomr6LQqJJamSYpwQbTGHonku6Tf3ylB4NLFqOnRCKE4K |
||||||
|
+zRSSYIqJBlKHmQ4pDm5awoupHYxMZLZKZvXNYyYN3kV8r1iiNVlY7KBR4CsX |
||||||
|
+rqUkXehRmcPnuqEMW8aOpuYe/HWf8PYI93oiDZjcEZMwW2IZFFrgBbqUeNCM |
||||||
|
+CQTkjAYxi5FyoaoTnHrj/aRtdLOg1xIJe4KKcmOXAVMmVM9QEPNfUwiXJrE7 |
||||||
|
+n42gl4NyzcZpxqwWBT++9TnQGZ/lEpwR6dzkZwICNQLdQ+elsdT7mumywP+1 |
||||||
|
+WaFqg9kpurimaiBu515vJNp9Iqv1Nmke6R8Lk6WVRKPg4Akw0fkuy6HS+LyN |
||||||
|
+ofdCfVUkPGN6zkjAxGZP9ZBwvXUbLRC5W3N5qZuAy5WcsS75z+oVeX9ePV63 |
||||||
|
+cue23sClu8JSJcw3HFgPaAE4sfkQ4MoihPY5kezgT7F7Lw/j86S0ebrDNp4N |
||||||
|
+Y685ec81NRHJ80CAM55f3kGCOEhoifD4VZrvr1TdHZY9Gm3b1RYaJCit2huF |
||||||
|
+nlOfzeimdcv/tkjb6UsbpXx3JKkF2NFFip0yEBERRCdWRYMUpBRcl3ad6XHy |
||||||
|
+w0pVTgIjTxGlbbtOCi3siqMOK0GNt6UgjoEFc1xqjsgLwU0Ta2quRu7RFPGM |
||||||
|
+GoEwoC6VH23p9Hr4uTFOL0uHfkKWKunNN+7YPi6LT6IKmTQwrp+fTO61N6Xh |
||||||
|
+KlqTpwESKsIJB2iMnc8wBkjXJtmG/e2n5oTqfhICIrxYmEb7zKDyK3eqeTj3 |
||||||
|
+FhQh2t7cUIiqcT52AckUqniPmlE6hf82yBjhaQUPfi/ExTBtTDSmFfRPUzq+ |
||||||
|
+Rlla4OHllPRzUXJExyansgCxZbPqlw46AtygSWRGcWoYAKUKwwoYjerqIV5g |
||||||
|
+JoZICV9BOU9TXco1dHXZQTs/nnTwoRmYiL/Ly5XpvUAnQOhYeCPjBeFnPSBR |
||||||
|
+R/hRNqrDH2MOV57v5KQIH2+mvy26tRG+tVGHmLMaOJeQkjLdxx+az8RfXIrH |
||||||
|
+7hpAsoBb+g9jUDY1mUVavPk1T45GMpQH8u3kkzRvChfOst6533GyIZhE7FhN |
||||||
|
+KanC6ACabVFDUs6P9pK9RPQMp1qJfpA0XJFx5TCbVbPkvnkZd8K5Tl/tzNM1 |
||||||
|
+n32eRao4MKr9KDwoDL93S1yJgYTlYjy1XW/ewdedtX+B4koAoz/wSXDYO+GQ |
||||||
|
+Zu6ZSpKSEHTRPhchsJ4oICvpriVaJkn0/Z7H3YjNMB9U5RR9+GiIg1wY1Oa1 |
||||||
|
+S3WfuwrrI6eqfbQwj6PDNu3IKy6srEgvJwaofQALNBPSYWbauM2brc8qsD+t |
||||||
|
+n8jC/aD1aMcy00+9t3H/RVCjEOb3yKfUpAldIkEA2NTTnZpoDQDXeNYU2F/W |
||||||
|
+yhmFjJy8A0O4QOk2xnZK9kcxSRs0v8vI8HivvgWENoVPscsDC4742SSIe6SL |
||||||
|
+f/T08reIX11f0K70rMtLhtFMQdHdYOTNl6JzhkHPLr/f9MEZsBEQx52depnF |
||||||
|
+ARb3gXGbCt7BAi0OeCEBSbLr2yWuW4r55N0wRZSOBtgqgjsiHP7CDQSkbL6p |
||||||
|
+FPlQS1do9gBSHiNYvsmN1LN5bG+mhcVb0UjZub4mL0EqGadjDfDdRJmWqlX0 |
||||||
|
+r5dyMcOWQVy4O2cPqYFlcP9lk8buc5otcyVI2isrAFdlvBK29oK6jc52Aq5Q |
||||||
|
+0b2ESDlgX8WRgiOPPxK8dySKEeuIwngCtJyNTecP9Ug06TDsu0znZGCXJ+3P |
||||||
|
+8JOpykgA8EQdOZOYHbo76ZfB2SkklI5KeRA5IBjGs9G3TZ4PHLy2DIwsbWzS |
||||||
|
+H1g01o1x264nx1cJ+eEgUN/KIiGFIib42RS8Af4D5e+Vj54Rt3axq+ag3kI+ |
||||||
|
+53p8uotyu+SpvvXUP7Kv4xpQ/L6k41VM0rfrd9+DrlDVvSfxP2uh6I1TKF7A |
||||||
|
+CT5n8zguMbng4PGjxvyPBM5k62t6hN5fuw6Af0aZFexh+IjB/5wFQ6onSz23 |
||||||
|
+fBzMW4St7RgSs8fDg3lrM+5rwXiey1jxY1ddaxOoUsWRMvvdd7rZxRZQoN5v |
||||||
|
+AcI5iMkK/vvpQgC/sfzhtXtrJ2XOPZ+GVgi7VcuDLKSkdFMcPbGzO8SdxUnS |
||||||
|
+SLV5XTKqKND+Lrfx7DAoKi5wbDFHu5496/MHK5qP4tBe6sJ5bZc+KDJIH46e |
||||||
|
+wTV1oWtB5tV4q46hOb5WRcn/Wjz3HSKaGZgx5QbK1MfKTzD5CTUn+ArMockX |
||||||
|
+2wJhPnFK85U4rgv8iBuh9bRjyw+YaKf7Z3loXRiE1eRG6RzuPF0ZecFiDumk |
||||||
|
+AC/VUXynJhzePBLqzrQj0exanACdullN+pSfHiRWBxR2VFUkjoFP5X45GK3z |
||||||
|
+OstSH6FOkMVU4afqEmjsIwozDFIyin5EyWTtdhJe3szdJSGY23Tut+9hUatx |
||||||
|
+9FDFLESOd8z3tyQSNiLk/Hib+e/lbjxqbXBG/p/oyvP3N999PLUPtpKqtYkV |
||||||
|
+H0+18sNh9CVfojiJl44fzxe8yCnuefBjut2PxEN0EFRBPv9P2wWlmOxkPKUq |
||||||
|
+NrCJP0rDj5aONLrNZPrR8bZNdIShkZ/rKkoTuA0WMZ+xUlDRxAupdMkWAlrz |
||||||
|
+8IcwNcdDjPnkGObpN5Ctm3vK7UGSBmPeNqkXOYf3QTJ9gStJEd0F6+DzTN5C |
||||||
|
+KGt1IyuGwZqL2Yk51FDIIkr9ykEnBMaA39LS7GFHEDNGlW+fKC7AzA0zfoOr |
||||||
|
+fXZlHMBuqHtXqk3zrsHRqGGoocigg4ctrhD1UREYKj+eIj1TBiRdf7c6+COf |
||||||
|
+NIOmej8pX3FmZ4ui+dDA8r2ctgsWHrb4A6iiH+v1DRA61GtoaA/tNRggewXW |
||||||
|
+VXCZCGWyyTuyHGOqq5ozrv5MlzZLWD/KV/uDsAWmy20RAed1C4AzcXlpX25O |
||||||
|
+M4SNl47g5VRNJRtMqokc8j6TjZrzMDEwITAJBgUrDgMCGgUABBRrkIRuS5qg |
||||||
|
+BC8fv38mue8LZVcbHQQIUNrWKEnskCoCAggA |
||||||
|
EOF |
||||||
|
p12 = OpenSSL::PKCS12.new(str, "abc123") |
||||||
|
|
||||||
|
- assert_equal @mykey.to_der, p12.key.to_der |
||||||
|
+ assert_equal Fixtures.pkey("rsa-1").to_der, p12.key.to_der |
||||||
|
assert_equal nil, p12.certificate |
||||||
|
assert_equal [], Array(p12.ca_certs) |
||||||
|
end |
||||||
|
|
||||||
|
def test_dup |
||||||
|
- p12 = OpenSSL::PKCS12.create("pass", "name", @mykey, @mycert) |
||||||
|
+ p12 = OpenSSL::PKCS12.create( |
||||||
|
+ "pass", |
||||||
|
+ "name", |
||||||
|
+ @mykey, |
||||||
|
+ @mycert, |
||||||
|
+ nil, |
||||||
|
+ DEFAULT_PBE_PKEYS, |
||||||
|
+ DEFAULT_PBE_CERTS, |
||||||
|
+ ) |
||||||
|
assert_equal p12.to_der, p12.dup.to_der |
||||||
|
end |
||||||
|
- |
||||||
|
- private |
||||||
|
- def assert_cert expected, actual |
||||||
|
- [ |
||||||
|
- :subject, |
||||||
|
- :issuer, |
||||||
|
- :serial, |
||||||
|
- :not_before, |
||||||
|
- :not_after, |
||||||
|
- ].each do |attribute| |
||||||
|
- assert_equal expected.send(attribute), actual.send(attribute) |
||||||
|
- end |
||||||
|
- assert_equal expected.to_der, actual.to_der |
||||||
|
- end |
||||||
|
- |
||||||
|
- def assert_include_cert cert, ary |
||||||
|
- der = cert.to_der |
||||||
|
- ary.each do |candidate| |
||||||
|
- if candidate.to_der == der |
||||||
|
- return true |
||||||
|
- end |
||||||
|
- end |
||||||
|
- false |
||||||
|
- end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
@ -0,0 +1,67 @@ |
|||||||
|
From 10d2216b2f35a31777a099d9f765b0b6ea34a63e Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Mon, 18 May 2020 02:35:35 +0900 |
||||||
|
Subject: [PATCH] test/openssl/test_pkey: use EC keys for |
||||||
|
PKey.generate_parameters tests |
||||||
|
|
||||||
|
OpenSSL 3.0 refuses to generate DSA parameters shorter than 2048 bits, |
||||||
|
but generating 2048 bits parameters takes very long time. Let's use EC |
||||||
|
in these test cases instead. |
||||||
|
--- |
||||||
|
test/openssl/test_pkey.rb | 27 +++++++++++---------------- |
||||||
|
1 file changed, 11 insertions(+), 16 deletions(-) |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb |
||||||
|
index 3630458b3c..88a6e04581 100644 |
||||||
|
--- a/test/openssl/test_pkey.rb |
||||||
|
+++ b/test/openssl/test_pkey.rb |
||||||
|
@@ -27,20 +27,16 @@ def test_generic_oid_inspect |
||||||
|
end |
||||||
|
|
||||||
|
def test_s_generate_parameters |
||||||
|
- # 512 is non-default; 1024 is used if 'dsa_paramgen_bits' is not specified |
||||||
|
- # with OpenSSL 1.1.0. |
||||||
|
- pkey = OpenSSL::PKey.generate_parameters("DSA", { |
||||||
|
- "dsa_paramgen_bits" => 512, |
||||||
|
- "dsa_paramgen_q_bits" => 256, |
||||||
|
+ pkey = OpenSSL::PKey.generate_parameters("EC", { |
||||||
|
+ "ec_paramgen_curve" => "secp384r1", |
||||||
|
}) |
||||||
|
- assert_instance_of OpenSSL::PKey::DSA, pkey |
||||||
|
- assert_equal 512, pkey.p.num_bits |
||||||
|
- assert_equal 256, pkey.q.num_bits |
||||||
|
- assert_equal nil, pkey.priv_key |
||||||
|
+ assert_instance_of OpenSSL::PKey::EC, pkey |
||||||
|
+ assert_equal "secp384r1", pkey.group.curve_name |
||||||
|
+ assert_equal nil, pkey.private_key |
||||||
|
|
||||||
|
# Invalid options are checked |
||||||
|
assert_raise(OpenSSL::PKey::PKeyError) { |
||||||
|
- OpenSSL::PKey.generate_parameters("DSA", "invalid" => "option") |
||||||
|
+ OpenSSL::PKey.generate_parameters("EC", "invalid" => "option") |
||||||
|
} |
||||||
|
|
||||||
|
# Parameter generation callback is called |
||||||
|
@@ -59,14 +55,13 @@ def test_s_generate_key |
||||||
|
# DSA key pair cannot be generated without parameters |
||||||
|
OpenSSL::PKey.generate_key("DSA") |
||||||
|
} |
||||||
|
- pkey_params = OpenSSL::PKey.generate_parameters("DSA", { |
||||||
|
- "dsa_paramgen_bits" => 512, |
||||||
|
- "dsa_paramgen_q_bits" => 256, |
||||||
|
+ pkey_params = OpenSSL::PKey.generate_parameters("EC", { |
||||||
|
+ "ec_paramgen_curve" => "secp384r1", |
||||||
|
}) |
||||||
|
pkey = OpenSSL::PKey.generate_key(pkey_params) |
||||||
|
- assert_instance_of OpenSSL::PKey::DSA, pkey |
||||||
|
- assert_equal 512, pkey.p.num_bits |
||||||
|
- assert_not_equal nil, pkey.priv_key |
||||||
|
+ assert_instance_of OpenSSL::PKey::EC, pkey |
||||||
|
+ assert_equal "secp384r1", pkey.group.curve_name |
||||||
|
+ assert_not_equal nil, pkey.private_key |
||||||
|
end |
||||||
|
|
||||||
|
def test_hmac_sign_verify |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
@ -0,0 +1,31 @@ |
|||||||
|
From 05fd14aea7eff2a6911a6f529f1237276482c6e7 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Fri, 10 Jul 2020 13:56:38 +0900 |
||||||
|
Subject: [PATCH] test/openssl/test_ssl: relax regex to match OpenSSL's error |
||||||
|
message |
||||||
|
|
||||||
|
OpenSSL 3.0 slightly changed the error message for a certificate |
||||||
|
verification failure when an untrusted self-signed certificate is found |
||||||
|
in the chain. |
||||||
|
--- |
||||||
|
test/openssl/test_ssl.rb | 4 +++- |
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb |
||||||
|
index 6095d545b5..9e9b8b9b69 100644 |
||||||
|
--- a/test/openssl/test_ssl.rb |
||||||
|
+++ b/test/openssl/test_ssl.rb |
||||||
|
@@ -964,7 +964,9 @@ def test_connect_certificate_verify_failed_exception_message |
||||||
|
start_server(ignore_listener_error: true) { |port| |
||||||
|
ctx = OpenSSL::SSL::SSLContext.new |
||||||
|
ctx.set_params |
||||||
|
- assert_raise_with_message(OpenSSL::SSL::SSLError, /self signed/) { |
||||||
|
+ # OpenSSL <= 1.1.0: "self signed certificate in certificate chain" |
||||||
|
+ # OpenSSL >= 3.0.0: "self-signed certificate in certificate chain" |
||||||
|
+ assert_raise_with_message(OpenSSL::SSL::SSLError, /self.signed/) { |
||||||
|
server_connect(port, ctx) |
||||||
|
} |
||||||
|
} |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
@ -0,0 +1,265 @@ |
|||||||
|
From 2c6797bc97d7c92284dc3c0ed27f97ace4e5cfb9 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Mon, 31 May 2021 11:44:05 +0900 |
||||||
|
Subject: [PATCH] test/openssl/utils: remove dup_public helper method |
||||||
|
|
||||||
|
It uses deprecated PKey::{RSA,DSA,DH}#set_* methods, which will not |
||||||
|
work with OpenSSL 3.0. The same can easily be achieved using |
||||||
|
PKey#public_to_der regardless of the key kind. |
||||||
|
--- |
||||||
|
test/openssl/test_pkey_dh.rb | 8 +++++--- |
||||||
|
test/openssl/test_pkey_dsa.rb | 15 +++++++++++---- |
||||||
|
test/openssl/test_pkey_ec.rb | 15 +++++++++++---- |
||||||
|
test/openssl/test_pkey_rsa.rb | 31 +++++++++++++++++-------------- |
||||||
|
test/openssl/utils.rb | 26 -------------------------- |
||||||
|
5 files changed, 44 insertions(+), 51 deletions(-) |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb |
||||||
|
index f80af8f841..757704caf6 100644 |
||||||
|
--- a/test/openssl/test_pkey_dh.rb |
||||||
|
+++ b/test/openssl/test_pkey_dh.rb |
||||||
|
@@ -40,12 +40,14 @@ def test_derive_key |
||||||
|
|
||||||
|
def test_DHparams |
||||||
|
dh1024 = Fixtures.pkey("dh1024") |
||||||
|
+ dh1024params = dh1024.public_key |
||||||
|
+ |
||||||
|
asn1 = OpenSSL::ASN1::Sequence([ |
||||||
|
OpenSSL::ASN1::Integer(dh1024.p), |
||||||
|
OpenSSL::ASN1::Integer(dh1024.g) |
||||||
|
]) |
||||||
|
key = OpenSSL::PKey::DH.new(asn1.to_der) |
||||||
|
- assert_same_dh dup_public(dh1024), key |
||||||
|
+ assert_same_dh dh1024params, key |
||||||
|
|
||||||
|
pem = <<~EOF |
||||||
|
-----BEGIN DH PARAMETERS----- |
||||||
|
@@ -55,9 +57,9 @@ def test_DHparams |
||||||
|
-----END DH PARAMETERS----- |
||||||
|
EOF |
||||||
|
key = OpenSSL::PKey::DH.new(pem) |
||||||
|
- assert_same_dh dup_public(dh1024), key |
||||||
|
+ assert_same_dh dh1024params, key |
||||||
|
key = OpenSSL::PKey.read(pem) |
||||||
|
- assert_same_dh dup_public(dh1024), key |
||||||
|
+ assert_same_dh dh1024params, key |
||||||
|
|
||||||
|
assert_equal asn1.to_der, dh1024.to_der |
||||||
|
assert_equal pem, dh1024.export |
||||||
|
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb |
||||||
|
index 147e50176b..0994607f21 100644 |
||||||
|
--- a/test/openssl/test_pkey_dsa.rb |
||||||
|
+++ b/test/openssl/test_pkey_dsa.rb |
||||||
|
@@ -138,6 +138,8 @@ def test_DSAPrivateKey_encrypted |
||||||
|
|
||||||
|
def test_PUBKEY |
||||||
|
dsa512 = Fixtures.pkey("dsa512") |
||||||
|
+ dsa512pub = OpenSSL::PKey::DSA.new(dsa512.public_to_der) |
||||||
|
+ |
||||||
|
asn1 = OpenSSL::ASN1::Sequence([ |
||||||
|
OpenSSL::ASN1::Sequence([ |
||||||
|
OpenSSL::ASN1::ObjectId("DSA"), |
||||||
|
@@ -153,7 +155,7 @@ def test_PUBKEY |
||||||
|
]) |
||||||
|
key = OpenSSL::PKey::DSA.new(asn1.to_der) |
||||||
|
assert_not_predicate key, :private? |
||||||
|
- assert_same_dsa dup_public(dsa512), key |
||||||
|
+ assert_same_dsa dsa512pub, key |
||||||
|
|
||||||
|
pem = <<~EOF |
||||||
|
-----BEGIN PUBLIC KEY----- |
||||||
|
@@ -166,10 +168,15 @@ def test_PUBKEY |
||||||
|
-----END PUBLIC KEY----- |
||||||
|
EOF |
||||||
|
key = OpenSSL::PKey::DSA.new(pem) |
||||||
|
- assert_same_dsa dup_public(dsa512), key |
||||||
|
+ assert_same_dsa dsa512pub, key |
||||||
|
+ |
||||||
|
+ assert_equal asn1.to_der, key.to_der |
||||||
|
+ assert_equal pem, key.export |
||||||
|
|
||||||
|
- assert_equal asn1.to_der, dup_public(dsa512).to_der |
||||||
|
- assert_equal pem, dup_public(dsa512).export |
||||||
|
+ assert_equal asn1.to_der, dsa512.public_to_der |
||||||
|
+ assert_equal asn1.to_der, key.public_to_der |
||||||
|
+ assert_equal pem, dsa512.public_to_pem |
||||||
|
+ assert_equal pem, key.public_to_pem |
||||||
|
end |
||||||
|
|
||||||
|
def test_read_DSAPublicKey_pem |
||||||
|
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb |
||||||
|
index 4b6df0290f..d62f1b5eb8 100644 |
||||||
|
--- a/test/openssl/test_pkey_ec.rb |
||||||
|
+++ b/test/openssl/test_pkey_ec.rb |
||||||
|
@@ -210,6 +210,8 @@ def test_ECPrivateKey_encrypted |
||||||
|
|
||||||
|
def test_PUBKEY |
||||||
|
p256 = Fixtures.pkey("p256") |
||||||
|
+ p256pub = OpenSSL::PKey::EC.new(p256.public_to_der) |
||||||
|
+ |
||||||
|
asn1 = OpenSSL::ASN1::Sequence([ |
||||||
|
OpenSSL::ASN1::Sequence([ |
||||||
|
OpenSSL::ASN1::ObjectId("id-ecPublicKey"), |
||||||
|
@@ -221,7 +223,7 @@ def test_PUBKEY |
||||||
|
]) |
||||||
|
key = OpenSSL::PKey::EC.new(asn1.to_der) |
||||||
|
assert_not_predicate key, :private? |
||||||
|
- assert_same_ec dup_public(p256), key |
||||||
|
+ assert_same_ec p256pub, key |
||||||
|
|
||||||
|
pem = <<~EOF |
||||||
|
-----BEGIN PUBLIC KEY----- |
||||||
|
@@ -230,10 +232,15 @@ def test_PUBKEY |
||||||
|
-----END PUBLIC KEY----- |
||||||
|
EOF |
||||||
|
key = OpenSSL::PKey::EC.new(pem) |
||||||
|
- assert_same_ec dup_public(p256), key |
||||||
|
+ assert_same_ec p256pub, key |
||||||
|
+ |
||||||
|
+ assert_equal asn1.to_der, key.to_der |
||||||
|
+ assert_equal pem, key.export |
||||||
|
|
||||||
|
- assert_equal asn1.to_der, dup_public(p256).to_der |
||||||
|
- assert_equal pem, dup_public(p256).export |
||||||
|
+ assert_equal asn1.to_der, p256.public_to_der |
||||||
|
+ assert_equal asn1.to_der, key.public_to_der |
||||||
|
+ assert_equal pem, p256.public_to_pem |
||||||
|
+ assert_equal pem, key.public_to_pem |
||||||
|
end |
||||||
|
|
||||||
|
def test_ec_group |
||||||
|
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb |
||||||
|
index 5e127f5407..4548bdb2cf 100644 |
||||||
|
--- a/test/openssl/test_pkey_rsa.rb |
||||||
|
+++ b/test/openssl/test_pkey_rsa.rb |
||||||
|
@@ -201,7 +201,7 @@ def test_sign_verify_pss |
||||||
|
|
||||||
|
def test_encrypt_decrypt |
||||||
|
rsapriv = Fixtures.pkey("rsa-1") |
||||||
|
- rsapub = dup_public(rsapriv) |
||||||
|
+ rsapub = OpenSSL::PKey.read(rsapriv.public_to_der) |
||||||
|
|
||||||
|
# Defaults to PKCS #1 v1.5 |
||||||
|
raw = "data" |
||||||
|
@@ -216,7 +216,7 @@ def test_encrypt_decrypt |
||||||
|
|
||||||
|
def test_encrypt_decrypt_legacy |
||||||
|
rsapriv = Fixtures.pkey("rsa-1") |
||||||
|
- rsapub = dup_public(rsapriv) |
||||||
|
+ rsapub = OpenSSL::PKey.read(rsapriv.public_to_der) |
||||||
|
|
||||||
|
# Defaults to PKCS #1 v1.5 |
||||||
|
raw = "data" |
||||||
|
@@ -346,13 +346,15 @@ def test_RSAPrivateKey_encrypted |
||||||
|
|
||||||
|
def test_RSAPublicKey |
||||||
|
rsa1024 = Fixtures.pkey("rsa1024") |
||||||
|
+ rsa1024pub = OpenSSL::PKey::RSA.new(rsa1024.public_to_der) |
||||||
|
+ |
||||||
|
asn1 = OpenSSL::ASN1::Sequence([ |
||||||
|
OpenSSL::ASN1::Integer(rsa1024.n), |
||||||
|
OpenSSL::ASN1::Integer(rsa1024.e) |
||||||
|
]) |
||||||
|
key = OpenSSL::PKey::RSA.new(asn1.to_der) |
||||||
|
assert_not_predicate key, :private? |
||||||
|
- assert_same_rsa dup_public(rsa1024), key |
||||||
|
+ assert_same_rsa rsa1024pub, key |
||||||
|
|
||||||
|
pem = <<~EOF |
||||||
|
-----BEGIN RSA PUBLIC KEY----- |
||||||
|
@@ -362,11 +364,13 @@ def test_RSAPublicKey |
||||||
|
-----END RSA PUBLIC KEY----- |
||||||
|
EOF |
||||||
|
key = OpenSSL::PKey::RSA.new(pem) |
||||||
|
- assert_same_rsa dup_public(rsa1024), key |
||||||
|
+ assert_same_rsa rsa1024pub, key |
||||||
|
end |
||||||
|
|
||||||
|
def test_PUBKEY |
||||||
|
rsa1024 = Fixtures.pkey("rsa1024") |
||||||
|
+ rsa1024pub = OpenSSL::PKey::RSA.new(rsa1024.public_to_der) |
||||||
|
+ |
||||||
|
asn1 = OpenSSL::ASN1::Sequence([ |
||||||
|
OpenSSL::ASN1::Sequence([ |
||||||
|
OpenSSL::ASN1::ObjectId("rsaEncryption"), |
||||||
|
@@ -381,7 +385,7 @@ def test_PUBKEY |
||||||
|
]) |
||||||
|
key = OpenSSL::PKey::RSA.new(asn1.to_der) |
||||||
|
assert_not_predicate key, :private? |
||||||
|
- assert_same_rsa dup_public(rsa1024), key |
||||||
|
+ assert_same_rsa rsa1024pub, key |
||||||
|
|
||||||
|
pem = <<~EOF |
||||||
|
-----BEGIN PUBLIC KEY----- |
||||||
|
@@ -392,10 +396,15 @@ def test_PUBKEY |
||||||
|
-----END PUBLIC KEY----- |
||||||
|
EOF |
||||||
|
key = OpenSSL::PKey::RSA.new(pem) |
||||||
|
- assert_same_rsa dup_public(rsa1024), key |
||||||
|
+ assert_same_rsa rsa1024pub, key |
||||||
|
+ |
||||||
|
+ assert_equal asn1.to_der, key.to_der |
||||||
|
+ assert_equal pem, key.export |
||||||
|
|
||||||
|
- assert_equal asn1.to_der, dup_public(rsa1024).to_der |
||||||
|
- assert_equal pem, dup_public(rsa1024).export |
||||||
|
+ assert_equal asn1.to_der, rsa1024.public_to_der |
||||||
|
+ assert_equal asn1.to_der, key.public_to_der |
||||||
|
+ assert_equal pem, rsa1024.public_to_pem |
||||||
|
+ assert_equal pem, key.public_to_pem |
||||||
|
end |
||||||
|
|
||||||
|
def test_pem_passwd |
||||||
|
@@ -482,12 +491,6 @@ def test_private_encoding_encrypted |
||||||
|
assert_same_rsa rsa1024, OpenSSL::PKey.read(pem, "abcdef") |
||||||
|
end |
||||||
|
|
||||||
|
- def test_public_encoding |
||||||
|
- rsa1024 = Fixtures.pkey("rsa1024") |
||||||
|
- assert_equal dup_public(rsa1024).to_der, rsa1024.public_to_der |
||||||
|
- assert_equal dup_public(rsa1024).to_pem, rsa1024.public_to_pem |
||||||
|
- end |
||||||
|
- |
||||||
|
def test_dup |
||||||
|
key = Fixtures.pkey("rsa1024") |
||||||
|
key2 = key.dup |
||||||
|
diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb |
||||||
|
index c1d737b2ab..f664bd3074 100644 |
||||||
|
--- a/test/openssl/utils.rb |
||||||
|
+++ b/test/openssl/utils.rb |
||||||
|
@@ -313,32 +313,6 @@ def check_component(base, test, keys) |
||||||
|
assert_equal base.send(comp), test.send(comp) |
||||||
|
} |
||||||
|
end |
||||||
|
- |
||||||
|
- def dup_public(key) |
||||||
|
- case key |
||||||
|
- when OpenSSL::PKey::RSA |
||||||
|
- rsa = OpenSSL::PKey::RSA.new |
||||||
|
- rsa.set_key(key.n, key.e, nil) |
||||||
|
- rsa |
||||||
|
- when OpenSSL::PKey::DSA |
||||||
|
- dsa = OpenSSL::PKey::DSA.new |
||||||
|
- dsa.set_pqg(key.p, key.q, key.g) |
||||||
|
- dsa.set_key(key.pub_key, nil) |
||||||
|
- dsa |
||||||
|
- when OpenSSL::PKey::DH |
||||||
|
- dh = OpenSSL::PKey::DH.new |
||||||
|
- dh.set_pqg(key.p, nil, key.g) |
||||||
|
- dh |
||||||
|
- else |
||||||
|
- if defined?(OpenSSL::PKey::EC) && OpenSSL::PKey::EC === key |
||||||
|
- ec = OpenSSL::PKey::EC.new(key.group) |
||||||
|
- ec.public_key = key.public_key |
||||||
|
- ec |
||||||
|
- else |
||||||
|
- raise "unknown key type" |
||||||
|
- end |
||||||
|
- end |
||||||
|
- end |
||||||
|
end |
||||||
|
|
||||||
|
module OpenSSL::Certs |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
@ -0,0 +1,31 @@ |
|||||||
|
--- ext/openssl/ossl_ocsp.c.orig 2022-04-07 16:40:13.263752886 +0200 |
||||||
|
+++ ext/openssl/ossl_ocsp.c 2022-04-07 16:45:56.818971187 +0200 |
||||||
|
@@ -382,7 +382,7 @@ |
||||||
|
if (!NIL_P(flags)) |
||||||
|
flg = NUM2INT(flags); |
||||||
|
if (NIL_P(digest)) |
||||||
|
- md = EVP_sha1(); |
||||||
|
+ md = NULL; |
||||||
|
else |
||||||
|
md = ossl_evp_get_digestbyname(digest); |
||||||
|
if (NIL_P(certs)) |
||||||
|
@@ -1033,7 +1033,7 @@ |
||||||
|
if (!NIL_P(flags)) |
||||||
|
flg = NUM2INT(flags); |
||||||
|
if (NIL_P(digest)) |
||||||
|
- md = EVP_sha1(); |
||||||
|
+ md = NULL; |
||||||
|
else |
||||||
|
md = ossl_evp_get_digestbyname(digest); |
||||||
|
if (NIL_P(certs)) |
||||||
|
--- test/openssl/test_ocsp.rb.orig 2022-04-08 08:20:31.400739869 +0200 |
||||||
|
+++ test/openssl/test_ocsp.rb 2022-04-08 08:20:37.208727488 +0200 |
||||||
|
@@ -99,7 +99,7 @@ |
||||||
|
request.sign(@cert, @cert_key, [@ca_cert], 0) |
||||||
|
asn1 = OpenSSL::ASN1.decode(request.to_der) |
||||||
|
assert_equal cid.to_der, asn1.value[0].value.find { |a| a.tag_class == :UNIVERSAL }.value[0].value[0].to_der |
||||||
|
- assert_equal OpenSSL::ASN1.ObjectId("sha1WithRSAEncryption").to_der, asn1.value[1].value[0].value[0].value[0].to_der |
||||||
|
+ assert_equal OpenSSL::ASN1.ObjectId("sha256WithRSAEncryption").to_der, asn1.value[1].value[0].value[0].value[0].to_der |
||||||
|
assert_equal @cert.to_der, asn1.value[1].value[0].value[2].value[0].value[0].to_der |
||||||
|
assert_equal @ca_cert.to_der, asn1.value[1].value[0].value[2].value[0].value[1].to_der |
||||||
|
assert_equal asn1.to_der, OpenSSL::OCSP::Request.new(asn1.to_der).to_der |
@ -0,0 +1,647 @@ |
|||||||
|
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb |
||||||
|
index fedcb93..53ad621 100644 |
||||||
|
--- a/ext/openssl/extconf.rb |
||||||
|
+++ b/ext/openssl/extconf.rb |
||||||
|
@@ -174,6 +174,7 @@ have_func("SSL_CTX_set_post_handshake_auth") |
||||||
|
|
||||||
|
# added in 1.1.1 |
||||||
|
have_func("EVP_PKEY_check") |
||||||
|
+have_func("SSL_CTX_set_ciphersuites") |
||||||
|
|
||||||
|
# added in 3.0.0 |
||||||
|
have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h") |
||||||
|
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h |
||||||
|
index 4b51268..2ab8aea 100644 |
||||||
|
--- a/ext/openssl/ossl.h |
||||||
|
+++ b/ext/openssl/ossl.h |
||||||
|
@@ -43,13 +43,13 @@ |
||||||
|
#ifndef LIBRESSL_VERSION_NUMBER |
||||||
|
# define OSSL_IS_LIBRESSL 0 |
||||||
|
# define OSSL_OPENSSL_PREREQ(maj, min, pat) \ |
||||||
|
- (OPENSSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12)) |
||||||
|
+ (OPENSSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12))) |
||||||
|
# define OSSL_LIBRESSL_PREREQ(maj, min, pat) 0 |
||||||
|
#else |
||||||
|
# define OSSL_IS_LIBRESSL 1 |
||||||
|
# define OSSL_OPENSSL_PREREQ(maj, min, pat) 0 |
||||||
|
# define OSSL_LIBRESSL_PREREQ(maj, min, pat) \ |
||||||
|
- (LIBRESSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12)) |
||||||
|
+ (LIBRESSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12))) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if !defined(OPENSSL_NO_ENGINE) && !OSSL_OPENSSL_PREREQ(3, 0, 0) |
||||||
|
diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c |
||||||
|
index a61d3ee..0d3fa9a 100644 |
||||||
|
--- a/ext/openssl/ossl_asn1.c |
||||||
|
+++ b/ext/openssl/ossl_asn1.c |
||||||
|
@@ -1510,7 +1510,7 @@ Init_ossl_asn1(void) |
||||||
|
* |
||||||
|
* An Array that stores the name of a given tag number. These names are |
||||||
|
* the same as the name of the tag constant that is additionally defined, |
||||||
|
- * e.g. UNIVERSAL_TAG_NAME[2] = "INTEGER" and OpenSSL::ASN1::INTEGER = 2. |
||||||
|
+ * e.g. <tt>UNIVERSAL_TAG_NAME[2] = "INTEGER"</tt> and <tt>OpenSSL::ASN1::INTEGER = 2</tt>. |
||||||
|
* |
||||||
|
* == Example usage |
||||||
|
* |
||||||
|
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c |
||||||
|
index 2a4835a..24d0da4 100644 |
||||||
|
--- a/ext/openssl/ossl_pkey.c |
||||||
|
+++ b/ext/openssl/ossl_pkey.c |
||||||
|
@@ -649,7 +649,7 @@ ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der) |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
-#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) |
||||||
|
+#if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 5, 0) |
||||||
|
if (!PEM_write_bio_PrivateKey_traditional(bio, pkey, enc, NULL, 0, |
||||||
|
ossl_pem_passwd_cb, |
||||||
|
(void *)pass)) { |
||||||
|
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c |
||||||
|
index 9a0682a..af262d9 100644 |
||||||
|
--- a/ext/openssl/ossl_ssl.c |
||||||
|
+++ b/ext/openssl/ossl_ssl.c |
||||||
|
@@ -1025,27 +1025,13 @@ ossl_sslctx_get_ciphers(VALUE self) |
||||||
|
return ary; |
||||||
|
} |
||||||
|
|
||||||
|
-/* |
||||||
|
- * call-seq: |
||||||
|
- * ctx.ciphers = "cipher1:cipher2:..." |
||||||
|
- * ctx.ciphers = [name, ...] |
||||||
|
- * ctx.ciphers = [[name, version, bits, alg_bits], ...] |
||||||
|
- * |
||||||
|
- * Sets the list of available cipher suites for this context. Note in a server |
||||||
|
- * context some ciphers require the appropriate certificates. For example, an |
||||||
|
- * RSA cipher suite can only be chosen when an RSA certificate is available. |
||||||
|
- */ |
||||||
|
static VALUE |
||||||
|
-ossl_sslctx_set_ciphers(VALUE self, VALUE v) |
||||||
|
+build_cipher_string(VALUE v) |
||||||
|
{ |
||||||
|
- SSL_CTX *ctx; |
||||||
|
VALUE str, elem; |
||||||
|
int i; |
||||||
|
|
||||||
|
- rb_check_frozen(self); |
||||||
|
- if (NIL_P(v)) |
||||||
|
- return v; |
||||||
|
- else if (RB_TYPE_P(v, T_ARRAY)) { |
||||||
|
+ if (RB_TYPE_P(v, T_ARRAY)) { |
||||||
|
str = rb_str_new(0, 0); |
||||||
|
for (i = 0; i < RARRAY_LEN(v); i++) { |
||||||
|
elem = rb_ary_entry(v, i); |
||||||
|
@@ -1059,14 +1059,67 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v) |
||||||
|
StringValue(str); |
||||||
|
} |
||||||
|
|
||||||
|
+ return str; |
||||||
|
+} |
||||||
|
+ |
||||||
|
+/* |
||||||
|
+ * call-seq: |
||||||
|
+ * ctx.ciphers = "cipher1:cipher2:..." |
||||||
|
+ * ctx.ciphers = [name, ...] |
||||||
|
+ * ctx.ciphers = [[name, version, bits, alg_bits], ...] |
||||||
|
+ * |
||||||
|
+ * Sets the list of available cipher suites for this context. Note in a server |
||||||
|
+ * context some ciphers require the appropriate certificates. For example, an |
||||||
|
+ * RSA cipher suite can only be chosen when an RSA certificate is available. |
||||||
|
+ */ |
||||||
|
+static VALUE |
||||||
|
+ossl_sslctx_set_ciphers(VALUE self, VALUE v) |
||||||
|
+{ |
||||||
|
+ SSL_CTX *ctx; |
||||||
|
+ VALUE str; |
||||||
|
+ |
||||||
|
+ rb_check_frozen(self); |
||||||
|
+ if (NIL_P(v)) |
||||||
|
+ return v; |
||||||
|
+ |
||||||
|
+ str = build_cipher_string(v); |
||||||
|
+ |
||||||
|
GetSSLCTX(self, ctx); |
||||||
|
- if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) { |
||||||
|
+ if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) |
||||||
|
ossl_raise(eSSLError, "SSL_CTX_set_cipher_list"); |
||||||
|
- } |
||||||
|
|
||||||
|
return v; |
||||||
|
} |
||||||
|
|
||||||
|
+#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES |
||||||
|
+/* |
||||||
|
+ * call-seq: |
||||||
|
+ * ctx.ciphersuites = "cipher1:cipher2:..." |
||||||
|
+ * ctx.ciphersuites = [name, ...] |
||||||
|
+ * ctx.ciphersuites = [[name, version, bits, alg_bits], ...] |
||||||
|
+ * |
||||||
|
+ * Sets the list of available TLSv1.3 cipher suites for this context. |
||||||
|
+ */ |
||||||
|
+static VALUE |
||||||
|
+ossl_sslctx_set_ciphersuites(VALUE self, VALUE v) |
||||||
|
+{ |
||||||
|
+ SSL_CTX *ctx; |
||||||
|
+ VALUE str; |
||||||
|
+ |
||||||
|
+ rb_check_frozen(self); |
||||||
|
+ if (NIL_P(v)) |
||||||
|
+ return v; |
||||||
|
+ |
||||||
|
+ str = build_cipher_string(v); |
||||||
|
+ |
||||||
|
+ GetSSLCTX(self, ctx); |
||||||
|
+ if (!SSL_CTX_set_ciphersuites(ctx, StringValueCStr(str))) |
||||||
|
+ ossl_raise(eSSLError, "SSL_CTX_set_ciphersuites"); |
||||||
|
+ |
||||||
|
+ return v; |
||||||
|
+} |
||||||
|
+#endif |
||||||
|
+ |
||||||
|
#if !defined(OPENSSL_NO_EC) |
||||||
|
/* |
||||||
|
* call-seq: |
||||||
|
@@ -2818,6 +2857,9 @@ Init_ossl_ssl(void) |
||||||
|
ossl_sslctx_set_minmax_proto_version, 2); |
||||||
|
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0); |
||||||
|
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1); |
||||||
|
+#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES |
||||||
|
+ rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1); |
||||||
|
+#endif |
||||||
|
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1); |
||||||
|
rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0); |
||||||
|
rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1); |
||||||
|
diff --git a/test/openssl/test_asn1.rb b/test/openssl/test_asn1.rb |
||||||
|
index 0fd7971..c79bc14 100644 |
||||||
|
--- a/test/openssl/test_asn1.rb |
||||||
|
+++ b/test/openssl/test_asn1.rb |
||||||
|
@@ -14,7 +14,7 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase |
||||||
|
["keyUsage","keyCertSign, cRLSign",true], |
||||||
|
["subjectKeyIdentifier","hash",false], |
||||||
|
] |
||||||
|
- dgst = OpenSSL::Digest.new('SHA1') |
||||||
|
+ dgst = OpenSSL::Digest.new('SHA256') |
||||||
|
cert = OpenSSL::TestUtils.issue_cert( |
||||||
|
subj, key, s, exts, nil, nil, digest: dgst, not_before: now, not_after: now+3600) |
||||||
|
|
||||||
|
@@ -42,7 +42,7 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase |
||||||
|
assert_equal(OpenSSL::ASN1::Sequence, sig.class) |
||||||
|
assert_equal(2, sig.value.size) |
||||||
|
assert_equal(OpenSSL::ASN1::ObjectId, sig.value[0].class) |
||||||
|
- assert_equal("1.2.840.113549.1.1.5", sig.value[0].oid) |
||||||
|
+ assert_equal("1.2.840.113549.1.1.11", sig.value[0].oid) |
||||||
|
assert_equal(OpenSSL::ASN1::Null, sig.value[1].class) |
||||||
|
|
||||||
|
dn = tbs_cert.value[3] # issuer |
||||||
|
@@ -189,7 +189,7 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase |
||||||
|
assert_equal(OpenSSL::ASN1::Null, pkey.value[0].value[1].class) |
||||||
|
|
||||||
|
assert_equal(OpenSSL::ASN1::BitString, sig_val.class) |
||||||
|
- cululated_sig = key.sign(OpenSSL::Digest.new('SHA1'), tbs_cert.to_der) |
||||||
|
+ cululated_sig = key.sign(OpenSSL::Digest.new('SHA256'), tbs_cert.to_der) |
||||||
|
assert_equal(cululated_sig, sig_val.value) |
||||||
|
end |
||||||
|
|
||||||
|
diff --git a/test/openssl/test_ns_spki.rb b/test/openssl/test_ns_spki.rb |
||||||
|
index ed3be86..383931b 100644 |
||||||
|
--- a/test/openssl/test_ns_spki.rb |
||||||
|
+++ b/test/openssl/test_ns_spki.rb |
||||||
|
@@ -22,7 +22,7 @@ class OpenSSL::TestNSSPI < OpenSSL::TestCase |
||||||
|
spki = OpenSSL::Netscape::SPKI.new |
||||||
|
spki.challenge = "RandomString" |
||||||
|
spki.public_key = key1.public_key |
||||||
|
- spki.sign(key1, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ spki.sign(key1, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert(spki.verify(spki.public_key)) |
||||||
|
assert(spki.verify(key1.public_key)) |
||||||
|
assert(!spki.verify(key2.public_key)) |
||||||
|
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb |
||||||
|
index 726b7db..08213df 100644 |
||||||
|
--- a/test/openssl/test_pkey_dsa.rb |
||||||
|
+++ b/test/openssl/test_pkey_dsa.rb |
||||||
|
@@ -36,8 +36,8 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase |
||||||
|
assert_equal true, dsa512.verify(OpenSSL::Digest.new('DSS1'), signature, data) |
||||||
|
end |
||||||
|
|
||||||
|
- signature = dsa512.sign("SHA1", data) |
||||||
|
- assert_equal true, dsa512.verify("SHA1", signature, data) |
||||||
|
+ signature = dsa512.sign("SHA256", data) |
||||||
|
+ assert_equal true, dsa512.verify("SHA256", signature, data) |
||||||
|
|
||||||
|
signature0 = (<<~'end;').unpack("m")[0] |
||||||
|
MCwCFH5h40plgU5Fh0Z4wvEEpz0eE9SnAhRPbkRB8ggsN/vsSEYMXvJwjGg/ |
||||||
|
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb |
||||||
|
index ffe5a94..c06fe6f 100644 |
||||||
|
--- a/test/openssl/test_pkey_ec.rb |
||||||
|
+++ b/test/openssl/test_pkey_ec.rb |
||||||
|
@@ -98,8 +98,8 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase |
||||||
|
def test_sign_verify |
||||||
|
p256 = Fixtures.pkey("p256") |
||||||
|
data = "Sign me!" |
||||||
|
- signature = p256.sign("SHA1", data) |
||||||
|
- assert_equal true, p256.verify("SHA1", signature, data) |
||||||
|
+ signature = p256.sign("SHA256", data) |
||||||
|
+ assert_equal true, p256.verify("SHA256", signature, data) |
||||||
|
|
||||||
|
signature0 = (<<~'end;').unpack("m")[0] |
||||||
|
MEQCIEOTY/hD7eI8a0qlzxkIt8LLZ8uwiaSfVbjX2dPAvN11AiAQdCYx56Fq |
||||||
|
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb |
||||||
|
index 4bb39ed..9e06e43 100644 |
||||||
|
--- a/test/openssl/test_pkey_rsa.rb |
||||||
|
+++ b/test/openssl/test_pkey_rsa.rb |
||||||
|
@@ -80,8 +80,8 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase |
||||||
|
def test_sign_verify |
||||||
|
rsa1024 = Fixtures.pkey("rsa1024") |
||||||
|
data = "Sign me!" |
||||||
|
- signature = rsa1024.sign("SHA1", data) |
||||||
|
- assert_equal true, rsa1024.verify("SHA1", signature, data) |
||||||
|
+ signature = rsa1024.sign("SHA256", data) |
||||||
|
+ assert_equal true, rsa1024.verify("SHA256", signature, data) |
||||||
|
|
||||||
|
signature0 = (<<~'end;').unpack("m")[0] |
||||||
|
oLCgbprPvfhM4pjFQiDTFeWI9Sk+Og7Nh9TmIZ/xSxf2CGXQrptlwo7NQ28+ |
||||||
|
@@ -113,10 +113,10 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase |
||||||
|
def test_sign_verify_raw |
||||||
|
key = Fixtures.pkey("rsa-1") |
||||||
|
data = "Sign me!" |
||||||
|
- hash = OpenSSL::Digest.digest("SHA1", data) |
||||||
|
- signature = key.sign_raw("SHA1", hash) |
||||||
|
- assert_equal true, key.verify_raw("SHA1", signature, hash) |
||||||
|
- assert_equal true, key.verify("SHA1", signature, data) |
||||||
|
+ hash = OpenSSL::Digest.digest("SHA256", data) |
||||||
|
+ signature = key.sign_raw("SHA256", hash) |
||||||
|
+ assert_equal true, key.verify_raw("SHA256", signature, hash) |
||||||
|
+ assert_equal true, key.verify("SHA256", signature, data) |
||||||
|
|
||||||
|
# Too long data |
||||||
|
assert_raise(OpenSSL::PKey::PKeyError) { |
||||||
|
@@ -129,9 +129,9 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase |
||||||
|
"rsa_pss_saltlen" => 20, |
||||||
|
"rsa_mgf1_md" => "SHA256" |
||||||
|
} |
||||||
|
- sig_pss = key.sign_raw("SHA1", hash, pssopts) |
||||||
|
- assert_equal true, key.verify("SHA1", sig_pss, data, pssopts) |
||||||
|
- assert_equal true, key.verify_raw("SHA1", sig_pss, hash, pssopts) |
||||||
|
+ sig_pss = key.sign_raw("SHA256", hash, pssopts) |
||||||
|
+ assert_equal true, key.verify("SHA256", sig_pss, data, pssopts) |
||||||
|
+ assert_equal true, key.verify_raw("SHA256", sig_pss, hash, pssopts) |
||||||
|
end |
||||||
|
|
||||||
|
def test_sign_verify_raw_legacy |
||||||
|
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb |
||||||
|
index a7607da..3ba8b39 100644 |
||||||
|
--- a/test/openssl/test_ssl.rb |
||||||
|
+++ b/test/openssl/test_ssl.rb |
||||||
|
@@ -669,10 +669,16 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase |
||||||
|
# buzz.example.net, respectively). ... |
||||||
|
assert_equal(true, OpenSSL::SSL.verify_certificate_identity( |
||||||
|
create_cert_with_san('DNS:baz*.example.com'), 'baz1.example.com')) |
||||||
|
+ |
||||||
|
+ # LibreSSL 3.5.0+ doesn't support other wildcard certificates |
||||||
|
+ # (it isn't required to, as RFC states MAY, not MUST) |
||||||
|
+ return if libressl?(3, 5, 0) |
||||||
|
+ |
||||||
|
assert_equal(true, OpenSSL::SSL.verify_certificate_identity( |
||||||
|
create_cert_with_san('DNS:*baz.example.com'), 'foobaz.example.com')) |
||||||
|
assert_equal(true, OpenSSL::SSL.verify_certificate_identity( |
||||||
|
create_cert_with_san('DNS:b*z.example.com'), 'buzz.example.com')) |
||||||
|
+ |
||||||
|
# Section 6.4.3 of RFC6125 states that client should NOT match identifier |
||||||
|
# where wildcard is other than left-most label. |
||||||
|
# |
||||||
|
@@ -1556,8 +1562,101 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
+ def test_ciphersuites_method_tls_connection |
||||||
|
+ ssl_ctx = OpenSSL::SSL::SSLContext.new |
||||||
|
+ if !tls13_supported? || !ssl_ctx.respond_to?(:ciphersuites=) |
||||||
|
+ pend 'TLS 1.3 not supported' |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ csuite = ['TLS_AES_128_GCM_SHA256', 'TLSv1.3', 128, 128] |
||||||
|
+ inputs = [csuite[0], [csuite[0]], [csuite]] |
||||||
|
+ |
||||||
|
+ start_server do |port| |
||||||
|
+ inputs.each do |input| |
||||||
|
+ cli_ctx = OpenSSL::SSL::SSLContext.new |
||||||
|
+ cli_ctx.min_version = cli_ctx.max_version = OpenSSL::SSL::TLS1_3_VERSION |
||||||
|
+ cli_ctx.ciphersuites = input |
||||||
|
+ |
||||||
|
+ server_connect(port, cli_ctx) do |ssl| |
||||||
|
+ assert_equal('TLSv1.3', ssl.ssl_version) |
||||||
|
+ if libressl?(3, 4, 0) && !libressl?(3, 5, 0) |
||||||
|
+ assert_equal("AEAD-AES128-GCM-SHA256", ssl.cipher[0]) |
||||||
|
+ else |
||||||
|
+ assert_equal(csuite[0], ssl.cipher[0]) |
||||||
|
+ end |
||||||
|
+ ssl.puts('abc'); assert_equal("abc\n", ssl.gets) |
||||||
|
+ end |
||||||
|
+ end |
||||||
|
+ end |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ def test_ciphersuites_method_nil_argument |
||||||
|
+ ssl_ctx = OpenSSL::SSL::SSLContext.new |
||||||
|
+ pend 'ciphersuites= method is missing' unless ssl_ctx.respond_to?(:ciphersuites=) |
||||||
|
+ |
||||||
|
+ assert_nothing_raised { ssl_ctx.ciphersuites = nil } |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ def test_ciphersuites_method_frozen_object |
||||||
|
+ ssl_ctx = OpenSSL::SSL::SSLContext.new |
||||||
|
+ pend 'ciphersuites= method is missing' unless ssl_ctx.respond_to?(:ciphersuites=) |
||||||
|
+ |
||||||
|
+ ssl_ctx.freeze |
||||||
|
+ assert_raise(FrozenError) { ssl_ctx.ciphersuites = 'TLS_AES_256_GCM_SHA384' } |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ def test_ciphersuites_method_bogus_csuite |
||||||
|
+ ssl_ctx = OpenSSL::SSL::SSLContext.new |
||||||
|
+ pend 'ciphersuites= method is missing' unless ssl_ctx.respond_to?(:ciphersuites=) |
||||||
|
+ |
||||||
|
+ assert_raise_with_message( |
||||||
|
+ OpenSSL::SSL::SSLError, |
||||||
|
+ /SSL_CTX_set_ciphersuites: no cipher match/i |
||||||
|
+ ) { ssl_ctx.ciphersuites = 'BOGUS' } |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ def test_ciphers_method_tls_connection |
||||||
|
+ csuite = ['ECDHE-RSA-AES256-GCM-SHA384', 'TLSv1.2', 256, 256] |
||||||
|
+ inputs = [csuite[0], [csuite[0]], [csuite]] |
||||||
|
+ |
||||||
|
+ start_server do |port| |
||||||
|
+ inputs.each do |input| |
||||||
|
+ cli_ctx = OpenSSL::SSL::SSLContext.new |
||||||
|
+ cli_ctx.min_version = cli_ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION |
||||||
|
+ cli_ctx.ciphers = input |
||||||
|
+ |
||||||
|
+ server_connect(port, cli_ctx) do |ssl| |
||||||
|
+ assert_equal('TLSv1.2', ssl.ssl_version) |
||||||
|
+ assert_equal(csuite[0], ssl.cipher[0]) |
||||||
|
+ ssl.puts('abc'); assert_equal("abc\n", ssl.gets) |
||||||
|
+ end |
||||||
|
+ end |
||||||
|
+ end |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ def test_ciphers_method_nil_argument |
||||||
|
+ ssl_ctx = OpenSSL::SSL::SSLContext.new |
||||||
|
+ assert_nothing_raised { ssl_ctx.ciphers = nil } |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ def test_ciphers_method_frozen_object |
||||||
|
+ ssl_ctx = OpenSSL::SSL::SSLContext.new |
||||||
|
+ |
||||||
|
+ ssl_ctx.freeze |
||||||
|
+ assert_raise(FrozenError) { ssl_ctx.ciphers = 'ECDHE-RSA-AES128-SHA' } |
||||||
|
+ end |
||||||
|
+ |
||||||
|
+ def test_ciphers_method_bogus_csuite |
||||||
|
+ ssl_ctx = OpenSSL::SSL::SSLContext.new |
||||||
|
+ |
||||||
|
+ assert_raise_with_message( |
||||||
|
+ OpenSSL::SSL::SSLError, |
||||||
|
+ /SSL_CTX_set_cipher_list: no cipher match/i |
||||||
|
+ ) { ssl_ctx.ciphers = 'BOGUS' } |
||||||
|
+ end |
||||||
|
+ |
||||||
|
def test_connect_works_when_setting_dh_callback_to_nil |
||||||
|
pend "TLS 1.2 is not supported" unless tls12_supported? |
||||||
|
|
||||||
|
ctx_proc = -> ctx { |
||||||
|
ctx.ssl_version = :TLSv1_2 |
||||||
|
diff --git a/test/openssl/test_x509cert.rb b/test/openssl/test_x509cert.rb |
||||||
|
index d696b98..4e2bd0c 100644 |
||||||
|
--- a/test/openssl/test_x509cert.rb |
||||||
|
+++ b/test/openssl/test_x509cert.rb |
||||||
|
@@ -180,6 +180,7 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase |
||||||
|
assert_equal(false, certificate_error_returns_false { cert.verify(@dsa512) }) |
||||||
|
cert.serial = 2 |
||||||
|
assert_equal(false, cert.verify(@rsa2048)) |
||||||
|
+ rescue OpenSSL::X509::CertificateError # RHEL 9 disables SHA1 |
||||||
|
end |
||||||
|
|
||||||
|
def test_sign_and_verify_rsa_md5 |
||||||
|
@@ -226,9 +227,8 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase |
||||||
|
assert_equal("dsa_with_SHA256", cert.signature_algorithm) |
||||||
|
# TODO: need more tests for dsa + sha2 |
||||||
|
|
||||||
|
- # SHA1 is allowed from OpenSSL 1.0.0 (0.9.8 requires DSS1) |
||||||
|
- cert = issue_cert(@ca, @dsa256, 1, [], nil, nil, digest: "sha1") |
||||||
|
- assert_equal("dsaWithSHA1", cert.signature_algorithm) |
||||||
|
+ cert = issue_cert(@ca, @dsa256, 1, [], nil, nil, digest: "sha512") |
||||||
|
+ assert_equal("dsa_with_SHA512", cert.signature_algorithm) |
||||||
|
end |
||||||
|
|
||||||
|
def test_check_private_key |
||||||
|
diff --git a/test/openssl/test_x509crl.rb b/test/openssl/test_x509crl.rb |
||||||
|
index bcdb0a6..146ee07 100644 |
||||||
|
--- a/test/openssl/test_x509crl.rb |
||||||
|
+++ b/test/openssl/test_x509crl.rb |
||||||
|
@@ -20,7 +20,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase |
||||||
|
|
||||||
|
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) |
||||||
|
crl = issue_crl([], 1, now, now+1600, [], |
||||||
|
- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal(1, crl.version) |
||||||
|
assert_equal(cert.issuer.to_der, crl.issuer.to_der) |
||||||
|
assert_equal(now, crl.last_update) |
||||||
|
@@ -57,7 +57,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase |
||||||
|
] |
||||||
|
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) |
||||||
|
crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [], |
||||||
|
- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
revoked = crl.revoked |
||||||
|
assert_equal(5, revoked.size) |
||||||
|
assert_equal(1, revoked[0].serial) |
||||||
|
@@ -98,7 +98,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase |
||||||
|
|
||||||
|
revoke_info = (1..1000).collect{|i| [i, now, 0] } |
||||||
|
crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [], |
||||||
|
- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
revoked = crl.revoked |
||||||
|
assert_equal(1000, revoked.size) |
||||||
|
assert_equal(1, revoked[0].serial) |
||||||
|
@@ -124,7 +124,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase |
||||||
|
|
||||||
|
cert = issue_cert(@ca, @rsa2048, 1, cert_exts, nil, nil) |
||||||
|
crl = issue_crl([], 1, Time.now, Time.now+1600, crl_exts, |
||||||
|
- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
exts = crl.extensions |
||||||
|
assert_equal(3, exts.size) |
||||||
|
assert_equal("1", exts[0].value) |
||||||
|
@@ -160,24 +160,24 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase |
||||||
|
assert_equal(false, exts[2].critical?) |
||||||
|
|
||||||
|
no_ext_crl = issue_crl([], 1, Time.now, Time.now+1600, [], |
||||||
|
- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal nil, no_ext_crl.authority_key_identifier |
||||||
|
end |
||||||
|
|
||||||
|
def test_crlnumber |
||||||
|
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) |
||||||
|
crl = issue_crl([], 1, Time.now, Time.now+1600, [], |
||||||
|
- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_match(1.to_s, crl.extensions[0].value) |
||||||
|
assert_match(/X509v3 CRL Number:\s+#{1}/m, crl.to_text) |
||||||
|
|
||||||
|
crl = issue_crl([], 2**32, Time.now, Time.now+1600, [], |
||||||
|
- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_match((2**32).to_s, crl.extensions[0].value) |
||||||
|
assert_match(/X509v3 CRL Number:\s+#{2**32}/m, crl.to_text) |
||||||
|
|
||||||
|
crl = issue_crl([], 2**100, Time.now, Time.now+1600, [], |
||||||
|
- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_match(/X509v3 CRL Number:\s+#{2**100}/m, crl.to_text) |
||||||
|
assert_match((2**100).to_s, crl.extensions[0].value) |
||||||
|
end |
||||||
|
@@ -185,7 +185,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase |
||||||
|
def test_sign_and_verify |
||||||
|
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) |
||||||
|
crl = issue_crl([], 1, Time.now, Time.now+1600, [], |
||||||
|
- cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal(false, crl.verify(@rsa1024)) |
||||||
|
assert_equal(true, crl.verify(@rsa2048)) |
||||||
|
assert_equal(false, crl_error_returns_false { crl.verify(@dsa256) }) |
||||||
|
@@ -195,7 +195,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase |
||||||
|
|
||||||
|
cert = issue_cert(@ca, @dsa512, 1, [], nil, nil) |
||||||
|
crl = issue_crl([], 1, Time.now, Time.now+1600, [], |
||||||
|
- cert, @dsa512, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ cert, @dsa512, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal(false, crl_error_returns_false { crl.verify(@rsa1024) }) |
||||||
|
assert_equal(false, crl_error_returns_false { crl.verify(@rsa2048) }) |
||||||
|
assert_equal(false, crl.verify(@dsa256)) |
||||||
|
diff --git a/test/openssl/test_x509req.rb b/test/openssl/test_x509req.rb |
||||||
|
index ee9c678..a84b162 100644 |
||||||
|
--- a/test/openssl/test_x509req.rb |
||||||
|
+++ b/test/openssl/test_x509req.rb |
||||||
|
@@ -23,31 +23,31 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase |
||||||
|
end |
||||||
|
|
||||||
|
def test_public_key |
||||||
|
- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der) |
||||||
|
req = OpenSSL::X509::Request.new(req.to_der) |
||||||
|
assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der) |
||||||
|
|
||||||
|
- req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal(@dsa512.public_key.to_der, req.public_key.to_der) |
||||||
|
req = OpenSSL::X509::Request.new(req.to_der) |
||||||
|
assert_equal(@dsa512.public_key.to_der, req.public_key.to_der) |
||||||
|
end |
||||||
|
|
||||||
|
def test_version |
||||||
|
- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal(0, req.version) |
||||||
|
req = OpenSSL::X509::Request.new(req.to_der) |
||||||
|
assert_equal(0, req.version) |
||||||
|
|
||||||
|
- req = issue_csr(1, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ req = issue_csr(1, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal(1, req.version) |
||||||
|
req = OpenSSL::X509::Request.new(req.to_der) |
||||||
|
assert_equal(1, req.version) |
||||||
|
end |
||||||
|
|
||||||
|
def test_subject |
||||||
|
- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal(@dn.to_der, req.subject.to_der) |
||||||
|
req = OpenSSL::X509::Request.new(req.to_der) |
||||||
|
assert_equal(@dn.to_der, req.subject.to_der) |
||||||
|
@@ -78,9 +78,9 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase |
||||||
|
OpenSSL::X509::Attribute.new("msExtReq", attrval), |
||||||
|
] |
||||||
|
|
||||||
|
- req0 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ req0 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) |
||||||
|
attrs.each{|attr| req0.add_attribute(attr) } |
||||||
|
- req1 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ req1 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) |
||||||
|
req1.attributes = attrs |
||||||
|
assert_equal(req0.to_der, req1.to_der) |
||||||
|
|
||||||
|
@@ -101,7 +101,7 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase |
||||||
|
end |
||||||
|
|
||||||
|
def test_sign_and_verify_rsa_sha1 |
||||||
|
- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal(true, req.verify(@rsa1024)) |
||||||
|
assert_equal(false, req.verify(@rsa2048)) |
||||||
|
assert_equal(false, request_error_returns_false { req.verify(@dsa256) }) |
||||||
|
@@ -122,7 +122,7 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase |
||||||
|
end |
||||||
|
|
||||||
|
def test_sign_and_verify_dsa |
||||||
|
- req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal(false, request_error_returns_false { req.verify(@rsa1024) }) |
||||||
|
assert_equal(false, request_error_returns_false { req.verify(@rsa2048) }) |
||||||
|
assert_equal(false, req.verify(@dsa256)) |
||||||
|
@@ -137,13 +137,13 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase |
||||||
|
end |
||||||
|
|
||||||
|
def test_dup |
||||||
|
- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) |
||||||
|
assert_equal(req.to_der, req.dup.to_der) |
||||||
|
end |
||||||
|
|
||||||
|
def test_eq |
||||||
|
- req1 = issue_csr(0, @dn, @rsa1024, "sha1") |
||||||
|
- req2 = issue_csr(0, @dn, @rsa1024, "sha1") |
||||||
|
+ req1 = issue_csr(0, @dn, @rsa1024, "sha512") |
||||||
|
+ req2 = issue_csr(0, @dn, @rsa1024, "sha512") |
||||||
|
req3 = issue_csr(0, @dn, @rsa1024, "sha256") |
||||||
|
|
||||||
|
assert_equal false, req1 == 12345 |
||||||
|
--- a/test/openssl/test_x509store.rb.orig 2022-07-14 14:07:32.468809273 +0200 |
||||||
|
+++ b/test/openssl/test_x509store.rb 2022-07-13 17:27:58.115363595 +0200 |
||||||
|
@@ -72,16 +72,16 @@ |
||||||
|
|
||||||
|
revoke_info = [] |
||||||
|
crl1 = issue_crl(revoke_info, 1, now, now+1800, [], |
||||||
|
- ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
revoke_info = [ [2, now, 1], ] |
||||||
|
crl1_2 = issue_crl(revoke_info, 2, now, now+1800, [], |
||||||
|
- ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
revoke_info = [ [20, now, 1], ] |
||||||
|
crl2 = issue_crl(revoke_info, 1, now, now+1800, [], |
||||||
|
- ca2_cert, @rsa1024, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ ca2_cert, @rsa1024, OpenSSL::Digest.new('SHA256')) |
||||||
|
revoke_info = [] |
||||||
|
crl2_2 = issue_crl(revoke_info, 2, now-100, now-1, [], |
||||||
|
- ca2_cert, @rsa1024, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ ca2_cert, @rsa1024, OpenSSL::Digest.new('SHA256')) |
||||||
|
|
||||||
|
assert_equal(true, ca1_cert.verify(ca1_cert.public_key)) # self signed |
||||||
|
assert_equal(true, ca2_cert.verify(ca1_cert.public_key)) # issued by ca1 |
||||||
|
@@ -220,10 +220,10 @@ |
||||||
|
|
||||||
|
revoke_info = [] |
||||||
|
crl1 = issue_crl(revoke_info, 1, now, now+1800, [], |
||||||
|
- ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
revoke_info = [ [2, now, 1], ] |
||||||
|
crl2 = issue_crl(revoke_info, 2, now+1800, now+3600, [], |
||||||
|
- ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA1')) |
||||||
|
+ ca1_cert, @rsa2048, OpenSSL::Digest.new('SHA256')) |
||||||
|
store.add_crl(crl1) |
||||||
|
assert_raise(OpenSSL::X509::StoreError){ |
||||||
|
store.add_crl(crl2) # add CRL issued by same CA twice. |
@ -0,0 +1,39 @@ |
|||||||
|
/* Example tapset file. |
||||||
|
* |
||||||
|
* You can execute the tapset using following command (please adjust the path |
||||||
|
* prior running the command, if needed): |
||||||
|
* |
||||||
|
* stap /usr/share/doc/ruby-2.0.0.0/ruby-exercise.stp -c "ruby -e \"puts 'test'\"" |
||||||
|
*/ |
||||||
|
|
||||||
|
probe ruby.cmethod.entry { |
||||||
|
printf("%d -> %s::%s %s:%d\n", tid(), classname, methodname, file, line); |
||||||
|
} |
||||||
|
|
||||||
|
probe ruby.cmethod.return { |
||||||
|
printf("%d <- %s::%s %s:%d\n", tid(), classname, methodname, file, line); |
||||||
|
} |
||||||
|
|
||||||
|
probe ruby.method.entry { |
||||||
|
printf("%d -> %s::%s %s:%d\n", tid(), classname, methodname, file, line); |
||||||
|
} |
||||||
|
|
||||||
|
probe ruby.method.return { |
||||||
|
printf("%d <- %s::%s %s:%d\n", tid(), classname, methodname, file, line); |
||||||
|
} |
||||||
|
|
||||||
|
probe ruby.gc.mark.begin { printf("%d gc.mark.begin\n", tid()); } |
||||||
|
|
||||||
|
probe ruby.gc.mark.end { printf("%d gc.mark.end\n", tid()); } |
||||||
|
|
||||||
|
probe ruby.gc.sweep.begin { printf("%d gc.sweep.begin\n", tid()); } |
||||||
|
|
||||||
|
probe ruby.gc.sweep.end { printf("%d gc.sweep.end\n", tid()); } |
||||||
|
|
||||||
|
probe ruby.object.create{ |
||||||
|
printf("%d obj.create %s %s:%d\n", tid(), classname, file, line); |
||||||
|
} |
||||||
|
|
||||||
|
probe ruby.raise { |
||||||
|
printf("%d raise %s %s:%d\n", tid(), classname, file, line); |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
From bb0f57aeb4de36a3b2b8b8cb01d25b32af0357d3 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> |
||||||
|
Date: Wed, 27 Oct 2021 16:28:24 +0200 |
||||||
|
Subject: [PATCH] Provide distinguished name which will be correctly parsed. |
||||||
|
|
||||||
|
It seems that since ruby openssl 2.1.0 [[1]], the distinguished name |
||||||
|
submitted to `OpenSSL::X509::Name.parse` is not correctly parsed if it |
||||||
|
does not contain the first slash: |
||||||
|
|
||||||
|
~~~ |
||||||
|
$ ruby -v |
||||||
|
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux] |
||||||
|
|
||||||
|
$ gem list | grep openssl |
||||||
|
openssl (default: 2.2.0) |
||||||
|
|
||||||
|
$ irb -r openssl |
||||||
|
irb(main):001:0> OpenSSL::X509::Name.parse("CN=nobody/DC=example").to_s(OpenSSL::X509::Name::ONELINE) |
||||||
|
=> "CN = nobody/DC=example" |
||||||
|
irb(main):002:0> OpenSSL::X509::Name.parse("/CN=nobody/DC=example").to_s(OpenSSL::X509::Name::ONELINE) |
||||||
|
=> "CN = nobody, DC = example" |
||||||
|
~~~ |
||||||
|
|
||||||
|
[1]: https://github.com/ruby/openssl/commit/19c67cd10c57f3ab7b13966c36431ebc3fdd653b |
||||||
|
--- |
||||||
|
lib/rubygems/security.rb | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb |
||||||
|
index c80639af6d..12de141f36 100644 |
||||||
|
--- a/lib/rubygems/security.rb |
||||||
|
+++ b/lib/rubygems/security.rb |
||||||
|
@@ -510,7 +510,7 @@ def self.email_to_name(email_address) |
||||||
|
|
||||||
|
dcs = dcs.split '.' |
||||||
|
|
||||||
|
- name = "CN=#{cn}/#{dcs.map {|dc| "DC=#{dc}" }.join '/'}" |
||||||
|
+ name = "/CN=#{cn}/#{dcs.map {|dc| "DC=#{dc}" }.join '/'}" |
||||||
|
|
||||||
|
OpenSSL::X509::Name.parse name |
||||||
|
end |
||||||
|
-- |
||||||
|
2.32.0 |
||||||
|
|
@ -0,0 +1,261 @@ |
|||||||
|
From e80e7a3d0b3d72f7af7286b935702b3fab117008 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net> |
||||||
|
Date: Wed, 8 Dec 2021 21:12:24 +0100 |
||||||
|
Subject: [PATCH 1/5] More explicit require |
||||||
|
|
||||||
|
This class does not use `rubygems/deprecate`. It uses |
||||||
|
`rubygems/version`, which in turn uses `rubygems/deprecate`. Make this |
||||||
|
explicit. |
||||||
|
--- |
||||||
|
lib/rubygems/requirement.rb | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb |
||||||
|
index d2e28fab5b4..9edd6aa7d3c 100644 |
||||||
|
--- a/lib/rubygems/requirement.rb |
||||||
|
+++ b/lib/rubygems/requirement.rb |
||||||
|
@@ -1,5 +1,5 @@ |
||||||
|
# frozen_string_literal: true |
||||||
|
-require_relative "deprecate" |
||||||
|
+require_relative "version" |
||||||
|
|
||||||
|
## |
||||||
|
# A Requirement is a set of one or more version restrictions. It supports a |
||||||
|
|
||||||
|
From 4e46dcc17ee5cabbde43b8a34063b8ab042536f9 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net> |
||||||
|
Date: Wed, 8 Dec 2021 21:17:30 +0100 |
||||||
|
Subject: [PATCH 2/5] Remove ineffective autoloads |
||||||
|
|
||||||
|
These files are loaded on startup unconditionally, so we can require |
||||||
|
them relatively when needed. |
||||||
|
--- |
||||||
|
lib/rubygems.rb | 4 +--- |
||||||
|
lib/rubygems/specification.rb | 2 ++ |
||||||
|
2 files changed, 3 insertions(+), 3 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/rubygems.rb b/lib/rubygems.rb |
||||||
|
index f803e47628e..b8747409304 100644 |
||||||
|
--- a/lib/rubygems.rb |
||||||
|
+++ b/lib/rubygems.rb |
||||||
|
@@ -1310,19 +1310,17 @@ def default_gem_load_paths |
||||||
|
autoload :Licenses, File.expand_path('rubygems/util/licenses', __dir__) |
||||||
|
autoload :NameTuple, File.expand_path('rubygems/name_tuple', __dir__) |
||||||
|
autoload :PathSupport, File.expand_path('rubygems/path_support', __dir__) |
||||||
|
- autoload :Platform, File.expand_path('rubygems/platform', __dir__) |
||||||
|
autoload :RequestSet, File.expand_path('rubygems/request_set', __dir__) |
||||||
|
- autoload :Requirement, File.expand_path('rubygems/requirement', __dir__) |
||||||
|
autoload :Resolver, File.expand_path('rubygems/resolver', __dir__) |
||||||
|
autoload :Source, File.expand_path('rubygems/source', __dir__) |
||||||
|
autoload :SourceList, File.expand_path('rubygems/source_list', __dir__) |
||||||
|
autoload :SpecFetcher, File.expand_path('rubygems/spec_fetcher', __dir__) |
||||||
|
- autoload :Specification, File.expand_path('rubygems/specification', __dir__) |
||||||
|
autoload :Util, File.expand_path('rubygems/util', __dir__) |
||||||
|
autoload :Version, File.expand_path('rubygems/version', __dir__) |
||||||
|
end |
||||||
|
|
||||||
|
require_relative 'rubygems/exceptions' |
||||||
|
+require_relative 'rubygems/specification' |
||||||
|
|
||||||
|
# REFACTOR: This should be pulled out into some kind of hacks file. |
||||||
|
begin |
||||||
|
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb |
||||||
|
index d3b96491a28..dc5e5ba0138 100644 |
||||||
|
--- a/lib/rubygems/specification.rb |
||||||
|
+++ b/lib/rubygems/specification.rb |
||||||
|
@@ -9,6 +9,8 @@ |
||||||
|
require_relative 'deprecate' |
||||||
|
require_relative 'basic_specification' |
||||||
|
require_relative 'stub_specification' |
||||||
|
+require_relative 'platform' |
||||||
|
+require_relative 'requirement' |
||||||
|
require_relative 'specification_policy' |
||||||
|
require_relative 'util/list' |
||||||
|
|
||||||
|
|
||||||
|
From 96b6b3e04e8e4fec17f63079a0caf999a2709d71 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net> |
||||||
|
Date: Wed, 8 Dec 2021 21:45:16 +0100 |
||||||
|
Subject: [PATCH 3/5] Load `operating_system.rb` customizations before setting |
||||||
|
up default gems |
||||||
|
|
||||||
|
It's very common for packagers to configure gem paths in this file, for |
||||||
|
example, `Gem.default_dir`. Also, setting up default gems requires these |
||||||
|
paths to be set, so that we know which default gems need to be setup. |
||||||
|
|
||||||
|
If we setup default gems before loading `operatin_system.rb` |
||||||
|
customizations, the wrong default gems will be setup. |
||||||
|
|
||||||
|
Unfortunately, default gems loaded by `operating_system.rb` can't be |
||||||
|
upgraded if we do this, but it seems much of a smaller issue. I wasn't |
||||||
|
even fully sure it was the right thing to do when I added that, and it |
||||||
|
was not the culprit of the end user issue that led to making that |
||||||
|
change. |
||||||
|
--- |
||||||
|
lib/rubygems.rb | 32 ++++++++++++++++---------------- |
||||||
|
test/rubygems/test_rubygems.rb | 23 +++++++++++++++++++++++ |
||||||
|
2 files changed, 39 insertions(+), 16 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/rubygems.rb b/lib/rubygems.rb |
||||||
|
index b8747409304..11474b6554c 100644 |
||||||
|
--- a/lib/rubygems.rb |
||||||
|
+++ b/lib/rubygems.rb |
||||||
|
@@ -1323,22 +1323,6 @@ def default_gem_load_paths |
||||||
|
require_relative 'rubygems/specification' |
||||||
|
|
||||||
|
# REFACTOR: This should be pulled out into some kind of hacks file. |
||||||
|
-begin |
||||||
|
- ## |
||||||
|
- # Defaults the Ruby implementation wants to provide for RubyGems |
||||||
|
- |
||||||
|
- require "rubygems/defaults/#{RUBY_ENGINE}" |
||||||
|
-rescue LoadError |
||||||
|
-end |
||||||
|
- |
||||||
|
-## |
||||||
|
-# Loads the default specs. |
||||||
|
-Gem::Specification.load_defaults |
||||||
|
- |
||||||
|
-require_relative 'rubygems/core_ext/kernel_gem' |
||||||
|
-require_relative 'rubygems/core_ext/kernel_require' |
||||||
|
-require_relative 'rubygems/core_ext/kernel_warn' |
||||||
|
- |
||||||
|
begin |
||||||
|
## |
||||||
|
# Defaults the operating system (or packager) wants to provide for RubyGems. |
||||||
|
@@ -1354,3 +1338,19 @@ def default_gem_load_paths |
||||||
|
"the problem and ask for help." |
||||||
|
raise e.class, msg |
||||||
|
end |
||||||
|
+ |
||||||
|
+begin |
||||||
|
+ ## |
||||||
|
+ # Defaults the Ruby implementation wants to provide for RubyGems |
||||||
|
+ |
||||||
|
+ require "rubygems/defaults/#{RUBY_ENGINE}" |
||||||
|
+rescue LoadError |
||||||
|
+end |
||||||
|
+ |
||||||
|
+## |
||||||
|
+# Loads the default specs. |
||||||
|
+Gem::Specification.load_defaults |
||||||
|
+ |
||||||
|
+require_relative 'rubygems/core_ext/kernel_gem' |
||||||
|
+require_relative 'rubygems/core_ext/kernel_require' |
||||||
|
+require_relative 'rubygems/core_ext/kernel_warn' |
||||||
|
diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb |
||||||
|
index 493b9fdf4a3..fa77a299322 100644 |
||||||
|
--- a/test/rubygems/test_rubygems.rb |
||||||
|
+++ b/test/rubygems/test_rubygems.rb |
||||||
|
@@ -22,6 +22,29 @@ def test_operating_system_other_exceptions |
||||||
|
"the problem and ask for help." |
||||||
|
end |
||||||
|
|
||||||
|
+ def test_operating_system_customizing_default_dir |
||||||
|
+ pend "does not apply to truffleruby" if RUBY_ENGINE == 'truffleruby' |
||||||
|
+ pend "loads a custom defaults/jruby file that gets in the middle" if RUBY_ENGINE == 'jruby' |
||||||
|
+ |
||||||
|
+ # On a non existing default dir, there should be no gems |
||||||
|
+ |
||||||
|
+ path = util_install_operating_system_rb <<-RUBY |
||||||
|
+ module Gem |
||||||
|
+ def self.default_dir |
||||||
|
+ File.expand_path("foo") |
||||||
|
+ end |
||||||
|
+ end |
||||||
|
+ RUBY |
||||||
|
+ |
||||||
|
+ output = Gem::Util.popen( |
||||||
|
+ *ruby_with_rubygems_and_fake_operating_system_in_load_path(path), |
||||||
|
+ '-e', |
||||||
|
+ "require \"rubygems\"; puts Gem::Specification.stubs.map(&:full_name)", |
||||||
|
+ {:err => [:child, :out]} |
||||||
|
+ ).strip |
||||||
|
+ assert_empty output |
||||||
|
+ end |
||||||
|
+ |
||||||
|
private |
||||||
|
|
||||||
|
def util_install_operating_system_rb(content) |
||||||
|
|
||||||
|
From 52cfdd14fd1213a97aac12f01177e27779de9035 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net> |
||||||
|
Date: Thu, 9 Dec 2021 06:08:31 +0100 |
||||||
|
Subject: [PATCH 4/5] Install default fiddle on latest ruby on specs that need |
||||||
|
it |
||||||
|
|
||||||
|
Otherwise first OS customizations load and activate that fiddle version, |
||||||
|
but then when we change to `Gem.default_dir`, that fiddle version is no |
||||||
|
longer there. |
||||||
|
--- |
||||||
|
spec/bundler/commands/clean_spec.rb | 2 +- |
||||||
|
spec/bundler/install/gems/standalone_spec.rb | 2 +- |
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb |
||||||
|
index ffaf22dbb32..65231b35fac 100644 |
||||||
|
--- a/spec/bundler/commands/clean_spec.rb |
||||||
|
+++ b/spec/bundler/commands/clean_spec.rb |
||||||
|
@@ -638,7 +638,7 @@ def should_not_have_gems(*gems) |
||||||
|
s.executables = "irb" |
||||||
|
end |
||||||
|
|
||||||
|
- realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1" |
||||||
|
+ realworld_system_gems "fiddle --version 1.0.8", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1" |
||||||
|
|
||||||
|
install_gemfile <<-G |
||||||
|
source "#{file_uri_for(gem_repo2)}" |
||||||
|
diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb |
||||||
|
index db16a1b0e13..faefda25f45 100644 |
||||||
|
--- a/spec/bundler/install/gems/standalone_spec.rb |
||||||
|
+++ b/spec/bundler/install/gems/standalone_spec.rb |
||||||
|
@@ -113,7 +113,7 @@ |
||||||
|
skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2 |
||||||
|
skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0" |
||||||
|
|
||||||
|
- realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0" |
||||||
|
+ realworld_system_gems "fiddle --version 1.0.8", "tsort --version 0.1.0" |
||||||
|
|
||||||
|
necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "yaml --version 0.1.1", "logger --version 1.4.3", "etc --version 1.2.0", "stringio --version 3.0.0"] |
||||||
|
necessary_system_gems += ["shellwords --version 0.1.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.3.a") |
||||||
|
|
||||||
|
From c6a9c81021092c9157f5616a2bbe1323411a5bf8 Mon Sep 17 00:00:00 2001 |
||||||
|
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net> |
||||||
|
Date: Thu, 9 Dec 2021 12:46:23 +0100 |
||||||
|
Subject: [PATCH 5/5] Resolve symlinks in LOAD_PATH when activating |
||||||
|
pre-required default gems |
||||||
|
|
||||||
|
Some double load issues were reported a while ago by OS packagers where |
||||||
|
if a gem has been required before rubygems, and then after, rubygems |
||||||
|
require would cause a double load. |
||||||
|
|
||||||
|
We avoid this issue by activating the corresponding gem if we detect |
||||||
|
that a file in the default LOAD_PATH that belongs to a default gem has |
||||||
|
already been required when rubygems registers default gems. |
||||||
|
|
||||||
|
However, the fix does not take into account that the default LOAD_PATH |
||||||
|
could potentially include symlinks. This change fixes the same double |
||||||
|
load issue described above but for situations where the default |
||||||
|
LOAD_PATH includes symlinks. |
||||||
|
--- |
||||||
|
lib/rubygems.rb | 7 ++++++- |
||||||
|
1 file changed, 6 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/lib/rubygems.rb b/lib/rubygems.rb |
||||||
|
index 11474b6554c..b7dda38d522 100644 |
||||||
|
--- a/lib/rubygems.rb |
||||||
|
+++ b/lib/rubygems.rb |
||||||
|
@@ -1293,7 +1293,12 @@ def already_loaded?(file) |
||||||
|
end |
||||||
|
|
||||||
|
def default_gem_load_paths |
||||||
|
- @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1] |
||||||
|
+ @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1].map do |lp| |
||||||
|
+ expanded = File.expand_path(lp) |
||||||
|
+ next expanded unless File.exist?(expanded) |
||||||
|
+ |
||||||
|
+ File.realpath(expanded) |
||||||
|
+ end |
||||||
|
end |
||||||
|
end |
||||||
|
|
@ -0,0 +1,105 @@ |
|||||||
|
From 558128594de16add5b453833fd5b043a24c1b7f5 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Wed, 22 Dec 2021 01:38:47 +0900 |
||||||
|
Subject: [PATCH 1/3] Use OpenSSL::PKey::EC.generate to generate ECC key pairs |
||||||
|
|
||||||
|
When Ruby/OpenSSL is built against OpenSSL 3.0, OpenSSL::PKey::PKey |
||||||
|
instances are immutable and OpenSSL::PKey::EC#generate_key cannot work |
||||||
|
because it modifies the receiver. |
||||||
|
|
||||||
|
OpenSSL::PKey::EC.generate is available on Ruby 2.4 (Ruby/OpenSSL 2.0) |
||||||
|
or later. |
||||||
|
--- |
||||||
|
lib/rubygems/security.rb | 10 +++++++--- |
||||||
|
1 file changed, 7 insertions(+), 3 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb |
||||||
|
index 22759972070..2aa07381d69 100644 |
||||||
|
--- a/lib/rubygems/security.rb |
||||||
|
+++ b/lib/rubygems/security.rb |
||||||
|
@@ -490,9 +490,13 @@ def self.create_key(algorithm) |
||||||
|
when 'rsa' |
||||||
|
OpenSSL::PKey::RSA.new(RSA_DSA_KEY_LENGTH) |
||||||
|
when 'ec' |
||||||
|
- domain_key = OpenSSL::PKey::EC.new(EC_NAME) |
||||||
|
- domain_key.generate_key |
||||||
|
- domain_key |
||||||
|
+ if RUBY_VERSION >= "2.4.0" |
||||||
|
+ OpenSSL::PKey::EC.generate(EC_NAME) |
||||||
|
+ else |
||||||
|
+ domain_key = OpenSSL::PKey::EC.new(EC_NAME) |
||||||
|
+ domain_key.generate_key |
||||||
|
+ domain_key |
||||||
|
+ end |
||||||
|
else |
||||||
|
raise Gem::Security::Exception, |
||||||
|
"#{algorithm} algorithm not found. RSA, DSA, and EC algorithms are supported." |
||||||
|
|
||||||
|
From 60067d4f09b7fb9c23bed38e91acfde0293f29a0 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Wed, 22 Dec 2021 01:49:05 +0900 |
||||||
|
Subject: [PATCH 2/3] Use OpenSSL::X509::Certificate#check_private_key |
||||||
|
|
||||||
|
The method is for the exact purpose: to check that an instance of |
||||||
|
OpenSSL::PKey::PKey matches the public key in a certificate. |
||||||
|
--- |
||||||
|
lib/rubygems/security.rb | 2 +- |
||||||
|
lib/rubygems/security/policy.rb | 4 +--- |
||||||
|
2 files changed, 2 insertions(+), 4 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb |
||||||
|
index 2aa07381d69..2906819bd34 100644 |
||||||
|
--- a/lib/rubygems/security.rb |
||||||
|
+++ b/lib/rubygems/security.rb |
||||||
|
@@ -530,7 +530,7 @@ def self.re_sign(expired_certificate, private_key, age = ONE_YEAR, |
||||||
|
raise Gem::Security::Exception, |
||||||
|
"incorrect signing key for re-signing " + |
||||||
|
"#{expired_certificate.subject}" unless |
||||||
|
- expired_certificate.public_key.to_pem == get_public_key(private_key).to_pem |
||||||
|
+ expired_certificate.check_private_key(private_key) |
||||||
|
|
||||||
|
unless expired_certificate.subject.to_s == |
||||||
|
expired_certificate.issuer.to_s |
||||||
|
diff --git a/lib/rubygems/security/policy.rb b/lib/rubygems/security/policy.rb |
||||||
|
index 3c3cb647ee3..06eae073f4a 100644 |
||||||
|
--- a/lib/rubygems/security/policy.rb |
||||||
|
+++ b/lib/rubygems/security/policy.rb |
||||||
|
@@ -115,11 +115,9 @@ def check_key(signer, key) |
||||||
|
raise Gem::Security::Exception, 'missing key or signature' |
||||||
|
end |
||||||
|
|
||||||
|
- public_key = Gem::Security.get_public_key(key) |
||||||
|
- |
||||||
|
raise Gem::Security::Exception, |
||||||
|
"certificate #{signer.subject} does not match the signing key" unless |
||||||
|
- signer.public_key.to_pem == public_key.to_pem |
||||||
|
+ signer.check_private_key(key) |
||||||
|
|
||||||
|
true |
||||||
|
end |
||||||
|
|
||||||
|
From 6819e3d0fadc10ce8d10919402eedb730cf0e43f Mon Sep 17 00:00:00 2001 |
||||||
|
From: Kazuki Yamaguchi <k@rhe.jp> |
||||||
|
Date: Wed, 22 Dec 2021 01:54:10 +0900 |
||||||
|
Subject: [PATCH 3/3] Fix Gem::Security.get_public_key on OpenSSL 3.0 |
||||||
|
|
||||||
|
Ruby/OpenSSL 2.2 added OpenSSL::PKey::PKey#public_to_der for serializing |
||||||
|
only the public key components contained in the instance. This works |
||||||
|
for all possible key types. |
||||||
|
--- |
||||||
|
lib/rubygems/security.rb | 2 ++ |
||||||
|
1 file changed, 2 insertions(+) |
||||||
|
|
||||||
|
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb |
||||||
|
index 2906819bd34..f21c1756422 100644 |
||||||
|
--- a/lib/rubygems/security.rb |
||||||
|
+++ b/lib/rubygems/security.rb |
||||||
|
@@ -424,6 +424,8 @@ def self.create_cert(subject, key, age = ONE_YEAR, extensions = EXTENSIONS, |
||||||
|
# Gets the right public key from a PKey instance |
||||||
|
|
||||||
|
def self.get_public_key(key) |
||||||
|
+ # Ruby 3.0 (Ruby/OpenSSL 2.2) or later |
||||||
|
+ return OpenSSL::PKey.read(key.public_to_der) if key.respond_to?(:public_to_der) |
||||||
|
return key.public_key unless key.is_a?(OpenSSL::PKey::EC) |
||||||
|
|
||||||
|
ec_key = OpenSSL::PKey::EC.new(key.group.curve_name) |
@ -0,0 +1,6 @@ |
|||||||
|
%__rubygems_requires %{_rpmconfigdir}/rubygems.req |
||||||
|
%__rubygems_provides %{_rpmconfigdir}/rubygems.prov |
||||||
|
%__rubygems_conflicts %{_rpmconfigdir}/rubygems.con |
||||||
|
# In non-gem packages, the %%{gem_name} macro is not available and the macro |
||||||
|
# stays unexpanded which leads to "invalid regex" error (rhbz#1154067). |
||||||
|
%__rubygems_path ^%{?gem_name:%{gem_spec}}%{!?gem_name:this_should_never_match_anything}$ |
@ -0,0 +1,52 @@ |
|||||||
|
#!/usr/bin/ruby |
||||||
|
|
||||||
|
require 'rubygems/package' |
||||||
|
|
||||||
|
module RubyGemsReq |
||||||
|
module Helpers |
||||||
|
# Keep only '!=' requirements. |
||||||
|
def self.conflicts(requirements) |
||||||
|
conflicts = requirements.select {|r| r.first == '!='} |
||||||
|
end |
||||||
|
|
||||||
|
# Converts Gem::Requirement into array of requirements strings compatible |
||||||
|
# with RPM .spec file. |
||||||
|
def self.requirement_versions_to_rpm(requirement) |
||||||
|
self.conflicts(requirement.requirements).map do |op, version| |
||||||
|
version == Gem::Version.new(0) ? "" : "= #{version}" |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
# Report conflicting gem dependencies including their version. |
||||||
|
def self.gem_depenencies(specification) |
||||||
|
specification.runtime_dependencies.each do |dependency| |
||||||
|
conflict_strings = Helpers::requirement_versions_to_rpm(dependency.requirement).map do |requirement| |
||||||
|
requirement_string = "rubygem(#{dependency.name}) #{requirement}" |
||||||
|
end |
||||||
|
if conflict_strings.length > 0 |
||||||
|
conflict_string = conflict_strings.join(' with ') |
||||||
|
conflict_string.prepend('(').concat(')') if conflict_strings.length > 1 |
||||||
|
puts conflict_string |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
# Reports all conflicts specified by all provided .gemspec files. |
||||||
|
def self.conflicts |
||||||
|
while filename = gets |
||||||
|
filename.strip! |
||||||
|
begin |
||||||
|
specification = Gem::Specification.load filename |
||||||
|
|
||||||
|
gem_depenencies(specification) |
||||||
|
rescue => e |
||||||
|
# Ignore all errors. |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
if __FILE__ == $0 |
||||||
|
RubyGemsReq::conflicts |
||||||
|
end |
@ -0,0 +1,36 @@ |
|||||||
|
#!/usr/bin/ruby |
||||||
|
|
||||||
|
require 'rubygems/package' |
||||||
|
|
||||||
|
module RubyGemsProv |
||||||
|
module Helpers |
||||||
|
# If there is some prelease version files, such as rc1 (i.e. non-numeric |
||||||
|
# field), prepend this field by tilde instead of dot. |
||||||
|
def self.normalize_prerelease(version) |
||||||
|
if version.prerelease? |
||||||
|
prerelease = version.version.sub /^#{version.release}\./, '' |
||||||
|
"#{version.release}~#{prerelease}" |
||||||
|
else |
||||||
|
version.release |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
# Reports all functionality gem provides. |
||||||
|
def self.provides |
||||||
|
while filename = gets |
||||||
|
filename.strip! |
||||||
|
begin |
||||||
|
specification = Gem::Specification.load filename |
||||||
|
|
||||||
|
puts "rubygem(#{specification.name}) = #{Helpers::normalize_prerelease(specification.version)}" |
||||||
|
rescue => e |
||||||
|
# Ignore all errors. |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
if __FILE__ == $0 |
||||||
|
RubyGemsProv::provides |
||||||
|
end |
@ -0,0 +1,88 @@ |
|||||||
|
#!/usr/bin/ruby |
||||||
|
|
||||||
|
require 'rubygems/package' |
||||||
|
|
||||||
|
module RubyGemsReq |
||||||
|
module Helpers |
||||||
|
# Expands '~>' and '!=' gem requirements. |
||||||
|
def self.expand_requirement(requirements) |
||||||
|
requirements.inject([]) do |output, r| |
||||||
|
output.concat case r.first |
||||||
|
when '~>' |
||||||
|
expand_pessimistic_requirement(r) |
||||||
|
when '!=' |
||||||
|
# If there is only the conflict requirement, we still need to depend |
||||||
|
# on the specified gem. |
||||||
|
if requirements.size == 1 |
||||||
|
Gem::Requirement.default.requirements |
||||||
|
else |
||||||
|
[] |
||||||
|
end |
||||||
|
else |
||||||
|
[r] |
||||||
|
end |
||||||
|
end.reject {|r| r.empty? } |
||||||
|
end |
||||||
|
|
||||||
|
# Expands the pessimistic version operator '~>' into equivalent '>=' and |
||||||
|
# '<' pair. |
||||||
|
def self.expand_pessimistic_requirement(requirement) |
||||||
|
next_version = Gem::Version.create(requirement.last).bump |
||||||
|
return ['>=', requirement.last], ['<', next_version] |
||||||
|
end |
||||||
|
|
||||||
|
# Converts Gem::Requirement into array of requirements strings compatible |
||||||
|
# with RPM .spec file. |
||||||
|
def self.requirement_versions_to_rpm(requirement) |
||||||
|
self.expand_requirement(requirement.requirements).map do |op, version| |
||||||
|
version == Gem::Version.new(0) ? "" : " #{op} #{version}" |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
# Compose dependency together with its requirements in RPM rich dependency |
||||||
|
# string. |
||||||
|
def self.compose_dependency_string(name, requirements) |
||||||
|
dependency_strings = requirements.map { |requirement| name + requirement } |
||||||
|
dependency_string = dependency_strings.join(' with ') |
||||||
|
dependency_string.prepend('(').concat(')') if dependency_strings.length > 1 |
||||||
|
dependency_string |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
# Report RubyGems dependency, versioned if required. |
||||||
|
def self.rubygems_dependency(specification) |
||||||
|
dependency_name = "ruby(rubygems)" |
||||||
|
requirements = Helpers::requirement_versions_to_rpm(specification.required_rubygems_version) |
||||||
|
|
||||||
|
puts Helpers::compose_dependency_string(dependency_name, requirements) |
||||||
|
end |
||||||
|
|
||||||
|
# Report all gem dependencies including their version. |
||||||
|
def self.gem_depenencies(specification) |
||||||
|
specification.runtime_dependencies.each do |dependency| |
||||||
|
dependency_name = "rubygem(#{dependency.name})" |
||||||
|
requirements = Helpers::requirement_versions_to_rpm(dependency.requirement) |
||||||
|
|
||||||
|
puts Helpers::compose_dependency_string(dependency_name, requirements) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
# Reports all requirements specified by all provided .gemspec files. |
||||||
|
def self.requires |
||||||
|
while filename = gets |
||||||
|
filename.strip! |
||||||
|
begin |
||||||
|
specification = Gem::Specification.load filename |
||||||
|
|
||||||
|
rubygems_dependency(specification) |
||||||
|
gem_depenencies(specification) |
||||||
|
rescue => e |
||||||
|
# Ignore all errors. |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
if __FILE__ == $0 |
||||||
|
RubyGemsReq::requires |
||||||
|
end |
@ -0,0 +1,7 @@ |
|||||||
|
if !!$LOADED_FEATURES.detect { |f| f =~ /abrt\.rb/ } |
||||||
|
exit true |
||||||
|
else |
||||||
|
puts 'ERROR: ABRT hook was not loaded.' |
||||||
|
|
||||||
|
exit false |
||||||
|
end |
@ -0,0 +1,65 @@ |
|||||||
|
require 'set' |
||||||
|
|
||||||
|
LIBRUBY_SO = 'libruby.so' |
||||||
|
PROBES_D = 'probes.d' |
||||||
|
|
||||||
|
# These probes are excluded by VM_COLLECT_USAGE_DETAILS ifdef. |
||||||
|
EXCLUDE_PROBES = Set.new %w(insn insn__operand) |
||||||
|
|
||||||
|
## Detect SystemTap section headers presence |
||||||
|
|
||||||
|
stap_headers = [ |
||||||
|
'\.stapsdt\.base', |
||||||
|
'\.note\.stapsdt' |
||||||
|
] |
||||||
|
|
||||||
|
header_regexp = %r{ (#{stap_headers.join('|')}) } |
||||||
|
|
||||||
|
section_headers = `readelf -S "#{LIBRUBY_SO}"` |
||||||
|
detected_stap_headers = section_headers.scan(header_regexp).flatten |
||||||
|
|
||||||
|
# Assume there are both headers until this is proven wrong ;) |
||||||
|
unless detected_stap_headers.size == 2 |
||||||
|
puts 'ERROR: SystemTap (DTrace) headers were not detected in resulting library.' |
||||||
|
exit false |
||||||
|
end |
||||||
|
|
||||||
|
## Find if every declared probe is propagated to resulting library |
||||||
|
|
||||||
|
# Colect probes specified in probes.d file. |
||||||
|
probes_declared = [] |
||||||
|
|
||||||
|
File.open(PROBES_D) do |file| |
||||||
|
file.each_line do |line| |
||||||
|
if probe = line[/probe (\S+)\(.*\);/, 1] |
||||||
|
probes_declared << probe |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
probes_declared = Set.new probes_declared |
||||||
|
|
||||||
|
unless EXCLUDE_PROBES.subset? probes_declared |
||||||
|
puts 'ERROR: Change in SystemTap (DTrace) probes definition file detected.' |
||||||
|
exit false |
||||||
|
end |
||||||
|
|
||||||
|
probes_declared -= EXCLUDE_PROBES |
||||||
|
|
||||||
|
# Detect probes in resulting library. |
||||||
|
get_probes_detected = %r{ |
||||||
|
^\s*Provider:\s+ruby,\s+Name:\s+(\S+),\s+.*$ |
||||||
|
} |
||||||
|
|
||||||
|
probes_detected = `eu-readelf -n "#{LIBRUBY_SO}"` |
||||||
|
|
||||||
|
probes_detected = Set.new probes_detected.scan(get_probes_detected).flatten |
||||||
|
|
||||||
|
# Both sets must be equal, otherwise something is wrong. |
||||||
|
unless probes_declared == probes_detected |
||||||
|
puts 'ERROR: SystemTap (DTrace) probes were not correctly propagated into resulting library.' |
||||||
|
puts " Undetected probes: #{(probes_declared - probes_detected).sort.join(', ')}\n", |
||||||
|
" Additional detected probes: #{(probes_detected - probes_declared).sort.join(', ')}" |
||||||
|
|
||||||
|
exit false |
||||||
|
end |
Loading…
Reference in new issue