diff options
118 files changed, 1384 insertions, 496 deletions
diff --git a/.astylerc b/.astylerc new file mode 100644 index 000000000..99cc98b00 --- /dev/null +++ b/.astylerc @@ -0,0 +1,15 @@ +--style=whitesmith +--indent=spaces=3 +--attach-namespaces +--break-one-line-headers +--add-braces +--add-one-line-braces +--convert-tabs +--max-code-length=120 +--break-after-logical +--indent-preproc-block +--pad-oper +--pad-comma +--unpad-paren +--align-pointer=type +--align-reference=type diff --git a/.gitignore b/.gitignore index d8d1d6cef..aaaa21c14 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ Makefile* +CMakeLists.txt* libbotan*.so.* *.a *.so @@ -123,16 +123,16 @@ argument-rgx=[a-z_][a-z0-9_]{0,30}$ argument-name-hint=[a-z_][a-z0-9_]{0,30}$ # Regular expression matching correct function names -function-rgx=[a-z_][a-z0-9_]{2,30}$ +function-rgx=[a-z_][a-z0-9_]{2,45}$ # Naming hint for function names -function-name-hint=[a-z_][a-z0-9_]{2,30}$ +function-name-hint=[a-z_][a-z0-9_]{2,45}$ # Regular expression matching correct variable names -variable-rgx=[a-z_][a-z0-9_]{0,30}$ +variable-rgx=[a-z_][a-z0-9_]{0,45}$ # Naming hint for variable names -variable-name-hint=[a-z_][a-z0-9_]{0,30}$ +variable-name-hint=[a-z_][a-z0-9_]{0,45}$ # Regular expression matching correct attribute names attr-rgx=[a-z_][a-z0-9_]{1,30}$ diff --git a/configure.py b/configure.py index 528f121ab..69b69526a 100755 --- a/configure.py +++ b/configure.py @@ -19,6 +19,7 @@ CPython 2.5 and earlier are not supported. On Jython target detection does not work (use --os and --cpu). """ +import collections import json import sys import os @@ -41,16 +42,21 @@ if 'dont_write_bytecode' in sys.__dict__: import botan_version # pylint: disable=wrong-import-position -class ConfigureError(Exception): + +# An error caused by and to be fixed by the user, e.g. invalid command line argument +class UserError(Exception): + pass + + +# An error caused by bugs in this script or when reading/parsing build data files +# Those are not expected to be fixed by the user of this script +class InternalError(Exception): pass + def flatten(l): return sum(l, []) -def chunks(l, n): - for i in range(0, len(l), n): - yield l[i:i+n] - class Version(object): """ @@ -385,6 +391,10 @@ def process_command_line(args): # pylint: disable=too-many-locals default=False, help='Generate bakefile which can be used to create Visual Studio or Xcode project files') + build_group.add_option('--with-cmake', action='store_true', + default=False, + help='Generate CMakeLists.txt which can be used to create many IDEs project files') + build_group.add_option('--unsafe-fuzzer-mode', action='store_true', default=False, help='disable essential checks for testing') @@ -482,10 +492,10 @@ def process_command_line(args): # pylint: disable=too-many-locals (options, args) = parser.parse_args(args) if args != []: - raise ConfigureError('Unhandled option(s): ' + ' '.join(args)) + raise UserError('Unhandled option(s): ' + ' '.join(args)) if options.with_endian != None and \ options.with_endian not in ['little', 'big']: - raise ConfigureError('Bad value to --with-endian "%s"' % ( + raise UserError('Bad value to --with-endian "%s"' % ( options.with_endian)) if options.debug_mode: @@ -516,7 +526,7 @@ class LexResult(object): pass -class LexerError(ConfigureError): +class LexerError(InternalError): def __init__(self, msg, lexfile, line): super(LexerError, self).__init__(msg) self.msg = msg @@ -529,12 +539,13 @@ class LexerError(ConfigureError): def parse_lex_dict(as_list): if len(as_list) % 3 != 0: - raise ConfigureError("Lex dictionary has invalid format") + raise InternalError( + "Lex dictionary has invalid format (input not divisible by 3): %s" % as_list) result = {} for key, sep, value in [as_list[3*i:3*i+3] for i in range(0, len(as_list)//3)]: if sep != '->': - raise ConfigureError("Lex dictionary has invalid format") + raise InternalError("Lex dictionary has invalid format") result[key] = value return result @@ -675,12 +686,12 @@ class ModuleInfo(InfoObject): # Coerce to more useful types def convert_lib_list(l): if len(l) % 3 != 0: - raise ConfigureError("Bad <libs> in module %s" % (self.basename)) + raise InternalError("Bad <libs> in module %s" % (self.basename)) result = {} for sep in l[1::3]: if sep != '->': - raise ConfigureError("Bad <libs> in module %s" % (self.basename)) + raise InternalError("Bad <libs> in module %s" % (self.basename)) for (targetlist, vallist) in zip(l[::3], l[2::3]): vals = vallist.split(',') @@ -738,20 +749,20 @@ class ModuleInfo(InfoObject): def _validate_defines_content(defines): for key, value in defines.items(): if not re.match('^[0-9A-Za-z_]{3,30}$', key): - raise ConfigureError('Module defines key has invalid format: "%s"' % key) + raise InternalError('Module defines key has invalid format: "%s"' % key) if not re.match('^[0-9]{8}$', value): - raise ConfigureError('Module defines value has invalid format: "%s"' % value) + raise InternalError('Module defines value has invalid format: "%s"' % value) def cross_check(self, arch_info, os_info, cc_info): for supp_os in self.os: if supp_os not in os_info: - raise ConfigureError('Module %s mentions unknown OS %s' % (self.infofile, supp_os)) + raise InternalError('Module %s mentions unknown OS %s' % (self.infofile, supp_os)) for supp_cc in self.cc: if supp_cc not in cc_info: - raise ConfigureError('Module %s mentions unknown compiler %s' % (self.infofile, supp_cc)) + raise InternalError('Module %s mentions unknown compiler %s' % (self.infofile, supp_cc)) for supp_arch in self.arch: if supp_arch not in arch_info: - raise ConfigureError('Module %s mentions unknown arch %s' % (self.infofile, supp_arch)) + raise InternalError('Module %s mentions unknown arch %s' % (self.infofile, supp_arch)) def sources(self): return self.source @@ -939,7 +950,11 @@ class ArchInfo(InfoObject): return macros -class CompilerInfo(InfoObject): + +MachOptFlags = collections.namedtuple('MachOptFlags', ['flags', 'submodel_prefix']) + + +class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes def __init__(self, infofile): super(CompilerInfo, self).__init__(infofile) lex = lex_me_harder( @@ -999,16 +1014,9 @@ class CompilerInfo(InfoObject): self.warning_flags = lex.warning_flags self.mach_opt_flags = {} - while lex.mach_opt: - proc = lex.mach_opt.pop(0) - if lex.mach_opt.pop(0) != '->': - raise ConfigureError('Parsing err in %s mach_opt' % self.basename) - - flags = lex.mach_opt.pop(0) - regex = '' - if lex.mach_opt and (len(lex.mach_opt) == 1 or lex.mach_opt[1] != '->'): - regex = lex.mach_opt.pop(0) - self.mach_opt_flags[proc] = (flags, regex) + for key, value in parse_lex_dict(lex.mach_opt).items(): + parts = value.split("|") + self.mach_opt_flags[key] = MachOptFlags(parts[0], parts[1] if len(parts) == 2 else '') def isa_flags_for(self, isa, arch): if isa in self.isa_flags: @@ -1057,22 +1065,22 @@ class CompilerInfo(InfoObject): if options.with_coverage_info: if self.coverage_flags == '': - raise ConfigureError('No coverage handling for %s' % (self.basename)) + raise InternalError('No coverage handling for %s' % (self.basename)) abi_link.append(self.coverage_flags) if options.with_sanitizers: if self.sanitizer_flags == '': - raise ConfigureError('No sanitizer handling for %s' % (self.basename)) + raise InternalError('No sanitizer handling for %s' % (self.basename)) abi_link.append(self.sanitizer_flags) if options.with_openmp: if 'openmp' not in self.mach_abi_linking: - raise ConfigureError('No support for OpenMP for %s' % (self.basename)) + raise InternalError('No support for OpenMP for %s' % (self.basename)) abi_link.append(self.mach_abi_linking['openmp']) if options.with_cilkplus: if 'cilkplus' not in self.mach_abi_linking: - raise ConfigureError('No support for Cilk Plus for %s' % (self.basename)) + raise InternalError('No support for Cilk Plus for %s' % (self.basename)) abi_link.append(self.mach_abi_linking['cilkplus']) abi_flags = ' '.join(sorted(abi_link)) @@ -1107,8 +1115,9 @@ class CompilerInfo(InfoObject): else: yield self.optimization_flags - def submodel_fixup(flags, tup): - return tup[0].replace('SUBMODEL', flags.replace(tup[1], '')) + def submodel_fixup(full_cpu, mach_opt_flags_tupel): + submodel_replacement = full_cpu.replace(mach_opt_flags_tupel.submodel_prefix, '') + return mach_opt_flags_tupel.flags.replace('SUBMODEL', submodel_replacement) if options.cpu != options.arch: if options.cpu in self.mach_opt_flags: @@ -1139,7 +1148,7 @@ class CompilerInfo(InfoObject): if s in self.so_link_commands: return self.so_link_commands[s] - raise ConfigureError( + raise InternalError( "No shared library link command found for target '%s' in compiler settings '%s'" % (osname, self.infofile)) @@ -1162,7 +1171,7 @@ class CompilerInfo(InfoObject): return ['BUILD_COMPILER_IS_' + self.macro_name] -class OsInfo(InfoObject): +class OsInfo(InfoObject): # pylint: disable=too-many-instance-attributes def __init__(self, infofile): super(OsInfo, self).__init__(infofile) lex = lex_me_harder( @@ -1199,7 +1208,7 @@ class OsInfo(InfoObject): self.soname_pattern_abi = lex.soname_pattern_abi else: # base set, only one of patch/abi set - raise ConfigureError("Invalid soname_patterns in %s" % (self.infofile)) + raise InternalError("Invalid soname_patterns in %s" % (self.infofile)) else: if lex.soname_suffix: self.soname_pattern_base = "libbotan-{version_major}.%s" % (lex.soname_suffix) @@ -1319,7 +1328,7 @@ def guess_processor(archinfo): else: logging.debug("Failed to deduce CPU from '%s'" % info_part) - raise ConfigureError('Could not determine target CPU; set with --cpu') + raise UserError('Could not determine target CPU; set with --cpu') def slurp_file(filename): """ @@ -1343,9 +1352,9 @@ def process_template(template_file, variables): template = PercentSignTemplate(slurp_file(template_file)) return template.substitute(variables) except KeyError as e: - raise ConfigureError('Unbound var %s in template %s' % (e, template_file)) + raise InternalError('Unbound var %s in template %s' % (e, template_file)) except Exception as e: - raise ConfigureError('Exception %s in template %s' % (e, template_file)) + raise InternalError('Exception %s in template %s' % (e, template_file)) def makefile_list(items): items = list(items) # force evaluation so we can slice it @@ -1429,46 +1438,176 @@ def gen_bakefile(build_config, options, external_libs): f.close() -def gen_makefile_lists(var, build_config, options, modules, cc, arch, osinfo): - def get_isa_specific_flags(cc, isas): +def gen_cmake(build_paths, using_mods, cc, options): + def create_target_rules(sources): + target = {'sources': {}, 'frameworks': set(), 'libs': set()} + for source in sources: + target['sources'][source] = {'isa_flags': set()} + return target + + def add_target_details(target, using_mod): + libs_or_frameworks_needed = False + for source_path in target['sources']: + for mod_source in using_mod.source: + if source_path == mod_source: + libs_or_frameworks_needed = True + for isa in using_mod.need_isa: + target['sources'][source_path]['isa_flags'].add(cc.isa_flags[isa]) + if libs_or_frameworks_needed: + if options.os in using_mod.libs: + for lib in using_mod.libs[options.os]: + target['libs'].add(lib) + if options.os in using_mod.frameworks: + for framework in using_mod.frameworks[options.os]: + target['frameworks'].add('"-framework %s"' % framework) + + def generate_target_sources_list(fd, target_name, target): + fd.write('set(%s\n' % target_name) + for source in target['sources']: + fd.write(' ${CMAKE_CURRENT_LIST_DIR}%s%s\n' % (os.sep, os.path.normpath(source))) + fd.write(')\n\n') + + def generate_target_source_files_isa_properties(fd, target): + for source in target['sources']: + joined_isa_flags = ' '.join(target['sources'][source]['isa_flags']) + if joined_isa_flags: + fd.write('set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}%s%s PROPERTIES COMPILE_FLAGS %s)\n' + % (os.sep, os.path.normpath(source), joined_isa_flags)) + + library_target_configuration = create_target_rules(build_paths.lib_sources) + tests_target_configuration = create_target_rules(build_paths.test_sources) + cli_target_configuration = create_target_rules(build_paths.cli_sources) + + for module in using_mods: + add_target_details(library_target_configuration, module) + add_target_details(tests_target_configuration, module) + add_target_details(cli_target_configuration, module) + + f = open('CMakeLists.txt', 'w') + f.write('cmake_minimum_required(VERSION 2.8.0)\n') + f.write('project(botan LANGUAGES CXX)\n\n') + f.write('cmake_policy(SET CMP0042 NEW)\n\n') + + generate_target_sources_list(f, 'BOTAN_SOURCES', library_target_configuration) + generate_target_sources_list(f, 'BOTAN_CLI', cli_target_configuration) + generate_target_sources_list(f, 'BOTAN_TESTS', tests_target_configuration) + + generate_target_source_files_isa_properties(f, library_target_configuration) + generate_target_source_files_isa_properties(f, cli_target_configuration) + generate_target_source_files_isa_properties(f, tests_target_configuration) + + f.write('\n') + + f.write('option(ENABLED_OPTIONAL_WARINIGS "If enabled more strict warinig policy will be used" OFF)\n') + f.write('option(ENABLED_LTO "If enabled link time optimization will be used" OFF)\n\n') + + f.write('set(COMPILER_FEATURES %s %s)\n' % (cc.cc_compile_flags(options), cc.mach_abi_link_flags(options))) + f.write('set(COMPILER_WARNINGS %s)\n' % cc.cc_warning_flags(options)) + f.write('set(COMPILER_INCLUDE_DIRS build/include build/include/external)\n') + f.write('if(ENABLED_LTO)\n') + f.write(' set(COMPILER_FEATURES ${COMPILER_FEATURES} -lto)\n') + f.write('endif()\n') + f.write('if(ENABLED_OPTIONAL_WARINIGS)\n') + f.write(' set(COMPILER_OPTIONAL_WARNINGS -Wsign-promo -Wctor-dtor-privacy -Wdeprecated -Winit-self' + + ' -Wnon-virtual-dtor -Wunused-macros -Wold-style-cast -Wuninitialized)\n') + f.write('endif()\n\n') + + library_target_libs_and_frameworks = '%s %s %s' % ( + ' '.join(library_target_configuration['frameworks']), + ' '.join(library_target_configuration['libs']), + cc.mach_abi_link_flags(options) + ) + tests_target_libs_and_frameworks = '%s %s' % ( + ' '.join(tests_target_configuration['frameworks']), + ' '.join(tests_target_configuration['libs']) + ) + cli_target_libs_and_frameworks = '%s %s' % ( + ' '.join(cli_target_configuration['frameworks']), + ' '.join(cli_target_configuration['libs']) + ) + + f.write('add_library(${PROJECT_NAME} STATIC ${BOTAN_SOURCES})\n') + f.write('target_link_libraries(${PROJECT_NAME} PUBLIC %s)\n' + % library_target_libs_and_frameworks) + f.write('target_compile_options(${PROJECT_NAME} PUBLIC ' + + '${COMPILER_WARNINGS} ${COMPILER_FEATURES} ${COMPILER_OPTIONAL_WARNINGS})\n') + f.write('target_include_directories(${PROJECT_NAME} PUBLIC ${COMPILER_INCLUDE_DIRS})\n\n') + + f.write('add_library(${PROJECT_NAME}_shared SHARED ${BOTAN_SOURCES})\n') + f.write('target_link_libraries(${PROJECT_NAME}_shared PUBLIC %s)\n' + % library_target_libs_and_frameworks) + f.write('target_compile_options(${PROJECT_NAME}_shared PUBLIC ' + + '${COMPILER_WARNINGS} ${COMPILER_FEATURES} ${COMPILER_OPTIONAL_WARNINGS})\n') + f.write('target_include_directories(${PROJECT_NAME}_shared PUBLIC ${COMPILER_INCLUDE_DIRS})\n') + f.write('set_target_properties(${PROJECT_NAME}_shared PROPERTIES OUTPUT_NAME ${PROJECT_NAME})\n\n') + + f.write('add_executable(${PROJECT_NAME}_cli ${BOTAN_CLI})\n') + f.write('target_link_libraries(${PROJECT_NAME}_cli PRIVATE ${PROJECT_NAME}_shared %s)\n' + % cli_target_libs_and_frameworks) + f.write('set_target_properties(${PROJECT_NAME}_cli PROPERTIES OUTPUT_NAME ${PROJECT_NAME})\n\n') + + f.write('add_executable(${PROJECT_NAME}_tests ${BOTAN_TESTS})\n') + f.write('target_link_libraries(${PROJECT_NAME}_tests PRIVATE ${PROJECT_NAME}_shared %s)\n' + % tests_target_libs_and_frameworks) + f.write('set_target_properties(${PROJECT_NAME}_tests PROPERTIES OUTPUT_NAME botan-test)\n\n') + + f.write('set(CONFIGURATION_FILES configure.py .gitignore .astylerc authors.txt news.rst readme.rst)\n') + f.write('file(GLOB_RECURSE DOCUMENTATION_FILES doc%s* )\n' % os.sep) + f.write('file(GLOB_RECURSE HEADER_FILES src%s*.h )\n' % os.sep) + f.write('file(GLOB_RECURSE INFO_FILES src%slib%s*info.txt )\n' % (os.sep, os.sep)) + f.write('add_custom_target(CONFIGURATION_DUMMY SOURCES ' + + '${CONFIGURATION_FILES} ${DOCUMENTATION_FILES} ${INFO_FILES} ${HEADER_FILES})\n') + f.close() + + +class MakefileListsGenerator(object): + def __init__(self, build_paths, options, modules, cc, arch, osinfo): + self._build_paths = build_paths + self._options = options + self._modules = modules + self._cc = cc + self._arch = arch + self._osinfo = osinfo + + def _simd_implementation(self): + for simd32_impl in ['sse2', 'altivec', 'neon']: + if simd32_impl in self._arch.isa_extensions \ + and self._cc.isa_flags_for(simd32_impl, self._arch.basename) is not None: + return simd32_impl + return None + + def _get_isa_specific_flags(self, isas): flags = [] for isa in isas: - flag = cc.isa_flags_for(isa, arch.basename) + flag = self._cc.isa_flags_for(isa, self._arch.basename) if flag is None: - raise ConfigureError('Compiler %s does not support %s' % (cc.basename, isa)) + raise UserError('Compiler %s does not support %s' % (self._cc.basename, isa)) flags.append(flag) return '' if len(flags) == 0 else (' ' + ' '.join(sorted(list(flags)))) - def isa_specific_flags(cc, src): - - def simd_dependencies(): - - for simd32_impl in ['sse2', 'altivec', 'neon']: - if simd32_impl in arch.isa_extensions and cc.isa_flags_for(simd32_impl, arch.basename) is not None: - return [simd32_impl] - - # default scalar - return [] + def _isa_specific_flags(self, src): + simd_impl = self._simd_implementation() if os.path.basename(src) == 'test_simd.cpp': - isas = list(simd_dependencies()) - return get_isa_specific_flags(cc, isas) + isas = [simd_impl] if simd_impl else [] + return self._get_isa_specific_flags(isas) - for mod in modules: + for mod in self._modules: if src in mod.sources(): isas = mod.need_isa if 'simd' in mod.dependencies(): - isas += list(simd_dependencies()) + if simd_impl: + isas.append(simd_impl) - return get_isa_specific_flags(cc, isas) + return self._get_isa_specific_flags(isas) if src.startswith('botan_all_'): - isa = src.replace('botan_all_', '').replace('.cpp', '').split('_') - return get_isa_specific_flags(cc, isa) + isas = src.replace('botan_all_', '').replace('.cpp', '').split('_') + return self._get_isa_specific_flags(isas) return '' - def objectfile_list(sources, obj_dir): + def _objectfile_list(self, sources, obj_dir): for src in sources: (directory, file) = os.path.split(os.path.normpath(src)) @@ -1482,7 +1621,7 @@ def gen_makefile_lists(var, build_config, options, modules, cc, arch, osinfo): elif file.find('botan_all') != -1: parts = [] else: - raise ConfigureError("Unexpected file '%s/%s'" % (directory, file)) + raise InternalError("Unexpected file '%s/%s'" % (directory, file)) if parts != []: @@ -1507,38 +1646,40 @@ def gen_makefile_lists(var, build_config, options, modules, cc, arch, osinfo): name = file for src_suffix in ['.cpp', '.S']: - name = name.replace(src_suffix, '.' + osinfo.obj_suffix) + name = name.replace(src_suffix, '.' + self._osinfo.obj_suffix) yield os.path.join(obj_dir, name) - def build_commands(sources, obj_dir, flags): + def _build_commands(self, sources, obj_dir, flags): """ Form snippets of makefile for building each source file """ - includes = cc.add_include_dir_option + build_config.include_dir - if build_config.external_headers: - includes += ' ' + cc.add_include_dir_option + build_config.external_include_dir - if options.with_external_includedir: - includes += ' ' + cc.add_include_dir_option + options.with_external_includedir + includes = self._cc.add_include_dir_option + self._build_paths.include_dir + if self._build_paths.external_headers: + includes += ' ' + self._cc.add_include_dir_option + self._build_paths.external_include_dir + if self._options.with_external_includedir: + includes += ' ' + self._cc.add_include_dir_option + self._options.with_external_includedir - for (obj_file, src) in zip(objectfile_list(sources, obj_dir), sources): + for (obj_file, src) in zip(self._objectfile_list(sources, obj_dir), sources): yield '%s: %s\n\t$(CXX)%s $(%s_FLAGS) %s %s %s %s$@\n' % ( - obj_file, src, - isa_specific_flags(cc, src), + obj_file, + src, + self._isa_specific_flags(src), flags, includes, - cc.compile_flags, + self._cc.compile_flags, src, - cc.output_to_option) + self._cc.output_to_option) - for t in ['lib', 'cli', 'test']: - obj_key = '%s_objs' % (t) - src_list, src_dir = build_config.src_info(t) - src_list.sort() - var[obj_key] = makefile_list(objectfile_list(src_list, src_dir)) - build_key = '%s_build_cmds' % (t) - var[build_key] = '\n'.join(build_commands(src_list, src_dir, t.upper())) + def generate(self, var): + for t in ['lib', 'cli', 'test']: + obj_key = '%s_objs' % (t) + src_list, src_dir = self._build_paths.src_info(t) + src_list.sort() + var[obj_key] = makefile_list(self._objectfile_list(src_list, src_dir)) + build_key = '%s_build_cmds' % (t) + var[build_key] = '\n'.join(self._build_commands(src_list, src_dir, t.upper())) def create_template_vars(build_config, options, modules, cc, arch, osinfo): """ @@ -1716,22 +1857,6 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): 'static_suffix': osinfo.static_suffix, - 'soname_base': osinfo.soname_pattern_base.format( - version_major=Version.major, - version_minor=Version.minor, - version_patch=Version.patch, - abi_rev=Version.so_rev), - 'soname_abi': osinfo.soname_pattern_abi.format( - version_major=Version.major, - version_minor=Version.minor, - version_patch=Version.patch, - abi_rev=Version.so_rev), - 'soname_patch': osinfo.soname_pattern_patch.format( - version_major=Version.major, - version_minor=Version.minor, - version_patch=Version.patch, - abi_rev=Version.so_rev), - 'mod_list': '\n'.join(sorted([m.basename for m in modules])), 'python_version': options.python_version, @@ -1740,6 +1865,29 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): 'misc_config': make_cpp_macros(misc_config()) } + if options.build_shared_lib: + + if osinfo.soname_pattern_base != None: + variables['soname_base'] = osinfo.soname_pattern_base.format( + version_major=Version.major, + version_minor=Version.minor, + version_patch=Version.patch, + abi_rev=Version.so_rev) + + if osinfo.soname_pattern_abi != None: + variables['soname_abi'] = osinfo.soname_pattern_abi.format( + version_major=Version.major, + version_minor=Version.minor, + version_patch=Version.patch, + abi_rev=Version.so_rev) + + if osinfo.soname_pattern_patch != None: + variables['soname_patch'] = osinfo.soname_pattern_patch.format( + version_major=Version.major, + version_minor=Version.minor, + version_patch=Version.patch, + abi_rev=Version.so_rev) + if options.os == 'darwin' and options.build_shared_lib: # In order that these executables work from the build directory, # we need to change the install names @@ -1751,7 +1899,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): variables['cli_post_link_cmd'] = '' variables['test_post_link_cmd'] = '' - gen_makefile_lists(variables, build_config, options, modules, cc, arch, osinfo) + MakefileListsGenerator(build_config, options, modules, cc, arch, osinfo).generate(variables) if options.os == 'windows': if options.with_debug_info: @@ -1978,7 +2126,7 @@ def portable_symlink(file_path, target_dir, method): elif method == 'copy': shutil.copy(file_path, target_dir) else: - raise ConfigureError('Unknown link method %s' % (method)) + raise UserError('Unknown link method %s' % (method)) def generate_amalgamation(build_config, modules, options): """ @@ -1996,7 +2144,7 @@ def generate_amalgamation(build_config, modules, options): contents = contents[1:] if len(contents) == 0: - raise ConfigureError("No header guard found in " + header_name) + raise InternalError("No header guard found in " + header_name) while contents[0] == '\n': contents = contents[1:] @@ -2229,7 +2377,7 @@ def main(argv=None): platform.system(), platform.machine(), platform.processor())) if options.os == "java": - raise ConfigureError("Jython detected: need --os and --cpu to set target") + raise UserError("Jython detected: need --os and --cpu to set target") options.base_dir = os.path.dirname(argv[0]) options.src_dir = os.path.join(options.base_dir, 'src') @@ -2330,7 +2478,7 @@ def main(argv=None): options.compiler)) if options.compiler not in info_cc: - raise ConfigureError('Unknown compiler "%s"; available options: %s' % ( + raise UserError('Unknown compiler "%s"; available options: %s' % ( options.compiler, ' '.join(sorted(info_cc.keys())))) if options.os not in info_os: @@ -2344,7 +2492,7 @@ def main(argv=None): options.os = find_canonical_os_name(options.os) if options.os not in info_os: - raise ConfigureError('Unknown OS "%s"; available options: %s' % ( + raise UserError('Unknown OS "%s"; available options: %s' % ( options.os, ' '.join(sorted(info_os.keys())))) if options.cpu is None: @@ -2385,10 +2533,10 @@ def main(argv=None): options.with_sphinx = True if options.gen_amalgamation: - raise ConfigureError("--gen-amalgamation was removed. Migrate to --amalgamation.") + raise UserError("--gen-amalgamation was removed. Migrate to --amalgamation.") if options.via_amalgamation: - raise ConfigureError("--via-amalgamation was removed. Use --amalgamation instead.") + raise UserError("--via-amalgamation was removed. Use --amalgamation instead.") if options.build_shared_lib and not osinfo.building_shared_supported: logging.warning('Shared libs not supported on %s, disabling shared lib support' % (osinfo.basename)) @@ -2485,7 +2633,7 @@ def main(argv=None): portable_symlink(header_file, directory, link_method) except OSError as e: if e.errno != errno.EEXIST: - raise ConfigureError('Error linking %s into %s: %s' % (header_file, directory, e)) + raise UserError('Error linking %s into %s: %s' % (header_file, directory, e)) link_headers(build_config.public_headers, 'public', build_config.botan_include_dir) @@ -2502,11 +2650,14 @@ def main(argv=None): if options.amalgamation: amalgamation_cpp_files = generate_amalgamation(build_config, using_mods, options) build_config.lib_sources = amalgamation_cpp_files - gen_makefile_lists(template_vars, build_config, options, using_mods, cc, arch, osinfo) + MakefileListsGenerator(build_config, options, using_mods, cc, arch, osinfo).generate(template_vars) if options.with_bakefile: gen_bakefile(build_config, options, template_vars['link_to']) + if options.with_cmake: + gen_cmake(build_config, using_mods, cc, options) + write_template(template_vars['makefile_path'], makefile_template) def release_date(datestamp): @@ -2526,9 +2677,20 @@ def main(argv=None): if __name__ == '__main__': try: main() - except ConfigureError as e: + except UserError as e: logging.debug(traceback.format_exc()) logging.error(e) + except InternalError as e: + # error() will stop script, so wrap all information into one call + logging.error("""%s +An internal error occurred. + +Don't panic, this is probably not your fault! + +Please report the entire output at https://github.com/randombit/botan or email +to the mailing list https://lists.randombit.net/mailman/listinfo/botan-devel + +You'll meet friendly people happy to help!""" % traceback.format_exc()) except Exception as e: # pylint: disable=broad-except logging.debug(traceback.format_exc()) logging.error(e) diff --git a/doc/manual/ffi.rst b/doc/manual/ffi.rst index f5f004624..8acbf225a 100644 --- a/doc/manual/ffi.rst +++ b/doc/manual/ffi.rst @@ -89,6 +89,50 @@ Random Number Generators Destroy the object created by :cpp:func:`botan_rng_init`. +Block Ciphers +---------------------------------------- + +This is a 'raw' interface to ECB mode block ciphers. Most applications +want the higher level cipher API which provides authenticated +encryption. This API exists as an escape hatch for applications which +need to implement custom primitives using a PRP. + +.. cpp:type:: opaque* botan_block_cipher_t + + An opauqe data type for a block cipher. Don't mess with it. + +.. cpp:function:: int botan_block_cipher_init(botan_block_cipher_t* bc, const char* cipher_name) + + Create a new cipher mode object, `cipher_name` should be for example "AES-128" or "Threefish-512" + +.. cpp:function:: int botan_block_cipher_block_size(botan_block_cipher_t bc) + + Return the block size of this cipher. + +.. cpp:function:: int botan_block_cipher_clear(botan_block_cipher_t bc) + + Clear the internal state (such as keys) of this cipher object, but do not deallocate it. + +.. cpp:function:: int botan_block_cipher_set_key(botan_block_cipher_t bc, const uint8_t key[], size_t key_len) + + Set the cipher key, which is required before encrypting or decrypting. + +.. cpp:function:: int botan_block_cipher_encrypt_blocks(botan_block_cipher_t bc, const uint8_t in[], uint8_t out[], size_t blocks) + + The key must have been set first with + Encrypt *blocks* blocks of data stored in *in* and place the ciphertext into *out*. + The two parameters may be the same buffer, but must not overlap. + +.. cpp:function:: int botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc, const uint8_t in[], uint8_t out[], size_t blocks) + + Decrypt *blocks* blocks of data stored in *in* and place the ciphertext into *out*. + The two parameters may be the same buffer, but must not overlap. + +.. cpp:function:: int botan_block_cipher_destroy(botan_block_cipher_t rng) + + Destroy the object created by :cpp:func:`botan_block_cipher_init`. + + Hash Functions ---------------------------------------- @@ -510,6 +554,21 @@ Public Key Creation, Import and Export .. cpp:function:: int botan_pubkey_destroy(botan_pubkey_t key) +.. cpp:function:: int botan_pubkey_get_field(botan_mp_t output, \ + botan_pubkey_t key, \ + const char* field_name) + + Read an algorithm specific field from the public key object, placing it into output. + For exampe "n" or "e" for RSA keys or "p", "q", "g", and "y" for DSA keys. + +.. cpp:function:: int botan_privkey_get_field(botan_mp_t output, \ + botan_privkey_t key, \ + const char* field_name) + + Read an algorithm specific field from the private key object, placing it into output. + For exampe "p" or "q" for RSA keys, or "x" for DSA keys or ECC keys. + + RSA specific functions ---------------------------------------- @@ -551,6 +610,19 @@ RSA specific functions Initialize a public RSA key using parameters n and e. +DSA specific functions +---------------------------------------- + +.. cpp:function:: int botan_privkey_load_dsa(botan_privkey_t* key, \ + botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t x) + + Initialize a private DSA key using group parameters p, q, and g and private key x. + +.. cpp:function:: int botan_pubkey_load_dsa(botan_pubkey_t* key, \ + botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t y) + + Initialize a private DSA key using group parameters p, q, and g and public key y. + Public Key Encryption/Decryption ---------------------------------------- diff --git a/doc/todo.rst b/doc/todo.rst index b3ad697e8..4a7d60191 100644 --- a/doc/todo.rst +++ b/doc/todo.rst @@ -108,6 +108,11 @@ New Protocols / Formats - Subset #2: Process OpenPGP public keys - Subset #3: Verification of OpenPGP signatures +Cleanups +----------- + +* Split ffi.cpp and test_ffi.cpp into multiple files + Compat Headers ---------------- @@ -119,9 +124,7 @@ Compat Headers FFI and Bindings ---------------------------------------- -* Expose BigInt * Expose compression -* Expose a raw block cipher interface * Expose more of X.509 (CRLs, OCSP, cert signing, etc) * Expose TLS * Write a CLI or HTTPS client in Python @@ -4,18 +4,24 @@ Release Notes Version 2.1.0, Not Yet Released ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -* Fix incorrect truncation in Bcrypt. Passwords in length between 56 - and 72 characters were truncated at 56 characters. Found and - reported by Solar Designer. (CVE-2017-7252) +* Fix incorrect truncation in Bcrypt. Passwords in length between 56 and 72 + characters were truncated at 56 characters. Found and reported by Solar Designer. + (CVE-2017-7252) (GH #938) * Correct minimum work factor for Bcrypt password hashes. All other - implementations require the work factor be at least 4. Previously - Botan simply required it be greater than zero. + implementations require the work factor be at least 4. Previously Botan simply + required it be greater than zero. (GH #938) + +* Converge on a single side channel silent EC blinded multiply algorithm. + Uses Montgomery ladder with order/2 bits scalar blinding and point randomization + now by default. (GH #893) * Support a 0-length IV in ChaCha stream cipher. Such an IV is treated identically to an 8-byte IV of all zeros. -* New C89 API interfaces for testing key validity. (GH #944) +* Add new interfaces to the C API including multiple precision integers, key + validity tests, extracting algorithm specific key paramters (eg the modulus + and public exponent from RSA public keys). GH #899 #944 #946 #961 #964 * The PKCS11 module did not require any external dependencies, so it has been enabled by default. The ``-with-pkcs11`` and ``--without-pkcs11`` @@ -56,7 +62,12 @@ Version 2.1.0, Not Yet Released * Add command line util ``timing_test`` which enables running timing-based side channel analysis of TLS CBC decryption, ECC scalar multiplies, OAEP decoding, and other operations which are prone to - providing an oracle via side channel. + providing an oracle via side channel. This replaces the standalone + timing test suite added in 1.11.34, which has been removed. + +* Various cleanups and refactorings (GH #965) + +* Add wrapper of C++14 make_unique (GH #974) * Fix pkg-config output when --build-dir was used (GH #936) @@ -68,21 +79,33 @@ Version 2.1.0, Not Yet Released * Avoid a GCC warning that triggered on the public key types (GH #849) * Fix various warnings flagged by pylint and pyflakes linters in - configure.py and botan.py (GH #832 #836 #839) - + configure.py and botan.py (GH #832 #836 #839 #962 #975) + +* Improve support for OpenBSD including using getentropy (GH #954) + for PRNG seeding, and arc4random to access system RNG (GH #953) + +* Add ability to build through CMake. As of now this is only supported + for development rather than production builds. (GH #967) + * Rename python wrapper to botan2.py (GH #847) * Change name constraint test to use a fixed reference time. Test certs have expired. -* Increase miller-rabin iterations for DSA primes (FIPS-186-4) (GH #881) +* Increase Miller-Rabin iterations for DSA primes to match FIPS 186-4. (GH #881) -* Fix possible ISO 9796-2 padding side channel and add a length check (GH #891) +* Fix possible ISO 9796-2 padding side channel, and add a missing length check (GH #891) -* In CLI, if system RNG is available prefer it +* In command line utility, prefer the system RNG if it is available. -* Converge on a single side channel silent EC blinded multiply algorithm. - Uses montgomery ladder with order/2 bits scalar blinding and point randomization - now by default. (GH #893) +Version 1.10.16, 2017-04-04 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Fix a bug in X509 DN string comparisons that could result in out of bound + reads. This could result in information leakage, denial of service, or + potentially incorrect certificate validation results. (CVE-2017-2801) + +* Avoid throwing during a destructor since this is undefined in C++11 + and rarely a good idea. (GH #930) Version 1.10.15, 2017-01-12 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt index 07c1d7d0a..5ace1931c 100644 --- a/src/build-data/cc/gcc.txt +++ b/src/build-data/cc/gcc.txt @@ -99,21 +99,21 @@ alpha-ev7 -> "-mcpu=ev67" sh4 -> "-m4 -mieee" # Default family options (SUBMODEL is substitued with the actual -# submodel name). Anything after the quotes is what should be -# *removed* from the submodel name before it's put into SUBMODEL. +# submodel name). Anything after the pipe will be removed from the +# submodel name before it's put into SUBMODEL. -alpha -> "-mcpu=SUBMODEL" alpha- +alpha -> "-mcpu=SUBMODEL|alpha-" arm32 -> "-march=SUBMODEL" arm64 -> "-march=SUBMODEL" -superh -> "-mSUBMODEL" sh -hppa -> "-march=SUBMODEL" hppa +superh -> "-mSUBMODEL|sh" +hppa -> "-march=SUBMODEL|hppa" ia64 -> "-mtune=SUBMODEL" m68k -> "-mSUBMODEL" -mips32 -> "-mips1 -mcpu=SUBMODEL" mips32- -mips64 -> "-mips3 -mcpu=SUBMODEL" mips64- -ppc32 -> "-mcpu=SUBMODEL" ppc -ppc64 -> "-mcpu=SUBMODEL" ppc -sparc32 -> "-mcpu=SUBMODEL -Wa,-xarch=v8plus" sparc32- +mips32 -> "-mips1 -mcpu=SUBMODEL|mips32-" +mips64 -> "-mips3 -mcpu=SUBMODEL|mips64-" +ppc32 -> "-mcpu=SUBMODEL|ppc" +ppc64 -> "-mcpu=SUBMODEL|ppc" +sparc32 -> "-mcpu=SUBMODEL -Wa,-xarch=v8plus|sparc32-" sparc64 -> "-mcpu=v9 -mtune=SUBMODEL" x86_32 -> "-march=SUBMODEL" x86_64 -> "-march=SUBMODEL" diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt index edf34017d..4d97f9d57 100644 --- a/src/build-data/cc/msvc.txt +++ b/src/build-data/cc/msvc.txt @@ -10,8 +10,8 @@ add_lib_option "" compile_flags "/nologo /c" -optimization_flags "/O2" -size_optimization_flags "/O1" +optimization_flags "/O2 /Oi" +size_optimization_flags "/O1 /Os" # for debug info in the object file: #debug_info_flags "/Z7" diff --git a/src/build-data/cc/sunstudio.txt b/src/build-data/cc/sunstudio.txt index 934b42099..c2fc97a01 100644 --- a/src/build-data/cc/sunstudio.txt +++ b/src/build-data/cc/sunstudio.txt @@ -43,7 +43,7 @@ ultrasparc3 -> "-xchip=ultra3" niagra1 -> "-xchip=ultraT1" niagra2 -> "-xchip=ultraT2" -sparc32 -> "-xchip=ultra -xarch=SUBMODEL" sparc32- +sparc32 -> "-xchip=ultra -xarch=SUBMODEL|sparc32-" sparc64 -> "-xchip=generic" </mach_opt> diff --git a/src/cli/asn1.cpp b/src/cli/asn1.cpp index 75ec5c3bb..b877a24a1 100644 --- a/src/cli/asn1.cpp +++ b/src/cli/asn1.cpp @@ -151,8 +151,6 @@ std::string type_name(Botan::ASN1_Tag type) default: return "TAG(" + std::to_string(static_cast<size_t>(type)) + ")"; } - - return "(UNKNOWN)"; } void decode(Botan::BER_Decoder& decoder, size_t level) diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp index 6ea70d3d1..2bffc736e 100644 --- a/src/cli/speed.cpp +++ b/src/cli/speed.cpp @@ -224,18 +224,13 @@ class Timer double milliseconds() const { return value() / 1000000.0; } double ms_per_event() const { return milliseconds() / events(); } - double seconds_per_event() const { return seconds() / events(); } uint64_t cycles_consumed() const { return m_cpu_cycles_used; } - uint64_t event_mult() const { return m_event_mult; } uint64_t events() const { return m_event_count * m_event_mult; } const std::string& get_name() const { return m_name; } const std::string& doing() const { return m_doing; } - uint64_t min_time() const { return m_min_time; } - uint64_t max_time() const { return m_max_time; } - static std::string result_string_bps(const Timer& t); static std::string result_string_ops(const Timer& t); private: @@ -1278,7 +1273,7 @@ class Speed final : public Command } } #endif - + #if defined(BOTAN_HAS_ECKCDSA) void bench_eckcdsa(const std::string& provider, std::chrono::milliseconds msec) @@ -1298,7 +1293,7 @@ class Speed final : public Command } } #endif - + #if defined(BOTAN_HAS_ECGDSA) void bench_ecgdsa(const std::string& provider, std::chrono::milliseconds msec) diff --git a/src/cli/timing_tests.cpp b/src/cli/timing_tests.cpp index 570957cc3..3adda8482 100644 --- a/src/cli/timing_tests.cpp +++ b/src/cli/timing_tests.cpp @@ -53,8 +53,8 @@ typedef uint64_t ticks; class Timing_Test { public: - Timing_Test() {} - virtual ~Timing_Test() {} + Timing_Test() = default; + virtual ~Timing_Test() = default; std::vector<std::vector<ticks>> execute_evaluation(const std::vector<std::string>& inputs, diff --git a/src/cli/tls_utils.cpp b/src/cli/tls_utils.cpp index 1e7332485..ef590ff3f 100644 --- a/src/cli/tls_utils.cpp +++ b/src/cli/tls_utils.cpp @@ -48,7 +48,7 @@ class TLS_All_Policy : public Botan::TLS::Policy std::vector<std::string> allowed_signature_methods() const override { return { "ECDSA", "RSA", "DSA" }; - }; + } }; class TLS_Ciphersuites final : public Command diff --git a/src/lib/asn1/alg_id.h b/src/lib/asn1/alg_id.h index 2cd0b350a..0a1ed0c66 100644 --- a/src/lib/asn1/alg_id.h +++ b/src/lib/asn1/alg_id.h @@ -25,7 +25,7 @@ class BOTAN_DLL AlgorithmIdentifier final : public ASN1_Object void encode_into(class DER_Encoder&) const override; void decode_from(class BER_Decoder&) override; - AlgorithmIdentifier() {} + AlgorithmIdentifier() = default; AlgorithmIdentifier(const OID&, Encoding_Option); AlgorithmIdentifier(const std::string&, Encoding_Option); diff --git a/src/lib/asn1/asn1_attribute.h b/src/lib/asn1/asn1_attribute.h index e6bcc5209..24d4a4bf1 100644 --- a/src/lib/asn1/asn1_attribute.h +++ b/src/lib/asn1/asn1_attribute.h @@ -29,7 +29,7 @@ class BOTAN_DLL Attribute final : public ASN1_Object // public member variable: std::vector<uint8_t> parameters; - Attribute() {} + Attribute() = default; Attribute(const OID&, const std::vector<uint8_t>&); Attribute(const std::string&, const std::vector<uint8_t>&); }; diff --git a/src/lib/asn1/asn1_obj.h b/src/lib/asn1/asn1_obj.h index 5e09da2fd..536f75ced 100644 --- a/src/lib/asn1/asn1_obj.h +++ b/src/lib/asn1/asn1_obj.h @@ -73,7 +73,10 @@ class BOTAN_DLL ASN1_Object */ virtual void decode_from(BER_Decoder& from) = 0; - virtual ~ASN1_Object() {} + ASN1_Object() = default; + ASN1_Object(const ASN1_Object&) = default; + ASN1_Object & operator=(const ASN1_Object&) = default; + virtual ~ASN1_Object() = default; }; /** diff --git a/src/lib/asn1/asn1_time.h b/src/lib/asn1/asn1_time.h index a2a526558..99047e475 100644 --- a/src/lib/asn1/asn1_time.h +++ b/src/lib/asn1/asn1_time.h @@ -38,7 +38,7 @@ class BOTAN_DLL X509_Time final : public ASN1_Object int32_t cmp(const X509_Time& other) const; /// Create an invalid X509_Time - X509_Time() {} + X509_Time() = default; /// Create a X509_Time from a time point explicit X509_Time(const std::chrono::system_clock::time_point& time); diff --git a/src/lib/base/secmem.h b/src/lib/base/secmem.h index 758045c93..3852c5323 100644 --- a/src/lib/base/secmem.h +++ b/src/lib/base/secmem.h @@ -46,13 +46,21 @@ class secure_allocator typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; - secure_allocator() BOTAN_NOEXCEPT {} +#ifdef BOTAN_BUILD_COMPILER_IS_MSVC_2013 + secure_allocator() = default; + secure_allocator(const secure_allocator&) = default; + secure_allocator& operator=(const secure_allocator&) = default; + ~secure_allocator() = default; +#else + secure_allocator() BOTAN_NOEXCEPT = default; + secure_allocator(const secure_allocator&) BOTAN_NOEXCEPT = default; + secure_allocator& operator=(const secure_allocator&) BOTAN_NOEXCEPT = default; + ~secure_allocator() BOTAN_NOEXCEPT = default; +#endif template<typename U> secure_allocator(const secure_allocator<U>&) BOTAN_NOEXCEPT {} - ~secure_allocator() BOTAN_NOEXCEPT {} - pointer address(reference x) const BOTAN_NOEXCEPT { return std::addressof(x); } diff --git a/src/lib/block/block_cipher.h b/src/lib/block/block_cipher.h index ec080dbf0..77a46d33b 100644 --- a/src/lib/block/block_cipher.h +++ b/src/lib/block/block_cipher.h @@ -173,7 +173,7 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm */ virtual BlockCipher* clone() const = 0; - virtual ~BlockCipher() {} + virtual ~BlockCipher() = default; }; /** diff --git a/src/lib/entropy/proc_walk/proc_walk.h b/src/lib/entropy/proc_walk/proc_walk.h index 054da3e51..e1a844c7d 100644 --- a/src/lib/entropy/proc_walk/proc_walk.h +++ b/src/lib/entropy/proc_walk/proc_walk.h @@ -17,7 +17,7 @@ class File_Descriptor_Source { public: virtual int next_fd() = 0; - virtual ~File_Descriptor_Source() {} + virtual ~File_Descriptor_Source() = default; }; /** diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp index 37664daa3..b4f0412d6 100644 --- a/src/lib/ffi/ffi.cpp +++ b/src/lib/ffi/ffi.cpp @@ -9,6 +9,7 @@ #include <botan/exceptn.h> #include <botan/auto_rng.h> #include <botan/aead.h> +#include <botan/block_cipher.h> #include <botan/hash.h> #include <botan/mac.h> #include <botan/pbkdf.h> @@ -32,10 +33,22 @@ #include <botan/rsa.h> #endif +#if defined(BOTAN_HAS_DSA) + #include <botan/dsa.h> +#endif + #if defined(BOTAN_HAS_ECDSA) #include <botan/ecdsa.h> #endif +#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) + #include <botan/ecc_key.h> +#endif + +#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY) + #include <botan/dl_algo.h> +#endif + #if defined(BOTAN_HAS_ECDH) #include <botan/ecdh.h> #endif @@ -205,6 +218,7 @@ struct botan_cipher_struct : public botan_struct<Botan::Cipher_Mode, 0xB4A2BF9C> BOTAN_FFI_DECLARE_STRUCT(botan_rng_struct, Botan::RandomNumberGenerator, 0x4901F9C1); BOTAN_FFI_DECLARE_STRUCT(botan_mp_struct, Botan::BigInt, 0xC828B9D2); +BOTAN_FFI_DECLARE_STRUCT(botan_block_cipher_struct, Botan::BlockCipher, 0x64C29716); BOTAN_FFI_DECLARE_STRUCT(botan_hash_struct, Botan::HashFunction, 0x1F0A4F84); BOTAN_FFI_DECLARE_STRUCT(botan_mac_struct, Botan::MessageAuthenticationCode, 0xA06E8FC1); BOTAN_FFI_DECLARE_STRUCT(botan_pubkey_struct, Botan::Public_Key, 0x2C286519); @@ -581,6 +595,81 @@ int botan_mp_num_bytes(const botan_mp_t mp, size_t* bytes) return BOTAN_FFI_DO(Botan::BigInt, mp, n, { *bytes = n.bytes(); }); } +int botan_block_cipher_init(botan_block_cipher_t* bc, const char* bc_name) + { + try + { + if(bc == nullptr || bc_name == nullptr || *bc_name == 0) + return BOTAN_FFI_ERROR_NULL_POINTER; + + std::unique_ptr<Botan::BlockCipher> cipher(Botan::BlockCipher::create(bc_name)); + if(cipher) + { + *bc = new botan_block_cipher_struct(cipher.release()); + return 0; + } + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + catch(...) + { + log_exception(BOTAN_CURRENT_FUNCTION, "unknown"); + } + + return BOTAN_FFI_ERROR_EXCEPTION_THROWN; + + } + +/** +* Destroy a block cipher object +*/ +int botan_block_cipher_destroy(botan_block_cipher_t bc) + { + delete bc; + return 0; + } + +int botan_block_cipher_clear(botan_block_cipher_t bc) + { + return BOTAN_FFI_DO(Botan::BlockCipher, bc, b, { b.clear(); }); + } + +/** +* Set the key for a block cipher instance +*/ +int botan_block_cipher_set_key(botan_block_cipher_t bc, + const uint8_t key[], size_t len) + { + return BOTAN_FFI_DO(Botan::BlockCipher, bc, b, { b.set_key(key, len); }); + } + +/** +* Return the positive block size of this block cipher, or negative to +* indicate an error +*/ +int botan_block_cipher_block_size(botan_block_cipher_t bc) + { + return BOTAN_FFI_DO(Botan::BlockCipher, bc, b, { return b.block_size(); }); + } + +int botan_block_cipher_encrypt_blocks(botan_block_cipher_t bc, + const uint8_t in[], + uint8_t out[], + size_t blocks) + { + return BOTAN_FFI_DO(Botan::BlockCipher, bc, b, { b.encrypt_n(in, out, blocks); }); + } + +int botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc, + const uint8_t in[], + uint8_t out[], + size_t blocks) + { + return BOTAN_FFI_DO(Botan::BlockCipher, bc, b, { b.decrypt_n(in, out, blocks); }); + } + int botan_hash_init(botan_hash_t* hash, const char* hash_name, uint32_t flags) { try @@ -1028,20 +1117,31 @@ int botan_privkey_create(botan_privkey_t* key_obj, { try { - if(key_obj == nullptr || rng_obj == nullptr) - return -1; + if(key_obj == nullptr) + return BOTAN_FFI_ERROR_NULL_POINTER; + + *key_obj = nullptr; + if(rng_obj == nullptr) + return BOTAN_FFI_ERROR_NULL_POINTER; + if(algo_name == nullptr) algo_name = "RSA"; if(algo_params == nullptr) algo_params = ""; - *key_obj = nullptr; - Botan::RandomNumberGenerator& rng = safe_get(rng_obj); std::unique_ptr<Botan::Private_Key> key( Botan::create_private_key(algo_name, rng, algo_params)); - *key_obj = new botan_privkey_struct(key.release()); - return 0; + + if(key) + { + *key_obj = new botan_privkey_struct(key.release()); + return 0; + } + else + { + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; + } } catch(std::exception& e) { @@ -1199,6 +1299,30 @@ int botan_privkey_load(botan_privkey_t* key, botan_rng_t rng_obj, return -1; } +int botan_pubkey_load(botan_pubkey_t* key, + const uint8_t bits[], size_t bits_len) + { + *key = nullptr; + + try + { + Botan::DataSource_Memory src(bits, bits_len); + std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(src)); + + if(pubkey) + { + *key = new botan_pubkey_struct(pubkey.release()); + return 0; + } + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + int botan_privkey_load_rsa(botan_privkey_t* key, botan_mp_t p, botan_mp_t q, botan_mp_t d) { @@ -1244,117 +1368,264 @@ int botan_pubkey_load_rsa(botan_pubkey_t* key, #endif } -int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key) +int botan_privkey_load_dsa(botan_privkey_t* key, + botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t x) { -#if defined(BOTAN_HAS_RSA) - return BOTAN_FFI_DO(Botan::Private_Key, key, k, { - if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<Botan::RSA_PrivateKey*>(&k)) - { - safe_get(p) = rsa->get_p(); - } - else - throw FFI_Error("Passed non-RSA key to botan_privkey_rsa_get_p"); - }); + *key = nullptr; + +#if defined(BOTAN_HAS_DSA) + try + { + Botan::Null_RNG null_rng; + Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g)); + *key = new botan_privkey_struct(new Botan::DSA_PrivateKey(null_rng, group, safe_get(x))); + return 0; + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + return -1; #else + BOTAN_UNUSED(p); + BOTAN_UNUSED(q); + BOTAN_UNUSED(g); + BOTAN_UNUSED(x); return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; #endif } -int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t key) +int botan_pubkey_load_dsa(botan_pubkey_t* key, + botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t y) { -#if defined(BOTAN_HAS_RSA) - return BOTAN_FFI_DO(Botan::Private_Key, key, k, { - if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<Botan::RSA_PrivateKey*>(&k)) - { - safe_get(q) = rsa->get_q(); - } - else - throw FFI_Error("Passed non-RSA key to botan_privkey_rsa_get_q"); - }); + *key = nullptr; + +#if defined(BOTAN_HAS_DSA) + try + { + Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g)); + *key = new botan_pubkey_struct(new Botan::DSA_PublicKey(group, safe_get(y))); + return 0; + } + catch(std::exception& exn) + { + log_exception(BOTAN_CURRENT_FUNCTION, exn.what()); + } + + return -1; #else + BOTAN_UNUSED(p); + BOTAN_UNUSED(q); + BOTAN_UNUSED(g); + BOTAN_UNUSED(y); return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; #endif } -int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t key) +namespace { + +Botan::BigInt botan_pubkey_do_get_field(const Botan::Public_Key& key, + const std::string& field) { + // Maybe this should be `return key.get_integer_field(field_name)`? + #if defined(BOTAN_HAS_RSA) - return BOTAN_FFI_DO(Botan::Private_Key, key, k, { - if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<Botan::RSA_PrivateKey*>(&k)) - { - safe_get(n) = rsa->get_n(); - } + if(const Botan::RSA_PublicKey* rsa = dynamic_cast<const Botan::RSA_PublicKey*>(&key)) + { + if(field == "n") + return rsa->get_n(); + else if(field == "e") + return rsa->get_e(); else - throw FFI_Error("Passed non-RSA key to botan_privkey_rsa_get_n"); - }); -#else - return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; + throw Botan::Exception("Field not supported"); + } +#endif + +#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY) + // Handles DSA, ElGamal, etc + if(const Botan::DL_Scheme_PublicKey* dl = dynamic_cast<const Botan::DL_Scheme_PublicKey*>(&key)) + { + if(field == "p") + return dl->group_p(); + else if(field == "q") + return dl->group_q(); + else if(field == "g") + return dl->group_g(); + else if(field == "y") + return dl->get_y(); + else + throw Botan::Exception("Field not supported"); + } #endif + +#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) + if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key)) + { + if(field == "public_x") + return ecc->public_point().get_affine_x(); + else if(field == "public_y") + return ecc->public_point().get_affine_y(); + else if(field == "base_x") + return ecc->domain().get_base_point().get_affine_x(); + else if(field == "base_y") + return ecc->domain().get_base_point().get_affine_y(); + else if(field == "p") + return ecc->domain().get_curve().get_p(); + else if(field == "a") + return ecc->domain().get_curve().get_a(); + else if(field == "b") + return ecc->domain().get_curve().get_b(); + else if(field == "cofactor") + return ecc->domain().get_cofactor(); + else if(field == "order") + return ecc->domain().get_order(); + else + throw Botan::Exception("Field not supported"); + } +#endif + + // Some other algorithm type not supported by this function + throw Botan::Exception("Unsupported algorithm type for botan_pubkey_get_field"); } -int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key) +Botan::BigInt botan_privkey_do_get_field(const Botan::Private_Key& key, + const std::string& field) { + //return key.get_integer_field(field); + #if defined(BOTAN_HAS_RSA) - return BOTAN_FFI_DO(Botan::Private_Key, key, k, { - if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<Botan::RSA_PrivateKey*>(&k)) - { - safe_get(e) = rsa->get_e(); - } + + if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&key)) + { + if(field == "p") + return rsa->get_p(); + else if(field == "q") + return rsa->get_q(); + else if(field == "d") + return rsa->get_d(); + else if(field == "c") + return rsa->get_c(); + else if(field == "d1") + return rsa->get_d1(); + else if(field == "d2") + return rsa->get_d2(); else - throw FFI_Error("Passed non-RSA key to botan_privkey_rsa_get_e"); - }); -#else - return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; + return botan_pubkey_do_get_field(key, field); + } #endif + +#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY) + // Handles DSA, ElGamal, etc + if(const Botan::DL_Scheme_PrivateKey* dl = dynamic_cast<const Botan::DL_Scheme_PrivateKey*>(&key)) + { + if(field == "x") + return dl->get_x(); + else + return botan_pubkey_do_get_field(key, field); + } +#endif + +#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) + if(const Botan::EC_PrivateKey* ecc = dynamic_cast<const Botan::EC_PrivateKey*>(&key)) + { + if(field == "x") + return ecc->private_value(); + else + return botan_pubkey_do_get_field(key, field); + } +#endif + + // Some other algorithm type not supported by this function + throw Botan::Exception("Unsupported algorithm type for botan_privkey_get_field"); } -int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t key) +} + +int botan_pubkey_get_field(botan_mp_t output, + botan_pubkey_t key, + const char* field_name_cstr) { -#if defined(BOTAN_HAS_RSA) + if(field_name_cstr == nullptr) + return BOTAN_FFI_ERROR_NULL_POINTER; + + const std::string field_name(field_name_cstr); + + return BOTAN_FFI_DO(Botan::Public_Key, key, k, { + safe_get(output) = botan_pubkey_do_get_field(k, field_name); + }); + } + +int botan_privkey_get_field(botan_mp_t output, + botan_privkey_t key, + const char* field_name_cstr) + { + if(field_name_cstr == nullptr) + return BOTAN_FFI_ERROR_NULL_POINTER; + + const std::string field_name(field_name_cstr); + return BOTAN_FFI_DO(Botan::Private_Key, key, k, { - if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<Botan::RSA_PrivateKey*>(&k)) - { - safe_get(d) = rsa->get_e(); - } - else - throw FFI_Error("Passed non-RSA key to botan_privkey_rsa_get_d"); + safe_get(output) = botan_privkey_do_get_field(k, field_name); }); -#else - return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; -#endif + } + +int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key) + { + return botan_privkey_get_field(p, key, "p"); + } + +int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t key) + { + return botan_privkey_get_field(q, key, "q"); + } + +int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t key) + { + return botan_privkey_get_field(n, key, "n"); + } + +int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key) + { + return botan_privkey_get_field(e, key, "e"); + } + +int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t key) + { + return botan_privkey_get_field(d, key, "d"); } int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t key) { -#if defined(BOTAN_HAS_RSA) - return BOTAN_FFI_DO(Botan::Public_Key, key, k, { - if(const Botan::RSA_PublicKey* rsa = dynamic_cast<Botan::RSA_PublicKey*>(&k)) - { - safe_get(e) = rsa->get_e(); - } - else - throw FFI_Error("Passed non-RSA key to botan_pubkey_rsa_get_e"); - }); -#else - return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; -#endif + return botan_pubkey_get_field(e, key, "e"); } int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t key) { -#if defined(BOTAN_HAS_RSA) - return BOTAN_FFI_DO(Botan::Public_Key, key, k, { - if(const Botan::RSA_PublicKey* rsa = dynamic_cast<Botan::RSA_PublicKey*>(&k)) - { - safe_get(n) = rsa->get_n(); - } - else - throw FFI_Error("Passed non-RSA key to botan_pubkey_rsa_get_n"); - }); -#else - return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; -#endif + return botan_pubkey_get_field(n, key, "n"); + } + +int botan_privkey_dsa_get_x(botan_mp_t x, botan_privkey_t key) + { + return botan_privkey_get_field(x, key, "x"); + } + +int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key) + { + return botan_pubkey_get_field(p, key, "p"); } +int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_t key) + { + return botan_pubkey_get_field(q, key, "q"); + } +int botan_pubkey_dsa_get_g(botan_mp_t g, botan_pubkey_t key) + { + return botan_pubkey_get_field(g, key, "g"); + } +int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key) + { + return botan_pubkey_get_field(y, key, "y"); + } + int botan_privkey_destroy(botan_privkey_t key) { diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h index 3d62bb8c0..76cdaa145 100644 --- a/src/lib/ffi/ffi.h +++ b/src/lib/ffi/ffi.h @@ -456,6 +456,51 @@ BOTAN_DLL int botan_bcrypt_generate(uint8_t* out, size_t* out_len, uint32_t flags); /* +* Raw Block Cipher (PRP) interface +*/ +typedef struct botan_block_cipher_struct* botan_block_cipher_t; + +/** +* Initialize a block cipher object +*/ +BOTAN_DLL int botan_block_cipher_init(botan_block_cipher_t* bc, + const char* cipher_name); + +/** +* Destroy a block cipher object +*/ +BOTAN_DLL int botan_block_cipher_destroy(botan_block_cipher_t bc); + +/** +* Reinitializes the block cipher +* @return 0 on success, a negative value on failure +*/ +BOTAN_DLL int botan_block_cipher_clear(botan_block_cipher_t bc); + +/** +* Set the key for a block cipher instance +*/ +BOTAN_DLL int botan_block_cipher_set_key(botan_block_cipher_t bc, + const uint8_t key[], size_t len); + +/** +* Return the positive block size of this block cipher, or negative to +* indicate an error +*/ +BOTAN_DLL int botan_block_cipher_block_size(botan_block_cipher_t bc); + +BOTAN_DLL int botan_block_cipher_encrypt_blocks(botan_block_cipher_t bc, + const uint8_t in[], + uint8_t out[], + size_t blocks); + +BOTAN_DLL int botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc, + const uint8_t in[], + uint8_t out[], + size_t blocks); + + +/* * Multiple precision integers */ typedef struct botan_mp_struct* botan_mp_t; @@ -683,6 +728,16 @@ BOTAN_DLL int botan_pubkey_fingerprint(botan_pubkey_t key, const char* hash, BOTAN_DLL int botan_pubkey_destroy(botan_pubkey_t key); +/* +* Get arbitrary named fields from public or privat keys +*/ +BOTAN_DLL int botan_pubkey_get_field(botan_mp_t output, + botan_pubkey_t key, + const char* field_name); + +BOTAN_DLL int botan_privkey_get_field(botan_mp_t output, + botan_privkey_t key, + const char* field_name); /* * Algorithm specific key operations: RSA @@ -706,6 +761,28 @@ BOTAN_DLL int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t rsa_key); BOTAN_DLL int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t rsa_key); /* +* Algorithm specific key operations: DSA +*/ +BOTAN_DLL int botan_privkey_load_dsa(botan_privkey_t* key, + botan_mp_t p, + botan_mp_t q, + botan_mp_t g, + botan_mp_t x); + +BOTAN_DLL int botan_pubkey_load_dsa(botan_pubkey_t* key, + botan_mp_t p, + botan_mp_t q, + botan_mp_t g, + botan_mp_t y); + +BOTAN_DLL int botan_privkey_dsa_get_x(botan_mp_t n, botan_privkey_t key); + +BOTAN_DLL int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key); +BOTAN_DLL int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_t key); +BOTAN_DLL int botan_pubkey_dsa_get_g(botan_mp_t d, botan_pubkey_t key); +BOTAN_DLL int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key); + +/* * Public Key Encryption */ typedef struct botan_pk_op_encrypt_struct* botan_pk_op_encrypt_t; diff --git a/src/lib/filters/buf_filt.h b/src/lib/filters/buf_filt.h index b7b915c88..d08dd9dec 100644 --- a/src/lib/filters/buf_filt.h +++ b/src/lib/filters/buf_filt.h @@ -49,7 +49,7 @@ class BOTAN_DLL Buffered_Filter */ Buffered_Filter(size_t block_size, size_t final_minimum); - virtual ~Buffered_Filter() {} + virtual ~Buffered_Filter() = default; protected: /** * The block processor, implemented by subclasses diff --git a/src/lib/filters/data_snk.h b/src/lib/filters/data_snk.h index 4c70d7f19..7accef358 100644 --- a/src/lib/filters/data_snk.h +++ b/src/lib/filters/data_snk.h @@ -21,8 +21,8 @@ class BOTAN_DLL DataSink : public Filter { public: bool attachable() override { return false; } - DataSink() {} - virtual ~DataSink() {} + DataSink() = default; + virtual ~DataSink() = default; DataSink& operator=(const DataSink&) = delete; DataSink(const DataSink&) = delete; diff --git a/src/lib/filters/filter.h b/src/lib/filters/filter.h index 81a35c003..6b93fd03b 100644 --- a/src/lib/filters/filter.h +++ b/src/lib/filters/filter.h @@ -51,7 +51,7 @@ class BOTAN_DLL Filter */ virtual bool attachable() { return true; } - virtual ~Filter() {} + virtual ~Filter() = default; protected: /** * @param in some input for the filter diff --git a/src/lib/hash/hash.h b/src/lib/hash/hash.h index f6cf470cb..5cb290499 100644 --- a/src/lib/hash/hash.h +++ b/src/lib/hash/hash.h @@ -56,7 +56,7 @@ class BOTAN_DLL HashFunction : public Buffered_Computation */ virtual std::string provider() const { return "base"; } - virtual ~HashFunction() {} + virtual ~HashFunction() = default; /** * Reset the state. diff --git a/src/lib/hash/par_hash/par_hash.h b/src/lib/hash/par_hash/par_hash.h index cbc2ad591..cf6f49af4 100644 --- a/src/lib/hash/par_hash/par_hash.h +++ b/src/lib/hash/par_hash/par_hash.h @@ -34,7 +34,7 @@ class BOTAN_DLL Parallel final : public HashFunction Parallel(const Parallel&) = delete; Parallel& operator=(const Parallel&) = delete; private: - Parallel() {} + Parallel() = delete; void add_data(const uint8_t[], size_t) override; void final_result(uint8_t[]) override; diff --git a/src/lib/kdf/kdf.h b/src/lib/kdf/kdf.h index 8c188bfb4..3be026222 100644 --- a/src/lib/kdf/kdf.h +++ b/src/lib/kdf/kdf.h @@ -20,7 +20,7 @@ namespace Botan { class BOTAN_DLL KDF { public: - virtual ~KDF() {} + virtual ~KDF() = default; /** * Create an instance based on a name diff --git a/src/lib/mac/mac.h b/src/lib/mac/mac.h index 44bdd3da4..c4d880658 100644 --- a/src/lib/mac/mac.h +++ b/src/lib/mac/mac.h @@ -48,7 +48,7 @@ class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation, */ static std::vector<std::string> providers(const std::string& algo_spec); - virtual ~MessageAuthenticationCode() {} + virtual ~MessageAuthenticationCode() = default; /** * Prepare for processing a message under the specified nonce diff --git a/src/lib/math/bigint/bigint.h b/src/lib/math/bigint/bigint.h index 42fe60e41..4bb0161fc 100644 --- a/src/lib/math/bigint/bigint.h +++ b/src/lib/math/bigint/bigint.h @@ -42,7 +42,7 @@ class BOTAN_DLL BigInt /** * Create empty BigInt */ - BigInt() {} + BigInt() = default; /** * Create BigInt from 64 bit integer diff --git a/src/lib/math/ec_gfp/curve_gfp.h b/src/lib/math/ec_gfp/curve_gfp.h index dde9f633e..f1b4b144a 100644 --- a/src/lib/math/ec_gfp/curve_gfp.h +++ b/src/lib/math/ec_gfp/curve_gfp.h @@ -18,7 +18,7 @@ namespace Botan { class CurveGFp_Repr { public: - virtual ~CurveGFp_Repr() {} + virtual ~CurveGFp_Repr() = default; virtual const BigInt& get_p() const = 0; virtual const BigInt& get_a() const = 0; @@ -57,7 +57,7 @@ class BOTAN_DLL CurveGFp /** * Create an uninitialized CurveGFp */ - CurveGFp() {} + CurveGFp() = default; /** * Construct the elliptic curve E: y^2 = x^3 + ax + b over GF(p) diff --git a/src/lib/math/ec_gfp/point_gfp.h b/src/lib/math/ec_gfp/point_gfp.h index 6f4c7e5f9..46ee5449a 100644 --- a/src/lib/math/ec_gfp/point_gfp.h +++ b/src/lib/math/ec_gfp/point_gfp.h @@ -50,7 +50,7 @@ class BOTAN_DLL PointGFp /** * Construct an uninitialized PointGFp */ - PointGFp() {} + PointGFp() = default; /** * Construct the zero point diff --git a/src/lib/math/numbertheory/pow_mod.h b/src/lib/math/numbertheory/pow_mod.h index 194d00ec8..e7db774b6 100644 --- a/src/lib/math/numbertheory/pow_mod.h +++ b/src/lib/math/numbertheory/pow_mod.h @@ -22,7 +22,11 @@ class BOTAN_DLL Modular_Exponentiator virtual void set_exponent(const BigInt&) = 0; virtual BigInt execute() const = 0; virtual Modular_Exponentiator* copy() const = 0; - virtual ~Modular_Exponentiator() {} + + Modular_Exponentiator() = default; + Modular_Exponentiator(const Modular_Exponentiator&) = default; + Modular_Exponentiator & operator=(const Modular_Exponentiator&) = default; + virtual ~Modular_Exponentiator() = default; }; /** @@ -103,7 +107,7 @@ class BOTAN_DLL Fixed_Exponent_Power_Mod : public Power_Mod BigInt operator()(const BigInt& b) const { set_base(b); return execute(); } - Fixed_Exponent_Power_Mod() {} + Fixed_Exponent_Power_Mod() = default; Fixed_Exponent_Power_Mod(const BigInt& exponent, const BigInt& modulus, @@ -119,7 +123,7 @@ class BOTAN_DLL Fixed_Base_Power_Mod : public Power_Mod BigInt operator()(const BigInt& e) const { set_exponent(e); return execute(); } - Fixed_Base_Power_Mod() {} + Fixed_Base_Power_Mod() = default; Fixed_Base_Power_Mod(const BigInt& base, const BigInt& modulus, diff --git a/src/lib/misc/tss/tss.h b/src/lib/misc/tss/tss.h index 79aa417c3..ac96a6e0c 100644 --- a/src/lib/misc/tss/tss.h +++ b/src/lib/misc/tss/tss.h @@ -41,7 +41,7 @@ class BOTAN_DLL RTSS_Share static secure_vector<uint8_t> reconstruct(const std::vector<RTSS_Share>& shares); - RTSS_Share() {} + RTSS_Share() = default; /** * @param hex_input the share encoded in hexadecimal diff --git a/src/lib/modes/aead/aead.h b/src/lib/modes/aead/aead.h index 3d3c7287f..a0b11541b 100644 --- a/src/lib/modes/aead/aead.h +++ b/src/lib/modes/aead/aead.h @@ -74,7 +74,7 @@ class BOTAN_DLL AEAD_Mode : public Cipher_Mode */ size_t default_nonce_length() const override { return 12; } - virtual ~AEAD_Mode() {} + virtual ~AEAD_Mode() = default; }; /** diff --git a/src/lib/modes/cipher_mode.h b/src/lib/modes/cipher_mode.h index cdf16e37c..411a1b3e5 100644 --- a/src/lib/modes/cipher_mode.h +++ b/src/lib/modes/cipher_mode.h @@ -23,7 +23,7 @@ namespace Botan { class BOTAN_DLL Cipher_Mode { public: - virtual ~Cipher_Mode() {} + virtual ~Cipher_Mode() = default; /* * Prepare for processing a message under the specified nonce diff --git a/src/lib/modes/mode_pad/mode_pad.h b/src/lib/modes/mode_pad/mode_pad.h index cfa27463b..c221882cc 100644 --- a/src/lib/modes/mode_pad/mode_pad.h +++ b/src/lib/modes/mode_pad/mode_pad.h @@ -59,7 +59,7 @@ class BOTAN_DLL BlockCipherModePaddingMethod /** * virtual destructor */ - virtual ~BlockCipherModePaddingMethod() {} + virtual ~BlockCipherModePaddingMethod() = default; }; /** diff --git a/src/lib/pbkdf/pbkdf.cpp b/src/lib/pbkdf/pbkdf.cpp index 8f72a9180..a60c93d5c 100644 --- a/src/lib/pbkdf/pbkdf.cpp +++ b/src/lib/pbkdf/pbkdf.cpp @@ -18,8 +18,6 @@ namespace Botan { -PBKDF::~PBKDF() {} - std::unique_ptr<PBKDF> PBKDF::create(const std::string& algo_spec, const std::string& provider) { diff --git a/src/lib/pbkdf/pbkdf.h b/src/lib/pbkdf/pbkdf.h index 95cf4da02..0f2feb751 100644 --- a/src/lib/pbkdf/pbkdf.h +++ b/src/lib/pbkdf/pbkdf.h @@ -47,7 +47,7 @@ class BOTAN_DLL PBKDF */ virtual std::string name() const = 0; - virtual ~PBKDF(); + virtual ~PBKDF() = default; /** * Derive a key from a passphrase for a number of iterations diff --git a/src/lib/pk_pad/eme_raw/eme_raw.h b/src/lib/pk_pad/eme_raw/eme_raw.h index ec698f759..50b9b6703 100644 --- a/src/lib/pk_pad/eme_raw/eme_raw.h +++ b/src/lib/pk_pad/eme_raw/eme_raw.h @@ -16,7 +16,7 @@ class BOTAN_DLL EME_Raw final : public EME public: size_t maximum_input_size(size_t i) const override; - EME_Raw() {} + EME_Raw() = default; private: secure_vector<uint8_t> pad(const uint8_t[], size_t, size_t, RandomNumberGenerator&) const override; diff --git a/src/lib/pk_pad/emsa.cpp b/src/lib/pk_pad/emsa.cpp index 3851f85a7..94274916e 100644 --- a/src/lib/pk_pad/emsa.cpp +++ b/src/lib/pk_pad/emsa.cpp @@ -33,8 +33,6 @@ namespace Botan { -EMSA::~EMSA() {} - EMSA* get_emsa(const std::string& algo_spec) { SCAN_Name req(algo_spec); diff --git a/src/lib/pk_pad/emsa.h b/src/lib/pk_pad/emsa.h index 4b932fd78..437f84d89 100644 --- a/src/lib/pk_pad/emsa.h +++ b/src/lib/pk_pad/emsa.h @@ -55,7 +55,7 @@ class BOTAN_DLL EMSA const secure_vector<uint8_t>& raw, size_t key_bits) = 0; - virtual ~EMSA(); + virtual ~EMSA() = default; /** * @return a new object representing the same encoding method as *this diff --git a/src/lib/prov/pkcs11/p11.cpp b/src/lib/prov/pkcs11/p11.cpp index d338438d3..8a460b66f 100644 --- a/src/lib/prov/pkcs11/p11.cpp +++ b/src/lib/prov/pkcs11/p11.cpp @@ -79,9 +79,6 @@ LowLevel::LowLevel(FunctionListPtr ptr) : } } -LowLevel::~LowLevel() BOTAN_NOEXCEPT -{} - /****************************** General purpose functions ******************************/ bool LowLevel::C_Initialize(VoidPtr init_args, diff --git a/src/lib/prov/pkcs11/p11.h b/src/lib/prov/pkcs11/p11.h index efc887e11..bbfbbd881 100644 --- a/src/lib/prov/pkcs11/p11.h +++ b/src/lib/prov/pkcs11/p11.h @@ -901,12 +901,9 @@ BOTAN_DLL void set_pin(Slot& slot, const secure_string& so_pin, const secure_str class BOTAN_DLL LowLevel { public: - /// @param ptr the functon list pointer to use. Can be retrieved via `LowLevel::C_GetFunctionList` explicit LowLevel(FunctionListPtr ptr); - ~LowLevel() BOTAN_NOEXCEPT; - /****************************** General purpose functions ******************************/ /** diff --git a/src/lib/prov/pkcs11/p11_mechanism.cpp b/src/lib/prov/pkcs11/p11_mechanism.cpp index a4c6e73a7..290465dac 100644 --- a/src/lib/prov/pkcs11/p11_mechanism.cpp +++ b/src/lib/prov/pkcs11/p11_mechanism.cpp @@ -35,6 +35,8 @@ struct MechanismData : type(_type) {} + MechanismData(MechanismData const&) = default; + MechanismData& operator=(MechanismData const&) = default; virtual ~MechanismData() = default; // the mechanism to perform diff --git a/src/lib/prov/pkcs11/p11_object.h b/src/lib/prov/pkcs11/p11_object.h index e7ab05f0d..fbf912233 100644 --- a/src/lib/prov/pkcs11/p11_object.h +++ b/src/lib/prov/pkcs11/p11_object.h @@ -656,6 +656,8 @@ class BOTAN_DLL Object */ Object(Session& session, const ObjectProperties& obj_props); + Object(const Object&) = default; + Object& operator=(const Object&) = default; virtual ~Object() = default; /// Searches for all objects of the given type that match `search_template` diff --git a/src/lib/pubkey/curve25519/curve25519.h b/src/lib/pubkey/curve25519/curve25519.h index 43e998df6..567bb7008 100644 --- a/src/lib/pubkey/curve25519/curve25519.h +++ b/src/lib/pubkey/curve25519/curve25519.h @@ -51,7 +51,7 @@ class BOTAN_DLL Curve25519_PublicKey : public virtual Public_Key m_public(pub.begin(), pub.end()) {} protected: - Curve25519_PublicKey() {} + Curve25519_PublicKey() = default; std::vector<uint8_t> m_public; }; diff --git a/src/lib/pubkey/dh/dh.h b/src/lib/pubkey/dh/dh.h index d5e86d154..f3f4b746b 100644 --- a/src/lib/pubkey/dh/dh.h +++ b/src/lib/pubkey/dh/dh.h @@ -40,7 +40,7 @@ class BOTAN_DLL DH_PublicKey : public virtual DL_Scheme_PublicKey */ DH_PublicKey(const DL_Group& grp, const BigInt& y); protected: - DH_PublicKey() {} + DH_PublicKey() = default; }; /** diff --git a/src/lib/pubkey/dl_algo/dl_algo.h b/src/lib/pubkey/dl_algo/dl_algo.h index 4c0d56931..94bf24387 100644 --- a/src/lib/pubkey/dl_algo/dl_algo.h +++ b/src/lib/pubkey/dl_algo/dl_algo.h @@ -76,7 +76,7 @@ class BOTAN_DLL DL_Scheme_PublicKey : public virtual Public_Key DL_Scheme_PublicKey& operator=(const DL_Scheme_PublicKey& other) = default; protected: - DL_Scheme_PublicKey() {} + DL_Scheme_PublicKey() = default; /** * The DL public key @@ -119,7 +119,7 @@ class BOTAN_DLL DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey, DL_Scheme_PrivateKey& operator=(const DL_Scheme_PrivateKey& other) = default; protected: - DL_Scheme_PrivateKey() {} + DL_Scheme_PrivateKey() = default; /** * The DL private key diff --git a/src/lib/pubkey/dsa/dsa.h b/src/lib/pubkey/dsa/dsa.h index a39105d8f..8fa338748 100644 --- a/src/lib/pubkey/dsa/dsa.h +++ b/src/lib/pubkey/dsa/dsa.h @@ -46,7 +46,7 @@ class BOTAN_DLL DSA_PublicKey : public virtual DL_Scheme_PublicKey create_verification_op(const std::string& params, const std::string& provider) const override; protected: - DSA_PublicKey() {} + DSA_PublicKey() = default; }; /** diff --git a/src/lib/pubkey/ecc_key/ecc_key.h b/src/lib/pubkey/ecc_key/ecc_key.h index 186182ba0..fc60bb17c 100644 --- a/src/lib/pubkey/ecc_key/ecc_key.h +++ b/src/lib/pubkey/ecc_key/ecc_key.h @@ -45,7 +45,9 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key EC_PublicKey(const AlgorithmIdentifier& alg_id, const std::vector<uint8_t>& key_bits); + EC_PublicKey(const EC_PublicKey& other) = default; EC_PublicKey& operator=(const EC_PublicKey& other) = default; + virtual ~EC_PublicKey() = default; /** * Get the public point of this key. @@ -135,8 +137,6 @@ class BOTAN_DLL EC_PrivateKey : public virtual EC_PublicKey, const secure_vector<uint8_t>& key_bits, bool with_modular_inverse=false); - EC_PrivateKey& operator=(const EC_PrivateKey& other) = default; - secure_vector<uint8_t> private_key_bits() const override; /** @@ -144,8 +144,12 @@ class BOTAN_DLL EC_PrivateKey : public virtual EC_PublicKey, * @result the private key value of this key object */ const BigInt& private_value() const; + + EC_PrivateKey(const EC_PrivateKey& other) = default; + EC_PrivateKey& operator=(const EC_PrivateKey& other) = default; + ~EC_PrivateKey() = default; protected: - EC_PrivateKey() {} + EC_PrivateKey() = default; BigInt m_private_key; }; diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp index 0ddb39275..f6d2bb251 100644 --- a/src/lib/pubkey/ecdh/ecdh.cpp +++ b/src/lib/pubkey/ecdh/ecdh.cpp @@ -16,8 +16,6 @@ namespace Botan { -ECDH_PublicKey::ECDH_PublicKey() {} - namespace { /** diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h index f5dc5a05d..f6ffb0a6e 100644 --- a/src/lib/pubkey/ecdh/ecdh.h +++ b/src/lib/pubkey/ecdh/ecdh.h @@ -57,7 +57,7 @@ class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey { return unlock(EC2OSP(public_point(), type)); } protected: - ECDH_PublicKey(); + ECDH_PublicKey() = default; }; /** diff --git a/src/lib/pubkey/ecdsa/ecdsa.h b/src/lib/pubkey/ecdsa/ecdsa.h index 8281c63fd..304a27776 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.h +++ b/src/lib/pubkey/ecdsa/ecdsa.h @@ -54,7 +54,7 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey create_verification_op(const std::string& params, const std::string& provider) const override; protected: - ECDSA_PublicKey() {} + ECDSA_PublicKey() = default; }; /** diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.h b/src/lib/pubkey/ecgdsa/ecgdsa.h index 9fb55de06..06a675531 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.h +++ b/src/lib/pubkey/ecgdsa/ecgdsa.h @@ -52,7 +52,7 @@ class BOTAN_DLL ECGDSA_PublicKey : public virtual EC_PublicKey create_verification_op(const std::string& params, const std::string& provider) const override; protected: - ECGDSA_PublicKey() {} + ECGDSA_PublicKey() = default; }; /** diff --git a/src/lib/pubkey/ecies/ecies.h b/src/lib/pubkey/ecies/ecies.h index 6daf5a641..0e348ca23 100644 --- a/src/lib/pubkey/ecies/ecies.h +++ b/src/lib/pubkey/ecies/ecies.h @@ -68,6 +68,8 @@ class BOTAN_DLL ECIES_KA_Params ECIES_KA_Params(const EC_Group& domain, const std::string& kdf_spec, size_t length, PointGFp::Compression_Type compression_type, ECIES_Flags flags); + ECIES_KA_Params(const ECIES_KA_Params&) = default; + ECIES_KA_Params& operator=(const ECIES_KA_Params&) = default; virtual ~ECIES_KA_Params() = default; inline const EC_Group& domain() const @@ -147,6 +149,8 @@ class BOTAN_DLL ECIES_System_Params : public ECIES_KA_Params size_t dem_key_len, const std::string& mac_spec, size_t mac_key_len, PointGFp::Compression_Type compression_type, ECIES_Flags flags); + ECIES_System_Params(const ECIES_System_Params&) = default; + ECIES_System_Params& operator=(const ECIES_System_Params&) = default; virtual ~ECIES_System_Params() = default; /// creates an instance of the message authentication code diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.h b/src/lib/pubkey/eckcdsa/eckcdsa.h index e941a393d..3959c5f78 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.h +++ b/src/lib/pubkey/eckcdsa/eckcdsa.h @@ -52,7 +52,7 @@ class BOTAN_DLL ECKCDSA_PublicKey : public virtual EC_PublicKey create_verification_op(const std::string& params, const std::string& provider) const override; protected: - ECKCDSA_PublicKey() {} + ECKCDSA_PublicKey() = default; }; /** diff --git a/src/lib/pubkey/elgamal/elgamal.h b/src/lib/pubkey/elgamal/elgamal.h index 0453e3564..33345d56f 100644 --- a/src/lib/pubkey/elgamal/elgamal.h +++ b/src/lib/pubkey/elgamal/elgamal.h @@ -44,7 +44,7 @@ class BOTAN_DLL ElGamal_PublicKey : public virtual DL_Scheme_PublicKey const std::string& provider) const override; protected: - ElGamal_PublicKey() {} + ElGamal_PublicKey() = default; }; /** diff --git a/src/lib/pubkey/gost_3410/gost_3410.h b/src/lib/pubkey/gost_3410/gost_3410.h index d7ae4a7dc..c6fc148ca 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.h +++ b/src/lib/pubkey/gost_3410/gost_3410.h @@ -58,7 +58,7 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey const std::string& provider) const override; protected: - GOST_3410_PublicKey() {} + GOST_3410_PublicKey() = default; }; /** diff --git a/src/lib/pubkey/mce/code_based_key_gen.cpp b/src/lib/pubkey/mce/code_based_key_gen.cpp index 4d68c875a..7377bc117 100644 --- a/src/lib/pubkey/mce/code_based_key_gen.cpp +++ b/src/lib/pubkey/mce/code_based_key_gen.cpp @@ -33,23 +33,18 @@ struct binary_matrix uint32_t coef(uint32_t i, uint32_t j) { return (m_elem[(i) * m_rwdcnt + (j) / 32] >> (j % 32)) & 1; - }; + } void set_coef_to_one(uint32_t i, uint32_t j) { m_elem[(i) * m_rwdcnt + (j) / 32] |= (static_cast<uint32_t>(1) << ((j) % 32)) ; - }; + } void toggle_coeff(uint32_t i, uint32_t j) { m_elem[(i) * m_rwdcnt + (j) / 32] ^= (static_cast<uint32_t>(1) << ((j) % 32)) ; } - void set_to_zero() - { - zeroise(m_elem); - } - //private: uint32_t m_rown; // number of rows. uint32_t m_coln; // number of columns. diff --git a/src/lib/pubkey/mce/gf2m_rootfind_dcmp.cpp b/src/lib/pubkey/mce/gf2m_rootfind_dcmp.cpp index a35fc7458..be2c5380e 100644 --- a/src/lib/pubkey/mce/gf2m_rootfind_dcmp.cpp +++ b/src/lib/pubkey/mce/gf2m_rootfind_dcmp.cpp @@ -44,7 +44,7 @@ class gf2m_decomp_rootfind_state void calc_next_Aij(); void calc_Ai_zero(const polyn_gf2m & sigma); secure_vector<gf2m> find_roots(const polyn_gf2m & sigma); - uint32_t get_code_length() const { return code_length; }; + uint32_t get_code_length() const { return code_length; } uint32_t code_length; secure_vector<gf2m> m_Lik; // size is outer_summands * m secure_vector<gf2m> m_Aij; // ... diff --git a/src/lib/pubkey/mce/mceliece.h b/src/lib/pubkey/mce/mceliece.h index 58c242360..946083128 100644 --- a/src/lib/pubkey/mce/mceliece.h +++ b/src/lib/pubkey/mce/mceliece.h @@ -23,13 +23,14 @@ class BOTAN_DLL McEliece_PublicKey : public virtual Public_Key public: explicit McEliece_PublicKey(const std::vector<uint8_t>& key_bits); - McEliece_PublicKey(std::vector<uint8_t> const& pub_matrix, uint32_t the_t, uint32_t the_code_length) : + McEliece_PublicKey(const std::vector<uint8_t>& pub_matrix, uint32_t the_t, uint32_t the_code_length) : m_public_matrix(pub_matrix), m_t(the_t), - m_code_length(the_code_length) - {} + m_code_length(the_code_length){} - McEliece_PublicKey(const McEliece_PublicKey& other); + McEliece_PublicKey(const McEliece_PublicKey& other) = default; + McEliece_PublicKey& operator=(const McEliece_PublicKey& other) = default; + virtual ~McEliece_PublicKey()= default; secure_vector<uint8_t> random_plaintext_element(RandomNumberGenerator& rng) const; diff --git a/src/lib/pubkey/mce/mceliece_key.cpp b/src/lib/pubkey/mce/mceliece_key.cpp index 798f7a91f..4c7eb6670 100644 --- a/src/lib/pubkey/mce/mceliece_key.cpp +++ b/src/lib/pubkey/mce/mceliece_key.cpp @@ -82,13 +82,6 @@ std::vector<uint8_t> McEliece_PublicKey::public_key_bits() const .get_contents_unlocked(); } -McEliece_PublicKey::McEliece_PublicKey(const McEliece_PublicKey & other) : - m_public_matrix(other.m_public_matrix), - m_t(other.m_t), - m_code_length(other.m_code_length) - { - } - size_t McEliece_PublicKey::key_length() const { return m_code_length; diff --git a/src/lib/pubkey/mce/polyn_gf2m.h b/src/lib/pubkey/mce/polyn_gf2m.h index 0782406ea..075cd1c88 100644 --- a/src/lib/pubkey/mce/polyn_gf2m.h +++ b/src/lib/pubkey/mce/polyn_gf2m.h @@ -30,8 +30,7 @@ struct polyn_gf2m explicit polyn_gf2m( std::shared_ptr<GF2m_Field> sp_field ); polyn_gf2m() - :m_deg(-1) - {}; + :m_deg(-1) {} polyn_gf2m(const secure_vector<uint8_t>& encoded, std::shared_ptr<GF2m_Field> sp_field ); @@ -39,12 +38,12 @@ struct polyn_gf2m bool operator==(const polyn_gf2m & other) const ; - bool operator!=(const polyn_gf2m & other) const { return !(*this == other); }; + bool operator!=(const polyn_gf2m & other) const { return !(*this == other); } polyn_gf2m(polyn_gf2m&& other) { this->swap(other); - }; + } polyn_gf2m & operator=(polyn_gf2m&& other) { @@ -74,9 +73,9 @@ struct polyn_gf2m polyn_gf2m(int t, RandomNumberGenerator& rng, std::shared_ptr<GF2m_Field> sp_field); std::shared_ptr<GF2m_Field> get_sp_field() const - { return msp_field; }; + { return msp_field; } - gf2m& operator[](size_t i) { return coeff[i]; }; + gf2m& operator[](size_t i) { return coeff[i]; } gf2m operator[](size_t i) const { return coeff[i]; } @@ -87,7 +86,7 @@ struct polyn_gf2m inline void set_coef(uint32_t i, gf2m v) { coeff[i] = v; - }; + } inline void add_to_coef(uint32_t i, gf2m v) { diff --git a/src/lib/pubkey/pk_keys.h b/src/lib/pubkey/pk_keys.h index 833dda69e..13e0dc768 100644 --- a/src/lib/pubkey/pk_keys.h +++ b/src/lib/pubkey/pk_keys.h @@ -24,10 +24,11 @@ class RandomNumberGenerator; class BOTAN_DLL Public_Key { public: + Public_Key() =default; + Public_Key(const Public_Key& other) = default; + Public_Key& operator=(const Public_Key& other) = default; virtual ~Public_Key() = default; - virtual Public_Key& operator=(const Public_Key& other) = default; - /** * Get the name of the underlying public key scheme. * @return name of the public key scheme @@ -165,10 +166,11 @@ class BOTAN_DLL Public_Key class BOTAN_DLL Private_Key : public virtual Public_Key { public: + Private_Key() = default; + Private_Key(const Private_Key& other) = default; + Private_Key& operator=(const Private_Key& other) = default; virtual ~Private_Key() = default; - virtual Private_Key& operator=(const Private_Key& other) = default; - /** * @return BER encoded private key bits */ @@ -274,7 +276,10 @@ class BOTAN_DLL PK_Key_Agreement_Key : public virtual Private_Key */ virtual std::vector<uint8_t> public_value() const = 0; - virtual ~PK_Key_Agreement_Key() {} + PK_Key_Agreement_Key() = default; + PK_Key_Agreement_Key(const PK_Key_Agreement_Key&) = default; + PK_Key_Agreement_Key& operator=(const PK_Key_Agreement_Key&) = default; + virtual ~PK_Key_Agreement_Key() = default; }; /* diff --git a/src/lib/pubkey/pk_ops.cpp b/src/lib/pubkey/pk_ops.cpp index cf10c4ba2..5c864d966 100644 --- a/src/lib/pubkey/pk_ops.cpp +++ b/src/lib/pubkey/pk_ops.cpp @@ -6,9 +6,6 @@ */ #include <botan/internal/pk_ops_impl.h> -#include <botan/eme.h> -#include <botan/kdf.h> -#include <botan/emsa.h> #include <botan/internal/bit_ops.h> namespace Botan { @@ -20,8 +17,6 @@ PK_Ops::Encryption_with_EME::Encryption_with_EME(const std::string& eme) throw Algorithm_Not_Found(eme); } -PK_Ops::Encryption_with_EME::~Encryption_with_EME() {} - size_t PK_Ops::Encryption_with_EME::max_input_bits() const { return m_eme->maximum_input_size(max_raw_input_bits()); @@ -42,8 +37,6 @@ PK_Ops::Decryption_with_EME::Decryption_with_EME(const std::string& eme) throw Algorithm_Not_Found(eme); } -PK_Ops::Decryption_with_EME::~Decryption_with_EME() {} - secure_vector<uint8_t> PK_Ops::Decryption_with_EME::decrypt(uint8_t& valid_mask, const uint8_t ciphertext[], @@ -59,8 +52,6 @@ PK_Ops::Key_Agreement_with_KDF::Key_Agreement_with_KDF(const std::string& kdf) m_kdf.reset(get_kdf(kdf)); } -PK_Ops::Key_Agreement_with_KDF::~Key_Agreement_with_KDF() {} - secure_vector<uint8_t> PK_Ops::Key_Agreement_with_KDF::agree(size_t key_len, const uint8_t w[], size_t w_len, const uint8_t salt[], size_t salt_len) @@ -81,8 +72,6 @@ PK_Ops::Signature_with_EMSA::Signature_with_EMSA(const std::string& emsa) : throw Algorithm_Not_Found(emsa); } -PK_Ops::Signature_with_EMSA::~Signature_with_EMSA() {} - void PK_Ops::Signature_with_EMSA::update(const uint8_t msg[], size_t msg_len) { if(has_prefix() && !m_prefix_used) @@ -112,8 +101,6 @@ PK_Ops::Verification_with_EMSA::Verification_with_EMSA(const std::string& emsa) throw Algorithm_Not_Found(emsa); } -PK_Ops::Verification_with_EMSA::~Verification_with_EMSA() {} - void PK_Ops::Verification_with_EMSA::update(const uint8_t msg[], size_t msg_len) { if(has_prefix() && !m_prefix_used) @@ -163,8 +150,6 @@ PK_Ops::KEM_Encryption_with_KDF::KEM_Encryption_with_KDF(const std::string& kdf) m_kdf.reset(get_kdf(kdf)); } -PK_Ops::KEM_Encryption_with_KDF::~KEM_Encryption_with_KDF() {} - secure_vector<uint8_t> PK_Ops::KEM_Decryption_with_KDF::kem_decrypt(const uint8_t encap_key[], size_t len, @@ -184,6 +169,4 @@ PK_Ops::KEM_Decryption_with_KDF::KEM_Decryption_with_KDF(const std::string& kdf) m_kdf.reset(get_kdf(kdf)); } -PK_Ops::KEM_Decryption_with_KDF::~KEM_Decryption_with_KDF() {} - } diff --git a/src/lib/pubkey/pk_ops.h b/src/lib/pubkey/pk_ops.h index d3c4c0d9b..d270954f9 100644 --- a/src/lib/pubkey/pk_ops.h +++ b/src/lib/pubkey/pk_ops.h @@ -42,7 +42,7 @@ class BOTAN_DLL Encryption virtual size_t max_input_bits() const = 0; - virtual ~Encryption() {} + virtual ~Encryption() = default; }; /** @@ -55,7 +55,7 @@ class BOTAN_DLL Decryption const uint8_t ciphertext[], size_t ciphertext_len) = 0; - virtual ~Decryption() {} + virtual ~Decryption() = default; }; /** @@ -77,7 +77,7 @@ class BOTAN_DLL Verification */ virtual bool is_valid_signature(const uint8_t sig[], size_t sig_len) = 0; - virtual ~Verification() {} + virtual ~Verification() = default; }; /** @@ -99,7 +99,7 @@ class BOTAN_DLL Signature */ virtual secure_vector<uint8_t> sign(RandomNumberGenerator& rng) = 0; - virtual ~Signature() {} + virtual ~Signature() = default; }; /** @@ -112,7 +112,7 @@ class BOTAN_DLL Key_Agreement const uint8_t other_key[], size_t other_key_len, const uint8_t salt[], size_t salt_len) = 0; - virtual ~Key_Agreement() {} + virtual ~Key_Agreement() = default; }; /** @@ -128,7 +128,7 @@ class BOTAN_DLL KEM_Encryption const uint8_t salt[], size_t salt_len) = 0; - virtual ~KEM_Encryption() {} + virtual ~KEM_Encryption() = default; }; class BOTAN_DLL KEM_Decryption @@ -140,7 +140,7 @@ class BOTAN_DLL KEM_Decryption const uint8_t salt[], size_t salt_len) = 0; - virtual ~KEM_Decryption() {} + virtual ~KEM_Decryption() = default; }; } diff --git a/src/lib/pubkey/pk_ops_impl.h b/src/lib/pubkey/pk_ops_impl.h index f6c1b0510..a9f8b9c11 100644 --- a/src/lib/pubkey/pk_ops_impl.h +++ b/src/lib/pubkey/pk_ops_impl.h @@ -9,6 +9,9 @@ #define BOTAN_PK_OPERATION_IMPL_H__ #include <botan/pk_ops.h> +#include <botan/eme.h> +#include <botan/kdf.h> +#include <botan/emsa.h> namespace Botan { @@ -22,7 +25,7 @@ class Encryption_with_EME : public Encryption secure_vector<uint8_t> encrypt(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& rng) override; - ~Encryption_with_EME(); + ~Encryption_with_EME() = default; protected: explicit Encryption_with_EME(const std::string& eme); private: @@ -39,7 +42,7 @@ class Decryption_with_EME : public Decryption secure_vector<uint8_t> decrypt(uint8_t& valid_mask, const uint8_t msg[], size_t msg_len) override; - ~Decryption_with_EME(); + ~Decryption_with_EME() = default; protected: explicit Decryption_with_EME(const std::string& eme); private: @@ -51,7 +54,7 @@ class Decryption_with_EME : public Decryption class Verification_with_EMSA : public Verification { public: - ~Verification_with_EMSA(); + ~Verification_with_EMSA() = default; void update(const uint8_t msg[], size_t msg_len) override; bool is_valid_signature(const uint8_t sig[], size_t sig_len) override; @@ -129,7 +132,7 @@ class Signature_with_EMSA : public Signature secure_vector<uint8_t> sign(RandomNumberGenerator& rng) override; protected: explicit Signature_with_EMSA(const std::string& emsa); - ~Signature_with_EMSA(); + ~Signature_with_EMSA() = default; std::string hash_for_signature() { return m_hash; } @@ -173,7 +176,7 @@ class Key_Agreement_with_KDF : public Key_Agreement protected: explicit Key_Agreement_with_KDF(const std::string& kdf); - ~Key_Agreement_with_KDF(); + ~Key_Agreement_with_KDF() = default; private: virtual secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) = 0; std::unique_ptr<KDF> m_kdf; @@ -195,7 +198,7 @@ class KEM_Encryption_with_KDF : public KEM_Encryption Botan::RandomNumberGenerator& rng) = 0; explicit KEM_Encryption_with_KDF(const std::string& kdf); - ~KEM_Encryption_with_KDF(); + ~KEM_Encryption_with_KDF() = default; private: std::unique_ptr<KDF> m_kdf; }; @@ -214,7 +217,7 @@ class KEM_Decryption_with_KDF : public KEM_Decryption raw_kem_decrypt(const uint8_t encap_key[], size_t len) = 0; explicit KEM_Decryption_with_KDF(const std::string& kdf); - ~KEM_Decryption_with_KDF(); + ~KEM_Decryption_with_KDF() = default; private: std::unique_ptr<KDF> m_kdf; }; diff --git a/src/lib/pubkey/pubkey.h b/src/lib/pubkey/pubkey.h index a5202d973..bfe444829 100644 --- a/src/lib/pubkey/pubkey.h +++ b/src/lib/pubkey/pubkey.h @@ -68,8 +68,8 @@ class BOTAN_DLL PK_Encryptor */ virtual size_t maximum_input_size() const = 0; - PK_Encryptor() {} - virtual ~PK_Encryptor() {} + PK_Encryptor() = default; + virtual ~PK_Encryptor() = default; PK_Encryptor(const PK_Encryptor&) = delete; PK_Encryptor& operator=(const PK_Encryptor&) = delete; @@ -142,7 +142,7 @@ class BOTAN_DLL PK_Decryptor const uint8_t required_content_offsets[], size_t required_contents) const; - PK_Decryptor() {} + PK_Decryptor() = default; virtual ~PK_Decryptor() = default; PK_Decryptor(const PK_Decryptor&) = delete; diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp index d8deccab3..7d48fd814 100644 --- a/src/lib/pubkey/rsa/rsa.cpp +++ b/src/lib/pubkey/rsa/rsa.cpp @@ -244,7 +244,7 @@ class RSA_Signature_Operation : public PK_Ops::Signature_with_EMSA, { public: - size_t max_input_bits() const override { return get_max_input_bits(); }; + size_t max_input_bits() const override { return get_max_input_bits(); } RSA_Signature_Operation(const RSA_PrivateKey& rsa, const std::string& emsa, RandomNumberGenerator& rng) : PK_Ops::Signature_with_EMSA(emsa), @@ -268,7 +268,7 @@ class RSA_Decryption_Operation : public PK_Ops::Decryption_with_EME, { public: - size_t max_raw_input_bits() const override { return get_max_input_bits(); }; + size_t max_raw_input_bits() const override { return get_max_input_bits(); } RSA_Decryption_Operation(const RSA_PrivateKey& rsa, const std::string& eme, RandomNumberGenerator& rng) : PK_Ops::Decryption_with_EME(eme), @@ -346,7 +346,7 @@ class RSA_Encryption_Operation : public PK_Ops::Encryption_with_EME, { } - size_t max_raw_input_bits() const override { return get_max_input_bits(); }; + size_t max_raw_input_bits() const override { return get_max_input_bits(); } secure_vector<uint8_t> raw_encrypt(const uint8_t msg[], size_t msg_len, RandomNumberGenerator&) override @@ -361,7 +361,7 @@ class RSA_Verify_Operation : public PK_Ops::Verification_with_EMSA, { public: - size_t max_input_bits() const override { return get_max_input_bits(); }; + size_t max_input_bits() const override { return get_max_input_bits(); } RSA_Verify_Operation(const RSA_PublicKey& rsa, const std::string& emsa) : PK_Ops::Verification_with_EMSA(emsa), diff --git a/src/lib/pubkey/rsa/rsa.h b/src/lib/pubkey/rsa/rsa.h index 4d20dce8c..89555b51b 100644 --- a/src/lib/pubkey/rsa/rsa.h +++ b/src/lib/pubkey/rsa/rsa.h @@ -71,7 +71,7 @@ class BOTAN_DLL RSA_PublicKey : public virtual Public_Key const std::string& provider) const override; protected: - RSA_PublicKey() {} + RSA_PublicKey() = default; BigInt m_n, m_e; }; diff --git a/src/lib/pubkey/xmss/atomic.h b/src/lib/pubkey/xmss/atomic.h index cf3f5528c..e2fdaa78d 100644 --- a/src/lib/pubkey/xmss/atomic.h +++ b/src/lib/pubkey/xmss/atomic.h @@ -23,9 +23,10 @@ template <typename T> class Atomic { public: - Atomic() : m_data() {}; + Atomic() = default; Atomic(const Atomic& data) : m_data(data.m_data.load()) {} Atomic(const std::atomic<T>& data) : m_data(data.load()) {} + ~Atomic() = default; Atomic& operator=(const Atomic& a) { diff --git a/src/lib/pubkey/xmss/xmss_common_ops.h b/src/lib/pubkey/xmss/xmss_common_ops.h index 26cb27d26..2aff9b5f8 100644 --- a/src/lib/pubkey/xmss/xmss_common_ops.h +++ b/src/lib/pubkey/xmss/xmss_common_ops.h @@ -26,7 +26,7 @@ class XMSS_Common_Ops { public: XMSS_Common_Ops(XMSS_Parameters::xmss_algorithm_t oid) - : m_xmss_params(oid), m_hash(m_xmss_params.hash_function_name()) {}; + : m_xmss_params(oid), m_hash(m_xmss_params.hash_function_name()) {} protected: /** diff --git a/src/lib/pubkey/xmss/xmss_hash.h b/src/lib/pubkey/xmss/xmss_hash.h index 29a6ff90e..55b5fe930 100644 --- a/src/lib/pubkey/xmss/xmss_hash.h +++ b/src/lib/pubkey/xmss/xmss_hash.h @@ -144,7 +144,7 @@ class XMSS_Hash **/ secure_vector<uint8_t> h_msg_final(); - size_t output_length() const { return m_output_length; }; + size_t output_length() const { return m_output_length; } private: static const uint8_t m_id_f = 0x00; diff --git a/src/lib/pubkey/xmss/xmss_index_registry.h b/src/lib/pubkey/xmss/xmss_index_registry.h index decd50a8a..28701353d 100644 --- a/src/lib/pubkey/xmss/xmss_index_registry.h +++ b/src/lib/pubkey/xmss/xmss_index_registry.h @@ -58,8 +58,7 @@ class XMSS_Index_Registry const secure_vector<uint8_t>& prf); private: - XMSS_Index_Registry() - : m_key_ids(), m_leaf_indices(), m_mutex() {} + XMSS_Index_Registry() = default; static const std::string m_index_hash_function; diff --git a/src/lib/pubkey/xmss/xmss_signature.h b/src/lib/pubkey/xmss/xmss_signature.h index 001465e64..0e6dccc9e 100644 --- a/src/lib/pubkey/xmss/xmss_signature.h +++ b/src/lib/pubkey/xmss/xmss_signature.h @@ -44,7 +44,7 @@ class XMSS_Signature const secure_vector<uint8_t>& randomness, const XMSS_WOTS_PublicKey::TreeSignature& tree_sig) : m_leaf_idx(leaf_idx), m_randomness(randomness), - m_tree_sig(tree_sig) {}; + m_tree_sig(tree_sig) {} /** * Creates an XMSS Signature from a leaf index used for signature @@ -58,7 +58,7 @@ class XMSS_Signature secure_vector<uint8_t>&& randomness, XMSS_WOTS_PublicKey::TreeSignature&& tree_sig) : m_leaf_idx(leaf_idx), m_randomness(std::move(randomness)), - m_tree_sig(std::move(tree_sig)) {}; + m_tree_sig(std::move(tree_sig)) {} size_t unused_leaf_index() const { return m_leaf_idx; } void set_unused_leaf_idx(size_t idx) { m_leaf_idx = idx; } diff --git a/src/lib/pubkey/xmss/xmss_signature_operation.h b/src/lib/pubkey/xmss/xmss_signature_operation.h index 67c2f5e71..e2393750a 100644 --- a/src/lib/pubkey/xmss/xmss_signature_operation.h +++ b/src/lib/pubkey/xmss/xmss_signature_operation.h @@ -38,7 +38,7 @@ class XMSS_Signature_Operation : public virtual PK_Ops::Signature, { public: XMSS_Signature_Operation(const XMSS_PrivateKey& private_key); - virtual ~XMSS_Signature_Operation() {} + virtual ~XMSS_Signature_Operation() = default; /** * Creates an XMSS signature for the message provided through call to diff --git a/src/lib/pubkey/xmss/xmss_verification_operation.h b/src/lib/pubkey/xmss/xmss_verification_operation.h index c3682c0ad..a967fd0ea 100644 --- a/src/lib/pubkey/xmss/xmss_verification_operation.h +++ b/src/lib/pubkey/xmss/xmss_verification_operation.h @@ -33,7 +33,7 @@ namespace Botan { XMSS_Verification_Operation( const XMSS_PublicKey& public_key); - virtual ~XMSS_Verification_Operation() {} + virtual ~XMSS_Verification_Operation() = default; virtual bool is_valid_signature(const uint8_t sig[], size_t sig_len) override; diff --git a/src/lib/pubkey/xmss/xmss_wots_publickey.h b/src/lib/pubkey/xmss/xmss_wots_publickey.h index 5d973fd6a..eb2f9695b 100644 --- a/src/lib/pubkey/xmss/xmss_wots_publickey.h +++ b/src/lib/pubkey/xmss/xmss_wots_publickey.h @@ -35,8 +35,7 @@ class BOTAN_DLL XMSS_WOTS_PublicKey : virtual public Public_Key class TreeSignature { public: - TreeSignature() - : m_ots_sig(), m_auth_path() {} + TreeSignature() = default; TreeSignature(const wots_keysig_t& ots_sig, const wots_keysig_t& auth_path) @@ -191,7 +190,7 @@ class BOTAN_DLL XMSS_WOTS_PublicKey : virtual public Public_Key * Convert the key into the raw key data. The key becomes a length * len vector of n-byte elements. **/ - operator const wots_keysig_t& () const { return m_key; }; + operator const wots_keysig_t& () const { return m_key; } /** * Convert the key into the raw key data. The key becomes a length diff --git a/src/lib/pubkey/xmss/xmss_wots_signature_operation.h b/src/lib/pubkey/xmss/xmss_wots_signature_operation.h index f319ac138..4656c3dd1 100644 --- a/src/lib/pubkey/xmss/xmss_wots_signature_operation.h +++ b/src/lib/pubkey/xmss/xmss_wots_signature_operation.h @@ -32,7 +32,7 @@ class XMSS_WOTS_Signature_Operation : public virtual PK_Ops::Signature, XMSS_WOTS_Signature_Operation( const XMSS_WOTS_Addressed_PrivateKey& private_key); - virtual ~XMSS_WOTS_Signature_Operation() {} + virtual ~XMSS_WOTS_Signature_Operation() = default; /** * Creates a XMSS WOTS signature for the message provided through call diff --git a/src/lib/pubkey/xmss/xmss_wots_verification_operation.h b/src/lib/pubkey/xmss/xmss_wots_verification_operation.h index 0bc5f0db9..5899e4f46 100644 --- a/src/lib/pubkey/xmss/xmss_wots_verification_operation.h +++ b/src/lib/pubkey/xmss/xmss_wots_verification_operation.h @@ -32,7 +32,7 @@ class XMSS_WOTS_Verification_Operation XMSS_WOTS_Verification_Operation( const XMSS_WOTS_Addressed_PublicKey& public_key); - virtual ~XMSS_WOTS_Verification_Operation() {} + virtual ~XMSS_WOTS_Verification_Operation() = default; virtual bool is_valid_signature(const uint8_t sig[], size_t sig_len) override; diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.cpp b/src/lib/rng/hmac_drbg/hmac_drbg.cpp index e47d49628..4f19b5256 100644 --- a/src/lib/rng/hmac_drbg/hmac_drbg.cpp +++ b/src/lib/rng/hmac_drbg/hmac_drbg.cpp @@ -158,12 +158,27 @@ void HMAC_DRBG::update(const uint8_t input[], size_t input_len) void HMAC_DRBG::add_entropy(const uint8_t input[], size_t input_len) { update(input, input_len); + + if(8*input_len >= security_level()) + { + m_reseed_counter = 1; + } } size_t HMAC_DRBG::security_level() const { - // sqrt of hash size - return m_mac->output_length() * 8 / 2; + // security strength of the hash function + // for pre-image resistance (see NIST SP 800-57) + // SHA-160: 128 bits, SHA-224, SHA-512/224: 192 bits, + // SHA-256, SHA-512/256, SHA-384, SHA-512: >= 256 bits + // NIST SP 800-90A only supports up to 256 bits though + if(m_mac->output_length() < 32) + { + return (m_mac->output_length() - 4) * 8; + } + else + { + return 32 * 8; + } } - } diff --git a/src/lib/rng/stateful_rng/stateful_rng.h b/src/lib/rng/stateful_rng/stateful_rng.h index 982747e01..ed51aac6a 100644 --- a/src/lib/rng/stateful_rng/stateful_rng.h +++ b/src/lib/rng/stateful_rng/stateful_rng.h @@ -121,14 +121,15 @@ class BOTAN_DLL Stateful_RNG : public RandomNumberGenerator Entropy_Sources* m_entropy_sources = nullptr; const size_t m_reseed_interval; + uint32_t m_last_pid = 0; + protected: /* - * Set to 1 after a sucessful seeding, then incremented. Reset + * Set to 1 after a successful seeding, then incremented. Reset * to 0 by clear() or a fork. This logic is used even if * automatic reseeding is disabled (via m_reseed_interval = 0) */ size_t m_reseed_counter = 0; - uint32_t m_last_pid = 0; }; } diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h index 3c843cb87..8a828ed26 100644 --- a/src/lib/stream/stream_cipher.h +++ b/src/lib/stream/stream_cipher.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL StreamCipher : public SymmetricAlgorithm { public: - virtual ~StreamCipher() {} + virtual ~StreamCipher() = default; /** * Create an instance based on a name diff --git a/src/lib/tls/credentials_manager.h b/src/lib/tls/credentials_manager.h index e39c81c36..bdcdf9ddd 100644 --- a/src/lib/tls/credentials_manager.h +++ b/src/lib/tls/credentials_manager.h @@ -28,7 +28,7 @@ class BigInt; class BOTAN_DLL Credentials_Manager { public: - virtual ~Credentials_Manager() {} + virtual ~Credentials_Manager() = default; /** * Return a list of the certificates of CAs that we trust in this diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp index 2ffa39a79..17f5cad4f 100644 --- a/src/lib/tls/msg_server_kex.cpp +++ b/src/lib/tls/msg_server_kex.cpp @@ -245,8 +245,6 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector<uint8_t>& buf, reader.assert_done(); } -Server_Key_Exchange::~Server_Key_Exchange() {} - /** * Serialize a Server Key Exchange message */ diff --git a/src/lib/tls/tls_blocking.h b/src/lib/tls/tls_blocking.h index 96928f425..d73d723d2 100644 --- a/src/lib/tls/tls_blocking.h +++ b/src/lib/tls/tls_blocking.h @@ -73,7 +73,7 @@ class BOTAN_DLL Blocking_Client std::vector<X509_Certificate> peer_cert_chain() const { return m_channel.peer_cert_chain(); } - virtual ~Blocking_Client() {} + virtual ~Blocking_Client() = default; protected: /** diff --git a/src/lib/tls/tls_callbacks.cpp b/src/lib/tls/tls_callbacks.cpp index f25f392b3..45d0518eb 100644 --- a/src/lib/tls/tls_callbacks.cpp +++ b/src/lib/tls/tls_callbacks.cpp @@ -13,8 +13,6 @@ namespace Botan { -TLS::Callbacks::~Callbacks() {} - void TLS::Callbacks::tls_inspect_handshake_msg(const Handshake_Message&) { // default is no op diff --git a/src/lib/tls/tls_callbacks.h b/src/lib/tls/tls_callbacks.h index a0b8894ad..b20e60218 100644 --- a/src/lib/tls/tls_callbacks.h +++ b/src/lib/tls/tls_callbacks.h @@ -35,7 +35,7 @@ class Policy; class BOTAN_DLL Callbacks { public: - virtual ~Callbacks(); + virtual ~Callbacks() = default; /** * Mandatory callback: output function diff --git a/src/lib/tls/tls_ciphersuite.h b/src/lib/tls/tls_ciphersuite.h index dd8e27b6f..157b1d234 100644 --- a/src/lib/tls/tls_ciphersuite.h +++ b/src/lib/tls/tls_ciphersuite.h @@ -113,7 +113,7 @@ class BOTAN_DLL Ciphersuite bool operator<(const Ciphersuite& o) const { return ciphersuite_code() < o.ciphersuite_code(); } bool operator<(const uint16_t c) const { return ciphersuite_code() < c; } - Ciphersuite() {} + Ciphersuite() = default; private: diff --git a/src/lib/tls/tls_extensions.h b/src/lib/tls/tls_extensions.h index 38d810c76..9f5d81214 100644 --- a/src/lib/tls/tls_extensions.h +++ b/src/lib/tls/tls_extensions.h @@ -65,7 +65,7 @@ class Extension */ virtual bool empty() const = 0; - virtual ~Extension() {} + virtual ~Extension() = default; }; /** @@ -133,7 +133,7 @@ class Renegotiation_Extension final : public Extension Handshake_Extension_Type type() const override { return static_type(); } - Renegotiation_Extension() {} + Renegotiation_Extension() = default; explicit Renegotiation_Extension(const std::vector<uint8_t>& bits) : m_reneg_data(bits) {} @@ -206,7 +206,7 @@ class Session_Ticket final : public Extension /** * Create empty extension, used by both client and server */ - Session_Ticket() {} + Session_Ticket() = default; /** * Extension with ticket, used by client @@ -369,7 +369,7 @@ class Extended_Master_Secret final : public Extension bool empty() const override { return false; } - Extended_Master_Secret() {} + Extended_Master_Secret() = default; Extended_Master_Secret(TLS_Data_Reader& reader, uint16_t extension_size); }; @@ -389,7 +389,7 @@ class Encrypt_then_MAC final : public Extension bool empty() const override { return false; } - Encrypt_then_MAC() {} + Encrypt_then_MAC() = default; Encrypt_then_MAC(TLS_Data_Reader& reader, uint16_t extension_size); }; @@ -459,13 +459,13 @@ class BOTAN_DLL Extensions void deserialize(TLS_Data_Reader& reader); - Extensions() {} + Extensions() = default; explicit Extensions(TLS_Data_Reader& reader) { deserialize(reader); } private: - Extensions(const Extensions&) {} - Extensions& operator=(const Extensions&) { return (*this); } + Extensions(const Extensions&) = delete; + Extensions& operator=(const Extensions&) = delete; std::map<Handshake_Extension_Type, std::unique_ptr<Extension>> m_extensions; }; diff --git a/src/lib/tls/tls_handshake_io.h b/src/lib/tls/tls_handshake_io.h index a9453abcc..c71de532b 100644 --- a/src/lib/tls/tls_handshake_io.h +++ b/src/lib/tls/tls_handshake_io.h @@ -50,13 +50,13 @@ class Handshake_IO virtual std::pair<Handshake_Type, std::vector<uint8_t>> get_next_record(bool expecting_ccs) = 0; - Handshake_IO() {} + Handshake_IO() = default; Handshake_IO(const Handshake_IO&) = delete; Handshake_IO& operator=(const Handshake_IO&) = delete; - virtual ~Handshake_IO() {} + virtual ~Handshake_IO() = default; }; /** @@ -146,7 +146,7 @@ class Datagram_Handshake_IO final : public Handshake_IO Handshake_Type msg_type, const std::vector<uint8_t>& msg); - class Handshake_Reassembly + class Handshake_Reassembly final { public: void add_fragment(const uint8_t fragment[], @@ -172,13 +172,11 @@ class Datagram_Handshake_IO final : public Handshake_IO std::vector<uint8_t> m_message; }; - struct Message_Info + struct Message_Info final { Message_Info(uint16_t e, Handshake_Type mt, const std::vector<uint8_t>& msg) : epoch(e), msg_type(mt), msg_bits(msg) {} - Message_Info(const Message_Info& other) = default; - Message_Info() : epoch(0xFFFF), msg_type(HANDSHAKE_NONE) {} uint16_t epoch; diff --git a/src/lib/tls/tls_handshake_state.cpp b/src/lib/tls/tls_handshake_state.cpp index 6d46c18ab..d87af7305 100644 --- a/src/lib/tls/tls_handshake_state.cpp +++ b/src/lib/tls/tls_handshake_state.cpp @@ -182,8 +182,6 @@ Handshake_State::Handshake_State(Handshake_IO* io, Callbacks& cb) : { } -Handshake_State::~Handshake_State() {} - void Handshake_State::note_message(const Handshake_Message& msg) { m_callbacks.tls_inspect_handshake_msg(msg); diff --git a/src/lib/tls/tls_handshake_state.h b/src/lib/tls/tls_handshake_state.h index 889f0d101..5851a8fe8 100644 --- a/src/lib/tls/tls_handshake_state.h +++ b/src/lib/tls/tls_handshake_state.h @@ -49,7 +49,7 @@ class Handshake_State public: Handshake_State(Handshake_IO* io, Callbacks& callbacks); - virtual ~Handshake_State(); + virtual ~Handshake_State() = default; Handshake_State(const Handshake_State&) = delete; Handshake_State& operator=(const Handshake_State&) = delete; diff --git a/src/lib/tls/tls_messages.h b/src/lib/tls/tls_messages.h index 5a1f03a06..aaf372447 100644 --- a/src/lib/tls/tls_messages.h +++ b/src/lib/tls/tls_messages.h @@ -20,17 +20,17 @@ #include <string> #include <set> -namespace Botan { - -class Credentials_Manager; +#if defined(BOTAN_HAS_CECPQ1) + #include <botan/cecpq1.h> +#endif #if defined(BOTAN_HAS_SRP6) -class SRP6_Server_Session; + #include <botan/srp6.h> #endif -#if defined(BOTAN_HAS_CECPQ1) -class CECPQ1_key; -#endif +namespace Botan { + +class Credentials_Manager; namespace TLS { @@ -75,10 +75,10 @@ class BOTAN_DLL Client_Hello final : public Handshake_Message const std::string& srp_identifier = "") : m_new_session_version(version), m_hostname(hostname), - m_srp_identifier(srp_identifier) {}; + m_srp_identifier(srp_identifier) {} - const Protocol_Version protocol_version() const { return m_new_session_version; }; - const std::string& hostname() const { return m_hostname; }; + const Protocol_Version protocol_version() const { return m_new_session_version; } + const std::string& hostname() const { return m_hostname; } const std::string& srp_identifier() const { return m_srp_identifier; } private: @@ -267,11 +267,11 @@ class BOTAN_DLL Server_Hello final : public Handshake_Message m_new_session_version(new_session_version), m_ciphersuite(ciphersuite), m_compression(compression), - m_offer_session_ticket(offer_session_ticket) {}; + m_offer_session_ticket(offer_session_ticket) {} - const std::vector<uint8_t>& session_id() const { return m_new_session_id; }; - Protocol_Version protocol_version() const { return m_new_session_version; }; - uint16_t ciphersuite() const { return m_ciphersuite; }; + const std::vector<uint8_t>& session_id() const { return m_new_session_id; } + Protocol_Version protocol_version() const { return m_new_session_version; } + uint16_t ciphersuite() const { return m_ciphersuite; } uint8_t compression() const { return m_compression; } bool offer_session_ticket() const { return m_offer_session_ticket; } @@ -622,7 +622,7 @@ class BOTAN_DLL Server_Key_Exchange final : public Handshake_Message const std::string& sig_alg, Protocol_Version version); - ~Server_Key_Exchange(); + ~Server_Key_Exchange() = default; private: std::vector<uint8_t> serialize() const override; diff --git a/src/lib/tls/tls_policy.h b/src/lib/tls/tls_policy.h index 6f617c673..ad95b7eb5 100644 --- a/src/lib/tls/tls_policy.h +++ b/src/lib/tls/tls_policy.h @@ -122,27 +122,27 @@ class BOTAN_DLL Policy * Allow servers to initiate a new handshake */ virtual bool allow_server_initiated_renegotiation() const; - + /** * Allow TLS v1.0 */ virtual bool allow_tls10() const; - + /** * Allow TLS v1.1 */ virtual bool allow_tls11() const; - + /** * Allow TLS v1.2 */ virtual bool allow_tls12() const; - + /** * Allow DTLS v1.0 */ virtual bool allow_dtls10() const; - + /** * Allow DTLS v1.2 */ @@ -155,14 +155,14 @@ class BOTAN_DLL Policy * Default is currently 1024 (insecure), should be 2048 */ virtual size_t minimum_dh_group_size() const; - + /** * For ECDSA authenticated ciphersuites, the smallest key size the * client will accept. * This policy is currently only enforced on the server by the client. */ virtual size_t minimum_ecdsa_group_size() const; - + /** * Return the minimum ECDH group size we're willing to use * for key exchange @@ -199,7 +199,7 @@ class BOTAN_DLL Policy * (or logging of) the peer's keys. */ virtual void check_peer_key_acceptable(const Public_Key& public_key) const; - + /** * If this function returns false, unknown SRP/PSK identifiers * will be rejected with an unknown_psk_identifier alert as soon @@ -297,7 +297,7 @@ class BOTAN_DLL Policy */ std::string to_string() const; - virtual ~Policy() {} + virtual ~Policy() = default; }; /** @@ -396,7 +396,7 @@ class BOTAN_DLL Datagram_Policy : public Policy public: std::vector<std::string> allowed_macs() const override { return std::vector<std::string>({"AEAD"}); } - + bool allow_tls10() const override { return false; } bool allow_tls11() const override { return false; } bool allow_tls12() const override { return false; } @@ -450,22 +450,22 @@ class BOTAN_DLL Text_Policy : public Policy std::vector<std::string> allowed_ecc_curves() const override { return get_list("ecc_curves", Policy::allowed_ecc_curves()); } - + bool use_ecc_point_compression() const override { return get_bool("use_ecc_point_compression", Policy::use_ecc_point_compression()); } bool allow_tls10() const override { return get_bool("allow_tls10", Policy::allow_tls10()); } - + bool allow_tls11() const override { return get_bool("allow_tls11", Policy::allow_tls11()); } - + bool allow_tls12() const override { return get_bool("allow_tls12", Policy::allow_tls12()); } - + bool allow_dtls10() const override { return get_bool("allow_dtls10", Policy::allow_dtls10()); } - + bool allow_dtls12() const override { return get_bool("allow_dtls12", Policy::allow_dtls12()); } diff --git a/src/lib/tls/tls_record.h b/src/lib/tls/tls_record.h index ebb83c484..782257b41 100644 --- a/src/lib/tls/tls_record.h +++ b/src/lib/tls/tls_record.h @@ -80,7 +80,7 @@ class Record Protocol_Version* protocol_version, Record_Type* type) : m_data(data), m_sequence(sequence), m_protocol_version(protocol_version), - m_type(type), m_size(data.size()) {}; + m_type(type), m_size(data.size()) {} secure_vector<uint8_t>& get_data() { return m_data; } @@ -104,15 +104,15 @@ class Record_Message { public: Record_Message(const uint8_t* data, size_t size) - : m_type(0), m_sequence(0), m_data(data), m_size(size) {}; + : m_type(0), m_sequence(0), m_data(data), m_size(size) {} Record_Message(uint8_t type, uint64_t sequence, const uint8_t* data, size_t size) : m_type(type), m_sequence(sequence), m_data(data), - m_size(size) {}; + m_size(size) {} - uint8_t& get_type() { return m_type; }; - uint64_t& get_sequence() { return m_sequence; }; - const uint8_t* get_data() { return m_data; }; - size_t& get_size() { return m_size; }; + uint8_t& get_type() { return m_type; } + uint64_t& get_sequence() { return m_sequence; } + const uint8_t* get_data() { return m_data; } + size_t& get_size() { return m_size; } private: uint8_t m_type; @@ -127,16 +127,16 @@ class Record_Raw_Input Record_Raw_Input(const uint8_t* data, size_t size, size_t& consumed, bool is_datagram) : m_data(data), m_size(size), m_consumed(consumed), - m_is_datagram(is_datagram) {}; + m_is_datagram(is_datagram) {} - const uint8_t*& get_data() { return m_data; }; + const uint8_t*& get_data() { return m_data; } - size_t& get_size() { return m_size; }; + size_t& get_size() { return m_size; } - size_t& get_consumed() { return m_consumed; }; + size_t& get_consumed() { return m_consumed; } void set_consumed(size_t consumed) { m_consumed = consumed; } - bool is_datagram() { return m_is_datagram; }; + bool is_datagram() { return m_is_datagram; } private: const uint8_t* m_data; diff --git a/src/lib/tls/tls_session_key.h b/src/lib/tls/tls_session_key.h index c2c082d4a..97ad3106d 100644 --- a/src/lib/tls/tls_session_key.h +++ b/src/lib/tls/tls_session_key.h @@ -57,7 +57,7 @@ class Session_Keys */ const secure_vector<uint8_t>& master_secret() const { return m_master_sec; } - Session_Keys() {} + Session_Keys() = default; /** * @param state state the handshake state diff --git a/src/lib/utils/data_src.h b/src/lib/utils/data_src.h index 5e062d3d7..81840e913 100644 --- a/src/lib/utils/data_src.h +++ b/src/lib/utils/data_src.h @@ -86,8 +86,8 @@ class BOTAN_DLL DataSource */ virtual size_t get_bytes_read() const = 0; - DataSource() {} - virtual ~DataSource() {} + DataSource() = default; + virtual ~DataSource() = default; DataSource& operator=(const DataSource&) = delete; DataSource(const DataSource&) = delete; }; diff --git a/src/lib/utils/info.txt b/src/lib/utils/info.txt index da84b64b4..193145c5d 100644 --- a/src/lib/utils/info.txt +++ b/src/lib/utils/info.txt @@ -22,6 +22,7 @@ parsing.h rotate.h types.h version.h +stl_compatibility.h </header:public> <header:internal> diff --git a/src/lib/utils/stl_compatibility.h b/src/lib/utils/stl_compatibility.h new file mode 100644 index 000000000..178afed52 --- /dev/null +++ b/src/lib/utils/stl_compatibility.h @@ -0,0 +1,77 @@ +/* +* STL standards compatibility functions +* (C) 2017 Tomasz Frydrych +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_STL_COMPATIBILITY_H__ +#define BOTAN_STL_COMPATIBILITY_H__ + +#include <memory> + +#if __cplusplus < 201402L +#include <cstddef> +#include <type_traits> +#include <utility> +#endif + +namespace Botan +{ +/* +* std::make_unique functionality similar as we have in C++14. +* C++11 version based on proposal for C++14 implemenatation by Stephan T. Lavavej +* source: https://isocpp.org/files/papers/N3656.txt +*/ +#if __cplusplus >= 201402L +template <typename T, typename ... Args> +constexpr auto make_unique(Args&&... args) + { + return std::make_unique<T>(std::forward<Args>(args)...); + } + +template<class T> +constexpr auto make_unique(std::size_t size) + { + return std::make_unique<T>(size); + } + +#else +namespace stlCompatibilityDetails +{ +template<class T> struct _Unique_if + { + typedef std::unique_ptr<T> _Single_object; + }; + +template<class T> struct _Unique_if<T[]> + { + typedef std::unique_ptr<T[]> _Unknown_bound; + }; + +template<class T, size_t N> struct _Unique_if<T[N]> + { + typedef void _Known_bound; + }; +} // namespace stlCompatibilityDetails + +template<class T, class... Args> +typename stlCompatibilityDetails::_Unique_if<T>::_Single_object make_unique(Args&&... args) + { + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); + } + +template<class T> +typename stlCompatibilityDetails::_Unique_if<T>::_Unknown_bound make_unique(size_t n) + { + typedef typename std::remove_extent<T>::type U; + return std::unique_ptr<T>(new U[n]()); + } + +template<class T, class... Args> +typename stlCompatibilityDetails::_Unique_if<T>::_Known_bound make_unique(Args&&...) = delete; + +#endif + +} // namespace Botan +#endif diff --git a/src/lib/x509/certstor.h b/src/lib/x509/certstor.h index d8630a192..2b68147f0 100644 --- a/src/lib/x509/certstor.h +++ b/src/lib/x509/certstor.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL Certificate_Store { public: - virtual ~Certificate_Store() {} + virtual ~Certificate_Store() = default; /** * Find a certificate by Subject DN and (optionally) key identifier @@ -88,7 +88,7 @@ class BOTAN_DLL Certificate_Store_In_Memory : public Certificate_Store /** * Create an empty store. */ - Certificate_Store_In_Memory() {} + Certificate_Store_In_Memory() = default; /** * Add a certificate to the store. diff --git a/src/lib/x509/name_constraint.h b/src/lib/x509/name_constraint.h index 43d7fcbcb..68551dc32 100644 --- a/src/lib/x509/name_constraint.h +++ b/src/lib/x509/name_constraint.h @@ -37,7 +37,7 @@ class BOTAN_DLL GeneralName : public ASN1_Object /** * Creates an empty GeneralName. */ - GeneralName() : m_type(), m_name() {} + GeneralName() = default; /** * Creates a new GeneralName for its string format. diff --git a/src/lib/x509/ocsp.h b/src/lib/x509/ocsp.h index 881eee124..42c45e406 100644 --- a/src/lib/x509/ocsp.h +++ b/src/lib/x509/ocsp.h @@ -72,7 +72,7 @@ class BOTAN_DLL Response /** * Creates an empty OCSP response. */ - Response() {} + Response() = default; /** * Parses an OCSP response. diff --git a/src/lib/x509/ocsp_types.h b/src/lib/x509/ocsp_types.h index be7ae716a..c69d306ed 100644 --- a/src/lib/x509/ocsp_types.h +++ b/src/lib/x509/ocsp_types.h @@ -19,7 +19,7 @@ namespace OCSP { class BOTAN_DLL CertID final : public ASN1_Object { public: - CertID() {} + CertID() = default; CertID(const X509_Certificate& issuer, const BigInt& subject_serial); diff --git a/src/lib/x509/x509_ext.cpp b/src/lib/x509/x509_ext.cpp index 965c8efcf..203a81cb9 100644 --- a/src/lib/x509/x509_ext.cpp +++ b/src/lib/x509/x509_ext.cpp @@ -658,7 +658,7 @@ namespace { class Policy_Information : public ASN1_Object { public: - Policy_Information() {} + Policy_Information() = default; explicit Policy_Information(const OID& oid) : m_oid(oid) {} const OID& oid() const { return m_oid; } diff --git a/src/lib/x509/x509_ext.h b/src/lib/x509/x509_ext.h index f00535eb2..c6cfbaee0 100644 --- a/src/lib/x509/x509_ext.h +++ b/src/lib/x509/x509_ext.h @@ -72,7 +72,7 @@ class BOTAN_DLL Certificate_Extension std::vector<std::set<Certificate_Status_Code>>& cert_status, size_t pos); - virtual ~Certificate_Extension() {} + virtual ~Certificate_Extension() = default; protected: friend class Extensions; virtual bool should_encode() const { return true; } @@ -236,7 +236,7 @@ class BOTAN_DLL Subject_Key_ID final : public Certificate_Extension Subject_Key_ID* copy() const override { return new Subject_Key_ID(m_key_id); } - Subject_Key_ID() {} + Subject_Key_ID() = default; explicit Subject_Key_ID(const std::vector<uint8_t>&); std::vector<uint8_t> get_key_id() const { return m_key_id; } @@ -261,7 +261,7 @@ class BOTAN_DLL Authority_Key_ID final : public Certificate_Extension Authority_Key_ID* copy() const override { return new Authority_Key_ID(m_key_id); } - Authority_Key_ID() {} + Authority_Key_ID() = default; explicit Authority_Key_ID(const std::vector<uint8_t>& k) : m_key_id(k) {} std::vector<uint8_t> get_key_id() const { return m_key_id; } @@ -336,7 +336,7 @@ class BOTAN_DLL Extended_Key_Usage final : public Certificate_Extension Extended_Key_Usage* copy() const override { return new Extended_Key_Usage(m_oids); } - Extended_Key_Usage() {} + Extended_Key_Usage() = default; explicit Extended_Key_Usage(const std::vector<OID>& o) : m_oids(o) {} std::vector<OID> get_oids() const { return m_oids; } @@ -362,7 +362,7 @@ class BOTAN_DLL Name_Constraints : public Certificate_Extension Name_Constraints* copy() const override { return new Name_Constraints(m_name_constraints); } - Name_Constraints() {} + Name_Constraints() = default; Name_Constraints(const NameConstraints &nc) : m_name_constraints(nc) {} void validate(const X509_Certificate& subject, const X509_Certificate& issuer, @@ -391,7 +391,7 @@ class BOTAN_DLL Certificate_Policies final : public Certificate_Extension Certificate_Policies* copy() const override { return new Certificate_Policies(m_oids); } - Certificate_Policies() {} + Certificate_Policies() = default; explicit Certificate_Policies(const std::vector<OID>& o) : m_oids(o) {} std::vector<OID> get_oids() const { return m_oids; } @@ -414,7 +414,7 @@ class BOTAN_DLL Authority_Information_Access final : public Certificate_Extensio Authority_Information_Access* copy() const override { return new Authority_Information_Access(m_ocsp_responder); } - Authority_Information_Access() {} + Authority_Information_Access() = default; explicit Authority_Information_Access(const std::string& ocsp) : m_ocsp_responder(ocsp) {} @@ -502,7 +502,7 @@ class BOTAN_DLL CRL_Distribution_Points final : public Certificate_Extension CRL_Distribution_Points* copy() const override { return new CRL_Distribution_Points(m_distribution_points); } - CRL_Distribution_Points() {} + CRL_Distribution_Points() = default; explicit CRL_Distribution_Points(const std::vector<Distribution_Point>& points) : m_distribution_points(points) {} @@ -537,12 +537,12 @@ class BOTAN_DLL Unknown_Critical_Extension final : public Certificate_Extension { return new Unknown_Critical_Extension(m_oid); } OID oid_of() const override - { return m_oid; }; + { return m_oid; } void validate(const X509_Certificate&, const X509_Certificate&, - const std::vector<std::shared_ptr<const X509_Certificate>>&, - std::vector<std::set<Certificate_Status_Code>>& cert_status, - size_t pos) override + const std::vector<std::shared_ptr<const X509_Certificate>>&, + std::vector<std::set<Certificate_Status_Code>>& cert_status, + size_t pos) override { cert_status.at(pos).insert(Certificate_Status_Code::UNKNOWN_CRITICAL_EXTENSION); } diff --git a/src/lib/x509/x509_obj.h b/src/lib/x509/x509_obj.h index c2bf7b9c2..522667397 100644 --- a/src/lib/x509/x509_obj.h +++ b/src/lib/x509/x509_obj.h @@ -93,7 +93,9 @@ class BOTAN_DLL X509_Object : public ASN1_Object */ std::string PEM_encode() const; - virtual ~X509_Object() {} + X509_Object(const X509_Object&) = default; + X509_Object& operator=(const X509_Object&) = default; + virtual ~X509_Object() = default; protected: X509_Object(DataSource& src, const std::string& pem_labels); X509_Object(const std::vector<uint8_t>& vec, const std::string& labels); @@ -103,7 +105,7 @@ class BOTAN_DLL X509_Object : public ASN1_Object #endif void do_decode(); - X509_Object() {} + X509_Object() = default; AlgorithmIdentifier m_sig_algo; std::vector<uint8_t> m_tbs_bits, m_sig; private: diff --git a/src/lib/x509/x509cert.h b/src/lib/x509/x509cert.h index 52b22d618..ceadf88c5 100644 --- a/src/lib/x509/x509cert.h +++ b/src/lib/x509/x509cert.h @@ -164,9 +164,9 @@ class BOTAN_DLL X509_Certificate : public X509_Object bool is_CA_cert() const; /** - * Returns true if the specified @param usage is set in the key usage extension + * Returns true if the specified @param usage is set in the key usage extension * or if no key usage constraints are set at all. - * To check if a certain key constraint is set in the certificate + * To check if a certain key constraint is set in the certificate * use @see X509_Certificate#has_constraints. */ bool allowed_usage(Key_Constraints usage) const; @@ -188,7 +188,7 @@ class BOTAN_DLL X509_Certificate : public X509_Object /// Returns true if the specified @param constraints are included in the key usage extension. bool has_constraints(Key_Constraints constraints) const; - + /** * Returns true if and only if @param ex_constraint (referring to an extended key * constraint, eg "PKIX.ServerAuth") is included in the extended @@ -314,7 +314,7 @@ class BOTAN_DLL X509_Certificate : public X509_Object friend class X509_CA; friend class BER_Decoder; - X509_Certificate() {} + X509_Certificate() = default; Data_Store m_subject, m_issuer; bool m_self_signed; diff --git a/src/lib/x509/x509path.cpp b/src/lib/x509/x509path.cpp index eeb75b279..8521e51a7 100644 --- a/src/lib/x509/x509path.cpp +++ b/src/lib/x509/x509path.cpp @@ -269,7 +269,6 @@ PKIX::check_ocsp_online(const std::vector<std::shared_ptr<const X509_Certificate { ocsp_response_futures.emplace_back(std::async(std::launch::deferred, [&]() -> std::shared_ptr<const OCSP::Response> { throw Exception("No OCSP responder URL set for this certificate"); - return std::shared_ptr<const OCSP::Response>(); })); } else @@ -358,7 +357,6 @@ PKIX::check_crl_online(const std::vector<std::shared_ptr<const X509_Certificate> // Avoid creating a thread for this case future_crls.emplace_back(std::async(std::launch::deferred, [&]() -> std::shared_ptr<const X509_CRL> { throw Exception("No CRL distribution point for this certificate"); - return std::shared_ptr<const X509_CRL>(); })); } else diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp index 4db0607f2..c84dfd224 100644 --- a/src/tests/test_ffi.cpp +++ b/src/tests/test_ffi.cpp @@ -387,10 +387,27 @@ class FFI_Unit_Tests : public Test std::vector<Test::Result> results; results.push_back(ffi_test_mp(rng)); + results.push_back(ffi_test_block_ciphers()); + +#if defined(BOTAN_HAS_RSA) results.push_back(ffi_test_rsa(rng)); +#endif + +#if defined(BOTAN_HAS_DSA) + results.push_back(ffi_test_dsa(rng)); +#endif + +#if defined(BOTAN_HAS_ECDSA) results.push_back(ffi_test_ecdsa(rng)); +#endif + +#if defined(BOTAN_HAS_ECDH) results.push_back(ffi_test_ecdh(rng)); +#endif + +#if defined(BOTAN_HAS_MCELIECE) results.push_back(ffi_test_mceliece(rng)); +#endif TEST_FFI_OK(botan_rng_destroy, (rng)); @@ -399,6 +416,42 @@ class FFI_Unit_Tests : public Test } private: + Test::Result ffi_test_block_ciphers() + { + Test::Result result("FFI block ciphers"); + + botan_block_cipher_t cipher; + + if(TEST_FFI_OK(botan_block_cipher_init, (&cipher, "AES-128"))) + { + const std::vector<uint8_t> zero16(16, 0); + std::vector<uint8_t> block(16, 0); + + TEST_FFI_OK(botan_block_cipher_clear, (cipher)); + + TEST_FFI_RC(16, botan_block_cipher_block_size, (cipher)); + + TEST_FFI_OK(botan_block_cipher_set_key, (cipher, zero16.data(), zero16.size())); + + TEST_FFI_OK(botan_block_cipher_encrypt_blocks, (cipher, block.data(), block.data(), 1)); + result.test_eq("AES-128 encryption works", block, "66E94BD4EF8A2C3B884CFA59CA342B2E"); + + TEST_FFI_OK(botan_block_cipher_encrypt_blocks, (cipher, block.data(), block.data(), 1)); + result.test_eq("AES-128 encryption works", block, "F795BD4A52E29ED713D313FA20E98DBC"); + + TEST_FFI_OK(botan_block_cipher_decrypt_blocks, (cipher, block.data(), block.data(), 1)); + result.test_eq("AES-128 decryption works", block, "66E94BD4EF8A2C3B884CFA59CA342B2E"); + + TEST_FFI_OK(botan_block_cipher_decrypt_blocks, (cipher, block.data(), block.data(), 1)); + result.test_eq("AES-128 decryption works", block, "00000000000000000000000000000000"); + + TEST_FFI_OK(botan_block_cipher_clear, (cipher)); + botan_block_cipher_destroy(cipher); + } + + return result; + } + Test::Result ffi_test_mp(botan_rng_t rng) { Test::Result result("FFI MP"); @@ -622,6 +675,11 @@ class FFI_Unit_Tests : public Test pubkey.resize(pubkey_len); TEST_FFI_OK(botan_pubkey_export, (pub, pubkey.data(), &pubkey_len, BOTAN_PRIVKEY_EXPORT_FLAG_PEM)); + // reimport exported public key + botan_pubkey_t pub_copy; + TEST_FFI_OK(botan_pubkey_load, (&pub_copy, pubkey.data(), pubkey_len)); + TEST_FFI_OK(botan_pubkey_check_key, (pub_copy, rng, 0)); + // export private key std::vector<uint8_t> privkey; size_t privkey_len = 0; @@ -678,6 +736,7 @@ class FFI_Unit_Tests : public Test Test::Result result("FFI RSA"); botan_privkey_t priv; + if(TEST_FFI_OK(botan_privkey_create_rsa, (&priv, rng, 1024))) { TEST_FFI_OK(botan_privkey_check_key, (priv, rng, 0)); @@ -798,6 +857,112 @@ class FFI_Unit_Tests : public Test return result; } + Test::Result ffi_test_dsa(botan_rng_t rng) + { + Test::Result result("FFI DSA"); + + botan_privkey_t priv; + + if(TEST_FFI_OK(botan_privkey_create, (&priv, "DSA", "dsa/jce/1024", rng))) + { + TEST_FFI_OK(botan_privkey_check_key, (priv, rng, 0)); + + botan_pubkey_t pub; + TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv)); + TEST_FFI_OK(botan_pubkey_check_key, (pub, rng, 0)); + + ffi_test_pubkey_export(result, pub, priv, rng); + + botan_mp_t p, q, g, x, y; + botan_mp_init(&p); + botan_mp_init(&q); + botan_mp_init(&g); + botan_mp_init(&x); + botan_mp_init(&y); + + TEST_FFI_OK(botan_privkey_dsa_get_x, (x, priv)); + TEST_FFI_OK(botan_pubkey_dsa_get_g, (g, pub)); + TEST_FFI_OK(botan_pubkey_dsa_get_p, (p, pub)); + TEST_FFI_OK(botan_pubkey_dsa_get_q, (q, pub)); + TEST_FFI_OK(botan_pubkey_dsa_get_y, (y, pub)); + + botan_mp_t cmp; + botan_mp_init(&cmp); + TEST_FFI_OK(botan_privkey_get_field, (cmp, priv, "x")); + TEST_FFI_RC(1, botan_mp_equal, (cmp, x)); + TEST_FFI_OK(botan_privkey_get_field, (cmp, priv, "y")); + TEST_FFI_RC(1, botan_mp_equal, (cmp, y)); + TEST_FFI_OK(botan_privkey_get_field, (cmp, priv, "p")); + TEST_FFI_RC(1, botan_mp_equal, (cmp, p)); + botan_mp_destroy(cmp); + + botan_privkey_t loaded_privkey; + TEST_FFI_OK(botan_privkey_load_dsa, (&loaded_privkey, p, q, g, x)); + TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey, rng, 0)); + + botan_pubkey_t loaded_pubkey; + TEST_FFI_OK(botan_pubkey_load_dsa, (&loaded_pubkey, p, q, g, y)); + TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey, rng, 0)); + + botan_mp_destroy(p); + botan_mp_destroy(q); + botan_mp_destroy(g); + botan_mp_destroy(y); + botan_mp_destroy(x); + + botan_pk_op_sign_t signer; + + std::vector<uint8_t> message(6, 6); + std::vector<uint8_t> signature(20*2); + + if(TEST_FFI_OK(botan_pk_op_sign_create, (&signer, loaded_privkey, "EMSA1(SHA-256)", 0))) + { + // TODO: break input into multiple calls to update + TEST_FFI_OK(botan_pk_op_sign_update, (signer, message.data(), message.size())); + + signature.resize(20*2); // TODO: no way to derive this from API + size_t sig_len = signature.size(); + TEST_FFI_OK(botan_pk_op_sign_finish, (signer, rng, signature.data(), &sig_len)); + signature.resize(sig_len); + + TEST_FFI_OK(botan_pk_op_sign_destroy, (signer)); + } + + botan_pk_op_verify_t verifier; + + if(TEST_FFI_OK(botan_pk_op_verify_create, (&verifier, pub, "EMSA1(SHA-256)", 0))) + { + TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size())); + TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size())); + + // TODO: randomize this + signature[0] ^= 1; + TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size())); + TEST_FFI_FAIL("bad signature", botan_pk_op_verify_finish, (verifier, signature.data(), signature.size())); + + message[0] ^= 1; + TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size())); + TEST_FFI_FAIL("bad signature", botan_pk_op_verify_finish, (verifier, signature.data(), signature.size())); + + signature[0] ^= 1; + TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size())); + TEST_FFI_FAIL("bad signature", botan_pk_op_verify_finish, (verifier, signature.data(), signature.size())); + + message[0] ^= 1; + TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size())); + TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size())); + + TEST_FFI_OK(botan_pk_op_verify_destroy, (verifier)); + } + + TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey)); + TEST_FFI_OK(botan_pubkey_destroy, (pub)); + TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey)); + TEST_FFI_OK(botan_privkey_destroy, (priv)); + } + + return result; + } Test::Result ffi_test_ecdsa(botan_rng_t rng) { Test::Result result("FFI ECDSA"); diff --git a/src/tests/test_pkcs11_high_level.cpp b/src/tests/test_pkcs11_high_level.cpp index 5ff092a74..5944a2b1d 100644 --- a/src/tests/test_pkcs11_high_level.cpp +++ b/src/tests/test_pkcs11_high_level.cpp @@ -80,9 +80,6 @@ class TestSession m_session->login(UserType::User, PIN_SECVEC); } } - - inline Module& module() const { return *m_module; } - inline Slot& slot() const { return *m_slot; } inline Session& session() const { return *m_session; } private: diff --git a/src/tests/test_rng.cpp b/src/tests/test_rng.cpp index 0ebc091e2..d057f0e55 100644 --- a/src/tests/test_rng.cpp +++ b/src/tests/test_rng.cpp @@ -105,7 +105,7 @@ class HMAC_DRBG_Unit_Tests : public Test class Request_Counting_RNG : public Botan::RandomNumberGenerator { public: - Request_Counting_RNG() : m_randomize_count(0) {}; + Request_Counting_RNG() : m_randomize_count(0) {} bool is_seeded() const override { return true; } @@ -144,16 +144,18 @@ class HMAC_DRBG_Unit_Tests : public Test Request_Counting_RNG counting_rng; Botan::HMAC_DRBG rng(std::move(mac), counting_rng, Botan::Entropy_Sources::global_sources(), 2); Botan::secure_vector<uint8_t> seed_input( - {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}); + {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, + 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}); Botan::secure_vector<uint8_t> output_after_initialization( - {0x26,0x06,0x95,0xF4,0xB8,0x96,0x0D,0x0B,0x27,0x4E,0xA2,0x9E,0x8D,0x2B,0x5A,0x35}); + {0x48,0xD3,0xB4,0x5A,0xAB,0x65,0xEF,0x92,0xCC,0xFC,0xB9,0x42,0x7E,0xF2,0x0C,0x90, + 0x29,0x70,0x65,0xEC,0xC1,0xB8,0xA5,0x25,0xBF,0xE4,0xDC,0x6F,0xF3,0x6D,0x0E,0x38}); Botan::secure_vector<uint8_t> output_without_reseed( {0xC4,0x90,0x04,0x5B,0x35,0x4F,0x50,0x09,0x68,0x45,0xF0,0x4B,0x11,0x03,0x58,0xF0}); result.test_eq("is_seeded",rng.is_seeded(),false); rng.initialize_with(seed_input.data(), seed_input.size()); - Botan::secure_vector<uint8_t> out(16); + Botan::secure_vector<uint8_t> out(32); rng.randomize(out.data(), out.size()); result.test_eq("underlying RNG calls", counting_rng.randomize_count(), size_t(0)); @@ -337,8 +339,8 @@ class HMAC_DRBG_Unit_Tests : public Test // make sure the nonce has at least 1/2*security_strength bits - // SHA-256 -> 128 bits security strength - for( auto nonce_size : { 0, 4, 15, 16, 17, 32 } ) + // SHA-256 -> 256 bits security strength + for( auto nonce_size : { 0, 4, 8, 16, 31, 32, 34 } ) { if(!mac) { @@ -350,15 +352,15 @@ class HMAC_DRBG_Unit_Tests : public Test std::vector<uint8_t> nonce(nonce_size); rng.initialize_with(nonce.data(), nonce.size()); - if(nonce_size < 16) + if(nonce_size < 32) { result.test_eq("not seeded", rng.is_seeded(), false); - result.test_throws("invalid nonce size", [&rng, &nonce] () { rng.random_vec(16); }); + result.test_throws("invalid nonce size", [&rng, &nonce] () { rng.random_vec(32); }); } else { result.test_eq("is seeded", rng.is_seeded(), true); - rng.random_vec(16); + rng.random_vec(32); } } @@ -487,6 +489,31 @@ class HMAC_DRBG_Unit_Tests : public Test return result; } + Test::Result test_security_level() + { + Test::Result result("HMAC_DRBG Security Level"); + + std::vector<std::string> approved_hash_fns { "SHA-160", "SHA-224", "SHA-256", "SHA-512/256", "SHA-384", "SHA-512" }; + std::vector<uint32_t> security_strengths { 128, 192, 256, 256, 256, 256 }; + + for( size_t i = 0; i < approved_hash_fns.size(); ++i ) + { + std::string hash_fn = approved_hash_fns[i]; + std::string mac_name = "HMAC(" + hash_fn + ")"; + auto mac = Botan::MessageAuthenticationCode::create(mac_name); + if(!mac) + { + result.note_missing(mac_name); + continue; + } + + Botan::HMAC_DRBG rng(std::move(mac)); + result.test_eq(hash_fn + " security level", rng.security_level(), security_strengths[i]); + } + + return result; + } + Test::Result test_randomize_with_ts_input() { Test::Result result("HMAC_DRBG Randomize With Timestamp Input"); @@ -536,6 +563,7 @@ class HMAC_DRBG_Unit_Tests : public Test results.push_back(test_prediction_resistance()); results.push_back(test_fork_safety()); results.push_back(test_randomize_with_ts_input()); + results.push_back(test_security_level()); return results; } }; diff --git a/src/tests/test_rng.h b/src/tests/test_rng.h index 90ade91c4..9086aaf12 100644 --- a/src/tests/test_rng.h +++ b/src/tests/test_rng.h @@ -53,7 +53,7 @@ class Fixed_Output_RNG : public Botan::RandomNumberGenerator std::string name() const override { return "Fixed_Output_RNG"; } - void clear() throw() override {} + void clear() BOTAN_NOEXCEPT override {} explicit Fixed_Output_RNG(const std::vector<uint8_t>& in) { @@ -66,7 +66,7 @@ class Fixed_Output_RNG : public Botan::RandomNumberGenerator m_buf.insert(m_buf.end(), in.begin(), in.end()); } - Fixed_Output_RNG() {} + Fixed_Output_RNG() = default; protected: size_t remaining() const { return m_buf.size(); } diff --git a/src/tests/tests.h b/src/tests/tests.h index 81243be58..f90e0037b 100644 --- a/src/tests/tests.h +++ b/src/tests/tests.h @@ -298,7 +298,7 @@ class Test } bool test_throws(const std::string& what, std::function<void ()> fn); - + bool test_throws(const std::string& what, const std::string& expected, std::function<void ()> fn); @@ -323,7 +323,7 @@ class Test }; virtual std::vector<Test::Result> run() = 0; - virtual ~Test() {} + virtual ~Test() = default; static std::vector<Test::Result> run_test(const std::string& what, bool fail_if_missing); diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp index 77aebce93..28152e624 100644 --- a/src/tests/unit_tls.cpp +++ b/src/tests/unit_tls.cpp @@ -132,6 +132,8 @@ class Credentials_Manager_Test : public Botan::Credentials_Manager chain.push_back(*m_dsa_ca); break; } +#else + BOTAN_UNUSED(context); #endif } } diff --git a/src/tests/unit_x509.cpp b/src/tests/unit_x509.cpp index 61b1dd4c7..981897ab0 100644 --- a/src/tests/unit_x509.cpp +++ b/src/tests/unit_x509.cpp @@ -802,7 +802,7 @@ Test::Result test_valid_constraints(const std::string& pk_algo) class String_Extension : public Botan::Certificate_Extension { public: - String_Extension() : m_contents() {} + String_Extension() = default; String_Extension(const std::string& val) : m_contents(val) {} std::string value() const { return m_contents; } |