Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minimal support for ssl module using Mbed TLS and sockets #929

Merged
merged 1 commit into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-and-test-macos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
submodules: 'recursive'

- name: "Install deps"
run: brew install gperf doxygen erlang@${{ matrix.otp }} ninja
run: brew install gperf doxygen erlang@${{ matrix.otp }} ninja mbedtls

# Builder info
- name: "System info"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-and-test-on-freebsd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
echo "%%"
echo "**freebsd-version:**"
freebsd-version
sudo pkg install -y cmake gperf erlang elixir
sudo pkg install -y cmake gperf erlang elixir mbedtls
echo "**uname:**"
uname -a
echo "**C Compiler version:**"
Expand All @@ -73,7 +73,7 @@ jobs:
echo "%%"
mkdir build
cd build
cmake ..
cmake .. -DMBEDTLS_ROOT_DIR=/usr/local
echo "%%"
echo "%% Building AtomVM ..."
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-and-test-other.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
apt update &&
apt install -y -t stretch-backports-sloppy libarchive13 &&
apt install -y -t stretch-backports cmake &&
apt install -y file gcc g++ binutils make doxygen gperf zlib1g-dev libssl-dev
apt install -y file gcc g++ binutils make doxygen gperf zlib1g-dev libssl-dev libmbedtls-dev

- arch: "arm32v7"
platform: "arm/v7"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-and-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ jobs:
cmake_opts_other: "-DOPENSSL_CRYPTO_LIBRARY=/usr/lib/i386-linux-gnu/libcrypto.so -DAVM_CREATE_STACKTRACES=off"
arch: "i386"
compiler_pkgs: "gcc-10 g++-10 gcc-10-multilib g++-10-multilib libc6-dev-i386
libc6-dbg:i386 zlib1g-dev:i386 libssl-dev:i386"
libc6-dbg:i386 zlib1g-dev:i386 libssl-dev:i386 libmbedtls-dev:i386"

env:
CC: ${{ matrix.cc }}
Expand Down Expand Up @@ -202,7 +202,7 @@ jobs:
run: sudo apt update -y

- name: "Install deps"
run: sudo apt install -y ${{ matrix.compiler_pkgs}} cmake gperf zlib1g-dev doxygen valgrind
run: sudo apt install -y ${{ matrix.compiler_pkgs}} cmake gperf zlib1g-dev doxygen valgrind libmbedtls-dev

# Builder info
- name: "System info"
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added support for interrupts to STM32 GPIO port driver.
- Added suppoprt for PicoW extra gpio pins (led) to the gpio driver.
- Added support for `net:getaddrinfo/1,2`
- Added minimal support for the OTP `ssl` interface.

## [0.6.0-alpha.1] - 2023-10-09

Expand Down
97 changes: 97 additions & 0 deletions CMakeModules/MbedTLS.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#
# This file is part of AtomVM.
#
# Copyright 2023 Paul Guyot <pguyot@kallisys.net>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#

# Find MbedTLS
# Search for MbedTLS 2.x or 3.x and define libraries like MbedTLS 3.x does.

# This script is not called FindMbedTLS.cmake because it would conflict with
# installed MbedTLS 3.x

# If MBEDTLS_ROOT_DIR is set, no heuristic is applied.
# It must be set to the parent directory of include/mbedtls/version.h
# Libraries are at ${MBEDTLS_LIBRARIES_DIR} or, if unset, ${MBEDTLS_ROOT_DIR}/lib/

# If MBEDTLS_ROOT_DIR is not set, apply the following heuristic:
# Try to find mbedtls 3.x CMake package with find_package
# If it doesn't work, search for MBEDTLS_VERSION_NUMBER symbol as well as
# the three libraries we need with check_symbol_exists and find_library

if (MBEDTLS_ROOT_DIR)
set(MbedTLS_FOUND TRUE)
if (NOT MBEDTLS_LIBRARIES_DIR)
set(MBEDTLS_LIBRARIES_DIR ${MBEDTLS_ROOT_DIR}/lib)
endif()
message(STATUS "Will use MbedTLS from ${MBEDTLS_ROOT_DIR} and ${MBEDTLS_LIBRARIES_DIR}")

