Initial commit: CCU621_M firmware project with BLE debug link support.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
libmbed*
|
||||
*.sln
|
||||
*.vcxproj
|
||||
|
||||
###START_GENERATED_FILES###
|
||||
/error.c
|
||||
/mbedtls_config_check_before.h
|
||||
/mbedtls_config_check_final.h
|
||||
/mbedtls_config_check_user.h
|
||||
/version_features.c
|
||||
/ssl_debug_helpers_generated.c
|
||||
###END_GENERATED_FILES###
|
||||
+376
@@ -0,0 +1,376 @@
|
||||
set(src_x509
|
||||
error.c
|
||||
mbedtls_config.c
|
||||
pkcs7.c
|
||||
x509.c
|
||||
x509_create.c
|
||||
x509_crl.c
|
||||
x509_crt.c
|
||||
x509_csr.c
|
||||
x509_oid.c
|
||||
x509write.c
|
||||
x509write_crt.c
|
||||
x509write_csr.c
|
||||
)
|
||||
|
||||
set(src_tls
|
||||
debug.c
|
||||
mps_reader.c
|
||||
mps_trace.c
|
||||
net_sockets.c
|
||||
ssl_cache.c
|
||||
ssl_ciphersuites.c
|
||||
ssl_client.c
|
||||
ssl_cookie.c
|
||||
ssl_debug_helpers_generated.c
|
||||
ssl_msg.c
|
||||
ssl_ticket.c
|
||||
ssl_tls.c
|
||||
ssl_tls12_client.c
|
||||
ssl_tls12_server.c
|
||||
ssl_tls13_keys.c
|
||||
ssl_tls13_server.c
|
||||
ssl_tls13_client.c
|
||||
ssl_tls13_generic.c
|
||||
timing.c
|
||||
version.c
|
||||
version_features.c
|
||||
)
|
||||
|
||||
if(GEN_FILES)
|
||||
find_package(Perl REQUIRED)
|
||||
|
||||
file(GLOB crypto_error_headers ${CMAKE_CURRENT_SOURCE_DIR}/include/mbedtls/*.h)
|
||||
file(GLOB tls_error_headers ${MBEDTLS_DIR}/include/mbedtls/*.h)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CMAKE_CURRENT_BINARY_DIR}/error.c
|
||||
COMMAND
|
||||
${PERL_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/generate_errors.pl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../tf-psa-crypto/drivers/builtin/include/mbedtls
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../include/mbedtls
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/data_files
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${TF_PSA_CRYPTO_DRIVERS_BUILTIN_SRC_DIR}/error.c
|
||||
DEPENDS
|
||||
${MBEDTLS_DIR}/scripts/generate_errors.pl
|
||||
${crypto_error_headers}
|
||||
${tls_error_headers}
|
||||
${MBEDTLS_DIR}/scripts/data_files/error.fmt
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version_features.c
|
||||
COMMAND
|
||||
${PERL_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/generate_features.pl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../include/mbedtls
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/data_files
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version_features.c
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/generate_features.pl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../include/mbedtls/mbedtls_config.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/data_files/version_features.fmt
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${MBEDTLS_PYTHON_EXECUTABLE}
|
||||
${MBEDTLS_DIR}/scripts/generate_config_checks.py
|
||||
--list-for-cmake "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
OUTPUT_VARIABLE
|
||||
MBEDTLS_GENERATED_CONFIG_CHECKS_HEADERS)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${MBEDTLS_GENERATED_CONFIG_CHECKS_HEADERS}
|
||||
COMMAND
|
||||
${MBEDTLS_PYTHON_EXECUTABLE}
|
||||
${MBEDTLS_DIR}/scripts/generate_config_checks.py
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS
|
||||
${MBEDTLS_DIR}/scripts/generate_config_checks.py
|
||||
${MBEDTLS_FRAMEWORK_DIR}/scripts/mbedtls_framework/config_checks_generator.py
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ssl_debug_helpers_generated.c
|
||||
COMMAND
|
||||
${MBEDTLS_PYTHON_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../framework/scripts/generate_ssl_debug_helpers.py
|
||||
--mbedtls-root ${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../framework/scripts/generate_ssl_debug_helpers.py
|
||||
${tls_error_headers}
|
||||
)
|
||||
|
||||
add_custom_target(${MBEDTLS_TARGET_PREFIX}libmbedx509_generated_files_target
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/error.c
|
||||
${MBEDTLS_GENERATED_CONFIG_CHECKS_HEADERS}
|
||||
)
|
||||
|
||||
add_custom_target(${MBEDTLS_TARGET_PREFIX}libmbedtls_generated_files_target
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ssl_debug_helpers_generated.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version_features.c
|
||||
)
|
||||
|
||||
# List generated headers as sources explicitly. Normally CMake finds
|
||||
# headers by tracing include directives, but if that happens before the
|
||||
# generated headers are generated, this process doesn't find them.
|
||||
list(APPEND src_x509
|
||||
${MBEDTLS_GENERATED_CONFIG_CHECKS_HEADERS}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(LIBS_C_FLAGS -Wmissing-declarations)
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
if(CMAKE_COMPILER_IS_CLANG)
|
||||
set(LIBS_C_FLAGS -Wmissing-declarations -Wdocumentation -Wno-documentation-deprecated-sync -Wunreachable-code)
|
||||
endif(CMAKE_COMPILER_IS_CLANG)
|
||||
|
||||
if(CMAKE_COMPILER_IS_MSVC)
|
||||
option(MSVC_STATIC_RUNTIME "Build the libraries with /MT compiler flag" OFF)
|
||||
if(MSVC_STATIC_RUNTIME)
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_C_FLAGS_CHECK)
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang")
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
endif()
|
||||
|
||||
if(HAIKU)
|
||||
set(libs ${libs} network)
|
||||
endif(HAIKU)
|
||||
|
||||
if(LINK_WITH_PTHREAD)
|
||||
set(libs ${libs} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
if (NOT USE_STATIC_MBEDTLS_LIBRARY AND NOT USE_SHARED_MBEDTLS_LIBRARY)
|
||||
message(FATAL_ERROR "Need to choose static or shared mbedtls build!")
|
||||
endif(NOT USE_STATIC_MBEDTLS_LIBRARY AND NOT USE_SHARED_MBEDTLS_LIBRARY)
|
||||
|
||||
set(mbedtls_target "${MBEDTLS_TARGET_PREFIX}mbedtls")
|
||||
set(mbedx509_target "${MBEDTLS_TARGET_PREFIX}mbedx509")
|
||||
|
||||
set(mbedtls_target ${mbedtls_target} PARENT_SCOPE)
|
||||
set(mbedx509_target ${mbedx509_target} PARENT_SCOPE)
|
||||
|
||||
if (USE_STATIC_MBEDTLS_LIBRARY)
|
||||
set(mbedtls_static_target ${mbedtls_target})
|
||||
set(mbedx509_static_target ${mbedx509_target})
|
||||
endif()
|
||||
|
||||
set(target_libraries ${mbedx509_target} ${mbedtls_target})
|
||||
|
||||
if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
|
||||
string(APPEND mbedtls_static_target "_static")
|
||||
string(APPEND mbedx509_static_target "_static")
|
||||
|
||||
list(APPEND target_libraries
|
||||
${mbedx509_static_target}
|
||||
${mbedtls_static_target})
|
||||
endif()
|
||||
|
||||
if(USE_STATIC_MBEDTLS_LIBRARY)
|
||||
add_library(${mbedx509_static_target} STATIC ${src_x509})
|
||||
set_base_compile_options(${mbedx509_static_target})
|
||||
target_compile_options(${mbedx509_static_target} PRIVATE ${LIBS_C_FLAGS})
|
||||
set_target_properties(${mbedx509_static_target} PROPERTIES OUTPUT_NAME mbedx509)
|
||||
target_link_libraries(${mbedx509_static_target} PUBLIC ${libs} ${tfpsacrypto_static_target})
|
||||
|
||||
add_library(${mbedtls_static_target} STATIC ${src_tls})
|
||||
set_base_compile_options(${mbedtls_static_target})
|
||||
target_compile_options(${mbedtls_static_target} PRIVATE ${LIBS_C_FLAGS})
|
||||
set_target_properties(${mbedtls_static_target} PROPERTIES OUTPUT_NAME mbedtls)
|
||||
target_link_libraries(${mbedtls_static_target} PUBLIC ${libs} ${mbedx509_static_target})
|
||||
|
||||
if(GEN_FILES)
|
||||
add_dependencies(${mbedx509_static_target}
|
||||
${MBEDTLS_TARGET_PREFIX}libmbedx509_generated_files_target)
|
||||
add_dependencies(${mbedtls_static_target}
|
||||
${MBEDTLS_TARGET_PREFIX}libmbedtls_generated_files_target)
|
||||
endif()
|
||||
endif(USE_STATIC_MBEDTLS_LIBRARY)
|
||||
|
||||
if(USE_SHARED_MBEDTLS_LIBRARY)
|
||||
add_library(${mbedx509_target} SHARED ${src_x509})
|
||||
set_base_compile_options(${mbedx509_target})
|
||||
target_compile_options(${mbedx509_target} PRIVATE ${LIBS_C_FLAGS})
|
||||
set_target_properties(${mbedx509_target} PROPERTIES VERSION ${MBEDTLS_VERSION} SOVERSION ${MBEDTLS_X509_SOVERSION})
|
||||
target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${tfpsacrypto_target})
|
||||
|
||||
add_library(${mbedtls_target} SHARED ${src_tls})
|
||||
set_base_compile_options(${mbedtls_target})
|
||||
target_compile_options(${mbedtls_target} PRIVATE ${LIBS_C_FLAGS})
|
||||
set_target_properties(${mbedtls_target} PROPERTIES VERSION ${MBEDTLS_VERSION} SOVERSION ${MBEDTLS_TLS_SOVERSION})
|
||||
target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
|
||||
|
||||
if(GEN_FILES)
|
||||
add_dependencies(${mbedx509_target}
|
||||
${MBEDTLS_TARGET_PREFIX}libmbedx509_generated_files_target)
|
||||
add_dependencies(${mbedtls_target}
|
||||
${MBEDTLS_TARGET_PREFIX}libmbedtls_generated_files_target)
|
||||
endif()
|
||||
endif(USE_SHARED_MBEDTLS_LIBRARY)
|
||||
|
||||
foreach(target IN LISTS target_libraries)
|
||||
add_library(MbedTLS::${target} ALIAS ${target}) # add_subdirectory support
|
||||
# Include public header files from /include, /tf-psa-crypto/include/ and
|
||||
# tf-psa-crypto/drivers/builtin/include/. Include private header files
|
||||
# from /library, tf-psa-crypto/core/ and tf-psa-crypto/drivers/builtin/src/.
|
||||
target_include_directories(${target}
|
||||
PUBLIC $<BUILD_INTERFACE:${MBEDTLS_DIR}/include/>
|
||||
$<BUILD_INTERFACE:${MBEDTLS_DIR}/tf-psa-crypto/include/>
|
||||
$<BUILD_INTERFACE:${MBEDTLS_DIR}/tf-psa-crypto/drivers/builtin/include/>
|
||||
$<INSTALL_INTERFACE:include/>
|
||||
PRIVATE ${MBEDTLS_DIR}/library/
|
||||
${MBEDTLS_DIR}/tf-psa-crypto/core
|
||||
${MBEDTLS_DIR}/tf-psa-crypto/drivers/builtin/src
|
||||
# needed for generated headers
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
set_config_files_compile_definitions(${target})
|
||||
install(
|
||||
TARGETS ${target}
|
||||
EXPORT MbedTLSTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
endforeach(target)
|
||||
|
||||
set(lib_target "${MBEDTLS_TARGET_PREFIX}lib")
|
||||
|
||||
add_custom_target(${lib_target} DEPENDS ${mbedx509_target} ${mbedtls_target})
|
||||
if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
|
||||
add_dependencies(${lib_target} ${mbedx509_static_target} ${mbedtls_static_target})
|
||||
endif()
|
||||
|
||||
foreach(target IN LISTS tf_psa_crypto_library_targets)
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
if (target_type STREQUAL STATIC_LIBRARY)
|
||||
add_custom_command(
|
||||
TARGET ${mbedtls_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:${target}>
|
||||
$<TARGET_FILE_NAME:${target}>
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:${target}>
|
||||
"libmbedcrypto.a"
|
||||
)
|
||||
install(FILES $<TARGET_FILE:${target}>
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RENAME "libmbedcrypto.a"
|
||||
)
|
||||
else()
|
||||
# Copy the crypto shared library from tf-psa-crypto:
|
||||
# - ".so.<VERSION>" on Unix
|
||||
# - ".dylib" on macOS
|
||||
# - ".dll" on Windows
|
||||
# The full path to the file is given by $<TARGET_FILE:${target}>.
|
||||
#
|
||||
# On systems that use .so versioning, also create the symbolic links
|
||||
# ".so.<SOVERSION>" and ".so", which correspond to
|
||||
# $<TARGET_SONAME_FILE_NAME:${target}> and $<TARGET_LINKER_FILE_NAME:${target}>,
|
||||
# respectively.
|
||||
#
|
||||
# On Windows, also copy the ".lib" file, whose full path is
|
||||
# $<TARGET_LINKER_FILE:${target}>.
|
||||
#
|
||||
# Provide also the crypto libraries under their historical names:
|
||||
# "libmbedcrypto.*"
|
||||
add_custom_command(
|
||||
TARGET ${mbedtls_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:${target}>
|
||||
$<TARGET_FILE_NAME:${target}>
|
||||
)
|
||||
if(APPLE)
|
||||
add_custom_command(
|
||||
TARGET ${mbedtls_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
$<TARGET_FILE_NAME:${target}>
|
||||
libmbedcrypto.dylib
|
||||
)
|
||||
install(FILES $<TARGET_FILE:${target}>
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RENAME "libmbedcrypto.dylib"
|
||||
)
|
||||
elseif(WIN32 AND NOT CYGWIN)
|
||||
add_custom_command(
|
||||
TARGET ${mbedtls_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:${target}>
|
||||
libmbedcrypto.dll
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET ${mbedtls_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_LINKER_FILE:${target}>
|
||||
$<TARGET_LINKER_FILE_NAME:${target}>
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_LINKER_FILE:${target}>
|
||||
libmbedcrypto.lib
|
||||
)
|
||||
install(FILES $<TARGET_FILE:${target}>
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
RENAME "libmbedcrypto.dll"
|
||||
)
|
||||
install(FILES $<TARGET_LINKER_FILE:${target}>
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RENAME "libmbedcrypto.lib"
|
||||
)
|
||||
else()
|
||||
add_custom_command(
|
||||
TARGET ${mbedtls_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
$<TARGET_FILE_NAME:${target}>
|
||||
$<TARGET_SONAME_FILE_NAME:${target}>
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
$<TARGET_SONAME_FILE_NAME:${target}>
|
||||
$<TARGET_LINKER_FILE_NAME:${target}>
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
$<TARGET_FILE_NAME:${target}>
|
||||
libmbedcrypto.so.${MBEDTLS_VERSION}
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
libmbedcrypto.so.${MBEDTLS_VERSION}
|
||||
libmbedcrypto.so.${MBEDTLS_CRYPTO_SOVERSION}
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
libmbedcrypto.so.${MBEDTLS_CRYPTO_SOVERSION}
|
||||
libmbedcrypto.so
|
||||
)
|
||||
install(FILES $<TARGET_FILE:${target}>
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RENAME "libmbedcrypto.so.${MBEDTLS_VERSION}"
|
||||
)
|
||||
install(CODE "
|
||||
set(_libdir \"\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}\")
|
||||
|
||||
execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E create_symlink
|
||||
\"libmbedcrypto.so.${MBEDTLS_VERSION}\"
|
||||
\${_libdir}/libmbedcrypto.so.${MBEDTLS_CRYPTO_SOVERSION})
|
||||
execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E create_symlink
|
||||
\"libmbedcrypto.so.${MBEDTLS_CRYPTO_SOVERSION}\"
|
||||
\${_libdir}/libmbedcrypto.so)
|
||||
")
|
||||
endif()
|
||||
endif()
|
||||
endforeach(target)
|
||||
Vendored
+379
@@ -0,0 +1,379 @@
|
||||
ifndef MBEDTLS_PATH
|
||||
MBEDTLS_PATH := ..
|
||||
endif
|
||||
|
||||
TF_PSA_CRYPTO_CORE_PATH = $(MBEDTLS_PATH)/tf-psa-crypto/core
|
||||
TF_PSA_CRYPTO_DRIVERS_BUILTIN_SRC_PATH = $(MBEDTLS_PATH)/tf-psa-crypto/drivers/builtin/src
|
||||
|
||||
# List the generated files without running a script, so that this
|
||||
# works with no tooling dependencies when GEN_FILES is disabled.
|
||||
GENERATED_FILES := \
|
||||
mbedtls_config_check_before.h \
|
||||
mbedtls_config_check_final.h \
|
||||
mbedtls_config_check_user.h \
|
||||
error.c \
|
||||
version_features.c \
|
||||
ssl_debug_helpers_generated.c
|
||||
|
||||
# Also list the generated files from crypto that are needed in the build,
|
||||
# because we don't have the list in a consumable form.
|
||||
GENERATED_FILES += \
|
||||
$(TF_PSA_CRYPTO_CORE_PATH)/psa_crypto_driver_wrappers.h \
|
||||
$(TF_PSA_CRYPTO_CORE_PATH)/psa_crypto_driver_wrappers_no_static.c \
|
||||
$(TF_PSA_CRYPTO_CORE_PATH)/tf_psa_crypto_config_check_before.h \
|
||||
$(TF_PSA_CRYPTO_CORE_PATH)/tf_psa_crypto_config_check_final.h \
|
||||
$(TF_PSA_CRYPTO_CORE_PATH)/tf_psa_crypto_config_check_user.h
|
||||
|
||||
ifneq ($(GENERATED_FILES),$(wildcard $(GENERATED_FILES)))
|
||||
ifeq (,$(wildcard $(MBEDTLS_PATH)/framework/exported.make))
|
||||
# Use the define keyword to get a multi-line message.
|
||||
# GNU make appends ". Stop.", so tweak the ending of our message accordingly.
|
||||
define error_message
|
||||
$(MBEDTLS_PATH)/framework/exported.make not found.
|
||||
Run `git submodule update --init` to fetch the submodule contents.
|
||||
This is a fatal error
|
||||
endef
|
||||
$(error $(error_message))
|
||||
endif
|
||||
include $(MBEDTLS_PATH)/framework/exported.make
|
||||
endif
|
||||
|
||||
# Also see "include/mbedtls/mbedtls_config.h"
|
||||
|
||||
CFLAGS ?= -O2
|
||||
WARNING_CFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
|
||||
LDFLAGS ?=
|
||||
|
||||
# Include ../include, ../tf-psa-crypto/include and
|
||||
# ../tf-psa-crypto/drivers/builtin/include for public headers and .,
|
||||
# ../tf-psa-crypto/core and ../tf-psa-crypto/drivers/builtin/src for
|
||||
# private headers.
|
||||
LOCAL_CFLAGS = $(WARNING_CFLAGS) -I. -I../tf-psa-crypto/core \
|
||||
-I../tf-psa-crypto/drivers/builtin/src \
|
||||
-I../include -I../tf-psa-crypto/include \
|
||||
-I../tf-psa-crypto/drivers/builtin/include -D_FILE_OFFSET_BITS=64
|
||||
LOCAL_LDFLAGS =
|
||||
|
||||
ifdef DEBUG
|
||||
LOCAL_CFLAGS += -g3
|
||||
endif
|
||||
|
||||
# MicroBlaze specific options:
|
||||
# CFLAGS += -mno-xl-soft-mul -mxl-barrel-shift
|
||||
|
||||
# To compile on Plan9:
|
||||
# CFLAGS += -D_BSD_EXTENSION
|
||||
|
||||
PERL ?= perl
|
||||
|
||||
ifdef WINDOWS
|
||||
PYTHON ?= python
|
||||
else
|
||||
PYTHON ?= $(shell if type python3 >/dev/null 2>/dev/null; then echo python3; else echo python; fi)
|
||||
endif
|
||||
|
||||
# if were running on Windows build for Windows
|
||||
ifdef WINDOWS
|
||||
WINDOWS_BUILD=1
|
||||
else ifeq ($(shell uname -s),Darwin)
|
||||
ifeq ($(AR),ar)
|
||||
APPLE_BUILD ?= 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef WINDOWS_BUILD
|
||||
LOCAL_LDFLAGS += -lbcrypt
|
||||
endif
|
||||
|
||||
# To compile as a shared library:
|
||||
ifdef SHARED
|
||||
# all code is position-indep with mingw, avoid warning about useless flag
|
||||
ifndef WINDOWS_BUILD
|
||||
LOCAL_CFLAGS += -fPIC -fpic
|
||||
endif
|
||||
endif
|
||||
|
||||
SOEXT_TLS?=so.21
|
||||
SOEXT_X509?=so.8
|
||||
SOEXT_CRYPTO?=so.16
|
||||
|
||||
# Set AR_DASH= (empty string) to use an ar implementation that does not accept
|
||||
# the - prefix for command line options (e.g. llvm-ar)
|
||||
AR_DASH ?= -
|
||||
|
||||
ARFLAGS = $(AR_DASH)src
|
||||
ifdef APPLE_BUILD
|
||||
ifneq ($(APPLE_BUILD),0)
|
||||
ARFLAGS = $(AR_DASH)Src
|
||||
RLFLAGS = -no_warning_for_no_symbols -c
|
||||
RL ?= ranlib
|
||||
endif
|
||||
endif
|
||||
|
||||
DLEXT ?= so
|
||||
ifdef WINDOWS_BUILD
|
||||
# Windows shared library extension:
|
||||
DLEXT = dll
|
||||
else ifdef APPLE_BUILD
|
||||
ifneq ($(APPLE_BUILD),0)
|
||||
# Mac OS X shared library extension:
|
||||
DLEXT = dylib
|
||||
endif
|
||||
endif
|
||||
|
||||
OBJS_CRYPTO = $(patsubst %.c, %.o,$(wildcard $(TF_PSA_CRYPTO_CORE_PATH)/*.c $(TF_PSA_CRYPTO_DRIVERS_BUILTIN_SRC_PATH)/*.c))
|
||||
GENERATED_OBJS_CRYPTO = $(TF_PSA_CRYPTO_CORE_PATH)/psa_crypto_driver_wrappers_no_static.o
|
||||
OBJS_CRYPTO := $(filter-out $(GENERATED_OBJS_CRYPTO),$(OBJS_CRYPTO))
|
||||
OBJS_CRYPTO += $(GENERATED_OBJS_CRYPTO)
|
||||
|
||||
THIRDPARTY_DIR := $(MBEDTLS_PATH)/tf-psa-crypto/drivers
|
||||
include $(MBEDTLS_PATH)/tf-psa-crypto/drivers/everest/Makefile.inc
|
||||
include $(MBEDTLS_PATH)/tf-psa-crypto/drivers/p256-m/Makefile.inc
|
||||
LOCAL_CFLAGS+=$(THIRDPARTY_INCLUDES)
|
||||
OBJS_CRYPTO+=$(THIRDPARTY_CRYPTO_OBJECTS)
|
||||
|
||||
OBJS_X509= \
|
||||
mbedtls_config.o \
|
||||
x509.o \
|
||||
x509_create.o \
|
||||
x509_crl.o \
|
||||
x509_crt.o \
|
||||
x509_csr.o \
|
||||
x509_oid.o \
|
||||
x509write.o \
|
||||
x509write_crt.o \
|
||||
x509write_csr.o \
|
||||
pkcs7.o \
|
||||
error.o \
|
||||
# This line is intentionally left blank
|
||||
|
||||
OBJS_TLS= \
|
||||
debug.o \
|
||||
mps_reader.o \
|
||||
mps_trace.o \
|
||||
net_sockets.o \
|
||||
ssl_cache.o \
|
||||
ssl_ciphersuites.o \
|
||||
ssl_client.o \
|
||||
ssl_cookie.o \
|
||||
ssl_debug_helpers_generated.o \
|
||||
ssl_msg.o \
|
||||
ssl_ticket.o \
|
||||
ssl_tls.o \
|
||||
ssl_tls12_client.o \
|
||||
ssl_tls12_server.o \
|
||||
ssl_tls13_keys.o \
|
||||
ssl_tls13_client.o \
|
||||
ssl_tls13_server.o \
|
||||
ssl_tls13_generic.o \
|
||||
timing.o \
|
||||
version.o \
|
||||
version_features.o \
|
||||
# This line is intentionally left blank
|
||||
|
||||
.SILENT:
|
||||
|
||||
.PHONY: all static shared clean
|
||||
|
||||
ifndef SHARED
|
||||
all: static
|
||||
else
|
||||
all: shared static
|
||||
endif
|
||||
|
||||
static: libmbedcrypto.a libmbedx509.a libmbedtls.a
|
||||
cd ../tests && echo "This is a seedfile that contains 64 bytes (65 on Windows)......" > seedfile
|
||||
cd ../tf-psa-crypto/tests && echo "This is a seedfile that contains 64 bytes (65 on Windows)......" > seedfile
|
||||
|
||||
shared: libmbedcrypto.$(DLEXT) libmbedx509.$(DLEXT) libmbedtls.$(DLEXT)
|
||||
|
||||
# Windows builds under Mingw can fail if make tries to create archives in the same
|
||||
# directory at the same time - see https://bugs.launchpad.net/gcc-arm-embedded/+bug/1848002.
|
||||
# This forces builds of the .a files to be serialised.
|
||||
ifdef WINDOWS
|
||||
libmbedtls.a: | libmbedx509.a
|
||||
libmbedx509.a: | libmbedcrypto.a
|
||||
endif
|
||||
|
||||
# tls
|
||||
libmbedtls.a: $(OBJS_TLS)
|
||||
echo " AR $@"
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS_TLS)
|
||||
ifdef APPLE_BUILD
|
||||
ifneq ($(APPLE_BUILD),0)
|
||||
echo " RL $@"
|
||||
$(RL) $(RLFLAGS) $@
|
||||
endif
|
||||
endif
|
||||
|
||||
libmbedtls.$(SOEXT_TLS): $(OBJS_TLS) libmbedx509.so
|
||||
echo " LD $@"
|
||||
$(CC) -shared -Wl,-soname,$@ -o $@ $(OBJS_TLS) -L. -lmbedx509 -lmbedcrypto $(LOCAL_LDFLAGS) $(LDFLAGS)
|
||||
|
||||
ifneq ($(SOEXT_TLS),so)
|
||||
libmbedtls.so: libmbedtls.$(SOEXT_TLS)
|
||||
echo " LN $@ -> $<"
|
||||
ln -sf $< $@
|
||||
endif
|
||||
|
||||
libmbedtls.dylib: $(OBJS_TLS) libmbedx509.dylib
|
||||
echo " LD $@"
|
||||
$(CC) -dynamiclib -o $@ $(OBJS_TLS) -L. -lmbedx509 -lmbedcrypto $(LOCAL_LDFLAGS) $(LDFLAGS)
|
||||
|
||||
libmbedtls.dll: $(OBJS_TLS) libmbedx509.dll
|
||||
echo " LD $@"
|
||||
$(CC) -shared -Wl,-soname,$@ -Wl,--out-implib,$@.a -o $@ $(OBJS_TLS) -lws2_32 -lwinmm -lgdi32 -L. -lmbedx509 -lmbedcrypto -static-libgcc $(LOCAL_LDFLAGS) $(LDFLAGS)
|
||||
|
||||
# x509
|
||||
libmbedx509.a: $(OBJS_X509)
|
||||
echo " AR $@"
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS_X509)
|
||||
ifdef APPLE_BUILD
|
||||
ifneq ($(APPLE_BUILD),0)
|
||||
echo " RL $@"
|
||||
$(RL) $(RLFLAGS) $@
|
||||
endif
|
||||
endif
|
||||
|
||||
libmbedx509.$(SOEXT_X509): $(OBJS_X509) libmbedcrypto.so
|
||||
echo " LD $@"
|
||||
$(CC) -shared -Wl,-soname,$@ -o $@ $(OBJS_X509) -L. -lmbedcrypto $(LOCAL_LDFLAGS) $(LDFLAGS)
|
||||
|
||||
ifneq ($(SOEXT_X509),so)
|
||||
libmbedx509.so: libmbedx509.$(SOEXT_X509)
|
||||
echo " LN $@ -> $<"
|
||||
ln -sf $< $@
|
||||
endif
|
||||
|
||||
libmbedx509.dylib: $(OBJS_X509) libmbedcrypto.dylib
|
||||
echo " LD $@"
|
||||
$(CC) -dynamiclib -o $@ $(OBJS_X509) -L. -lmbedcrypto $(LOCAL_LDFLAGS) $(LDFLAGS)
|
||||
|
||||
libmbedx509.dll: $(OBJS_X509) libmbedcrypto.dll
|
||||
echo " LD $@"
|
||||
$(CC) -shared -Wl,-soname,$@ -Wl,--out-implib,$@.a -o $@ $(OBJS_X509) -lws2_32 -lwinmm -lgdi32 -L. -lmbedcrypto -static-libgcc $(LOCAL_LDFLAGS) $(LDFLAGS)
|
||||
|
||||
# crypto
|
||||
libmbedcrypto.a: $(OBJS_CRYPTO)
|
||||
echo " AR $@"
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS_CRYPTO)
|
||||
ifdef APPLE_BUILD
|
||||
ifneq ($(APPLE_BUILD),0)
|
||||
echo " RL $@"
|
||||
$(RL) $(RLFLAGS) $@
|
||||
endif
|
||||
endif
|
||||
|
||||
libmbedcrypto.$(SOEXT_CRYPTO): $(OBJS_CRYPTO)
|
||||
echo " LD $@"
|
||||
$(CC) -shared -Wl,-soname,$@ -o $@ $(OBJS_CRYPTO) $(LOCAL_LDFLAGS) $(LDFLAGS)
|
||||
|
||||
ifneq ($(SOEXT_CRYPTO),so)
|
||||
libmbedcrypto.so: libmbedcrypto.$(SOEXT_CRYPTO)
|
||||
echo " LN $@ -> $<"
|
||||
ln -sf $< $@
|
||||
endif
|
||||
|
||||
libmbedcrypto.dylib: $(OBJS_CRYPTO)
|
||||
echo " LD $@"
|
||||
$(CC) -dynamiclib -o $@ $(OBJS_CRYPTO) $(LOCAL_LDFLAGS) $(LDFLAGS)
|
||||
|
||||
libmbedcrypto.dll: $(OBJS_CRYPTO)
|
||||
echo " LD $@"
|
||||
$(CC) -shared -Wl,-soname,$@ -Wl,--out-implib,$@.a -o $@ $(OBJS_CRYPTO) -lws2_32 -lwinmm -lgdi32 -static-libgcc $(LOCAL_LDFLAGS) $(LDFLAGS)
|
||||
|
||||
.c.o:
|
||||
echo " CC $<"
|
||||
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
.c.s:
|
||||
echo " CC $<"
|
||||
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -S -o $@ -c $<
|
||||
|
||||
.PHONY: generated_files
|
||||
generated_files: $(GENERATED_FILES)
|
||||
|
||||
# See root Makefile
|
||||
GEN_FILES ?= yes
|
||||
ifdef GEN_FILES
|
||||
gen_file_dep =
|
||||
else
|
||||
gen_file_dep = |
|
||||
endif
|
||||
|
||||
error.c: $(gen_file_dep) ../scripts/generate_errors.pl
|
||||
error.c: $(gen_file_dep) ../scripts/data_files/error.fmt
|
||||
error.c: $(gen_file_dep) $(filter-out %config%,$(wildcard ../include/mbedtls/*.h))
|
||||
error.c:
|
||||
echo " Gen $@"
|
||||
$(PERL) ../scripts/generate_errors.pl
|
||||
|
||||
ssl_debug_helpers_generated.c: $(gen_file_dep) ../framework/scripts/generate_ssl_debug_helpers.py
|
||||
ssl_debug_helpers_generated.c: $(gen_file_dep) $(filter-out %config%,$(wildcard ../include/mbedtls/*.h))
|
||||
ssl_debug_helpers_generated.c:
|
||||
echo " Gen $@"
|
||||
$(PYTHON) ../framework/scripts/generate_ssl_debug_helpers.py --mbedtls-root .. .
|
||||
|
||||
version_features.c: $(gen_file_dep) ../scripts/generate_features.pl
|
||||
version_features.c: $(gen_file_dep) ../scripts/data_files/version_features.fmt
|
||||
## The generated file only depends on the options that are present in mbedtls_config.h,
|
||||
## not on which options are set. To avoid regenerating this file all the time
|
||||
## when switching between configurations, don't declare mbedtls_config.h as a
|
||||
## dependency. Remove this file from your working tree if you've just added or
|
||||
## removed an option in mbedtls_config.h.
|
||||
#version_features.c: ../include/mbedtls/mbedtls_config.h
|
||||
version_features.c:
|
||||
echo " Gen $@"
|
||||
$(PERL) ../scripts/generate_features.pl
|
||||
|
||||
GENERATED_WRAPPER_FILES = \
|
||||
$(TF_PSA_CRYPTO_CORE_PATH)/psa_crypto_driver_wrappers.h \
|
||||
$(TF_PSA_CRYPTO_CORE_PATH)/psa_crypto_driver_wrappers_no_static.c
|
||||
$(GENERATED_WRAPPER_FILES): ../tf-psa-crypto/scripts/generate_driver_wrappers.py
|
||||
$(GENERATED_WRAPPER_FILES): ../tf-psa-crypto/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja
|
||||
$(GENERATED_WRAPPER_FILES): ../tf-psa-crypto/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja
|
||||
$(GENERATED_WRAPPER_FILES):
|
||||
echo " Gen $(GENERATED_WRAPPER_FILES)"
|
||||
$(PYTHON) ../tf-psa-crypto/scripts/generate_driver_wrappers.py $(TF_PSA_CRYPTO_CORE_PATH)
|
||||
|
||||
$(TF_PSA_CRYPTO_CORE_PATH)/psa_crypto.o:$(TF_PSA_CRYPTO_CORE_PATH)/psa_crypto_driver_wrappers.h
|
||||
|
||||
GENERATED_CONFIG_CHECK_FILES = $(shell $(PYTHON) ../scripts/generate_config_checks.py --list .)
|
||||
$(GENERATED_CONFIG_CHECK_FILES): $(gen_file_dep) \
|
||||
$(TF_PSA_CRYPTO_CORE_PATH)/../scripts/generate_config_checks.py \
|
||||
../framework/scripts/mbedtls_framework/config_checks_generator.py
|
||||
$(GENERATED_CONFIG_CHECK_FILES):
|
||||
echo " Gen $(GENERATED_CONFIG_CHECK_FILES)"
|
||||
$(PYTHON) ../scripts/generate_config_checks.py
|
||||
|
||||
mbedtls_config.o: $(GENERATED_CONFIG_CHECK_FILES)
|
||||
|
||||
TF_PSA_CRYPTO_GENERATED_CONFIG_CHECK_FILES = $(shell $(PYTHON) \
|
||||
$(TF_PSA_CRYPTO_CORE_PATH)/../scripts/generate_config_checks.py \
|
||||
--list $(TF_PSA_CRYPTO_CORE_PATH))
|
||||
$(TF_PSA_CRYPTO_GENERATED_CONFIG_CHECK_FILES): $(gen_file_dep) \
|
||||
../scripts/generate_config_checks.py \
|
||||
../framework/scripts/mbedtls_framework/config_checks_generator.py
|
||||
$(TF_PSA_CRYPTO_GENERATED_CONFIG_CHECK_FILES):
|
||||
echo " Gen $(TF_PSA_CRYPTO_GENERATED_CONFIG_CHECK_FILES)"
|
||||
$(PYTHON) $(TF_PSA_CRYPTO_CORE_PATH)/../scripts/generate_config_checks.py
|
||||
|
||||
$(TF_PSA_CRYPTO_CORE_PATH)/tf_psa_crypto_config.o: $(TF_PSA_CRYPTO_GENERATED_CONFIG_CHECK_FILES)
|
||||
|
||||
clean:
|
||||
ifndef WINDOWS
|
||||
rm -f *.o *.s libmbed*
|
||||
rm -f $(OBJS_CRYPTO) $(OBJS_CRYPTO:.o=.s)
|
||||
else
|
||||
if exist *.o del /Q /F *.o
|
||||
if exist *.s del /Q /F *.s
|
||||
if exist libmbed* del /Q /F libmbed*
|
||||
del /Q /F del_errors_out_if_the_file_list_is_empty_but_not_if_a_file_does_not_exist $(subst /,\,$(OBJS_CRYPTO))
|
||||
endif
|
||||
|
||||
neat: clean
|
||||
ifndef WINDOWS
|
||||
rm -f $(GENERATED_FILES)
|
||||
else
|
||||
for %f in ($(subst /,\,$(GENERATED_FILES))) if exist %f del /Q /F %f
|
||||
endif
|
||||
Vendored
+495
@@ -0,0 +1,495 @@
|
||||
/*
|
||||
* Debugging routines
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "debug_internal.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* DEBUG_BUF_SIZE must be at least 2 */
|
||||
#define DEBUG_BUF_SIZE 512
|
||||
|
||||
static int debug_threshold = 0;
|
||||
|
||||
void mbedtls_debug_set_threshold(int threshold)
|
||||
{
|
||||
debug_threshold = threshold;
|
||||
}
|
||||
|
||||
/*
|
||||
* All calls to f_dbg must be made via this function
|
||||
*/
|
||||
static inline void debug_send_line(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *str)
|
||||
{
|
||||
/*
|
||||
* If in a threaded environment, we need a thread identifier.
|
||||
* Since there is no portable way to get one, use the address of the ssl
|
||||
* context instead, as it shouldn't be shared between threads.
|
||||
*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */
|
||||
mbedtls_snprintf(idstr, sizeof(idstr), "%p: %s", (void *) ssl, str);
|
||||
ssl->conf->f_dbg(ssl->conf->p_dbg, level, file, line, idstr);
|
||||
#else
|
||||
ssl->conf->f_dbg(ssl->conf->p_dbg, level, file, line, str);
|
||||
#endif
|
||||
}
|
||||
|
||||
MBEDTLS_PRINTF_ATTRIBUTE(5, 6)
|
||||
void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *format, ...)
|
||||
{
|
||||
va_list argp;
|
||||
char str[DEBUG_BUF_SIZE];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
MBEDTLS_STATIC_ASSERT(DEBUG_BUF_SIZE >= 2, "DEBUG_BUF_SIZE too small");
|
||||
|
||||
if (NULL == ssl ||
|
||||
NULL == ssl->conf ||
|
||||
NULL == ssl->conf->f_dbg ||
|
||||
level > debug_threshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(argp, format);
|
||||
ret = mbedtls_vsnprintf(str, DEBUG_BUF_SIZE, format, argp);
|
||||
va_end(argp);
|
||||
|
||||
if (ret < 0) {
|
||||
ret = 0;
|
||||
} else {
|
||||
if (ret >= DEBUG_BUF_SIZE - 1) {
|
||||
ret = DEBUG_BUF_SIZE - 2;
|
||||
}
|
||||
}
|
||||
str[ret] = '\n';
|
||||
str[ret + 1] = '\0';
|
||||
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
}
|
||||
|
||||
void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, int ret)
|
||||
{
|
||||
char str[DEBUG_BUF_SIZE];
|
||||
|
||||
if (NULL == ssl ||
|
||||
NULL == ssl->conf ||
|
||||
NULL == ssl->conf->f_dbg ||
|
||||
level > debug_threshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* With non-blocking I/O and examples that just retry immediately,
|
||||
* the logs would be quickly flooded with WANT_READ, so ignore that.
|
||||
* Don't ignore WANT_WRITE however, since it is usually rare.
|
||||
*/
|
||||
if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_snprintf(str, sizeof(str), "%s() returned %d (-0x%04x)\n",
|
||||
text, ret, (unsigned int) -ret);
|
||||
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
}
|
||||
|
||||
void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line, const char *text,
|
||||
const unsigned char *buf, size_t len)
|
||||
{
|
||||
char str[DEBUG_BUF_SIZE];
|
||||
char txt[17];
|
||||
size_t i, idx = 0;
|
||||
|
||||
if (NULL == ssl ||
|
||||
NULL == ssl->conf ||
|
||||
NULL == ssl->conf->f_dbg ||
|
||||
level > debug_threshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_snprintf(str + idx, sizeof(str) - idx, "dumping '%s' (%u bytes)\n",
|
||||
text, (unsigned int) len);
|
||||
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
|
||||
memset(txt, 0, sizeof(txt));
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i >= 4096) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (i % 16 == 0) {
|
||||
if (i > 0) {
|
||||
mbedtls_snprintf(str + idx, sizeof(str) - idx, " %s\n", txt);
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
|
||||
idx = 0;
|
||||
memset(txt, 0, sizeof(txt));
|
||||
}
|
||||
|
||||
idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, "%04x: ",
|
||||
(unsigned int) i);
|
||||
|
||||
}
|
||||
|
||||
idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x",
|
||||
(unsigned int) buf[i]);
|
||||
txt[i % 16] = (buf[i] > 31 && buf[i] < 127) ? buf[i] : '.';
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
for (/* i = i */; i % 16 != 0; i++) {
|
||||
idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " ");
|
||||
}
|
||||
|
||||
mbedtls_snprintf(str + idx, sizeof(str) - idx, " %s\n", txt);
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mbedtls_mpi *X)
|
||||
{
|
||||
char str[DEBUG_BUF_SIZE];
|
||||
size_t bitlen;
|
||||
size_t idx = 0;
|
||||
|
||||
if (NULL == ssl ||
|
||||
NULL == ssl->conf ||
|
||||
NULL == ssl->conf->f_dbg ||
|
||||
NULL == X ||
|
||||
level > debug_threshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
bitlen = mbedtls_mpi_bitlen(X);
|
||||
|
||||
mbedtls_snprintf(str, sizeof(str), "value of '%s' (%u bits) is:\n",
|
||||
text, (unsigned) bitlen);
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
|
||||
if (bitlen == 0) {
|
||||
str[0] = ' '; str[1] = '0'; str[2] = '0';
|
||||
idx = 3;
|
||||
} else {
|
||||
int n;
|
||||
for (n = (int) ((bitlen - 1) / 8); n >= 0; n--) {
|
||||
size_t limb_offset = n / sizeof(mbedtls_mpi_uint);
|
||||
size_t offset_in_limb = n % sizeof(mbedtls_mpi_uint);
|
||||
unsigned char octet =
|
||||
(X->p[limb_offset] >> (offset_in_limb * 8)) & 0xff;
|
||||
mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x", octet);
|
||||
idx += 3;
|
||||
/* Wrap lines after 16 octets that each take 3 columns */
|
||||
if (idx >= 3 * 16) {
|
||||
mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (idx != 0) {
|
||||
mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_BIGNUM_C */
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
|
||||
/* no-check-names will be removed in mbedtls#10229. */
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) || defined(MBEDTLS_PK_USE_PSA_RSA_DATA) //no-check-names
|
||||
static void mbedtls_debug_print_integer(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line, const char *text,
|
||||
const unsigned char *buf, size_t bitlen)
|
||||
{
|
||||
char str[DEBUG_BUF_SIZE];
|
||||
size_t i, len_bytes = PSA_BITS_TO_BYTES(bitlen), idx = 0;
|
||||
|
||||
mbedtls_snprintf(str + idx, sizeof(str) - idx, "value of '%s' (%u bits) is:\n",
|
||||
text, (unsigned int) bitlen);
|
||||
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
|
||||
for (i = 0; i < len_bytes; i++) {
|
||||
if (i >= 4096) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (i % 16 == 0) {
|
||||
if (i > 0) {
|
||||
mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x",
|
||||
(unsigned int) buf[i]);
|
||||
}
|
||||
|
||||
if (len_bytes > 0) {
|
||||
mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
}
|
||||
}
|
||||
/* no-check-names will be removed in mbedtls#10229. */
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY || MBEDTLS_PK_USE_PSA_RSA_DATA */ //no-check-names
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
static void mbedtls_debug_print_psa_ec(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mbedtls_pk_context *pk)
|
||||
{
|
||||
char str[DEBUG_BUF_SIZE];
|
||||
const uint8_t *coord_start;
|
||||
size_t coord_len;
|
||||
|
||||
if (NULL == ssl ||
|
||||
NULL == ssl->conf ||
|
||||
NULL == ssl->conf->f_dbg ||
|
||||
level > debug_threshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* For the description of pk->pk_raw content please refer to the description
|
||||
* psa_export_public_key() function. */
|
||||
coord_len = (pk->pub_raw_len - 1)/2;
|
||||
|
||||
/* X coordinate */
|
||||
coord_start = pk->pub_raw + 1;
|
||||
mbedtls_snprintf(str, sizeof(str), "%s(X)", text);
|
||||
mbedtls_debug_print_integer(ssl, level, file, line, str, coord_start, coord_len * 8);
|
||||
|
||||
/* Y coordinate */
|
||||
coord_start = coord_start + coord_len;
|
||||
mbedtls_snprintf(str, sizeof(str), "%s(Y)", text);
|
||||
mbedtls_debug_print_integer(ssl, level, file, line, str, coord_start, coord_len * 8);
|
||||
}
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
|
||||
/* no-check-names will be removed in mbedtls#10229. */
|
||||
#if defined(MBEDTLS_PK_USE_PSA_RSA_DATA) //no-check-names
|
||||
static size_t debug_count_valid_bits(unsigned char **buf, size_t len)
|
||||
{
|
||||
size_t i, bits;
|
||||
|
||||
/* Ignore initial null bytes (if any). */
|
||||
while ((len > 0) && (**buf == 0x00)) {
|
||||
(*buf)++;
|
||||
len--;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bits = len * 8;
|
||||
|
||||
/* Ignore initial null bits (if any). */
|
||||
for (i = 7; i > 0; i--) {
|
||||
if ((**buf & (0x1 << i)) != 0) {
|
||||
break;
|
||||
}
|
||||
bits--;
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
static void mbedtls_debug_print_psa_rsa(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mbedtls_pk_context *pk)
|
||||
{
|
||||
char str[DEBUG_BUF_SIZE];
|
||||
/* no-check-names will be removed in mbedtls#10229. */
|
||||
unsigned char key_der[MBEDTLS_PK_MAX_RSA_PUBKEY_RAW_LEN]; //no-check-names
|
||||
unsigned char *start_cur;
|
||||
unsigned char *end_cur;
|
||||
size_t len, bits;
|
||||
int ret;
|
||||
|
||||
if (NULL == ssl ||
|
||||
NULL == ssl->conf ||
|
||||
NULL == ssl->conf->f_dbg ||
|
||||
level > debug_threshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pk->pub_raw_len > sizeof(key_der)) {
|
||||
snprintf(str, sizeof(str),
|
||||
"RSA public key too large: %" MBEDTLS_PRINTF_SIZET " > %" MBEDTLS_PRINTF_SIZET,
|
||||
pk->pub_raw_len, sizeof(key_der));
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(key_der, pk->pub_raw, pk->pub_raw_len);
|
||||
start_cur = key_der;
|
||||
end_cur = key_der + pk->pub_raw_len;
|
||||
|
||||
/* This integer parsing solution should be replaced with mbedtls_asn1_get_integer().
|
||||
* See #10238. */
|
||||
ret = mbedtls_asn1_get_tag(&start_cur, end_cur, &len,
|
||||
MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = mbedtls_asn1_get_tag(&start_cur, end_cur, &len, MBEDTLS_ASN1_INTEGER);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
bits = debug_count_valid_bits(&start_cur, len);
|
||||
if (bits == 0) {
|
||||
return;
|
||||
}
|
||||
len = PSA_BITS_TO_BYTES(bits);
|
||||
|
||||
mbedtls_snprintf(str, sizeof(str), "%s.N", text);
|
||||
mbedtls_debug_print_integer(ssl, level, file, line, str, start_cur, bits);
|
||||
|
||||
start_cur += len;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(&start_cur, end_cur, &len, MBEDTLS_ASN1_INTEGER);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
bits = debug_count_valid_bits(&start_cur, len);
|
||||
if (bits == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_snprintf(str, sizeof(str), "%s.E", text);
|
||||
mbedtls_debug_print_integer(ssl, level, file, line, str, start_cur, bits);
|
||||
}
|
||||
/* no-check-names will be removed in mbedtls#10229. */
|
||||
#endif /* MBEDTLS_PK_USE_PSA_RSA_DATA */ //no-check-names
|
||||
|
||||
static void debug_print_pk(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mbedtls_pk_context *pk)
|
||||
{
|
||||
size_t i;
|
||||
mbedtls_pk_debug_item items[MBEDTLS_PK_DEBUG_MAX_ITEMS];
|
||||
char name[16];
|
||||
|
||||
memset(items, 0, sizeof(items));
|
||||
|
||||
if (mbedtls_pk_debug(pk, items) != 0) {
|
||||
debug_send_line(ssl, level, file, line,
|
||||
"invalid PK context\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < MBEDTLS_PK_DEBUG_MAX_ITEMS; i++) {
|
||||
if (items[i].type == MBEDTLS_PK_DEBUG_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_snprintf(name, sizeof(name), "%s%s", text, items[i].name);
|
||||
name[sizeof(name) - 1] = '\0';
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
if (items[i].type == MBEDTLS_PK_DEBUG_MPI) {
|
||||
mbedtls_debug_print_mpi(ssl, level, file, line, name, items[i].value);
|
||||
} else
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
/* no-check-names will be removed in mbedtls#10229. */
|
||||
#if defined(MBEDTLS_PK_USE_PSA_RSA_DATA) //no-check-names
|
||||
if (items[i].type == MBEDTLS_PK_DEBUG_PSA_RSA) { //no-check-names
|
||||
mbedtls_debug_print_psa_rsa(ssl, level, file, line, name, items[i].value);
|
||||
} else
|
||||
#endif /* MBEDTLS_PK_USE_PSA_RSA_DATA */ //no-check-names
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
if (items[i].type == MBEDTLS_PK_DEBUG_PSA_EC) {
|
||||
mbedtls_debug_print_psa_ec(ssl, level, file, line, name, items[i].value);
|
||||
} else
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
{ debug_send_line(ssl, level, file, line,
|
||||
"should not happen\n"); }
|
||||
}
|
||||
}
|
||||
|
||||
static void debug_print_line_by_line(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line, const char *text)
|
||||
{
|
||||
char str[DEBUG_BUF_SIZE];
|
||||
const char *start, *cur;
|
||||
|
||||
start = text;
|
||||
for (cur = text; *cur != '\0'; cur++) {
|
||||
if (*cur == '\n') {
|
||||
size_t len = (size_t) (cur - start) + 1;
|
||||
if (len > DEBUG_BUF_SIZE - 1) {
|
||||
len = DEBUG_BUF_SIZE - 1;
|
||||
}
|
||||
|
||||
memcpy(str, start, len);
|
||||
str[len] = '\0';
|
||||
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
|
||||
start = cur + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mbedtls_x509_crt *crt)
|
||||
{
|
||||
char str[DEBUG_BUF_SIZE];
|
||||
int i = 0;
|
||||
|
||||
if (NULL == ssl ||
|
||||
NULL == ssl->conf ||
|
||||
NULL == ssl->conf->f_dbg ||
|
||||
NULL == crt ||
|
||||
level > debug_threshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (crt != NULL) {
|
||||
char buf[1024];
|
||||
|
||||
mbedtls_snprintf(str, sizeof(str), "%s #%d:\n", text, ++i);
|
||||
debug_send_line(ssl, level, file, line, str);
|
||||
|
||||
mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
|
||||
debug_print_line_by_line(ssl, level, file, line, buf);
|
||||
|
||||
debug_print_pk(ssl, level, file, line, "crt->", &crt->pk);
|
||||
|
||||
crt = crt->next;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_X509_REMOVE_INFO */
|
||||
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* \file debug_internal.h
|
||||
*
|
||||
* \brief Internal part of the public "debug.h".
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_DEBUG_INTERNAL_H
|
||||
#define MBEDTLS_DEBUG_INTERNAL_H
|
||||
|
||||
#include "mbedtls/debug.h"
|
||||
|
||||
/**
|
||||
* \brief Print a message to the debug output. This function is always used
|
||||
* through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl
|
||||
* context, file and line number parameters.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the message has occurred in
|
||||
* \param line line number the message has occurred at
|
||||
* \param format format specifier, in printf format
|
||||
* \param ... variables used by the format specifier
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(5, 6);
|
||||
|
||||
/**
|
||||
* \brief Print the return value of a function to the debug output. This
|
||||
* function is always used through the MBEDTLS_SSL_DEBUG_RET() macro,
|
||||
* which supplies the ssl context, file and line number parameters.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the error has occurred in
|
||||
* \param line line number the error has occurred in
|
||||
* \param text the name of the function that returned the error
|
||||
* \param ret the return code value
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, int ret);
|
||||
|
||||
/**
|
||||
* \brief Output a buffer of size len bytes to the debug output. This function
|
||||
* is always used through the MBEDTLS_SSL_DEBUG_BUF() macro,
|
||||
* which supplies the ssl context, file and line number parameters.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the error has occurred in
|
||||
* \param line line number the error has occurred in
|
||||
* \param text a name or label for the buffer being dumped. Normally the
|
||||
* variable or buffer name
|
||||
* \param buf the buffer to be outputted
|
||||
* \param len length of the buffer
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line, const char *text,
|
||||
const unsigned char *buf, size_t len);
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
/**
|
||||
* \brief Print a MPI variable to the debug output.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the error has occurred in
|
||||
* \param line line number the error has occurred in
|
||||
* \param text a name or label for the MPI being output. Normally the
|
||||
* variable name
|
||||
* \param X the MPI variable
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mbedtls_mpi *X);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
/**
|
||||
* \brief Print a X.509 certificate structure to the debug output. This
|
||||
* function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro,
|
||||
* which supplies the ssl context, file and line number parameters.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param level error level of the debug message
|
||||
* \param file file the error has occurred in
|
||||
* \param line line number the error has occurred in
|
||||
* \param text a name or label for the certificate being output
|
||||
* \param crt X.509 certificate structure
|
||||
*
|
||||
* \attention This function is intended for INTERNAL usage within the
|
||||
* library only.
|
||||
*/
|
||||
void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *file, int line,
|
||||
const char *text, const mbedtls_x509_crt *crt);
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_DEBUG_INTERNAL_H */
|
||||
+369
@@ -0,0 +1,369 @@
|
||||
/**
|
||||
* \file mbedtls/check_config.h
|
||||
*
|
||||
* \brief Consistency checks for configuration options
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* This header is included automatically by all public Mbed TLS headers
|
||||
* (via mbedtls/build_info.h). Do not include it directly in a configuration
|
||||
* file such as mbedtls/mbedtls_config.h or #MBEDTLS_USER_CONFIG_FILE!
|
||||
* It would run at the wrong time due to missing derived symbols.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CHECK_CONFIG_H
|
||||
#define MBEDTLS_CHECK_CONFIG_H
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_IS_FINALIZED)
|
||||
#warning "Do not include mbedtls/check_config.h manually! " \
|
||||
"This may cause spurious errors. " \
|
||||
"It is included automatically at the right point since Mbed TLS 3.0."
|
||||
#endif /* !MBEDTLS_CONFIG_IS_FINALIZED */
|
||||
|
||||
#if defined(TARGET_LIKE_MBED) && defined(MBEDTLS_NET_C)
|
||||
#error "The NET module is not available for mbed OS - please use the network functions provided by Mbed OS"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME)
|
||||
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
|
||||
#endif
|
||||
|
||||
/* Limitations on ECC curves acceleration: partial curve acceleration is only
|
||||
* supported with crypto excluding PK, X.509 or TLS.
|
||||
* Note: no need to check X.509 as it depends on PK. */
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256) || \
|
||||
defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384) || \
|
||||
defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512) || \
|
||||
defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255) || \
|
||||
defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448) || \
|
||||
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192) || \
|
||||
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256) || \
|
||||
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192) || \
|
||||
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \
|
||||
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384) || \
|
||||
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521)
|
||||
#if defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
|
||||
#if defined(MBEDTLS_SSL_TLS_C)
|
||||
#error "Unsupported partial support for ECC curves acceleration, see docs/driver-only-builds.md"
|
||||
#endif /* modules beyond what's supported */
|
||||
#endif /* not all curves accelerated */
|
||||
#endif /* some curve accelerated */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \
|
||||
!defined(MBEDTLS_CAN_ECDH)
|
||||
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
|
||||
( !defined(MBEDTLS_CAN_ECDH) || !defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
|
||||
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) || !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) )
|
||||
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
|
||||
( !defined(MBEDTLS_CAN_ECDH) || \
|
||||
!defined(PSA_HAVE_ALG_ECDSA_SIGN) || \
|
||||
!defined(MBEDTLS_X509_CRT_PARSE_C) )
|
||||
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
|
||||
( !defined(PSA_WANT_ALG_JPAKE) || \
|
||||
!defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
|
||||
!defined(PSA_WANT_ECC_SECP_R1_256) )
|
||||
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
/* Use of EC J-PAKE in TLS requires SHA-256. */
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
|
||||
!defined(PSA_WANT_ALG_SHA_256)
|
||||
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \
|
||||
!defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \
|
||||
!defined(PSA_WANT_ALG_SHA_256) && \
|
||||
!defined(PSA_WANT_ALG_SHA_512) && \
|
||||
!defined(PSA_WANT_ALG_SHA_1)
|
||||
#error "!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE requires SHA-512, SHA-256 or SHA-1".
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
|
||||
( !defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || !defined(PSA_WANT_ALG_RSA_OAEP) )
|
||||
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
/* TLS 1.3 requires separate HKDF parts from PSA,
|
||||
* and at least one ciphersuite, so at least SHA-256 or SHA-384
|
||||
* from PSA to use with HKDF.
|
||||
*
|
||||
* Note: for dependencies common with TLS 1.2 (running handshake hash),
|
||||
* see MBEDTLS_SSL_TLS_C. */
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
!(defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \
|
||||
defined(PSA_WANT_ALG_HKDF_EXTRACT) && \
|
||||
defined(PSA_WANT_ALG_HKDF_EXPAND) && \
|
||||
(defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384)))
|
||||
#error "MBEDTLS_SSL_PROTO_TLS1_3 defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
#if !( (defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)) && \
|
||||
defined(MBEDTLS_X509_CRT_PARSE_C) && \
|
||||
( defined(PSA_HAVE_ALG_ECDSA_SIGN) || defined(PSA_WANT_ALG_RSA_OAEP) ) )
|
||||
#error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
|
||||
#if !( defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) )
|
||||
#error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED defined, but not all prerequisites"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The current implementation of TLS 1.3 requires MBEDTLS_SSL_KEEP_PEER_CERTIFICATE.
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
#error "MBEDTLS_SSL_PROTO_TLS1_3 defined without MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
|
||||
!(defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) )
|
||||
#error "One or more versions of the TLS protocol are enabled " \
|
||||
"but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
|
||||
!(defined(PSA_WANT_ALG_SHA_1) || defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_512))
|
||||
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && \
|
||||
( !defined(MBEDTLS_SSL_SESSION_TICKETS) || \
|
||||
( !defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) && \
|
||||
!defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) ) )
|
||||
#error "MBEDTLS_SSL_EARLY_DATA defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C) && \
|
||||
defined(MBEDTLS_SSL_MAX_EARLY_DATA_SIZE) && \
|
||||
((MBEDTLS_SSL_MAX_EARLY_DATA_SIZE < 0) || \
|
||||
(MBEDTLS_SSL_MAX_EARLY_DATA_SIZE > UINT32_MAX))
|
||||
#error "MBEDTLS_SSL_MAX_EARLY_DATA_SIZE must be in the range(0..UINT32_MAX)"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C)
|
||||
#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && !defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
#error "MBEDTLS_SSL_ASYNC_PRIVATE defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
/* TLS 1.2 and 1.3 require SHA-256 or SHA-384 (running handshake hash) */
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && \
|
||||
!(defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384))
|
||||
#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C)
|
||||
#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && \
|
||||
!( defined(MBEDTLS_SSL_PROTO_TLS1_2) || defined(MBEDTLS_SSL_PROTO_TLS1_3) )
|
||||
#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||
#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \
|
||||
!defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
|
||||
#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \
|
||||
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
|
||||
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
|
||||
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
|
||||
#error "MBEDTLS_SSL_DTLS_CONNECTION_ID defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
|
||||
defined(MBEDTLS_SSL_CID_IN_LEN_MAX) && \
|
||||
MBEDTLS_SSL_CID_IN_LEN_MAX > 255
|
||||
#error "MBEDTLS_SSL_CID_IN_LEN_MAX too large (max 255)"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
|
||||
defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) && \
|
||||
MBEDTLS_SSL_CID_OUT_LEN_MAX > 255
|
||||
#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_RENEGOTIATION) && \
|
||||
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#error "MBEDTLS_SSL_RENEGOTIATION defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TICKET_C) && \
|
||||
!( defined(PSA_WANT_ALG_CCM) || defined(PSA_WANT_ALG_GCM) || \
|
||||
defined(PSA_WANT_ALG_CHACHA20_POLY1305) )
|
||||
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH) && \
|
||||
MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH >= 256
|
||||
#error "MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH must be less than 256"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
|
||||
!defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
|
||||
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_USE_C) && \
|
||||
(!defined(MBEDTLS_ASN1_PARSE_C) || !defined(MBEDTLS_PK_PARSE_C))
|
||||
#error "MBEDTLS_X509_USE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CREATE_C) && \
|
||||
(!defined(MBEDTLS_ASN1_WRITE_C) || !defined(MBEDTLS_PK_PARSE_C))
|
||||
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
|
||||
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
|
||||
#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
|
||||
#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
|
||||
#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
|
||||
#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) && \
|
||||
( !defined(MBEDTLS_X509_CRT_PARSE_C) )
|
||||
#error "MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) )
|
||||
#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) && ( !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) )
|
||||
#error "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) && ( !defined(MBEDTLS_SSL_PROTO_TLS1_3) )
|
||||
#error "MBEDTLS_SSL_RECORD_SIZE_LIMIT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) && \
|
||||
!( defined(PSA_WANT_ALG_CCM) || defined(PSA_WANT_ALG_GCM) || \
|
||||
defined(PSA_WANT_ALG_CHACHA20_POLY1305) )
|
||||
#error "MBEDTLS_SSL_CONTEXT_SERIALIZATION defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
/* Reject attempts to enable options that have been removed and that could
|
||||
* cause a build to succeed but with features removed. */
|
||||
|
||||
#if defined(MBEDTLS_HAVEGE_C) //no-check-names
|
||||
#error "MBEDTLS_HAVEGE_C was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/2599"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) //no-check-names
|
||||
#error "MBEDTLS_SSL_HW_RECORD_ACCEL was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_SSL3) //no-check-names
|
||||
#error "MBEDTLS_SSL_PROTO_SSL3 (SSL v3.0 support) was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) //no-check-names
|
||||
#error "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO (SSL v2 ClientHello support) was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) //no-check-names
|
||||
#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT (compatibility with the buggy implementation of truncated HMAC in Mbed TLS up to 2.7) was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES) //no-check-names
|
||||
#error "MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES was removed in Mbed TLS 3.0. See the ChangeLog entry if you really need SHA-1-signed certificates."
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ZLIB_SUPPORT) //no-check-names
|
||||
#error "MBEDTLS_ZLIB_SUPPORT was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS) //no-check-names
|
||||
#error "MBEDTLS_CHECK_PARAMS was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4313"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_CID_PADDING_GRANULARITY) //no-check-names
|
||||
#error "MBEDTLS_SSL_CID_PADDING_GRANULARITY was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4335"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY) //no-check-names
|
||||
#error "MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4335"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) //no-check-names
|
||||
#error "MBEDTLS_SSL_TRUNCATED_HMAC was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4341"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PKCS7_C) && ( ( !defined(MBEDTLS_ASN1_PARSE_C) ) || \
|
||||
( !defined(MBEDTLS_PK_PARSE_C) ) || \
|
||||
( !defined(MBEDTLS_X509_CRT_PARSE_C) ) || \
|
||||
( !defined(MBEDTLS_X509_CRL_PARSE_C) ) || \
|
||||
( !defined(MBEDTLS_MD_C) ) )
|
||||
#error "MBEDTLS_PKCS7_C is defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
/* *INDENT-ON* */
|
||||
#endif /* MBEDTLS_CHECK_CONFIG_H */
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Mbed TLS configuration checks
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/* Apply the TF-PSA-Crypto configuration first. We need to do this
|
||||
* before <mbedtls/build_info.h>, because "mbedtls_config_check_before.h"
|
||||
* needs to run after the crypto config (including derived macros) is
|
||||
* finalized, but before the user's mbedtls config is applied. This way
|
||||
* it is possible to differentiate macros set by the user's mbedtls config
|
||||
* from macros set or derived by the crypto config. */
|
||||
#include <tf-psa-crypto/build_info.h>
|
||||
|
||||
/* Consistency checks on the user's configuration.
|
||||
* Check that it doesn't define macros that we assume are under full
|
||||
* control of the library, or options from past major versions that
|
||||
* no longer have any effect.
|
||||
* These headers are automatically generated. See
|
||||
* framework/scripts/mbedtls_framework/config_checks_generator.py
|
||||
*/
|
||||
#include "mbedtls_config_check_before.h"
|
||||
#define MBEDTLS_INCLUDE_AFTER_RAW_CONFIG "mbedtls_config_check_user.h"
|
||||
|
||||
#include <mbedtls/build_info.h>
|
||||
|
||||
/* Consistency checks in the configuration: check for incompatible options,
|
||||
* missing options when at least one of a set needs to be enabled, etc. */
|
||||
/* Manually written checks */
|
||||
#include "mbedtls_check_config.h"
|
||||
/* Automatically generated checks */
|
||||
#include "mbedtls_config_check_final.h"
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file mps_common.h
|
||||
*
|
||||
* \brief Common functions and macros used by MPS
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MPS_COMMON_H
|
||||
#define MBEDTLS_MPS_COMMON_H
|
||||
|
||||
#include "mps_error.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* \name SECTION: MPS Configuration
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
/*! This flag controls whether the MPS-internal components
|
||||
* (reader, writer, Layer 1-3) perform validation of the
|
||||
* expected abstract state at the entry of API calls.
|
||||
*
|
||||
* Context: All MPS API functions impose assumptions/preconditions on the
|
||||
* context on which they operate. For example, every structure has a notion of
|
||||
* state integrity which is established by `xxx_init()` and preserved by any
|
||||
* calls to the MPS API which satisfy their preconditions and either succeed,
|
||||
* or fail with an error code which is explicitly documented to not corrupt
|
||||
* structure integrity (such as WANT_READ and WANT_WRITE);
|
||||
* apart from `xxx_init()` any function assumes state integrity as a
|
||||
* precondition (but usually more). If any of the preconditions is violated,
|
||||
* the function's behavior is entirely undefined.
|
||||
* In addition to state integrity, all MPS structures have a more refined
|
||||
* notion of abstract state that the API operates on. For example, all layers
|
||||
* have a notion of 'abstract read state' which indicates if incoming data has
|
||||
* been passed to the user, e.g. through mps_l2_read_start() for Layer 2
|
||||
* or mps_l3_read() in Layer 3. After such a call, it doesn't make sense to
|
||||
* call these reading functions again until the incoming data has been
|
||||
* explicitly 'consumed', e.g. through mps_l2_read_consume() for Layer 2 or
|
||||
* mps_l3_read_consume() on Layer 3. However, even if it doesn't make sense,
|
||||
* it's a design choice whether the API should fail gracefully on such
|
||||
* non-sensical calls or not, and that's what this option is about:
|
||||
*
|
||||
* This option determines whether the expected abstract state
|
||||
* is part of the API preconditions or not: If the option is set,
|
||||
* then the abstract state is not part of the precondition and is
|
||||
* thus required to be validated by the implementation. If an unexpected
|
||||
* abstract state is encountered, the implementation must fail gracefully
|
||||
* with error #MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED.
|
||||
* Conversely, if this option is not set, then the expected abstract state
|
||||
* is included in the preconditions of the respective API calls, and
|
||||
* an implementation's behaviour is undefined if the abstract state is
|
||||
* not as expected.
|
||||
*
|
||||
* For example: Enabling this makes mps_l2_read_done() fail if
|
||||
* no incoming record is currently open; disabling this would
|
||||
* lead to undefined behavior in this case.
|
||||
*
|
||||
* Comment this to remove state validation.
|
||||
*/
|
||||
#define MBEDTLS_MPS_STATE_VALIDATION
|
||||
|
||||
/*! This flag enables/disables assertions on the internal state of MPS.
|
||||
*
|
||||
* Assertions are sanity checks that should never trigger when MPS
|
||||
* is used within the bounds of its API and preconditions.
|
||||
*
|
||||
* Enabling this increases security by limiting the scope of
|
||||
* potential bugs, but comes at the cost of increased code size.
|
||||
*
|
||||
* Note: So far, there is no guiding principle as to what
|
||||
* expected conditions merit an assertion, and which don't.
|
||||
*
|
||||
* Comment this to disable assertions.
|
||||
*/
|
||||
#define MBEDTLS_MPS_ENABLE_ASSERTIONS
|
||||
|
||||
/*! This flag controls whether tracing for MPS should be enabled. */
|
||||
//#define MBEDTLS_MPS_ENABLE_TRACE
|
||||
|
||||
#if defined(MBEDTLS_MPS_STATE_VALIDATION)
|
||||
|
||||
#define MBEDTLS_MPS_STATE_VALIDATE_RAW(cond, string) \
|
||||
do \
|
||||
{ \
|
||||
if (!(cond)) \
|
||||
{ \
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR, string); \
|
||||
MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else /* MBEDTLS_MPS_STATE_VALIDATION */
|
||||
|
||||
#define MBEDTLS_MPS_STATE_VALIDATE_RAW(cond, string) \
|
||||
do \
|
||||
{ \
|
||||
(cond); \
|
||||
} while (0)
|
||||
|
||||
#endif /* MBEDTLS_MPS_STATE_VALIDATION */
|
||||
|
||||
#if defined(MBEDTLS_MPS_ENABLE_ASSERTIONS)
|
||||
|
||||
#define MBEDTLS_MPS_ASSERT_RAW(cond, string) \
|
||||
do \
|
||||
{ \
|
||||
if (!(cond)) \
|
||||
{ \
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR, string); \
|
||||
MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_INTERNAL_ERROR); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else /* MBEDTLS_MPS_ENABLE_ASSERTIONS */
|
||||
|
||||
#define MBEDTLS_MPS_ASSERT_RAW(cond, string) do {} while (0)
|
||||
|
||||
#endif /* MBEDTLS_MPS_ENABLE_ASSERTIONS */
|
||||
|
||||
|
||||
/* \} name SECTION: MPS Configuration */
|
||||
|
||||
/**
|
||||
* \name SECTION: Common types
|
||||
*
|
||||
* Various common types used throughout MPS.
|
||||
* \{
|
||||
*/
|
||||
|
||||
/** \brief The type of buffer sizes and offsets used in MPS structures.
|
||||
*
|
||||
* This is an unsigned integer type that should be large enough to
|
||||
* hold the length of any buffer or message processed by MPS.
|
||||
*
|
||||
* The reason to pick a value as small as possible here is
|
||||
* to reduce the size of MPS structures.
|
||||
*
|
||||
* \warning Care has to be taken when using a narrower type
|
||||
* than ::mbedtls_mps_size_t here because of
|
||||
* potential truncation during conversion.
|
||||
*
|
||||
* \warning Handshake messages in TLS may be up to 2^24 ~ 16Mb in size.
|
||||
* If mbedtls_mps_[opt_]stored_size_t is smaller than that, the
|
||||
* maximum handshake message is restricted accordingly.
|
||||
*
|
||||
* For now, we use the default type of size_t throughout, and the use of
|
||||
* smaller types or different types for ::mbedtls_mps_size_t and
|
||||
* ::mbedtls_mps_stored_size_t is not yet supported.
|
||||
*
|
||||
*/
|
||||
typedef size_t mbedtls_mps_stored_size_t;
|
||||
#define MBEDTLS_MPS_STORED_SIZE_MAX (SIZE_MAX)
|
||||
|
||||
/** \brief The type of buffer sizes and offsets used in the MPS API
|
||||
* and implementation.
|
||||
*
|
||||
* This must be at least as wide as ::mbedtls_stored_size_t but
|
||||
* may be chosen to be strictly larger if more suitable for the
|
||||
* target architecture.
|
||||
*
|
||||
* For example, in a test build for ARM Thumb, using uint_fast16_t
|
||||
* instead of uint16_t reduced the code size from 1060 Byte to 962 Byte,
|
||||
* so almost 10%.
|
||||
*/
|
||||
typedef size_t mbedtls_mps_size_t;
|
||||
#define MBEDTLS_MPS_SIZE_MAX (SIZE_MAX)
|
||||
|
||||
#if MBEDTLS_MPS_STORED_SIZE_MAX > MBEDTLS_MPS_SIZE_MAX
|
||||
#error "Misconfiguration of mbedtls_mps_size_t and mbedtls_mps_stored_size_t."
|
||||
#endif
|
||||
|
||||
/* \} SECTION: Common types */
|
||||
|
||||
|
||||
#endif /* MBEDTLS_MPS_COMMON_H */
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file mps_error.h
|
||||
*
|
||||
* \brief Error codes used by MPS
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MPS_ERROR_H
|
||||
#define MBEDTLS_MPS_ERROR_H
|
||||
|
||||
|
||||
/* TODO: The error code allocation needs to be revisited:
|
||||
*
|
||||
* - Should we make (some of) the MPS Reader error codes public?
|
||||
* If so, we need to adjust MBEDTLS_MPS_READER_MAKE_ERROR() to hit
|
||||
* a gap in the Mbed TLS public error space.
|
||||
* If not, we have to make sure we don't forward those errors
|
||||
* at the level of the public API -- no risk at the moment as
|
||||
* long as MPS is an experimental component not accessible from
|
||||
* public API.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \name SECTION: MPS general error codes
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MPS_ERR_BASE
|
||||
#define MBEDTLS_MPS_ERR_BASE (0)
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_MPS_MAKE_ERROR(code) \
|
||||
(-(MBEDTLS_MPS_ERR_BASE | (code)))
|
||||
|
||||
#define MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED MBEDTLS_MPS_MAKE_ERROR(0x1)
|
||||
#define MBEDTLS_ERR_MPS_INTERNAL_ERROR MBEDTLS_MPS_MAKE_ERROR(0x2)
|
||||
|
||||
/* \} name SECTION: MPS general error codes */
|
||||
|
||||
/**
|
||||
* \name SECTION: MPS Reader error codes
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MPS_READER_ERR_BASE
|
||||
#define MBEDTLS_MPS_READER_ERR_BASE (1 << 8)
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_MPS_READER_MAKE_ERROR(code) \
|
||||
(-(MBEDTLS_MPS_READER_ERR_BASE | (code)))
|
||||
|
||||
/*! An attempt to reclaim the data buffer from a reader failed because
|
||||
* the user hasn't yet read and committed all of it. */
|
||||
#define MBEDTLS_ERR_MPS_READER_DATA_LEFT MBEDTLS_MPS_READER_MAKE_ERROR(0x1)
|
||||
|
||||
/*! An invalid argument was passed to the reader. */
|
||||
#define MBEDTLS_ERR_MPS_READER_INVALID_ARG MBEDTLS_MPS_READER_MAKE_ERROR(0x2)
|
||||
|
||||
/*! An attempt to move a reader to consuming mode through mbedtls_mps_reader_feed()
|
||||
* after pausing failed because the provided data is not sufficient to serve the
|
||||
* read requests that led to the pausing. */
|
||||
#define MBEDTLS_ERR_MPS_READER_NEED_MORE MBEDTLS_MPS_READER_MAKE_ERROR(0x3)
|
||||
|
||||
/*! A get request failed because not enough data is available in the reader. */
|
||||
#define MBEDTLS_ERR_MPS_READER_OUT_OF_DATA MBEDTLS_MPS_READER_MAKE_ERROR(0x4)
|
||||
|
||||
/*!< A get request after pausing and reactivating the reader failed because
|
||||
* the request is not in line with the request made prior to pausing. The user
|
||||
* must not change it's 'strategy' after pausing and reactivating a reader. */
|
||||
#define MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS MBEDTLS_MPS_READER_MAKE_ERROR(0x5)
|
||||
|
||||
/*! An attempt to reclaim the data buffer from a reader failed because the reader
|
||||
* has no accumulator it can use to backup the data that hasn't been processed. */
|
||||
#define MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR MBEDTLS_MPS_READER_MAKE_ERROR(0x6)
|
||||
|
||||
/*! An attempt to reclaim the data buffer from a reader failed because the
|
||||
* accumulator passed to the reader is not large enough to hold both the
|
||||
* data that hasn't been processed and the excess of the last read-request. */
|
||||
#define MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL MBEDTLS_MPS_READER_MAKE_ERROR(0x7)
|
||||
|
||||
/* \} name SECTION: MPS Reader error codes */
|
||||
|
||||
#endif /* MBEDTLS_MPS_ERROR_H */
|
||||
+538
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
* Message Processing Stack, Reader implementation
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
|
||||
#include "mps_reader.h"
|
||||
#include "mps_common.h"
|
||||
#include "mps_trace.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_MPS_ENABLE_TRACE)
|
||||
static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER;
|
||||
#endif /* MBEDTLS_MPS_ENABLE_TRACE */
|
||||
|
||||
/*
|
||||
* GENERAL NOTE ON CODING STYLE
|
||||
*
|
||||
* The following code intentionally separates memory loads
|
||||
* and stores from other operations (arithmetic or branches).
|
||||
* This leads to the introduction of many local variables
|
||||
* and significantly increases the C-code line count, but
|
||||
* should not increase the size of generated assembly.
|
||||
*
|
||||
* The reason for this is twofold:
|
||||
* (1) It will ease verification efforts using the VST
|
||||
* (Verified Software Toolchain)
|
||||
* whose program logic cannot directly reason
|
||||
* about instructions containing a load or store in
|
||||
* addition to other operations (e.g. *p = *q or
|
||||
* tmp = *p + 42).
|
||||
* (2) Operating on local variables and writing the results
|
||||
* back to the target contexts on success only
|
||||
* allows to maintain structure invariants even
|
||||
* on failure - this in turn has two benefits:
|
||||
* (2.a) If for some reason an error code is not caught
|
||||
* and operation continues, functions are nonetheless
|
||||
* called with sane contexts, reducing the risk
|
||||
* of dangerous behavior.
|
||||
* (2.b) Randomized testing is easier if structures
|
||||
* remain intact even in the face of failing
|
||||
* and/or non-sensical calls.
|
||||
* Moreover, it might even reduce code-size because
|
||||
* the compiler need not write back temporary results
|
||||
* to memory in case of failure.
|
||||
*
|
||||
*/
|
||||
|
||||
static inline int mps_reader_is_accumulating(
|
||||
mbedtls_mps_reader const *rd)
|
||||
{
|
||||
mbedtls_mps_size_t acc_remaining;
|
||||
if (rd->acc == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
acc_remaining = rd->acc_share.acc_remaining;
|
||||
return acc_remaining > 0;
|
||||
}
|
||||
|
||||
static inline int mps_reader_is_producing(
|
||||
mbedtls_mps_reader const *rd)
|
||||
{
|
||||
unsigned char *frag = rd->frag;
|
||||
return frag == NULL;
|
||||
}
|
||||
|
||||
static inline int mps_reader_is_consuming(
|
||||
mbedtls_mps_reader const *rd)
|
||||
{
|
||||
return !mps_reader_is_producing(rd);
|
||||
}
|
||||
|
||||
static inline mbedtls_mps_size_t mps_reader_get_fragment_offset(
|
||||
mbedtls_mps_reader const *rd)
|
||||
{
|
||||
unsigned char *acc = rd->acc;
|
||||
mbedtls_mps_size_t frag_offset;
|
||||
|
||||
if (acc == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
frag_offset = rd->acc_share.frag_offset;
|
||||
return frag_offset;
|
||||
}
|
||||
|
||||
static inline mbedtls_mps_size_t mps_reader_serving_from_accumulator(
|
||||
mbedtls_mps_reader const *rd)
|
||||
{
|
||||
mbedtls_mps_size_t frag_offset, end;
|
||||
|
||||
frag_offset = mps_reader_get_fragment_offset(rd);
|
||||
end = rd->end;
|
||||
|
||||
return end < frag_offset;
|
||||
}
|
||||
|
||||
static inline void mps_reader_zero(mbedtls_mps_reader *rd)
|
||||
{
|
||||
/* A plain memset() would likely be more efficient,
|
||||
* but the current way of zeroing makes it harder
|
||||
* to overlook fields which should not be zero-initialized.
|
||||
* It's also more suitable for FV efforts since it
|
||||
* doesn't require reasoning about structs being
|
||||
* interpreted as unstructured binary blobs. */
|
||||
static mbedtls_mps_reader const zero =
|
||||
{ .frag = NULL,
|
||||
.frag_len = 0,
|
||||
.commit = 0,
|
||||
.end = 0,
|
||||
.pending = 0,
|
||||
.acc = NULL,
|
||||
.acc_len = 0,
|
||||
.acc_available = 0,
|
||||
.acc_share = { .acc_remaining = 0 } };
|
||||
*rd = zero;
|
||||
}
|
||||
|
||||
int mbedtls_mps_reader_init(mbedtls_mps_reader *rd,
|
||||
unsigned char *acc,
|
||||
mbedtls_mps_size_t acc_len)
|
||||
{
|
||||
MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_init");
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"* Accumulator size: %u bytes", (unsigned) acc_len);
|
||||
mps_reader_zero(rd);
|
||||
rd->acc = acc;
|
||||
rd->acc_len = acc_len;
|
||||
MBEDTLS_MPS_TRACE_RETURN(0);
|
||||
}
|
||||
|
||||
int mbedtls_mps_reader_free(mbedtls_mps_reader *rd)
|
||||
{
|
||||
MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_free");
|
||||
mps_reader_zero(rd);
|
||||
MBEDTLS_MPS_TRACE_RETURN(0);
|
||||
}
|
||||
|
||||
int mbedtls_mps_reader_feed(mbedtls_mps_reader *rd,
|
||||
unsigned char *new_frag,
|
||||
mbedtls_mps_size_t new_frag_len)
|
||||
{
|
||||
mbedtls_mps_size_t copy_to_acc;
|
||||
MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_feed");
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"* Fragment length: %u bytes", (unsigned) new_frag_len);
|
||||
|
||||
if (new_frag == NULL) {
|
||||
MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_READER_INVALID_ARG);
|
||||
}
|
||||
|
||||
MBEDTLS_MPS_STATE_VALIDATE_RAW(mps_reader_is_producing(
|
||||
rd),
|
||||
"mbedtls_mps_reader_feed() requires reader to be in producing mode");
|
||||
|
||||
if (mps_reader_is_accumulating(rd)) {
|
||||
unsigned char *acc = rd->acc;
|
||||
mbedtls_mps_size_t acc_remaining = rd->acc_share.acc_remaining;
|
||||
mbedtls_mps_size_t acc_available = rd->acc_available;
|
||||
|
||||
/* Skip over parts of the accumulator that have already been filled. */
|
||||
acc += acc_available;
|
||||
|
||||
copy_to_acc = acc_remaining;
|
||||
if (copy_to_acc > new_frag_len) {
|
||||
copy_to_acc = new_frag_len;
|
||||
}
|
||||
|
||||
/* Copy new contents to accumulator. */
|
||||
memcpy(acc, new_frag, copy_to_acc);
|
||||
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"Copy new data of size %u of %u into accumulator at offset %u",
|
||||
(unsigned) copy_to_acc, (unsigned) new_frag_len,
|
||||
(unsigned) acc_available);
|
||||
|
||||
/* Check if, with the new fragment, we have enough data. */
|
||||
acc_remaining -= copy_to_acc;
|
||||
if (acc_remaining > 0) {
|
||||
/* We need to accumulate more data. Stay in producing mode. */
|
||||
acc_available += copy_to_acc;
|
||||
rd->acc_share.acc_remaining = acc_remaining;
|
||||
rd->acc_available = acc_available;
|
||||
MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_READER_NEED_MORE);
|
||||
}
|
||||
|
||||
/* We have filled the accumulator: Move to consuming mode. */
|
||||
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"Enough data available to serve user request");
|
||||
|
||||
/* Remember overlap of accumulator and fragment. */
|
||||
rd->acc_share.frag_offset = acc_available;
|
||||
acc_available += copy_to_acc;
|
||||
rd->acc_available = acc_available;
|
||||
} else { /* Not accumulating */
|
||||
rd->acc_share.frag_offset = 0;
|
||||
}
|
||||
|
||||
rd->frag = new_frag;
|
||||
rd->frag_len = new_frag_len;
|
||||
rd->commit = 0;
|
||||
rd->end = 0;
|
||||
MBEDTLS_MPS_TRACE_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int mbedtls_mps_reader_get(mbedtls_mps_reader *rd,
|
||||
mbedtls_mps_size_t desired,
|
||||
unsigned char **buffer,
|
||||
mbedtls_mps_size_t *buflen)
|
||||
{
|
||||
unsigned char *frag;
|
||||
mbedtls_mps_size_t frag_len, frag_offset, end, frag_fetched, frag_remaining;
|
||||
MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_get");
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"* Bytes requested: %u", (unsigned) desired);
|
||||
|
||||
MBEDTLS_MPS_STATE_VALIDATE_RAW(mps_reader_is_consuming(
|
||||
rd),
|
||||
"mbedtls_mps_reader_get() requires reader to be in consuming mode");
|
||||
|
||||
end = rd->end;
|
||||
frag_offset = mps_reader_get_fragment_offset(rd);
|
||||
|
||||
/* Check if we're still serving from the accumulator. */
|
||||
if (mps_reader_serving_from_accumulator(rd)) {
|
||||
/* Illustration of supported and unsupported cases:
|
||||
*
|
||||
* - Allowed #1
|
||||
*
|
||||
* +-----------------------------------+
|
||||
* | frag |
|
||||
* +-----------------------------------+
|
||||
*
|
||||
* end end+desired
|
||||
* | |
|
||||
* +-----v-------v-------------+
|
||||
* | acc |
|
||||
* +---------------------------+
|
||||
* | |
|
||||
* frag_offset acc_available
|
||||
*
|
||||
* - Allowed #2
|
||||
*
|
||||
* +-----------------------------------+
|
||||
* | frag |
|
||||
* +-----------------------------------+
|
||||
*
|
||||
* end end+desired
|
||||
* | |
|
||||
* +----------v----------------v
|
||||
* | acc |
|
||||
* +---------------------------+
|
||||
* | |
|
||||
* frag_offset acc_available
|
||||
*
|
||||
* - Not allowed #1 (could be served, but we don't actually use it):
|
||||
*
|
||||
* +-----------------------------------+
|
||||
* | frag |
|
||||
* +-----------------------------------+
|
||||
*
|
||||
* end end+desired
|
||||
* | |
|
||||
* +------v-------------v------+
|
||||
* | acc |
|
||||
* +---------------------------+
|
||||
* | |
|
||||
* frag_offset acc_available
|
||||
*
|
||||
*
|
||||
* - Not allowed #2 (can't be served with a contiguous buffer):
|
||||
*
|
||||
* +-----------------------------------+
|
||||
* | frag |
|
||||
* +-----------------------------------+
|
||||
*
|
||||
* end end + desired
|
||||
* | |
|
||||
* +------v--------------------+ v
|
||||
* | acc |
|
||||
* +---------------------------+
|
||||
* | |
|
||||
* frag_offset acc_available
|
||||
*
|
||||
* In case of Allowed #2 we're switching to serve from
|
||||
* `frag` starting from the next call to mbedtls_mps_reader_get().
|
||||
*/
|
||||
|
||||
unsigned char *acc;
|
||||
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"Serve the request from the accumulator");
|
||||
if (frag_offset - end < desired) {
|
||||
mbedtls_mps_size_t acc_available;
|
||||
acc_available = rd->acc_available;
|
||||
if (acc_available - end != desired) {
|
||||
/* It might be possible to serve some of these situations by
|
||||
* making additional space in the accumulator, removing those
|
||||
* parts that have already been committed.
|
||||
* On the other hand, this brings additional complexity and
|
||||
* enlarges the code size, while there doesn't seem to be a use
|
||||
* case where we don't attempt exactly the same `get` calls when
|
||||
* resuming on a reader than what we tried before pausing it.
|
||||
* If we believe we adhere to this restricted usage throughout
|
||||
* the library, this check is a good opportunity to
|
||||
* validate this. */
|
||||
MBEDTLS_MPS_TRACE_RETURN(
|
||||
MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS);
|
||||
}
|
||||
}
|
||||
|
||||
acc = rd->acc;
|
||||
acc += end;
|
||||
|
||||
*buffer = acc;
|
||||
if (buflen != NULL) {
|
||||
*buflen = desired;
|
||||
}
|
||||
|
||||
end += desired;
|
||||
rd->end = end;
|
||||
rd->pending = 0;
|
||||
|
||||
MBEDTLS_MPS_TRACE_RETURN(0);
|
||||
}
|
||||
|
||||
/* Attempt to serve the request from the current fragment */
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"Serve the request from the current fragment.");
|
||||
|
||||
frag_len = rd->frag_len;
|
||||
frag_fetched = end - frag_offset; /* The amount of data from the current
|
||||
* fragment that has already been passed
|
||||
* to the user. */
|
||||
frag_remaining = frag_len - frag_fetched; /* Remaining data in fragment */
|
||||
|
||||
/* Check if we can serve the read request from the fragment. */
|
||||
if (frag_remaining < desired) {
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"There's not enough data in the current fragment "
|
||||
"to serve the request.");
|
||||
/* There's not enough data in the current fragment,
|
||||
* so either just RETURN what we have or fail. */
|
||||
if (buflen == NULL) {
|
||||
if (frag_remaining > 0) {
|
||||
rd->pending = desired - frag_remaining;
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"Remember to collect %u bytes before re-opening",
|
||||
(unsigned) rd->pending);
|
||||
}
|
||||
MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
|
||||
}
|
||||
|
||||
desired = frag_remaining;
|
||||
}
|
||||
|
||||
/* There's enough data in the current fragment to serve the
|
||||
* (potentially modified) read request. */
|
||||
|
||||
frag = rd->frag;
|
||||
frag += frag_fetched;
|
||||
|
||||
*buffer = frag;
|
||||
if (buflen != NULL) {
|
||||
*buflen = desired;
|
||||
}
|
||||
|
||||
end += desired;
|
||||
rd->end = end;
|
||||
rd->pending = 0;
|
||||
MBEDTLS_MPS_TRACE_RETURN(0);
|
||||
}
|
||||
|
||||
int mbedtls_mps_reader_commit(mbedtls_mps_reader *rd)
|
||||
{
|
||||
mbedtls_mps_size_t end;
|
||||
MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_commit");
|
||||
MBEDTLS_MPS_STATE_VALIDATE_RAW(mps_reader_is_consuming(
|
||||
rd),
|
||||
"mbedtls_mps_reader_commit() requires reader to be in consuming mode");
|
||||
|
||||
end = rd->end;
|
||||
rd->commit = end;
|
||||
|
||||
MBEDTLS_MPS_TRACE_RETURN(0);
|
||||
}
|
||||
|
||||
int mbedtls_mps_reader_reclaim(mbedtls_mps_reader *rd,
|
||||
int *paused)
|
||||
{
|
||||
unsigned char *frag, *acc;
|
||||
mbedtls_mps_size_t pending, commit;
|
||||
mbedtls_mps_size_t acc_len, frag_offset, frag_len;
|
||||
MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_reclaim");
|
||||
|
||||
if (paused != NULL) {
|
||||
*paused = 0;
|
||||
}
|
||||
|
||||
MBEDTLS_MPS_STATE_VALIDATE_RAW(mps_reader_is_consuming(
|
||||
rd),
|
||||
"mbedtls_mps_reader_reclaim() requires reader to be in consuming mode");
|
||||
|
||||
frag = rd->frag;
|
||||
acc = rd->acc;
|
||||
pending = rd->pending;
|
||||
commit = rd->commit;
|
||||
frag_len = rd->frag_len;
|
||||
|
||||
frag_offset = mps_reader_get_fragment_offset(rd);
|
||||
|
||||
if (pending == 0) {
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"No unsatisfied read-request has been logged.");
|
||||
|
||||
/* Check if there's data left to be consumed. */
|
||||
if (commit < frag_offset || commit - frag_offset < frag_len) {
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"There is data left to be consumed.");
|
||||
rd->end = commit;
|
||||
MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_READER_DATA_LEFT);
|
||||
}
|
||||
|
||||
rd->acc_available = 0;
|
||||
rd->acc_share.acc_remaining = 0;
|
||||
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"Fragment has been fully processed and committed.");
|
||||
} else {
|
||||
int overflow;
|
||||
|
||||
mbedtls_mps_size_t acc_backup_offset;
|
||||
mbedtls_mps_size_t acc_backup_len;
|
||||
mbedtls_mps_size_t frag_backup_offset;
|
||||
mbedtls_mps_size_t frag_backup_len;
|
||||
|
||||
mbedtls_mps_size_t backup_len;
|
||||
mbedtls_mps_size_t acc_len_needed;
|
||||
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"There has been an unsatisfied read with %u bytes overhead.",
|
||||
(unsigned) pending);
|
||||
|
||||
if (acc == NULL) {
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"No accumulator present");
|
||||
MBEDTLS_MPS_TRACE_RETURN(
|
||||
MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR);
|
||||
}
|
||||
acc_len = rd->acc_len;
|
||||
|
||||
/* Check if the upper layer has already fetched
|
||||
* and committed the contents of the accumulator. */
|
||||
if (commit < frag_offset) {
|
||||
/* No, accumulator is still being processed. */
|
||||
frag_backup_offset = 0;
|
||||
frag_backup_len = frag_len;
|
||||
acc_backup_offset = commit;
|
||||
acc_backup_len = frag_offset - commit;
|
||||
} else {
|
||||
/* Yes, the accumulator is already processed. */
|
||||
frag_backup_offset = commit - frag_offset;
|
||||
frag_backup_len = frag_len - frag_backup_offset;
|
||||
acc_backup_offset = 0;
|
||||
acc_backup_len = 0;
|
||||
}
|
||||
|
||||
backup_len = acc_backup_len + frag_backup_len;
|
||||
acc_len_needed = backup_len + pending;
|
||||
|
||||
overflow = 0;
|
||||
overflow |= (backup_len < acc_backup_len);
|
||||
overflow |= (acc_len_needed < backup_len);
|
||||
|
||||
if (overflow || acc_len < acc_len_needed) {
|
||||
/* Except for the different return code, we behave as if
|
||||
* there hadn't been a call to mbedtls_mps_reader_get()
|
||||
* since the last commit. */
|
||||
rd->end = commit;
|
||||
rd->pending = 0;
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR,
|
||||
"The accumulator is too small to handle the backup.");
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR,
|
||||
"* Size: %u", (unsigned) acc_len);
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR,
|
||||
"* Needed: %u (%u + %u)",
|
||||
(unsigned) acc_len_needed,
|
||||
(unsigned) backup_len, (unsigned) pending);
|
||||
MBEDTLS_MPS_TRACE_RETURN(
|
||||
MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL);
|
||||
}
|
||||
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"Fragment backup: %u", (unsigned) frag_backup_len);
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"Accumulator backup: %u", (unsigned) acc_backup_len);
|
||||
|
||||
/* Move uncommitted parts from the accumulator to the front
|
||||
* of the accumulator. */
|
||||
memmove(acc, acc + acc_backup_offset, acc_backup_len);
|
||||
|
||||
/* Copy uncommitted parts of the current fragment to the
|
||||
* accumulator. */
|
||||
memcpy(acc + acc_backup_len,
|
||||
frag + frag_backup_offset, frag_backup_len);
|
||||
|
||||
rd->acc_available = backup_len;
|
||||
rd->acc_share.acc_remaining = pending;
|
||||
|
||||
if (paused != NULL) {
|
||||
*paused = 1;
|
||||
}
|
||||
}
|
||||
|
||||
rd->frag = NULL;
|
||||
rd->frag_len = 0;
|
||||
|
||||
rd->commit = 0;
|
||||
rd->end = 0;
|
||||
rd->pending = 0;
|
||||
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
"Final state: aa %u, al %u, ar %u",
|
||||
(unsigned) rd->acc_available, (unsigned) rd->acc_len,
|
||||
(unsigned) rd->acc_share.acc_remaining);
|
||||
MBEDTLS_MPS_TRACE_RETURN(0);
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
+366
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file mps_reader.h
|
||||
*
|
||||
* \brief This file defines reader objects, which together with their
|
||||
* sibling writer objects form the basis for the communication
|
||||
* between the various layers of the Mbed TLS messaging stack,
|
||||
* as well as the communication between the messaging stack and
|
||||
* the (D)TLS handshake protocol implementation.
|
||||
*
|
||||
* Readers provide a means of transferring incoming data from
|
||||
* a 'producer' providing it in chunks of arbitrary size, to
|
||||
* a 'consumer' which fetches and processes it in chunks of
|
||||
* again arbitrary, and potentially different, size.
|
||||
*
|
||||
* Readers can thus be seen as datagram-to-stream converters,
|
||||
* and they abstract away the following two tasks from the user:
|
||||
* 1. The pointer arithmetic of stepping through a producer-
|
||||
* provided chunk in smaller chunks.
|
||||
* 2. The merging of incoming data chunks in case the
|
||||
* consumer requests data in larger chunks than what the
|
||||
* producer provides.
|
||||
*
|
||||
* The basic abstract flow of operation is the following:
|
||||
* - Initially, the reader is in 'producing mode'.
|
||||
* - The producer hands an incoming data buffer to the reader,
|
||||
* moving it from 'producing' to 'consuming' mode.
|
||||
* - The consumer subsequently fetches and processes the buffer
|
||||
* content. Once that's done -- or partially done and a consumer's
|
||||
* request can't be fulfilled -- the producer revokes the reader's
|
||||
* access to the incoming data buffer, putting the reader back to
|
||||
* producing mode.
|
||||
* - The producer subsequently gathers more incoming data and hands
|
||||
* it to the reader until it switches back to consuming mode
|
||||
* if enough data is available for the last consumer request to
|
||||
* be satisfiable.
|
||||
* - Repeat the above.
|
||||
*
|
||||
* The abstract states of the reader from the producer's and
|
||||
* consumer's perspective are as follows:
|
||||
*
|
||||
* - From the perspective of the consumer, the state of the
|
||||
* reader consists of the following:
|
||||
* - A byte stream representing (concatenation of) the data
|
||||
* received through calls to mbedtls_mps_reader_get(),
|
||||
* - A marker within that byte stream indicating which data
|
||||
* can be considered processed, and hence need not be retained,
|
||||
* when the reader is passed back to the producer via
|
||||
* mbedtls_mps_reader_reclaim().
|
||||
* The marker is set via mbedtls_mps_reader_commit()
|
||||
* which places it at the end of the current byte stream.
|
||||
* The consumer need not be aware of the distinction between consumer
|
||||
* and producer mode, because it only interfaces with the reader
|
||||
* when the latter is in consuming mode.
|
||||
*
|
||||
* - From the perspective of the producer, the reader's state is one of:
|
||||
* - Attached: The reader is in consuming mode.
|
||||
* - Unset: No incoming data buffer is currently managed by the reader,
|
||||
* and all previously handed incoming data buffers have been
|
||||
* fully processed. More data needs to be fed into the reader
|
||||
* via mbedtls_mps_reader_feed().
|
||||
*
|
||||
* - Accumulating: No incoming data buffer is currently managed by the
|
||||
* reader, but some data from the previous incoming data
|
||||
* buffer hasn't been processed yet and is internally
|
||||
* held back.
|
||||
* The Attached state belongs to consuming mode, while the Unset and
|
||||
* Accumulating states belong to producing mode.
|
||||
*
|
||||
* Transitioning from the Unset or Accumulating state to Attached is
|
||||
* done via successful calls to mbedtls_mps_reader_feed(), while
|
||||
* transitioning from Attached to either Unset or Accumulating (depending
|
||||
* on what has been processed) is done via mbedtls_mps_reader_reclaim().
|
||||
*
|
||||
* The following diagram depicts the producer-state progression:
|
||||
*
|
||||
* +------------------+ reclaim
|
||||
* | Unset +<-------------------------------------+ get
|
||||
* +--------|---------+ | +------+
|
||||
* | | | |
|
||||
* | | | |
|
||||
* | feed +---------+---+--+ |
|
||||
* +--------------------------------------> <---+
|
||||
* | Attached |
|
||||
* +--------------------------------------> <---+
|
||||
* | feed, enough data available +---------+---+--+ |
|
||||
* | to serve previous consumer request | | |
|
||||
* | | | |
|
||||
* +--------+---------+ | +------+
|
||||
* +----> Accumulating |<-------------------------------------+ commit
|
||||
* | +---+--------------+ reclaim, previous read request
|
||||
* | | couldn't be fulfilled
|
||||
* | |
|
||||
* +--------+
|
||||
* feed, need more data to serve
|
||||
* previous consumer request
|
||||
* |
|
||||
* |
|
||||
* producing mode | consuming mode
|
||||
* |
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_READER_H
|
||||
#define MBEDTLS_READER_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mps_common.h"
|
||||
#include "mps_error.h"
|
||||
|
||||
struct mbedtls_mps_reader;
|
||||
typedef struct mbedtls_mps_reader mbedtls_mps_reader;
|
||||
|
||||
/*
|
||||
* Structure definitions
|
||||
*/
|
||||
|
||||
struct mbedtls_mps_reader {
|
||||
unsigned char *frag; /*!< The fragment of incoming data managed by
|
||||
* the reader; it is provided to the reader
|
||||
* through mbedtls_mps_reader_feed(). The reader
|
||||
* does not own the fragment and does not
|
||||
* perform any allocation operations on it,
|
||||
* but does have read and write access to it.
|
||||
*
|
||||
* The reader is in consuming mode if
|
||||
* and only if \c frag is not \c NULL. */
|
||||
mbedtls_mps_stored_size_t frag_len;
|
||||
/*!< The length of the current fragment.
|
||||
* Must be 0 if \c frag == \c NULL. */
|
||||
mbedtls_mps_stored_size_t commit;
|
||||
/*!< The offset of the last commit, relative
|
||||
* to the first byte in the fragment, if
|
||||
* no accumulator is present. If an accumulator
|
||||
* is present, it is viewed as a prefix to the
|
||||
* current fragment, and this variable contains
|
||||
* an offset from the beginning of the accumulator.
|
||||
*
|
||||
* This is only used when the reader is in
|
||||
* consuming mode, i.e. \c frag != \c NULL;
|
||||
* otherwise, its value is \c 0. */
|
||||
mbedtls_mps_stored_size_t end;
|
||||
/*!< The offset of the end of the last chunk
|
||||
* passed to the user through a call to
|
||||
* mbedtls_mps_reader_get(), relative to the first
|
||||
* byte in the fragment, if no accumulator is
|
||||
* present. If an accumulator is present, it is
|
||||
* viewed as a prefix to the current fragment, and
|
||||
* this variable contains an offset from the
|
||||
* beginning of the accumulator.
|
||||
*
|
||||
* This is only used when the reader is in
|
||||
* consuming mode, i.e. \c frag != \c NULL;
|
||||
* otherwise, its value is \c 0. */
|
||||
mbedtls_mps_stored_size_t pending;
|
||||
/*!< The amount of incoming data missing on the
|
||||
* last call to mbedtls_mps_reader_get().
|
||||
* In particular, it is \c 0 if the last call
|
||||
* was successful.
|
||||
* If a reader is reclaimed after an
|
||||
* unsuccessful call to mbedtls_mps_reader_get(),
|
||||
* this variable is used to have the reader
|
||||
* remember how much data should be accumulated
|
||||
* so that the call to mbedtls_mps_reader_get()
|
||||
* succeeds next time.
|
||||
* This is only used when the reader is in
|
||||
* consuming mode, i.e. \c frag != \c NULL;
|
||||
* otherwise, its value is \c 0. */
|
||||
|
||||
/* The accumulator is only needed if we need to be able to pause
|
||||
* the reader. A few bytes could be saved by moving this to a
|
||||
* separate struct and using a pointer here. */
|
||||
|
||||
unsigned char *acc; /*!< The accumulator is used to gather incoming
|
||||
* data if a read-request via mbedtls_mps_reader_get()
|
||||
* cannot be served from the current fragment. */
|
||||
mbedtls_mps_stored_size_t acc_len;
|
||||
/*!< The total size of the accumulator. */
|
||||
mbedtls_mps_stored_size_t acc_available;
|
||||
/*!< The number of bytes currently gathered in
|
||||
* the accumulator. This is both used in
|
||||
* producing and in consuming mode:
|
||||
* While producing, it is increased until
|
||||
* it reaches the value of \c acc_remaining below.
|
||||
* While consuming, it is used to judge if a
|
||||
* get request can be served from the
|
||||
* accumulator or not.
|
||||
* Must not be larger than \c acc_len. */
|
||||
union {
|
||||
mbedtls_mps_stored_size_t acc_remaining;
|
||||
/*!< This indicates the amount of data still
|
||||
* to be gathered in the accumulator. It is
|
||||
* only used in producing mode.
|
||||
* Must be at most acc_len - acc_available. */
|
||||
mbedtls_mps_stored_size_t frag_offset;
|
||||
/*!< If an accumulator is present and in use, this
|
||||
* field indicates the offset of the current
|
||||
* fragment from the beginning of the
|
||||
* accumulator. If no accumulator is present
|
||||
* or the accumulator is not in use, this is \c 0.
|
||||
* It is only used in consuming mode.
|
||||
* Must not be larger than \c acc_available. */
|
||||
} acc_share;
|
||||
};
|
||||
|
||||
/*
|
||||
* API organization:
|
||||
* A reader object is usually prepared and maintained
|
||||
* by some lower layer and passed for usage to an upper
|
||||
* layer, and the API naturally splits according to which
|
||||
* layer is supposed to use the respective functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Maintenance API (Lower layer)
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Initialize a reader object
|
||||
*
|
||||
* \param reader The reader to be initialized.
|
||||
* \param acc The buffer to be used as a temporary accumulator
|
||||
* in case get requests through mbedtls_mps_reader_get()
|
||||
* exceed the buffer provided by mbedtls_mps_reader_feed().
|
||||
* This buffer is owned by the caller and exclusive use
|
||||
* for reading and writing is given to the reader for the
|
||||
* duration of the reader's lifetime. It is thus the caller's
|
||||
* responsibility to maintain (and not touch) the buffer for
|
||||
* the lifetime of the reader, and to properly zeroize and
|
||||
* free the memory after the reader has been destroyed.
|
||||
* \param acc_len The size in Bytes of \p acc.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_mps_reader_init(mbedtls_mps_reader *reader,
|
||||
unsigned char *acc,
|
||||
mbedtls_mps_size_t acc_len);
|
||||
|
||||
/**
|
||||
* \brief Free a reader object
|
||||
*
|
||||
* \param reader The reader to be freed.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_mps_reader_free(mbedtls_mps_reader *reader);
|
||||
|
||||
/**
|
||||
* \brief Pass chunk of data for the reader to manage.
|
||||
*
|
||||
* \param reader The reader context to use. The reader must be
|
||||
* in producing mode.
|
||||
* \param buf The buffer to be managed by the reader.
|
||||
* \param buflen The size in Bytes of \p buffer.
|
||||
*
|
||||
* \return \c 0 on success. In this case, the reader will be
|
||||
* moved to consuming mode and obtains read access
|
||||
* of \p buf until mbedtls_mps_reader_reclaim()
|
||||
* is called. It is the responsibility of the caller
|
||||
* to ensure that the \p buf persists and is not changed
|
||||
* between successful calls to mbedtls_mps_reader_feed()
|
||||
* and mbedtls_mps_reader_reclaim().
|
||||
* \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
|
||||
* required to fulfill a previous request to mbedtls_mps_reader_get().
|
||||
* In this case, the reader remains in producing mode and
|
||||
* takes no ownership of the provided buffer (an internal copy
|
||||
* is made instead).
|
||||
* \return Another negative \c MBEDTLS_ERR_READER_XXX error code on
|
||||
* different kinds of failures.
|
||||
*/
|
||||
int mbedtls_mps_reader_feed(mbedtls_mps_reader *reader,
|
||||
unsigned char *buf,
|
||||
mbedtls_mps_size_t buflen);
|
||||
|
||||
/**
|
||||
* \brief Reclaim reader's access to the current input buffer.
|
||||
*
|
||||
* \param reader The reader context to use. The reader must be
|
||||
* in consuming mode.
|
||||
* \param paused If not \c NULL, the integer at address \p paused will be
|
||||
* modified to indicate whether the reader has been paused
|
||||
* (value \c 1) or not (value \c 0). Pausing happens if there
|
||||
* is uncommitted data and a previous request to
|
||||
* mbedtls_mps_reader_get() has exceeded the bounds of the
|
||||
* input buffer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_mps_reader_reclaim(mbedtls_mps_reader *reader,
|
||||
int *paused);
|
||||
|
||||
/*
|
||||
* Usage API (Upper layer)
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Request data from the reader.
|
||||
*
|
||||
* \param reader The reader context to use. The reader must
|
||||
* be in consuming mode.
|
||||
* \param desired The desired amount of data to be read, in Bytes.
|
||||
* \param buffer The address to store the buffer pointer in.
|
||||
* This must not be \c NULL.
|
||||
* \param buflen The address to store the actual buffer
|
||||
* length in, or \c NULL.
|
||||
*
|
||||
* \return \c 0 on success. In this case, \c *buf holds the
|
||||
* address of a buffer of size \c *buflen
|
||||
* (if \c buflen != \c NULL) or \c desired
|
||||
* (if \c buflen == \c NULL). The user has read access
|
||||
* to the buffer and guarantee of stability of the data
|
||||
* until the next call to mbedtls_mps_reader_reclaim().
|
||||
* \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
|
||||
* data available to serve the get request. In this case, the
|
||||
* reader remains intact and in consuming mode, and the consumer
|
||||
* should retry the call after a successful cycle of
|
||||
* mbedtls_mps_reader_reclaim() and mbedtls_mps_reader_feed().
|
||||
* If, after such a cycle, the consumer requests a different
|
||||
* amount of data, the result is implementation-defined;
|
||||
* progress is guaranteed only if the same amount of data
|
||||
* is requested after a mbedtls_mps_reader_reclaim() and
|
||||
* mbedtls_mps_reader_feed() cycle.
|
||||
* \return Another negative \c MBEDTLS_ERR_READER_XXX error
|
||||
* code for different kinds of failure.
|
||||
*
|
||||
* \note Passing \c NULL as \p buflen is a convenient way to
|
||||
* indicate that fragmentation is not tolerated.
|
||||
* It's functionally equivalent to passing a valid
|
||||
* address as buflen and checking \c *buflen == \c desired
|
||||
* afterwards.
|
||||
*/
|
||||
int mbedtls_mps_reader_get(mbedtls_mps_reader *reader,
|
||||
mbedtls_mps_size_t desired,
|
||||
unsigned char **buffer,
|
||||
mbedtls_mps_size_t *buflen);
|
||||
|
||||
/**
|
||||
* \brief Mark data obtained from mbedtls_mps_reader_get() as processed.
|
||||
*
|
||||
* This call indicates that all data received from prior calls to
|
||||
* mbedtls_mps_reader_get() has been or will have been
|
||||
* processed when mbedtls_mps_reader_reclaim() is called,
|
||||
* and thus need not be backed up.
|
||||
*
|
||||
* This function has no user observable effect until
|
||||
* mbedtls_mps_reader_reclaim() is called. In particular,
|
||||
* buffers received from mbedtls_mps_reader_get() remain
|
||||
* valid until mbedtls_mps_reader_reclaim() is called.
|
||||
*
|
||||
* \param reader The reader context to use.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_mps_reader_commit(mbedtls_mps_reader *reader);
|
||||
|
||||
#endif /* MBEDTLS_READER_H */
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Message Processing Stack, Trace module
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
|
||||
#include "mps_common.h"
|
||||
|
||||
#if defined(MBEDTLS_MPS_ENABLE_TRACE)
|
||||
|
||||
#include "mps_trace.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
static int trace_depth = 0;
|
||||
|
||||
#define color_default "\x1B[0m"
|
||||
#define color_red "\x1B[1;31m"
|
||||
#define color_green "\x1B[1;32m"
|
||||
#define color_yellow "\x1B[1;33m"
|
||||
#define color_blue "\x1B[1;34m"
|
||||
#define color_magenta "\x1B[1;35m"
|
||||
#define color_cyan "\x1B[1;36m"
|
||||
#define color_white "\x1B[1;37m"
|
||||
|
||||
static char const *colors[] =
|
||||
{
|
||||
color_default,
|
||||
color_green,
|
||||
color_yellow,
|
||||
color_magenta,
|
||||
color_cyan,
|
||||
color_blue,
|
||||
color_white
|
||||
};
|
||||
|
||||
#define MPS_TRACE_BUF_SIZE 100
|
||||
|
||||
void mbedtls_mps_trace_print_msg(int id, int line, const char *format, ...)
|
||||
{
|
||||
int ret;
|
||||
char str[MPS_TRACE_BUF_SIZE];
|
||||
va_list argp;
|
||||
va_start(argp, format);
|
||||
ret = mbedtls_vsnprintf(str, MPS_TRACE_BUF_SIZE, format, argp);
|
||||
va_end(argp);
|
||||
|
||||
if (ret >= 0 && ret < MPS_TRACE_BUF_SIZE) {
|
||||
str[ret] = '\0';
|
||||
mbedtls_printf("[%d|L%d]: %s\n", id, line, str);
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_mps_trace_get_depth()
|
||||
{
|
||||
return trace_depth;
|
||||
}
|
||||
void mbedtls_mps_trace_dec_depth()
|
||||
{
|
||||
trace_depth--;
|
||||
}
|
||||
void mbedtls_mps_trace_inc_depth()
|
||||
{
|
||||
trace_depth++;
|
||||
}
|
||||
|
||||
void mbedtls_mps_trace_color(int id)
|
||||
{
|
||||
if (id > (int) (sizeof(colors) / sizeof(*colors))) {
|
||||
return;
|
||||
}
|
||||
printf("%s", colors[id]);
|
||||
}
|
||||
|
||||
void mbedtls_mps_trace_indent(int level, mbedtls_mps_trace_type ty)
|
||||
{
|
||||
if (level > 0) {
|
||||
while (--level) {
|
||||
printf("| ");
|
||||
}
|
||||
|
||||
printf("| ");
|
||||
}
|
||||
|
||||
switch (ty) {
|
||||
case MBEDTLS_MPS_TRACE_TYPE_COMMENT:
|
||||
mbedtls_printf("@ ");
|
||||
break;
|
||||
|
||||
case MBEDTLS_MPS_TRACE_TYPE_CALL:
|
||||
mbedtls_printf("+--> ");
|
||||
break;
|
||||
|
||||
case MBEDTLS_MPS_TRACE_TYPE_ERROR:
|
||||
mbedtls_printf("E ");
|
||||
break;
|
||||
|
||||
case MBEDTLS_MPS_TRACE_TYPE_RETURN:
|
||||
mbedtls_printf("< ");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_MPS_ENABLE_TRACE */
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file mps_trace.h
|
||||
*
|
||||
* \brief Tracing module for MPS
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H
|
||||
#define MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H
|
||||
|
||||
#include "ssl_misc.h"
|
||||
#include "mps_common.h"
|
||||
#include "mps_trace.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if defined(MBEDTLS_MPS_ENABLE_TRACE)
|
||||
|
||||
/*
|
||||
* Adapt this to enable/disable tracing output
|
||||
* from the various layers of the MPS.
|
||||
*/
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_1
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_2
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_3
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_4
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_READER
|
||||
#define MBEDTLS_MPS_TRACE_ENABLE_WRITER
|
||||
|
||||
/*
|
||||
* To use the existing trace module, only change
|
||||
* MBEDTLS_MPS_TRACE_ENABLE_XXX above, but don't modify the
|
||||
* rest of this file.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_MPS_TRACE_TYPE_COMMENT,
|
||||
MBEDTLS_MPS_TRACE_TYPE_CALL,
|
||||
MBEDTLS_MPS_TRACE_TYPE_ERROR,
|
||||
MBEDTLS_MPS_TRACE_TYPE_RETURN
|
||||
} mbedtls_mps_trace_type;
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_BIT_LAYER_1 1
|
||||
#define MBEDTLS_MPS_TRACE_BIT_LAYER_2 2
|
||||
#define MBEDTLS_MPS_TRACE_BIT_LAYER_3 3
|
||||
#define MBEDTLS_MPS_TRACE_BIT_LAYER_4 4
|
||||
#define MBEDTLS_MPS_TRACE_BIT_WRITER 5
|
||||
#define MBEDTLS_MPS_TRACE_BIT_READER 6
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_1)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_1)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 0
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_2)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_2)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 0
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_3)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_3)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 0
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_4)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_4)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 0
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_READER)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_READER (1u << MBEDTLS_MPS_TRACE_BIT_READER)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_READER 0
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MPS_TRACE_ENABLE_WRITER)
|
||||
#define MBEDTLS_MPS_TRACE_MASK_WRITER (1u << MBEDTLS_MPS_TRACE_BIT_WRITER)
|
||||
#else
|
||||
#define MBEDTLS_MPS_TRACE_MASK_WRITER 0
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_MASK (MBEDTLS_MPS_TRACE_MASK_LAYER_1 | \
|
||||
MBEDTLS_MPS_TRACE_MASK_LAYER_2 | \
|
||||
MBEDTLS_MPS_TRACE_MASK_LAYER_3 | \
|
||||
MBEDTLS_MPS_TRACE_MASK_LAYER_4 | \
|
||||
MBEDTLS_MPS_TRACE_MASK_READER | \
|
||||
MBEDTLS_MPS_TRACE_MASK_WRITER)
|
||||
|
||||
/* We have to avoid globals because E-ACSL chokes on them...
|
||||
* Wrap everything in stub functions. */
|
||||
int mbedtls_mps_trace_get_depth(void);
|
||||
void mbedtls_mps_trace_inc_depth(void);
|
||||
void mbedtls_mps_trace_dec_depth(void);
|
||||
|
||||
void mbedtls_mps_trace_color(int id);
|
||||
void mbedtls_mps_trace_indent(int level, mbedtls_mps_trace_type ty);
|
||||
|
||||
void mbedtls_mps_trace_print_msg(int id, int line, const char *format, ...);
|
||||
|
||||
#define MBEDTLS_MPS_TRACE(type, ...) \
|
||||
do { \
|
||||
if (!(MBEDTLS_MPS_TRACE_MASK & (1u << mbedtls_mps_trace_id))) \
|
||||
break; \
|
||||
mbedtls_mps_trace_indent(mbedtls_mps_trace_get_depth(), type); \
|
||||
mbedtls_mps_trace_color(mbedtls_mps_trace_id); \
|
||||
mbedtls_mps_trace_print_msg(mbedtls_mps_trace_id, __LINE__, __VA_ARGS__); \
|
||||
mbedtls_mps_trace_color(0); \
|
||||
} while (0)
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_INIT(...) \
|
||||
do { \
|
||||
if (!(MBEDTLS_MPS_TRACE_MASK & (1u << mbedtls_mps_trace_id))) \
|
||||
break; \
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_CALL, __VA_ARGS__); \
|
||||
mbedtls_mps_trace_inc_depth(); \
|
||||
} while (0)
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_END(val) \
|
||||
do { \
|
||||
if (!(MBEDTLS_MPS_TRACE_MASK & (1u << mbedtls_mps_trace_id))) \
|
||||
break; \
|
||||
MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_RETURN, "%d (-%#04x)", \
|
||||
(int) (val), -((unsigned) (val))); \
|
||||
mbedtls_mps_trace_dec_depth(); \
|
||||
} while (0)
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_RETURN(val) \
|
||||
do { \
|
||||
/* Breaks tail recursion. */ \
|
||||
int ret__ = val; \
|
||||
MBEDTLS_MPS_TRACE_END(ret__); \
|
||||
return ret__; \
|
||||
} while (0)
|
||||
|
||||
#else /* MBEDTLS_MPS_TRACE */
|
||||
|
||||
#define MBEDTLS_MPS_TRACE(type, ...) do { } while (0)
|
||||
#define MBEDTLS_MPS_TRACE_INIT(...) do { } while (0)
|
||||
#define MBEDTLS_MPS_TRACE_END do { } while (0)
|
||||
|
||||
#define MBEDTLS_MPS_TRACE_RETURN(val) return val;
|
||||
|
||||
#endif /* MBEDTLS_MPS_TRACE */
|
||||
|
||||
#endif /* MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H */
|
||||
+696
@@ -0,0 +1,696 @@
|
||||
/*
|
||||
* TCP/IP or UDP/IP networking functions
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must
|
||||
* be set before mbedtls_config.h, which pulls in glibc's features.h indirectly.
|
||||
* Harmless on other platforms. */
|
||||
#ifndef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 200112L
|
||||
#endif
|
||||
#ifndef _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 600 /* sockaddr_storage */
|
||||
#endif
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_NET_C)
|
||||
|
||||
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
|
||||
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
|
||||
!defined(__HAIKU__) && !defined(__midipix__)
|
||||
#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in mbedtls_config.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "mbedtls/net_sockets.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
|
||||
!defined(EFI32)
|
||||
|
||||
#define IS_EINTR(ret) ((ret) == WSAEINTR)
|
||||
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#if (_WIN32_WINNT < 0x0501)
|
||||
#include <wspiapi.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_WIN32_WCE)
|
||||
#pragma comment( lib, "ws2.lib" )
|
||||
#else
|
||||
#pragma comment( lib, "ws2_32.lib" )
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#define read(fd, buf, len) recv(fd, (char *) (buf), (int) (len), 0)
|
||||
#define write(fd, buf, len) send(fd, (char *) (buf), (int) (len), 0)
|
||||
#define close(fd) closesocket(fd)
|
||||
|
||||
static int wsa_init_done = 0;
|
||||
|
||||
#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define IS_EINTR(ret) ((ret) == EINTR)
|
||||
#define SOCKET int
|
||||
|
||||
#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
|
||||
|
||||
/* Some MS functions want int and MSVC warns if we pass size_t,
|
||||
* but the standard functions use socklen_t, so cast only for MSVC */
|
||||
#if defined(_MSC_VER)
|
||||
#define MSVC_INT_CAST (int)
|
||||
#else
|
||||
#define MSVC_INT_CAST
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Prepare for using the sockets interface
|
||||
*/
|
||||
static int net_prepare(void)
|
||||
{
|
||||
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
|
||||
!defined(EFI32)
|
||||
WSADATA wsaData;
|
||||
|
||||
if (wsa_init_done == 0) {
|
||||
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
|
||||
return MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
}
|
||||
|
||||
wsa_init_done = 1;
|
||||
}
|
||||
#else
|
||||
#if !defined(EFIX64) && !defined(EFI32)
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 0 if the file descriptor is valid, an error otherwise.
|
||||
* If for_select != 0, check whether the file descriptor is within the range
|
||||
* allowed for fd_set used for the FD_xxx macros and the select() function.
|
||||
*/
|
||||
static int check_fd(int fd, int for_select)
|
||||
{
|
||||
if (fd < 0) {
|
||||
return MBEDTLS_ERR_NET_INVALID_CONTEXT;
|
||||
}
|
||||
|
||||
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
|
||||
!defined(EFI32)
|
||||
(void) for_select;
|
||||
#else
|
||||
/* A limitation of select() is that it only works with file descriptors
|
||||
* that are strictly less than FD_SETSIZE. This is a limitation of the
|
||||
* fd_set type. Error out early, because attempting to call FD_SET on a
|
||||
* large file descriptor is a buffer overflow on typical platforms. */
|
||||
if (for_select && fd >= FD_SETSIZE) {
|
||||
return MBEDTLS_ERR_NET_POLL_FAILED;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a context
|
||||
*/
|
||||
void mbedtls_net_init(mbedtls_net_context *ctx)
|
||||
{
|
||||
ctx->fd = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initiate a TCP connection with host:port and the given protocol
|
||||
*/
|
||||
int mbedtls_net_connect(mbedtls_net_context *ctx, const char *host,
|
||||
const char *port, int proto)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
struct addrinfo hints, *addr_list, *cur;
|
||||
|
||||
if ((ret = net_prepare()) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Do name resolution with both IPv6 and IPv4 */
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
|
||||
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
|
||||
if (getaddrinfo(host, port, &hints, &addr_list) != 0) {
|
||||
return MBEDTLS_ERR_NET_UNKNOWN_HOST;
|
||||
}
|
||||
|
||||
/* Try the sockaddrs until a connection succeeds */
|
||||
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
|
||||
for (cur = addr_list; cur != NULL; cur = cur->ai_next) {
|
||||
ctx->fd = (int) socket(cur->ai_family, cur->ai_socktype,
|
||||
cur->ai_protocol);
|
||||
if (ctx->fd < 0) {
|
||||
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (connect(ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen) == 0) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
mbedtls_net_close(ctx);
|
||||
ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a listening socket on bind_ip:port
|
||||
*/
|
||||
int mbedtls_net_bind(mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto)
|
||||
{
|
||||
int n, ret;
|
||||
struct addrinfo hints, *addr_list, *cur;
|
||||
|
||||
if ((ret = net_prepare()) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Bind to IPv6 and/or IPv4, but only in the desired protocol */
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
|
||||
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
if (bind_ip == NULL) {
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
}
|
||||
|
||||
if (getaddrinfo(bind_ip, port, &hints, &addr_list) != 0) {
|
||||
return MBEDTLS_ERR_NET_UNKNOWN_HOST;
|
||||
}
|
||||
|
||||
/* Try the sockaddrs until a binding succeeds */
|
||||
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
|
||||
for (cur = addr_list; cur != NULL; cur = cur->ai_next) {
|
||||
ctx->fd = (int) socket(cur->ai_family, cur->ai_socktype,
|
||||
cur->ai_protocol);
|
||||
if (ctx->fd < 0) {
|
||||
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
n = 1;
|
||||
if (setsockopt(ctx->fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char *) &n, sizeof(n)) != 0) {
|
||||
mbedtls_net_close(ctx);
|
||||
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bind(ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen) != 0) {
|
||||
mbedtls_net_close(ctx);
|
||||
ret = MBEDTLS_ERR_NET_BIND_FAILED;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Listen only makes sense for TCP */
|
||||
if (proto == MBEDTLS_NET_PROTO_TCP) {
|
||||
if (listen(ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG) != 0) {
|
||||
mbedtls_net_close(ctx);
|
||||
ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bind was successful */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr_list);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
|
||||
!defined(EFI32)
|
||||
/*
|
||||
* Check if the requested operation would be blocking on a non-blocking socket
|
||||
* and thus 'failed' with a negative return value.
|
||||
*/
|
||||
static int net_would_block(const mbedtls_net_context *ctx)
|
||||
{
|
||||
((void) ctx);
|
||||
return WSAGetLastError() == WSAEWOULDBLOCK;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* Check if the requested operation would be blocking on a non-blocking socket
|
||||
* and thus 'failed' with a negative return value.
|
||||
*
|
||||
* Note: on a blocking socket this function always returns 0!
|
||||
*/
|
||||
static int net_would_block(const mbedtls_net_context *ctx)
|
||||
{
|
||||
int err = errno;
|
||||
|
||||
/*
|
||||
* Never return 'WOULD BLOCK' on a blocking socket
|
||||
*/
|
||||
if ((fcntl(ctx->fd, F_GETFL) & O_NONBLOCK) != O_NONBLOCK) {
|
||||
errno = err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (errno = err) {
|
||||
#if defined EAGAIN
|
||||
case EAGAIN:
|
||||
#endif
|
||||
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
|
||||
|
||||
/*
|
||||
* Accept a connection from a remote client
|
||||
*/
|
||||
int mbedtls_net_accept(mbedtls_net_context *bind_ctx,
|
||||
mbedtls_net_context *client_ctx,
|
||||
void *client_ip, size_t buf_size, size_t *cip_len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int type;
|
||||
|
||||
struct sockaddr_storage client_addr;
|
||||
|
||||
#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
|
||||
defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) || \
|
||||
defined(socklen_t) || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L)
|
||||
socklen_t n = (socklen_t) sizeof(client_addr);
|
||||
socklen_t type_len = (socklen_t) sizeof(type);
|
||||
#else
|
||||
int n = (int) sizeof(client_addr);
|
||||
int type_len = (int) sizeof(type);
|
||||
#endif
|
||||
|
||||
/* Is this a TCP or UDP socket? */
|
||||
if (getsockopt(bind_ctx->fd, SOL_SOCKET, SO_TYPE,
|
||||
(void *) &type, &type_len) != 0 ||
|
||||
(type != SOCK_STREAM && type != SOCK_DGRAM)) {
|
||||
return MBEDTLS_ERR_NET_ACCEPT_FAILED;
|
||||
}
|
||||
|
||||
if (type == SOCK_STREAM) {
|
||||
/* TCP: actual accept() */
|
||||
ret = client_ctx->fd = (int) accept(bind_ctx->fd,
|
||||
(struct sockaddr *) &client_addr, &n);
|
||||
} else {
|
||||
/* UDP: wait for a message, but keep it in the queue */
|
||||
char buf[1] = { 0 };
|
||||
|
||||
ret = (int) recvfrom(bind_ctx->fd, buf, sizeof(buf), MSG_PEEK,
|
||||
(struct sockaddr *) &client_addr, &n);
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (ret == SOCKET_ERROR &&
|
||||
WSAGetLastError() == WSAEMSGSIZE) {
|
||||
/* We know buf is too small, thanks, just peeking here */
|
||||
ret = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (net_would_block(bind_ctx) != 0) {
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
}
|
||||
|
||||
return MBEDTLS_ERR_NET_ACCEPT_FAILED;
|
||||
}
|
||||
|
||||
/* UDP: hijack the listening socket to communicate with the client,
|
||||
* then bind a new socket to accept new connections */
|
||||
if (type != SOCK_STREAM) {
|
||||
struct sockaddr_storage local_addr;
|
||||
int one = 1;
|
||||
|
||||
if (connect(bind_ctx->fd, (struct sockaddr *) &client_addr, n) != 0) {
|
||||
return MBEDTLS_ERR_NET_ACCEPT_FAILED;
|
||||
}
|
||||
|
||||
client_ctx->fd = bind_ctx->fd;
|
||||
bind_ctx->fd = -1; /* In case we exit early */
|
||||
|
||||
n = sizeof(struct sockaddr_storage);
|
||||
if (getsockname(client_ctx->fd,
|
||||
(struct sockaddr *) &local_addr, &n) != 0 ||
|
||||
(bind_ctx->fd = (int) socket(local_addr.ss_family,
|
||||
SOCK_DGRAM, IPPROTO_UDP)) < 0 ||
|
||||
setsockopt(bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char *) &one, sizeof(one)) != 0) {
|
||||
return MBEDTLS_ERR_NET_SOCKET_FAILED;
|
||||
}
|
||||
|
||||
if (bind(bind_ctx->fd, (struct sockaddr *) &local_addr, n) != 0) {
|
||||
return MBEDTLS_ERR_NET_BIND_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (client_ip != NULL) {
|
||||
if (client_addr.ss_family == AF_INET) {
|
||||
struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
|
||||
*cip_len = sizeof(addr4->sin_addr.s_addr);
|
||||
|
||||
if (buf_size < *cip_len) {
|
||||
return MBEDTLS_ERR_NET_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
memcpy(client_ip, &addr4->sin_addr.s_addr, *cip_len);
|
||||
} else {
|
||||
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
|
||||
*cip_len = sizeof(addr6->sin6_addr.s6_addr);
|
||||
|
||||
if (buf_size < *cip_len) {
|
||||
return MBEDTLS_ERR_NET_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
memcpy(client_ip, &addr6->sin6_addr.s6_addr, *cip_len);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the socket blocking or non-blocking
|
||||
*/
|
||||
int mbedtls_net_set_block(mbedtls_net_context *ctx)
|
||||
{
|
||||
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
|
||||
!defined(EFI32)
|
||||
u_long n = 0;
|
||||
return ioctlsocket(ctx->fd, FIONBIO, &n);
|
||||
#else
|
||||
return fcntl(ctx->fd, F_SETFL, fcntl(ctx->fd, F_GETFL) & ~O_NONBLOCK);
|
||||
#endif
|
||||
}
|
||||
|
||||
int mbedtls_net_set_nonblock(mbedtls_net_context *ctx)
|
||||
{
|
||||
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
|
||||
!defined(EFI32)
|
||||
u_long n = 1;
|
||||
return ioctlsocket(ctx->fd, FIONBIO, &n);
|
||||
#else
|
||||
return fcntl(ctx->fd, F_SETFL, fcntl(ctx->fd, F_GETFL) | O_NONBLOCK);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if data is available on the socket
|
||||
*/
|
||||
|
||||
int mbedtls_net_poll(mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
struct timeval tv;
|
||||
|
||||
fd_set read_fds;
|
||||
fd_set write_fds;
|
||||
|
||||
int fd = ctx->fd;
|
||||
|
||||
ret = check_fd(fd, 1);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(memory_sanitizer)
|
||||
/* Ensure that memory sanitizers consider read_fds and write_fds as
|
||||
* initialized even on platforms such as Glibc/x86_64 where FD_ZERO
|
||||
* is implemented in assembly. */
|
||||
memset(&read_fds, 0, sizeof(read_fds));
|
||||
memset(&write_fds, 0, sizeof(write_fds));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
if (rw & MBEDTLS_NET_POLL_READ) {
|
||||
rw &= ~MBEDTLS_NET_POLL_READ;
|
||||
FD_SET((SOCKET) fd, &read_fds);
|
||||
}
|
||||
|
||||
FD_ZERO(&write_fds);
|
||||
if (rw & MBEDTLS_NET_POLL_WRITE) {
|
||||
rw &= ~MBEDTLS_NET_POLL_WRITE;
|
||||
FD_SET((SOCKET) fd, &write_fds);
|
||||
}
|
||||
|
||||
if (rw != 0) {
|
||||
return MBEDTLS_ERR_NET_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
do {
|
||||
ret = select(fd + 1, &read_fds, &write_fds, NULL,
|
||||
timeout == (uint32_t) -1 ? NULL : &tv);
|
||||
} while (IS_EINTR(ret));
|
||||
|
||||
if (ret < 0) {
|
||||
return MBEDTLS_ERR_NET_POLL_FAILED;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
if (FD_ISSET(fd, &read_fds)) {
|
||||
ret |= MBEDTLS_NET_POLL_READ;
|
||||
}
|
||||
if (FD_ISSET(fd, &write_fds)) {
|
||||
ret |= MBEDTLS_NET_POLL_WRITE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Portable usleep helper
|
||||
*/
|
||||
void mbedtls_net_usleep(unsigned long usec)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
Sleep((usec + 999) / 1000);
|
||||
#else
|
||||
struct timeval tv;
|
||||
tv.tv_sec = usec / 1000000;
|
||||
#if (defined(__unix__) || defined(__unix) || \
|
||||
(defined(__APPLE__) && defined(__MACH__))) && !defined(__DJGPP__)
|
||||
tv.tv_usec = (suseconds_t) usec % 1000000;
|
||||
#else
|
||||
tv.tv_usec = usec % 1000000;
|
||||
#endif
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Read at most 'len' characters
|
||||
*/
|
||||
int mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int fd = ((mbedtls_net_context *) ctx)->fd;
|
||||
|
||||
ret = check_fd(fd, 0);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = (int) read(fd, buf, len);
|
||||
|
||||
if (ret < 0) {
|
||||
if (net_would_block(ctx) != 0) {
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
}
|
||||
|
||||
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
|
||||
!defined(EFI32)
|
||||
if (WSAGetLastError() == WSAECONNRESET) {
|
||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
}
|
||||
#else
|
||||
if (errno == EPIPE || errno == ECONNRESET) {
|
||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
}
|
||||
|
||||
if (errno == EINTR) {
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
}
|
||||
#endif
|
||||
|
||||
return MBEDTLS_ERR_NET_RECV_FAILED;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read at most 'len' characters, blocking for at most 'timeout' ms
|
||||
*/
|
||||
int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf,
|
||||
size_t len, uint32_t timeout)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
struct timeval tv;
|
||||
fd_set read_fds;
|
||||
int fd = ((mbedtls_net_context *) ctx)->fd;
|
||||
|
||||
ret = check_fd(fd, 1);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET((SOCKET) fd, &read_fds);
|
||||
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
ret = select(fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv);
|
||||
|
||||
/* Zero fds ready means we timed out */
|
||||
if (ret == 0) {
|
||||
return MBEDTLS_ERR_SSL_TIMEOUT;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
|
||||
!defined(EFI32)
|
||||
if (WSAGetLastError() == WSAEINTR) {
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
}
|
||||
#else
|
||||
if (errno == EINTR) {
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
}
|
||||
#endif
|
||||
|
||||
return MBEDTLS_ERR_NET_RECV_FAILED;
|
||||
}
|
||||
|
||||
/* This call will not block */
|
||||
return mbedtls_net_recv(ctx, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write at most 'len' characters
|
||||
*/
|
||||
int mbedtls_net_send(void *ctx, const unsigned char *buf, size_t len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int fd = ((mbedtls_net_context *) ctx)->fd;
|
||||
|
||||
ret = check_fd(fd, 0);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = (int) write(fd, buf, len);
|
||||
|
||||
if (ret < 0) {
|
||||
if (net_would_block(ctx) != 0) {
|
||||
return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
}
|
||||
|
||||
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
|
||||
!defined(EFI32)
|
||||
if (WSAGetLastError() == WSAECONNRESET) {
|
||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
}
|
||||
#else
|
||||
if (errno == EPIPE || errno == ECONNRESET) {
|
||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
}
|
||||
|
||||
if (errno == EINTR) {
|
||||
return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return MBEDTLS_ERR_NET_SEND_FAILED;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the connection
|
||||
*/
|
||||
void mbedtls_net_close(mbedtls_net_context *ctx)
|
||||
{
|
||||
if (ctx->fd == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
close(ctx->fd);
|
||||
|
||||
ctx->fd = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gracefully close the connection
|
||||
*/
|
||||
void mbedtls_net_free(mbedtls_net_context *ctx)
|
||||
{
|
||||
if (ctx == NULL || ctx->fd == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
shutdown(ctx->fd, 2);
|
||||
close(ctx->fd);
|
||||
|
||||
ctx->fd = -1;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_NET_C */
|
||||
Vendored
+772
@@ -0,0 +1,772 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#include "x509_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_PKCS7_C)
|
||||
#include "mbedtls/pkcs7.h"
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/x509_crl.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "x509_oid.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#include "mbedtls/platform_time.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initializes the mbedtls_pkcs7 structure.
|
||||
*/
|
||||
void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7)
|
||||
{
|
||||
memset(pkcs7, 0, sizeof(*pkcs7));
|
||||
}
|
||||
|
||||
static int pkcs7_get_next_content_len(unsigned char **p, unsigned char *end,
|
||||
size_t *len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED
|
||||
| MBEDTLS_ASN1_CONTEXT_SPECIFIC);
|
||||
if (ret != 0) {
|
||||
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
|
||||
} else if ((size_t) (end - *p) != *len) {
|
||||
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* version Version
|
||||
* Version ::= INTEGER
|
||||
**/
|
||||
static int pkcs7_get_version(unsigned char **p, unsigned char *end, int *ver)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
ret = mbedtls_asn1_get_int(p, end, ver);
|
||||
if (ret != 0) {
|
||||
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_VERSION, ret);
|
||||
}
|
||||
|
||||
/* If version != 1, return invalid version */
|
||||
if (*ver != MBEDTLS_PKCS7_SUPPORTED_VERSION) {
|
||||
ret = MBEDTLS_ERR_PKCS7_INVALID_VERSION;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ContentInfo ::= SEQUENCE {
|
||||
* contentType ContentType,
|
||||
* content
|
||||
* [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
|
||||
**/
|
||||
static int pkcs7_get_content_info_type(unsigned char **p, unsigned char *end,
|
||||
unsigned char **seq_end,
|
||||
mbedtls_pkcs7_buf *pkcs7)
|
||||
{
|
||||
size_t len = 0;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *start = *p;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
|
||||
| MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
*p = start;
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
|
||||
}
|
||||
*seq_end = *p + len;
|
||||
ret = mbedtls_asn1_get_tag(p, *seq_end, &len, MBEDTLS_ASN1_OID);
|
||||
if (ret != 0) {
|
||||
*p = start;
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
|
||||
}
|
||||
|
||||
pkcs7->tag = MBEDTLS_ASN1_OID;
|
||||
pkcs7->len = len;
|
||||
pkcs7->p = *p;
|
||||
*p += len;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
*
|
||||
* This is from x509.h
|
||||
**/
|
||||
static int pkcs7_get_digest_algorithm(unsigned char **p, unsigned char *end,
|
||||
mbedtls_x509_buf *alg)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
|
||||
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* DigestAlgorithmIdentifiers :: SET of DigestAlgorithmIdentifier
|
||||
**/
|
||||
static int pkcs7_get_digest_algorithm_set(unsigned char **p,
|
||||
unsigned char *end,
|
||||
mbedtls_x509_buf *alg)
|
||||
{
|
||||
size_t len = 0;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
|
||||
| MBEDTLS_ASN1_SET);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
|
||||
}
|
||||
|
||||
end = *p + len;
|
||||
|
||||
ret = mbedtls_asn1_get_alg_null(p, end, alg);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
|
||||
}
|
||||
|
||||
/** For now, it assumes there is only one digest algorithm specified **/
|
||||
if (*p != end) {
|
||||
return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* certificates :: SET OF ExtendedCertificateOrCertificate,
|
||||
* ExtendedCertificateOrCertificate ::= CHOICE {
|
||||
* certificate Certificate -- x509,
|
||||
* extendedCertificate[0] IMPLICIT ExtendedCertificate }
|
||||
* Return number of certificates added to the signed data,
|
||||
* 0 or higher is valid.
|
||||
* Return negative error code for failure.
|
||||
**/
|
||||
static int pkcs7_get_certificates(unsigned char **p, unsigned char *end,
|
||||
mbedtls_x509_crt *certs)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len1 = 0;
|
||||
size_t len2 = 0;
|
||||
unsigned char *end_set, *end_cert, *start;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
|
||||
| MBEDTLS_ASN1_CONTEXT_SPECIFIC);
|
||||
if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
||||
return 0;
|
||||
}
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
|
||||
}
|
||||
start = *p;
|
||||
end_set = *p + len1;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED
|
||||
| MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CERT, ret);
|
||||
}
|
||||
|
||||
end_cert = *p + len2;
|
||||
|
||||
/*
|
||||
* This is to verify that there is only one signer certificate. It seems it is
|
||||
* not easy to differentiate between the chain vs different signer's certificate.
|
||||
* So, we support only the root certificate and the single signer.
|
||||
* The behaviour would be improved with addition of multiple signer support.
|
||||
*/
|
||||
if (end_cert != end_set) {
|
||||
return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_x509_crt_parse_der(certs, start, len1)) < 0) {
|
||||
return MBEDTLS_ERR_PKCS7_INVALID_CERT;
|
||||
}
|
||||
|
||||
*p = end_cert;
|
||||
|
||||
/*
|
||||
* Since in this version we strictly support single certificate, and reaching
|
||||
* here implies we have parsed successfully, we return 1.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* EncryptedDigest ::= OCTET STRING
|
||||
**/
|
||||
static int pkcs7_get_signature(unsigned char **p, unsigned char *end,
|
||||
mbedtls_pkcs7_buf *signature)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
signature->tag = MBEDTLS_ASN1_OCTET_STRING;
|
||||
signature->len = len;
|
||||
signature->p = *p;
|
||||
|
||||
*p = *p + len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer)
|
||||
{
|
||||
mbedtls_x509_name *name_cur;
|
||||
mbedtls_x509_name *name_prv;
|
||||
|
||||
if (signer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
name_cur = signer->issuer.next;
|
||||
while (name_cur != NULL) {
|
||||
name_prv = name_cur;
|
||||
name_cur = name_cur->next;
|
||||
mbedtls_free(name_prv);
|
||||
}
|
||||
signer->issuer.next = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* SignerInfo ::= SEQUENCE {
|
||||
* version Version;
|
||||
* issuerAndSerialNumber IssuerAndSerialNumber,
|
||||
* digestAlgorithm DigestAlgorithmIdentifier,
|
||||
* authenticatedAttributes
|
||||
* [0] IMPLICIT Attributes OPTIONAL,
|
||||
* digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
|
||||
* encryptedDigest EncryptedDigest,
|
||||
* unauthenticatedAttributes
|
||||
* [1] IMPLICIT Attributes OPTIONAL,
|
||||
* Returns 0 if the signerInfo is valid.
|
||||
* Return negative error code for failure.
|
||||
* Structure must not contain vales for authenticatedAttributes
|
||||
* and unauthenticatedAttributes.
|
||||
**/
|
||||
static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
|
||||
mbedtls_pkcs7_signer_info *signer,
|
||||
mbedtls_x509_buf *alg)
|
||||
{
|
||||
unsigned char *end_signer, *end_issuer_and_sn;
|
||||
int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
asn1_ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
|
||||
| MBEDTLS_ASN1_SEQUENCE);
|
||||
if (asn1_ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
end_signer = *p + len;
|
||||
|
||||
ret = pkcs7_get_version(p, end_signer, &signer->version);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
asn1_ret = mbedtls_asn1_get_tag(p, end_signer, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
|
||||
if (asn1_ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
end_issuer_and_sn = *p + len;
|
||||
/* Parsing IssuerAndSerialNumber */
|
||||
signer->issuer_raw.p = *p;
|
||||
|
||||
asn1_ret = mbedtls_asn1_get_tag(p, end_issuer_and_sn, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
|
||||
if (asn1_ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509_get_name(p, *p + len, &signer->issuer);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
signer->issuer_raw.len = (size_t) (*p - signer->issuer_raw.p);
|
||||
|
||||
ret = mbedtls_x509_get_serial(p, end_issuer_and_sn, &signer->serial);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* ensure no extra or missing bytes */
|
||||
if (*p != end_issuer_and_sn) {
|
||||
ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->alg_identifier);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Check that the digest algorithm used matches the one provided earlier */
|
||||
if (signer->alg_identifier.tag != alg->tag ||
|
||||
signer->alg_identifier.len != alg->len ||
|
||||
memcmp(signer->alg_identifier.p, alg->p, alg->len) != 0) {
|
||||
ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Assume authenticatedAttributes is nonexistent */
|
||||
ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = pkcs7_get_signature(p, end_signer, &signer->sig);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Do not permit any unauthenticated attributes */
|
||||
if (*p != end_signer) {
|
||||
ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
|
||||
}
|
||||
|
||||
out:
|
||||
if (asn1_ret != 0 || ret != 0) {
|
||||
pkcs7_free_signer_info(signer);
|
||||
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,
|
||||
asn1_ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* SignerInfos ::= SET of SignerInfo
|
||||
* Return number of signers added to the signed data,
|
||||
* 0 or higher is valid.
|
||||
* Return negative error code for failure.
|
||||
**/
|
||||
static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end,
|
||||
mbedtls_pkcs7_signer_info *signers_set,
|
||||
mbedtls_x509_buf *digest_alg)
|
||||
{
|
||||
unsigned char *end_set;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int count = 0;
|
||||
size_t len = 0;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
|
||||
| MBEDTLS_ASN1_SET);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, ret);
|
||||
}
|
||||
|
||||
/* Detect zero signers */
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
end_set = *p + len;
|
||||
|
||||
ret = pkcs7_get_signer_info(p, end_set, signers_set, digest_alg);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
count++;
|
||||
|
||||
mbedtls_pkcs7_signer_info *prev = signers_set;
|
||||
while (*p != end_set) {
|
||||
mbedtls_pkcs7_signer_info *signer =
|
||||
mbedtls_calloc(1, sizeof(mbedtls_pkcs7_signer_info));
|
||||
if (!signer) {
|
||||
ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = pkcs7_get_signer_info(p, end_set, signer, digest_alg);
|
||||
if (ret != 0) {
|
||||
mbedtls_free(signer);
|
||||
goto cleanup;
|
||||
}
|
||||
prev->next = signer;
|
||||
prev = signer;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
|
||||
cleanup:
|
||||
pkcs7_free_signer_info(signers_set);
|
||||
mbedtls_pkcs7_signer_info *signer = signers_set->next;
|
||||
while (signer != NULL) {
|
||||
prev = signer;
|
||||
signer = signer->next;
|
||||
pkcs7_free_signer_info(prev);
|
||||
mbedtls_free(prev);
|
||||
}
|
||||
signers_set->next = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* SignedData ::= SEQUENCE {
|
||||
* version Version,
|
||||
* digestAlgorithms DigestAlgorithmIdentifiers,
|
||||
* contentInfo ContentInfo,
|
||||
* certificates
|
||||
* [0] IMPLICIT ExtendedCertificatesAndCertificates
|
||||
* OPTIONAL,
|
||||
* crls
|
||||
* [0] IMPLICIT CertificateRevocationLists OPTIONAL,
|
||||
* signerInfos SignerInfos }
|
||||
*/
|
||||
static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen,
|
||||
mbedtls_pkcs7_signed_data *signed_data)
|
||||
{
|
||||
unsigned char *p = buf;
|
||||
unsigned char *end = buf + buflen;
|
||||
unsigned char *end_content_info = NULL;
|
||||
size_t len = 0;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_md_type_t md_alg;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
|
||||
| MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
|
||||
}
|
||||
|
||||
if (p + len != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
/* Get version of signed data */
|
||||
ret = pkcs7_get_version(&p, end, &signed_data->version);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get digest algorithm */
|
||||
ret = pkcs7_get_digest_algorithm_set(&p, end,
|
||||
&signed_data->digest_alg_identifiers);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509_oid_get_md_alg(&signed_data->digest_alg_identifiers, &md_alg);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERR_PKCS7_INVALID_ALG;
|
||||
}
|
||||
|
||||
mbedtls_pkcs7_buf content_type;
|
||||
memset(&content_type, 0, sizeof(content_type));
|
||||
ret = pkcs7_get_content_info_type(&p, end, &end_content_info, &content_type);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) {
|
||||
return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO;
|
||||
}
|
||||
|
||||
if (p != end_content_info) {
|
||||
/* Determine if valid content is present */
|
||||
ret = mbedtls_asn1_get_tag(&p,
|
||||
end_content_info,
|
||||
&len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
|
||||
}
|
||||
p += len;
|
||||
if (p != end_content_info) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
|
||||
}
|
||||
/* Valid content is present - this is not supported */
|
||||
return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* Look for certificates, there may or may not be any */
|
||||
mbedtls_x509_crt_init(&signed_data->certs);
|
||||
ret = pkcs7_get_certificates(&p, end, &signed_data->certs);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
signed_data->no_of_certs = ret;
|
||||
|
||||
/*
|
||||
* Currently CRLs are not supported. If CRL exist, the parsing will fail
|
||||
* at next step of getting signers info and return error as invalid
|
||||
* signer info.
|
||||
*/
|
||||
|
||||
signed_data->no_of_crls = 0;
|
||||
|
||||
/* Get signers info */
|
||||
ret = pkcs7_get_signers_info_set(&p,
|
||||
end,
|
||||
&signed_data->signers,
|
||||
&signed_data->digest_alg_identifiers);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
signed_data->no_of_signers = ret;
|
||||
|
||||
/* Don't permit trailing data */
|
||||
if (p != end) {
|
||||
return MBEDTLS_ERR_PKCS7_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
|
||||
const size_t buflen)
|
||||
{
|
||||
unsigned char *p;
|
||||
unsigned char *end;
|
||||
size_t len = 0;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (pkcs7 == NULL) {
|
||||
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
/* make an internal copy of the buffer for parsing */
|
||||
pkcs7->raw.p = p = mbedtls_calloc(1, buflen);
|
||||
if (pkcs7->raw.p == NULL) {
|
||||
ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
|
||||
goto out;
|
||||
}
|
||||
memcpy(p, buf, buflen);
|
||||
pkcs7->raw.len = buflen;
|
||||
end = p + buflen;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
|
||||
| MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((size_t) (end - p) != len) {
|
||||
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
|
||||
if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
||||
goto out;
|
||||
}
|
||||
p = pkcs7->raw.p;
|
||||
len = buflen;
|
||||
goto try_data;
|
||||
}
|
||||
|
||||
if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_DATA, p, len)) {
|
||||
/* OID is not MBEDTLS_OID_PKCS7_SIGNED_DATA, which is the only supported feature */
|
||||
if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA, p, len)
|
||||
|| !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, p, len)
|
||||
|| !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, p, len)
|
||||
|| !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, p, len)
|
||||
|| !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DIGESTED_DATA, p, len)) {
|
||||
/* OID is valid according to the spec, but unsupported */
|
||||
ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
|
||||
} else {
|
||||
/* OID is invalid according to the spec */
|
||||
ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
p += len;
|
||||
|
||||
ret = pkcs7_get_next_content_len(&p, end, &len);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* ensure no extra/missing data */
|
||||
if (p + len != end) {
|
||||
ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
|
||||
goto out;
|
||||
}
|
||||
|
||||
try_data:
|
||||
ret = pkcs7_get_signed_data(p, len, &pkcs7->signed_data);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = MBEDTLS_PKCS7_SIGNED_DATA;
|
||||
|
||||
out:
|
||||
if (ret < 0) {
|
||||
mbedtls_pkcs7_free(pkcs7);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *cert,
|
||||
const unsigned char *data,
|
||||
size_t datalen,
|
||||
const int is_data_hash)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *hash;
|
||||
mbedtls_pk_context pk_cxt = cert->pk;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
mbedtls_md_type_t md_alg;
|
||||
mbedtls_pkcs7_signer_info *signer;
|
||||
|
||||
if (pkcs7->signed_data.no_of_signers == 0) {
|
||||
return MBEDTLS_ERR_PKCS7_INVALID_CERT;
|
||||
}
|
||||
|
||||
if (mbedtls_x509_time_is_past(&cert->valid_to) ||
|
||||
mbedtls_x509_time_is_future(&cert->valid_from)) {
|
||||
return MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509_oid_get_md_alg(&pkcs7->signed_data.digest_alg_identifiers, &md_alg);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
md_info = mbedtls_md_info_from_type(md_alg);
|
||||
if (md_info == NULL) {
|
||||
return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
|
||||
}
|
||||
|
||||
hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1);
|
||||
if (hash == NULL) {
|
||||
return MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
/* BEGIN must free hash before jumping out */
|
||||
if (is_data_hash) {
|
||||
if (datalen != mbedtls_md_get_size(md_info)) {
|
||||
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
|
||||
} else {
|
||||
memcpy(hash, data, datalen);
|
||||
}
|
||||
} else {
|
||||
ret = mbedtls_md(md_info, data, datalen, hash);
|
||||
}
|
||||
if (ret != 0) {
|
||||
mbedtls_free(hash);
|
||||
return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
|
||||
}
|
||||
|
||||
/* assume failure */
|
||||
ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
|
||||
|
||||
/*
|
||||
* Potential TODOs
|
||||
* Currently we iterate over all signers and return success if any of them
|
||||
* verify.
|
||||
*
|
||||
* However, we could make this better by checking against the certificate's
|
||||
* identification and SignerIdentifier fields first. That would also allow
|
||||
* us to distinguish between 'no signature for key' and 'signature for key
|
||||
* failed to validate'.
|
||||
*/
|
||||
for (signer = &pkcs7->signed_data.signers; signer; signer = signer->next) {
|
||||
ret = mbedtls_pk_verify(&pk_cxt, md_alg, hash,
|
||||
mbedtls_md_get_size(md_info),
|
||||
signer->sig.p, signer->sig.len);
|
||||
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_free(hash);
|
||||
/* END must free hash before jumping out */
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *cert,
|
||||
const unsigned char *data,
|
||||
size_t datalen)
|
||||
{
|
||||
if (data == NULL) {
|
||||
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
|
||||
}
|
||||
return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0);
|
||||
}
|
||||
|
||||
int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
|
||||
const mbedtls_x509_crt *cert,
|
||||
const unsigned char *hash,
|
||||
size_t hashlen)
|
||||
{
|
||||
if (hash == NULL) {
|
||||
return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
|
||||
}
|
||||
return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unallocate all pkcs7 data
|
||||
*/
|
||||
void mbedtls_pkcs7_free(mbedtls_pkcs7 *pkcs7)
|
||||
{
|
||||
mbedtls_pkcs7_signer_info *signer_cur;
|
||||
mbedtls_pkcs7_signer_info *signer_prev;
|
||||
|
||||
if (pkcs7 == NULL || pkcs7->raw.p == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_free(pkcs7->raw.p);
|
||||
|
||||
mbedtls_x509_crt_free(&pkcs7->signed_data.certs);
|
||||
mbedtls_x509_crl_free(&pkcs7->signed_data.crl);
|
||||
|
||||
signer_cur = pkcs7->signed_data.signers.next;
|
||||
pkcs7_free_signer_info(&pkcs7->signed_data.signers);
|
||||
while (signer_cur != NULL) {
|
||||
signer_prev = signer_cur;
|
||||
signer_cur = signer_prev->next;
|
||||
pkcs7_free_signer_info(signer_prev);
|
||||
mbedtls_free(signer_prev);
|
||||
}
|
||||
|
||||
pkcs7->raw.p = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
+409
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* SSL session cache implementation
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
/*
|
||||
* These session callbacks use a simple chained list
|
||||
* to store and retrieve the session information.
|
||||
*/
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_SSL_CACHE_C)
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "mbedtls/ssl_cache.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void mbedtls_ssl_cache_init(mbedtls_ssl_cache_context *cache)
|
||||
{
|
||||
memset(cache, 0, sizeof(mbedtls_ssl_cache_context));
|
||||
|
||||
cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT;
|
||||
cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init(&cache->mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_cache_find_entry(mbedtls_ssl_cache_context *cache,
|
||||
unsigned char const *session_id,
|
||||
size_t session_id_len,
|
||||
mbedtls_ssl_cache_entry **dst)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND;
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_time_t t = mbedtls_time(NULL);
|
||||
#endif
|
||||
mbedtls_ssl_cache_entry *cur;
|
||||
|
||||
for (cur = cache->chain; cur != NULL; cur = cur->next) {
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
if (cache->timeout != 0 &&
|
||||
(int) (t - cur->timestamp) > cache->timeout) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (session_id_len != cur->session_id_len ||
|
||||
memcmp(session_id, cur->session_id,
|
||||
cur->session_id_len) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (cur != NULL) {
|
||||
*dst = cur;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int mbedtls_ssl_cache_get(void *data,
|
||||
unsigned char const *session_id,
|
||||
size_t session_id_len,
|
||||
mbedtls_ssl_session *session)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
|
||||
mbedtls_ssl_cache_entry *entry;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ((ret = mbedtls_mutex_lock(&cache->mutex)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = ssl_cache_find_entry(cache, session_id, session_id_len, &entry);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_session_load(session,
|
||||
entry->session,
|
||||
entry->session_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_unlock(&cache->mutex) != 0) {
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* zeroize a cache entry */
|
||||
static void ssl_cache_entry_zeroize(mbedtls_ssl_cache_entry *entry)
|
||||
{
|
||||
if (entry == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* zeroize and free session structure */
|
||||
if (entry->session != NULL) {
|
||||
mbedtls_zeroize_and_free(entry->session, entry->session_len);
|
||||
}
|
||||
|
||||
/* zeroize the whole entry structure */
|
||||
mbedtls_platform_zeroize(entry, sizeof(mbedtls_ssl_cache_entry));
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_cache_pick_writing_slot(mbedtls_ssl_cache_context *cache,
|
||||
unsigned char const *session_id,
|
||||
size_t session_id_len,
|
||||
mbedtls_ssl_cache_entry **dst)
|
||||
{
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_time_t t = mbedtls_time(NULL), oldest = 0;
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
|
||||
mbedtls_ssl_cache_entry *old = NULL;
|
||||
int count = 0;
|
||||
mbedtls_ssl_cache_entry *cur, *last;
|
||||
|
||||
/* Check 1: Is there already an entry with the given session ID?
|
||||
*
|
||||
* If yes, overwrite it.
|
||||
*
|
||||
* If not, `count` will hold the size of the session cache
|
||||
* at the end of this loop, and `last` will point to the last
|
||||
* entry, both of which will be used later. */
|
||||
|
||||
last = NULL;
|
||||
for (cur = cache->chain; cur != NULL; cur = cur->next) {
|
||||
count++;
|
||||
if (session_id_len == cur->session_id_len &&
|
||||
memcmp(session_id, cur->session_id, cur->session_id_len) == 0) {
|
||||
goto found;
|
||||
}
|
||||
last = cur;
|
||||
}
|
||||
|
||||
/* Check 2: Is there an outdated entry in the cache?
|
||||
*
|
||||
* If so, overwrite it.
|
||||
*
|
||||
* If not, remember the oldest entry in `old` for later.
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
for (cur = cache->chain; cur != NULL; cur = cur->next) {
|
||||
if (cache->timeout != 0 &&
|
||||
(int) (t - cur->timestamp) > cache->timeout) {
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (oldest == 0 || cur->timestamp < oldest) {
|
||||
oldest = cur->timestamp;
|
||||
old = cur;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
|
||||
/* Check 3: Is there free space in the cache? */
|
||||
|
||||
if (count < cache->max_entries) {
|
||||
/* Create new entry */
|
||||
cur = mbedtls_calloc(1, sizeof(mbedtls_ssl_cache_entry));
|
||||
if (cur == NULL) {
|
||||
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
/* Append to the end of the linked list. */
|
||||
if (last == NULL) {
|
||||
cache->chain = cur;
|
||||
} else {
|
||||
last->next = cur;
|
||||
}
|
||||
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* Last resort: The cache is full and doesn't contain any outdated
|
||||
* elements. In this case, we evict the oldest one, judged by timestamp
|
||||
* (if present) or cache-order. */
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
if (old == NULL) {
|
||||
/* This should only happen on an ill-configured cache
|
||||
* with max_entries == 0. */
|
||||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
}
|
||||
#else /* MBEDTLS_HAVE_TIME */
|
||||
/* Reuse first entry in chain, but move to last place. */
|
||||
if (cache->chain == NULL) {
|
||||
/* This should never happen */
|
||||
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
|
||||
old = cache->chain;
|
||||
cache->chain = old->next;
|
||||
old->next = NULL;
|
||||
last->next = old;
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
|
||||
/* Now `old` points to the oldest entry to be overwritten. */
|
||||
cur = old;
|
||||
|
||||
found:
|
||||
|
||||
/* If we're reusing an entry, free it first. */
|
||||
if (cur->session != NULL) {
|
||||
/* `ssl_cache_entry_zeroize` would break the chain,
|
||||
* so we reuse `old` to record `next` temporarily. */
|
||||
old = cur->next;
|
||||
ssl_cache_entry_zeroize(cur);
|
||||
cur->next = old;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
cur->timestamp = t;
|
||||
#endif
|
||||
|
||||
*dst = cur;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_cache_set(void *data,
|
||||
unsigned char const *session_id,
|
||||
size_t session_id_len,
|
||||
const mbedtls_ssl_session *session)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
|
||||
mbedtls_ssl_cache_entry *cur;
|
||||
|
||||
size_t session_serialized_len = 0;
|
||||
unsigned char *session_serialized = NULL;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ((ret = mbedtls_mutex_lock(&cache->mutex)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = ssl_cache_pick_writing_slot(cache,
|
||||
session_id, session_id_len,
|
||||
&cur);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Check how much space we need to serialize the session
|
||||
* and allocate a sufficiently large buffer. */
|
||||
ret = mbedtls_ssl_session_save(session, NULL, 0, &session_serialized_len);
|
||||
if (ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
session_serialized = mbedtls_calloc(1, session_serialized_len);
|
||||
if (session_serialized == NULL) {
|
||||
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Now serialize the session into the allocated buffer. */
|
||||
ret = mbedtls_ssl_session_save(session,
|
||||
session_serialized,
|
||||
session_serialized_len,
|
||||
&session_serialized_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (session_id_len > sizeof(cur->session_id)) {
|
||||
ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
goto exit;
|
||||
}
|
||||
cur->session_id_len = session_id_len;
|
||||
memcpy(cur->session_id, session_id, session_id_len);
|
||||
|
||||
cur->session = session_serialized;
|
||||
cur->session_len = session_serialized_len;
|
||||
session_serialized = NULL;
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_unlock(&cache->mutex) != 0) {
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (session_serialized != NULL) {
|
||||
mbedtls_zeroize_and_free(session_serialized, session_serialized_len);
|
||||
session_serialized = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_cache_remove(void *data,
|
||||
unsigned char const *session_id,
|
||||
size_t session_id_len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
|
||||
mbedtls_ssl_cache_entry *entry;
|
||||
mbedtls_ssl_cache_entry *prev;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ((ret = mbedtls_mutex_lock(&cache->mutex)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = ssl_cache_find_entry(cache, session_id, session_id_len, &entry);
|
||||
/* No valid entry found, exit with success */
|
||||
if (ret != 0) {
|
||||
ret = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Now we remove the entry from the chain */
|
||||
if (entry == cache->chain) {
|
||||
cache->chain = entry->next;
|
||||
goto free;
|
||||
}
|
||||
for (prev = cache->chain; prev->next != NULL; prev = prev->next) {
|
||||
if (prev->next == entry) {
|
||||
prev->next = entry->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free:
|
||||
ssl_cache_entry_zeroize(entry);
|
||||
mbedtls_free(entry);
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_unlock(&cache->mutex) != 0) {
|
||||
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
void mbedtls_ssl_cache_set_timeout(mbedtls_ssl_cache_context *cache, int timeout)
|
||||
{
|
||||
if (timeout < 0) {
|
||||
timeout = 0;
|
||||
}
|
||||
|
||||
cache->timeout = timeout;
|
||||
}
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
|
||||
void mbedtls_ssl_cache_set_max_entries(mbedtls_ssl_cache_context *cache, int max)
|
||||
{
|
||||
if (max < 0) {
|
||||
max = 0;
|
||||
}
|
||||
|
||||
cache->max_entries = max;
|
||||
}
|
||||
|
||||
void mbedtls_ssl_cache_free(mbedtls_ssl_cache_context *cache)
|
||||
{
|
||||
mbedtls_ssl_cache_entry *cur, *prv;
|
||||
|
||||
cur = cache->chain;
|
||||
|
||||
while (cur != NULL) {
|
||||
prv = cur;
|
||||
cur = cur->next;
|
||||
|
||||
ssl_cache_entry_zeroize(prv);
|
||||
mbedtls_free(prv);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_free(&cache->mutex);
|
||||
#endif
|
||||
cache->chain = NULL;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SSL_CACHE_C */
|
||||
+996
@@ -0,0 +1,996 @@
|
||||
/**
|
||||
* \file ssl_ciphersuites.c
|
||||
*
|
||||
* \brief SSL ciphersuites for Mbed TLS
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C)
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "mbedtls/ssl_ciphersuites.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "ssl_misc.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Ordered from most preferred to least preferred in terms of security.
|
||||
*
|
||||
* Current rule (except weak and null which come last):
|
||||
* 1. By key exchange:
|
||||
* Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK
|
||||
* 2. By key length and cipher:
|
||||
* ChaCha > AES-256 > Camellia-256 > ARIA-256 > AES-128 > Camellia-128 > ARIA-128
|
||||
* 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8
|
||||
* 4. By hash function used when relevant
|
||||
* 5. By key exchange/auth again: EC > non-EC
|
||||
*/
|
||||
static const int ciphersuite_preference[] =
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_CIPHERSUITES)
|
||||
MBEDTLS_SSL_CIPHERSUITES,
|
||||
#else
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
/* TLS 1.3 ciphersuites */
|
||||
MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256,
|
||||
MBEDTLS_TLS1_3_AES_256_GCM_SHA384,
|
||||
MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
|
||||
MBEDTLS_TLS1_3_AES_128_CCM_SHA256,
|
||||
MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256,
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
/* Chacha-Poly ephemeral suites */
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
|
||||
/* All AES-256 ephemeral suites */
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
|
||||
|
||||
/* All CAMELLIA-256 ephemeral suites */
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
|
||||
|
||||
/* All ARIA-256 ephemeral suites */
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
|
||||
|
||||
/* All AES-128 ephemeral suites */
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
|
||||
|
||||
/* All CAMELLIA-128 ephemeral suites */
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
|
||||
|
||||
/* All ARIA-128 ephemeral suites */
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
|
||||
|
||||
/* The PSK ephemeral suites */
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
|
||||
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
|
||||
|
||||
/* The ECJPAKE suite */
|
||||
MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8,
|
||||
|
||||
/* The PSK suites */
|
||||
MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CCM,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA,
|
||||
MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
|
||||
MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
|
||||
MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
|
||||
MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
|
||||
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CCM,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA,
|
||||
MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
|
||||
MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
|
||||
MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
|
||||
MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
|
||||
|
||||
/* NULL suites */
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA,
|
||||
MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA,
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384,
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256,
|
||||
MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA,
|
||||
|
||||
MBEDTLS_TLS_PSK_WITH_NULL_SHA384,
|
||||
MBEDTLS_TLS_PSK_WITH_NULL_SHA256,
|
||||
MBEDTLS_TLS_PSK_WITH_NULL_SHA,
|
||||
|
||||
#endif /* MBEDTLS_SSL_CIPHERSUITES */
|
||||
0
|
||||
};
|
||||
|
||||
static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
#if defined(PSA_WANT_KEY_TYPE_AES)
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS1_3_AES_256_GCM_SHA384, "TLS1-3-AES-256-GCM-SHA384",
|
||||
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384,
|
||||
MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_3, MBEDTLS_SSL_VERSION_TLS1_3 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS1_3_AES_128_GCM_SHA256, "TLS1-3-AES-128-GCM-SHA256",
|
||||
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_3, MBEDTLS_SSL_VERSION_TLS1_3 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
#endif /* PSA_WANT_ALG_GCM */
|
||||
#if defined(PSA_WANT_ALG_CCM) && defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS1_3_AES_128_CCM_SHA256, "TLS1-3-AES-128-CCM-SHA256",
|
||||
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_3, MBEDTLS_SSL_VERSION_TLS1_3 },
|
||||
{ MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256, "TLS1-3-AES-128-CCM-8-SHA256",
|
||||
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */
|
||||
MBEDTLS_CIPHERSUITE_SHORT_TAG,
|
||||
MBEDTLS_SSL_VERSION_TLS1_3, MBEDTLS_SSL_VERSION_TLS1_3 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 && PSA_WANT_ALG_CCM */
|
||||
#endif /* PSA_WANT_KEY_TYPE_AES */
|
||||
#if defined(PSA_WANT_ALG_CHACHA20_POLY1305) && defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256,
|
||||
"TLS1-3-CHACHA20-POLY1305-SHA256",
|
||||
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_3, MBEDTLS_SSL_VERSION_TLS1_3 },
|
||||
#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 && PSA_WANT_ALG_SHA_256 */
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_CHACHA20_POLY1305) && \
|
||||
defined(PSA_WANT_ALG_SHA_256) && \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
"TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
|
||||
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
"TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256",
|
||||
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
|
||||
{ MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
|
||||
"TLS-PSK-WITH-CHACHA20-POLY1305-SHA256",
|
||||
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
|
||||
"TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256",
|
||||
MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 &&
|
||||
PSA_WANT_ALG_SHA_256 &&
|
||||
MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
#if defined(PSA_WANT_KEY_TYPE_AES)
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA",
|
||||
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA",
|
||||
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
|
||||
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_GCM */
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384",
|
||||
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_GCM */
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#if defined(PSA_WANT_ALG_CCM)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM",
|
||||
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8",
|
||||
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
MBEDTLS_CIPHERSUITE_SHORT_TAG,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM",
|
||||
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8",
|
||||
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
MBEDTLS_CIPHERSUITE_SHORT_TAG,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_CCM */
|
||||
#endif /* PSA_WANT_KEY_TYPE_AES */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
|
||||
"TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
|
||||
"TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
|
||||
"TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256",
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
|
||||
"TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#endif /* PSA_WANT_ALG_GCM */
|
||||
#endif /* PSA_WANT_KEY_TYPE_CAMELLIA */
|
||||
|
||||
#if defined(MBEDTLS_SSL_NULL_CIPHERSUITES)
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS-ECDHE-ECDSA-WITH-NULL-SHA",
|
||||
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
MBEDTLS_CIPHERSUITE_WEAK,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
#endif /* MBEDTLS_SSL_NULL_CIPHERSUITES */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
|
||||
#if defined(PSA_WANT_KEY_TYPE_AES)
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
|
||||
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
|
||||
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256",
|
||||
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_GCM */
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384",
|
||||
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_GCM */
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#endif /* PSA_WANT_KEY_TYPE_AES */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
|
||||
"TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
|
||||
"TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
|
||||
"TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256",
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
|
||||
"TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384",
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#endif /* PSA_WANT_ALG_GCM */
|
||||
#endif /* PSA_WANT_KEY_TYPE_CAMELLIA */
|
||||
|
||||
#if defined(MBEDTLS_SSL_NULL_CIPHERSUITES)
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS-ECDHE-RSA-WITH-NULL-SHA",
|
||||
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
MBEDTLS_CIPHERSUITE_WEAK,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
#endif /* MBEDTLS_SSL_NULL_CIPHERSUITES */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
|
||||
#if defined(PSA_WANT_KEY_TYPE_AES)
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, "TLS-PSK-WITH-AES-128-GCM-SHA256",
|
||||
MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, "TLS-PSK-WITH-AES-256-GCM-SHA384",
|
||||
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#endif /* PSA_WANT_ALG_GCM */
|
||||
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
{ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA",
|
||||
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
|
||||
{ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, "TLS-PSK-WITH-AES-256-CBC-SHA",
|
||||
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
#if defined(PSA_WANT_ALG_CCM)
|
||||
{ MBEDTLS_TLS_PSK_WITH_AES_256_CCM, "TLS-PSK-WITH-AES-256-CCM",
|
||||
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
{ MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, "TLS-PSK-WITH-AES-256-CCM-8",
|
||||
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
MBEDTLS_CIPHERSUITE_SHORT_TAG,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
{ MBEDTLS_TLS_PSK_WITH_AES_128_CCM, "TLS-PSK-WITH-AES-128-CCM",
|
||||
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
{ MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, "TLS-PSK-WITH-AES-128-CCM-8",
|
||||
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
MBEDTLS_CIPHERSUITE_SHORT_TAG,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_CCM */
|
||||
#endif /* PSA_WANT_KEY_TYPE_AES */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256",
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384",
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#endif /* PSA_WANT_ALG_GCM */
|
||||
#endif /* PSA_WANT_KEY_TYPE_CAMELLIA */
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
|
||||
#if defined(PSA_WANT_KEY_TYPE_AES)
|
||||
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA",
|
||||
MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA",
|
||||
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
#endif /* PSA_WANT_KEY_TYPE_AES */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
|
||||
"TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
|
||||
"TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
#endif /* PSA_WANT_KEY_TYPE_CAMELLIA */
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
||||
#if defined(PSA_WANT_KEY_TYPE_AES)
|
||||
#if defined(PSA_WANT_ALG_CCM)
|
||||
{ MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, "TLS-ECJPAKE-WITH-AES-128-CCM-8",
|
||||
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECJPAKE,
|
||||
MBEDTLS_CIPHERSUITE_SHORT_TAG,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_CCM */
|
||||
#endif /* PSA_WANT_KEY_TYPE_AES */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_NULL_CIPHERSUITES)
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
{ MBEDTLS_TLS_PSK_WITH_NULL_SHA, "TLS-PSK-WITH-NULL-SHA",
|
||||
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
MBEDTLS_CIPHERSUITE_WEAK,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256",
|
||||
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
MBEDTLS_CIPHERSUITE_WEAK,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384",
|
||||
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
MBEDTLS_CIPHERSUITE_WEAK,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, "TLS-ECDHE-PSK-WITH-NULL-SHA",
|
||||
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
MBEDTLS_CIPHERSUITE_WEAK,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, "TLS-ECDHE-PSK-WITH-NULL-SHA256",
|
||||
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
MBEDTLS_CIPHERSUITE_WEAK,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384",
|
||||
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
MBEDTLS_CIPHERSUITE_WEAK,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
|
||||
#endif /* MBEDTLS_SSL_NULL_CIPHERSUITES */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ARIA)
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
|
||||
|
||||
#if (defined(PSA_WANT_ALG_GCM) && defined(PSA_WANT_ALG_SHA_384))
|
||||
{ MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
|
||||
"TLS-PSK-WITH-ARIA-256-GCM-SHA384",
|
||||
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if (defined(PSA_WANT_ALG_CBC_NO_PADDING) && \
|
||||
defined(PSA_WANT_ALG_SHA_384))
|
||||
{ MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
|
||||
"TLS-PSK-WITH-ARIA-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if (defined(PSA_WANT_ALG_GCM) && defined(PSA_WANT_ALG_SHA_256))
|
||||
{ MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
|
||||
"TLS-PSK-WITH-ARIA-128-GCM-SHA256",
|
||||
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if (defined(PSA_WANT_ALG_CBC_NO_PADDING) && \
|
||||
defined(PSA_WANT_ALG_SHA_256))
|
||||
{ MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
|
||||
"TLS-PSK-WITH-ARIA-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
|
||||
|
||||
#if (defined(PSA_WANT_ALG_GCM) && defined(PSA_WANT_ALG_SHA_384))
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
|
||||
"TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384",
|
||||
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if (defined(PSA_WANT_ALG_CBC_NO_PADDING) && \
|
||||
defined(PSA_WANT_ALG_SHA_384))
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
|
||||
"TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if (defined(PSA_WANT_ALG_GCM) && defined(PSA_WANT_ALG_SHA_256))
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
|
||||
"TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256",
|
||||
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if (defined(PSA_WANT_ALG_CBC_NO_PADDING) && \
|
||||
defined(PSA_WANT_ALG_SHA_256))
|
||||
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
|
||||
"TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
|
||||
|
||||
#if (defined(PSA_WANT_ALG_CBC_NO_PADDING) && \
|
||||
defined(PSA_WANT_ALG_SHA_384))
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
|
||||
"TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if (defined(PSA_WANT_ALG_CBC_NO_PADDING) && \
|
||||
defined(PSA_WANT_ALG_SHA_256))
|
||||
{ MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
|
||||
"TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
|
||||
#if (defined(PSA_WANT_ALG_GCM) && defined(PSA_WANT_ALG_SHA_384))
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
|
||||
"TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384",
|
||||
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if (defined(PSA_WANT_ALG_CBC_NO_PADDING) && \
|
||||
defined(PSA_WANT_ALG_SHA_384))
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
|
||||
"TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
|
||||
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if (defined(PSA_WANT_ALG_GCM) && defined(PSA_WANT_ALG_SHA_256))
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
|
||||
"TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256",
|
||||
MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
#if (defined(PSA_WANT_ALG_CBC_NO_PADDING) && \
|
||||
defined(PSA_WANT_ALG_SHA_256))
|
||||
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
|
||||
"TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256",
|
||||
MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
|
||||
0,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 },
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
|
||||
|
||||
#endif /* PSA_WANT_KEY_TYPE_ARIA */
|
||||
|
||||
|
||||
{ 0, "",
|
||||
MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE,
|
||||
0, 0, 0 }
|
||||
};
|
||||
|
||||
#if defined(MBEDTLS_SSL_CIPHERSUITES)
|
||||
const int *mbedtls_ssl_list_ciphersuites(void)
|
||||
{
|
||||
return ciphersuite_preference;
|
||||
}
|
||||
#else
|
||||
#define MAX_CIPHERSUITES sizeof(ciphersuite_definitions) / \
|
||||
sizeof(ciphersuite_definitions[0])
|
||||
static int supported_ciphersuites[MAX_CIPHERSUITES];
|
||||
static int supported_init = 0;
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ciphersuite_is_removed(const mbedtls_ssl_ciphersuite_t *cs_info)
|
||||
{
|
||||
(void) cs_info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int *mbedtls_ssl_list_ciphersuites(void)
|
||||
{
|
||||
/*
|
||||
* On initial call filter out all ciphersuites not supported by current
|
||||
* build based on presence in the ciphersuite_definitions.
|
||||
*/
|
||||
if (supported_init == 0) {
|
||||
const int *p;
|
||||
int *q;
|
||||
|
||||
for (p = ciphersuite_preference, q = supported_ciphersuites;
|
||||
*p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1;
|
||||
p++) {
|
||||
const mbedtls_ssl_ciphersuite_t *cs_info;
|
||||
if ((cs_info = mbedtls_ssl_ciphersuite_from_id(*p)) != NULL &&
|
||||
!ciphersuite_is_removed(cs_info)) {
|
||||
*(q++) = *p;
|
||||
}
|
||||
}
|
||||
*q = 0;
|
||||
|
||||
supported_init = 1;
|
||||
}
|
||||
|
||||
return supported_ciphersuites;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_CIPHERSUITES */
|
||||
|
||||
const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string(
|
||||
const char *ciphersuite_name)
|
||||
{
|
||||
const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions;
|
||||
|
||||
if (NULL == ciphersuite_name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (cur->id != 0) {
|
||||
if (0 == strcmp(cur->name, ciphersuite_name)) {
|
||||
return cur;
|
||||
}
|
||||
|
||||
cur++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id(int ciphersuite)
|
||||
{
|
||||
const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions;
|
||||
|
||||
while (cur->id != 0) {
|
||||
if (cur->id == ciphersuite) {
|
||||
return cur;
|
||||
}
|
||||
|
||||
cur++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *mbedtls_ssl_get_ciphersuite_name(const int ciphersuite_id)
|
||||
{
|
||||
const mbedtls_ssl_ciphersuite_t *cur;
|
||||
|
||||
cur = mbedtls_ssl_ciphersuite_from_id(ciphersuite_id);
|
||||
|
||||
if (cur == NULL) {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
return cur->name;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_get_ciphersuite_id(const char *ciphersuite_name)
|
||||
{
|
||||
const mbedtls_ssl_ciphersuite_t *cur;
|
||||
|
||||
cur = mbedtls_ssl_ciphersuite_from_string(ciphersuite_name);
|
||||
|
||||
if (cur == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cur->id;
|
||||
}
|
||||
|
||||
size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_type_t key_type;
|
||||
psa_algorithm_t alg;
|
||||
size_t key_bits;
|
||||
|
||||
status = mbedtls_ssl_cipher_to_psa((mbedtls_cipher_type_t) info->cipher,
|
||||
info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16,
|
||||
&alg, &key_type, &key_bits);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return key_bits;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_C)
|
||||
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->key_exchange) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
return MBEDTLS_PK_RSA;
|
||||
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
return MBEDTLS_PK_ECDSA;
|
||||
|
||||
default:
|
||||
return MBEDTLS_PK_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
psa_algorithm_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->key_exchange) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
return PSA_ALG_RSA_PKCS1V15_SIGN(
|
||||
mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) info->mac));
|
||||
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
return MBEDTLS_PK_ALG_ECDSA(mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) info->mac));
|
||||
|
||||
default:
|
||||
return PSA_ALG_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
psa_key_usage_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->key_exchange) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
return PSA_KEY_USAGE_SIGN_HASH;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->key_exchange) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
return MBEDTLS_PK_RSA;
|
||||
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
return MBEDTLS_PK_ECDSA;
|
||||
|
||||
default:
|
||||
return MBEDTLS_PK_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PK_C */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
||||
int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->key_exchange) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
|
||||
* MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
|
||||
* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
int mbedtls_ssl_ciphersuite_uses_psk(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->key_exchange) {
|
||||
case MBEDTLS_KEY_EXCHANGE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_SSL_TLS_C */
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* \file ssl_ciphersuites_internal.h
|
||||
*
|
||||
* \brief Internal part of the public "ssl_ciphersuites.h".
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H
|
||||
#define MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H
|
||||
|
||||
#include "mbedtls/pk.h"
|
||||
#if defined(MBEDTLS_PK_HAVE_PRIVATE_HEADER)
|
||||
#include <mbedtls/private/pk_private.h>
|
||||
#endif /* MBEDTLS_PK_HAVE_PRIVATE_HEADER */
|
||||
|
||||
#if defined(MBEDTLS_PK_C)
|
||||
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg(const mbedtls_ssl_ciphersuite_t *info);
|
||||
psa_algorithm_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(const mbedtls_ssl_ciphersuite_t *info);
|
||||
psa_key_usage_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(const mbedtls_ssl_ciphersuite_t *info);
|
||||
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg(const mbedtls_ssl_ciphersuite_t *info);
|
||||
#endif /* MBEDTLS_PK_C */
|
||||
|
||||
int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info);
|
||||
int mbedtls_ssl_ciphersuite_uses_psk(const mbedtls_ssl_ciphersuite_t *info);
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
|
||||
static inline int mbedtls_ssl_ciphersuite_has_pfs(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
|
||||
static inline int mbedtls_ssl_ciphersuite_no_pfs(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_PSK:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
|
||||
|
||||
static inline int mbedtls_ssl_ciphersuite_cert_req_allowed(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int mbedtls_ssl_ciphersuite_uses_srv_cert(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
|
||||
static inline int mbedtls_ssl_ciphersuite_uses_ecdhe(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
|
||||
static inline int mbedtls_ssl_ciphersuite_uses_server_signature(
|
||||
const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
switch (info->MBEDTLS_PRIVATE(key_exchange)) {
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H */
|
||||
+1015
File diff suppressed because it is too large
Load Diff
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* TLS 1.2 and 1.3 client-side functions
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_SSL_CLIENT_H
|
||||
#define MBEDTLS_SSL_CLIENT_H
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_write_client_hello(mbedtls_ssl_context *ssl);
|
||||
|
||||
#endif /* MBEDTLS_SSL_CLIENT_H */
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* DTLS cookie callbacks implementation
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
/*
|
||||
* These session callbacks use a simple chained list
|
||||
* to store and retrieve the session information.
|
||||
*/
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_SSL_COOKIE_C)
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "mbedtls/ssl_cookie.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/constant_time.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/psa_util.h"
|
||||
/* Define a local translating function to save code size by not using too many
|
||||
* arguments in each translating place. */
|
||||
static int local_err_translation(psa_status_t status)
|
||||
{
|
||||
return psa_status_to_mbedtls(status, psa_to_ssl_errors,
|
||||
ARRAY_LENGTH(psa_to_ssl_errors),
|
||||
psa_generic_status_to_mbedtls);
|
||||
}
|
||||
#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
|
||||
|
||||
/*
|
||||
* If DTLS is in use, then at least one of SHA-256 or SHA-384 is
|
||||
* available. Try SHA-256 first as 384 wastes resources
|
||||
*/
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
#define COOKIE_MD MBEDTLS_MD_SHA256
|
||||
#define COOKIE_MD_OUTLEN 32
|
||||
#define COOKIE_HMAC_LEN 28
|
||||
#elif defined(PSA_WANT_ALG_SHA_384)
|
||||
#define COOKIE_MD MBEDTLS_MD_SHA384
|
||||
#define COOKIE_MD_OUTLEN 48
|
||||
#define COOKIE_HMAC_LEN 28
|
||||
#else
|
||||
#error "DTLS hello verify needs SHA-256 or SHA-384"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Cookies are formed of a 4-bytes timestamp (or serial number) and
|
||||
* an HMAC of timestamp and client ID.
|
||||
*/
|
||||
#define COOKIE_LEN (4 + COOKIE_HMAC_LEN)
|
||||
|
||||
void mbedtls_ssl_cookie_init(mbedtls_ssl_cookie_ctx *ctx)
|
||||
{
|
||||
ctx->psa_hmac_key = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
#if !defined(MBEDTLS_HAVE_TIME)
|
||||
ctx->serial = 0;
|
||||
#endif
|
||||
ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT;
|
||||
|
||||
}
|
||||
|
||||
void mbedtls_ssl_cookie_set_timeout(mbedtls_ssl_cookie_ctx *ctx, unsigned long delay)
|
||||
{
|
||||
ctx->timeout = delay;
|
||||
}
|
||||
|
||||
void mbedtls_ssl_cookie_free(mbedtls_ssl_cookie_ctx *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
psa_destroy_key(ctx->psa_hmac_key);
|
||||
|
||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ssl_cookie_ctx));
|
||||
}
|
||||
|
||||
int mbedtls_ssl_cookie_setup(mbedtls_ssl_cookie_ctx *ctx)
|
||||
{
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_algorithm_t alg;
|
||||
|
||||
|
||||
alg = mbedtls_md_psa_alg_from_type(COOKIE_MD);
|
||||
if (alg == 0) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ctx->psa_hmac_alg = PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(alg),
|
||||
COOKIE_HMAC_LEN);
|
||||
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_MESSAGE |
|
||||
PSA_KEY_USAGE_SIGN_MESSAGE);
|
||||
psa_set_key_algorithm(&attributes, ctx->psa_hmac_alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
|
||||
psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(COOKIE_MD_OUTLEN));
|
||||
|
||||
if ((status = psa_generate_key(&attributes,
|
||||
&ctx->psa_hmac_key)) != PSA_SUCCESS) {
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generate cookie for DTLS ClientHello verification
|
||||
*/
|
||||
int mbedtls_ssl_cookie_write(void *p_ctx,
|
||||
unsigned char **p, unsigned char *end,
|
||||
const unsigned char *cli_id, size_t cli_id_len)
|
||||
{
|
||||
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t sign_mac_length = 0;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
|
||||
unsigned long t;
|
||||
|
||||
if (ctx == NULL || cli_id == NULL) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_PTR(*p, end, COOKIE_LEN);
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
t = (unsigned long) mbedtls_time(NULL);
|
||||
#else
|
||||
t = ctx->serial++;
|
||||
#endif
|
||||
|
||||
MBEDTLS_PUT_UINT32_BE(t, *p, 0);
|
||||
*p += 4;
|
||||
|
||||
status = psa_mac_sign_setup(&operation, ctx->psa_hmac_key,
|
||||
ctx->psa_hmac_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_mac_update(&operation, *p - 4, 4);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_mac_update(&operation, cli_id, cli_id_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_mac_sign_finish(&operation, *p, COOKIE_MD_OUTLEN,
|
||||
&sign_mac_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*p += COOKIE_HMAC_LEN;
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
status = psa_mac_abort(&operation);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check a cookie
|
||||
*/
|
||||
int mbedtls_ssl_cookie_check(void *p_ctx,
|
||||
const unsigned char *cookie, size_t cookie_len,
|
||||
const unsigned char *cli_id, size_t cli_id_len)
|
||||
{
|
||||
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
int ret = 0;
|
||||
mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
|
||||
unsigned long cur_time, cookie_time;
|
||||
|
||||
if (ctx == NULL || cli_id == NULL) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (cookie_len != COOKIE_LEN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = psa_mac_verify_setup(&operation, ctx->psa_hmac_key,
|
||||
ctx->psa_hmac_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_mac_update(&operation, cookie, 4);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_mac_update(&operation, cli_id,
|
||||
cli_id_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_mac_verify_finish(&operation, cookie + 4,
|
||||
COOKIE_HMAC_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
cur_time = (unsigned long) mbedtls_time(NULL);
|
||||
#else
|
||||
cur_time = ctx->serial;
|
||||
#endif
|
||||
|
||||
cookie_time = (unsigned long) MBEDTLS_GET_UINT32_BE(cookie, 0);
|
||||
|
||||
if (ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout) {
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
status = psa_mac_abort(&operation);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_COOKIE_C */
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* \file ssl_debug_helpers.h
|
||||
*
|
||||
* \brief Automatically generated helper functions for debugging
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_SSL_DEBUG_HELPERS_H
|
||||
#define MBEDTLS_SSL_DEBUG_HELPERS_H
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
|
||||
#include "mbedtls/ssl.h"
|
||||
|
||||
const char *mbedtls_ssl_states_str(mbedtls_ssl_states in);
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
|
||||
const char *mbedtls_ssl_early_data_status_str(mbedtls_ssl_early_data_status in);
|
||||
const char *mbedtls_ssl_early_data_state_str(mbedtls_ssl_early_data_state in);
|
||||
#endif
|
||||
|
||||
const char *mbedtls_ssl_protocol_version_str(mbedtls_ssl_protocol_version in);
|
||||
|
||||
const char *mbedtls_tls_prf_types_str(mbedtls_tls_prf_types in);
|
||||
|
||||
const char *mbedtls_ssl_key_export_type_str(mbedtls_ssl_key_export_type in);
|
||||
|
||||
const char *mbedtls_ssl_sig_alg_to_str(uint16_t in);
|
||||
|
||||
const char *mbedtls_ssl_named_group_to_str(uint16_t in);
|
||||
|
||||
const char *mbedtls_ssl_get_extension_name(unsigned int extension_type);
|
||||
|
||||
void mbedtls_ssl_print_extensions(const mbedtls_ssl_context *ssl,
|
||||
int level, const char *file, int line,
|
||||
int hs_msg_type, uint32_t extensions_mask,
|
||||
const char *extra);
|
||||
|
||||
void mbedtls_ssl_print_extension(const mbedtls_ssl_context *ssl,
|
||||
int level, const char *file, int line,
|
||||
int hs_msg_type, unsigned int extension_type,
|
||||
const char *extra_msg0, const char *extra_msg1);
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl,
|
||||
int level, const char *file, int line,
|
||||
unsigned int flags);
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
#define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extensions_mask) \
|
||||
mbedtls_ssl_print_extensions(ssl, level, __FILE__, __LINE__, \
|
||||
hs_msg_type, extensions_mask, NULL)
|
||||
|
||||
#define MBEDTLS_SSL_PRINT_EXT(level, hs_msg_type, extension_type, extra) \
|
||||
mbedtls_ssl_print_extension(ssl, level, __FILE__, __LINE__, \
|
||||
hs_msg_type, extension_type, \
|
||||
extra, NULL)
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
#define MBEDTLS_SSL_PRINT_TICKET_FLAGS(level, flags) \
|
||||
mbedtls_ssl_print_ticket_flags(ssl, level, __FILE__, __LINE__, flags)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extension_mask)
|
||||
|
||||
#define MBEDTLS_SSL_PRINT_EXT(level, hs_msg_type, extension_type, extra)
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
#define MBEDTLS_SSL_PRINT_TICKET_FLAGS(level, flags)
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
|
||||
#endif /* MBEDTLS_SSL_DEBUG_HELPERS_H */
|
||||
+2920
File diff suppressed because it is too large
Load Diff
+6168
File diff suppressed because it is too large
Load Diff
+453
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
* TLS server tickets callbacks implementation
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_SSL_TICKET_C)
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "mbedtls/ssl_ticket.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Define a local translating function to save code size by not using too many
|
||||
* arguments in each translating place. */
|
||||
static int local_err_translation(psa_status_t status)
|
||||
{
|
||||
return psa_status_to_mbedtls(status, psa_to_ssl_errors,
|
||||
ARRAY_LENGTH(psa_to_ssl_errors),
|
||||
psa_generic_status_to_mbedtls);
|
||||
}
|
||||
#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
|
||||
|
||||
/*
|
||||
* Initialize context
|
||||
*/
|
||||
void mbedtls_ssl_ticket_init(mbedtls_ssl_ticket_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(mbedtls_ssl_ticket_context));
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init(&ctx->mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define MAX_KEY_BYTES MBEDTLS_SSL_TICKET_MAX_KEY_BYTES
|
||||
|
||||
#define TICKET_KEY_NAME_BYTES MBEDTLS_SSL_TICKET_KEY_NAME_BYTES
|
||||
#define TICKET_IV_BYTES 12
|
||||
#define TICKET_CRYPT_LEN_BYTES 2
|
||||
#define TICKET_AUTH_TAG_BYTES 16
|
||||
|
||||
#define TICKET_MIN_LEN (TICKET_KEY_NAME_BYTES + \
|
||||
TICKET_IV_BYTES + \
|
||||
TICKET_CRYPT_LEN_BYTES + \
|
||||
TICKET_AUTH_TAG_BYTES)
|
||||
#define TICKET_ADD_DATA_LEN (TICKET_KEY_NAME_BYTES + \
|
||||
TICKET_IV_BYTES + \
|
||||
TICKET_CRYPT_LEN_BYTES)
|
||||
|
||||
/*
|
||||
* Generate/update a key
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_ticket_gen_key(mbedtls_ssl_ticket_context *ctx,
|
||||
unsigned char index)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char buf[MAX_KEY_BYTES] = { 0 };
|
||||
mbedtls_ssl_ticket_key *key = ctx->keys + index;
|
||||
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
key->generation_time = mbedtls_time(NULL);
|
||||
#endif
|
||||
/* The lifetime of a key is the configured lifetime of the tickets when
|
||||
* the key is created.
|
||||
*/
|
||||
key->lifetime = ctx->ticket_lifetime;
|
||||
|
||||
if ((ret = psa_generate_random(key->name, sizeof(key->name))) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = psa_generate_random(buf, sizeof(buf))) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&attributes,
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, key->alg);
|
||||
psa_set_key_type(&attributes, key->key_type);
|
||||
psa_set_key_bits(&attributes, key->key_bits);
|
||||
|
||||
ret = PSA_TO_MBEDTLS_ERR(
|
||||
psa_import_key(&attributes, buf,
|
||||
PSA_BITS_TO_BYTES(key->key_bits),
|
||||
&key->key));
|
||||
|
||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rotate/generate keys if necessary
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_ticket_update_keys(mbedtls_ssl_ticket_context *ctx)
|
||||
{
|
||||
#if !defined(MBEDTLS_HAVE_TIME)
|
||||
((void) ctx);
|
||||
#else
|
||||
mbedtls_ssl_ticket_key * const key = ctx->keys + ctx->active;
|
||||
if (key->lifetime != 0) {
|
||||
mbedtls_time_t current_time = mbedtls_time(NULL);
|
||||
mbedtls_time_t key_time = key->generation_time;
|
||||
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (current_time >= key_time &&
|
||||
(uint64_t) (current_time - key_time) < key->lifetime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->active = 1 - ctx->active;
|
||||
|
||||
if ((status = psa_destroy_key(ctx->keys[ctx->active].key)) != PSA_SUCCESS) {
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
return ssl_ticket_gen_key(ctx, ctx->active);
|
||||
} else
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rotate active session ticket encryption key
|
||||
*/
|
||||
int mbedtls_ssl_ticket_rotate(mbedtls_ssl_ticket_context *ctx,
|
||||
const unsigned char *name, size_t nlength,
|
||||
const unsigned char *k, size_t klength,
|
||||
uint32_t lifetime)
|
||||
{
|
||||
const unsigned char idx = 1 - ctx->active;
|
||||
mbedtls_ssl_ticket_key * const key = ctx->keys + idx;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
const size_t bitlen = key->key_bits;
|
||||
|
||||
if (nlength < TICKET_KEY_NAME_BYTES || klength * 8 < (size_t) bitlen) {
|
||||
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((status = psa_destroy_key(key->key)) != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&attributes,
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, key->alg);
|
||||
psa_set_key_type(&attributes, key->key_type);
|
||||
psa_set_key_bits(&attributes, key->key_bits);
|
||||
|
||||
if ((status = psa_import_key(&attributes, k,
|
||||
PSA_BITS_TO_BYTES(key->key_bits),
|
||||
&key->key)) != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->active = idx;
|
||||
ctx->ticket_lifetime = lifetime;
|
||||
memcpy(key->name, name, TICKET_KEY_NAME_BYTES);
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
key->generation_time = mbedtls_time(NULL);
|
||||
#endif
|
||||
key->lifetime = lifetime;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup context for actual use
|
||||
*/
|
||||
int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx,
|
||||
psa_algorithm_t alg, psa_key_type_t key_type, psa_key_bits_t key_bits,
|
||||
uint32_t lifetime)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (PSA_ALG_IS_AEAD(alg) == 0) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (key_bits > 8 * MAX_KEY_BYTES) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ctx->ticket_lifetime = lifetime;
|
||||
|
||||
ctx->keys[0].alg = alg;
|
||||
ctx->keys[0].key_type = key_type;
|
||||
ctx->keys[0].key_bits = key_bits;
|
||||
|
||||
ctx->keys[1].alg = alg;
|
||||
ctx->keys[1].key_type = key_type;
|
||||
ctx->keys[1].key_bits = key_bits;
|
||||
|
||||
if ((ret = ssl_ticket_gen_key(ctx, 0)) != 0 ||
|
||||
(ret = ssl_ticket_gen_key(ctx, 1)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create session ticket, with the following structure:
|
||||
*
|
||||
* struct {
|
||||
* opaque key_name[4];
|
||||
* opaque iv[12];
|
||||
* opaque encrypted_state<0..2^16-1>;
|
||||
* opaque tag[16];
|
||||
* } ticket;
|
||||
*
|
||||
* The key_name, iv, and length of encrypted_state are the additional
|
||||
* authenticated data.
|
||||
*/
|
||||
|
||||
int mbedtls_ssl_ticket_write(void *p_ticket,
|
||||
const mbedtls_ssl_session *session,
|
||||
unsigned char *start,
|
||||
const unsigned char *end,
|
||||
size_t *tlen,
|
||||
uint32_t *ticket_lifetime)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ssl_ticket_context *ctx = p_ticket;
|
||||
mbedtls_ssl_ticket_key *key;
|
||||
unsigned char *key_name = start;
|
||||
unsigned char *iv = start + TICKET_KEY_NAME_BYTES;
|
||||
unsigned char *state_len_bytes = iv + TICKET_IV_BYTES;
|
||||
unsigned char *state = state_len_bytes + TICKET_CRYPT_LEN_BYTES;
|
||||
size_t clear_len, ciph_len;
|
||||
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
*tlen = 0;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
/* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag,
|
||||
* in addition to session itself, that will be checked when writing it. */
|
||||
MBEDTLS_SSL_CHK_BUF_PTR(start, end, TICKET_MIN_LEN);
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ret = ssl_ticket_update_keys(ctx)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
key = &ctx->keys[ctx->active];
|
||||
|
||||
*ticket_lifetime = key->lifetime;
|
||||
|
||||
memcpy(key_name, key->name, TICKET_KEY_NAME_BYTES);
|
||||
|
||||
if ((ret = psa_generate_random(iv, TICKET_IV_BYTES)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Dump session state */
|
||||
if ((ret = mbedtls_ssl_session_save(session,
|
||||
state, (size_t) (end - state),
|
||||
&clear_len)) != 0 ||
|
||||
(unsigned long) clear_len > 65535) {
|
||||
goto cleanup;
|
||||
}
|
||||
MBEDTLS_PUT_UINT16_BE(clear_len, state_len_bytes, 0);
|
||||
|
||||
/* Encrypt and authenticate */
|
||||
if ((status = psa_aead_encrypt(key->key, key->alg, iv, TICKET_IV_BYTES,
|
||||
key_name, TICKET_ADD_DATA_LEN,
|
||||
state, clear_len,
|
||||
state, end - state,
|
||||
&ciph_len)) != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ciph_len != clear_len + TICKET_AUTH_TAG_BYTES) {
|
||||
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*tlen = TICKET_MIN_LEN + ciph_len - TICKET_AUTH_TAG_BYTES;
|
||||
|
||||
cleanup:
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
|
||||
return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select key based on name
|
||||
*/
|
||||
static mbedtls_ssl_ticket_key *ssl_ticket_select_key(
|
||||
mbedtls_ssl_ticket_context *ctx,
|
||||
const unsigned char name[4])
|
||||
{
|
||||
unsigned char i;
|
||||
|
||||
for (i = 0; i < sizeof(ctx->keys) / sizeof(*ctx->keys); i++) {
|
||||
if (memcmp(name, ctx->keys[i].name, 4) == 0) {
|
||||
return &ctx->keys[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load session ticket (see mbedtls_ssl_ticket_write for structure)
|
||||
*/
|
||||
int mbedtls_ssl_ticket_parse(void *p_ticket,
|
||||
mbedtls_ssl_session *session,
|
||||
unsigned char *buf,
|
||||
size_t len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ssl_ticket_context *ctx = p_ticket;
|
||||
mbedtls_ssl_ticket_key *key;
|
||||
unsigned char *key_name = buf;
|
||||
unsigned char *iv = buf + TICKET_KEY_NAME_BYTES;
|
||||
unsigned char *enc_len_p = iv + TICKET_IV_BYTES;
|
||||
unsigned char *ticket = enc_len_p + TICKET_CRYPT_LEN_BYTES;
|
||||
size_t enc_len, clear_len;
|
||||
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (ctx == NULL) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (len < TICKET_MIN_LEN) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ret = ssl_ticket_update_keys(ctx)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
enc_len = MBEDTLS_GET_UINT16_BE(enc_len_p, 0);
|
||||
|
||||
if (len != TICKET_MIN_LEN + enc_len) {
|
||||
ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Select key */
|
||||
if ((key = ssl_ticket_select_key(ctx, key_name)) == NULL) {
|
||||
/* We can't know for sure but this is a likely option unless we're
|
||||
* under attack - this is only informative anyway */
|
||||
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Decrypt and authenticate */
|
||||
if ((status = psa_aead_decrypt(key->key, key->alg, iv, TICKET_IV_BYTES,
|
||||
key_name, TICKET_ADD_DATA_LEN,
|
||||
ticket, enc_len + TICKET_AUTH_TAG_BYTES,
|
||||
ticket, enc_len, &clear_len)) != PSA_SUCCESS) {
|
||||
ret = PSA_TO_MBEDTLS_ERR(status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (clear_len != enc_len) {
|
||||
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Actually load session */
|
||||
if ((ret = mbedtls_ssl_session_load(session, ticket, clear_len)) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_ms_time_t ticket_creation_time, ticket_age;
|
||||
mbedtls_ms_time_t ticket_lifetime =
|
||||
(mbedtls_ms_time_t) key->lifetime * 1000;
|
||||
|
||||
ret = mbedtls_ssl_session_get_ticket_creation_time(session,
|
||||
&ticket_creation_time);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ticket_age = mbedtls_ms_time() - ticket_creation_time;
|
||||
if (ticket_age < 0 || ticket_age > ticket_lifetime) {
|
||||
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
|
||||
return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free context
|
||||
*/
|
||||
void mbedtls_ssl_ticket_free(mbedtls_ssl_ticket_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
psa_destroy_key(ctx->keys[0].key);
|
||||
psa_destroy_key(ctx->keys[1].key);
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_free(&ctx->mutex);
|
||||
#endif
|
||||
|
||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ssl_ticket_context));
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SSL_TICKET_C */
|
||||
+9006
File diff suppressed because it is too large
Load Diff
+2967
File diff suppressed because it is too large
Load Diff
+3655
File diff suppressed because it is too large
Load Diff
+3181
File diff suppressed because it is too large
Load Diff
+1732
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_SSL_TLS13_INVASIVE_H
|
||||
#define MBEDTLS_SSL_TLS13_INVASIVE_H
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
int mbedtls_ssl_tls13_parse_certificate(mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf,
|
||||
const unsigned char *end);
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
#endif /* MBEDTLS_SSL_TLS13_INVASIVE_H */
|
||||
+1860
File diff suppressed because it is too large
Load Diff
+668
@@ -0,0 +1,668 @@
|
||||
/*
|
||||
* TLS 1.3 key schedule
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#if !defined(MBEDTLS_SSL_TLS1_3_KEYS_H)
|
||||
#define MBEDTLS_SSL_TLS1_3_KEYS_H
|
||||
|
||||
/* This requires MBEDTLS_SSL_TLS1_3_LABEL( idx, name, string ) to be defined at
|
||||
* the point of use. See e.g. the definition of mbedtls_ssl_tls13_labels_union
|
||||
* below. */
|
||||
#define MBEDTLS_SSL_TLS1_3_LABEL_LIST \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(finished, "finished") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(resumption, "resumption") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(traffic_upd, "traffic upd") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(exporter, "exporter") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(key, "key") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(iv, "iv") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(c_hs_traffic, "c hs traffic") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(c_ap_traffic, "c ap traffic") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(c_e_traffic, "c e traffic") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(s_hs_traffic, "s hs traffic") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(s_ap_traffic, "s ap traffic") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(s_e_traffic, "s e traffic") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(e_exp_master, "e exp master") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(res_master, "res master") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(exp_master, "exp master") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(ext_binder, "ext binder") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(res_binder, "res binder") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(derived, "derived") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(client_cv, "TLS 1.3, client CertificateVerify") \
|
||||
MBEDTLS_SSL_TLS1_3_LABEL(server_cv, "TLS 1.3, server CertificateVerify")
|
||||
|
||||
#define MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED 0
|
||||
#define MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED 1
|
||||
|
||||
#define MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL 0
|
||||
#define MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION 1
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
|
||||
/* We need to tell the compiler that we meant to leave out the null character. */
|
||||
#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \
|
||||
const unsigned char name [sizeof(string) - 1] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING;
|
||||
|
||||
union mbedtls_ssl_tls13_labels_union {
|
||||
MBEDTLS_SSL_TLS1_3_LABEL_LIST
|
||||
};
|
||||
struct mbedtls_ssl_tls13_labels_struct {
|
||||
MBEDTLS_SSL_TLS1_3_LABEL_LIST
|
||||
};
|
||||
#undef MBEDTLS_SSL_TLS1_3_LABEL
|
||||
|
||||
extern const struct mbedtls_ssl_tls13_labels_struct mbedtls_ssl_tls13_labels;
|
||||
|
||||
#define MBEDTLS_SSL_TLS1_3_LBL_LEN(LABEL) \
|
||||
sizeof(mbedtls_ssl_tls13_labels.LABEL)
|
||||
|
||||
#define MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(LABEL) \
|
||||
mbedtls_ssl_tls13_labels.LABEL, \
|
||||
MBEDTLS_SSL_TLS1_3_LBL_LEN(LABEL)
|
||||
|
||||
/* Maximum length of the label field in the HkdfLabel struct defined in
|
||||
* RFC 8446, Section 7.1, excluding the "tls13 " prefix. */
|
||||
#define MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN 249
|
||||
|
||||
/* The maximum length of HKDF contexts used in the TLS 1.3 standard.
|
||||
* Since contexts are always hashes of message transcripts, this can
|
||||
* be approximated from above by the maximum hash size. */
|
||||
#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN \
|
||||
PSA_HASH_MAX_SIZE
|
||||
|
||||
/* Maximum desired length for expanded key material generated
|
||||
* by HKDF-Expand-Label. This algorithm can output up to 255 * hash_size
|
||||
* bytes of key material where hash_size is the output size of the
|
||||
* underlying hash function. */
|
||||
#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN \
|
||||
(255 * MBEDTLS_TLS1_3_MD_MAX_SIZE)
|
||||
|
||||
/**
|
||||
* \brief The \c HKDF-Expand-Label function from
|
||||
* the TLS 1.3 standard RFC 8446.
|
||||
*
|
||||
* <tt>
|
||||
* HKDF-Expand-Label( Secret, Label, Context, Length ) =
|
||||
* HKDF-Expand( Secret, HkdfLabel, Length )
|
||||
* </tt>
|
||||
*
|
||||
* \param hash_alg The identifier for the hash algorithm to use.
|
||||
* \param secret The \c Secret argument to \c HKDF-Expand-Label.
|
||||
* This must be a readable buffer of length
|
||||
* \p secret_len Bytes.
|
||||
* \param secret_len The length of \p secret in Bytes.
|
||||
* \param label The \c Label argument to \c HKDF-Expand-Label.
|
||||
* This must be a readable buffer of length
|
||||
* \p label_len Bytes.
|
||||
* \param label_len The length of \p label in Bytes.
|
||||
* \param ctx The \c Context argument to \c HKDF-Expand-Label.
|
||||
* This must be a readable buffer of length \p ctx_len Bytes.
|
||||
* \param ctx_len The length of \p context in Bytes.
|
||||
* \param buf The destination buffer to hold the expanded secret.
|
||||
* This must be a writable buffer of length \p buf_len Bytes.
|
||||
* \param buf_len The desired size of the expanded secret in Bytes.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_hkdf_expand_label(
|
||||
psa_algorithm_t hash_alg,
|
||||
const unsigned char *secret, size_t secret_len,
|
||||
const unsigned char *label, size_t label_len,
|
||||
const unsigned char *ctx, size_t ctx_len,
|
||||
unsigned char *buf, size_t buf_len);
|
||||
|
||||
/**
|
||||
* \brief This function is part of the TLS 1.3 key schedule.
|
||||
* It extracts key and IV for the actual client/server traffic
|
||||
* from the client/server traffic secrets.
|
||||
*
|
||||
* From RFC 8446:
|
||||
*
|
||||
* <tt>
|
||||
* [sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length)
|
||||
* [sender]_write_iv = HKDF-Expand-Label(Secret, "iv", "", iv_length)*
|
||||
* </tt>
|
||||
*
|
||||
* \param hash_alg The identifier for the hash algorithm to be used
|
||||
* for the HKDF-based expansion of the secret.
|
||||
* \param client_secret The client traffic secret.
|
||||
* This must be a readable buffer of size
|
||||
* \p secret_len Bytes
|
||||
* \param server_secret The server traffic secret.
|
||||
* This must be a readable buffer of size
|
||||
* \p secret_len Bytes
|
||||
* \param secret_len Length of the secrets \p client_secret and
|
||||
* \p server_secret in Bytes.
|
||||
* \param key_len The desired length of the key to be extracted in Bytes.
|
||||
* \param iv_len The desired length of the IV to be extracted in Bytes.
|
||||
* \param keys The address of the structure holding the generated
|
||||
* keys and IVs.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_make_traffic_keys(
|
||||
psa_algorithm_t hash_alg,
|
||||
const unsigned char *client_secret,
|
||||
const unsigned char *server_secret, size_t secret_len,
|
||||
size_t key_len, size_t iv_len,
|
||||
mbedtls_ssl_key_set *keys);
|
||||
|
||||
/**
|
||||
* \brief The \c Derive-Secret function from the TLS 1.3 standard RFC 8446.
|
||||
*
|
||||
* <tt>
|
||||
* Derive-Secret( Secret, Label, Messages ) =
|
||||
* HKDF-Expand-Label( Secret, Label,
|
||||
* Hash( Messages ),
|
||||
* Hash.Length ) )
|
||||
* </tt>
|
||||
*
|
||||
* \param hash_alg The identifier for the hash function used for the
|
||||
* applications of HKDF.
|
||||
* \param secret The \c Secret argument to the \c Derive-Secret function.
|
||||
* This must be a readable buffer of length
|
||||
* \p secret_len Bytes.
|
||||
* \param secret_len The length of \p secret in Bytes.
|
||||
* \param label The \c Label argument to the \c Derive-Secret function.
|
||||
* This must be a readable buffer of length
|
||||
* \p label_len Bytes.
|
||||
* \param label_len The length of \p label in Bytes.
|
||||
* \param ctx The hash of the \c Messages argument to the
|
||||
* \c Derive-Secret function, or the \c Messages argument
|
||||
* itself, depending on \p ctx_hashed.
|
||||
* \param ctx_len The length of \p ctx in Bytes.
|
||||
* \param ctx_hashed This indicates whether the \p ctx contains the hash of
|
||||
* the \c Messages argument in the application of the
|
||||
* \c Derive-Secret function
|
||||
* (value MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED), or whether
|
||||
* it is the content of \c Messages itself, in which case
|
||||
* the function takes care of the hashing
|
||||
* (value MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED).
|
||||
* \param dstbuf The target buffer to write the output of
|
||||
* \c Derive-Secret to. This must be a writable buffer of
|
||||
* size \p dtsbuf_len Bytes.
|
||||
* \param dstbuf_len The length of \p dstbuf in Bytes.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_derive_secret(
|
||||
psa_algorithm_t hash_alg,
|
||||
const unsigned char *secret, size_t secret_len,
|
||||
const unsigned char *label, size_t label_len,
|
||||
const unsigned char *ctx, size_t ctx_len,
|
||||
int ctx_hashed,
|
||||
unsigned char *dstbuf, size_t dstbuf_len);
|
||||
|
||||
/**
|
||||
* \brief Derive TLS 1.3 early data key material from early secret.
|
||||
*
|
||||
* This is a small wrapper invoking mbedtls_ssl_tls13_derive_secret()
|
||||
* with the appropriate labels.
|
||||
*
|
||||
* <tt>
|
||||
* Early Secret
|
||||
* |
|
||||
* +-----> Derive-Secret(., "c e traffic", ClientHello)
|
||||
* | = client_early_traffic_secret
|
||||
* |
|
||||
* +-----> Derive-Secret(., "e exp master", ClientHello)
|
||||
* . = early_exporter_master_secret
|
||||
* .
|
||||
* .
|
||||
* </tt>
|
||||
*
|
||||
* \note To obtain the actual key and IV for the early data traffic,
|
||||
* the client secret derived by this function need to be
|
||||
* further processed by mbedtls_ssl_tls13_make_traffic_keys().
|
||||
*
|
||||
* \note The binder key, which is also generated from the early secret,
|
||||
* is omitted here. Its calculation is part of the separate routine
|
||||
* mbedtls_ssl_tls13_create_psk_binder().
|
||||
*
|
||||
* \param hash_alg The hash algorithm associated with the PSK for which
|
||||
* early data key material is being derived.
|
||||
* \param early_secret The early secret from which the early data key material
|
||||
* should be derived. This must be a readable buffer whose
|
||||
* length is the digest size of the hash algorithm
|
||||
* represented by \p md_size.
|
||||
* \param transcript The transcript of the handshake so far, calculated with
|
||||
* respect to \p hash_alg. This must be a readable buffer
|
||||
* whose length is the digest size of the hash algorithm
|
||||
* represented by \p md_size.
|
||||
* \param derived The address of the structure in which to store
|
||||
* the early data key material.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_derive_early_secrets(
|
||||
psa_algorithm_t hash_alg,
|
||||
unsigned char const *early_secret,
|
||||
unsigned char const *transcript, size_t transcript_len,
|
||||
mbedtls_ssl_tls13_early_secrets *derived);
|
||||
|
||||
/**
|
||||
* \brief Derive TLS 1.3 handshake key material from the handshake secret.
|
||||
*
|
||||
* This is a small wrapper invoking mbedtls_ssl_tls13_derive_secret()
|
||||
* with the appropriate labels from the standard.
|
||||
*
|
||||
* <tt>
|
||||
* Handshake Secret
|
||||
* |
|
||||
* +-----> Derive-Secret( ., "c hs traffic",
|
||||
* | ClientHello...ServerHello )
|
||||
* | = client_handshake_traffic_secret
|
||||
* |
|
||||
* +-----> Derive-Secret( ., "s hs traffic",
|
||||
* . ClientHello...ServerHello )
|
||||
* . = server_handshake_traffic_secret
|
||||
* .
|
||||
* </tt>
|
||||
*
|
||||
* \note To obtain the actual key and IV for the encrypted handshake traffic,
|
||||
* the client and server secret derived by this function need to be
|
||||
* further processed by mbedtls_ssl_tls13_make_traffic_keys().
|
||||
*
|
||||
* \param hash_alg The hash algorithm associated with the ciphersuite
|
||||
* that's being used for the connection.
|
||||
* \param handshake_secret The handshake secret from which the handshake key
|
||||
* material should be derived. This must be a readable
|
||||
* buffer whose length is the digest size of the hash
|
||||
* algorithm represented by \p md_size.
|
||||
* \param transcript The transcript of the handshake so far, calculated
|
||||
* with respect to \p hash_alg. This must be a readable
|
||||
* buffer whose length is the digest size of the hash
|
||||
* algorithm represented by \p md_size.
|
||||
* \param derived The address of the structure in which to
|
||||
* store the handshake key material.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_derive_handshake_secrets(
|
||||
psa_algorithm_t hash_alg,
|
||||
unsigned char const *handshake_secret,
|
||||
unsigned char const *transcript, size_t transcript_len,
|
||||
mbedtls_ssl_tls13_handshake_secrets *derived);
|
||||
|
||||
/**
|
||||
* \brief Derive TLS 1.3 application key material from the master secret.
|
||||
*
|
||||
* This is a small wrapper invoking mbedtls_ssl_tls13_derive_secret()
|
||||
* with the appropriate labels from the standard.
|
||||
*
|
||||
* <tt>
|
||||
* Master Secret
|
||||
* |
|
||||
* +-----> Derive-Secret( ., "c ap traffic",
|
||||
* | ClientHello...server Finished )
|
||||
* | = client_application_traffic_secret_0
|
||||
* |
|
||||
* +-----> Derive-Secret( ., "s ap traffic",
|
||||
* | ClientHello...Server Finished )
|
||||
* | = server_application_traffic_secret_0
|
||||
* |
|
||||
* +-----> Derive-Secret( ., "exp master",
|
||||
* . ClientHello...server Finished)
|
||||
* . = exporter_master_secret
|
||||
* .
|
||||
* </tt>
|
||||
*
|
||||
* \note To obtain the actual key and IV for the (0-th) application traffic,
|
||||
* the client and server secret derived by this function need to be
|
||||
* further processed by mbedtls_ssl_tls13_make_traffic_keys().
|
||||
*
|
||||
* \param hash_alg The hash algorithm associated with the ciphersuite
|
||||
* that's being used for the connection.
|
||||
* \param master_secret The master secret from which the application key
|
||||
* material should be derived. This must be a readable
|
||||
* buffer whose length is the digest size of the hash
|
||||
* algorithm represented by \p md_size.
|
||||
* \param transcript The transcript of the handshake up to and including
|
||||
* the ServerFinished message, calculated with respect
|
||||
* to \p hash_alg. This must be a readable buffer whose
|
||||
* length is the digest size of the hash algorithm
|
||||
* represented by \p hash_alg.
|
||||
* \param derived The address of the structure in which to
|
||||
* store the application key material.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_derive_application_secrets(
|
||||
psa_algorithm_t hash_alg,
|
||||
unsigned char const *master_secret,
|
||||
unsigned char const *transcript, size_t transcript_len,
|
||||
mbedtls_ssl_tls13_application_secrets *derived);
|
||||
|
||||
/**
|
||||
* \brief Derive TLS 1.3 resumption master secret from the master secret.
|
||||
*
|
||||
* This is a small wrapper invoking mbedtls_ssl_tls13_derive_secret()
|
||||
* with the appropriate labels from the standard.
|
||||
*
|
||||
* \param hash_alg The hash algorithm used in the application for which
|
||||
* key material is being derived.
|
||||
* \param application_secret The application secret from which the resumption master
|
||||
* secret should be derived. This must be a readable
|
||||
* buffer whose length is the digest size of the hash
|
||||
* algorithm represented by \p md_size.
|
||||
* \param transcript The transcript of the handshake up to and including
|
||||
* the ClientFinished message, calculated with respect
|
||||
* to \p hash_alg. This must be a readable buffer whose
|
||||
* length is the digest size of the hash algorithm
|
||||
* represented by \p hash_alg.
|
||||
* \param transcript_len The length of \p transcript in Bytes.
|
||||
* \param derived The address of the structure in which to
|
||||
* store the resumption master secret.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_derive_resumption_master_secret(
|
||||
psa_algorithm_t hash_alg,
|
||||
unsigned char const *application_secret,
|
||||
unsigned char const *transcript, size_t transcript_len,
|
||||
mbedtls_ssl_tls13_application_secrets *derived);
|
||||
|
||||
/**
|
||||
* \brief Compute the next secret in the TLS 1.3 key schedule
|
||||
*
|
||||
* The TLS 1.3 key schedule proceeds as follows to compute
|
||||
* the three main secrets during the handshake: The early
|
||||
* secret for early data, the handshake secret for all
|
||||
* other encrypted handshake messages, and the master
|
||||
* secret for all application traffic.
|
||||
*
|
||||
* <tt>
|
||||
* 0
|
||||
* |
|
||||
* v
|
||||
* PSK -> HKDF-Extract = Early Secret
|
||||
* |
|
||||
* v
|
||||
* Derive-Secret( ., "derived", "" )
|
||||
* |
|
||||
* v
|
||||
* (EC)DHE -> HKDF-Extract = Handshake Secret
|
||||
* |
|
||||
* v
|
||||
* Derive-Secret( ., "derived", "" )
|
||||
* |
|
||||
* v
|
||||
* 0 -> HKDF-Extract = Master Secret
|
||||
* </tt>
|
||||
*
|
||||
* Each of the three secrets in turn is the basis for further
|
||||
* key derivations, such as the derivation of traffic keys and IVs;
|
||||
* see e.g. mbedtls_ssl_tls13_make_traffic_keys().
|
||||
*
|
||||
* This function implements one step in this evolution of secrets:
|
||||
*
|
||||
* <tt>
|
||||
* old_secret
|
||||
* |
|
||||
* v
|
||||
* Derive-Secret( ., "derived", "" )
|
||||
* |
|
||||
* v
|
||||
* input -> HKDF-Extract = new_secret
|
||||
* </tt>
|
||||
*
|
||||
* \param hash_alg The identifier for the hash function used for the
|
||||
* applications of HKDF.
|
||||
* \param secret_old The address of the buffer holding the old secret
|
||||
* on function entry. If not \c NULL, this must be a
|
||||
* readable buffer whose size matches the output size
|
||||
* of the hash function represented by \p hash_alg.
|
||||
* If \c NULL, an all \c 0 array will be used instead.
|
||||
* \param input The address of the buffer holding the additional
|
||||
* input for the key derivation (e.g., the PSK or the
|
||||
* ephemeral (EC)DH secret). If not \c NULL, this must be
|
||||
* a readable buffer whose size \p input_len Bytes.
|
||||
* If \c NULL, an all \c 0 array will be used instead.
|
||||
* \param input_len The length of \p input in Bytes.
|
||||
* \param secret_new The address of the buffer holding the new secret
|
||||
* on function exit. This must be a writable buffer
|
||||
* whose size matches the output size of the hash
|
||||
* function represented by \p hash_alg.
|
||||
* This may be the same as \p secret_old.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_evolve_secret(
|
||||
psa_algorithm_t hash_alg,
|
||||
const unsigned char *secret_old,
|
||||
const unsigned char *input, size_t input_len,
|
||||
unsigned char *secret_new);
|
||||
|
||||
/**
|
||||
* \brief Calculate a TLS 1.3 PSK binder.
|
||||
*
|
||||
* \param ssl The SSL context. This is used for debugging only and may
|
||||
* be \c NULL if MBEDTLS_DEBUG_C is disabled.
|
||||
* \param hash_alg The hash algorithm associated to the PSK \p psk.
|
||||
* \param psk The buffer holding the PSK for which to create a binder.
|
||||
* \param psk_len The size of \p psk in bytes.
|
||||
* \param psk_type This indicates whether the PSK \p psk is externally
|
||||
* provisioned (#MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL) or a
|
||||
* resumption PSK (#MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION).
|
||||
* \param transcript The handshake transcript up to the point where the
|
||||
* PSK binder calculation happens. This must be readable,
|
||||
* and its size must be equal to the digest size of
|
||||
* the hash algorithm represented by \p hash_alg.
|
||||
* \param result The address at which to store the PSK binder on success.
|
||||
* This must be writable, and its size must be equal to the
|
||||
* digest size of the hash algorithm represented by
|
||||
* \p hash_alg.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_create_psk_binder(mbedtls_ssl_context *ssl,
|
||||
const psa_algorithm_t hash_alg,
|
||||
unsigned char const *psk, size_t psk_len,
|
||||
int psk_type,
|
||||
unsigned char const *transcript,
|
||||
unsigned char *result);
|
||||
|
||||
/**
|
||||
* \bref Setup an SSL transform structure representing the
|
||||
* record protection mechanism used by TLS 1.3
|
||||
*
|
||||
* \param transform The SSL transform structure to be created. This must have
|
||||
* been initialized through mbedtls_ssl_transform_init() and
|
||||
* not used in any other way prior to calling this function.
|
||||
* In particular, this function does not clean up the
|
||||
* transform structure prior to installing the new keys.
|
||||
* \param endpoint Indicates whether the transform is for the client
|
||||
* (value #MBEDTLS_SSL_IS_CLIENT) or the server
|
||||
* (value #MBEDTLS_SSL_IS_SERVER).
|
||||
* \param ciphersuite The numerical identifier for the ciphersuite to use.
|
||||
* This must be one of the identifiers listed in
|
||||
* ssl_ciphersuites.h.
|
||||
* \param traffic_keys The key material to use. No reference is stored in
|
||||
* the SSL transform being generated, and the caller
|
||||
* should destroy the key material afterwards.
|
||||
* \param ssl (Debug-only) The SSL context to use for debug output
|
||||
* in case of failure. This parameter is only needed if
|
||||
* #MBEDTLS_DEBUG_C is set, and is ignored otherwise.
|
||||
*
|
||||
* \return \c 0 on success. In this case, \p transform is ready to
|
||||
* be used with mbedtls_ssl_transform_decrypt() and
|
||||
* mbedtls_ssl_transform_encrypt().
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_populate_transform(mbedtls_ssl_transform *transform,
|
||||
int endpoint,
|
||||
int ciphersuite,
|
||||
mbedtls_ssl_key_set const *traffic_keys,
|
||||
mbedtls_ssl_context *ssl);
|
||||
|
||||
/*
|
||||
* TLS 1.3 key schedule evolutions
|
||||
*
|
||||
* Early -> Handshake -> Application
|
||||
*
|
||||
* Small wrappers around mbedtls_ssl_tls13_evolve_secret().
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Begin TLS 1.3 key schedule by calculating early secret.
|
||||
*
|
||||
* The TLS 1.3 key schedule can be viewed as a simple state machine
|
||||
* with states Initial -> Early -> Handshake -> Application, and
|
||||
* this function represents the Initial -> Early transition.
|
||||
*
|
||||
* \param ssl The SSL context to operate on.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_key_schedule_stage_early(mbedtls_ssl_context *ssl);
|
||||
|
||||
/**
|
||||
* \brief Compute TLS 1.3 resumption master secret.
|
||||
*
|
||||
* \param ssl The SSL context to operate on. This must be in
|
||||
* key schedule stage \c Application, see
|
||||
* mbedtls_ssl_tls13_key_schedule_stage_application().
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_compute_resumption_master_secret(mbedtls_ssl_context *ssl);
|
||||
|
||||
/**
|
||||
* \brief Calculate the verify_data value for the client or server TLS 1.3
|
||||
* Finished message.
|
||||
*
|
||||
* \param ssl The SSL context to operate on. This must be in
|
||||
* key schedule stage \c Handshake, see
|
||||
* mbedtls_ssl_tls13_key_schedule_stage_application().
|
||||
* \param dst The address at which to write the verify_data value.
|
||||
* \param dst_len The size of \p dst in bytes.
|
||||
* \param actual_len The address at which to store the amount of data
|
||||
* actually written to \p dst upon success.
|
||||
* \param which The message to calculate the `verify_data` for:
|
||||
* - #MBEDTLS_SSL_IS_CLIENT for the Client's Finished message
|
||||
* - #MBEDTLS_SSL_IS_SERVER for the Server's Finished message
|
||||
*
|
||||
* \note Both client and server call this function twice, once to
|
||||
* generate their own Finished message, and once to verify the
|
||||
* peer's Finished message.
|
||||
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_calculate_verify_data(mbedtls_ssl_context *ssl,
|
||||
unsigned char *dst,
|
||||
size_t dst_len,
|
||||
size_t *actual_len,
|
||||
int which);
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
/**
|
||||
* \brief Compute TLS 1.3 early transform
|
||||
*
|
||||
* \param ssl The SSL context to operate on.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*
|
||||
* \warning The function does not compute the early master secret. Call
|
||||
* mbedtls_ssl_tls13_key_schedule_stage_early() before to
|
||||
* call this function to generate the early master secret.
|
||||
* \note For a client/server endpoint, the function computes only the
|
||||
* encryption/decryption part of the transform as the decryption/
|
||||
* encryption part is not defined by the specification (no early
|
||||
* traffic from the server to the client).
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_compute_early_transform(mbedtls_ssl_context *ssl);
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
/**
|
||||
* \brief Compute TLS 1.3 handshake transform
|
||||
*
|
||||
* \param ssl The SSL context to operate on. The early secret must have been
|
||||
* computed.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_compute_handshake_transform(mbedtls_ssl_context *ssl);
|
||||
|
||||
/**
|
||||
* \brief Compute TLS 1.3 application transform
|
||||
*
|
||||
* \param ssl The SSL context to operate on. The early secret must have been
|
||||
* computed.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_compute_application_transform(mbedtls_ssl_context *ssl);
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
/**
|
||||
* \brief Export TLS 1.3 PSK from handshake context
|
||||
*
|
||||
* \param[in] ssl The SSL context to operate on.
|
||||
* \param[out] psk PSK output pointer.
|
||||
* \param[out] psk_len Length of PSK.
|
||||
*
|
||||
* \returns \c 0 if there is a configured PSK and it was exported
|
||||
* successfully.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl,
|
||||
unsigned char **psk,
|
||||
size_t *psk_len);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Calculate TLS-Exporter function as defined in RFC 8446, Section 7.5.
|
||||
*
|
||||
* \param[in] hash_alg The hash algorithm.
|
||||
* \param[in] secret The secret to use. (Should be the exporter master secret.)
|
||||
* \param[in] secret_len Length of secret.
|
||||
* \param[in] label The label of the exported key.
|
||||
* \param[in] label_len The length of label.
|
||||
* \param[out] out The output buffer for the exported key. Must have room for at least out_len bytes.
|
||||
* \param[in] out_len Length of the key to generate.
|
||||
*/
|
||||
int mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg,
|
||||
const unsigned char *secret, const size_t secret_len,
|
||||
const unsigned char *label, const size_t label_len,
|
||||
const unsigned char *context_value, const size_t context_len,
|
||||
uint8_t *out, const size_t out_len);
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */
|
||||
+3589
File diff suppressed because it is too large
Load Diff
Vendored
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Portable interface to the CPU cycle counter
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_TIMING_C)
|
||||
|
||||
#include "mbedtls/timing.h"
|
||||
|
||||
#if !defined(MBEDTLS_TIMING_ALT)
|
||||
|
||||
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
|
||||
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
|
||||
!defined(__HAIKU__) && !defined(__midipix__)
|
||||
#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in mbedtls_config.h"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
struct _hr_time {
|
||||
LARGE_INTEGER start;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
/* time.h should be included independently of MBEDTLS_HAVE_TIME. If the
|
||||
* platform matches the ifdefs above, it will be used. */
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
struct _hr_time {
|
||||
struct timeval start;
|
||||
};
|
||||
#endif /* _WIN32 && !EFIX64 && !EFI32 */
|
||||
|
||||
/**
|
||||
* \brief Return the elapsed time in milliseconds
|
||||
*
|
||||
* \warning May change without notice
|
||||
*
|
||||
* \param val points to a timer structure
|
||||
* \param reset If 0, query the elapsed time. Otherwise (re)start the timer.
|
||||
*
|
||||
* \return Elapsed time since the previous reset in ms. When
|
||||
* restarting, this is always 0.
|
||||
*
|
||||
* \note To initialize a timer, call this function with reset=1.
|
||||
*
|
||||
* Determining the elapsed time and resetting the timer is not
|
||||
* atomic on all platforms, so after the sequence
|
||||
* `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 =
|
||||
* get_timer(0) }` the value time1+time2 is only approximately
|
||||
* the delay since the first reset.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
|
||||
|
||||
unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset)
|
||||
{
|
||||
struct _hr_time *t = (struct _hr_time *) val;
|
||||
|
||||
if (reset) {
|
||||
QueryPerformanceCounter(&t->start);
|
||||
return 0;
|
||||
} else {
|
||||
unsigned long delta;
|
||||
LARGE_INTEGER now, hfreq;
|
||||
QueryPerformanceCounter(&now);
|
||||
QueryPerformanceFrequency(&hfreq);
|
||||
delta = (unsigned long) ((now.QuadPart - t->start.QuadPart) * 1000ul
|
||||
/ hfreq.QuadPart);
|
||||
return delta;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* _WIN32 && !EFIX64 && !EFI32 */
|
||||
|
||||
unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset)
|
||||
{
|
||||
struct _hr_time *t = (struct _hr_time *) val;
|
||||
|
||||
if (reset) {
|
||||
gettimeofday(&t->start, NULL);
|
||||
return 0;
|
||||
} else {
|
||||
unsigned long delta;
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
delta = (now.tv_sec - t->start.tv_sec) * 1000ul
|
||||
+ (now.tv_usec - t->start.tv_usec) / 1000;
|
||||
return delta;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _WIN32 && !EFIX64 && !EFI32 */
|
||||
|
||||
/*
|
||||
* Set delays to watch
|
||||
*/
|
||||
void mbedtls_timing_set_delay(void *data, uint32_t int_ms, uint32_t fin_ms)
|
||||
{
|
||||
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
|
||||
|
||||
ctx->int_ms = int_ms;
|
||||
ctx->fin_ms = fin_ms;
|
||||
|
||||
if (fin_ms != 0) {
|
||||
(void) mbedtls_timing_get_timer(&ctx->timer, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get number of delays expired
|
||||
*/
|
||||
int mbedtls_timing_get_delay(void *data)
|
||||
{
|
||||
mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
|
||||
unsigned long elapsed_ms;
|
||||
|
||||
if (ctx->fin_ms == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
elapsed_ms = mbedtls_timing_get_timer(&ctx->timer, 0);
|
||||
|
||||
if (elapsed_ms >= ctx->fin_ms) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (elapsed_ms >= ctx->int_ms) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the final delay.
|
||||
*/
|
||||
uint32_t mbedtls_timing_get_final_delay(
|
||||
const mbedtls_timing_delay_context *data)
|
||||
{
|
||||
return data->fin_ms;
|
||||
}
|
||||
#endif /* !MBEDTLS_TIMING_ALT */
|
||||
#endif /* MBEDTLS_TIMING_C */
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Version information
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "ssl_misc.h"
|
||||
|
||||
#if defined(MBEDTLS_VERSION_C)
|
||||
|
||||
#include "mbedtls/version.h"
|
||||
#include <string.h>
|
||||
|
||||
unsigned int mbedtls_version_get_number(void)
|
||||
{
|
||||
return MBEDTLS_VERSION_NUMBER;
|
||||
}
|
||||
|
||||
const char *mbedtls_version_get_string(void)
|
||||
{
|
||||
return MBEDTLS_VERSION_STRING;
|
||||
}
|
||||
|
||||
const char *mbedtls_version_get_string_full(void)
|
||||
{
|
||||
return MBEDTLS_VERSION_STRING_FULL;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_VERSION_C */
|
||||
Vendored
+1831
File diff suppressed because it is too large
Load Diff
+744
@@ -0,0 +1,744 @@
|
||||
/*
|
||||
* X.509 base functions for creating certificates / CSRs
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "x509_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_X509_CREATE_C)
|
||||
|
||||
#include "mbedtls/asn1write.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "x509_oid.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "mbedtls/asn1.h"
|
||||
|
||||
/* Structure linking OIDs for X.509 DN AttributeTypes to their
|
||||
* string representations and default string encodings used by Mbed TLS. */
|
||||
typedef struct {
|
||||
const char *name; /* String representation of AttributeType, e.g.
|
||||
* "CN" or "emailAddress". */
|
||||
size_t name_len; /* Length of 'name', without trailing 0 byte. */
|
||||
const char *oid; /* String representation of OID of AttributeType,
|
||||
* as per RFC 5280, Appendix A.1. encoded as per
|
||||
* X.690 */
|
||||
int default_tag; /* The default character encoding used for the
|
||||
* given attribute type, e.g.
|
||||
* MBEDTLS_ASN1_UTF8_STRING for UTF-8. */
|
||||
} x509_attr_descriptor_t;
|
||||
|
||||
#define ADD_STRLEN(s) s, sizeof(s) - 1
|
||||
|
||||
/* X.509 DN attributes from RFC 5280, Appendix A.1. */
|
||||
static const x509_attr_descriptor_t x509_attrs[] =
|
||||
{
|
||||
{ ADD_STRLEN("CN"),
|
||||
MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("commonName"),
|
||||
MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("C"),
|
||||
MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING },
|
||||
{ ADD_STRLEN("countryName"),
|
||||
MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING },
|
||||
{ ADD_STRLEN("O"),
|
||||
MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("organizationName"),
|
||||
MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("L"),
|
||||
MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("locality"),
|
||||
MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("R"),
|
||||
MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING },
|
||||
{ ADD_STRLEN("OU"),
|
||||
MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("organizationalUnitName"),
|
||||
MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("ST"),
|
||||
MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("stateOrProvinceName"),
|
||||
MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("emailAddress"),
|
||||
MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING },
|
||||
{ ADD_STRLEN("serialNumber"),
|
||||
MBEDTLS_OID_AT_SERIAL_NUMBER, MBEDTLS_ASN1_PRINTABLE_STRING },
|
||||
{ ADD_STRLEN("postalAddress"),
|
||||
MBEDTLS_OID_AT_POSTAL_ADDRESS, MBEDTLS_ASN1_PRINTABLE_STRING },
|
||||
{ ADD_STRLEN("postalCode"),
|
||||
MBEDTLS_OID_AT_POSTAL_CODE, MBEDTLS_ASN1_PRINTABLE_STRING },
|
||||
{ ADD_STRLEN("dnQualifier"),
|
||||
MBEDTLS_OID_AT_DN_QUALIFIER, MBEDTLS_ASN1_PRINTABLE_STRING },
|
||||
{ ADD_STRLEN("title"),
|
||||
MBEDTLS_OID_AT_TITLE, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("surName"),
|
||||
MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("SN"),
|
||||
MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("givenName"),
|
||||
MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("GN"),
|
||||
MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("initials"),
|
||||
MBEDTLS_OID_AT_INITIALS, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("pseudonym"),
|
||||
MBEDTLS_OID_AT_PSEUDONYM, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("generationQualifier"),
|
||||
MBEDTLS_OID_AT_GENERATION_QUALIFIER, MBEDTLS_ASN1_UTF8_STRING },
|
||||
{ ADD_STRLEN("domainComponent"),
|
||||
MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING },
|
||||
{ ADD_STRLEN("DC"),
|
||||
MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING },
|
||||
{ NULL, 0, NULL, MBEDTLS_ASN1_NULL }
|
||||
};
|
||||
|
||||
static const x509_attr_descriptor_t *x509_attr_descr_from_name(const char *name, size_t name_len)
|
||||
{
|
||||
const x509_attr_descriptor_t *cur;
|
||||
|
||||
for (cur = x509_attrs; cur->name != NULL; cur++) {
|
||||
if (cur->name_len == name_len &&
|
||||
strncmp(cur->name, name, name_len) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cur->name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
static int hex_to_int(char c)
|
||||
{
|
||||
return ('0' <= c && c <= '9') ? (c - '0') :
|
||||
('a' <= c && c <= 'f') ? (c - 'a' + 10) :
|
||||
('A' <= c && c <= 'F') ? (c - 'A' + 10) : -1;
|
||||
}
|
||||
|
||||
static int hexpair_to_int(const char *hexpair)
|
||||
{
|
||||
int n1 = hex_to_int(*hexpair);
|
||||
int n2 = hex_to_int(*(hexpair + 1));
|
||||
|
||||
if (n1 != -1 && n2 != -1) {
|
||||
return (n1 << 4) | n2;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_attribute_value_string(const char *s,
|
||||
int len,
|
||||
unsigned char *data,
|
||||
size_t *data_len)
|
||||
{
|
||||
const char *c;
|
||||
const char *end = s + len;
|
||||
unsigned char *d = data;
|
||||
int n;
|
||||
|
||||
for (c = s; c < end; c++) {
|
||||
if (*c == '\\') {
|
||||
c++;
|
||||
|
||||
/* Check for valid escaped characters as per RFC 4514 Section 3 */
|
||||
if (c + 1 < end && (n = hexpair_to_int(c)) != -1) {
|
||||
if (n == 0) {
|
||||
return MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
}
|
||||
*(d++) = n;
|
||||
c++;
|
||||
} else if (c < end && strchr(" ,=+<>#;\"\\", *c)) {
|
||||
*(d++) = *c;
|
||||
} else {
|
||||
return MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
}
|
||||
} else {
|
||||
*(d++) = *c;
|
||||
}
|
||||
|
||||
if (d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE) {
|
||||
return MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
}
|
||||
}
|
||||
*data_len = (size_t) (d - data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Parse a hexstring containing a DER-encoded string.
|
||||
*
|
||||
* \param s A string of \p len bytes hexadecimal digits.
|
||||
* \param len Number of bytes to read from \p s.
|
||||
* \param data Output buffer of size \p data_size.
|
||||
* On success, it contains the payload that's DER-encoded
|
||||
* in the input (content without the tag and length).
|
||||
* If the DER tag is a string tag, the payload is guaranteed
|
||||
* not to contain null bytes.
|
||||
* \param data_size Length of the \p data buffer.
|
||||
* \param data_len On success, the length of the parsed string.
|
||||
* It is guaranteed to be less than
|
||||
* #MBEDTLS_X509_MAX_DN_NAME_SIZE.
|
||||
* \param tag The ASN.1 tag that the payload in \p data is encoded in.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval #MBEDTLS_ERR_X509_INVALID_NAME if \p s does not contain
|
||||
* a valid hexstring,
|
||||
* or if the decoded hexstring is not valid DER,
|
||||
* or if the payload does not fit in \p data,
|
||||
* or if the payload is more than
|
||||
* #MBEDTLS_X509_MAX_DN_NAME_SIZE bytes,
|
||||
* of if \p *tag is an ASN.1 string tag and the payload
|
||||
* contains a null byte.
|
||||
* \retval #MBEDTLS_ERR_X509_ALLOC_FAILED on low memory.
|
||||
*/
|
||||
static int parse_attribute_value_hex_der_encoded(const char *s,
|
||||
size_t len,
|
||||
unsigned char *data,
|
||||
size_t data_size,
|
||||
size_t *data_len,
|
||||
int *tag)
|
||||
{
|
||||
/* Step 1: preliminary length checks. */
|
||||
/* Each byte is encoded by exactly two hexadecimal digits. */
|
||||
if (len % 2 != 0) {
|
||||
/* Odd number of hex digits */
|
||||
return MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
}
|
||||
size_t const der_length = len / 2;
|
||||
if (der_length > MBEDTLS_X509_MAX_DN_NAME_SIZE + 4) {
|
||||
/* The payload would be more than MBEDTLS_X509_MAX_DN_NAME_SIZE
|
||||
* (after subtracting the ASN.1 tag and length). Reject this early
|
||||
* to avoid allocating a large intermediate buffer. */
|
||||
return MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
}
|
||||
if (der_length < 1) {
|
||||
/* Avoid empty-buffer shenanigans. A valid DER encoding is never
|
||||
* empty. */
|
||||
return MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
}
|
||||
|
||||
/* Step 2: Decode the hex string into an intermediate buffer. */
|
||||
unsigned char *der = mbedtls_calloc(1, der_length);
|
||||
if (der == NULL) {
|
||||
return MBEDTLS_ERR_X509_ALLOC_FAILED;
|
||||
}
|
||||
/* Beyond this point, der needs to be freed on exit. */
|
||||
for (size_t i = 0; i < der_length; i++) {
|
||||
int c = hexpair_to_int(s + 2 * i);
|
||||
if (c < 0) {
|
||||
goto error;
|
||||
}
|
||||
der[i] = c;
|
||||
}
|
||||
|
||||
/* Step 3: decode the DER. */
|
||||
/* We've checked that der_length >= 1 above. */
|
||||
*tag = der[0];
|
||||
{
|
||||
unsigned char *p = der + 1;
|
||||
if (mbedtls_asn1_get_len(&p, der + der_length, data_len) != 0) {
|
||||
goto error;
|
||||
}
|
||||
/* Now p points to the first byte of the payload inside der,
|
||||
* and *data_len is the length of the payload. */
|
||||
|
||||
/* Step 4: payload validation */
|
||||
if (*data_len > MBEDTLS_X509_MAX_DN_NAME_SIZE) {
|
||||
goto error;
|
||||
}
|
||||
/* Strings must not contain null bytes. */
|
||||
if (MBEDTLS_ASN1_IS_STRING_TAG(*tag)) {
|
||||
for (size_t i = 0; i < *data_len; i++) {
|
||||
if (p[i] == 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 5: output the payload. */
|
||||
if (*data_len > data_size) {
|
||||
goto error;
|
||||
}
|
||||
memcpy(data, p, *data_len);
|
||||
}
|
||||
mbedtls_free(der);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
mbedtls_free(der);
|
||||
return MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
}
|
||||
|
||||
static int oid_parse_number(unsigned int *num, const char **p, const char *bound)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
|
||||
*num = 0;
|
||||
|
||||
while (*p < bound && **p >= '0' && **p <= '9') {
|
||||
ret = 0;
|
||||
if (*num > (UINT_MAX / 10)) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
*num *= 10;
|
||||
*num += **p - '0';
|
||||
(*p)++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static size_t oid_subidentifier_num_bytes(unsigned int value)
|
||||
{
|
||||
size_t num_bytes = 0;
|
||||
|
||||
do {
|
||||
value >>= 7;
|
||||
num_bytes++;
|
||||
} while (value != 0);
|
||||
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
static int oid_subidentifier_encode_into(unsigned char **p,
|
||||
unsigned char *bound,
|
||||
unsigned int value)
|
||||
{
|
||||
size_t num_bytes = oid_subidentifier_num_bytes(value);
|
||||
|
||||
if ((size_t) (bound - *p) < num_bytes) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
(*p)[num_bytes - 1] = (unsigned char) (value & 0x7f);
|
||||
value >>= 7;
|
||||
|
||||
for (size_t i = 2; i <= num_bytes; i++) {
|
||||
(*p)[num_bytes - i] = 0x80 | (unsigned char) (value & 0x7f);
|
||||
value >>= 7;
|
||||
}
|
||||
*p += num_bytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the OID for the given x.y.z.... style numeric string */
|
||||
int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid,
|
||||
const char *oid_str, size_t size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
const char *str_ptr = oid_str;
|
||||
const char *str_bound = oid_str + size;
|
||||
unsigned int val = 0;
|
||||
unsigned int component1, component2;
|
||||
size_t encoded_len;
|
||||
unsigned char *resized_mem;
|
||||
|
||||
/* Count the number of dots to get a worst-case allocation size. */
|
||||
size_t num_dots = 0;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (oid_str[i] == '.') {
|
||||
num_dots++;
|
||||
}
|
||||
}
|
||||
/* Allocate maximum possible required memory:
|
||||
* There are (num_dots + 1) integer components, but the first 2 share the
|
||||
* same subidentifier, so we only need num_dots subidentifiers maximum. */
|
||||
if (num_dots == 0 || (num_dots > MBEDTLS_OID_MAX_COMPONENTS - 1)) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
/* Each byte can store 7 bits, calculate number of bytes for a
|
||||
* subidentifier:
|
||||
*
|
||||
* bytes = ceil(subidentifer_size * 8 / 7)
|
||||
*/
|
||||
size_t bytes_per_subidentifier = (((sizeof(unsigned int) * 8) - 1) / 7)
|
||||
+ 1;
|
||||
size_t max_possible_bytes = num_dots * bytes_per_subidentifier;
|
||||
oid->p = mbedtls_calloc(max_possible_bytes, 1);
|
||||
if (oid->p == NULL) {
|
||||
return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
|
||||
}
|
||||
unsigned char *out_ptr = oid->p;
|
||||
unsigned char *out_bound = oid->p + max_possible_bytes;
|
||||
|
||||
ret = oid_parse_number(&component1, &str_ptr, str_bound);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
if (component1 > 2) {
|
||||
/* First component can't be > 2 */
|
||||
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
goto error;
|
||||
}
|
||||
if (str_ptr >= str_bound || *str_ptr != '.') {
|
||||
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
goto error;
|
||||
}
|
||||
str_ptr++;
|
||||
|
||||
ret = oid_parse_number(&component2, &str_ptr, str_bound);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
if ((component1 < 2) && (component2 > 39)) {
|
||||
/* Root nodes 0 and 1 may have up to 40 children, numbered 0-39 */
|
||||
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
goto error;
|
||||
}
|
||||
if (str_ptr < str_bound) {
|
||||
if (*str_ptr == '.') {
|
||||
str_ptr++;
|
||||
} else {
|
||||
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (component2 > (UINT_MAX - (component1 * 40))) {
|
||||
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
goto error;
|
||||
}
|
||||
ret = oid_subidentifier_encode_into(&out_ptr, out_bound,
|
||||
(component1 * 40) + component2);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
while (str_ptr < str_bound) {
|
||||
ret = oid_parse_number(&val, &str_ptr, str_bound);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
if (str_ptr < str_bound) {
|
||||
if (*str_ptr == '.') {
|
||||
str_ptr++;
|
||||
} else {
|
||||
ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
ret = oid_subidentifier_encode_into(&out_ptr, out_bound, val);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
encoded_len = (size_t) (out_ptr - oid->p);
|
||||
resized_mem = mbedtls_calloc(encoded_len, 1);
|
||||
if (resized_mem == NULL) {
|
||||
ret = MBEDTLS_ERR_ASN1_ALLOC_FAILED;
|
||||
goto error;
|
||||
}
|
||||
memcpy(resized_mem, oid->p, encoded_len);
|
||||
mbedtls_free(oid->p);
|
||||
oid->p = resized_mem;
|
||||
oid->len = encoded_len;
|
||||
|
||||
oid->tag = MBEDTLS_ASN1_OID;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
mbedtls_free(oid->p);
|
||||
oid->p = NULL;
|
||||
oid->len = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
int parse_ret = 0;
|
||||
const char *s = name, *c = s;
|
||||
const char *end = s + strlen(s);
|
||||
mbedtls_asn1_buf oid = { .p = NULL, .len = 0, .tag = MBEDTLS_ASN1_NULL };
|
||||
const x509_attr_descriptor_t *attr_descr = NULL;
|
||||
int in_attr_type = 1;
|
||||
int tag;
|
||||
int numericoid = 0;
|
||||
unsigned char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
|
||||
size_t data_len = 0;
|
||||
|
||||
/* Ensure the output parameter is not already populated.
|
||||
* (If it were, overwriting it would likely cause a memory leak.)
|
||||
*/
|
||||
if (*head != NULL) {
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
while (c <= end) {
|
||||
if (in_attr_type && *c == '=') {
|
||||
if ((attr_descr = x509_attr_descr_from_name(s, (size_t) (c - s))) == NULL) {
|
||||
if ((mbedtls_oid_from_numeric_string(&oid, s, (size_t) (c - s))) != 0) {
|
||||
return MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
} else {
|
||||
numericoid = 1;
|
||||
}
|
||||
} else {
|
||||
oid.len = strlen(attr_descr->oid);
|
||||
oid.p = mbedtls_calloc(1, oid.len);
|
||||
memcpy(oid.p, attr_descr->oid, oid.len);
|
||||
numericoid = 0;
|
||||
}
|
||||
|
||||
s = c + 1;
|
||||
in_attr_type = 0;
|
||||
}
|
||||
|
||||
if (!in_attr_type && ((*c == ',' && *(c-1) != '\\') || c == end)) {
|
||||
if (s == c) {
|
||||
mbedtls_free(oid.p);
|
||||
return MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
} else if (*s == '#') {
|
||||
/* We know that c >= s (loop invariant) and c != s (in this
|
||||
* else branch), hence c - s - 1 >= 0. */
|
||||
parse_ret = parse_attribute_value_hex_der_encoded(
|
||||
s + 1, (size_t) (c - s) - 1,
|
||||
data, sizeof(data), &data_len, &tag);
|
||||
if (parse_ret != 0) {
|
||||
mbedtls_free(oid.p);
|
||||
return parse_ret;
|
||||
}
|
||||
} else {
|
||||
if (numericoid) {
|
||||
mbedtls_free(oid.p);
|
||||
return MBEDTLS_ERR_X509_INVALID_NAME;
|
||||
} else {
|
||||
if ((parse_ret =
|
||||
parse_attribute_value_string(s, (int) (c - s), data,
|
||||
&data_len)) != 0) {
|
||||
mbedtls_free(oid.p);
|
||||
return parse_ret;
|
||||
}
|
||||
tag = attr_descr->default_tag;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_asn1_named_data *cur =
|
||||
mbedtls_asn1_store_named_data(head, (char *) oid.p, oid.len,
|
||||
(unsigned char *) data,
|
||||
data_len);
|
||||
mbedtls_free(oid.p);
|
||||
oid.p = NULL;
|
||||
if (cur == NULL) {
|
||||
return MBEDTLS_ERR_X509_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
// set tagType
|
||||
cur->val.tag = tag;
|
||||
|
||||
while (c < end && *(c + 1) == ' ') {
|
||||
c++;
|
||||
}
|
||||
|
||||
s = c + 1;
|
||||
in_attr_type = 1;
|
||||
|
||||
/* Successfully parsed one name, update ret to success */
|
||||
ret = 0;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
if (oid.p != NULL) {
|
||||
mbedtls_free(oid.p);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The first byte of the value in the mbedtls_asn1_named_data structure is reserved
|
||||
* to store the critical boolean for us
|
||||
*/
|
||||
int mbedtls_x509_set_extension(mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
|
||||
int critical, const unsigned char *val, size_t val_len)
|
||||
{
|
||||
mbedtls_asn1_named_data *cur;
|
||||
|
||||
if (val_len > (SIZE_MAX - 1)) {
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((cur = mbedtls_asn1_store_named_data(head, oid, oid_len,
|
||||
NULL, val_len + 1)) == NULL) {
|
||||
return MBEDTLS_ERR_X509_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
cur->val.p[0] = critical;
|
||||
memcpy(cur->val.p + 1, val, val_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* RelativeDistinguishedName ::=
|
||||
* SET OF AttributeTypeAndValue
|
||||
*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* value AttributeValue }
|
||||
*
|
||||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* AttributeValue ::= ANY DEFINED BY AttributeType
|
||||
*/
|
||||
static int x509_write_name(unsigned char **p,
|
||||
unsigned char *start,
|
||||
mbedtls_asn1_named_data *cur_name)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
const char *oid = (const char *) cur_name->oid.p;
|
||||
size_t oid_len = cur_name->oid.len;
|
||||
const unsigned char *name = cur_name->val.p;
|
||||
size_t name_len = cur_name->val.len;
|
||||
|
||||
// Write correct string tag and value
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tagged_string(p, start,
|
||||
cur_name->val.tag,
|
||||
(const char *) name,
|
||||
name_len));
|
||||
// Write OID
|
||||
//
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid,
|
||||
oid_len));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SET));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
int mbedtls_x509_write_names(unsigned char **p, unsigned char *start,
|
||||
mbedtls_asn1_named_data *first)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
mbedtls_asn1_named_data *cur = first;
|
||||
|
||||
while (cur != NULL) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, x509_write_name(p, start, cur));
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
unsigned char *sig, size_t size,
|
||||
mbedtls_pk_sigalg_t pk_alg)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int write_null_par;
|
||||
size_t len = 0;
|
||||
|
||||
if (*p < start || (size_t) (*p - start) < size) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
len = size;
|
||||
(*p) -= len;
|
||||
memcpy(*p, sig, len);
|
||||
|
||||
if (*p - start < 1) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
*--(*p) = 0;
|
||||
len += 1;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_BIT_STRING));
|
||||
|
||||
// Write OID
|
||||
//
|
||||
if (pk_alg == MBEDTLS_PK_SIGALG_ECDSA) {
|
||||
/*
|
||||
* The AlgorithmIdentifier's parameters field must be absent for DSA/ECDSA signature
|
||||
* algorithms, see https://www.rfc-editor.org/rfc/rfc5480#page-17 and
|
||||
* https://www.rfc-editor.org/rfc/rfc5758#section-3.
|
||||
*/
|
||||
write_null_par = 0;
|
||||
} else {
|
||||
write_null_par = 1;
|
||||
}
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_algorithm_identifier_ext(p, start, oid, oid_len,
|
||||
0, write_null_par));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
static int x509_write_extension(unsigned char **p, unsigned char *start,
|
||||
mbedtls_asn1_named_data *ext)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, ext->val.p + 1,
|
||||
ext->val.len - 1));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, ext->val.len - 1));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_OCTET_STRING));
|
||||
|
||||
if (ext->val.p[0] != 0) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_bool(p, start, 1));
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, ext->oid.p,
|
||||
ext->oid.len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, ext->oid.len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_OID));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extension ::= SEQUENCE {
|
||||
* extnID OBJECT IDENTIFIER,
|
||||
* critical BOOLEAN DEFAULT FALSE,
|
||||
* extnValue OCTET STRING
|
||||
* -- contains the DER encoding of an ASN.1 value
|
||||
* -- corresponding to the extension type identified
|
||||
* -- by extnID
|
||||
* }
|
||||
*/
|
||||
int mbedtls_x509_write_extensions(unsigned char **p, unsigned char *start,
|
||||
mbedtls_asn1_named_data *first)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
mbedtls_asn1_named_data *cur_ext = first;
|
||||
|
||||
while (cur_ext != NULL) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, x509_write_extension(p, start, cur_ext));
|
||||
cur_ext = cur_ext->next;
|
||||
}
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_X509_CREATE_C */
|
||||
+701
@@ -0,0 +1,701 @@
|
||||
/*
|
||||
* X.509 Certificate Revocation List (CRL) parsing
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
/*
|
||||
* The ITU-T X.509 standard defines a certificate format for PKI.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
|
||||
* http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
|
||||
* http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
|
||||
*
|
||||
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
|
||||
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
|
||||
*/
|
||||
|
||||
#include "x509_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_X509_CRL_PARSE_C)
|
||||
|
||||
#include "mbedtls/x509_crl.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
#include "mbedtls/pem.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER { v1(0), v2(1) }
|
||||
*/
|
||||
static int x509_crl_get_version(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *ver)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) {
|
||||
if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
||||
*ver = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* X.509 CRL v2 extensions
|
||||
*
|
||||
* We currently don't parse any extension's content, but we do check that the
|
||||
* list of extensions is well-formed and abort on critical extensions (that
|
||||
* are unsupported as we don't support any extension so far)
|
||||
*/
|
||||
static int x509_get_crl_ext(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_x509_buf *ext)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (*p == end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* crlExtensions [0] EXPLICIT Extensions OPTIONAL
|
||||
* -- if present, version MUST be v2
|
||||
*/
|
||||
if ((ret = mbedtls_x509_get_ext(p, end, ext, 0)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
end = ext->p + ext->len;
|
||||
|
||||
while (*p < end) {
|
||||
/*
|
||||
* Extension ::= SEQUENCE {
|
||||
* extnID OBJECT IDENTIFIER,
|
||||
* critical BOOLEAN DEFAULT FALSE,
|
||||
* extnValue OCTET STRING }
|
||||
*/
|
||||
int is_critical = 0;
|
||||
const unsigned char *end_ext_data;
|
||||
size_t len;
|
||||
|
||||
/* Get enclosing sequence tag */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
end_ext_data = *p + len;
|
||||
|
||||
/* Get OID (currently ignored) */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
|
||||
MBEDTLS_ASN1_OID)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
*p += len;
|
||||
|
||||
/* Get optional critical */
|
||||
if ((ret = mbedtls_asn1_get_bool(p, end_ext_data,
|
||||
&is_critical)) != 0 &&
|
||||
(ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
/* Data should be octet string type */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
|
||||
MBEDTLS_ASN1_OCTET_STRING)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
/* Ignore data so far and just check its length */
|
||||
*p += len;
|
||||
if (*p != end_ext_data) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
/* Abort on (unsupported) critical extensions */
|
||||
if (is_critical) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
if (*p != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* X.509 CRL v2 entry extensions (no extensions parsed yet.)
|
||||
*/
|
||||
static int x509_get_crl_entry_ext(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_x509_buf *ext)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
/* OPTIONAL */
|
||||
if (end <= *p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ext->tag = **p;
|
||||
ext->p = *p;
|
||||
|
||||
/*
|
||||
* Get CRL-entry extension sequence header
|
||||
* crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
|
||||
*/
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &ext->len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
||||
ext->p = NULL;
|
||||
return 0;
|
||||
}
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
end = *p + ext->len;
|
||||
|
||||
if (end != *p + ext->len) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
while (*p < end) {
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
*p += len;
|
||||
}
|
||||
|
||||
if (*p != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* X.509 CRL Entries
|
||||
*/
|
||||
static int x509_get_entries(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_x509_crl_entry *entry)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t entry_len;
|
||||
mbedtls_x509_crl_entry *cur_entry = entry;
|
||||
|
||||
if (*p == end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &entry_len,
|
||||
MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED)) != 0) {
|
||||
if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
end = *p + entry_len;
|
||||
|
||||
while (*p < end) {
|
||||
size_t len2;
|
||||
const unsigned char *end2;
|
||||
|
||||
cur_entry->raw.tag = **p;
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len2,
|
||||
MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
cur_entry->raw.p = *p;
|
||||
cur_entry->raw.len = len2;
|
||||
end2 = *p + len2;
|
||||
|
||||
if ((ret = mbedtls_x509_get_serial(p, end2, &cur_entry->serial)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_x509_get_time(p, end2,
|
||||
&cur_entry->revocation_date)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = x509_get_crl_entry_ext(p, end2,
|
||||
&cur_entry->entry_ext)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (*p < end) {
|
||||
cur_entry->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl_entry));
|
||||
|
||||
if (cur_entry->next == NULL) {
|
||||
return MBEDTLS_ERR_X509_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
cur_entry = cur_entry->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse one CRLs in DER format and append it to the chained list
|
||||
*/
|
||||
int mbedtls_x509_crl_parse_der(mbedtls_x509_crl *chain,
|
||||
const unsigned char *buf, size_t buflen)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
unsigned char *p = NULL, *end = NULL;
|
||||
mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
|
||||
mbedtls_x509_crl *crl = chain;
|
||||
|
||||
/*
|
||||
* Check for valid input
|
||||
*/
|
||||
if (crl == NULL || buf == NULL) {
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
memset(&sig_params1, 0, sizeof(mbedtls_x509_buf));
|
||||
memset(&sig_params2, 0, sizeof(mbedtls_x509_buf));
|
||||
memset(&sig_oid2, 0, sizeof(mbedtls_x509_buf));
|
||||
|
||||
/*
|
||||
* Add new CRL on the end of the chain if needed.
|
||||
*/
|
||||
while (crl->version != 0 && crl->next != NULL) {
|
||||
crl = crl->next;
|
||||
}
|
||||
|
||||
if (crl->version != 0 && crl->next == NULL) {
|
||||
crl->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl));
|
||||
|
||||
if (crl->next == NULL) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return MBEDTLS_ERR_X509_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
mbedtls_x509_crl_init(crl->next);
|
||||
crl = crl->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy raw DER-encoded CRL
|
||||
*/
|
||||
if (buflen == 0) {
|
||||
return MBEDTLS_ERR_X509_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
p = mbedtls_calloc(1, buflen);
|
||||
if (p == NULL) {
|
||||
return MBEDTLS_ERR_X509_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
memcpy(p, buf, buflen);
|
||||
|
||||
crl->raw.p = p;
|
||||
crl->raw.len = buflen;
|
||||
|
||||
end = p + buflen;
|
||||
|
||||
/*
|
||||
* CertificateList ::= SEQUENCE {
|
||||
* tbsCertList TBSCertList,
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signatureValue BIT STRING }
|
||||
*/
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return MBEDTLS_ERR_X509_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
if (len != (size_t) (end - p)) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
/*
|
||||
* TBSCertList ::= SEQUENCE {
|
||||
*/
|
||||
crl->tbs.p = p;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
|
||||
}
|
||||
|
||||
end = p + len;
|
||||
crl->tbs.len = (size_t) (end - crl->tbs.p);
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
|
||||
* -- if present, MUST be v2
|
||||
*
|
||||
* signature AlgorithmIdentifier
|
||||
*/
|
||||
if ((ret = x509_crl_get_version(&p, end, &crl->version)) != 0 ||
|
||||
(ret = mbedtls_x509_get_alg(&p, end, &crl->sig_oid, &sig_params1)) != 0) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (crl->version < 0 || crl->version > 1) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return MBEDTLS_ERR_X509_UNKNOWN_VERSION;
|
||||
}
|
||||
|
||||
crl->version++;
|
||||
|
||||
if ((ret = mbedtls_x509_get_sig_alg(&crl->sig_oid, &sig_params1,
|
||||
&crl->sig_md, &crl->sig_pk)) != 0) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG;
|
||||
}
|
||||
|
||||
/*
|
||||
* issuer Name
|
||||
*/
|
||||
crl->issuer_raw.p = p;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_x509_get_name(&p, p + len, &crl->issuer)) != 0) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
crl->issuer_raw.len = (size_t) (p - crl->issuer_raw.p);
|
||||
|
||||
/*
|
||||
* thisUpdate Time
|
||||
* nextUpdate Time OPTIONAL
|
||||
*/
|
||||
if ((ret = mbedtls_x509_get_time(&p, end, &crl->this_update)) != 0) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_x509_get_time(&p, end, &crl->next_update)) != 0) {
|
||||
if (ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
|
||||
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) &&
|
||||
ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
|
||||
MBEDTLS_ERR_ASN1_OUT_OF_DATA))) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* revokedCertificates SEQUENCE OF SEQUENCE {
|
||||
* userCertificate CertificateSerialNumber,
|
||||
* revocationDate Time,
|
||||
* crlEntryExtensions Extensions OPTIONAL
|
||||
* -- if present, MUST be v2
|
||||
* } OPTIONAL
|
||||
*/
|
||||
if ((ret = x509_get_entries(&p, end, &crl->entry)) != 0) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* crlExtensions EXPLICIT Extensions OPTIONAL
|
||||
* -- if present, MUST be v2
|
||||
*/
|
||||
if (crl->version == 2) {
|
||||
ret = x509_get_crl_ext(&p, end, &crl->crl_ext);
|
||||
|
||||
if (ret != 0) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (p != end) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
end = crl->raw.p + crl->raw.len;
|
||||
|
||||
/*
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signatureValue BIT STRING
|
||||
*/
|
||||
if ((ret = mbedtls_x509_get_alg(&p, end, &sig_oid2, &sig_params2)) != 0) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (crl->sig_oid.len != sig_oid2.len ||
|
||||
memcmp(crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len) != 0 ||
|
||||
sig_params1.len != sig_params2.len ||
|
||||
(sig_params1.len != 0 &&
|
||||
memcmp(sig_params1.p, sig_params2.p, sig_params1.len) != 0)) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return MBEDTLS_ERR_X509_SIG_MISMATCH;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_x509_get_sig(&p, end, &crl->sig)) != 0) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (p != end) {
|
||||
mbedtls_x509_crl_free(crl);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse one or more CRLs and add them to the chained list
|
||||
*/
|
||||
int mbedtls_x509_crl_parse(mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen)
|
||||
{
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t use_len = 0;
|
||||
mbedtls_pem_context pem;
|
||||
int is_pem = 0;
|
||||
|
||||
if (chain == NULL || buf == NULL) {
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
do {
|
||||
mbedtls_pem_init(&pem);
|
||||
|
||||
// Avoid calling mbedtls_pem_read_buffer() on non-null-terminated
|
||||
// string
|
||||
if (buflen == 0 || buf[buflen - 1] != '\0') {
|
||||
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
|
||||
} else {
|
||||
ret = mbedtls_pem_read_buffer(&pem,
|
||||
"-----BEGIN X509 CRL-----",
|
||||
"-----END X509 CRL-----",
|
||||
buf, NULL, 0, &use_len);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* Was PEM encoded
|
||||
*/
|
||||
is_pem = 1;
|
||||
|
||||
buflen -= use_len;
|
||||
buf += use_len;
|
||||
|
||||
if ((ret = mbedtls_x509_crl_parse_der(chain,
|
||||
pem.buf, pem.buflen)) != 0) {
|
||||
mbedtls_pem_free(&pem);
|
||||
return ret;
|
||||
}
|
||||
} else if (is_pem) {
|
||||
mbedtls_pem_free(&pem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
mbedtls_pem_free(&pem);
|
||||
}
|
||||
/* In the PEM case, buflen is 1 at the end, for the terminated NULL byte.
|
||||
* And a valid CRL cannot be less than 1 byte anyway. */
|
||||
while (is_pem && buflen > 1);
|
||||
|
||||
if (is_pem) {
|
||||
return 0;
|
||||
} else
|
||||
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||
return mbedtls_x509_crl_parse_der(chain, buf, buflen);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/*
|
||||
* Load one or more CRLs and add them to the chained list
|
||||
*/
|
||||
int mbedtls_x509_crl_parse_file(mbedtls_x509_crl *chain, const char *path)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n;
|
||||
unsigned char *buf;
|
||||
|
||||
if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509_crl_parse(chain, buf, n);
|
||||
|
||||
mbedtls_zeroize_and_free(buf, n);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
/*
|
||||
* Return an informational string about the CRL.
|
||||
*/
|
||||
int mbedtls_x509_crl_info(char *buf, size_t size, const char *prefix,
|
||||
const mbedtls_x509_crl *crl)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n;
|
||||
char *p;
|
||||
const mbedtls_x509_crl_entry *entry;
|
||||
|
||||
p = buf;
|
||||
n = size;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "%sCRL version : %d",
|
||||
prefix, crl->version);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "\n%sissuer name : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
ret = mbedtls_x509_dn_gets(p, n, &crl->issuer);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "\n%sthis update : " \
|
||||
"%04d-%02d-%02d %02d:%02d:%02d", prefix,
|
||||
crl->this_update.year, crl->this_update.mon,
|
||||
crl->this_update.day, crl->this_update.hour,
|
||||
crl->this_update.min, crl->this_update.sec);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "\n%snext update : " \
|
||||
"%04d-%02d-%02d %02d:%02d:%02d", prefix,
|
||||
crl->next_update.year, crl->next_update.mon,
|
||||
crl->next_update.day, crl->next_update.hour,
|
||||
crl->next_update.min, crl->next_update.sec);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
entry = &crl->entry;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "\n%sRevoked certificates:",
|
||||
prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
while (entry != NULL && entry->raw.len != 0) {
|
||||
ret = mbedtls_snprintf(p, n, "\n%sserial number: ",
|
||||
prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_x509_serial_gets(p, n, &entry->serial);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, " revocation date: " \
|
||||
"%04d-%02d-%02d %02d:%02d:%02d",
|
||||
entry->revocation_date.year, entry->revocation_date.mon,
|
||||
entry->revocation_date.day, entry->revocation_date.hour,
|
||||
entry->revocation_date.min, entry->revocation_date.sec);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "\n%ssigned using : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_x509_sig_alg_gets(p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "\n");
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
return (int) (size - n);
|
||||
}
|
||||
#endif /* MBEDTLS_X509_REMOVE_INFO */
|
||||
|
||||
/*
|
||||
* Initialize a CRL chain
|
||||
*/
|
||||
void mbedtls_x509_crl_init(mbedtls_x509_crl *crl)
|
||||
{
|
||||
memset(crl, 0, sizeof(mbedtls_x509_crl));
|
||||
}
|
||||
|
||||
/*
|
||||
* Unallocate all CRL data
|
||||
*/
|
||||
void mbedtls_x509_crl_free(mbedtls_x509_crl *crl)
|
||||
{
|
||||
mbedtls_x509_crl *crl_cur = crl;
|
||||
mbedtls_x509_crl *crl_prv;
|
||||
mbedtls_x509_crl_entry *entry_cur;
|
||||
mbedtls_x509_crl_entry *entry_prv;
|
||||
|
||||
while (crl_cur != NULL) {
|
||||
mbedtls_asn1_free_named_data_list_shallow(crl_cur->issuer.next);
|
||||
|
||||
entry_cur = crl_cur->entry.next;
|
||||
while (entry_cur != NULL) {
|
||||
entry_prv = entry_cur;
|
||||
entry_cur = entry_cur->next;
|
||||
mbedtls_zeroize_and_free(entry_prv,
|
||||
sizeof(mbedtls_x509_crl_entry));
|
||||
}
|
||||
|
||||
if (crl_cur->raw.p != NULL) {
|
||||
mbedtls_zeroize_and_free(crl_cur->raw.p, crl_cur->raw.len);
|
||||
}
|
||||
|
||||
crl_prv = crl_cur;
|
||||
crl_cur = crl_cur->next;
|
||||
|
||||
mbedtls_platform_zeroize(crl_prv, sizeof(mbedtls_x509_crl));
|
||||
if (crl_prv != crl) {
|
||||
mbedtls_free(crl_prv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_X509_CRL_PARSE_C */
|
||||
+3268
File diff suppressed because it is too large
Load Diff
+633
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
* X.509 Certificate Signing Request (CSR) parsing
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
/*
|
||||
* The ITU-T X.509 standard defines a certificate format for PKI.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
|
||||
* http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
|
||||
* http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
|
||||
*
|
||||
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
|
||||
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
|
||||
*/
|
||||
|
||||
#include "x509_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_X509_CSR_PARSE_C)
|
||||
|
||||
#include "mbedtls/x509_csr.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "x509_oid.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
#include "mbedtls/pem.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER { v1(0) }
|
||||
*/
|
||||
static int x509_csr_get_version(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *ver)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) {
|
||||
if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
||||
*ver = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse CSR extension requests in DER format
|
||||
*/
|
||||
static int x509_csr_parse_extensions(mbedtls_x509_csr *csr,
|
||||
unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_csr_ext_cb_t cb,
|
||||
void *p_ctx)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
unsigned char *end_ext_data, *end_ext_octet;
|
||||
|
||||
while (*p < end) {
|
||||
mbedtls_x509_buf extn_oid = { 0, 0, NULL };
|
||||
int is_critical = 0; /* DEFAULT FALSE */
|
||||
int ext_type = 0;
|
||||
|
||||
/* Read sequence tag */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
end_ext_data = *p + len;
|
||||
|
||||
/* Get extension ID */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &extn_oid.len,
|
||||
MBEDTLS_ASN1_OID)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
extn_oid.tag = MBEDTLS_ASN1_OID;
|
||||
extn_oid.p = *p;
|
||||
*p += extn_oid.len;
|
||||
|
||||
/* Get optional critical */
|
||||
if ((ret = mbedtls_asn1_get_bool(p, end_ext_data, &is_critical)) != 0 &&
|
||||
(ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
/* Data should be octet string type */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
|
||||
MBEDTLS_ASN1_OCTET_STRING)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
end_ext_octet = *p + len;
|
||||
|
||||
if (end_ext_octet != end_ext_data) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect supported extensions and skip unsupported extensions
|
||||
*/
|
||||
ret = mbedtls_x509_oid_get_x509_ext_type(&extn_oid, &ext_type);
|
||||
|
||||
if (ret != 0) {
|
||||
/* Give the callback (if any) a chance to handle the extension */
|
||||
if (cb != NULL) {
|
||||
ret = cb(p_ctx, csr, &extn_oid, is_critical, *p, end_ext_octet);
|
||||
if (ret != 0 && is_critical) {
|
||||
return ret;
|
||||
}
|
||||
*p = end_ext_octet;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* No parser found, skip extension */
|
||||
*p = end_ext_octet;
|
||||
|
||||
if (is_critical) {
|
||||
/* Data is marked as critical: fail */
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Forbid repeated extensions */
|
||||
if ((csr->ext_types & ext_type) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_INVALID_DATA);
|
||||
}
|
||||
|
||||
csr->ext_types |= ext_type;
|
||||
|
||||
switch (ext_type) {
|
||||
case MBEDTLS_X509_EXT_KEY_USAGE:
|
||||
/* Parse key usage */
|
||||
if ((ret = mbedtls_x509_get_key_usage(p, end_ext_data,
|
||||
&csr->key_usage)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
|
||||
/* Parse subject alt name */
|
||||
if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_data,
|
||||
&csr->subject_alt_names)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case MBEDTLS_X509_EXT_NS_CERT_TYPE:
|
||||
/* Parse netscape certificate type */
|
||||
if ((ret = mbedtls_x509_get_ns_cert_type(p, end_ext_data,
|
||||
&csr->ns_cert_type)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* If this is a non-critical extension, which the oid layer
|
||||
* supports, but there isn't an x509 parser for it,
|
||||
* skip the extension.
|
||||
*/
|
||||
if (is_critical) {
|
||||
return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
|
||||
} else {
|
||||
*p = end_ext_octet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*p != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse CSR attributes in DER format
|
||||
*/
|
||||
static int x509_csr_parse_attributes(mbedtls_x509_csr *csr,
|
||||
const unsigned char *start, const unsigned char *end,
|
||||
mbedtls_x509_csr_ext_cb_t cb,
|
||||
void *p_ctx)
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
unsigned char *end_attr_data;
|
||||
unsigned char **p = (unsigned char **) &start;
|
||||
|
||||
while (*p < end) {
|
||||
mbedtls_x509_buf attr_oid = { 0, 0, NULL };
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
end_attr_data = *p + len;
|
||||
|
||||
/* Get attribute ID */
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end_attr_data, &attr_oid.len,
|
||||
MBEDTLS_ASN1_OID)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
attr_oid.tag = MBEDTLS_ASN1_OID;
|
||||
attr_oid.p = *p;
|
||||
*p += attr_oid.len;
|
||||
|
||||
/* Check that this is an extension-request attribute */
|
||||
if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS9_CSR_EXT_REQ, &attr_oid) == 0) {
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) !=
|
||||
0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
|
||||
}
|
||||
|
||||
if ((ret = x509_csr_parse_extensions(csr, p, *p + len, cb, p_ctx)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (*p != end_attr_data) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
}
|
||||
|
||||
*p = end_attr_data;
|
||||
}
|
||||
|
||||
if (*p != end) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a CSR in DER format
|
||||
*/
|
||||
static int mbedtls_x509_csr_parse_der_internal(mbedtls_x509_csr *csr,
|
||||
const unsigned char *buf, size_t buflen,
|
||||
mbedtls_x509_csr_ext_cb_t cb,
|
||||
void *p_ctx)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
unsigned char *p, *end;
|
||||
mbedtls_x509_buf sig_params;
|
||||
|
||||
memset(&sig_params, 0, sizeof(mbedtls_x509_buf));
|
||||
|
||||
/*
|
||||
* Check for valid input
|
||||
*/
|
||||
if (csr == NULL || buf == NULL || buflen == 0) {
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mbedtls_x509_csr_init(csr);
|
||||
|
||||
/*
|
||||
* first copy the raw DER data
|
||||
*/
|
||||
p = mbedtls_calloc(1, len = buflen);
|
||||
|
||||
if (p == NULL) {
|
||||
return MBEDTLS_ERR_X509_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
memcpy(p, buf, buflen);
|
||||
|
||||
csr->raw.p = p;
|
||||
csr->raw.len = len;
|
||||
end = p + len;
|
||||
|
||||
/*
|
||||
* CertificationRequest ::= SEQUENCE {
|
||||
* certificationRequestInfo CertificationRequestInfo,
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signature BIT STRING
|
||||
* }
|
||||
*/
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return MBEDTLS_ERR_X509_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
if (len != (size_t) (end - p)) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
/*
|
||||
* CertificationRequestInfo ::= SEQUENCE {
|
||||
*/
|
||||
csr->cri.p = p;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
|
||||
}
|
||||
|
||||
end = p + len;
|
||||
csr->cri.len = (size_t) (end - csr->cri.p);
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER { v1(0) }
|
||||
*/
|
||||
if ((ret = x509_csr_get_version(&p, end, &csr->version)) != 0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (csr->version != 0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return MBEDTLS_ERR_X509_UNKNOWN_VERSION;
|
||||
}
|
||||
|
||||
csr->version++;
|
||||
|
||||
/*
|
||||
* subject Name
|
||||
*/
|
||||
csr->subject_raw.p = p;
|
||||
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_x509_get_name(&p, p + len, &csr->subject)) != 0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
csr->subject_raw.len = (size_t) (p - csr->subject_raw.p);
|
||||
|
||||
/*
|
||||
* subjectPKInfo SubjectPublicKeyInfo
|
||||
*/
|
||||
if ((ret = mbedtls_pk_parse_subpubkey(&p, end, &csr->pk)) != 0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* attributes [0] Attributes
|
||||
*
|
||||
* The list of possible attributes is open-ended, though RFC 2985
|
||||
* (PKCS#9) defines a few in section 5.4. We currently don't support any,
|
||||
* so we just ignore them. This is a safe thing to do as the worst thing
|
||||
* that could happen is that we issue a certificate that does not match
|
||||
* the requester's expectations - this cannot cause a violation of our
|
||||
* signature policies.
|
||||
*/
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
|
||||
0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
|
||||
}
|
||||
|
||||
if ((ret = x509_csr_parse_attributes(csr, p, p + len, cb, p_ctx)) != 0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
p += len;
|
||||
|
||||
end = csr->raw.p + csr->raw.len;
|
||||
|
||||
/*
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signature BIT STRING
|
||||
*/
|
||||
if ((ret = mbedtls_x509_get_alg(&p, end, &csr->sig_oid, &sig_params)) != 0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_x509_get_sig_alg(&csr->sig_oid, &sig_params,
|
||||
&csr->sig_md, &csr->sig_pk)) != 0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_x509_get_sig(&p, end, &csr->sig)) != 0) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (p != end) {
|
||||
mbedtls_x509_csr_free(csr);
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a CSR in DER format
|
||||
*/
|
||||
int mbedtls_x509_csr_parse_der(mbedtls_x509_csr *csr,
|
||||
const unsigned char *buf, size_t buflen)
|
||||
{
|
||||
return mbedtls_x509_csr_parse_der_internal(csr, buf, buflen, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a CSR in DER format with callback for unknown extensions
|
||||
*/
|
||||
int mbedtls_x509_csr_parse_der_with_ext_cb(mbedtls_x509_csr *csr,
|
||||
const unsigned char *buf, size_t buflen,
|
||||
mbedtls_x509_csr_ext_cb_t cb,
|
||||
void *p_ctx)
|
||||
{
|
||||
return mbedtls_x509_csr_parse_der_internal(csr, buf, buflen, cb, p_ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a CSR, allowing for PEM or raw DER encoding
|
||||
*/
|
||||
int mbedtls_x509_csr_parse(mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen)
|
||||
{
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t use_len;
|
||||
mbedtls_pem_context pem;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check for valid input
|
||||
*/
|
||||
if (csr == NULL || buf == NULL || buflen == 0) {
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
|
||||
if (buf[buflen - 1] == '\0') {
|
||||
mbedtls_pem_init(&pem);
|
||||
ret = mbedtls_pem_read_buffer(&pem,
|
||||
"-----BEGIN CERTIFICATE REQUEST-----",
|
||||
"-----END CERTIFICATE REQUEST-----",
|
||||
buf, NULL, 0, &use_len);
|
||||
if (ret == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
|
||||
ret = mbedtls_pem_read_buffer(&pem,
|
||||
"-----BEGIN NEW CERTIFICATE REQUEST-----",
|
||||
"-----END NEW CERTIFICATE REQUEST-----",
|
||||
buf, NULL, 0, &use_len);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* Was PEM encoded, parse the result
|
||||
*/
|
||||
ret = mbedtls_x509_csr_parse_der(csr, pem.buf, pem.buflen);
|
||||
}
|
||||
|
||||
mbedtls_pem_free(&pem);
|
||||
if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||
return mbedtls_x509_csr_parse_der(csr, buf, buflen);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/*
|
||||
* Load a CSR into the structure
|
||||
*/
|
||||
int mbedtls_x509_csr_parse_file(mbedtls_x509_csr *csr, const char *path)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n;
|
||||
unsigned char *buf;
|
||||
|
||||
if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509_csr_parse(csr, buf, n);
|
||||
|
||||
mbedtls_zeroize_and_free(buf, n);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
#define MBEDTLS_BEFORE_COLON 14
|
||||
#define MBEDTLS_BEFORE_COLON_STR "14"
|
||||
/*
|
||||
* Return an informational string about the CSR.
|
||||
*/
|
||||
int mbedtls_x509_csr_info(char *buf, size_t size, const char *prefix,
|
||||
const mbedtls_x509_csr *csr)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n;
|
||||
char *p;
|
||||
char key_size_str[MBEDTLS_BEFORE_COLON];
|
||||
|
||||
p = buf;
|
||||
n = size;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "%sCSR version : %d",
|
||||
prefix, csr->version);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "\n%ssubject name : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
ret = mbedtls_x509_dn_gets(p, n, &csr->subject);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "\n%ssigned using : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
ret = mbedtls_x509_sig_alg_gets(p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
if ((ret = mbedtls_x509_key_size_helper(key_size_str, MBEDTLS_BEFORE_COLON,
|
||||
mbedtls_pk_get_name(&csr->pk))) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_snprintf(p, n, "\n%s%-" MBEDTLS_BEFORE_COLON_STR "s: %d bits\n",
|
||||
prefix, key_size_str, (int) mbedtls_pk_get_bitlen(&csr->pk));
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
/*
|
||||
* Optional extensions
|
||||
*/
|
||||
|
||||
if (csr->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
|
||||
ret = mbedtls_snprintf(p, n, "\n%ssubject alt name :", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
if ((ret = mbedtls_x509_info_subject_alt_name(&p, &n,
|
||||
&csr->subject_alt_names,
|
||||
prefix)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (csr->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) {
|
||||
ret = mbedtls_snprintf(p, n, "\n%scert. type : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
if ((ret = mbedtls_x509_info_cert_type(&p, &n, csr->ns_cert_type)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (csr->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) {
|
||||
ret = mbedtls_snprintf(p, n, "\n%skey usage : ", prefix);
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
|
||||
if ((ret = mbedtls_x509_info_key_usage(&p, &n, csr->key_usage)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (csr->ext_types != 0) {
|
||||
ret = mbedtls_snprintf(p, n, "\n");
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
}
|
||||
|
||||
return (int) (size - n);
|
||||
}
|
||||
#endif /* MBEDTLS_X509_REMOVE_INFO */
|
||||
|
||||
/*
|
||||
* Initialize a CSR
|
||||
*/
|
||||
void mbedtls_x509_csr_init(mbedtls_x509_csr *csr)
|
||||
{
|
||||
memset(csr, 0, sizeof(mbedtls_x509_csr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Unallocate all CSR data
|
||||
*/
|
||||
void mbedtls_x509_csr_free(mbedtls_x509_csr *csr)
|
||||
{
|
||||
if (csr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_pk_free(&csr->pk);
|
||||
|
||||
mbedtls_asn1_free_named_data_list_shallow(csr->subject.next);
|
||||
mbedtls_asn1_sequence_free(csr->subject_alt_names.next);
|
||||
|
||||
if (csr->raw.p != NULL) {
|
||||
mbedtls_zeroize_and_free(csr->raw.p, csr->raw.len);
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize(csr, sizeof(mbedtls_x509_csr));
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_X509_CSR_PARSE_C */
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* \file x509.h
|
||||
*
|
||||
* \brief Internal part of the public "x509.h".
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_X509_INTERNAL_H
|
||||
#define MBEDTLS_X509_INTERNAL_H
|
||||
|
||||
#include "tf_psa_crypto_common.h"
|
||||
#include "mbedtls/build_info.h"
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "pk_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
#include "mbedtls/private/rsa.h"
|
||||
#endif
|
||||
|
||||
int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_name *cur);
|
||||
int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *alg);
|
||||
int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *alg, mbedtls_x509_buf *params);
|
||||
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
|
||||
int mbedtls_x509_get_rsassa_pss_params(const mbedtls_x509_buf *params,
|
||||
mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
|
||||
int *salt_len);
|
||||
#endif
|
||||
int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig);
|
||||
int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
|
||||
mbedtls_md_type_t *md_alg, mbedtls_pk_sigalg_t *pk_alg);
|
||||
int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_time *t);
|
||||
int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *serial);
|
||||
int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_buf *ext, int tag);
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
|
||||
mbedtls_pk_sigalg_t pk_alg, mbedtls_md_type_t md_alg);
|
||||
#endif
|
||||
int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name);
|
||||
int mbedtls_x509_set_extension(mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
|
||||
int critical, const unsigned char *val,
|
||||
size_t val_len);
|
||||
int mbedtls_x509_write_extensions(unsigned char **p, unsigned char *start,
|
||||
mbedtls_asn1_named_data *first);
|
||||
int mbedtls_x509_write_names(unsigned char **p, unsigned char *start,
|
||||
mbedtls_asn1_named_data *first);
|
||||
int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
unsigned char *sig, size_t size,
|
||||
mbedtls_pk_sigalg_t pk_alg);
|
||||
int mbedtls_x509_get_ns_cert_type(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
unsigned char *ns_cert_type);
|
||||
int mbedtls_x509_get_key_usage(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
unsigned int *key_usage);
|
||||
int mbedtls_x509_get_subject_alt_name(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_x509_sequence *subject_alt_name);
|
||||
int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_x509_sequence *subject_alt_name);
|
||||
int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
|
||||
const mbedtls_x509_sequence
|
||||
*subject_alt_name,
|
||||
const char *prefix);
|
||||
int mbedtls_x509_info_cert_type(char **buf, size_t *size,
|
||||
unsigned char ns_cert_type);
|
||||
int mbedtls_x509_info_key_usage(char **buf, size_t *size,
|
||||
unsigned int key_usage);
|
||||
|
||||
int mbedtls_x509_write_set_san_common(mbedtls_asn1_named_data **extensions,
|
||||
const mbedtls_x509_san_list *san_list);
|
||||
|
||||
#endif /* MBEDTLS_X509_INTERNAL_H */
|
||||
+603
@@ -0,0 +1,603 @@
|
||||
/**
|
||||
* \file x509_oid.c
|
||||
*
|
||||
* \brief Object Identifier (OID) database
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "x509_internal.h"
|
||||
|
||||
/* Each group of tables and functions has its own dependencies, but
|
||||
* don't even bother to define helper macros if X.509 is completely
|
||||
* disabled. */
|
||||
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
|
||||
|
||||
#include "mbedtls/oid.h"
|
||||
#include "x509_oid.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
/*
|
||||
* Macro to automatically add the size of #define'd OIDs
|
||||
*/
|
||||
#define ADD_LEN(s) s, MBEDTLS_OID_SIZE(s)
|
||||
|
||||
/*
|
||||
* Macro to generate mbedtls_x509_oid_descriptor_t
|
||||
*/
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
#define OID_DESCRIPTOR(s, name, description) { ADD_LEN(s), name, description }
|
||||
#define NULL_OID_DESCRIPTOR { NULL, 0, NULL, NULL }
|
||||
#else
|
||||
#define OID_DESCRIPTOR(s, name, description) { ADD_LEN(s) }
|
||||
#define NULL_OID_DESCRIPTOR { NULL, 0 }
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro to generate an internal function for oid_XXX_from_asn1() (used by
|
||||
* the other functions)
|
||||
*/
|
||||
#define FN_OID_TYPED_FROM_ASN1(TYPE_T, NAME, LIST) \
|
||||
static const TYPE_T *oid_ ## NAME ## _from_asn1( \
|
||||
const mbedtls_asn1_buf *oid) \
|
||||
{ \
|
||||
const TYPE_T *p = (LIST); \
|
||||
const mbedtls_x509_oid_descriptor_t *cur = \
|
||||
(const mbedtls_x509_oid_descriptor_t *) p; \
|
||||
if (p == NULL || oid == NULL) return NULL; \
|
||||
while (cur->asn1 != NULL) { \
|
||||
if (cur->asn1_len == oid->len && \
|
||||
memcmp(cur->asn1, oid->p, oid->len) == 0) { \
|
||||
return p; \
|
||||
} \
|
||||
p++; \
|
||||
cur = (const mbedtls_x509_oid_descriptor_t *) p; \
|
||||
} \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
/*
|
||||
* Macro to generate a function for retrieving a single attribute from the
|
||||
* descriptor of an mbedtls_x509_oid_descriptor_t wrapper.
|
||||
*/
|
||||
#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
|
||||
int FN_NAME(const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1) \
|
||||
{ \
|
||||
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1(oid); \
|
||||
if (data == NULL) return MBEDTLS_ERR_X509_UNKNOWN_OID; \
|
||||
*ATTR1 = data->descriptor.ATTR1; \
|
||||
return 0; \
|
||||
}
|
||||
#endif /* MBEDTLS_X509_REMOVE_INFO */
|
||||
|
||||
/*
|
||||
* Macro to generate a function for retrieving a single attribute from an
|
||||
* mbedtls_x509_oid_descriptor_t wrapper.
|
||||
*/
|
||||
#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
|
||||
int FN_NAME(const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1) \
|
||||
{ \
|
||||
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1(oid); \
|
||||
if (data == NULL) return MBEDTLS_ERR_X509_UNKNOWN_OID; \
|
||||
*ATTR1 = data->ATTR1; \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Macro to generate a function for retrieving two attributes from an
|
||||
* mbedtls_x509_oid_descriptor_t wrapper.
|
||||
*/
|
||||
#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \
|
||||
ATTR2_TYPE, ATTR2) \
|
||||
int FN_NAME(const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, \
|
||||
ATTR2_TYPE * ATTR2) \
|
||||
{ \
|
||||
const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1(oid); \
|
||||
if (data == NULL) return MBEDTLS_ERR_X509_UNKNOWN_OID; \
|
||||
*(ATTR1) = data->ATTR1; \
|
||||
*(ATTR2) = data->ATTR2; \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Macro to generate a function for retrieving the OID based on a single
|
||||
* attribute from a mbedtls_x509_oid_descriptor_t wrapper.
|
||||
*/
|
||||
#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \
|
||||
int FN_NAME(ATTR1_TYPE ATTR1, const char **oid, size_t *olen) \
|
||||
{ \
|
||||
const TYPE_T *cur = (LIST); \
|
||||
while (cur->descriptor.asn1 != NULL) { \
|
||||
if (cur->ATTR1 == (ATTR1)) { \
|
||||
*oid = cur->descriptor.asn1; \
|
||||
*olen = cur->descriptor.asn1_len; \
|
||||
return 0; \
|
||||
} \
|
||||
cur++; \
|
||||
} \
|
||||
return MBEDTLS_ERR_X509_UNKNOWN_OID; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Macro to generate a function for retrieving the OID based on two
|
||||
* attributes from a mbedtls_x509_oid_descriptor_t wrapper.
|
||||
*/
|
||||
#define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1, \
|
||||
ATTR2_TYPE, ATTR2) \
|
||||
int FN_NAME(ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid, \
|
||||
size_t *olen) \
|
||||
{ \
|
||||
const TYPE_T *cur = (LIST); \
|
||||
while (cur->descriptor.asn1 != NULL) { \
|
||||
if (cur->ATTR1 == (ATTR1) && cur->ATTR2 == (ATTR2)) { \
|
||||
*oid = cur->descriptor.asn1; \
|
||||
*olen = cur->descriptor.asn1_len; \
|
||||
return 0; \
|
||||
} \
|
||||
cur++; \
|
||||
} \
|
||||
return MBEDTLS_ERR_X509_UNKNOWN_OID; \
|
||||
}
|
||||
|
||||
/*
|
||||
* For X520 attribute types
|
||||
*/
|
||||
#if defined(MBEDTLS_X509_USE_C)
|
||||
typedef struct {
|
||||
mbedtls_x509_oid_descriptor_t descriptor;
|
||||
const char *short_name;
|
||||
} oid_x520_attr_t;
|
||||
|
||||
static const oid_x520_attr_t oid_x520_attr_type[] =
|
||||
{
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_CN, "id-at-commonName", "Common Name"),
|
||||
"CN",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_COUNTRY, "id-at-countryName", "Country"),
|
||||
"C",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_LOCALITY, "id-at-locality", "Locality"),
|
||||
"L",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_STATE, "id-at-state", "State"),
|
||||
"ST",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_ORGANIZATION, "id-at-organizationName",
|
||||
"Organization"),
|
||||
"O",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_ORG_UNIT, "id-at-organizationalUnitName", "Org Unit"),
|
||||
"OU",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_PKCS9_EMAIL,
|
||||
"emailAddress",
|
||||
"E-mail address"),
|
||||
"emailAddress",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_SERIAL_NUMBER,
|
||||
"id-at-serialNumber",
|
||||
"Serial number"),
|
||||
"serialNumber",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_POSTAL_ADDRESS,
|
||||
"id-at-postalAddress",
|
||||
"Postal address"),
|
||||
"postalAddress",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_POSTAL_CODE, "id-at-postalCode", "Postal code"),
|
||||
"postalCode",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_SUR_NAME, "id-at-surName", "Surname"),
|
||||
"SN",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_GIVEN_NAME, "id-at-givenName", "Given name"),
|
||||
"GN",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_INITIALS, "id-at-initials", "Initials"),
|
||||
"initials",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_GENERATION_QUALIFIER,
|
||||
"id-at-generationQualifier",
|
||||
"Generation qualifier"),
|
||||
"generationQualifier",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_TITLE, "id-at-title", "Title"),
|
||||
"title",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_DN_QUALIFIER,
|
||||
"id-at-dnQualifier",
|
||||
"Distinguished Name qualifier"),
|
||||
"dnQualifier",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_PSEUDONYM, "id-at-pseudonym", "Pseudonym"),
|
||||
"pseudonym",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_UID, "id-uid", "User Id"),
|
||||
"uid",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DOMAIN_COMPONENT,
|
||||
"id-domainComponent",
|
||||
"Domain component"),
|
||||
"DC",
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AT_UNIQUE_IDENTIFIER,
|
||||
"id-at-uniqueIdentifier",
|
||||
"Unique Identifier"),
|
||||
"uniqueIdentifier",
|
||||
},
|
||||
{
|
||||
NULL_OID_DESCRIPTOR,
|
||||
NULL,
|
||||
}
|
||||
};
|
||||
|
||||
FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type)
|
||||
FN_OID_GET_ATTR1(mbedtls_x509_oid_get_attr_short_name,
|
||||
oid_x520_attr_t,
|
||||
x520_attr,
|
||||
const char *,
|
||||
short_name)
|
||||
#endif /* MBEDTLS_X509_USE_C */
|
||||
|
||||
/*
|
||||
* For X509 extensions
|
||||
*/
|
||||
#if defined(MBEDTLS_X509_OID_HAVE_GET_X509_EXT_TYPE)
|
||||
typedef struct {
|
||||
mbedtls_x509_oid_descriptor_t descriptor;
|
||||
int ext_type;
|
||||
} oid_x509_ext_t;
|
||||
|
||||
static const oid_x509_ext_t oid_x509_ext[] =
|
||||
{
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_BASIC_CONSTRAINTS,
|
||||
"id-ce-basicConstraints",
|
||||
"Basic Constraints"),
|
||||
MBEDTLS_X509_EXT_BASIC_CONSTRAINTS,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_KEY_USAGE, "id-ce-keyUsage", "Key Usage"),
|
||||
MBEDTLS_X509_EXT_KEY_USAGE,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_EXTENDED_KEY_USAGE,
|
||||
"id-ce-extKeyUsage",
|
||||
"Extended Key Usage"),
|
||||
MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_SUBJECT_ALT_NAME,
|
||||
"id-ce-subjectAltName",
|
||||
"Subject Alt Name"),
|
||||
MBEDTLS_X509_EXT_SUBJECT_ALT_NAME,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_NS_CERT_TYPE,
|
||||
"id-netscape-certtype",
|
||||
"Netscape Certificate Type"),
|
||||
MBEDTLS_X509_EXT_NS_CERT_TYPE,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_CERTIFICATE_POLICIES,
|
||||
"id-ce-certificatePolicies",
|
||||
"Certificate Policies"),
|
||||
MBEDTLS_X509_EXT_CERTIFICATE_POLICIES,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER,
|
||||
"id-ce-subjectKeyIdentifier",
|
||||
"Subject Key Identifier"),
|
||||
MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER,
|
||||
},
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
|
||||
"id-ce-authorityKeyIdentifier",
|
||||
"Authority Key Identifier"),
|
||||
MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER,
|
||||
},
|
||||
{
|
||||
NULL_OID_DESCRIPTOR,
|
||||
0,
|
||||
},
|
||||
};
|
||||
|
||||
FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext)
|
||||
FN_OID_GET_ATTR1(mbedtls_x509_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type)
|
||||
#endif /* MBEDTLS_X509_OID_HAVE_GET_X509_EXT_TYPE */
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
static const mbedtls_x509_oid_descriptor_t oid_ext_key_usage[] =
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_SERVER_AUTH,
|
||||
"id-kp-serverAuth",
|
||||
"TLS Web Server Authentication"),
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_CLIENT_AUTH,
|
||||
"id-kp-clientAuth",
|
||||
"TLS Web Client Authentication"),
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_CODE_SIGNING, "id-kp-codeSigning", "Code Signing"),
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_EMAIL_PROTECTION, "id-kp-emailProtection", "E-mail Protection"),
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_TIME_STAMPING, "id-kp-timeStamping", "Time Stamping"),
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_OCSP_SIGNING, "id-kp-OCSPSigning", "OCSP Signing"),
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_WISUN_FAN,
|
||||
"id-kp-wisun-fan-device",
|
||||
"Wi-SUN Alliance Field Area Network (FAN)"),
|
||||
NULL_OID_DESCRIPTOR,
|
||||
};
|
||||
|
||||
FN_OID_TYPED_FROM_ASN1(mbedtls_x509_oid_descriptor_t, ext_key_usage, oid_ext_key_usage)
|
||||
FN_OID_GET_ATTR1(mbedtls_x509_oid_get_extended_key_usage,
|
||||
mbedtls_x509_oid_descriptor_t,
|
||||
ext_key_usage,
|
||||
const char *,
|
||||
description)
|
||||
|
||||
static const mbedtls_x509_oid_descriptor_t oid_certificate_policies[] =
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_ANY_POLICY, "anyPolicy", "Any Policy"),
|
||||
NULL_OID_DESCRIPTOR,
|
||||
};
|
||||
|
||||
FN_OID_TYPED_FROM_ASN1(mbedtls_x509_oid_descriptor_t, certificate_policies,
|
||||
oid_certificate_policies)
|
||||
FN_OID_GET_ATTR1(mbedtls_x509_oid_get_certificate_policies,
|
||||
mbedtls_x509_oid_descriptor_t,
|
||||
certificate_policies,
|
||||
const char *,
|
||||
description)
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_X509_REMOVE_INFO */
|
||||
|
||||
/*
|
||||
* For SignatureAlgorithmIdentifier
|
||||
*/
|
||||
#if defined(MBEDTLS_X509_USE_C) || \
|
||||
defined(MBEDTLS_X509_CRT_WRITE_C) || defined(MBEDTLS_X509_CSR_WRITE_C)
|
||||
typedef struct {
|
||||
mbedtls_x509_oid_descriptor_t descriptor;
|
||||
mbedtls_md_type_t md_alg;
|
||||
mbedtls_pk_sigalg_t pk_alg;
|
||||
} oid_sig_alg_t;
|
||||
|
||||
static const oid_sig_alg_t oid_sig_alg[] =
|
||||
{
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
#if defined(PSA_WANT_ALG_MD5)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_MD5, "md5WithRSAEncryption", "RSA with MD5"),
|
||||
MBEDTLS_MD_MD5, MBEDTLS_PK_SIGALG_RSA_PKCS1V15,
|
||||
},
|
||||
#endif /* PSA_WANT_ALG_MD5 */
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_SHA1, "sha-1WithRSAEncryption", "RSA with SHA1"),
|
||||
MBEDTLS_MD_SHA1, MBEDTLS_PK_SIGALG_RSA_PKCS1V15,
|
||||
},
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
#if defined(PSA_WANT_ALG_SHA_224)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_SHA224, "sha224WithRSAEncryption",
|
||||
"RSA with SHA-224"),
|
||||
MBEDTLS_MD_SHA224, MBEDTLS_PK_SIGALG_RSA_PKCS1V15,
|
||||
},
|
||||
#endif /* PSA_WANT_ALG_SHA_224 */
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_SHA256, "sha256WithRSAEncryption",
|
||||
"RSA with SHA-256"),
|
||||
MBEDTLS_MD_SHA256, MBEDTLS_PK_SIGALG_RSA_PKCS1V15,
|
||||
},
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_SHA384, "sha384WithRSAEncryption",
|
||||
"RSA with SHA-384"),
|
||||
MBEDTLS_MD_SHA384, MBEDTLS_PK_SIGALG_RSA_PKCS1V15,
|
||||
},
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#if defined(PSA_WANT_ALG_SHA_512)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_SHA512, "sha512WithRSAEncryption",
|
||||
"RSA with SHA-512"),
|
||||
MBEDTLS_MD_SHA512, MBEDTLS_PK_SIGALG_RSA_PKCS1V15,
|
||||
},
|
||||
#endif /* PSA_WANT_ALG_SHA_512 */
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_RSA_SHA_OBS, "sha-1WithRSAEncryption", "RSA with SHA1"),
|
||||
MBEDTLS_MD_SHA1, MBEDTLS_PK_SIGALG_RSA_PKCS1V15,
|
||||
},
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
#if defined(PSA_HAVE_ALG_SOME_ECDSA)
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_ECDSA_SHA1, "ecdsa-with-SHA1", "ECDSA with SHA1"),
|
||||
MBEDTLS_MD_SHA1, MBEDTLS_PK_SIGALG_ECDSA,
|
||||
},
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
#if defined(PSA_WANT_ALG_SHA_224)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_ECDSA_SHA224, "ecdsa-with-SHA224", "ECDSA with SHA224"),
|
||||
MBEDTLS_MD_SHA224, MBEDTLS_PK_SIGALG_ECDSA,
|
||||
},
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_ECDSA_SHA256, "ecdsa-with-SHA256", "ECDSA with SHA256"),
|
||||
MBEDTLS_MD_SHA256, MBEDTLS_PK_SIGALG_ECDSA,
|
||||
},
|
||||
#endif /* PSA_WANT_ALG_SHA_256 */
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_ECDSA_SHA384, "ecdsa-with-SHA384", "ECDSA with SHA384"),
|
||||
MBEDTLS_MD_SHA384, MBEDTLS_PK_SIGALG_ECDSA,
|
||||
},
|
||||
#endif /* PSA_WANT_ALG_SHA_384 */
|
||||
#if defined(PSA_WANT_ALG_SHA_512)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_ECDSA_SHA512, "ecdsa-with-SHA512", "ECDSA with SHA512"),
|
||||
MBEDTLS_MD_SHA512, MBEDTLS_PK_SIGALG_ECDSA,
|
||||
},
|
||||
#endif /* PSA_WANT_ALG_SHA_512 */
|
||||
#endif /* PSA_HAVE_ALG_SOME_ECDSA */
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_RSASSA_PSS, "RSASSA-PSS", "RSASSA-PSS"),
|
||||
MBEDTLS_MD_NONE, MBEDTLS_PK_SIGALG_RSA_PSS,
|
||||
},
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
{
|
||||
NULL_OID_DESCRIPTOR,
|
||||
MBEDTLS_MD_NONE, MBEDTLS_PK_SIGALG_NONE,
|
||||
},
|
||||
};
|
||||
|
||||
FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg)
|
||||
|
||||
#if defined(MBEDTLS_X509_USE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
FN_OID_GET_DESCRIPTOR_ATTR1(mbedtls_x509_oid_get_sig_alg_desc,
|
||||
oid_sig_alg_t,
|
||||
sig_alg,
|
||||
const char *,
|
||||
description)
|
||||
#endif /* MBEDTLS_X509_USE_C && !MBEDTLS_X509_REMOVE_INFO */
|
||||
|
||||
#if defined(MBEDTLS_X509_USE_C)
|
||||
FN_OID_GET_ATTR2(mbedtls_x509_oid_get_sig_alg,
|
||||
oid_sig_alg_t,
|
||||
sig_alg,
|
||||
mbedtls_md_type_t,
|
||||
md_alg,
|
||||
mbedtls_pk_sigalg_t,
|
||||
pk_alg)
|
||||
#endif /* MBEDTLS_X509_USE_C */
|
||||
#if defined(MBEDTLS_X509_CRT_WRITE_C) || defined(MBEDTLS_X509_CSR_WRITE_C)
|
||||
FN_OID_GET_OID_BY_ATTR2(mbedtls_x509_oid_get_oid_by_sig_alg,
|
||||
oid_sig_alg_t,
|
||||
oid_sig_alg,
|
||||
mbedtls_pk_sigalg_t,
|
||||
pk_alg,
|
||||
mbedtls_md_type_t,
|
||||
md_alg)
|
||||
#endif /* MBEDTLS_X509_CRT_WRITE_C || MBEDTLS_X509_CSR_WRITE_C */
|
||||
|
||||
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CRT_WRITE_C || MBEDTLS_X509_CSR_WRITE_C */
|
||||
|
||||
#if defined(MBEDTLS_X509_OID_HAVE_GET_MD_ALG)
|
||||
/*
|
||||
* For digestAlgorithm
|
||||
*/
|
||||
/* The table of digest OIDs is duplicated in TF-PSA-Crypto (which uses it to
|
||||
* look up the OID for a hash algorithm in RSA PKCS#1v1.5 signature and
|
||||
* verification). */
|
||||
typedef struct {
|
||||
mbedtls_x509_oid_descriptor_t descriptor;
|
||||
mbedtls_md_type_t md_alg;
|
||||
} oid_md_alg_t;
|
||||
|
||||
static const oid_md_alg_t oid_md_alg[] =
|
||||
{
|
||||
#if defined(PSA_WANT_ALG_MD5)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_MD5, "id-md5", "MD5"),
|
||||
MBEDTLS_MD_MD5,
|
||||
},
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA1, "id-sha1", "SHA-1"),
|
||||
MBEDTLS_MD_SHA1,
|
||||
},
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_SHA_224)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA224, "id-sha224", "SHA-224"),
|
||||
MBEDTLS_MD_SHA224,
|
||||
},
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA256, "id-sha256", "SHA-256"),
|
||||
MBEDTLS_MD_SHA256,
|
||||
},
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_SHA_384)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA384, "id-sha384", "SHA-384"),
|
||||
MBEDTLS_MD_SHA384,
|
||||
},
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_SHA_512)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA512, "id-sha512", "SHA-512"),
|
||||
MBEDTLS_MD_SHA512,
|
||||
},
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_RIPEMD160)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_RIPEMD160, "id-ripemd160", "RIPEMD-160"),
|
||||
MBEDTLS_MD_RIPEMD160,
|
||||
},
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_SHA3_224)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA3_224, "id-sha3-224", "SHA-3-224"),
|
||||
MBEDTLS_MD_SHA3_224,
|
||||
},
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_SHA3_256)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA3_256, "id-sha3-256", "SHA-3-256"),
|
||||
MBEDTLS_MD_SHA3_256,
|
||||
},
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_SHA3_384)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA3_384, "id-sha3-384", "SHA-3-384"),
|
||||
MBEDTLS_MD_SHA3_384,
|
||||
},
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_SHA3_512)
|
||||
{
|
||||
OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA3_512, "id-sha3-512", "SHA-3-512"),
|
||||
MBEDTLS_MD_SHA3_512,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
NULL_OID_DESCRIPTOR,
|
||||
MBEDTLS_MD_NONE,
|
||||
},
|
||||
};
|
||||
|
||||
FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg)
|
||||
FN_OID_GET_ATTR1(mbedtls_x509_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg)
|
||||
|
||||
#endif /* MBEDTLS_X509_OID_HAVE_GET_MD_ALG */
|
||||
|
||||
#endif /* some X.509 is enabled */
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* \file x509_oid.h
|
||||
*
|
||||
* \brief Object Identifier (OID) database
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_X509_OID_H
|
||||
#define MBEDTLS_X509_OID_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "mbedtls/pk.h"
|
||||
#if defined(MBEDTLS_PK_HAVE_PRIVATE_HEADER)
|
||||
#include <mbedtls/private/pk_private.h>
|
||||
#endif /* MBEDTLS_PK_HAVE_PRIVATE_HEADER */
|
||||
#include "mbedtls/x509.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
/*
|
||||
* Maximum number of OID components allowed
|
||||
*/
|
||||
#define MBEDTLS_OID_MAX_COMPONENTS 128
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Base OID descriptor structure
|
||||
*/
|
||||
typedef struct {
|
||||
const char *MBEDTLS_PRIVATE(asn1); /*!< OID ASN.1 representation */
|
||||
size_t MBEDTLS_PRIVATE(asn1_len); /*!< length of asn1 */
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
const char *MBEDTLS_PRIVATE(name); /*!< official name (e.g. from RFC) */
|
||||
const char *MBEDTLS_PRIVATE(description); /*!< human friendly description */
|
||||
#endif
|
||||
} mbedtls_x509_oid_descriptor_t;
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C)
|
||||
#define MBEDTLS_X509_OID_HAVE_GET_X509_EXT_TYPE
|
||||
/**
|
||||
* \brief Translate an X.509 extension OID into local values
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param ext_type place to store the extension type
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_X509_UNKNOWN_OID
|
||||
*/
|
||||
int mbedtls_x509_oid_get_x509_ext_type(const mbedtls_asn1_buf *oid, int *ext_type);
|
||||
#endif /* MBEDTLS_X509_OID_HAVE_GET_X509_EXT_TYPE */
|
||||
|
||||
#if defined(MBEDTLS_X509_USE_C)
|
||||
/**
|
||||
* \brief Translate an X.509 attribute type OID into the short name
|
||||
* (e.g. the OID for an X520 Common Name into "CN")
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param short_name place to store the string pointer
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_X509_UNKNOWN_OID
|
||||
*/
|
||||
int mbedtls_x509_oid_get_attr_short_name(const mbedtls_asn1_buf *oid, const char **short_name);
|
||||
#endif /* MBEDTLS_X509_USE_C */
|
||||
|
||||
#if defined(MBEDTLS_X509_USE_C)
|
||||
/**
|
||||
* \brief Translate SignatureAlgorithm OID into md_type and pk_type
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param md_alg place to store message digest algorithm
|
||||
* \param pk_alg place to store public key algorithm
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_X509_UNKNOWN_OID
|
||||
*/
|
||||
int mbedtls_x509_oid_get_sig_alg(const mbedtls_asn1_buf *oid,
|
||||
mbedtls_md_type_t *md_alg, mbedtls_pk_sigalg_t *pk_alg);
|
||||
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
/**
|
||||
* \brief Translate SignatureAlgorithm OID into description
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param desc place to store string pointer
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_X509_UNKNOWN_OID
|
||||
*/
|
||||
int mbedtls_x509_oid_get_sig_alg_desc(const mbedtls_asn1_buf *oid, const char **desc);
|
||||
#endif /* !MBEDTLS_X509_REMOVE_INFO */
|
||||
#endif /* MBEDTLS_X509_USE_C */
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_WRITE_C) || defined(MBEDTLS_X509_CSR_WRITE_C)
|
||||
/**
|
||||
* \brief Translate md_type and pk_type into SignatureAlgorithm OID
|
||||
*
|
||||
* \param md_alg message digest algorithm
|
||||
* \param pk_alg public key algorithm
|
||||
* \param oid place to store ASN.1 OID string pointer
|
||||
* \param olen length of the OID
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_X509_UNKNOWN_OID
|
||||
*/
|
||||
int mbedtls_x509_oid_get_oid_by_sig_alg(mbedtls_pk_sigalg_t pk_alg, mbedtls_md_type_t md_alg,
|
||||
const char **oid, size_t *olen);
|
||||
#endif /* MBEDTLS_X509_CRT_WRITE_C || MBEDTLS_X509_CSR_WRITE_C */
|
||||
|
||||
#if (defined(MBEDTLS_X509_USE_C) && defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)) || \
|
||||
defined(MBEDTLS_PKCS7_C)
|
||||
#define MBEDTLS_X509_OID_HAVE_GET_MD_ALG
|
||||
/**
|
||||
* \brief Translate hash algorithm OID into md_type
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param md_alg place to store message digest algorithm
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_X509_UNKNOWN_OID
|
||||
*/
|
||||
int mbedtls_x509_oid_get_md_alg(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg);
|
||||
#endif /* MBEDTLS_X509_OID_HAVE_GET_MD_ALG */
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
/**
|
||||
* \brief Translate Extended Key Usage OID into description
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param desc place to store string pointer
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_X509_UNKNOWN_OID
|
||||
*/
|
||||
int mbedtls_x509_oid_get_extended_key_usage(const mbedtls_asn1_buf *oid, const char **desc);
|
||||
|
||||
/**
|
||||
* \brief Translate certificate policies OID into description
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param desc place to store string pointer
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_X509_UNKNOWN_OID
|
||||
*/
|
||||
int mbedtls_x509_oid_get_certificate_policies(const mbedtls_asn1_buf *oid, const char **desc);
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_X509_REMOVE_INFO */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* x509_oid.h */
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* X.509 internal, common functions for writing
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#include "x509_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_X509_CSR_WRITE_C) || defined(MBEDTLS_X509_CRT_WRITE_C)
|
||||
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/asn1write.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||
#include "mbedtls/pem.h"
|
||||
#endif /* MBEDTLS_PEM_WRITE_C */
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
#include "md_psa.h"
|
||||
|
||||
#define CHECK_OVERFLOW_ADD(a, b) \
|
||||
do \
|
||||
{ \
|
||||
if (a > SIZE_MAX - (b)) \
|
||||
{ \
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA; \
|
||||
} \
|
||||
a += b; \
|
||||
} while (0)
|
||||
|
||||
int mbedtls_x509_write_set_san_common(mbedtls_asn1_named_data **extensions,
|
||||
const mbedtls_x509_san_list *san_list)
|
||||
{
|
||||
int ret = 0;
|
||||
const mbedtls_x509_san_list *cur;
|
||||
unsigned char *buf;
|
||||
unsigned char *p;
|
||||
size_t len;
|
||||
size_t buflen = 0;
|
||||
|
||||
/* Determine the maximum size of the SubjectAltName list */
|
||||
for (cur = san_list; cur != NULL; cur = cur->next) {
|
||||
/* Calculate size of the required buffer */
|
||||
switch (cur->node.type) {
|
||||
case MBEDTLS_X509_SAN_DNS_NAME:
|
||||
case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
|
||||
case MBEDTLS_X509_SAN_IP_ADDRESS:
|
||||
case MBEDTLS_X509_SAN_RFC822_NAME:
|
||||
/* length of value for each name entry,
|
||||
* maximum 4 bytes for the length field,
|
||||
* 1 byte for the tag/type.
|
||||
*/
|
||||
CHECK_OVERFLOW_ADD(buflen, cur->node.san.unstructured_name.len);
|
||||
CHECK_OVERFLOW_ADD(buflen, 4 + 1);
|
||||
break;
|
||||
case MBEDTLS_X509_SAN_DIRECTORY_NAME:
|
||||
{
|
||||
const mbedtls_asn1_named_data *chunk = &cur->node.san.directory_name;
|
||||
while (chunk != NULL) {
|
||||
// Max 4 bytes for length, +1 for tag,
|
||||
// additional 4 max for length, +1 for tag.
|
||||
// See x509_write_name for more information.
|
||||
CHECK_OVERFLOW_ADD(buflen, 4 + 1 + 4 + 1);
|
||||
CHECK_OVERFLOW_ADD(buflen, chunk->oid.len);
|
||||
CHECK_OVERFLOW_ADD(buflen, chunk->val.len);
|
||||
chunk = chunk->next;
|
||||
}
|
||||
CHECK_OVERFLOW_ADD(buflen, 4 + 1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Not supported - return. */
|
||||
return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the extra length field and tag */
|
||||
CHECK_OVERFLOW_ADD(buflen, 4 + 1);
|
||||
|
||||
/* Allocate buffer */
|
||||
buf = mbedtls_calloc(1, buflen);
|
||||
if (buf == NULL) {
|
||||
return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
|
||||
}
|
||||
p = buf + buflen;
|
||||
|
||||
/* Write ASN.1-based structure */
|
||||
cur = san_list;
|
||||
len = 0;
|
||||
while (cur != NULL) {
|
||||
size_t single_san_len = 0;
|
||||
switch (cur->node.type) {
|
||||
case MBEDTLS_X509_SAN_DNS_NAME:
|
||||
case MBEDTLS_X509_SAN_RFC822_NAME:
|
||||
case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
|
||||
case MBEDTLS_X509_SAN_IP_ADDRESS:
|
||||
{
|
||||
const unsigned char *unstructured_name =
|
||||
(const unsigned char *) cur->node.san.unstructured_name.p;
|
||||
size_t unstructured_name_len = cur->node.san.unstructured_name.len;
|
||||
|
||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
|
||||
mbedtls_asn1_write_raw_buffer(
|
||||
&p, buf,
|
||||
unstructured_name, unstructured_name_len));
|
||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, mbedtls_asn1_write_len(
|
||||
&p, buf, unstructured_name_len));
|
||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
|
||||
mbedtls_asn1_write_tag(
|
||||
&p, buf,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC | cur->node.type));
|
||||
}
|
||||
break;
|
||||
case MBEDTLS_X509_SAN_DIRECTORY_NAME:
|
||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
|
||||
mbedtls_x509_write_names(&p, buf,
|
||||
(mbedtls_asn1_named_data *) &
|
||||
cur->node
|
||||
.san.directory_name));
|
||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
|
||||
mbedtls_asn1_write_len(&p, buf, single_san_len));
|
||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
|
||||
mbedtls_asn1_write_tag(&p, buf,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_X509_SAN_DIRECTORY_NAME));
|
||||
break;
|
||||
default:
|
||||
/* Error out on an unsupported SAN */
|
||||
ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
|
||||
goto cleanup;
|
||||
}
|
||||
cur = cur->next;
|
||||
/* check for overflow */
|
||||
if (len > SIZE_MAX - single_san_len) {
|
||||
ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
goto cleanup;
|
||||
}
|
||||
len += single_san_len;
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
|
||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(len,
|
||||
mbedtls_asn1_write_tag(&p, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
ret = mbedtls_x509_set_extension(extensions,
|
||||
MBEDTLS_OID_SUBJECT_ALT_NAME,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_SUBJECT_ALT_NAME),
|
||||
0,
|
||||
buf + buflen - len, len);
|
||||
|
||||
/* If we exceeded the allocated buffer it means that maximum size of the SubjectAltName list
|
||||
* was incorrectly calculated and memory is corrupted. */
|
||||
if (p < buf) {
|
||||
ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
|
||||
}
|
||||
cleanup:
|
||||
mbedtls_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_X509_CSR_WRITE_C || MBEDTLS_X509_CRT_WRITE_C */
|
||||
+637
@@ -0,0 +1,637 @@
|
||||
/*
|
||||
* X.509 certificate writing
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
/*
|
||||
* References:
|
||||
* - certificates: RFC 5280, updated by RFC 6818
|
||||
* - CSRs: PKCS#10 v1.7 aka RFC 2986
|
||||
* - attributes: PKCS#9 v2.0 aka RFC 2985
|
||||
*/
|
||||
|
||||
#include "x509_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_WRITE_C)
|
||||
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/asn1write.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "x509_oid.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||
#include "mbedtls/pem.h"
|
||||
#endif /* MBEDTLS_PEM_WRITE_C */
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_util_internal.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
void mbedtls_x509write_crt_init(mbedtls_x509write_cert *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(mbedtls_x509write_cert));
|
||||
|
||||
ctx->version = MBEDTLS_X509_CRT_VERSION_3;
|
||||
}
|
||||
|
||||
void mbedtls_x509write_crt_free(mbedtls_x509write_cert *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_asn1_free_named_data_list(&ctx->subject);
|
||||
mbedtls_asn1_free_named_data_list(&ctx->issuer);
|
||||
mbedtls_asn1_free_named_data_list(&ctx->extensions);
|
||||
|
||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_x509write_cert));
|
||||
}
|
||||
|
||||
void mbedtls_x509write_crt_set_version(mbedtls_x509write_cert *ctx,
|
||||
int version)
|
||||
{
|
||||
ctx->version = version;
|
||||
}
|
||||
|
||||
void mbedtls_x509write_crt_set_md_alg(mbedtls_x509write_cert *ctx,
|
||||
mbedtls_md_type_t md_alg)
|
||||
{
|
||||
ctx->md_alg = md_alg;
|
||||
}
|
||||
|
||||
void mbedtls_x509write_crt_set_subject_key(mbedtls_x509write_cert *ctx,
|
||||
mbedtls_pk_context *key)
|
||||
{
|
||||
ctx->subject_key = key;
|
||||
}
|
||||
|
||||
void mbedtls_x509write_crt_set_issuer_key(mbedtls_x509write_cert *ctx,
|
||||
mbedtls_pk_context *key)
|
||||
{
|
||||
ctx->issuer_key = key;
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_subject_name(mbedtls_x509write_cert *ctx,
|
||||
const char *subject_name)
|
||||
{
|
||||
mbedtls_asn1_free_named_data_list(&ctx->subject);
|
||||
return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx,
|
||||
const char *issuer_name)
|
||||
{
|
||||
mbedtls_asn1_free_named_data_list(&ctx->issuer);
|
||||
return mbedtls_x509_string_to_names(&ctx->issuer, issuer_name);
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_serial_raw(mbedtls_x509write_cert *ctx,
|
||||
const unsigned char *serial, size_t serial_len)
|
||||
{
|
||||
if (serial_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) {
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ctx->serial_len = serial_len;
|
||||
memcpy(ctx->serial, serial, serial_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_validity(mbedtls_x509write_cert *ctx,
|
||||
const char *not_before,
|
||||
const char *not_after)
|
||||
{
|
||||
if (strlen(not_before) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ||
|
||||
strlen(not_after) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1) {
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
strncpy(ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN);
|
||||
strncpy(ctx->not_after, not_after, MBEDTLS_X509_RFC5280_UTC_TIME_LEN);
|
||||
ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
|
||||
ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_subject_alternative_name(mbedtls_x509write_cert *ctx,
|
||||
const mbedtls_x509_san_list *san_list)
|
||||
{
|
||||
return mbedtls_x509_write_set_san_common(&ctx->extensions, san_list);
|
||||
}
|
||||
|
||||
|
||||
int mbedtls_x509write_crt_set_extension(mbedtls_x509write_cert *ctx,
|
||||
const char *oid, size_t oid_len,
|
||||
int critical,
|
||||
const unsigned char *val, size_t val_len)
|
||||
{
|
||||
return mbedtls_x509_set_extension(&ctx->extensions, oid, oid_len,
|
||||
critical, val, val_len);
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_basic_constraints(mbedtls_x509write_cert *ctx,
|
||||
int is_ca, int max_pathlen)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char buf[9];
|
||||
unsigned char *c = buf + sizeof(buf);
|
||||
size_t len = 0;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
if (is_ca && max_pathlen > 127) {
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (is_ca) {
|
||||
if (max_pathlen >= 0) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(&c, buf,
|
||||
max_pathlen));
|
||||
}
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_bool(&c, buf, 1));
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
return
|
||||
mbedtls_x509write_crt_set_extension(ctx, MBEDTLS_OID_BASIC_CONSTRAINTS,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_BASIC_CONSTRAINTS),
|
||||
is_ca, buf + sizeof(buf) - len, len);
|
||||
}
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_1)
|
||||
static int mbedtls_x509write_crt_set_key_identifier(mbedtls_x509write_cert *ctx,
|
||||
int is_ca,
|
||||
unsigned char tag)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
|
||||
unsigned char *c = buf + sizeof(buf);
|
||||
size_t len = 0;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t hash_length;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_pk_write_pubkey(&c,
|
||||
buf,
|
||||
is_ca ?
|
||||
ctx->issuer_key :
|
||||
ctx->subject_key));
|
||||
|
||||
|
||||
status = psa_hash_compute(PSA_ALG_SHA_1,
|
||||
buf + sizeof(buf) - len,
|
||||
len,
|
||||
buf + sizeof(buf) - 20,
|
||||
20,
|
||||
&hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
}
|
||||
|
||||
c = buf + sizeof(buf) - 20;
|
||||
len = 20;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, tag));
|
||||
|
||||
if (is_ca) { // writes AuthorityKeyIdentifier sequence
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(&c,
|
||||
buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
}
|
||||
|
||||
if (is_ca) {
|
||||
return mbedtls_x509write_crt_set_extension(ctx,
|
||||
MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
|
||||
MBEDTLS_OID_SIZE(
|
||||
MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER),
|
||||
0, buf + sizeof(buf) - len, len);
|
||||
} else {
|
||||
return mbedtls_x509write_crt_set_extension(ctx,
|
||||
MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER,
|
||||
MBEDTLS_OID_SIZE(
|
||||
MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER),
|
||||
0, buf + sizeof(buf) - len, len);
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_subject_key_identifier(mbedtls_x509write_cert *ctx)
|
||||
{
|
||||
return mbedtls_x509write_crt_set_key_identifier(ctx,
|
||||
0,
|
||||
MBEDTLS_ASN1_OCTET_STRING);
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_authority_key_identifier(mbedtls_x509write_cert *ctx)
|
||||
{
|
||||
return mbedtls_x509write_crt_set_key_identifier(ctx,
|
||||
1,
|
||||
(MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0));
|
||||
}
|
||||
#endif /* PSA_WANT_ALG_SHA_1 */
|
||||
|
||||
int mbedtls_x509write_crt_set_key_usage(mbedtls_x509write_cert *ctx,
|
||||
unsigned int key_usage)
|
||||
{
|
||||
unsigned char buf[5] = { 0 }, ku[2] = { 0 };
|
||||
unsigned char *c;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
|
||||
MBEDTLS_X509_KU_NON_REPUDIATION |
|
||||
MBEDTLS_X509_KU_KEY_ENCIPHERMENT |
|
||||
MBEDTLS_X509_KU_DATA_ENCIPHERMENT |
|
||||
MBEDTLS_X509_KU_KEY_AGREEMENT |
|
||||
MBEDTLS_X509_KU_KEY_CERT_SIGN |
|
||||
MBEDTLS_X509_KU_CRL_SIGN |
|
||||
MBEDTLS_X509_KU_ENCIPHER_ONLY |
|
||||
MBEDTLS_X509_KU_DECIPHER_ONLY;
|
||||
|
||||
/* Check that nothing other than the allowed flags is set */
|
||||
if ((key_usage & ~allowed_bits) != 0) {
|
||||
return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
c = buf + 5;
|
||||
MBEDTLS_PUT_UINT16_LE(key_usage, ku, 0);
|
||||
ret = mbedtls_asn1_write_named_bitstring(&c, buf, ku, 9);
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
} else if (ret < 3 || ret > 5) {
|
||||
return MBEDTLS_ERR_X509_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509write_crt_set_extension(ctx, MBEDTLS_OID_KEY_USAGE,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_KEY_USAGE),
|
||||
1, c, (size_t) ret);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_ext_key_usage(mbedtls_x509write_cert *ctx,
|
||||
const mbedtls_asn1_sequence *exts)
|
||||
{
|
||||
unsigned char buf[256];
|
||||
unsigned char *c = buf + sizeof(buf);
|
||||
int ret;
|
||||
size_t len = 0;
|
||||
const mbedtls_asn1_sequence *last_ext = NULL;
|
||||
const mbedtls_asn1_sequence *ext;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
/* We need at least one extension: SEQUENCE SIZE (1..MAX) OF KeyPurposeId */
|
||||
if (exts == NULL) {
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
/* Iterate over exts backwards, so we write them out in the requested order */
|
||||
while (last_ext != exts) {
|
||||
for (ext = exts; ext->next != last_ext; ext = ext->next) {
|
||||
}
|
||||
if (ext->buf.tag != MBEDTLS_ASN1_OID) {
|
||||
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
||||
}
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf, ext->buf.p, ext->buf.len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, ext->buf.len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_OID));
|
||||
last_ext = ext;
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(&c, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
return mbedtls_x509write_crt_set_extension(ctx,
|
||||
MBEDTLS_OID_EXTENDED_KEY_USAGE,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
|
||||
1, c, len);
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_set_ns_cert_type(mbedtls_x509write_cert *ctx,
|
||||
unsigned char ns_cert_type)
|
||||
{
|
||||
unsigned char buf[4] = { 0 };
|
||||
unsigned char *c;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
c = buf + 4;
|
||||
|
||||
ret = mbedtls_asn1_write_named_bitstring(&c, buf, &ns_cert_type, 8);
|
||||
if (ret < 3 || ret > 4) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509write_crt_set_extension(ctx, MBEDTLS_OID_NS_CERT_TYPE,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_NS_CERT_TYPE),
|
||||
0, c, (size_t) ret);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int x509_write_time(unsigned char **p, unsigned char *start,
|
||||
const char *t, size_t size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len = 0;
|
||||
|
||||
/*
|
||||
* write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter)
|
||||
*/
|
||||
if (t[0] < '2' || (t[0] == '2' && t[1] == '0' && t[2] < '5')) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start,
|
||||
(const unsigned char *) t + 2,
|
||||
size - 2));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
|
||||
MBEDTLS_ASN1_UTC_TIME));
|
||||
} else {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start,
|
||||
(const unsigned char *) t,
|
||||
size));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
|
||||
MBEDTLS_ASN1_GENERALIZED_TIME));
|
||||
}
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx,
|
||||
unsigned char *buf, size_t size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const char *sig_oid;
|
||||
size_t sig_oid_len = 0;
|
||||
unsigned char *c, *c2;
|
||||
unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
|
||||
size_t hash_length = 0;
|
||||
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_algorithm_t psa_algorithm;
|
||||
|
||||
size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
|
||||
size_t len = 0;
|
||||
mbedtls_pk_type_t pk_alg;
|
||||
int write_sig_null_par;
|
||||
|
||||
/*
|
||||
* Prepare data to be signed at the end of the target buffer
|
||||
*/
|
||||
c = buf + size;
|
||||
|
||||
/* Signature algorithm needed in TBS, and later for actual signature */
|
||||
|
||||
/* There's no direct way of extracting a signature algorithm
|
||||
* (represented as an element of mbedtls_pk_type_t) from a PK instance. */
|
||||
if (mbedtls_pk_can_do(ctx->issuer_key, MBEDTLS_PK_RSA)) {
|
||||
pk_alg = MBEDTLS_PK_RSA;
|
||||
} else if (mbedtls_pk_can_do(ctx->issuer_key, MBEDTLS_PK_ECDSA)) {
|
||||
pk_alg = MBEDTLS_PK_ECDSA;
|
||||
} else {
|
||||
return MBEDTLS_ERR_X509_INVALID_ALG;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_x509_oid_get_oid_by_sig_alg((mbedtls_pk_sigalg_t) pk_alg, ctx->md_alg,
|
||||
&sig_oid, &sig_oid_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
|
||||
*/
|
||||
|
||||
/* Only for v3 */
|
||||
if (ctx->version == MBEDTLS_X509_CRT_VERSION_3) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_x509_write_extensions(&c,
|
||||
buf, ctx->extensions));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(&c, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(&c, buf,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
|
||||
MBEDTLS_ASN1_CONSTRUCTED | 3));
|
||||
}
|
||||
|
||||
/*
|
||||
* SubjectPublicKeyInfo
|
||||
*/
|
||||
MBEDTLS_ASN1_CHK_ADD(pub_len,
|
||||
mbedtls_pk_write_pubkey_der(ctx->subject_key,
|
||||
buf, (size_t) (c - buf)));
|
||||
c -= pub_len;
|
||||
len += pub_len;
|
||||
|
||||
/*
|
||||
* Subject ::= Name
|
||||
*/
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_x509_write_names(&c, buf,
|
||||
ctx->subject));
|
||||
|
||||
/*
|
||||
* Validity ::= SEQUENCE {
|
||||
* notBefore Time,
|
||||
* notAfter Time }
|
||||
*/
|
||||
sub_len = 0;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(sub_len,
|
||||
x509_write_time(&c, buf, ctx->not_after,
|
||||
MBEDTLS_X509_RFC5280_UTC_TIME_LEN));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(sub_len,
|
||||
x509_write_time(&c, buf, ctx->not_before,
|
||||
MBEDTLS_X509_RFC5280_UTC_TIME_LEN));
|
||||
|
||||
len += sub_len;
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, sub_len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(&c, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
/*
|
||||
* Issuer ::= Name
|
||||
*/
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_names(&c, buf,
|
||||
ctx->issuer));
|
||||
|
||||
/*
|
||||
* Signature ::= AlgorithmIdentifier
|
||||
*/
|
||||
if (pk_alg == MBEDTLS_PK_ECDSA) {
|
||||
/*
|
||||
* The AlgorithmIdentifier's parameters field must be absent for DSA/ECDSA signature
|
||||
* algorithms, see https://www.rfc-editor.org/rfc/rfc5480#page-17 and
|
||||
* https://www.rfc-editor.org/rfc/rfc5758#section-3.
|
||||
*/
|
||||
write_sig_null_par = 0;
|
||||
} else {
|
||||
write_sig_null_par = 1;
|
||||
}
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_algorithm_identifier_ext(&c, buf,
|
||||
sig_oid, strlen(sig_oid),
|
||||
0, write_sig_null_par));
|
||||
|
||||
/*
|
||||
* Serial ::= INTEGER
|
||||
*
|
||||
* Written data is:
|
||||
* - "ctx->serial_len" bytes for the raw serial buffer
|
||||
* - if MSb of "serial" is 1, then prepend an extra 0x00 byte
|
||||
* - 1 byte for the length
|
||||
* - 1 byte for the TAG
|
||||
*/
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf,
|
||||
ctx->serial, ctx->serial_len));
|
||||
if (*c & 0x80) {
|
||||
if (c - buf < 1) {
|
||||
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
|
||||
}
|
||||
*(--c) = 0x0;
|
||||
len++;
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf,
|
||||
ctx->serial_len + 1));
|
||||
} else {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf,
|
||||
ctx->serial_len));
|
||||
}
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf,
|
||||
MBEDTLS_ASN1_INTEGER));
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
|
||||
*/
|
||||
|
||||
/* Can be omitted for v1 */
|
||||
if (ctx->version != MBEDTLS_X509_CRT_VERSION_1) {
|
||||
sub_len = 0;
|
||||
MBEDTLS_ASN1_CHK_ADD(sub_len,
|
||||
mbedtls_asn1_write_int(&c, buf, ctx->version));
|
||||
len += sub_len;
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_len(&c, buf, sub_len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(&c, buf,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
|
||||
MBEDTLS_ASN1_CONSTRUCTED | 0));
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
/*
|
||||
* Make signature
|
||||
*/
|
||||
|
||||
/* Compute hash of CRT. */
|
||||
psa_algorithm = mbedtls_md_psa_alg_from_type(ctx->md_alg);
|
||||
|
||||
status = psa_hash_compute(psa_algorithm,
|
||||
c,
|
||||
len,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
&hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
}
|
||||
|
||||
|
||||
if ((ret = mbedtls_pk_sign(ctx->issuer_key, ctx->md_alg,
|
||||
hash, hash_length, sig, sizeof(sig), &sig_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Move CRT to the front of the buffer to have space
|
||||
* for the signature. */
|
||||
memmove(buf, c, len);
|
||||
c = buf + len;
|
||||
|
||||
/* Add signature at the end of the buffer,
|
||||
* making sure that it doesn't underflow
|
||||
* into the CRT buffer. */
|
||||
c2 = buf + size;
|
||||
MBEDTLS_ASN1_CHK_ADD(sig_and_oid_len, mbedtls_x509_write_sig(&c2, c,
|
||||
sig_oid, sig_oid_len,
|
||||
sig, sig_len,
|
||||
(mbedtls_pk_sigalg_t) pk_alg));
|
||||
|
||||
/*
|
||||
* Memory layout after this step:
|
||||
*
|
||||
* buf c=buf+len c2 buf+size
|
||||
* [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm]
|
||||
*/
|
||||
|
||||
/* Move raw CRT to just before the signature. */
|
||||
c = c2 - len;
|
||||
memmove(c, buf, len);
|
||||
|
||||
len += sig_and_oid_len;
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n"
|
||||
#define PEM_END_CRT "-----END CERTIFICATE-----\n"
|
||||
|
||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||
int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *crt,
|
||||
unsigned char *buf, size_t size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t olen;
|
||||
|
||||
if ((ret = mbedtls_x509write_crt_der(crt, buf, size)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_CRT, PEM_END_CRT,
|
||||
buf + size - ret, ret,
|
||||
buf, size, &olen)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PEM_WRITE_C */
|
||||
|
||||
#endif /* MBEDTLS_X509_CRT_WRITE_C */
|
||||
+316
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* X.509 Certificate Signing Request writing
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
/*
|
||||
* References:
|
||||
* - CSRs: PKCS#10 v1.7 aka RFC 2986
|
||||
* - attributes: PKCS#9 v2.0 aka RFC 2985
|
||||
*/
|
||||
|
||||
#include "x509_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_X509_CSR_WRITE_C)
|
||||
|
||||
#include "mbedtls/x509_csr.h"
|
||||
#include "mbedtls/asn1write.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "x509_oid.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_util_internal.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||
#include "mbedtls/pem.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
void mbedtls_x509write_csr_init(mbedtls_x509write_csr *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(mbedtls_x509write_csr));
|
||||
}
|
||||
|
||||
void mbedtls_x509write_csr_free(mbedtls_x509write_csr *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_asn1_free_named_data_list(&ctx->subject);
|
||||
mbedtls_asn1_free_named_data_list(&ctx->extensions);
|
||||
|
||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_x509write_csr));
|
||||
}
|
||||
|
||||
void mbedtls_x509write_csr_set_md_alg(mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg)
|
||||
{
|
||||
ctx->md_alg = md_alg;
|
||||
}
|
||||
|
||||
void mbedtls_x509write_csr_set_key(mbedtls_x509write_csr *ctx, mbedtls_pk_context *key)
|
||||
{
|
||||
ctx->key = key;
|
||||
}
|
||||
|
||||
int mbedtls_x509write_csr_set_subject_name(mbedtls_x509write_csr *ctx,
|
||||
const char *subject_name)
|
||||
{
|
||||
mbedtls_asn1_free_named_data_list(&ctx->subject);
|
||||
return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
|
||||
}
|
||||
|
||||
int mbedtls_x509write_csr_set_extension(mbedtls_x509write_csr *ctx,
|
||||
const char *oid, size_t oid_len,
|
||||
int critical,
|
||||
const unsigned char *val, size_t val_len)
|
||||
{
|
||||
return mbedtls_x509_set_extension(&ctx->extensions, oid, oid_len,
|
||||
critical, val, val_len);
|
||||
}
|
||||
|
||||
int mbedtls_x509write_csr_set_subject_alternative_name(mbedtls_x509write_csr *ctx,
|
||||
const mbedtls_x509_san_list *san_list)
|
||||
{
|
||||
return mbedtls_x509_write_set_san_common(&ctx->extensions, san_list);
|
||||
}
|
||||
|
||||
int mbedtls_x509write_csr_set_key_usage(mbedtls_x509write_csr *ctx, unsigned char key_usage)
|
||||
{
|
||||
unsigned char buf[4] = { 0 };
|
||||
unsigned char *c;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
c = buf + 4;
|
||||
|
||||
ret = mbedtls_asn1_write_named_bitstring(&c, buf, &key_usage, 8);
|
||||
if (ret < 3 || ret > 4) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509write_csr_set_extension(ctx, MBEDTLS_OID_KEY_USAGE,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_KEY_USAGE),
|
||||
0, c, (size_t) ret);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_x509write_csr_set_ns_cert_type(mbedtls_x509write_csr *ctx,
|
||||
unsigned char ns_cert_type)
|
||||
{
|
||||
unsigned char buf[4] = { 0 };
|
||||
unsigned char *c;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
c = buf + 4;
|
||||
|
||||
ret = mbedtls_asn1_write_named_bitstring(&c, buf, &ns_cert_type, 8);
|
||||
if (ret < 3 || ret > 4) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509write_csr_set_extension(ctx, MBEDTLS_OID_NS_CERT_TYPE,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_NS_CERT_TYPE),
|
||||
0, c, (size_t) ret);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int x509write_csr_der_internal(mbedtls_x509write_csr *ctx,
|
||||
unsigned char *buf,
|
||||
size_t size,
|
||||
unsigned char *sig, size_t sig_size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const char *sig_oid;
|
||||
size_t sig_oid_len = 0;
|
||||
unsigned char *c, *c2;
|
||||
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
||||
size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
|
||||
size_t len = 0;
|
||||
mbedtls_pk_type_t pk_alg;
|
||||
size_t hash_len;
|
||||
psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(ctx->md_alg);
|
||||
|
||||
/* Write the CSR backwards starting from the end of buf */
|
||||
c = buf + size;
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_extensions(&c, buf,
|
||||
ctx->extensions));
|
||||
|
||||
if (len) {
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(
|
||||
&c, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(
|
||||
&c, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_oid(
|
||||
&c, buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_PKCS9_CSR_EXT_REQ)));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(
|
||||
&c, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(
|
||||
&c, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_pk_write_pubkey_der(ctx->key,
|
||||
buf, (size_t) (c - buf)));
|
||||
c -= pub_len;
|
||||
len += pub_len;
|
||||
|
||||
/*
|
||||
* Subject ::= Name
|
||||
*/
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_names(&c, buf,
|
||||
ctx->subject));
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
|
||||
*/
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(&c, buf, 0));
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(
|
||||
&c, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
/*
|
||||
* Sign the written CSR data into the sig buffer
|
||||
* Note: hash errors can happen only after an internal error
|
||||
*/
|
||||
if (psa_hash_compute(hash_alg,
|
||||
c,
|
||||
len,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
&hash_len) != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
}
|
||||
if ((ret = mbedtls_pk_sign(ctx->key, ctx->md_alg, hash, 0,
|
||||
sig, sig_size, &sig_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mbedtls_pk_can_do(ctx->key, MBEDTLS_PK_RSA)) {
|
||||
pk_alg = MBEDTLS_PK_RSA;
|
||||
} else if (mbedtls_pk_can_do(ctx->key, MBEDTLS_PK_ECDSA)) {
|
||||
pk_alg = MBEDTLS_PK_ECDSA;
|
||||
} else {
|
||||
return MBEDTLS_ERR_X509_INVALID_ALG;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_x509_oid_get_oid_by_sig_alg((mbedtls_pk_sigalg_t) pk_alg, ctx->md_alg,
|
||||
&sig_oid, &sig_oid_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the written CSR data to the start of buf to create space for
|
||||
* writing the signature into buf.
|
||||
*/
|
||||
memmove(buf, c, len);
|
||||
|
||||
/*
|
||||
* Write sig and its OID into buf backwards from the end of buf.
|
||||
* Note: mbedtls_x509_write_sig will check for c2 - ( buf + len ) < sig_len
|
||||
* and return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if needed.
|
||||
*/
|
||||
c2 = buf + size;
|
||||
MBEDTLS_ASN1_CHK_ADD(sig_and_oid_len,
|
||||
mbedtls_x509_write_sig(&c2, buf + len, sig_oid, sig_oid_len,
|
||||
sig, sig_len, (mbedtls_pk_sigalg_t) pk_alg));
|
||||
|
||||
/*
|
||||
* Compact the space between the CSR data and signature by moving the
|
||||
* CSR data to the start of the signature.
|
||||
*/
|
||||
c2 -= len;
|
||||
memmove(c2, buf, len);
|
||||
|
||||
/* ASN encode the total size and tag the CSR data with it. */
|
||||
len += sig_and_oid_len;
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c2, buf, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len,
|
||||
mbedtls_asn1_write_tag(
|
||||
&c2, buf,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
/* Zero the unused bytes at the start of buf */
|
||||
memset(buf, 0, (size_t) (c2 - buf));
|
||||
|
||||
return (int) len;
|
||||
}
|
||||
|
||||
int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf,
|
||||
size_t size)
|
||||
{
|
||||
int ret;
|
||||
unsigned char *sig;
|
||||
|
||||
if ((sig = mbedtls_calloc(1, MBEDTLS_PK_SIGNATURE_MAX_SIZE)) == NULL) {
|
||||
return MBEDTLS_ERR_X509_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
ret = x509write_csr_der_internal(ctx, buf, size,
|
||||
sig, MBEDTLS_PK_SIGNATURE_MAX_SIZE);
|
||||
|
||||
mbedtls_free(sig);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n"
|
||||
#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n"
|
||||
|
||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||
int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t olen = 0;
|
||||
|
||||
if ((ret = mbedtls_x509write_csr_der(ctx, buf, size)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_CSR, PEM_END_CSR,
|
||||
buf + size - ret,
|
||||
ret, buf, size, &olen)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_PEM_WRITE_C */
|
||||
|
||||
#endif /* MBEDTLS_X509_CSR_WRITE_C */
|
||||
Reference in New Issue
Block a user