- unified HAL with lib60870 and libtase2 (LIB61850-261)

pull/356/head
Michael Zillgith 4 years ago
parent 263c34f016
commit 6b9437b8c0

@ -1,25 +1,10 @@
/*
* hal_base.h
*
* Copyright 2018 MZ Automation GmbH
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850 and lib60870.
*
* libpal is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libpal is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libpal. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* for libiec61850, libmms, and lib60870.
*/
#ifndef HAL_INC_HAL_BASE_H_

@ -1,24 +1,10 @@
/*
* ethernet_hal.h
*
* Copyright 2013, 2014 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#ifndef ETHERNET_HAL_H_

@ -1,24 +1,10 @@
/*
* filesystem_hal.h
*
* Copyright 2014 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#ifndef FILESYSTEM_HAL_H_

@ -1,24 +1,10 @@
/*
* hal_serial.h
*
* Copyright 2017 MZ Automation GmbH
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of lib60870-C
*
* lib60870-C is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lib60870-C is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lib60870-C. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#ifndef SRC_IEC60870_LINK_LAYER_SERIAL_PORT_H_

@ -1,24 +1,10 @@
/*
* socket_hal.h
*
* Copyright 2013-2020 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#ifndef SOCKET_HAL_H_
@ -242,6 +228,20 @@ TcpSocket_create(void);
PAL_API void
Socket_setConnectTimeout(Socket self, uint32_t timeoutInMs);
/**
* \brief bind a socket to a particular IP address and port (for TcpSocket)
*
* NOTE: Don't use the socket when this functions returns false!
*
* \param self the client socket instance
* \param srcAddress the local IP address or hostname as C string
* \param srcPort the local TCP port to use. When < 1 the OS will chose the TCP port to use.
*
* \return true in case of success, false otherwise
*/
PAL_API bool
Socket_bind(Socket self, const char* srcAddress, int srcPort);
/**
* \brief connect to a server
*

@ -3,24 +3,10 @@
*
* Multi-threading abstraction layer
*
* Copyright 2013-2018 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#ifndef THREAD_HAL_H_

@ -1,24 +1,10 @@
/*
* time.c
*
* Copyright 2013-2020 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#ifndef HAL_C_

@ -1,24 +1,10 @@
/*
* lib_memory.h
*
* Copyright 2014 Michael Zillgith
* Copyright 2014-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#ifndef MEMORY_H_
@ -40,6 +26,8 @@
extern "C" {
#endif
#include <stdlib.h>
typedef void
(*MemoryExceptionHandler) (void* parameter);

@ -1,24 +1,10 @@
/*
* platform_endian.h
*
* Copyright 2013-2018 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#ifndef ENDIAN_H_

@ -3,7 +3,7 @@
*
* TLS Configuration API for protocol stacks using TCP/IP
*
* Copyright 2017-2018 MZ Automation GmbH
* Copyright 2017-2021 Michael Zillgith
*
* Abstraction layer for configuration of different TLS implementations
*
@ -90,21 +90,64 @@ TLSConfiguration_setOwnCertificate(TLSConfiguration self, uint8_t* certificate,
PAL_API bool
TLSConfiguration_setOwnCertificateFromFile(TLSConfiguration self, const char* filename);
/**
* \brief Set the own private key from a byte buffer
*
* \param key the private key to use
* \param keyLen the length of the key
* \param password the password of the key or null if the key is not password protected
*
* \return true, when the key was set, false otherwise (e.g. unknown key format)
*/
PAL_API bool
TLSConfiguration_setOwnKey(TLSConfiguration self, uint8_t* key, int keyLen, const char* keyPassword);
/**
* \brief Set the own private key from a key file
*
* \param filename filename/path of the key file
* \param password the password of the key or null if the key is not password protected
*
* \return true, when the key was set, false otherwise (e.g. unknown key format)
*/
PAL_API bool
TLSConfiguration_setOwnKeyFromFile(TLSConfiguration self, const char* filename, const char* keyPassword);
/**
* Add a certificate to the list of allowed peer certificates from a byte buffer
*
* \param certificate the certificate buffer
* \param certLen the length of the certificate buffer
* \return true, when the certificate was set, false otherwise (e.g. unknown certificate format)
*/
PAL_API bool
TLSConfiguration_addAllowedCertificate(TLSConfiguration self, uint8_t* certifcate, int certLen);
TLSConfiguration_addAllowedCertificate(TLSConfiguration self, uint8_t* certificate, int certLen);
/**
* \brief Add a certificate to the list of allowed peer certificates
*
* \param filename filename of the certificate file
* \return true, when the certificate was set, false otherwise (e.g. unknown certificate format)
*/
PAL_API bool
TLSConfiguration_addAllowedCertificateFromFile(TLSConfiguration self, const char* filename);
/**
* \brief Add a CA certificate used to validate peer certificates from a byte buffer
*
* \param certificate the certificate buffer
* \param certLen the length of the certificate buffer
* \return true, when the certificate was set, false otherwise (e.g. unknown certificate format)
*/
PAL_API bool
TLSConfiguration_addCACertificate(TLSConfiguration self, uint8_t* certifcate, int certLen);
TLSConfiguration_addCACertificate(TLSConfiguration self, uint8_t* certificate, int certLen);
/**
* \brief Add a CA certificate used to validate peer certificates from a file
*
* \param filename filename of the certificate file
* \return true, when the certificate was set, false otherwise (e.g. unknown certificate format)
*/
PAL_API bool
TLSConfiguration_addCACertificateFromFile(TLSConfiguration self, const char* filename);
@ -118,6 +161,51 @@ TLSConfiguration_addCACertificateFromFile(TLSConfiguration self, const char* fil
PAL_API void
TLSConfiguration_setRenegotiationTime(TLSConfiguration self, int timeInMs);
typedef enum {
TLS_VERSION_NOT_SELECTED = 0,
TLS_VERSION_SSL_3_0 = 3,
TLS_VERSION_TLS_1_0 = 4,
TLS_VERSION_TLS_1_1 = 5,
TLS_VERSION_TLS_1_2 = 6,
TLS_VERSION_TLS_1_3 = 7
} TLSConfigVersion;
/**
* \brief Set minimal allowed TLS version to use
*/
PAL_API void
TLSConfiguration_setMinTlsVersion(TLSConfiguration self, TLSConfigVersion version);
/**
* \brief Set maximal allowed TLS version to use
*/
PAL_API void
TLSConfiguration_setMaxTlsVersion(TLSConfiguration self, TLSConfigVersion version);
/**
* \brief Add a CRL (certificate revocation list) from buffer
*
* \param crl the buffer containing the CRL
* \param crlLen the length of the CRL buffer
* \return true, when the CRL was imported, false otherwise (e.g. unknown format)
*/
PAL_API bool
TLSConfiguration_addCRL(TLSConfiguration self, uint8_t* crl, int crlLen);
/**
* \brief Add a CRL (certificate revocation list) from a file
*
* \param filename filename of the CRL file
* \return true, when the CRL was imported, false otherwise (e.g. unknown format)
*/
PAL_API bool
TLSConfiguration_addCRLFromFile(TLSConfiguration self, const char* filename);
/**
* Release all resource allocated by the TLSConfiguration instance
*
* NOTE: Do not use the object after calling this function!
*/
PAL_API void
TLSConfiguration_destroy(TLSConfiguration self);

@ -3,7 +3,7 @@
*
* TLS socket API for protocol libraries using TCP/IP
*
* Copyright 2017-2020 Michael Zillgith, MZ Automation GmbH
* Copyright 2017-2021 Michael Zillgith, MZ Automation GmbH
*
* Abstraction layer for different TLS implementations
*

@ -1,24 +1,10 @@
/*
* lib_memory.c
*
* Copyright 2014-2018 Michael Zillgith
* Copyright 2014-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#include <stdlib.h>

@ -1,24 +1,10 @@
/*
* serial_port_linux.c
*
* Copyright 2017 MZ Automation GmbH
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of lib60870-C
*
* lib60870-C is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lib60870-C is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lib60870-C. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#include "lib_memory.h"

@ -1,24 +1,10 @@
/*
* serial_port_win32.c
*
* Copyright 2017 MZ Automation GmbH
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of lib60870-C
*
* lib60870-C is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lib60870-C is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lib60870-C. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#include <stdint.h>

@ -1,25 +1,10 @@
/*
* socket_bsd.c
*
* Copyright 2013-2020 Michael Zillgith
* contributions by Michael Clausen (School of engineering Valais).
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#include "hal_socket.h"
@ -199,7 +184,7 @@ Socket_activateTcpKeepAlive(Socket self, int idleTime, int interval, int count)
}
static bool
prepareServerAddress(const char* address, int port, struct sockaddr_in* sockaddr)
prepareAddress(const char* address, int port, struct sockaddr_in* sockaddr)
{
memset((char *) sockaddr , 0, sizeof(struct sockaddr_in));
@ -246,7 +231,7 @@ TcpServerSocket_create(const char* address, int port)
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) {
struct sockaddr_in serverAddress;
if (!prepareServerAddress(address, port, &serverAddress)) {
if (!prepareAddress(address, port, &serverAddress)) {
close(fd);
return NULL;
}
@ -257,7 +242,7 @@ TcpServerSocket_create(const char* address, int port)
if (bind(fd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) >= 0) {
serverSocket = (ServerSocket) GLOBAL_MALLOC(sizeof(struct sServerSocket));
serverSocket->fd = fd;
serverSocket->backLog = 0;
serverSocket->backLog = 2;
setSocketNonBlocking((Socket) serverSocket);
}
@ -345,7 +330,7 @@ ServerSocket_destroy(ServerSocket self)
Socket
TcpSocket_create()
{
Socket self = NULL;
Socket self = (Socket)NULL;
int sock = socket(AF_INET, SOCK_STREAM, 0);
@ -368,7 +353,6 @@ TcpSocket_create()
if (DEBUG_SOCKET)
printf("SOCKET: out of memory\n");
}
}
else {
if (DEBUG_SOCKET)
@ -385,15 +369,24 @@ Socket_setConnectTimeout(Socket self, uint32_t timeoutInMs)
}
bool
Socket_setLocalAddress(Socket self, const char* address, int port)
Socket_bind(Socket self, const char* srcAddress, int srcPort)
{
struct sockaddr_in clientAddress;
struct sockaddr_in localAddress;
if (!prepareServerAddress(address, port, &clientAddress))
if (!prepareAddress(srcAddress, srcPort, &localAddress))
return false;
if (bind(self->fd, (struct sockaddr *) &clientAddress, sizeof(clientAddress)) != 0)
int result = bind(self->fd, (struct sockaddr*)&localAddress, sizeof(localAddress));
if (result == -1) {
if (DEBUG_SOCKET)
printf("SOCKET: failed to bind TCP socket (errno=%i)\n", errno);
close(self->fd);
self->fd = -1;
return false;
}
return true;
}

@ -1,34 +1,21 @@
/*
* socket_linux.c
*
* Copyright 2013-2020 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#include "hal_socket.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
@ -215,7 +202,7 @@ Socket_activateTcpKeepAlive(Socket self, int idleTime, int interval, int count)
}
static bool
prepareServerAddress(const char* address, int port, struct sockaddr_in* sockaddr)
prepareAddress(const char* address, int port, struct sockaddr_in* sockaddr)
{
bool retVal = true;
@ -231,6 +218,10 @@ prepareServerAddress(const char* address, int port, struct sockaddr_in* sockaddr
result = getaddrinfo(address, NULL, &addressHints, &lookupResult);
if (result != 0) {
if (DEBUG_SOCKET)
printf("SOCKET: getaddrinfo failed (code=%i)\n", result);
retVal = false;
goto exit_function;
}
@ -242,6 +233,10 @@ prepareServerAddress(const char* address, int port, struct sockaddr_in* sockaddr
sockaddr->sin_addr.s_addr = htonl(INADDR_ANY);
sockaddr->sin_family = AF_INET;
if (port < 0)
port = 0;
sockaddr->sin_port = htons(port);
exit_function:
@ -273,7 +268,7 @@ TcpServerSocket_create(const char* address, int port)
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) {
struct sockaddr_in serverAddress;
if (!prepareServerAddress(address, port, &serverAddress)) {
if (!prepareAddress(address, port, &serverAddress)) {
close(fd);
return NULL;
}
@ -327,10 +322,20 @@ ServerSocket_accept(ServerSocket self)
if (fd >= 0) {
conSocket = (Socket) GLOBAL_CALLOC(1, sizeof(struct sSocket));
if (conSocket) {
conSocket->fd = fd;
activateTcpNoDelay(conSocket);
}
else {
/* out of memory */
close(fd);
if (DEBUG_SOCKET)
printf("SOCKET: out of memory\n");
}
}
return conSocket;
}
@ -350,9 +355,19 @@ closeAndShutdownSocket(int socketFd)
printf("SOCKET: call shutdown for %i!\n", socketFd);
/* shutdown is required to unblock read or accept in another thread! */
shutdown(socketFd, SHUT_RDWR);
int result = shutdown(socketFd, SHUT_RDWR);
if (result == -1) {
if (DEBUG_SOCKET)
printf("SOCKET: shutdown error: %i\n", errno);
}
result = close(socketFd);
close(socketFd);
if (result == -1) {
if (DEBUG_SOCKET)
printf("SOCKET: close error: %i\n", errno);
}
}
}
@ -373,13 +388,14 @@ ServerSocket_destroy(ServerSocket self)
Socket
TcpSocket_create()
{
Socket self = NULL;
Socket self = (Socket)NULL;
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock != -1) {
self = (Socket) GLOBAL_MALLOC(sizeof(struct sSocket));
if (self) {
self->fd = sock;
self->connectTimeout = 5000;
@ -387,12 +403,19 @@ TcpSocket_create()
int tcpUserTimeout = 10000;
int result = setsockopt(sock, SOL_TCP, TCP_USER_TIMEOUT, &tcpUserTimeout, sizeof(tcpUserTimeout));
if (result < 0) {
if (result == -1) {
if (DEBUG_SOCKET)
printf("SOCKET: failed to set TCP_USER_TIMEOUT\n");
printf("SOCKET: failed to set TCP_USER_TIMEOUT (errno=%i)\n", errno);
}
#endif
}
else {
/* out of memory */
close(sock);
if (DEBUG_SOCKET)
printf("SOCKET: out of memory\n");
}
}
else {
if (DEBUG_SOCKET)
@ -402,13 +425,35 @@ TcpSocket_create()
return self;
}
void
Socket_setConnectTimeout(Socket self, uint32_t timeoutInMs)
{
self->connectTimeout = timeoutInMs;
}
bool
Socket_bind(Socket self, const char* srcAddress, int srcPort)
{
struct sockaddr_in localAddress;
if (!prepareAddress(srcAddress, srcPort, &localAddress))
return false;
int result = bind(self->fd, (struct sockaddr*)&localAddress, sizeof(localAddress));
if (result == -1) {
if (DEBUG_SOCKET)
printf("SOCKET: failed to bind TCP socket (errno=%i)\n", errno);
close(self->fd);
self->fd = -1;
return false;
}
return true;
}
bool
Socket_connectAsync(Socket self, const char* address, int port)
{
@ -417,7 +462,7 @@ Socket_connectAsync(Socket self, const char* address, int port)
if (DEBUG_SOCKET)
printf("SOCKET: connect: %s:%i\n", address, port);
if (!prepareServerAddress(address, port, &serverAddress))
if (!prepareAddress(address, port, &serverAddress))
return false;
fd_set fdSet;
@ -627,6 +672,8 @@ Socket_read(Socket self, uint8_t* buf, int size)
case EAGAIN:
return 0;
case EBADF:
return -1;
default:
@ -647,7 +694,7 @@ Socket_write(Socket self, uint8_t* buf, int size)
return -1;
/* MSG_NOSIGNAL - prevent send to signal SIGPIPE when peer unexpectedly closed the socket */
int retVal = send(self->fd, buf, size, MSG_NOSIGNAL);
int retVal = send(self->fd, buf, size, MSG_NOSIGNAL | MSG_DONTWAIT);
if (retVal == -1) {
if (errno == EAGAIN) {
@ -701,7 +748,7 @@ UdpSocket_bind(UdpSocket self, const char* address, int port)
{
struct sockaddr_in localAddress;
if (!prepareServerAddress(address, port, &localAddress)) {
if (!prepareAddress(address, port, &localAddress)) {
close(self->fd);
self->fd = 0;
return false;
@ -727,7 +774,7 @@ UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, in
{
struct sockaddr_in remoteAddress;
if (!prepareServerAddress(address, port, &remoteAddress)) {
if (!prepareAddress(address, port, &remoteAddress)) {
if (DEBUG_SOCKET)
printf("SOCKET: failed to lookup remote address %s\n", address);

@ -1,26 +1,14 @@
/*
* socket_win32.c
*
* Copyright 2013-2020 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
@ -71,6 +59,7 @@ Handleset_new(void)
FD_ZERO(&result->handles);
result->maxHandle = INVALID_SOCKET;
}
return result;
}
@ -97,7 +86,10 @@ void
Handleset_removeSocket(HandleSet self, const Socket sock)
{
if (self != NULL && sock != NULL && sock->fd != INVALID_SOCKET) {
FD_CLR(sock->fd, &self->handles);
FD_SET(sock->fd, &self->handles);
if ((sock->fd > self->maxHandle) || (self->maxHandle == INVALID_SOCKET))
self->maxHandle = sock->fd;
}
}
@ -172,18 +164,18 @@ setSocketNonBlocking(Socket self)
}
static bool
prepareServerAddress(const char* address, int port, struct sockaddr_in* sockaddr)
prepareAddress(const char *address, int port, struct sockaddr_in *sockaddr)
{
memset((char *) sockaddr , 0, sizeof(struct sockaddr_in));
memset((char *)sockaddr, 0, sizeof(struct sockaddr_in));
if (address != NULL) {
struct hostent *server;
server = gethostbyname(address);
if (server == NULL) return false;
if (server == NULL)
return false;
memcpy((char *) &sockaddr->sin_addr.s_addr, (char *) server->h_addr, server->h_length);
memcpy((char *)&sockaddr->sin_addr.s_addr, (char *)server->h_addr, server->h_length);
}
else
sockaddr->sin_addr.s_addr = htonl(INADDR_ANY);
@ -240,7 +232,7 @@ TcpServerSocket_create(const char* address, int port)
struct sockaddr_in server_addr;
if (!prepareServerAddress(address, port, &server_addr))
if (!prepareAddress(address, port, &server_addr))
return NULL;
listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
@ -269,14 +261,20 @@ TcpServerSocket_create(const char* address, int port)
return NULL;
}
serverSocket = (ServerSocket) GLOBAL_MALLOC(sizeof(struct sServerSocket));
serverSocket = (ServerSocket)GLOBAL_MALLOC(sizeof(struct sServerSocket));
if (serverSocket) {
serverSocket->fd = listen_socket;
serverSocket->backLog = 10;
setSocketNonBlocking((Socket) serverSocket);
setSocketNonBlocking((Socket)serverSocket);
socketCount++;
}
else {
closesocket(listen_socket);
wsaShutdown();
}
return serverSocket;
}
@ -346,6 +344,7 @@ TcpSocket_create()
if (sock != INVALID_SOCKET) {
self = (Socket) GLOBAL_MALLOC(sizeof(struct sSocket));
if (self) {
self->fd = sock;
self->connectTimeout = 5000;
@ -353,7 +352,16 @@ TcpSocket_create()
}
else {
if (DEBUG_SOCKET)
printf("WIN32_SOCKET: failed to create socket (error code=%i)\n", WSAGetLastError());
printf("SOCKET: failed to create socket - cannot allocate memory\n");
closesocket(sock);
wsaShutdown();
}
}
else {
if (DEBUG_SOCKET)
printf("SOCKET: failed to create socket (error code=%i)\n", WSAGetLastError());
}
return self;
@ -365,6 +373,29 @@ Socket_setConnectTimeout(Socket self, uint32_t timeoutInMs)
self->connectTimeout = timeoutInMs;
}
bool
Socket_bind(Socket self, const char* srcAddress, int srcPort)
{
struct sockaddr_in localAddress;
if (!prepareAddress(srcAddress, srcPort, &localAddress))
return false;
int result = bind(self->fd, (struct sockaddr*)&localAddress, sizeof(localAddress));
if (result == SOCKET_ERROR) {
if (DEBUG_SOCKET)
printf("SOCKET: failed to bind TCP socket (errno=%i)\n", WSAGetLastError());
closesocket(self->fd);
self->fd = -1;
return false;
]
return true;
}
bool
Socket_connectAsync(Socket self, const char* address, int port)
{
@ -381,7 +412,7 @@ Socket_connectAsync(Socket self, const char* address, int port)
return false;
}
if (!prepareServerAddress(address, port, &serverAddress))
if (!prepareAddress(address, port, &serverAddress))
return false;
setSocketNonBlocking(self);
@ -438,7 +469,7 @@ Socket_connect(Socket self, const char* address, int port)
{
struct sockaddr_in serverAddress;
if (!prepareServerAddress(address, port, &serverAddress))
if (!prepareAddress(address, port, &serverAddress))
return false;
setSocketNonBlocking(self);
@ -456,7 +487,7 @@ Socket_connect(Socket self, const char* address, int port)
timeout.tv_sec = self->connectTimeout / 1000;
timeout.tv_usec = (self->connectTimeout % 1000) * 1000;
if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) <= 0)
if (select((int)self->fd + 1, NULL, &fdSet, NULL, &timeout) <= 0)
return false;
else
return true;
@ -647,7 +678,7 @@ UdpSocket_bind(UdpSocket self, const char* address, int port)
{
struct sockaddr_in localAddress;
if (!prepareServerAddress(address, port, &localAddress)) {
if (!prepareAddress(address, port, &localAddress)) {
closesocket(self->fd);
self->fd = 0;
return false;
@ -673,7 +704,7 @@ UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, in
{
struct sockaddr_in remoteAddress;
if (!prepareServerAddress(address, port, &remoteAddress)) {
if (!prepareAddress(address, port, &remoteAddress)) {
if (DEBUG_SOCKET)
printf("SOCKET: failed to lookup remote address %s\n", address);

@ -1,31 +1,16 @@
/**
* thread_bsd.c
*
* Copyright 2016 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include "hal_thread.h"
#include "lib_memory.h"
struct sThread {
@ -62,7 +47,8 @@ Semaphore_post(Semaphore self)
void
Semaphore_destroy(Semaphore self)
{
sem_close(self);
sem_destroy((sem_t*) self);
GLOBAL_FREEMEM(self);
}
Thread
@ -120,3 +106,4 @@ Thread_sleep(int millies)
{
usleep(millies * 1000);
}

@ -1,32 +1,16 @@
/*
* thread_linux.c
*
* Copyright 2013 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include "hal_thread.h"
#include "lib_memory.h"
struct sThread {

@ -1,7 +1,7 @@
/**
* thread_macos.c
*
* Copyright 2013-2019 MZ Automation GmbH
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.

@ -1,24 +1,10 @@
/*
* thread_win32.c
*
* Copyright 2013, 2014 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#include <windows.h>

@ -3,26 +3,11 @@
*
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#include "hal_time.h"
#include <time.h>
#ifdef CONFIG_SYSTEM_HAS_CLOCK_GETTIME

@ -1,30 +1,14 @@
/*
* time.c
*
* Copyright 2013, 2014 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
#include "hal_time.h"
#include <time.h>
#include <windows.h>
uint64_t

@ -40,6 +40,7 @@
#define MBEDTLS_SSL_SRV_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_CRL_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_SSL_CACHE_C

@ -3,7 +3,7 @@
*
* TLS API for TCP/IP protocol stacks
*
* Copyright 2017 MZ Automation GmbH
* Copyright 2017-2021 Michael Zillgith, MZ Automation GmbH
*
* Implementation of the TLS abstraction layer for mbedtls
*
@ -14,6 +14,7 @@
#include "tls_socket.h"
#include "hal_thread.h"
#include "lib_memory.h"
#include "hal_time.h"
#include "linked_list.h"
#include "mbedtls/platform.h"
@ -27,9 +28,7 @@
#include "mbedtls/debug.h"
#if (CONFIG_DEBUG_TLS == 1)
#define DEBUG_PRINT(appId, fmt, ...) fprintf(stderr, "%s: " fmt, \
appId, \
__VA_ARGS__)
#define DEBUG_PRINT(appId, fmt, ...) fprintf(stderr, "%s: " fmt, appId, ## __VA_ARGS__);
#else
#define DEBUG_PRINT(fmt, ...) {do {} while(0);}
#endif
@ -44,15 +43,23 @@ struct sTLSConfiguration {
mbedtls_x509_crt cacerts;
mbedtls_x509_crl crl;
mbedtls_ssl_config conf;
LinkedList /* <mbedtls_x509_crt*> */ allowedCertificates;
bool chainValidation;
bool allowOnlyKnownCertificates;
/* TLS session renegotioation time in milliseconds */
/* TLS session renegotiation interval in milliseconds */
int renegotiationTimeInMs;
/* TLS minimum version allowed (default: TLS_VERSION_TLS_1_0) */
TLSConfigVersion minVersion;
/* TLS minimum version allowed (default: TLS_VERSION_TLS_1_2) */
TLSConfigVersion maxVersion;
bool setupComplete;
};
@ -64,6 +71,9 @@ struct sTLSSocket {
bool storePeerCert;
uint8_t* peerCert;
int peerCertLength;
/* time of last session renegotiation (used to calculate next renegotiation time) */
uint64_t lastRenegotiationTime;
};
static bool
@ -147,7 +157,27 @@ verifyCertificate (void* parameter, mbedtls_x509_crt *crt, int certificate_depth
return 0;
}
/*
* Finish configuration when used the first time.
*/
static bool
TLSConfiguration_setupComplete(TLSConfiguration self)
{
if (self->setupComplete == false) {
mbedtls_ssl_conf_ca_chain( &(self->conf), &(self->cacerts), NULL );
int ret = mbedtls_ssl_conf_own_cert( &(self->conf), &(self->ownCertificate), &(self->ownKey));
if (ret != 0) {
DEBUG_PRINT("TLS", "mbedtls_ssl_conf_own_cert returned %d\n", ret);
return false;
}
self->setupComplete = true;
}
return true;
}
TLSConfiguration
TLSConfiguration_create()
@ -157,7 +187,8 @@ TLSConfiguration_create()
if (self != NULL) {
mbedtls_ssl_config_init( &(self->conf) );
mbedtls_x509_crt_init( &(self->ownCertificate) );
mbedtls_x509_crt_init( &(self->cacerts));
mbedtls_x509_crt_init( &(self->cacerts) );
mbedtls_x509_crl_init( &(self->crl) );
mbedtls_pk_init( &(self->ownKey) );
mbedtls_entropy_init( &(self->entropy) );
mbedtls_ctr_drbg_init( &(self->ctr_drbg) );
@ -173,11 +204,16 @@ TLSConfiguration_create()
mbedtls_ssl_conf_authmode(&(self->conf), MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_renegotiation(&(self->conf), MBEDTLS_SSL_RENEGOTIATION_DISABLED);
mbedtls_ssl_conf_renegotiation(&(self->conf), MBEDTLS_SSL_RENEGOTIATION_ENABLED);
/* static int hashes[] = {3,4,5,6,7,8,0}; */
/* mbedtls_ssl_conf_sig_hashes(&(self->conf), hashes); */
self->minVersion = TLS_VERSION_TLS_1_0;
self->maxVersion = TLS_VERSION_NOT_SELECTED;
self->renegotiationTimeInMs = -1; /* no automatic renegotiation */
self->allowedCertificates = LinkedList_create();
/* default behavior is to allow all certificates that are signed by the CA */
@ -195,6 +231,18 @@ TLSConfiguration_setClientMode(TLSConfiguration self)
self->conf.endpoint = MBEDTLS_SSL_IS_CLIENT;
}
void
TLSConfiguration_setMinTlsVersion(TLSConfiguration self, TLSConfigVersion version)
{
self->minVersion = version;
}
void
TLSConfiguration_setMaxTlsVersion(TLSConfiguration self, TLSConfigVersion version)
{
self->maxVersion = version;
}
void
TLSConfiguration_setChainValidation(TLSConfiguration self, bool value)
{
@ -213,7 +261,7 @@ TLSConfiguration_setOwnCertificate(TLSConfiguration self, uint8_t* certificate,
int ret = mbedtls_x509_crt_parse(&(self->ownCertificate), certificate, certLen);
if (ret != 0)
DEBUG_PRINT("mbedtls_x509_crt_parse returned %d\n", ret);
DEBUG_PRINT("TLS", "mbedtls_x509_crt_parse returned %d\n", ret);
return (ret == 0);
}
@ -309,6 +357,29 @@ TLSConfiguration_addCACertificateFromFile(TLSConfiguration self, const char* fil
return (ret == 0);
}
bool
TLSConfiguration_addCRL(TLSConfiguration self, uint8_t* crl, int crlLen)
{
int ret = mbedtls_x509_crl_parse(&(self->crl), crl, crlLen);
if (ret != 0) {
DEBUG_PRINT("TLS", "mbedtls_x509_crl_parse returned %d\n", ret);
}
return (ret == 0);
}
bool
TLSConfiguration_addCRLFromFile(TLSConfiguration self, const char* filename)
{
int ret = mbedtls_x509_crl_parse_file(&(self->crl), filename);
if (ret != 0)
DEBUG_PRINT("TLS", "mbedtls_x509_crl_parse_file returned %d\n", ret);
return (ret == 0);
}
void
TLSConfiguration_setRenegotiationTime(TLSConfiguration self, int timeInMs)
{
@ -320,6 +391,7 @@ TLSConfiguration_destroy(TLSConfiguration self)
{
mbedtls_x509_crt_free(&(self->ownCertificate));
mbedtls_x509_crt_free(&(self->cacerts));
mbedtls_x509_crl_free(&(self->crl));
mbedtls_pk_free(&(self->ownKey));
mbedtls_ssl_config_free(&(self->conf));
@ -351,26 +423,42 @@ readFunction(void* ctx, unsigned char* buf, size_t len)
return ret;
}
/*
* Finish configuration when used the first time.
*/
static bool
TLSConfiguration_setupComplete(TLSConfiguration self)
static int
getMajorVersion(TLSConfigVersion version)
{
if (self->setupComplete == false) {
mbedtls_ssl_conf_ca_chain( &(self->conf), &(self->cacerts), NULL );
int ret = mbedtls_ssl_conf_own_cert( &(self->conf), &(self->ownCertificate), &(self->ownKey));
if (ret != 0) {
DEBUG_PRINT("TLS", "mbedtls_ssl_conf_own_cert returned %d\n", ret);
return false;
switch(version) {
case TLS_VERSION_NOT_SELECTED:
return 0;
case TLS_VERSION_SSL_3_0:
case TLS_VERSION_TLS_1_0:
case TLS_VERSION_TLS_1_1:
case TLS_VERSION_TLS_1_2:
case TLS_VERSION_TLS_1_3:
return 3;
default:
return 0;
}
}
self->setupComplete = true;
static int
getMinorVersion(TLSConfigVersion version)
{
switch(version) {
case TLS_VERSION_NOT_SELECTED:
return 0;
case TLS_VERSION_SSL_3_0:
return 0;
case TLS_VERSION_TLS_1_0:
return 1;
case TLS_VERSION_TLS_1_1:
return 2;
case TLS_VERSION_TLS_1_2:
return 3;
case TLS_VERSION_TLS_1_3:
return 4;
default:
return 0;
}
return true;
}
TLSSocket
@ -392,7 +480,34 @@ TLSSocket_create(Socket socket, TLSConfiguration configuration, bool storeClient
mbedtls_ssl_conf_verify(&(self->conf), verifyCertificate, (void*) self);
int ret = mbedtls_ssl_setup( &(self->ssl), &(self->conf) );
int ret;
mbedtls_ssl_conf_ca_chain( &(self->conf), &(configuration->cacerts), NULL );
if (configuration->minVersion != TLS_VERSION_NOT_SELECTED) {
/* set minimum TLS version */
int majorVer = getMajorVersion(configuration->minVersion);
int minorVer = getMinorVersion(configuration->minVersion);
mbedtls_ssl_conf_min_version( &(self->conf), majorVer, minorVer);
}
if (configuration->maxVersion != TLS_VERSION_NOT_SELECTED) {
/* set maximum TLS version */
int majorVer = getMajorVersion(configuration->maxVersion);
int minorVer = getMinorVersion(configuration->maxVersion);
mbedtls_ssl_conf_max_version( &(self->conf), majorVer, minorVer);
}
ret = mbedtls_ssl_conf_own_cert( &(self->conf), &(configuration->ownCertificate), &(configuration->ownKey));
if (ret != 0)
DEBUG_PRINT("TLS", "mbedtls_ssl_conf_own_cert returned %d\n", ret);
ret = mbedtls_ssl_setup( &(self->ssl), &(self->conf) );
if (ret != 0)
DEBUG_PRINT("TLS", "mbedtls_ssl_setup returned %d\n", ret);
@ -404,15 +519,24 @@ TLSSocket_create(Socket socket, TLSConfiguration configuration, bool storeClient
{
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
DEBUG_PRINT("TLS", "mbedtls_ssl_handshake returned %d\n\n", ret );
DEBUG_PRINT("TLS", "handshake failed - mbedtls_ssl_handshake --> %d\n\n", ret );
mbedtls_ssl_free(&(self->ssl));
if (self->peerCert) {
GLOBAL_FREEMEM(self->peerCert);
}
GLOBAL_FREEMEM(self);
return NULL;
}
}
self->lastRenegotiationTime = Hal_getTimeInMs();
/* TODO check for TLS version warning or alarm condition */
/* printf("TLS %i.%i\n", self->ssl.major_ver, self->ssl.minor_ver); */
}
return self;
@ -439,6 +563,19 @@ TLSSocket_performHandshake(TLSSocket self)
int
TLSSocket_read(TLSSocket self, uint8_t* buf, int size)
{
if (self->tlsConfig->renegotiationTimeInMs > 0) {
if (Hal_getTimeInMs() > self->lastRenegotiationTime + self->tlsConfig->renegotiationTimeInMs) {
if (TLSSocket_performHandshake(self) == false) {
DEBUG_PRINT("TLS", " renegotiation failed\n");
return -1;
}
else {
DEBUG_PRINT("TLS", " started renegotiation\n");
self->lastRenegotiationTime = Hal_getTimeInMs();
}
}
}
int ret = mbedtls_ssl_read(&(self->ssl), buf, size);
if ((ret == MBEDTLS_ERR_SSL_WANT_READ) || (ret == MBEDTLS_ERR_SSL_WANT_WRITE))

Loading…
Cancel
Save