add_library(MbedTLS::mbedcrypto SHARED IMPORTED)
set_target_properties(MbedTLS::mbedcrypto PROPERTIES
IMPORTED_LOCATION "${MBEDTLS_LIBRARIES_DIR}/libmbedcrypto${CMAKE_SHARED_LIBRARY_SUFFIX}"
INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_ROOT_DIR}/include/"
)

add_library(MbedTLS::mbedx509 SHARED IMPORTED)
set_target_properties(MbedTLS::mbedx509 PROPERTIES
IMPORTED_LOCATION "${MBEDTLS_LIBRARIES_DIR}/libmbedx509${CMAKE_SHARED_LIBRARY_SUFFIX}"
INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_ROOT_DIR}/include/"
INTERFACE_LINK_LIBRARIES "MbedTLS::mbedcrypto"
)

add_library(MbedTLS::mbedtls SHARED IMPORTED)
set_target_properties(MbedTLS::mbedtls PROPERTIES
IMPORTED_LOCATION "${MBEDTLS_LIBRARIES_DIR}/libmbedtls${CMAKE_SHARED_LIBRARY_SUFFIX}"
INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_ROOT_DIR}/include/"
INTERFACE_LINK_LIBRARIES "MbedTLS::mbedx509"
)
else()
# MbedTLS 3.x is installed as a CMake package
find_package(MbedTLS QUIET)
if (MbedTLS_FOUND)
message(STATUS "Found MbedTLS package ${MbedTLS_FOUND}")
else()
include(CheckSymbolExists)
check_symbol_exists(MBEDTLS_VERSION_NUMBER "mbedtls/version.h" HAVE_MBEDTLS_VERSION_NUMBER)
find_library(MBEDCRYPTO mbedcrypto)
find_library(MBEDX509 mbedx509)
find_library(MBEDTLS mbedtls)
if (HAVE_MBEDTLS_VERSION_NUMBER
AND NOT ${MBEDCRYPTO} STREQUAL "MBEDCRYPTO-NOTFOUND"
AND NOT ${MBEDX509} STREQUAL "MBEDX509-NOTFOUND"
AND NOT ${MBEDTLS} STREQUAL "MBEDTLS-NOTFOUND")
message(STATUS "Found MbedTLS with mbedcrypto ${MBEDCRYPTO}, mbedx509 ${MBEDX509} and mbedtls ${MBEDTLS}")
set(MbedTLS_FOUND TRUE)
add_library(MbedTLS::mbedcrypto SHARED IMPORTED)
set_target_properties(MbedTLS::mbedcrypto PROPERTIES
IMPORTED_LOCATION "${MBEDCRYPTO}"
)

add_library(MbedTLS::mbedx509 SHARED IMPORTED)
set_target_properties(MbedTLS::mbedx509 PROPERTIES
IMPORTED_LOCATION "${MBEDX509}"
INTERFACE_LINK_LIBRARIES "MbedTLS::mbedcrypto"
)

add_library(MbedTLS::mbedtls SHARED IMPORTED)
set_target_properties(MbedTLS::mbedtls PROPERTIES
IMPORTED_LOCATION "${MBEDTLS}"
INTERFACE_LINK_LIBRARIES "MbedTLS::mbedx509"
)
endif()
endif()
endif()
1 change: 1 addition & 0 deletions README.Md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Required for building:
* gperf ([GNU Perfect Hash Function Generator](https://www.gnu.org/software/gperf/manual/gperf.html))
* erlc ([erlang compiler](https://www.erlang.org/))
* elixirc ([elixir compiler](https://elixir-lang.org))
* Mbed TLS ([portable TLS library, optionally required to support SSL](https://www.trustedfirmware.org/projects/mbed-tls/))
* zlib ([zlib compression and decompression library](https://zlib.net/))

Documentation and Coverage:
Expand Down
1 change: 1 addition & 0 deletions doc/src/build-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ The following software is required in order to build AtomVM in generic UNIX syst
* `make`
* `gperf`
* `zlib`
* `Mbed TLS`
* Erlang/OTP compiler (`erlc`)
* Elixir compiler

Expand Down
1 change: 1 addition & 0 deletions libs/estdlib/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ set(ERLANG_MODULES
logger_std_h
proplists
socket
ssl
string
timer
unicode
Expand Down
2 changes: 1 addition & 1 deletion libs/estdlib/src/gen_tcp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
%% @end
%%-----------------------------------------------------------------------------
-spec connect(
Address :: inet:address() | inet:hostname(),
Address :: inet:ip_address() | inet:hostname(),
Port :: inet:port_number(),
Options :: [connect_option()]
) ->
Expand Down
6 changes: 3 additions & 3 deletions libs/estdlib/src/gen_udp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ open(PortNum, Options) ->
%%-----------------------------------------------------------------------------
-spec send(
Socket :: inet:socket(),
Address :: inet:address(),
Address :: inet:ip_address(),
PortNum :: inet:port_number(),
Packet :: packet()
) -> ok | {error, reason()}.
Expand All @@ -121,7 +121,7 @@ send(Socket, Address, PortNum, Packet) ->
%% @end
%%-----------------------------------------------------------------------------
-spec recv(Socket :: inet:socket(), Length :: non_neg_integer()) ->
{ok, {inet:address(), inet:port_number(), packet()}} | {error, reason()}.
{ok, {inet:ip_address(), inet:port_number(), packet()}} | {error, reason()}.
recv(Socket, Length) ->
recv(Socket, Length, infinity).

Expand All @@ -143,7 +143,7 @@ recv(Socket, Length) ->
%% @end
%%-----------------------------------------------------------------------------
-spec recv(Socket :: inet:socket(), Length :: non_neg_integer(), Timeout :: timeout()) ->
{ok, {inet:address(), inet:port_number(), packet()}} | {error, reason()}.
{ok, {inet:ip_address(), inet:port_number(), packet()}} | {error, reason()}.
recv(Socket, Length, Timeout) ->
call(Socket, {recvfrom, Length, Timeout}).

Expand Down
13 changes: 7 additions & 6 deletions libs/estdlib/src/inet.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@

-type port_number() :: 0..65535.
-type socket() :: pid().
-type address() :: ipv4_address().
-type ipv4_address() :: {octet(), octet(), octet(), octet()}.
-type octet() :: 0..255.
-type ip_address() :: ip4_address().
-type ip4_address() :: {0..255, 0..255, 0..255, 0..255}.
-type hostname() :: iodata().

-export_type([socket/0, port_number/0, address/0, ipv4_address/0, octet/0, hostname/0]).
-export_type([socket/0, port_number/0, ip_address/0, ip4_address/0, hostname/0]).

%%-----------------------------------------------------------------------------
%% @param Socket the socket from which to obtain the port number
Expand Down Expand Up @@ -61,7 +60,8 @@ close(Socket) ->
%% This function should be called on a running socket instance.
%% @end
%%-----------------------------------------------------------------------------
-spec sockname(Socket :: socket()) -> {ok, {address(), port_number()}} | {error, Reason :: term()}.
-spec sockname(Socket :: socket()) ->
{ok, {ip_address(), port_number()}} | {error, Reason :: term()}.
sockname(Socket) ->
call(Socket, {sockname}).

Expand All @@ -72,7 +72,8 @@ sockname(Socket) ->
%% This function should be called on a running socket instance.
%% @end
%%-----------------------------------------------------------------------------
-spec peername(Socket :: socket()) -> {ok, {address(), port_number()}} | {error, Reason :: term()}.
-spec peername(Socket :: socket()) ->
{ok, {ip_address(), port_number()}} | {error, Reason :: term()}.
peername(Socket) ->
call(Socket, {peername}).

Expand Down
Loading